ComputeIonoModel.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: ComputeIonoModel.cpp 2526 2011-03-09 17:46:16Z yanweignss $"
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 //  Wei Yan - Chinese Academy of Sciences . 2009, 2010, 2011
00028 //
00029 //============================================================================
00030 
00031 
00032 #include "ComputeIonoModel.hpp"
00033 #include "RinexUtilities.hpp"
00034 #include "RinexNavStream.hpp"
00035 #include "RinexNavHeader.hpp"
00036 #include "Logger.hpp"
00037 
00038 namespace gpstk
00039 {
00040 
00041    using namespace std;
00042 
00043       // Index initially assigned to this class
00044    int ComputeIonoModel::classIndex = 5500000;
00045 
00046 
00047       // Returns an index identifying this object.
00048    int ComputeIonoModel::getIndex() const
00049    { return index; }
00050 
00051 
00052       // Returns a string identifying this object.
00053    std::string ComputeIonoModel::getClassName() const
00054    { return "ComputeIonoModel"; }
00055 
00056 
00057 
00058       /* Returns a satTypeValueMap object, adding the new data generated when
00059        * calling a modeling object.
00060        *
00061        * @param time      Epoch.
00062        * @param gData     Data object holding the data.
00063        */
00064    satTypeValueMap& ComputeIonoModel::Process( const DayTime& time,
00065                                          satTypeValueMap& gData )
00066       throw(ProcessingException)
00067    {
00068 
00069       try
00070       {
00071          
00072          SatIDSet satRejectedSet;
00073 
00074          Position rxPos(nominalPos[0],nominalPos[1],nominalPos[2],
00075             Position::Cartesian);
00076 
00077          Geodetic rxGeo(rxPos.getGeodeticLatitude(),
00078             rxPos.getLongitude(),
00079             rxPos.getAltitude());
00080                 
00081             // Loop through all the satellites
00082          satTypeValueMap::iterator stv;
00083          for(stv = gData.begin(); stv != gData.end(); ++stv) 
00084          {
00085 
00086             Position svPos(0.0, 0.0, 0.0, Position::Cartesian);
00087             
00088                // If elevation or azimuth is missing, then remove satellite
00089             if( stv->second.find(TypeID::elevation) == stv->second.end() ||
00090                stv->second.find(TypeID::azimuth)   == stv->second.end() )
00091             {
00092 
00093                satRejectedSet.insert( stv->first );
00094 
00095                continue;
00096 
00097             }
00098             
00099             const double elevation = (*stv).second[TypeID::elevation];
00100             const double azimuth = (*stv).second[TypeID::azimuth]; 
00101 
00102             double ionL1 = 0.0;
00103             
00104             if(ionoType == Ionex)
00105             {
00106                try
00107                {
00108                   //const string mapType = "SLM";
00109                   //const double ionoHeight = 450000.0;
00110 
00111                   const string mapType = "MSLM";
00112                   const double ionoHeight = 506700.0;
00113 
00114                   Position IPP = rxPos.getIonosphericPiercePoint(elevation,
00115                      azimuth,
00116                      ionoHeight);
00117 
00118                   Position pos(IPP);
00119                   pos.transformTo(Position::Geocentric);
00120 
00121                   Triple val = gridStore.getIonexValue( time, pos );
00122 
00123                   double tecval = val[0];
00124 
00125                   double ionMap = gridStore.iono_mapping_function(elevation,
00126                                                                   mapType);
00127                   
00128                   ionL1 = gridStore.getIonoL1(elevation, tecval, mapType);
00129                }
00130                catch(InvalidRequest& e)
00131                {
00132                   satRejectedSet.insert(stv->first);
00133                   continue;
00134                }
00135             }
00136             else if(ionoType == Klobuchar)
00137             {
00138                ionL1 = klbStore.getCorrection(time,rxGeo,elevation,azimuth);
00139             }
00140             else if(ionoType == DualFreq)
00141             {
00142                const double gamma = (L1_FREQ/L2_FREQ) * (L1_FREQ/L2_FREQ);
00143 
00144                double P1(0.0);
00145                if(stv->second.find(TypeID::P1)==stv->second.end())
00146                {
00147                   if(stv->second.find(TypeID::C1)!=stv->second.end())
00148                   {
00149                      P1 = stv->second[TypeID::C1];
00150                   }
00151                }
00152                else
00153                {
00154                   P1 = stv->second[TypeID::P1];
00155                }
00156 
00157                double P2(0.0);
00158                if(stv->second.find(TypeID::P2)!=stv->second.end())
00159                {
00160                   P2 = stv->second[TypeID::P2];
00161                }
00162                
00163                if( P1!=0 && P2!=0 )
00164                {
00165                   ionL1 = (P1-P2)/(1.0-gamma);
00166                }
00167             }
00168 
00169             double ionL2 = ionL1 * (L1_FREQ/L2_FREQ) * (L1_FREQ/L2_FREQ);
00170             double ionL5 = ionL1 * (L1_FREQ/L5_FREQ) * (L1_FREQ/L5_FREQ);
00171             
00172                // TODO: more frequency later
00173 
00174                // Now we have to add the new values to the data structure
00175             (*stv).second[TypeID::ionoL1] = ionL1;
00176             (*stv).second[TypeID::ionoL2] = ionL2;
00177             (*stv).second[TypeID::ionoL5] = ionL5;
00178 
00179          }  // End of loop 'for(stv = gData.begin()...'
00180 
00181             // Remove satellites with missing data
00182          gData.removeSatID(satRejectedSet);
00183 
00184          return gData;
00185 
00186       }   // End of try...
00187       catch(Exception& u)
00188       {
00189             // Throw an exception if something unexpected happens
00190          ProcessingException e( getClassName() + ":"
00191                                 + StringUtils::asString( getIndex() ) + ":"
00192                                 + u.what() );
00193 
00194          GPSTK_THROW(e);
00195 
00196       }
00197 
00198    } // End ComputeIonoModel::Process()
00199 
00200 
00201    ComputeIonoModel& ComputeIonoModel::setKlobucharModel(const double a[4], 
00202                                                          const double b[4])
00203    {
00204       IonoModel ionModel(a,b);
00205       klbStore.addIonoModel(DayTime::BEGINNING_OF_TIME,ionModel);      
00206       ionoType = Klobuchar;
00207 
00208       return (*this);
00209    }
00210 
00211    ComputeIonoModel& ComputeIonoModel::setKlobucharModel(const IonoModel& im)
00212    {
00213       klbStore.addIonoModel(DayTime::BEGINNING_OF_TIME, im);
00214       ionoType = Klobuchar;
00215 
00216       return (*this);
00217    }
00218 
00219    ComputeIonoModel& ComputeIonoModel::setklobucharModel(const std::string& brdcFile)
00220    {
00221       if( isRinexNavFile( brdcFile ) )
00222       {
00223          RinexNavStream nstrm(brdcFile.c_str());
00224          nstrm.exceptions(fstream::failbit);
00225 
00226          try
00227          {
00228             RinexNavHeader rnh;
00229             nstrm >> rnh;
00230             nstrm.close();
00231 
00232             setKlobucharModel(rnh.ionAlpha,rnh.ionBeta);
00233          }
00234          catch (Exception& e)
00235          {
00236             nstrm.close();
00237 
00238             GPSTK_RETHROW(e);
00239          }
00240       }
00241       else
00242       {
00243          Exception e("The input is not a rinex nav file:" + brdcFile);
00244          GPSTK_THROW(e);
00245       }
00246       
00247 
00248       return (*this);
00249    }
00250 
00251    ComputeIonoModel& ComputeIonoModel::setIonosphereMap(const string& ionexFile)
00252    {
00253       gridStore.clear();
00254       gridStore.loadFile(ionexFile);
00255       ionoType = Ionex;
00256 
00257       return (*this);
00258    }
00259 
00260 } // End of namespace gpstk

Generated on Tue May 22 03:30:56 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1