| 1 | /** | 
| 2 | * SaaaatInc | 
| 3 | * author  Malakhov V. | 
| 4 | * version 1.0 - 05/02/2007 | 
| 5 | */ | 
| 6 |  | 
| 7 | #include "InclinationInfo.h" | 
| 8 |  | 
| 9 | #include <mcmd/McmdEvent.h> | 
| 10 | #include <mcmd/McmdRecord.h> | 
| 11 | #include <EventHeader.h> | 
| 12 | #include <PscuHeader.h> | 
| 13 | #include "RunHeaderEvent.h" | 
| 14 | #include <TTree.h> | 
| 15 | #include "sgp4.h" | 
| 16 | #include "TH2F.h" | 
| 17 |  | 
| 18 | #include "TFrame.h" | 
| 19 | #include "TGraph.h" | 
| 20 | #include "TCanvas.h" | 
| 21 |  | 
| 22 | #include <TDatime.h> | 
| 23 | #include <TFile.h> | 
| 24 |  | 
| 25 | #include <TTimeStamp.h> | 
| 26 | #include "TString.h" | 
| 27 | #include "TObjString.h" | 
| 28 | #include "TPaletteAxis.h" | 
| 29 | #include "TROOT.h" | 
| 30 | #include <sys/stat.h> | 
| 31 | #include <fstream> | 
| 32 | #include <iostream> | 
| 33 |  | 
| 34 | #include "OrbitalRate.h" | 
| 35 |  | 
| 36 | //#include "TMatrixD.h" | 
| 37 |  | 
| 38 |  | 
| 39 | using namespace std; | 
| 40 |  | 
| 41 | int main(int argc, char* argv[]){ | 
| 42 |  | 
| 43 | TString *rootFile = NULL; | 
| 44 | TString outDir  = "./"; | 
| 45 | TString mapFile = ""; | 
| 46 | TString tleFile = ""; | 
| 47 | int offDate = 20060928; | 
| 48 | //int offDate = 20060614; | 
| 49 | int offTime = 210000; | 
| 50 |  | 
| 51 | if (argc < 2){ | 
| 52 | printf("You have to insert at least the file to analyze and the mapFile \n"); | 
| 53 | printf("Try '--help' for more information. \n"); | 
| 54 | exit(1); | 
| 55 | } | 
| 56 |  | 
| 57 | if (!strcmp(argv[1], "--help")){ | 
| 58 | //printf( "Usage: OrbitRate FILE -map mapFile [OPTION] \n"); | 
| 59 | //printf( "mapFile have to be a mercator map image [gif|jpg|png] \n"); | 
| 60 | printf( "\t --help                 Print this help and exit \n"); | 
| 61 | printf( "\t -tle[File path]         Path where to find the tle infos \n"); | 
| 62 | printf( "\t\tUse the script retrieve_TLE.sh to create the file.\n "); | 
| 63 | printf( "\t -outDir[path]          Path where to put the output without last directory.\n"); | 
| 64 | printf( "\t -offDate               Date of resetting of the Resource counter [format YYMMDD (UTC date) default 20060928] \n"); | 
| 65 | printf( "\t -offTime               Time of resetting of the Resource counter [format HHMMSS (UTC date) default 210000] \n"); | 
| 66 | exit(1); | 
| 67 | } | 
| 68 |  | 
| 69 | // Ok, here we should have at least one root file.  We check that | 
| 70 | // the filename contains ".root". | 
| 71 | if(strstr(argv[1], ".root")) | 
| 72 | rootFile = new TString(argv[1]); | 
| 73 | else { | 
| 74 | cerr << "OrbitalRate: no root file." << endl << "See --help" << endl; | 
| 75 | exit(EXIT_FAILURE); | 
| 76 | } | 
| 77 |  | 
| 78 | for (int i = 2; i < argc; i++){ | 
| 79 | if (!strcmp(argv[i], "-outDir")){ | 
| 80 | if (++i >= argc){ | 
| 81 | printf( "-outDir needs arguments. \n"); | 
| 82 | printf( "Try '--help' for more information. \n"); | 
| 83 | exit(1); | 
| 84 | } else { | 
| 85 | outDir = argv[i]; | 
| 86 | continue; | 
| 87 | } | 
| 88 | } | 
| 89 |  | 
| 90 | if (!strcmp(argv[i], "-tle")){ | 
| 91 | if (++i >= argc){ | 
| 92 | printf( "-tle needs arguments. \n"); | 
| 93 | printf( "Try '--help' for more information. \n"); | 
| 94 | exit(1); | 
| 95 | } else { | 
| 96 | tleFile = argv[i]; | 
| 97 | continue; | 
| 98 | } | 
| 99 | } | 
| 100 |  | 
| 101 | if (!strcmp(argv[i], "-offTime")){ | 
| 102 | if (++i >= argc){ | 
| 103 | printf( "-offTime needs arguments. \n"); | 
| 104 | printf( "Try '--help' for more information. \n"); | 
| 105 | exit(1); | 
| 106 | } | 
| 107 | else{ | 
| 108 | offTime = atol(argv[i]); | 
| 109 | continue; | 
| 110 | } | 
| 111 | } | 
| 112 |  | 
| 113 | if (!strcmp(argv[i], "-offDate")){ | 
| 114 | if (++i >= argc){ | 
| 115 | printf( "-offDate needs arguments. \n"); | 
| 116 | printf( "Try '--help' for more information. \n"); | 
| 117 | exit(1); | 
| 118 | } | 
| 119 | else{ | 
| 120 | offDate = atol(argv[i]); | 
| 121 | continue; | 
| 122 | } | 
| 123 | } | 
| 124 |  | 
| 125 | } | 
| 126 |  | 
| 127 | Rate(rootFile, outDir, mapFile, tleFile, offDate, offTime); | 
| 128 |  | 
| 129 | } | 
| 130 |  | 
| 131 |  | 
| 132 | void Rate(TString *filename, TString outDirectory = "", TString mapFile = "", TString tleFile = "", int offDate = 20060614, int offTime = 210000) | 
| 133 | { | 
| 134 | // **** Offset to temporarily correct the TDatime bug ****/ | 
| 135 | //  offTime += 10000; | 
| 136 | //********************************************************/ | 
| 137 |  | 
| 138 | McmdScan *mcmdReader = new McmdScan(); | 
| 139 |  | 
| 140 | pamela::McmdEvent      *mcmdev     = 0; | 
| 141 | pamela::McmdRecord     *mcmdrc     = 0; | 
| 142 | pamela::EventHeader    *eh         = 0; | 
| 143 | pamela::PscuHeader     *ph       = 0; | 
| 144 | TArrayC                *mcmddata; | 
| 145 |  | 
| 146 | pamela::RunHeaderEvent *reh = new pamela::RunHeaderEvent; | 
| 147 | pamela::EventHeader    *eH  = new pamela::EventHeader; | 
| 148 |  | 
| 149 | Quaternions *L_QQ_Q_l = new Quaternions(); | 
| 150 | InclinationInfo *Plux     = new InclinationInfo(); | 
| 151 |  | 
| 152 | float timesync = 0, obt_timesync = 0; | 
| 153 |  | 
| 154 | ULong64_t nevents = 0; | 
| 155 | stringstream  oss; | 
| 156 |  | 
| 157 | Long64_t offsetTime = 0; | 
| 158 | Long64_t timeElapsedFromTLE = 0; | 
| 159 | Long64_t deltaTime = 0, oldtimeElapsedFromTLE = 0; | 
| 160 | bool a_second_is_over; | 
| 161 |  | 
| 162 | // Get a char* to "file" from "/dir1/dir2/.../file.root" | 
| 163 | TString basename; | 
| 164 | basename = ((TObjString*) filename->Tokenize('/')->Last())->GetString(); // we get file.root | 
| 165 | basename = ((TObjString*)basename.Tokenize('.')->First())->GetString(); // we get file | 
| 166 |  | 
| 167 | TFile *rootFile = new TFile(*filename); | 
| 168 |  | 
| 169 | if (rootFile->IsZombie()) printf("The %s file does not exist",basename.Data()); | 
| 170 | TString fileName = ((TObjString*)basename.Tokenize('/')->Last())->GetString(); | 
| 171 | TString filePath = basename; | 
| 172 | filePath.ReplaceAll(fileName, ""); | 
| 173 | filePath.ReplaceAll(".root", ""); | 
| 174 |  | 
| 175 | TTree *tr = (TTree*)rootFile->Get("Mcmd"); | 
| 176 | nevents = tr->GetEntries(); | 
| 177 | tr->SetBranchAddress("Mcmd",&mcmdev); | 
| 178 | tr->SetBranchAddress("Header",&eh); | 
| 179 |  | 
| 180 | ULong_t firstime = 99999999;//ph->GetOrbitalTime(); | 
| 181 | UInt_t  firstID  = 65535; | 
| 182 | ULong_t lastime = 0;//ph->GetOrbitalTime(); | 
| 183 | UInt_t lastID = 0; | 
| 184 | for(int ii = 0; ii < nevents; ii++){ | 
| 185 | tr->GetEntry(ii); | 
| 186 | ph = eh->GetPscuHeader(); | 
| 187 | Int_t tmpSize = mcmdev->Records->GetEntries(); | 
| 188 | for (int qq=0; qq < tmpSize; qq++){ | 
| 189 | mcmdrc = (pamela::McmdRecord*)mcmdev->Records->At(qq); | 
| 190 | if (mcmdrc->SeqID <= firstID) firstID = mcmdrc->SeqID; | 
| 191 | if (mcmdrc->SeqID >= lastID)  lastID  = mcmdrc->SeqID; | 
| 192 | if ((int)mcmdrc->ID1 == 226){ | 
| 193 | L_QQ_Q_l->fill(mcmdrc->McmdData); | 
| 194 | if (L_QQ_Q_l->time[0] >= lastime) lastime = L_QQ_Q_l->time[0]; | 
| 195 | if (L_QQ_Q_l->time[0] <= firstime) firstime = L_QQ_Q_l->time[0]; | 
| 196 | } | 
| 197 | }; | 
| 198 | } | 
| 199 |  | 
| 200 | TTree *tp = (TTree*)rootFile->Get("RunHeader"); | 
| 201 | tp->SetBranchAddress("Header", &eH); | 
| 202 | tp->SetBranchAddress("RunHeader", &reh); | 
| 203 | tp->GetEntry(0); | 
| 204 | ph = eH->GetPscuHeader(); | 
| 205 | ULong_t TimeSync = reh->LAST_TIME_SYNC_INFO; | 
| 206 |  | 
| 207 | //Get Orientation information | 
| 208 |  | 
| 209 | TH2F *_L1 = new TH2F("_L1",basename+";OnBoard Time, s; Value of l0",1000,firstime,lastime,1000,-1,1); | 
| 210 | TH2F *_L2 = new TH2F("_L2",basename+";OnBoard Time, s; Value of l1",1000,firstime,lastime,1000,-1,1); | 
| 211 | TH2F *_L3 = new TH2F("_L3",basename+";OnBoard Time, s; Value of l2",1000,firstime,lastime,1000,-1,1); | 
| 212 | TH2F *_L4 = new TH2F("_L4",basename+";OnBoard Time, s; Value of l3",1000,firstime,lastime,1000,-1,1); | 
| 213 |  | 
| 214 | //TH2F *_A1 = new TH2F("_A1",basename,1000,firstime,lastime,1000,-180,180); | 
| 215 | //TH2F *_A2 = new TH2F("_A2",basename,1000,firstime,lastime,1000,-180,180); | 
| 216 | //TH2F *_A3 = new TH2F("_A3",basename,1000,firstime,lastime,1000,-180,180); | 
| 217 |  | 
| 218 | //TH2F *_secID = new TH2F("_secID",basename,1000,firstime,lastime,1000,firstID,lastID); | 
| 219 |  | 
| 220 | TH2F *_Tangazh = new TH2F("Pitch",basename+";OnBoard Time, s;Angel of pith, deg",1000,firstime,lastime,1000,-20,20); | 
| 221 | TH2F *_Ryskanie = new TH2F("Yaw",basename+";OnBoard Time, s;Angel of yaw, deg",1000,firstime,lastime,1000,-100,-80); | 
| 222 | TH2F *_Kren = new TH2F("Roll",basename+";OnBoard Time, s;Angel of roll, deg",1000,firstime,lastime,1000,-50,50); | 
| 223 |  | 
| 224 | // Open the root file. | 
| 225 | rootFile = new TFile(filename->Data()); | 
| 226 | if (rootFile->IsZombie()) { | 
| 227 | printf("The file %s does not exist\n", (filename->Data())); | 
| 228 | exit(EXIT_FAILURE); | 
| 229 | } | 
| 230 |  | 
| 231 | // Look for a timesync in the TFile rootFile.  We also get the obt | 
| 232 | // of the timesync mcmd. | 
| 233 | bool err; | 
| 234 | err = lookforTimesync(rootFile, ×ync, &obt_timesync); | 
| 235 | if(!err) { | 
| 236 | cerr << "Warning!!! No timesync info has been found in the file " | 
| 237 | << filename->Data() << endl; | 
| 238 | exit(EXIT_FAILURE); | 
| 239 | } | 
| 240 |  | 
| 241 | //Get the Julian date of the Resours offset | 
| 242 | TDatime offRes = TDatime(offDate, offTime); | 
| 243 | // Add to the Resours Offset the timesync.  This is now the date at | 
| 244 | // the moment of the timesync. | 
| 245 | ULong_t TH=offRes.Convert(); | 
| 246 | //cout<<"TH= "<<TH/86400<<"\n"; | 
| 247 | offRes.Set(offRes.Convert() + (UInt_t) timesync); | 
| 248 |  | 
| 249 | // Now I need a pointer to a cTle object.  The class misses a | 
| 250 | // constructor without arguments, so we have to give it a dummy TLE. | 
| 251 | string str1 = "RESURS-DK 1"; | 
| 252 | string str2 = "1 29228U 06021A   06170.19643714  .00009962  00000-0  21000-3 0   196"; | 
| 253 | string str3 = "2 29228 069.9363 054.7893 0167576 127.4359 017.0674 15.31839265   604"; | 
| 254 | cTle *tle1 = new cTle(str1, str2, str3); | 
| 255 |  | 
| 256 | // If we have to use a TLE file, call getTle(). | 
| 257 | if (tleFile != "") | 
| 258 | tle1 = getTle(tleFile, offRes); | 
| 259 |  | 
| 260 | cOrbit       orbit(*tle1); | 
| 261 | cEci         eci; | 
| 262 | cCoordGeo    coo; | 
| 263 |  | 
| 264 | // Get the Julian date of the TLE epoch | 
| 265 | string datetime = getTleDatetime(tle1); | 
| 266 | TDatime tledate = TDatime(datetime.c_str()); | 
| 267 |  | 
| 268 |  | 
| 269 | tr = (TTree*)rootFile->Get("Mcmd"); | 
| 270 | nevents = tr->GetEntries(); | 
| 271 | tr->SetBranchAddress("Mcmd", &mcmdev); | 
| 272 | tr->SetBranchAddress("Header", &eh); | 
| 273 |  | 
| 274 | // oss.str(""); | 
| 275 | // oss << basename+".txt"; | 
| 276 |  | 
| 277 | // ofstream outputFile; | 
| 278 | // outputFile.open(oss.str().c_str()); | 
| 279 |  | 
| 280 | Int_t tmpSize; | 
| 281 |  | 
| 282 | for(UInt_t i = 0; i < nevents; i++) //Fill variables from root-ple | 
| 283 | { | 
| 284 | tr->GetEntry(i); | 
| 285 | tmpSize = mcmdev->Records->GetEntries(); | 
| 286 | ph = eh->GetPscuHeader(); | 
| 287 |  | 
| 288 | for (Int_t j3 = 0; j3 < tmpSize; j3++){ | 
| 289 | mcmdrc = (pamela::McmdRecord*)mcmdev->Records->At(j3); | 
| 290 | if ((int)mcmdrc->ID1 == 226){ | 
| 291 | L_QQ_Q_l->fill(mcmdrc->McmdData); | 
| 292 | Plux->QuaternionstoAngle(*L_QQ_Q_l); | 
| 293 | for (Int_t oi = 0; oi < 6; oi++){ | 
| 294 | //if ((Int_t)L_QQ_Q_l->CodeErrQua[oi]==0){ | 
| 295 |  | 
| 296 | _L1->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][0]); | 
| 297 | _L2->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][1]); | 
| 298 | _L3->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][2]); | 
| 299 | _L4->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][3]); | 
| 300 |  | 
| 301 | //outputFile << " " << L_QQ_Q_l->time[oi] << " " << -L_QQ_Q_l->quat[oi][0] << " " << -L_QQ_Q_l->quat[oi][1] << " " << -L_QQ_Q_l->quat[oi][2] << " " << -L_QQ_Q_l->quat[oi][3]; | 
| 302 |  | 
| 303 | //_A1->Fill(L_QQ_Q_l->time[oi],Plux->A11); | 
| 304 | //_A2->Fill(L_QQ_Q_l->time[oi],Plux->A12); | 
| 305 | //_A3->Fill(L_QQ_Q_l->time[oi],Plux->A13); | 
| 306 |  | 
| 307 | //outputFile << " " << Plux->A11 << " " << Plux->A12 << " " << Plux->A13; | 
| 308 |  | 
| 309 | //_secID->Fill(L_QQ_Q_l->time[oi],mcmdrc->SeqID); | 
| 310 |  | 
| 311 | timeElapsedFromTLE = TH - (Long64_t) tledate.Convert()+ L_QQ_Q_l->time[oi]; | 
| 312 | orbit.getPosition(((double) timeElapsedFromTLE)/60., &eci); | 
| 313 | //outputFile<<" "<< eci.getPos().m_z;//eci.getPos().m_x<<" "<<eci.getPos().m_y<<" "<<eci.getPos().m_z<<" "<<eci.getVel().m_x<<" "<<eci.getVel().m_y<<" "<<eci.getVel().m_z; | 
| 314 | Plux->TransAngle(eci.getPos().m_x,eci.getPos().m_y,eci.getPos().m_z,eci.getVel().m_x,eci.getVel().m_y,eci.getVel().m_z,Plux->A11,Plux->A12,Plux->A13,L_QQ_Q_l->quat[oi][0],L_QQ_Q_l->quat[oi][1],L_QQ_Q_l->quat[oi][2],L_QQ_Q_l->quat[oi][3]); | 
| 315 |  | 
| 316 | _Tangazh->Fill(L_QQ_Q_l->time[oi],Plux->Tangazh); | 
| 317 | _Ryskanie->Fill(L_QQ_Q_l->time[oi],Plux->Ryskanie); | 
| 318 | _Kren->Fill(L_QQ_Q_l->time[oi],Plux->Kren); | 
| 319 |  | 
| 320 | //outputFile<<" "<<Plux->Tangazh<<"  "<<Plux->Kren<<" "<<Plux->Ryskanie<<"\n"; | 
| 321 | //} | 
| 322 | } | 
| 323 | } | 
| 324 | } | 
| 325 | } | 
| 326 |  | 
| 327 | //outputFile.close(); | 
| 328 |  | 
| 329 | TCanvas *c1 = new TCanvas("c1","Quaternions",1200,1600); | 
| 330 | //TCanvas *c2 = new TCanvas("c2","Anglees",1200,1600); | 
| 331 | TCanvas *c4 = new TCanvas("c4","AngleesTRK",1200,1600); | 
| 332 |  | 
| 333 | c1->Divide(1,4); | 
| 334 | //c2->Divide(1,3); | 
| 335 | c4->Divide(1,3); | 
| 336 |  | 
| 337 | c1->cd(1); | 
| 338 | _L1->SetMarkerColor(kBlack); | 
| 339 | _L1->Draw(""); | 
| 340 |  | 
| 341 | c1->cd(2); | 
| 342 | _L2->SetMarkerColor(kBlue); | 
| 343 | _L2->Draw(""); | 
| 344 |  | 
| 345 | c1->cd(3); | 
| 346 | _L3->SetMarkerColor(kRed); | 
| 347 | _L3->Draw(""); | 
| 348 |  | 
| 349 | c1->cd(4); | 
| 350 | _L4->SetMarkerColor(kGreen); | 
| 351 | _L4->Draw(""); | 
| 352 |  | 
| 353 | //    c1->cd(5); | 
| 354 | //    _secID->SetMarkerColor(kYellow); | 
| 355 | //    _secID->Draw(""); | 
| 356 | /* | 
| 357 | c2->cd(1); | 
| 358 | _A3->SetMarkerColor(kRed); | 
| 359 | _A3->Draw(""); | 
| 360 |  | 
| 361 | c2->cd(2); | 
| 362 | _A2->SetMarkerColor(kGreen); | 
| 363 | _A2->Draw(""); | 
| 364 |  | 
| 365 | c2->cd(3); | 
| 366 | _A1->SetMarkerColor(13); | 
| 367 | _A1->Draw(""); | 
| 368 | */ | 
| 369 | c4->cd(1); | 
| 370 | _Tangazh->SetMarkerColor(142); | 
| 371 | _Tangazh->Draw(""); | 
| 372 |  | 
| 373 | c4->cd(2); | 
| 374 | _Ryskanie->SetMarkerColor(226); | 
| 375 | _Ryskanie->Draw(""); | 
| 376 |  | 
| 377 | c4->cd(3); | 
| 378 | _Kren->SetMarkerColor(142); | 
| 379 | _Kren->Draw(""); | 
| 380 |  | 
| 381 | oss.str(""); | 
| 382 | oss << outDirectory+basename+"/"+basename << "_Inclinations_Quaternions.png"; | 
| 383 | c1->SaveAs(oss.str().c_str()); | 
| 384 | oss.str(); | 
| 385 |  | 
| 386 | /*    oss.str(""); | 
| 387 | oss << basename<< "_Angles.png"; | 
| 388 | c2->SaveAs(oss.str().c_str()); | 
| 389 | oss.str(); | 
| 390 | */ | 
| 391 | oss.str(""); | 
| 392 | oss <<  outDirectory+basename+"/"+basename << "_Inclinations_Angles.png"; | 
| 393 | c4->SaveAs(oss.str().c_str()); | 
| 394 | oss.str(); | 
| 395 |  | 
| 396 |  | 
| 397 |  | 
| 398 | delete _L1; | 
| 399 | delete _L2; | 
| 400 | delete _L3; | 
| 401 | delete _L4; | 
| 402 |  | 
| 403 | // delete _A1; | 
| 404 | // delete _A2; | 
| 405 | // delete _A3; | 
| 406 |  | 
| 407 | //delete _secID; | 
| 408 |  | 
| 409 | delete _Tangazh; | 
| 410 | delete _Kren; | 
| 411 | delete _Ryskanie; | 
| 412 |  | 
| 413 | rootFile->Close(); | 
| 414 | } | 
| 415 |  | 
| 416 | // Get the TLE from tleFile.  The right TLE is that one with the | 
| 417 | // closest previous date to offRes, that is the date at the time of | 
| 418 | // the first timesync found in the root file. | 
| 419 | // | 
| 420 | // Warning: you must use a tle file obtained by space-track.org | 
| 421 | // querying the database with the RESURS DK-1 id number 29228, | 
| 422 | // selecting the widest timespan, including the satellite name in the | 
| 423 | // results. | 
| 424 | cTle *getTle(TString tleFile, TDatime offRes) | 
| 425 | { | 
| 426 | Float_t tledatefromfile, tledatefromroot; | 
| 427 | fstream tlefile(tleFile.Data(), ios::in); | 
| 428 | vector<cTle*> ctles; | 
| 429 | vector<cTle*>::iterator iter; | 
| 430 |  | 
| 431 |  | 
| 432 | // Build a vector of *cTle | 
| 433 | while(1) { | 
| 434 | cTle *tlef; | 
| 435 | string str1, str2, str3; | 
| 436 |  | 
| 437 | getline(tlefile, str1); | 
| 438 | if(tlefile.eof()) break; | 
| 439 |  | 
| 440 | getline(tlefile, str2); | 
| 441 | if(tlefile.eof()) break; | 
| 442 |  | 
| 443 | getline(tlefile, str3); | 
| 444 | if(tlefile.eof()) break; | 
| 445 |  | 
| 446 | // We now have three good lines for a cTle. | 
| 447 | tlef = new cTle(str1, str2, str3); | 
| 448 | ctles.push_back(tlef); | 
| 449 | } | 
| 450 |  | 
| 451 | // Sort by date | 
| 452 | sort(ctles.begin(), ctles.end(), compTLE); | 
| 453 |  | 
| 454 | tledatefromroot = (offRes.GetYear()-2000)*1e3 + (offRes.Convert() - (TDatime(offRes.GetYear(), 1, 1, 0, 0, 0)).Convert())/ (24.*3600.); | 
| 455 |  | 
| 456 | for(iter = ctles.begin(); iter != ctles.end(); iter++) { | 
| 457 | cTle *tle = *iter; | 
| 458 |  | 
| 459 | tledatefromfile = getTleJulian(tle); | 
| 460 |  | 
| 461 | if(tledatefromroot > tledatefromfile) { | 
| 462 | tlefile.close(); | 
| 463 | cTle *thisTle = tle; | 
| 464 | ctles.clear(); | 
| 465 |  | 
| 466 | return thisTle; | 
| 467 | } | 
| 468 | } | 
| 469 |  | 
| 470 | // File ended withoud founding a TLE with a date after offRes.  We'll use the last aviable date. | 
| 471 | cerr << "Warning: using last available TLE in " << tleFile.Data() << ".  Consider updating your tle file." << endl; | 
| 472 |  | 
| 473 | tlefile.close(); | 
| 474 | cTle *thisTle = ctles[ctles.size()-1]; | 
| 475 | ctles.clear(); | 
| 476 |  | 
| 477 | return thisTle; | 
| 478 | } | 
| 479 |  | 
| 480 |  | 
| 481 | // Return whether the first TLE is older than the second | 
| 482 | bool compTLE (cTle *tle1, cTle *tle2) | 
| 483 | { | 
| 484 | return getTleJulian(tle1) > getTleJulian(tle2); | 
| 485 | } | 
| 486 |  | 
| 487 |  | 
| 488 | // Return the date of the tle using the format (year-2000)*1e3 + | 
| 489 | // julian day.  e.g. 6364.5 is the 31th Dec 2006 12:00:00. | 
| 490 | // It does *not* return a cJulian date. | 
| 491 | float getTleJulian(cTle *tle) { | 
| 492 | return tle->getField(cTle::FLD_EPOCHYEAR)*1e3 + tle->getField(cTle::FLD_EPOCHDAY); | 
| 493 | } | 
| 494 |  | 
| 495 |  | 
| 496 | // Look for a timesync in the TFile rootFile.  Set timesync and | 
| 497 | // obt_timesync.  Returns 1 if timesync is found, 0 otherwise. | 
| 498 | int lookforTimesync(TFile *rootFile, Float_t *timesync, Float_t *obt_timesync) { | 
| 499 | *timesync = -1;  // will be != -1 if found | 
| 500 |  | 
| 501 | ULong64_t             nevents    = 0; | 
| 502 | pamela::McmdRecord     *mcmdrc     = 0; | 
| 503 | pamela::McmdEvent      *mcmdev     = 0; | 
| 504 | TArrayC                *mcmddata; | 
| 505 | TTree *tr = (TTree*) rootFile->Get("Mcmd"); | 
| 506 |  | 
| 507 | tr->SetBranchAddress("Mcmd", &mcmdev); | 
| 508 |  | 
| 509 | nevents = tr->GetEntries(); | 
| 510 |  | 
| 511 | // Looking for a timesync.  We stop at the first one found. | 
| 512 | long int recEntries; | 
| 513 |  | 
| 514 | for(UInt_t i = 0; i < nevents; i++) { | 
| 515 | tr->GetEntry(i); | 
| 516 | recEntries = mcmdev->Records->GetEntries(); | 
| 517 |  | 
| 518 | for(UInt_t j = 0; j < recEntries; j++) { | 
| 519 | mcmdrc = (pamela::McmdRecord*)mcmdev->Records->At(j); | 
| 520 |  | 
| 521 | if ((mcmdrc != 0) && (mcmdrc->ID1 == 0xE0)) //Is it a TimeSync? | 
| 522 | { | 
| 523 | mcmddata = mcmdrc->McmdData; | 
| 524 | *timesync = (((unsigned int)mcmddata->At(0)<<24)&0xFF000000) | 
| 525 | + (((unsigned int)mcmddata->At(1)<<16)&0x00FF0000) | 
| 526 | + (((unsigned int)mcmddata->At(2)<<8)&0x0000FF00) | 
| 527 | + (((unsigned int)mcmddata->At(3))&0x000000FF); | 
| 528 | *obt_timesync = (mcmdrc->MCMD_RECORD_OBT)*(1./1000.); | 
| 529 |  | 
| 530 | goto out;  // a timesync is found | 
| 531 | } | 
| 532 | } | 
| 533 | } | 
| 534 |  | 
| 535 | out: | 
| 536 |  | 
| 537 | if (*timesync == -1) | 
| 538 | return 0; | 
| 539 | else | 
| 540 | return 1; | 
| 541 | } | 
| 542 |  | 
| 543 |  | 
| 544 | // Return a string like YYYY-MM-DD hh:mm:ss, a datetime format. | 
| 545 | string getTleDatetime(cTle *tle) | 
| 546 | { | 
| 547 | int year, mon, day, hh, mm, ss; | 
| 548 | double dom; // day of month (is double!) | 
| 549 | stringstream date; // date in datetime format | 
| 550 |  | 
| 551 | // create a cJulian from the date in tle | 
| 552 | cJulian jdate = cJulian( 2000 + (int) tle->getField(cTle::FLD_EPOCHYEAR), tle->getField(cTle::FLD_EPOCHDAY)); | 
| 553 |  | 
| 554 | // get year, month, day of month | 
| 555 | jdate.getComponent(&year, &mon, &dom); | 
| 556 |  | 
| 557 | // build a datetime YYYY-MM-DD hh:mm:ss | 
| 558 | date.str(""); | 
| 559 | day = (int) floor(dom); | 
| 560 | hh = (int) floor( (dom - day) * 24); | 
| 561 | mm = (int) floor( ((dom - day) * 24 - hh) * 60); | 
| 562 | ss = (int) floor( ((((dom - day) * 24 - hh) * 60 - mm) * 60)); | 
| 563 | //  ms = (int) floor( (((((dom - day) * 24 - hh) * 60 - mm) * 60) - ss) * 1000); | 
| 564 |  | 
| 565 | date << year << "-" << mon << "-" << day << " " << hh << ":" << mm << ":" << ss; | 
| 566 |  | 
| 567 | return date.str(); | 
| 568 | } | 
| 569 |  | 
| 570 | // | 
| 571 | // Solve the overflow for anticoincidence because this counter is | 
| 572 | // stored in 2 bytes so counts from 0 to 65535. | 
| 573 | // | 
| 574 | // counter is the actual value. | 
| 575 | // oldValue is meant to be the previous value of counter. | 
| 576 | // | 
| 577 | // Example: | 
| 578 | // for(...) { | 
| 579 | //   ... | 
| 580 | //   corrected_diff = solve_ac_overflow(oldValueOfTheCounter, actualValue); | 
| 581 | //   ... | 
| 582 | // } | 
| 583 | // | 
| 584 | // | 
| 585 | // Returns the corrected difference between counter and oldValue and | 
| 586 | // set oldValue to the value of counter. | 
| 587 | // Attention: oldValue is a reference. | 
| 588 | Int_t solve_ac_overflow(Int_t& oldValue, Int_t counter) | 
| 589 | { | 
| 590 | Int_t truediff = 0; | 
| 591 |  | 
| 592 | if (counter < oldValue)  // overflow! | 
| 593 | truediff = 0xFFFF - oldValue + counter; | 
| 594 | else | 
| 595 | truediff = counter - oldValue; | 
| 596 |  | 
| 597 | oldValue = counter; | 
| 598 |  | 
| 599 | return truediff; | 
| 600 | } |