/[PAMELA software]/quicklook/OrbitalRate/src/OrbitalRate.cpp
ViewVC logotype

Annotation of /quicklook/OrbitalRate/src/OrbitalRate.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (hide annotations) (download)
Sun Nov 4 16:01:37 2007 UTC (17 years, 1 month ago) by pam-rm2
Branch: MAIN
CVS Tags: v2r02, HEAD
Changes since 1.8: +11 -4 lines
isUTC is kFALSE instead of kTRUE in TTimeStamp::Set().  I dont know why.

1 pam-rm2 1.1 /**
2     * OrbitalRate
3     * author Nagni
4     * version 1.0 - 27 April 2006
5     *
6     * version 2.0
7     * author De Simone
8     * - most of the code rewritten
9     * - added graphs, magnetic field, new overflow resolution (AC), tle
10     * stuff.
11     *
12     */
13     #include <physics/anticounter/AnticounterEvent.h>
14     #include <physics/trigger/TriggerEvent.h>
15     #include <physics/neutronDetector/NeutronEvent.h>
16     #include "physics/neutronDetector/NeutronRecord.h"
17     #include <mcmd/McmdEvent.h>
18     #include <mcmd/McmdRecord.h>
19     #include <EventHeader.h>
20     #include <PscuHeader.h>
21     #include <TTree.h>
22     #include "sgp4.h"
23     #include "TH2F.h"
24     #include "TFrame.h"
25     #include "TGraph.h"
26     #include "TCanvas.h"
27     #include "TASImage.h"
28     #include <TDatime.h>
29     #include <TFile.h>
30    
31     #include <TTimeStamp.h>
32     #include "TString.h"
33     #include "TObjString.h"
34     #include "TStyle.h"
35     #include "TPaletteAxis.h"
36     #include "TROOT.h"
37     #include <sys/stat.h>
38     #include <fstream>
39     #include <iostream>
40    
41     #include <OrbitalRate.h>
42    
43     using namespace std;
44    
45     int main(int argc, char* argv[]){
46     TString *rootFile = NULL;
47     TString outDir = "./";
48     TString mapFile = "";
49     TString tleFile = "";
50     int offDate = 20060928;
51     // int offDate = 20060614;
52     int offTime = 210000;
53 pam-rm2 1.6 bool field = false;
54 pam-rm2 1.1
55     if (argc < 2){
56     printf("You have to insert at least the file to analyze and the mapFile \n");
57     printf("Try '--help' for more information. \n");
58     exit(1);
59     }
60    
61     if (!strcmp(argv[1], "--help")){
62     printf( "Usage: OrbitRate FILE -map mapFile [OPTION] \n");
63     printf( "mapFile have to be a mercator map image [gif|jpg|png] \n");
64     printf( "\t --help Print this help and exit \n");
65     printf( "\t -tle[File path] Path where to find the tle infos \n");
66     printf( "\t\tUse the script retrieve_TLE.sh to create the file.\n ");
67     printf( "\t -outDir[path] Path where to put the output.\n");
68     printf( "\t -offDate Date of resetting of the Resource counter [format YYMMDD (UTC date) default 20060928] \n");
69     printf( "\t -offTime Time of resetting of the Resource counter [format HHMMSS (UTC date) default 210000] \n");
70 pam-rm2 1.6 printf( "\t -field Produce maps of the magnetic field \n");
71 pam-rm2 1.1 exit(1);
72     }
73    
74     // Ok, here we should have at least one root file. We check that
75     // the filename contains ".root".
76     if(strstr(argv[1], ".root"))
77     rootFile = new TString(argv[1]);
78     else {
79     cerr << "OrbitalRate: no root file." << endl << "See --help" << endl;
80     exit(EXIT_FAILURE);
81     }
82    
83     for (int i = 2; i < argc; i++){
84 pam-rm2 1.6 if (!strcmp(argv[i], "-field")){
85     field = true;
86     i++;
87     continue;
88     }
89    
90 pam-rm2 1.1 if (!strcmp(argv[i], "-outDir")){
91     if (++i >= argc){
92     printf( "-outDir needs arguments. \n");
93     printf( "Try '--help' for more information. \n");
94     exit(1);
95     } else {
96     outDir = argv[i];
97     continue;
98     }
99     }
100    
101     if (!strcmp(argv[i], "-tle")){
102     if (++i >= argc){
103     printf( "-tle needs arguments. \n");
104     printf( "Try '--help' for more information. \n");
105     exit(1);
106     } else {
107     tleFile = argv[i];
108     continue;
109     }
110     }
111    
112     if (!strcmp(argv[i], "-offTime")){
113     if (++i >= argc){
114     printf( "-offTime needs arguments. \n");
115     printf( "Try '--help' for more information. \n");
116     exit(1);
117     }
118     else{
119     offTime = atol(argv[i]);
120     continue;
121     }
122     }
123    
124     if (!strcmp(argv[i], "-offDate")){
125     if (++i >= argc){
126     printf( "-offDate needs arguments. \n");
127     printf( "Try '--help' for more information. \n");
128     exit(1);
129     }
130     else{
131     offDate = atol(argv[i]);
132     continue;
133     }
134     }
135    
136     if (!strcmp(argv[i], "-map")){
137     if (++i >= argc){
138     printf( "-map needs arguments. \n");
139     printf( "Try '--help' for more information. \n");
140     exit(1);
141     } else {
142     mapFile = argv[i];
143     continue;
144     }
145     }
146     }
147    
148     if (mapFile != ""){
149 pam-rm2 1.6 Rate(rootFile, outDir, mapFile, tleFile, offDate, offTime, field);
150 pam-rm2 1.1 } else {
151     printf("You have to insert at least the file to analyze and the mapFile \n");
152     printf("Try '--help' for more information. \n");
153     }
154     }
155    
156    
157     void InitStyle() {
158     gROOT->SetStyle("Plain");
159    
160     TStyle *myStyle[2], *tempo;
161     myStyle[0]=new TStyle("StyleWhite", "white");
162     myStyle[1]=new TStyle("StyleBlack", "black");
163    
164     tempo=gStyle;
165     Int_t linecol, bkgndcol, histcol;
166    
167     for(Int_t style=0; style<2; style++) {
168    
169     linecol=kWhite*style+kBlack*(1-style);
170     bkgndcol=kBlack*style+kWhite*(1-style);
171     histcol=kYellow*style+kBlack*(1-style); // was 95
172    
173     myStyle[style]->Copy(*tempo);
174    
175     myStyle[style]->SetCanvasBorderMode(0);
176     myStyle[style]->SetCanvasBorderSize(1);
177     myStyle[style]->SetFrameBorderSize(1);
178     myStyle[style]->SetFrameBorderMode(0);
179     myStyle[style]->SetPadBorderSize(1);
180     myStyle[style]->SetStatBorderSize(1);
181     myStyle[style]->SetTitleBorderSize(1);
182     myStyle[style]->SetPadBorderMode(0);
183     myStyle[style]->SetPalette(1,0);
184     myStyle[style]->SetPaperSize(20,27);
185     myStyle[style]->SetFuncColor(kRed);
186     myStyle[style]->SetFuncWidth(1);
187     myStyle[style]->SetLineScalePS(1);
188     myStyle[style]->SetCanvasColor(bkgndcol);
189     myStyle[style]->SetAxisColor(linecol,"XYZ");
190     myStyle[style]->SetFrameFillColor(bkgndcol);
191     myStyle[style]->SetFrameLineColor(linecol);
192     myStyle[style]->SetLabelColor(linecol,"XYZ");
193     myStyle[style]->SetPadColor(bkgndcol);
194     myStyle[style]->SetStatColor(bkgndcol);
195     myStyle[style]->SetStatTextColor(linecol);
196     myStyle[style]->SetTitleColor(linecol,"XYZ");
197     myStyle[style]->SetTitleFillColor(bkgndcol);
198     myStyle[style]->SetTitleTextColor(linecol);
199     myStyle[style]->SetLineColor(linecol);
200     myStyle[style]->SetMarkerColor(histcol);
201     myStyle[style]->SetTextColor(linecol);
202    
203     myStyle[style]->SetGridColor((style)?13:kBlack);
204     myStyle[style]->SetHistFillStyle(1001*(1-style));
205     myStyle[style]->SetHistLineColor(histcol);
206     myStyle[style]->SetHistFillColor((style)?bkgndcol:kYellow);
207    
208     myStyle[style]->SetOptStat(0); // Remove statistic summary
209     }
210    
211     myStyle[1]->cd();
212    
213     gROOT->ForceStyle();
214    
215     }
216    
217    
218 pam-rm2 1.6 void Rate(TString *filename, TString outDirectory = "", TString mapFile = "", TString tleFile = "", int offDate = 20060614, int offTime = 210000, bool field = false)
219 pam-rm2 1.1 {
220     // **** Offset to temporarily correct the TDatime bug ****/
221 pam-rm2 1.5 // offTime += 10000;
222 pam-rm2 1.1 //********************************************************/
223    
224     TTree *tr = 0;
225     TFile *rootFile;
226     FILE *f;
227    
228     pamela::McmdEvent *mcmdev = 0;
229     pamela::McmdRecord *mcmdrc = 0;
230     pamela::EventHeader *eh = 0;
231     pamela::PscuHeader *ph = 0;
232     TArrayC *mcmddata;
233     ULong64_t nevents = 0;
234     stringstream oss;
235    
236     Float_t timesync = 0, obt_timesync = 0;
237     Long64_t offsetTime = 0;
238     Long64_t timeElapsedFromTLE = 0;
239     Long64_t deltaTime = 0, oldtimeElapsedFromTLE = 0;
240     bool a_second_is_over;
241    
242     Float_t lon, lat, alt;
243    
244     vector<Double_t> vector_trigAndOr;
245     vector<Double_t> vector_trigAndAnd;
246     vector<Double_t> vector_trigS11andS12;
247     vector<Double_t> vector_trigS12andS21andS22;
248     vector<Double_t> vector_trigS111A;
249    
250     double mean_trigAndOr;
251     double mean_trigAndAnd;
252     double mean_trigS11andS12;
253     double mean_trigS12andS21andS22;
254     double mean_trigS111A;
255    
256     // We'll use this size for the generated images.
257     TImage *tImage=TImage::Open(mapFile);
258     int width=(int)(tImage->GetWidth()*0.80);
259     int height=(int)(tImage->GetHeight()*0.80);
260     delete tImage;
261    
262     // This histogram will store time (in seconds) spent in each bin.
263     TH2F *obtBinTime = new TH2F("obtBinTime", "Time of acquisition of background data", 360, -180, 180, 180, -90, 90);
264    
265     // Now I create histograms longitude x latitude to hold values. I
266     // use the suffix _counter to say that this values are what I read
267     // from Pamela and they are not normalized in any way.
268    
269     // This historam will store the number of events occurred in each bin.
270     TH2F *event_counter = new TH2F("event_counter", "Event rate", 360, -180, 180, 180, -90, 90);
271     TH2F *nd_counter = new TH2F("nd_counter", "Upper background neutrons", 360, -180, 180, 180, -90, 90);
272     TH2F *antiCAS4_counter = new TH2F("CAS4_counter", "CAS4 rate", 360, -180, 180, 180, -90, 90);
273     TH2F *antiCAS3_counter = new TH2F("CAS3_counter", "CAS3 rate", 360, -180, 180, 180, -90, 90);
274     TH2F *trigAndOr_counter = new TH2F("trigAndOr_counter", "Rate of triggering in (S11+S12)*(S21+S22)*(S31+S32) configuration", 360, -180, 180, 180, -90, 90);
275     TH2F *trigAndAnd_counter = new TH2F("trigAndAnd_counter", "Rate of triggering in (S11*S12)*(S21*S22)*(S31*S32) configuration", 360, -180, 180, 180, -90, 90);
276     TH2F *trigS11andS12_counter = new TH2F("trigS11andS12_counter", "Rate of S1 triggers", 360, -180, 180, 180, -90, 90); //(S11+S12)
277     TH2F *trigS12andS21andS22_counter = new TH2F("trigS12andS21andS22_counter", "Rate of S11*S21*S21 triggers", 360, -180, 180, 180, -90, 90); //(S11*S12*S21)
278     TH2F *trigS111A_counter = new TH2F("trigS111A_counter", "Rate of S111A counts", 360, -180, 180, 180, -90, 90); //(S111A)
279    
280     // Magnetic field histograms. I use always the suffix _counter
281     // because they are not normalized. Imagine that an instrument
282     // give us the value of the magnetic field for each event.
283 pam-rm2 1.6 TH2F *hbabs_counter;
284     TH2F *hbnorth_counter;
285     TH2F *hbdown_counter;
286     TH2F *hbeast_counter;
287     TH2F *hb0_counter;
288     TH2F *hl_counter;
289    
290     if(field) {
291     hbabs_counter = new TH2F("hbabs_counter", "B module", 360, -180, 180, 180, -90, 90);
292     hbnorth_counter = new TH2F("hbnorth_counter", "B north", 360, -180, 180, 180, -90, 90);
293     hbdown_counter = new TH2F("hbdown_counter", "B down", 360, -180, 180, 180, -90, 90);
294     hbeast_counter = new TH2F("hbeast_counter", "B east", 360, -180, 180, 180, -90, 90);
295     hb0_counter = new TH2F("hb0_counter", "B_0", 360, -180, 180, 180, -90, 90);
296     hl_counter = new TH2F("hl_counter", "l", 360, -180, 180, 180, -90, 90);
297     }
298 pam-rm2 1.1
299     // Get a char* to "file" from "/dir1/dir2/.../file.root"
300     TString basename;
301     basename = ((TObjString*) filename->Tokenize('/')->Last())->GetString(); // we get file.root
302     basename = ((TObjString*)basename.Tokenize('.')->First())->GetString(); // we get file
303    
304     // Exit if the map file doesn't exist.
305     if(! (f = fopen(mapFile.Data(), "r")) ) {
306     cerr << "Error: the file " << mapFile.Data() << " does not exists." << endl;
307     exit(EXIT_FAILURE);
308     }
309    
310     // Open the root file.
311     rootFile = new TFile(filename->Data());
312     if (rootFile->IsZombie()) {
313     printf("The file %s does not exist\n", (filename->Data()));
314     exit(EXIT_FAILURE);
315     }
316    
317     // Look for a timesync in the TFile rootFile. We also get the obt
318     // of the timesync mcmd.
319     bool err;
320     err = lookforTimesync(rootFile, &timesync, &obt_timesync);
321     if(!err) {
322     cerr << "Warning!!! No timesync info has been found in the file "
323     << filename->Data() << endl;
324     exit(EXIT_FAILURE);
325     }
326    
327 pam-rm2 1.8 // Here I do: resurs offset + timesync
328 pam-rm2 1.1 TDatime offRes = TDatime(offDate, offTime);
329 pam-rm2 1.8 TTimeStamp offResTS = TTimeStamp(offRes.GetYear(), offRes.GetMonth(), offRes.GetDay(), offRes.GetHour(), offRes.GetMinute(), offRes.GetSecond(), 0, kTRUE, timesync);
330 pam-rm2 1.9 // cout<<"timesync="<<timesync<<" obt_timesync="<<obt_timesync<<endl;
331     // cout<<"offResTS.GetSec()="<<offResTS.GetSec()<<endl;
332     // cout<<"offResTS.AsString()="<<offResTS.AsString()<<endl<<endl;
333 pam-rm2 1.1
334     // Now I need a pointer to a cTle object. The class misses a
335     // constructor without arguments, so we have to give it a dummy TLE.
336     string str1 = "RESURS-DK 1";
337     string str2 = "1 29228U 06021A 06170.19643714 .00009962 00000-0 21000-3 0 196";
338     string str3 = "2 29228 069.9363 054.7893 0167576 127.4359 017.0674 15.31839265 604";
339     cTle *tle1 = new cTle(str1, str2, str3);
340    
341     // If we have to use a TLE file, call getTle().
342     if (tleFile != "")
343 pam-rm2 1.8 tle1 = getTle(tleFile, offResTS); // modify getTle() to use offResTS!
344     else
345     cout<<"OrbitalRate: Warning!!! No tle file supplied.\n";
346    
347     // Here I do: resurs offset + timesync - obt of the timesync
348 pam-rm2 1.9 // cout<<"here0 "<<offResTS.GetSec()<<endl;
349     // offResTS.Set(offResTS.GetSec() - obt_timesync, kTRUE, 0, kFALSE);
350     offResTS.Set(offResTS.GetSec() - obt_timesync, kFALSE, 0, kFALSE);
351     // cout<<"here1 "<<offResTS.GetSec()<<endl;
352 pam-rm2 1.1
353     cOrbit orbit(*tle1);
354     cEci eci;
355     cCoordGeo coo;
356    
357 pam-rm2 1.8 // Here I do: resurs offset + timesync - obt of the timesync - tle time
358     TTimeStamp tledate = getTleDatetime(tle1);
359 pam-rm2 1.1 cJulian jdatetime = cJulian((int) (tle1->getField(cTle::FLD_EPOCHYEAR)+2e3), tle1->getField(cTle::FLD_EPOCHDAY));
360     int pYear, pMon; double pDOM;
361     jdatetime.getComponent(&pYear, &pMon, &pDOM);
362 pam-rm2 1.8 offsetTime = ((Long64_t) offResTS.GetSec() - (Long64_t) tledate.GetSec());
363 pam-rm2 1.9 // cerr<<"offsetTime="<<offsetTime<<endl
364     // <<"offResTS.GetSec()="<<offResTS.GetSec()<<endl
365     // <<"tledate.GetSec()="<<tledate.GetSec()<<endl<<endl;
366 pam-rm2 1.1
367     /********** Magnetic Field **************/
368     // Check that all this is correct!
369 pam-rm2 1.4 float br, btheta, bphi;
370 pam-rm2 1.1
371     // I can now compute the magnetic dipole moment at the actual date,
372     // using the cJulian date. I don't to recompute it for every event
373     // beacause changes are not relevant at all.
374 pam-rm2 1.8 UInt_t y, m, d;
375     tledate.GetDate(kTRUE, 0, &y, &m, &d);
376 pam-rm2 1.1 float year = (float) y + (m*31+d)/365;
377    
378 pam-rm2 1.4 // Initialize common data for geopack
379 pam-rm2 1.6 if(field)
380     recalc_(y, m*31+d, 0, 0, 0);
381 pam-rm2 1.1 /********** Magnetic Field **************/
382    
383     tr = (TTree*)rootFile->Get("Physics");
384     TBranch *headBr = tr->GetBranch("Header");
385     tr->SetBranchAddress("Header", &eh);
386    
387     /********** Anticounter **************/
388     pamela::anticounter::AnticounterEvent *antiev = 0;
389     tr->SetBranchAddress("Anticounter", &antiev);
390    
391     Int_t oldCAS4 = 0;
392     Int_t diffCAS4 = 0;
393     Int_t oldCAS3 = 0;
394     Int_t diffCAS3 = 0;
395     /********** Anticounter **************/
396    
397     /********** Trigger **************/
398     pamela::trigger::TriggerEvent *trigger = 0;
399     tr->SetBranchAddress("Trigger", &trigger);
400    
401     Int_t oldtrigAndOr = 0;
402     Int_t oldtrigAndAnd = 0;
403     Int_t oldtrigS11andS12 = 0;
404     Int_t oldtrigS12andS21andS22 = 0;
405     Int_t oldtrigS111A = 0;
406     /********** Trigger **************/
407    
408     /********** ND **************/
409     Int_t tmpSize=0;
410     Int_t sumTrig=0;
411     Int_t sumUpperBackground=0;
412     Int_t sumBottomBackground=0;
413    
414     pamela::neutron::NeutronRecord *nr = 0;
415     pamela::neutron::NeutronEvent *ne = 0;
416     tr->SetBranchAddress("Neutron", &ne);
417     /********** ND **************/
418    
419     nevents = tr->GetEntries();
420    
421     for(UInt_t i = 0; i < nevents; i++) //Fill variables from root-ple
422     {
423     tr->GetEntry(i);
424     ph = eh->GetPscuHeader();
425    
426     // obt in ms
427 pam-rm2 1.6 UInt_t obt = (UInt_t) ph->GetOrbitalTime();
428 pam-rm2 1.1
429     // timeElapsedFromTLE is the difference, in seconds, between the
430     // event and the tle date. I use seconds and not milliseconds
431     // because the indetermination on the timesync is about 1s.
432     timeElapsedFromTLE = offsetTime + obt/1000;
433 pam-rm2 1.9 if(!i) cerr<<"1st event: timeElapsedFromTLE="<<timeElapsedFromTLE<<endl;
434 pam-rm2 1.1
435     // I also need the abstime in seconds rounded to the lower
436     // value. Every second, we set a_second_is_over to true. Only
437     // in this case histograms with triggers are filled.
438     a_second_is_over = (timeElapsedFromTLE > oldtimeElapsedFromTLE) ? 1 : 0;
439     oldtimeElapsedFromTLE = timeElapsedFromTLE;
440    
441     // I need the acquisition time between two triggers to fill the
442     // obtBinTime (histo of time spent in the bin). The time is in
443     // second.
444     deltaTime = timeElapsedFromTLE - oldtimeElapsedFromTLE;
445     oldtimeElapsedFromTLE = timeElapsedFromTLE;
446    
447     // Finally, we get coordinates from absolute time the orbit
448     // object initialised with the TLE data. cOrbit::getPosition()
449     // requires the elapased time from the tle in minutes.
450     // Coordinates are stored in the structure eci.
451     orbit.getPosition(((double) timeElapsedFromTLE)/60., &eci);
452     coo = eci.toGeo();
453    
454     /********** ND **************/
455     // Summing over all stored pamela::neutron::NeutronRecords in
456     // this event *ne.
457     for(Int_t j = 0; j < ne->Records->GetEntries(); j++) {
458     nr = (pamela::neutron::NeutronRecord*)ne->Records->At(j);
459     sumTrig += (int)nr->trigPhysics;
460     sumUpperBackground += (int)nr->upperBack;
461     sumBottomBackground += (int)nr->bottomBack;
462     }
463     /********** ND **************/
464    
465     /********** Anticounter **************/
466     // Get the difference between the actual counter and the
467     // previous counter for anticoincidence, dealing with the
468     // overflow with solve_ac_overflow().
469     diffCAS4 = solve_ac_overflow(oldCAS4, antiev->counters[0][6]);
470     diffCAS3 = solve_ac_overflow(oldCAS3, antiev->counters[0][10]);
471     /********** Anticounter **************/
472    
473     // Build coordinates in the right range. We want to convert,
474     // just for aesthetic, longitude from (0, 2*pi) to (-pi, pi).
475     // We also want to convert from radians to degrees.
476     lon = (coo.m_Lon > PI) ? rad2deg(coo.m_Lon - 2*PI) : rad2deg(coo.m_Lon);
477     lat = rad2deg(coo.m_Lat);
478     alt = coo.m_Alt;
479    
480     /********** Magnetic Field **************/
481 pam-rm2 1.6 if(field)
482     igrf_geo__((coo.m_Alt+6371.2)/6371.2, M_PI/2.-coo.m_Lat, coo.m_Lon, br, btheta, bphi);
483 pam-rm2 1.4 // cout<<"("<<(coo.m_Alt+6371.2)/6371.2<<", "<<M_PI/2.-coo.m_Lat<<", "<<coo.m_Lon<<")"<<endl;
484 pam-rm2 1.1 /********** Magnetic Field **************/
485    
486     // serve fare il controllo deltatime < 1?
487     if (deltaTime > 1) cout << endl << "******** deltaTime<1 ********" << endl;
488     // Does nothing for the first two events or if acquisition time if more
489     // than 1s.
490 pam-rm2 1.3 if(i<1 || (deltaTime > 1)) continue;
491 pam-rm2 1.1
492     // CAS3 and CAS4 are not rates but only counters. So I fill
493     // with the bin with the difference beetween the actual counter
494     // and the previous one and then divide with the time (see
495     // below) to have rates.
496     if(diffCAS3>1e3) // additional cut to avoid the peaks after dead time
497     diffCAS3 = (Int_t) antiCAS3_counter->GetBinContent((Int_t)antiCAS3_counter->GetEntries()-1);
498     antiCAS3_counter->Fill(lon , lat, diffCAS3);
499    
500     if(diffCAS4>1e3) // additional cut to avoid the peaks after dead time
501     diffCAS4 = (Int_t) antiCAS4_counter->GetBinContent((Int_t) antiCAS4_counter->GetEntries()-1);
502     antiCAS4_counter->Fill(lon, lat, diffCAS4);
503    
504     // Magnetic field values should be handled a bit carefully.
505     // For every event I get a position and the related magnetic
506     // field values. I can fill the histograms lon x lat with
507     // this values but I need to count how many times I fill
508     // each bin. This is done by the histogram event_counter.
509     // I will normalize later.
510 pam-rm2 1.6 if(field) {
511     hbabs_counter->Fill(lon, lat, sqrt(br*br+btheta*btheta+bphi*bphi)*1e-5);
512     hbnorth_counter->Fill(lon, lat, -btheta*1e-5);
513     hbdown_counter->Fill(lon, lat, -br*1e-5);
514     hbeast_counter->Fill(lon, lat, bphi*1e-5);
515     }
516 pam-rm2 1.1 // This histograms is now filled with the number of entries.
517     // Below we will divide with the time (in seconds) to get
518     // event rate per bin.
519     event_counter->Fill(lon, lat);
520    
521     // counters about triggers are already rates (Hz). Only
522     // every second we fill fill with the mean over all values.
523     if(a_second_is_over) {
524     // This histograms will hold the time, in seconds, spent
525     // in the bin.
526     obtBinTime->Fill(lon, lat, 1);
527    
528     // get the means
529     mean_trigAndOr = getMean(vector_trigAndOr);
530     mean_trigAndAnd = getMean(vector_trigAndAnd);
531     mean_trigS11andS12 = getMean(vector_trigS11andS12);
532     mean_trigS12andS21andS22 = getMean(vector_trigS12andS21andS22);
533     mean_trigS111A = getMean(vector_trigS111A);
534    
535     // clear data about the last second
536     vector_trigAndOr.clear();
537     vector_trigAndAnd.clear();
538     vector_trigS11andS12.clear();
539     vector_trigS12andS21andS22.clear();
540     vector_trigS111A.clear();
541    
542     // Fill with the mean rate value
543     trigAndOr_counter->Fill(lon , lat, mean_trigAndOr);
544     trigAndAnd_counter->Fill(lon , lat, mean_trigAndAnd);
545     trigS11andS12_counter->Fill(lon , lat, mean_trigS11andS12);
546     trigS12andS21andS22_counter->Fill(lon , lat, mean_trigS12andS21andS22);
547     trigS111A_counter->Fill(lon, lat, mean_trigS111A);
548     }
549     else { // Collect values for all the second
550     vector_trigAndOr.push_back((1/4.)*trigger->trigrate[0]);
551     vector_trigAndAnd.push_back((1/4.)*trigger->trigrate[1]);
552     // pmtpl[0] is the rate every 60ms but I want Hz.
553     vector_trigS11andS12.push_back((1000./60.)*trigger->pmtpl[0]);
554     vector_trigS12andS21andS22.push_back((1/4.)*trigger->trigrate[4]);
555     vector_trigS111A.push_back(1.*trigger->pmtcount1[0]);
556     }
557    
558     // Now we discard ND data if:
559     // - NeutronEvent is corrupted.
560     if((ne->unpackError != 1))
561     nd_counter->Fill(lon, lat, 1.*(sumUpperBackground+sumTrig));
562    
563     // Reset counters for ND.
564     sumTrig = 0;
565     sumUpperBackground = 0;
566     sumBottomBackground = 0;
567     }
568    
569     // We now need to normalize the histograms to print something
570     // meaningful. I create similar histograms with the suffix _rate or
571     // _norm.
572     TH2F *event_rate = (TH2F*) event_counter->Clone("event_rate");
573     TH2F *trigS111A_rate = (TH2F*) trigS111A_counter->Clone("trigS111A_rate");
574     TH2F *antiCAS4_rate = (TH2F*) antiCAS4_counter->Clone("antiCAS4_rate");
575     TH2F *antiCAS3_rate = (TH2F*) antiCAS3_counter->Clone("antiCAS3_rate");
576     TH2F *trigS11andS12_rate = (TH2F*) trigS11andS12_counter->Clone("trigS11andS12_rate");
577     TH2F *trigS12andS21andS22_rate = (TH2F*) trigS12andS21andS22_counter->Clone("trigS12andS21andS22_rate");
578     TH2F *trigAndOr_rate = (TH2F*) trigAndOr_counter->Clone("trigAndOr_rate");
579     TH2F *trigAndAnd_rate = (TH2F*) trigAndAnd_counter->Clone("trigAndAnd_rate");
580     TH2F *nd_rate = (TH2F*) nd_counter->Clone("nd_rate");
581 pam-rm2 1.6
582     TH2F *hbabs_norm;
583     TH2F *hbnorth_norm;
584     TH2F *hbdown_norm;
585     TH2F *hbeast_norm;
586    
587     if(field) {
588     hbabs_norm = (TH2F*) hbabs_counter->Clone("hbabs_norm");
589     hbnorth_norm = (TH2F*) hbnorth_counter->Clone("hbnorth_norm");
590     hbdown_norm = (TH2F*) hbabs_counter->Clone("hbdown_norm");
591     hbeast_norm = (TH2F*) hbabs_counter->Clone("hbeast_norm");
592     }
593 pam-rm2 1.1
594     // Now we divide each histogram _counter with the time histogram
595     // obtBinTime to have an histogram _rate. Note that, when a second
596     // is passed in the above cycle, we fill the histogram obtBinTime
597     // with 1 (second) together with all the other histograms. So
598     // dividing here does make sense.
599     //
600     // Then we call printHist() for each filled TH2F. These are
601     // refered to the root file we're now reading. We also build up a
602     // filename to be passed to the function. Pay attention that the
603     // filename must end with a file format (such as .png or .pdf)
604     // recognised by TPad::SaveAs().
605     trigS111A_rate->Divide(trigS111A_counter, obtBinTime, 1, 1, "");
606     oss.str("");
607     oss << basename.Data() << "_orbit_trigS111A.png";
608 pam-rm2 1.3 trigS111A_rate->SetMinimum(9);
609 pam-rm2 1.1 printHist(trigS111A_rate, mapFile, outDirectory, oss.str().c_str(), "S111A (Hz)", -width, height, true, 0);
610    
611     antiCAS4_rate->Divide(antiCAS4_counter, obtBinTime, 1, 1, "");
612     oss.str("");
613     oss << basename.Data() << "_orbit_CAS4.png";
614 pam-rm2 1.3 antiCAS4_rate->SetMinimum(99);
615 pam-rm2 1.1 printHist(antiCAS4_rate, mapFile, outDirectory, oss.str().c_str(), "CAS4 (Hz)", -width, height, true, 0);
616    
617     antiCAS3_rate->Divide(antiCAS3_counter, obtBinTime, 1, 1, "");
618     oss.str("");
619     oss << basename.Data() << "_orbit_CAS3.png";
620 pam-rm2 1.3 antiCAS3_rate->SetMinimum(99);
621 pam-rm2 1.1 printHist(antiCAS3_rate, mapFile, outDirectory, oss.str().c_str(), "CAS3 (Hz)", -width, height, true, 0);
622    
623     event_rate->Divide(event_counter, obtBinTime, 1, 1, "");
624     oss.str("");
625     oss << basename.Data() << "_orbit_EventRate.png";
626     printHist(event_rate, mapFile, outDirectory, oss.str().c_str(), "Event rate (Hz)", -width, height, 0, 0);
627    
628     trigS11andS12_rate->Divide(trigS11andS12_counter, obtBinTime, 1, 1, "");
629     oss.str("");
630     oss << basename.Data() << "_orbit_trigS11andS12.png";
631 pam-rm2 1.3 trigS11andS12_rate->SetMinimum(99);
632 pam-rm2 1.1 printHist(trigS11andS12_rate, mapFile, outDirectory, oss.str().c_str(), "(S11*S12) (Hz)", -width, height, 1, 0);
633    
634     trigS12andS21andS22_rate->Divide(trigS12andS21andS22_counter, obtBinTime, 1, 1, "");
635     oss.str("");
636     oss << basename.Data() << "_orbit_trigS12andS21andS22.png";
637 pam-rm2 1.3 trigS12andS21andS22_rate->SetMinimum(9);
638 pam-rm2 1.1 printHist(trigS12andS21andS22_rate, mapFile, outDirectory, oss.str().c_str(), "(S12*S12*S21) (Hz)", -width, height, true, 0);
639    
640     trigAndOr_rate->Divide(trigAndOr_counter, obtBinTime, 1, 1, "");
641     oss.str("");
642     oss << basename.Data() << "_orbit_trigANDofOR.png";
643     printHist(trigAndOr_rate, mapFile, outDirectory, oss.str().c_str(), "(S11+S12)*(S21+S22)*(S31+S32) (Hz)", -width, height, 0, 0);
644    
645     trigAndAnd_rate->Divide(trigAndAnd_counter, obtBinTime, 1, 1, "");
646     oss.str("");
647     oss << basename.Data() << "_orbit_trigANDofAND.png";
648     printHist(trigAndAnd_rate, mapFile, outDirectory, oss.str().c_str(), "(S11*S12)*(S21*S22)*(S31*S32) (Hz)", -width, height, 0, 0);
649    
650     nd_rate->Divide(nd_counter, obtBinTime, 1, 1, "");
651     oss.str("");
652     oss << basename.Data() << "_orbit_ND.png";
653     printHist(nd_rate, mapFile, outDirectory, oss.str().c_str(), "Neutron rate (Hz)", -width, height, 0, 0);
654    
655     // Also normalize histograms about magnetic fields. Beacause we
656     // fill the bins with the values of the magnetic field for each
657     // event, we need to divide with the number of fills done, that is
658     // event_counter.
659 pam-rm2 1.6 if(field) {
660     hbabs_norm->Divide(hbabs_counter, event_counter, 1, 1, "");
661     oss.str("");
662     oss << basename.Data() << "_orbit_Babs.png";
663     printHist(hbabs_norm, mapFile, outDirectory, oss.str().c_str(), "B abs (G)", -width, height, 0, 0);
664    
665     hbnorth_norm->Divide(hbnorth_counter, event_counter, 1, 1, "");
666     oss.str("");
667     oss << basename.Data() << "_orbit_Bnorth.png";
668     printHist(hbnorth_norm, mapFile, outDirectory, oss.str().c_str(), "B north (G)", -width, height, 0, 1);
669    
670     hbdown_norm->Divide(hbdown_counter, event_counter, 1, 1, "");
671     oss.str("");
672     oss << basename.Data() << "_orbit_Bdown.png";
673     printHist(hbdown_norm, mapFile, outDirectory, oss.str().c_str(), "B down (G)", -width, height, 0, 1);
674    
675     hbeast_norm->Divide(hbeast_counter, event_counter, 1, 1, "");
676     oss.str("");
677     oss << basename.Data() << "_orbit_Beast.png";
678     printHist(hbeast_norm, mapFile, outDirectory, oss.str().c_str(), "B east (G)", -width, height, 0, 1);
679     }
680 pam-rm2 1.1
681     delete obtBinTime;
682     delete event_counter;
683    
684     delete nd_counter;
685     delete antiCAS4_counter;
686     delete antiCAS3_counter;
687     delete trigAndOr_counter;
688     delete trigAndAnd_counter;
689     delete trigS11andS12_counter;
690     delete trigS111A_counter;
691     delete trigS12andS21andS22_counter;
692    
693     delete event_rate;
694     delete nd_rate;
695     delete antiCAS4_rate;
696     delete antiCAS3_rate;
697     delete trigAndOr_rate;
698     delete trigAndAnd_rate;
699     delete trigS11andS12_rate;
700     delete trigS111A_rate;
701     delete trigS12andS21andS22_rate;
702    
703 pam-rm2 1.6 if(field) {
704     delete hbabs_counter;
705     delete hbnorth_counter;
706     delete hbdown_counter;
707     delete hbeast_counter;
708     delete hbabs_norm;
709     delete hbnorth_norm;
710     delete hbdown_norm;
711     delete hbeast_norm;
712     }
713 pam-rm2 1.1
714     rootFile->Close();
715     }
716    
717    
718     // Print the istogram *h on the file outputfilename in the direcotry
719     // outDirectory, using mapFile as background image, sizing the image
720     // width per height. Log scale will be used if use_log is true.
721     //
722     // If bool_shift is true a further process is performed to solve a
723     // problem with actual root version (5.12). This should be used when
724     // the histrogram is filled also with negative values, because root
725     // draws zero filled bins (so I have all the pad colorized and this is
726     // really weird!). To avoid this problem I shift all the values in a
727     // positive range and draw again using colz. Now I will not have zero
728     // filled bins painted but the scale will be wrong. This is why I
729     // need to draw a new axis along the palette.
730     //
731     // Pay attention: you cannot use a mapFile different from the provided
732     // one without adjusting the scaling and position of the image (see
733     // Scale() and Merge()).
734     //
735     // This function depends on InitStyle();
736 pam-rm2 1.8 int printHist(TH2F *h, TString mapFile, TString outDirectory, TString outputFilename, const char *title, int width, int height, bool use_log, bool bool_shift)
737 pam-rm2 1.1 {
738     InitStyle();
739    
740     // Create a canvas and draw the TH2F with a nice colormap for z
741     // values, using log scale for z values, if requested, and setting
742     // some title.
743 pam-rm2 1.3 TCanvas *canvas = new TCanvas("h", "h histogram", width*2, height*2);
744 pam-rm2 1.1
745 pam-rm2 1.3 if(use_log) canvas->SetLogz();
746 pam-rm2 1.1
747     h->SetTitle(title);
748     h->SetXTitle("Longitude (deg)");
749     h->SetYTitle("Latitude (deg)");
750     h->SetLabelColor(0, "X");
751     h->SetAxisColor(0, "X");
752     h->SetLabelColor(0, "Y");
753     h->SetAxisColor(0, "Y");
754     h->SetLabelColor(0, "Z");
755     h->SetAxisColor(0, "Z");
756    
757     h->Draw("colz");
758     canvas->Update(); // Update! Otherwise we can't get any palette.
759    
760     // If shift in a positive range required (see comment above).
761     if(bool_shift) {
762     // Remember the minimum and maximum in this graph.
763     Float_t min = h->GetMinimum();
764     Float_t max = h->GetMaximum();
765    
766     // Shift the graph up by 100. Increase the value if you still get
767     // negative filled bins.
768     h = shiftHist(h, 100.0);
769     h->SetMinimum(min+100.0);
770     h->SetMaximum(max+100.0);
771    
772     // Hide the current axis of the palette
773     TPaletteAxis *palette = (TPaletteAxis*) h->GetListOfFunctions()->FindObject("palette");
774     if(!palette) cout << "palette is null" << endl;
775     TGaxis *ax = (TGaxis*) palette->GetAxis();
776     if(!ax) cout << "ax is null" << endl;
777     ax->SetLabelOffset(999);
778     ax->SetTickSize(0);
779    
780     // Create a new axis of the palette using the right min and max and draw it.
781     TGaxis *gaxis = new TGaxis(palette->GetX2(), palette->GetY1(), palette->GetX2(), palette->GetY2(), min, max, 510,"+L");
782     gaxis->SetLabelColor(0);
783     gaxis->Draw();
784    
785     // Update again.
786     canvas->Update();
787     }
788    
789     // We merge two images: the image of the earth read from a file on
790     // that one of the TPad of canvas (the histogram). The first one is
791     // scaled and adjusted to fit well inside the frame of the second
792     // one. Finally we draw them both.
793     //
794     // Here there's a trick to avoid blurring during the merging
795     // operation. We get the image from a canvas sized (width*2 x
796     // height*2) and draw it on a canvas sized (width x height).
797    
798     TCanvas *mergeCanvas = new TCanvas("", "", width, height);
799     TImage *img = TImage::Create();
800     TImage *terra = TImage::Create();
801     img->FromPad(canvas); // get the TCanvas canvas as TImage
802     terra->ReadImage(mapFile, TImage::kPng); // get the png file as TImage
803     terra->Scale(1304,830);
804     img->Merge(terra, "add", 166, 112); // add image terra to image img
805     img->Draw("X"); // see what we get, eXpanding img all over mergeCanvas.
806    
807     stringstream oss;
808     oss << outDirectory.Data() << "/" << outputFilename.Data();
809    
810     mergeCanvas->SaveAs(oss.str().c_str());
811     mergeCanvas->Close();
812     canvas->Close();
813    
814     return EXIT_SUCCESS;
815     }
816    
817     void saveHist(TH1 *h, TString savetorootfile)
818     {
819     TFile *file = new TFile(savetorootfile.Data(), "update");
820    
821     h->Write();
822     file->Close();
823     }
824    
825    
826     // Get the TLE from tleFile. The right TLE is that one with the
827     // closest previous date to offRes, that is the date at the time of
828     // the first timesync found in the root file.
829     //
830     // Warning: you must use a tle file obtained by space-track.org
831     // querying the database with the RESURS DK-1 id number 29228,
832     // selecting the widest timespan, including the satellite name in the
833     // results.
834 pam-rm2 1.8 cTle *getTle(TString tleFile, TTimeStamp offResTS)
835 pam-rm2 1.1 {
836     Float_t tledatefromfile, tledatefromroot;
837     fstream tlefile(tleFile.Data(), ios::in);
838     vector<cTle*> ctles;
839     vector<cTle*>::iterator iter;
840    
841    
842     // Build a vector of *cTle
843     while(1) {
844     cTle *tlef;
845     string str1, str2, str3;
846    
847     getline(tlefile, str1);
848     if(tlefile.eof()) break;
849    
850     getline(tlefile, str2);
851     if(tlefile.eof()) break;
852    
853     getline(tlefile, str3);
854     if(tlefile.eof()) break;
855    
856     // We now have three good lines for a cTle.
857     tlef = new cTle(str1, str2, str3);
858     ctles.push_back(tlef);
859     }
860    
861     // Sort by date
862     sort(ctles.begin(), ctles.end(), compTLE);
863    
864 pam-rm2 1.8 UInt_t year, month, day;
865     offResTS.GetDate(kTRUE, 0, &year, &month, &day);
866     TTimeStamp firstofjan = TTimeStamp(year, 1, 1, 0, 0, 0);
867     tledatefromroot = (year-2000)*1e3 + (offResTS.GetSec() - firstofjan.GetSec())/(24.*3600.);
868 pam-rm2 1.1
869     for(iter = ctles.begin(); iter != ctles.end(); iter++) {
870     cTle *tle = *iter;
871    
872     tledatefromfile = getTleJulian(tle);
873    
874     if(tledatefromroot > tledatefromfile) {
875     tlefile.close();
876     cTle *thisTle = tle;
877     ctles.clear();
878    
879     return thisTle;
880     }
881     }
882    
883     // File ended withoud founding a TLE with a date after offRes. We'll use the last aviable date.
884     cerr << "Warning: using last available TLE in " << tleFile.Data() << ". Consider updating your tle file." << endl;
885    
886     tlefile.close();
887     cTle *thisTle = ctles[ctles.size()-1];
888     ctles.clear();
889    
890     return thisTle;
891     }
892    
893    
894     // Return whether the first TLE is older than the second
895     bool compTLE (cTle *tle1, cTle *tle2)
896     {
897     return getTleJulian(tle1) > getTleJulian(tle2);
898     }
899    
900    
901     // Return the date of the tle using the format (year-2000)*1e3 +
902     // julian day. e.g. 6364.5 is the 31th Dec 2006 12:00:00.
903     // It does *not* return a cJulian date.
904     float getTleJulian(cTle *tle) {
905     return tle->getField(cTle::FLD_EPOCHYEAR)*1e3 + tle->getField(cTle::FLD_EPOCHDAY);
906     }
907    
908    
909     // Look for a timesync in the TFile rootFile. Set timesync and
910     // obt_timesync. Returns 1 if timesync is found, 0 otherwise.
911 pam-rm2 1.7 UInt_t lookforTimesync(TFile *rootFile, Float_t *timesync, Float_t *obt_timesync) {
912 pam-rm2 1.1 *timesync = -1; // will be != -1 if found
913    
914     ULong64_t nevents = 0;
915     pamela::McmdRecord *mcmdrc = 0;
916     pamela::McmdEvent *mcmdev = 0;
917     TArrayC *mcmddata;
918     TTree *tr = (TTree*) rootFile->Get("Mcmd");
919    
920     tr->SetBranchAddress("Mcmd", &mcmdev);
921    
922     nevents = tr->GetEntries();
923    
924     // Looking for a timesync. We stop at the first one found.
925     long int recEntries;
926    
927     for(UInt_t i = 0; i < nevents; i++) {
928     tr->GetEntry(i);
929     recEntries = mcmdev->Records->GetEntries();
930    
931     for(UInt_t j = 0; j < recEntries; j++) {
932     mcmdrc = (pamela::McmdRecord*)mcmdev->Records->At(j);
933    
934     if ((mcmdrc != 0) && (mcmdrc->ID1 == 0xE0)) //Is it a TimeSync?
935     {
936     mcmddata = mcmdrc->McmdData;
937     *timesync = (((unsigned int)mcmddata->At(0)<<24)&0xFF000000)
938     + (((unsigned int)mcmddata->At(1)<<16)&0x00FF0000)
939     + (((unsigned int)mcmddata->At(2)<<8)&0x0000FF00)
940     + (((unsigned int)mcmddata->At(3))&0x000000FF);
941     *obt_timesync = (mcmdrc->MCMD_RECORD_OBT)*(1./1000.);
942    
943     goto out; // a timesync is found
944     }
945     }
946     }
947    
948     out:
949    
950     if (*timesync == -1)
951     return 0;
952     else
953     return 1;
954     }
955    
956    
957     // Returns the mean value of the elements stored in the vector v.
958     double getMean(vector<Double_t> v)
959     {
960     double mean = 0;
961    
962     for(int i=0; i < v.size(); i++)
963     mean += v.at(i);
964    
965     return mean/v.size();
966     }
967    
968    
969     // Shift all non zero bins by shift.
970     TH2F* shiftHist(TH2F* h, Float_t shift)
971     {
972     // Global bin number.
973     Int_t nBins = h->GetBin(h->GetNbinsX(), h->GetNbinsY());
974    
975     for(int i = 0; i < nBins; i++)
976     if(h->GetBinContent(i)) h->AddBinContent(i, shift);
977    
978     return h;
979     }
980    
981    
982 pam-rm2 1.8 //
983     // Returns the tle date as a TTimeStamp object.
984     //
985     TTimeStamp getTleDatetime(cTle *tle)
986 pam-rm2 1.1 {
987     int year, mon, day, hh, mm, ss;
988     double dom; // day of month (is double!)
989     stringstream date; // date in datetime format
990    
991     // create a cJulian from the date in tle
992     cJulian jdate = cJulian( 2000 + (int) tle->getField(cTle::FLD_EPOCHYEAR), tle->getField(cTle::FLD_EPOCHDAY));
993    
994     // get year, month, day of month
995     jdate.getComponent(&year, &mon, &dom);
996    
997     // build a datetime YYYY-MM-DD hh:mm:ss
998     date.str("");
999     day = (int) floor(dom);
1000     hh = (int) floor( (dom - day) * 24);
1001     mm = (int) floor( ((dom - day) * 24 - hh) * 60);
1002     ss = (int) floor( ((((dom - day) * 24 - hh) * 60 - mm) * 60));
1003     // ms = (int) floor( (((((dom - day) * 24 - hh) * 60 - mm) * 60) - ss) * 1000);
1004    
1005 pam-rm2 1.8 TTimeStamp t = TTimeStamp(year, mon, day, hh, mm, ss, 0, true);
1006 pam-rm2 1.1
1007 pam-rm2 1.8 return t;
1008 pam-rm2 1.1 }
1009    
1010     //
1011     // Solve the overflow for anticoincidence because this counter is
1012     // stored in 2 bytes so counts from 0 to 65535.
1013     //
1014     // counter is the actual value.
1015     // oldValue is meant to be the previous value of counter.
1016     //
1017     // Example:
1018     // for(...) {
1019     // ...
1020     // corrected_diff = solve_ac_overflow(oldValueOfTheCounter, actualValue);
1021     // ...
1022     // }
1023     //
1024     //
1025     // Returns the corrected difference between counter and oldValue and
1026     // set oldValue to the value of counter.
1027     // Attention: oldValue is a reference.
1028     Int_t solve_ac_overflow(Int_t& oldValue, Int_t counter)
1029     {
1030     Int_t truediff = 0;
1031    
1032     if (counter < oldValue) // overflow!
1033     truediff = 0xFFFF - oldValue + counter;
1034     else
1035     truediff = counter - oldValue;
1036    
1037     oldValue = counter;
1038    
1039     return truediff;
1040     }

  ViewVC Help
Powered by ViewVC 1.1.23