IonexModel.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: IonexModel.cpp 1804 2009-03-17 15:13:29Z coandrei $"
00002 
00009 //============================================================================
00010 //
00011 //  This file is part of GPSTk, the GPS Toolkit.
00012 //
00013 //  The GPSTk is free software; you can redistribute it and/or modify
00014 //  it under the terms of the GNU Lesser General Public License as published
00015 //  by the Free Software Foundation; either version 2.1 of the License, or
00016 //  any later version.
00017 //
00018 //  The GPSTk is distributed in the hope that it will be useful,
00019 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021 //  GNU Lesser General Public License for more details.
00022 //
00023 //  You should have received a copy of the GNU Lesser General Public
00024 //  License along with GPSTk; if not, write to the Free Software Foundation,
00025 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 //
00027 //  Octavian Andrei - FGI ( http://www.fgi.fi ). 2008, 2009
00028 //
00029 //============================================================================
00030 
00031 
00032 #include "IonexModel.hpp"
00033 #include "icd_200_constants.hpp"          // C_GPS_M
00034 
00035 
00036 namespace gpstk
00037 {
00038 
00039       // Index initially assigned to this class.
00040    int IonexModel::classIndex = 5100000;
00041 
00042 
00043       // Returns an index identifying this object.
00044    int IonexModel::getIndex() const
00045    { return index; }
00046 
00047 
00048       // Returns a string identifying this object.
00049    std::string IonexModel::getClassName() const
00050    { return "IonexModel"; }
00051 
00052 
00053 
00054       // Explicit constructor, taking as input a Position object
00055       // containing reference station coordinates.
00056    IonexModel::IonexModel(const Position& RxCoordinates)
00057       throw(Exception)
00058    {
00059 
00060       pDefaultMaps = NULL;
00061       defaultObservable = TypeID::P1;
00062       useDCB = true;
00063       setIonoMapType("NONE");
00064       setInitialRxPosition(RxCoordinates);
00065       setIndex();
00066 
00067    }  // End of constructor 'IonexModel::IonexModel()'
00068 
00069 
00070 
00082    IonexModel::IonexModel( const Position& RxCoordinates,
00083                            IonexStore& istore,
00084                            const TypeID& dObservable,
00085                            const bool& applyDCB,
00086                            const std::string& ionoMap)
00087          throw(Exception)
00088       {
00089 
00090          setInitialRxPosition(RxCoordinates);
00091          setDefaultMaps(istore);
00092          defaultObservable = dObservable;
00093          useDCB = applyDCB;
00094          setIonoMapType(ionoMap);
00095          setIndex();
00096 
00097       }  // End of constructor 'IonexModel::IonexModel()'
00098 
00099 
00100 
00107    satTypeValueMap& IonexModel::Process( const DayTime& time,
00108                                          satTypeValueMap& gData )
00109       throw(Exception)
00110    {
00111 
00112       SatIDSet satRejectedSet;
00113 
00114       try
00115       {
00116 
00117             // Loop through all the satellites
00118          satTypeValueMap::iterator stv;
00119          for(stv = gData.begin(); stv != gData.end(); ++stv)
00120          {
00121 
00122                // First check if ionex maps were set
00123             if(pDefaultMaps==NULL)
00124             {
00125 
00126                   // If ionex maps are missing, then remove all satellites
00127                satRejectedSet.insert( stv->first );
00128 
00129                continue;
00130 
00131             }
00132 
00133                // If elevation or azimuth is missing, then remove satellite
00134             if( stv->second.find(TypeID::elevation) == stv->second.end() ||
00135                 stv->second.find(TypeID::azimuth)   == stv->second.end() )
00136             {
00137 
00138                satRejectedSet.insert( stv->first );
00139 
00140                continue;
00141 
00142             }
00143             else
00144             {
00145 
00146                   // Scalars to hold satellite elevation, azimuth, ionospheric 
00147                   // map and ionospheric slant delays
00148                double elevation( stv->second(TypeID::elevation) );
00149                double azimuth(   stv->second(TypeID::azimuth)   );
00150                double ionoMap(0.0);
00151                double ionexL1(0.0), ionexL2(0.0), ionexL5(0.0);   // GPS
00152                double ionexL6(0.0), ionexL7(0.0), ionexL8(0.0);   // Galileo
00153 
00154                   //    calculate the position of the ionospheric pierce-point 
00155                   // corresponding to the receiver-satellite ray
00156                Position IPP = rxPos.getIonosphericPiercePoint( elevation,
00157                                                                azimuth,
00158                                                                ionoHeight);
00159 
00160                   // TODO
00161                   // Checking the collinearity of rxPos, IPP and SV
00162 
00163 
00164                   // Let's get TEC, RMS and ionosphere height for IPP 
00165                   // at current epoch
00166                Position pos(IPP);
00167                pos.transformTo(Position::Geocentric);
00168                Triple val = pDefaultMaps->getIonexValue( time, pos );
00169 
00170                   // just to make it handy for useage
00171                double tecval = val[0];
00172 
00173                try
00174                {
00175 
00176                   ionoMap = pDefaultMaps->iono_mapping_function( elevation,
00177                                                                  ionoMapType);
00178 
00179                      // Compute ionospheric slant correction
00180                   ionexL1 = pDefaultMaps->getIonoL1( elevation,
00181                                                      tecval,
00182                                                      ionoMapType);
00183 
00184                   ionexL2 = pDefaultMaps->getIonoL2( elevation,
00185                                                      tecval,
00186                                                      ionoMapType);
00187 
00188                   ionexL5 = pDefaultMaps->getIonoL5( elevation,
00189                                                      tecval,
00190                                                      ionoMapType);
00191 
00192                   ionexL6 = pDefaultMaps->getIonoL6( elevation,
00193                                                      tecval,
00194                                                      ionoMapType);
00195 
00196                   ionexL7 = pDefaultMaps->getIonoL7( elevation,
00197                                                      tecval,
00198                                                      ionoMapType);
00199 
00200                   ionexL8 = pDefaultMaps->getIonoL8( elevation,
00201                                                      tecval,
00202                                                      ionoMapType);
00203 
00204                }
00205                catch(InvalidRequest)
00206                {
00207 
00208                      // If some problem appears, then schedule this
00209                      // satellite for removal
00210                   satRejectedSet.insert( stv->first );
00211 
00212                   continue;    // Skip this SV if problems arise
00213 
00214                }
00215 
00216                   // Now we have to add the new values (i.e., ionosphere delays)
00217                   // to the data structure
00218                (*stv).second[TypeID::ionoTEC] = tecval;
00219                (*stv).second[TypeID::ionoMap] = ionoMap;
00220                (*stv).second[TypeID::ionoL1]  = ionexL1;
00221                (*stv).second[TypeID::ionoL2]  = ionexL2;
00222                (*stv).second[TypeID::ionoL5]  = ionexL5;
00223                (*stv).second[TypeID::ionoL6]  = ionexL6;
00224                (*stv).second[TypeID::ionoL7]  = ionexL7;
00225                (*stv).second[TypeID::ionoL8]  = ionexL8;
00226 
00227 
00228                   // DCB corrections for P1 measurements and satellite clock
00229                   // values should be considered because precise ephemerides
00230                   // and satellite clock information for SP3 orbit file always
00231                   // refers to the ionosphere-free linear combination (LC)
00232                   // see Appendix B, pg.14 of the Ionex manual
00233                   // Useful link:
00234 
00235       // http://www.ngs.noaa.gov/IGSWorkshop2008/docs/Schaer_DCB_IGSWS2008.ppt
00236 
00237                   // Computing Differential Code Biases (DCB - nanoseconds)
00238                double tempDCB( getDCBCorrections( time,
00239                                                  (*pDefaultMaps),
00240                                                   stv->first) );
00241 
00242 
00243                   // add to the GDS the  corresponding correction, 
00244                   // if appropriate
00245                if(useDCB)
00246                {
00247 
00248                      // the second LC factor (see gpstk::LinearCombinations.cpp)
00249                      // see pg.14, Ionex manual
00250                   double kappa2(-1.0/0.646944444);
00251                   double dcb(tempDCB * C_GPS_M * 1e-9);  // meters
00252 
00253                   if( stv->second.find(TypeID::instC1) == stv->second.end() )
00254                   {
00255                      stv->second[TypeID::instC1] = (kappa2 * dcb);
00256                   }
00257                   else
00258                   {
00259                      stv->second[TypeID::instC1] += (kappa2 * dcb);
00260                   }
00261 
00262                }  // End of 'if(useDCB)...'
00263 
00264             }  // End of 'if( stv->second.find(TypeID::elevation) == ... '
00265 
00266          }  // End of loop 'for(stv = gData.begin()...'
00267 
00268 
00269             // Remove satellites with missing data
00270          gData.removeSatID(satRejectedSet);
00271 
00272          return gData;
00273 
00274       }   // End of try...
00275       catch(Exception& e)
00276       {
00277 
00278          GPSTK_RETHROW(e);
00279 
00280       }
00281 
00282    }  // End of method 'IonexModel::Process()'
00283 
00284 
00285 
00286       /* Method to set the initial (a priori) position of receiver.
00287        * @return
00288        *  0 if OK
00289        *  -1 if problems arose
00290        */
00291    int IonexModel::setInitialRxPosition(const Position& RxCoordinates)
00292       throw(GeometryException)
00293    {
00294 
00295       try
00296       {
00297 
00298          rxPos = RxCoordinates;
00299 
00300          return 0;
00301 
00302       }
00303       catch(GeometryException)
00304       {
00305          return -1;
00306       }
00307 
00308    }  // End of method 'IonexModel::setInitialRxPosition()'
00309 
00310 
00311 
00312       // Method to set the initial (a priori) position of receiver.
00313    int IonexModel::setInitialRxPosition(void)
00314       throw(GeometryException) 
00315    {
00316 
00317       try
00318       {
00319 
00320          Position rxpos(0.0, 0.0, 0.0, Position::Cartesian, NULL);
00321 
00322          setInitialRxPosition(rxpos);
00323 
00324          return 0;
00325 
00326       }
00327       catch(GeometryException)
00328       {
00329          return -1;
00330       }
00331 
00332    }  // End of method 'IonexModel::setInitialRxPosition()'
00333 
00334 
00335 
00344    IonexModel& IonexModel::setIonoMapType(const std::string& ionoMap)
00345    { 
00346 
00347          // here we set the type
00348       ionoMapType = ( ionoMap != "NONE" && ionoMap != "SLM" && 
00349                       ionoMap != "MSLM" && ionoMap != "ESM") ? "NONE" : 
00350                                                                ionoMap;
00351 
00352          // and here the ionosphere height, in meters
00353       ionoHeight = (ionoMap == "MSLM") ? 506700.0 : 450000.0;
00354 
00355       return (*this);
00356 
00357    }
00358 
00359 
00360 
00369    double IonexModel::getDCBCorrections( const DayTime& time,
00370                                          const IonexStore& Maps,
00371                                          SatID sat )
00372       throw()
00373    {
00374 
00375       try
00376       {
00377 
00378          double dcb = Maps.findDCB(sat,time);   // nanoseconds
00379 
00380          return dcb;
00381 
00382       }
00383       catch(...)
00384       {
00385 
00386          return 0.0;
00387 
00388       }
00389 
00390    }  // End of method 'IonexModel::getDCBCorrections()'
00391 
00392 
00393 
00394 }  // End of namespace gpstk

Generated on Thu Sep 9 03:30:53 2010 for GPS ToolKit Software Library by  doxygen 1.3.9.1