00001 #pragma ident "$Id: ComputeIonoModel.cpp 2526 2011-03-09 17:46:16Z yanweignss $"
00002
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00044 int ComputeIonoModel::classIndex = 5500000;
00045
00046
00047
00048 int ComputeIonoModel::getIndex() const
00049 { return index; }
00050
00051
00052
00053 std::string ComputeIonoModel::getClassName() const
00054 { return "ComputeIonoModel"; }
00055
00056
00057
00058
00059
00060
00061
00062
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
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
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
00109
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
00173
00174
00175 (*stv).second[TypeID::ionoL1] = ionL1;
00176 (*stv).second[TypeID::ionoL2] = ionL2;
00177 (*stv).second[TypeID::ionoL5] = ionL5;
00178
00179 }
00180
00181
00182 gData.removeSatID(satRejectedSet);
00183
00184 return gData;
00185
00186 }
00187 catch(Exception& u)
00188 {
00189
00190 ProcessingException e( getClassName() + ":"
00191 + StringUtils::asString( getIndex() ) + ":"
00192 + u.what() );
00193
00194 GPSTK_THROW(e);
00195
00196 }
00197
00198 }
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 }