/** * SaaaatInc * author Malakhov V. * version 1.0 - 05/02/2007 */ #include "InclinationInfo.h" #include #include #include #include #include "RunHeaderEvent.h" #include #include "sgp4.h" #include "TH2F.h" #include "TFrame.h" #include "TGraph.h" #include "TCanvas.h" #include #include #include #include "TString.h" #include "TObjString.h" #include "TPaletteAxis.h" #include "TROOT.h" #include #include #include #include "OrbitalRate.h" //#include "TMatrixD.h" using namespace std; int main(int argc, char* argv[]){ TString *rootFile = NULL; TString outDir = "./"; TString mapFile = ""; TString tleFile = ""; int offDate = 20060928; //int offDate = 20060614; int offTime = 210000; if (argc < 2){ printf("You have to insert at least the file to analyze and the mapFile \n"); printf("Try '--help' for more information. \n"); exit(1); } if (!strcmp(argv[1], "--help")){ //printf( "Usage: OrbitRate FILE -map mapFile [OPTION] \n"); //printf( "mapFile have to be a mercator map image [gif|jpg|png] \n"); printf( "\t --help Print this help and exit \n"); printf( "\t -tle[File path] Path where to find the tle infos \n"); printf( "\t\tUse the script retrieve_TLE.sh to create the file.\n "); printf( "\t -outDir[path] Path where to put the output without last directory.\n"); printf( "\t -offDate Date of resetting of the Resource counter [format YYMMDD (UTC date) default 20060928] \n"); printf( "\t -offTime Time of resetting of the Resource counter [format HHMMSS (UTC date) default 210000] \n"); exit(1); } // Ok, here we should have at least one root file. We check that // the filename contains ".root". if(strstr(argv[1], ".root")) rootFile = new TString(argv[1]); else { cerr << "OrbitalRate: no root file." << endl << "See --help" << endl; exit(EXIT_FAILURE); } for (int i = 2; i < argc; i++){ if (!strcmp(argv[i], "-outDir")){ if (++i >= argc){ printf( "-outDir needs arguments. \n"); printf( "Try '--help' for more information. \n"); exit(1); } else { outDir = argv[i]; continue; } } if (!strcmp(argv[i], "-tle")){ if (++i >= argc){ printf( "-tle needs arguments. \n"); printf( "Try '--help' for more information. \n"); exit(1); } else { tleFile = argv[i]; continue; } } if (!strcmp(argv[i], "-offTime")){ if (++i >= argc){ printf( "-offTime needs arguments. \n"); printf( "Try '--help' for more information. \n"); exit(1); } else{ offTime = atol(argv[i]); continue; } } if (!strcmp(argv[i], "-offDate")){ if (++i >= argc){ printf( "-offDate needs arguments. \n"); printf( "Try '--help' for more information. \n"); exit(1); } else{ offDate = atol(argv[i]); continue; } } } Rate(rootFile, outDir, mapFile, tleFile, offDate, offTime); } void Rate(TString *filename, TString outDirectory = "", TString mapFile = "", TString tleFile = "", int offDate = 20060614, int offTime = 210000) { // **** Offset to temporarily correct the TDatime bug ****/ // offTime += 10000; //********************************************************/ McmdScan *mcmdReader = new McmdScan(); pamela::McmdEvent *mcmdev = 0; pamela::McmdRecord *mcmdrc = 0; pamela::EventHeader *eh = 0; pamela::PscuHeader *ph = 0; TArrayC *mcmddata; pamela::RunHeaderEvent *reh = new pamela::RunHeaderEvent; pamela::EventHeader *eH = new pamela::EventHeader; Quaternions *L_QQ_Q_l = new Quaternions(); InclinationInfo *Plux = new InclinationInfo(); float timesync = 0, obt_timesync = 0; ULong64_t nevents = 0; stringstream oss; Long64_t offsetTime = 0; Long64_t timeElapsedFromTLE = 0; Long64_t deltaTime = 0, oldtimeElapsedFromTLE = 0; bool a_second_is_over; // Get a char* to "file" from "/dir1/dir2/.../file.root" TString basename; basename = ((TObjString*) filename->Tokenize('/')->Last())->GetString(); // we get file.root basename = ((TObjString*)basename.Tokenize('.')->First())->GetString(); // we get file TFile *rootFile = new TFile(*filename); if (rootFile->IsZombie()) printf("The %s file does not exist",basename.Data()); TString fileName = ((TObjString*)basename.Tokenize('/')->Last())->GetString(); TString filePath = basename; filePath.ReplaceAll(fileName, ""); filePath.ReplaceAll(".root", ""); TTree *tr = (TTree*)rootFile->Get("Mcmd"); nevents = tr->GetEntries(); tr->SetBranchAddress("Mcmd",&mcmdev); tr->SetBranchAddress("Header",&eh); ULong_t firstime = 99999999;//ph->GetOrbitalTime(); UInt_t firstID = 65535; ULong_t lastime = 0;//ph->GetOrbitalTime(); UInt_t lastID = 0; for(int ii = 0; ii < nevents; ii++){ tr->GetEntry(ii); ph = eh->GetPscuHeader(); Int_t tmpSize = mcmdev->Records->GetEntries(); for (int qq=0; qq < tmpSize; qq++){ mcmdrc = (pamela::McmdRecord*)mcmdev->Records->At(qq); if (mcmdrc->SeqID <= firstID) firstID = mcmdrc->SeqID; if (mcmdrc->SeqID >= lastID) lastID = mcmdrc->SeqID; if ((int)mcmdrc->ID1 == 226){ L_QQ_Q_l->fill(mcmdrc->McmdData); if (L_QQ_Q_l->time[0] >= lastime) lastime = L_QQ_Q_l->time[0]; if (L_QQ_Q_l->time[0] <= firstime) firstime = L_QQ_Q_l->time[0]; } }; } TTree *tp = (TTree*)rootFile->Get("RunHeader"); tp->SetBranchAddress("Header", &eH); tp->SetBranchAddress("RunHeader", &reh); tp->GetEntry(0); ph = eH->GetPscuHeader(); ULong_t TimeSync = reh->LAST_TIME_SYNC_INFO; //Get Orientation information TH2F *_L1 = new TH2F("_L1",basename+";OnBoard Time, s; Value of l0",1000,firstime,lastime,1000,-1,1); TH2F *_L2 = new TH2F("_L2",basename+";OnBoard Time, s; Value of l1",1000,firstime,lastime,1000,-1,1); TH2F *_L3 = new TH2F("_L3",basename+";OnBoard Time, s; Value of l2",1000,firstime,lastime,1000,-1,1); TH2F *_L4 = new TH2F("_L4",basename+";OnBoard Time, s; Value of l3",1000,firstime,lastime,1000,-1,1); //TH2F *_A1 = new TH2F("_A1",basename,1000,firstime,lastime,1000,-180,180); //TH2F *_A2 = new TH2F("_A2",basename,1000,firstime,lastime,1000,-180,180); //TH2F *_A3 = new TH2F("_A3",basename,1000,firstime,lastime,1000,-180,180); //TH2F *_secID = new TH2F("_secID",basename,1000,firstime,lastime,1000,firstID,lastID); TH2F *_Tangazh = new TH2F("Pitch",basename+";OnBoard Time, s;Angel of pith, deg",1000,firstime,lastime,1000,-20,20); TH2F *_Ryskanie = new TH2F("Yaw",basename+";OnBoard Time, s;Angel of yaw, deg",1000,firstime,lastime,1000,-100,-80); TH2F *_Kren = new TH2F("Roll",basename+";OnBoard Time, s;Angel of roll, deg",1000,firstime,lastime,1000,-50,50); // Open the root file. rootFile = new TFile(filename->Data()); if (rootFile->IsZombie()) { printf("The file %s does not exist\n", (filename->Data())); exit(EXIT_FAILURE); } // Look for a timesync in the TFile rootFile. We also get the obt // of the timesync mcmd. bool err; err = lookforTimesync(rootFile, ×ync, &obt_timesync); if(!err) { cerr << "Warning!!! No timesync info has been found in the file " << filename->Data() << endl; exit(EXIT_FAILURE); } //Get the Julian date of the Resours offset TDatime offRes = TDatime(offDate, offTime); // Add to the Resours Offset the timesync. This is now the date at // the moment of the timesync. ULong_t TH=offRes.Convert(); //cout<<"TH= "<Get("Mcmd"); nevents = tr->GetEntries(); tr->SetBranchAddress("Mcmd", &mcmdev); tr->SetBranchAddress("Header", &eh); // oss.str(""); // oss << basename+".txt"; // ofstream outputFile; // outputFile.open(oss.str().c_str()); Int_t tmpSize; for(UInt_t i = 0; i < nevents; i++) //Fill variables from root-ple { tr->GetEntry(i); tmpSize = mcmdev->Records->GetEntries(); ph = eh->GetPscuHeader(); for (Int_t j3 = 0; j3 < tmpSize; j3++){ mcmdrc = (pamela::McmdRecord*)mcmdev->Records->At(j3); if ((int)mcmdrc->ID1 == 226){ L_QQ_Q_l->fill(mcmdrc->McmdData); Plux->QuaternionstoAngle(*L_QQ_Q_l); for (Int_t oi = 0; oi < 6; oi++){ //if ((Int_t)L_QQ_Q_l->CodeErrQua[oi]==0){ _L1->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][0]); _L2->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][1]); _L3->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][2]); _L4->Fill(L_QQ_Q_l->time[oi],L_QQ_Q_l->quat[oi][3]); //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]; //_A1->Fill(L_QQ_Q_l->time[oi],Plux->A11); //_A2->Fill(L_QQ_Q_l->time[oi],Plux->A12); //_A3->Fill(L_QQ_Q_l->time[oi],Plux->A13); //outputFile << " " << Plux->A11 << " " << Plux->A12 << " " << Plux->A13; //_secID->Fill(L_QQ_Q_l->time[oi],mcmdrc->SeqID); timeElapsedFromTLE = TH - (Long64_t) tledate.Convert()+ L_QQ_Q_l->time[oi]; orbit.getPosition(((double) timeElapsedFromTLE)/60., &eci); //outputFile<<" "<< eci.getPos().m_z;//eci.getPos().m_x<<" "<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]); _Tangazh->Fill(L_QQ_Q_l->time[oi],Plux->Tangazh); _Ryskanie->Fill(L_QQ_Q_l->time[oi],Plux->Ryskanie); _Kren->Fill(L_QQ_Q_l->time[oi],Plux->Kren); //outputFile<<" "<Tangazh<<" "<Kren<<" "<Ryskanie<<"\n"; //} } } } } //outputFile.close(); TCanvas *c1 = new TCanvas("c1","Quaternions",1200,1600); //TCanvas *c2 = new TCanvas("c2","Anglees",1200,1600); TCanvas *c4 = new TCanvas("c4","AngleesTRK",1200,1600); c1->Divide(1,4); //c2->Divide(1,3); c4->Divide(1,3); c1->cd(1); _L1->SetMarkerColor(kBlack); _L1->Draw(""); c1->cd(2); _L2->SetMarkerColor(kBlue); _L2->Draw(""); c1->cd(3); _L3->SetMarkerColor(kRed); _L3->Draw(""); c1->cd(4); _L4->SetMarkerColor(kGreen); _L4->Draw(""); // c1->cd(5); // _secID->SetMarkerColor(kYellow); // _secID->Draw(""); /* c2->cd(1); _A3->SetMarkerColor(kRed); _A3->Draw(""); c2->cd(2); _A2->SetMarkerColor(kGreen); _A2->Draw(""); c2->cd(3); _A1->SetMarkerColor(13); _A1->Draw(""); */ c4->cd(1); _Tangazh->SetMarkerColor(142); _Tangazh->Draw(""); c4->cd(2); _Ryskanie->SetMarkerColor(226); _Ryskanie->Draw(""); c4->cd(3); _Kren->SetMarkerColor(142); _Kren->Draw(""); oss.str(""); oss << outDirectory+basename+"/"+basename << "_Inclinations_Quaternions.png"; c1->SaveAs(oss.str().c_str()); oss.str(); /* oss.str(""); oss << basename<< "_Angles.png"; c2->SaveAs(oss.str().c_str()); oss.str(); */ oss.str(""); oss << outDirectory+basename+"/"+basename << "_Inclinations_Angles.png"; c4->SaveAs(oss.str().c_str()); oss.str(); delete _L1; delete _L2; delete _L3; delete _L4; // delete _A1; // delete _A2; // delete _A3; //delete _secID; delete _Tangazh; delete _Kren; delete _Ryskanie; rootFile->Close(); } // Get the TLE from tleFile. The right TLE is that one with the // closest previous date to offRes, that is the date at the time of // the first timesync found in the root file. // // Warning: you must use a tle file obtained by space-track.org // querying the database with the RESURS DK-1 id number 29228, // selecting the widest timespan, including the satellite name in the // results. cTle *getTle(TString tleFile, TDatime offRes) { Float_t tledatefromfile, tledatefromroot; fstream tlefile(tleFile.Data(), ios::in); vector ctles; vector::iterator iter; // Build a vector of *cTle while(1) { cTle *tlef; string str1, str2, str3; getline(tlefile, str1); if(tlefile.eof()) break; getline(tlefile, str2); if(tlefile.eof()) break; getline(tlefile, str3); if(tlefile.eof()) break; // We now have three good lines for a cTle. tlef = new cTle(str1, str2, str3); ctles.push_back(tlef); } // Sort by date sort(ctles.begin(), ctles.end(), compTLE); tledatefromroot = (offRes.GetYear()-2000)*1e3 + (offRes.Convert() - (TDatime(offRes.GetYear(), 1, 1, 0, 0, 0)).Convert())/ (24.*3600.); for(iter = ctles.begin(); iter != ctles.end(); iter++) { cTle *tle = *iter; tledatefromfile = getTleJulian(tle); if(tledatefromroot > tledatefromfile) { tlefile.close(); cTle *thisTle = tle; ctles.clear(); return thisTle; } } // File ended withoud founding a TLE with a date after offRes. We'll use the last aviable date. cerr << "Warning: using last available TLE in " << tleFile.Data() << ". Consider updating your tle file." << endl; tlefile.close(); cTle *thisTle = ctles[ctles.size()-1]; ctles.clear(); return thisTle; } // Return whether the first TLE is older than the second bool compTLE (cTle *tle1, cTle *tle2) { return getTleJulian(tle1) > getTleJulian(tle2); } // Return the date of the tle using the format (year-2000)*1e3 + // julian day. e.g. 6364.5 is the 31th Dec 2006 12:00:00. // It does *not* return a cJulian date. float getTleJulian(cTle *tle) { return tle->getField(cTle::FLD_EPOCHYEAR)*1e3 + tle->getField(cTle::FLD_EPOCHDAY); } // Look for a timesync in the TFile rootFile. Set timesync and // obt_timesync. Returns 1 if timesync is found, 0 otherwise. int lookforTimesync(TFile *rootFile, Float_t *timesync, Float_t *obt_timesync) { *timesync = -1; // will be != -1 if found ULong64_t nevents = 0; pamela::McmdRecord *mcmdrc = 0; pamela::McmdEvent *mcmdev = 0; TArrayC *mcmddata; TTree *tr = (TTree*) rootFile->Get("Mcmd"); tr->SetBranchAddress("Mcmd", &mcmdev); nevents = tr->GetEntries(); // Looking for a timesync. We stop at the first one found. long int recEntries; for(UInt_t i = 0; i < nevents; i++) { tr->GetEntry(i); recEntries = mcmdev->Records->GetEntries(); for(UInt_t j = 0; j < recEntries; j++) { mcmdrc = (pamela::McmdRecord*)mcmdev->Records->At(j); if ((mcmdrc != 0) && (mcmdrc->ID1 == 0xE0)) //Is it a TimeSync? { mcmddata = mcmdrc->McmdData; *timesync = (((unsigned int)mcmddata->At(0)<<24)&0xFF000000) + (((unsigned int)mcmddata->At(1)<<16)&0x00FF0000) + (((unsigned int)mcmddata->At(2)<<8)&0x0000FF00) + (((unsigned int)mcmddata->At(3))&0x000000FF); *obt_timesync = (mcmdrc->MCMD_RECORD_OBT)*(1./1000.); goto out; // a timesync is found } } } out: if (*timesync == -1) return 0; else return 1; } // Return a string like YYYY-MM-DD hh:mm:ss, a datetime format. string getTleDatetime(cTle *tle) { int year, mon, day, hh, mm, ss; double dom; // day of month (is double!) stringstream date; // date in datetime format // create a cJulian from the date in tle cJulian jdate = cJulian( 2000 + (int) tle->getField(cTle::FLD_EPOCHYEAR), tle->getField(cTle::FLD_EPOCHDAY)); // get year, month, day of month jdate.getComponent(&year, &mon, &dom); // build a datetime YYYY-MM-DD hh:mm:ss date.str(""); day = (int) floor(dom); hh = (int) floor( (dom - day) * 24); mm = (int) floor( ((dom - day) * 24 - hh) * 60); ss = (int) floor( ((((dom - day) * 24 - hh) * 60 - mm) * 60)); // ms = (int) floor( (((((dom - day) * 24 - hh) * 60 - mm) * 60) - ss) * 1000); date << year << "-" << mon << "-" << day << " " << hh << ":" << mm << ":" << ss; return date.str(); } // // Solve the overflow for anticoincidence because this counter is // stored in 2 bytes so counts from 0 to 65535. // // counter is the actual value. // oldValue is meant to be the previous value of counter. // // Example: // for(...) { // ... // corrected_diff = solve_ac_overflow(oldValueOfTheCounter, actualValue); // ... // } // // // Returns the corrected difference between counter and oldValue and // set oldValue to the value of counter. // Attention: oldValue is a reference. Int_t solve_ac_overflow(Int_t& oldValue, Int_t counter) { Int_t truediff = 0; if (counter < oldValue) // overflow! truediff = 0xFFFF - oldValue + counter; else truediff = counter - oldValue; oldValue = counter; return truediff; }