1616#include <TCanvas.h>
1717#include <TFile.h>
1818#include <TH2F.h>
19- #include <TH1F.h>
2019#include <TNtuple.h>
2120#include <TString.h>
2221#include <TTree.h>
2322#include <TLine.h>
2423#include <TStyle.h>
2524
26- #include <set>
27-
28- #include "IOTOFBase/Segmentation.h"
25+ #include "IOTOFSimulation/Segmentation.h"
2926#include "IOTOFBase/IOTOFBaseParam.h"
3027#include "IOTOFBase/GeometryTGeo.h"
31- #include "IOTOFSimulation/Digitizer.h"
3228#include "DataFormatsIOTOF/Digit.h"
3329#include "ITSMFTSimulation/Hit.h"
3430#include "MathUtils/Utils.h"
3531#include "SimulationDataFormat/ConstMCTruthContainer.h"
3632#include "SimulationDataFormat/IOMCTruthContainerView.h"
3733#include "SimulationDataFormat/MCCompLabel.h"
38- #include "SimulationDataFormat/MCTrack.h"
39- #include "SimulationDataFormat/TrackReference.h"
4034#include "DetectorsBase/GeometryManager.h"
4135#include "CCDB/BasicCCDBManager.h"
4236
@@ -81,11 +75,7 @@ void addTLines(float pitch)
8175 gPad -> Update ();
8276}
8377
84- void CheckDigitsIOTOF (std ::string digifile = "tf3digits.root" ,
85- std ::string hitfile = "o2sim_HitsTF3.root" ,
86- std ::string kinefile = "o2sim_Kine.root" ,
87- std ::string inputGeom = "o2sim_geometry.root" ,
88- std ::string geomCfgStr = "IOTOFBase.segmentedInnerTOF=true;IOTOFBase.segmentedOuterTOF=true;IOTOFBase.enableForwardTOF=false;IOTOFBase.enableBackwardTOF=false;" )
78+ void CheckDigitsIOTOF (std ::string digifile = "tf3digits.root" , std ::string hitfile = "o2sim_HitsTF3.root" , std ::string inputGeom = "o2sim_geometry.root" )
8979{
9080 gStyle -> SetPalette (55 );
9181
@@ -95,7 +85,7 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
9585 using o2 ::iotof ::Digit ;
9686 using o2 ::itsmft ::Hit ;
9787
98- o2 ::conf ::ConfigurableParam ::updateFromString (geomCfgStr );
88+ o2 ::conf ::ConfigurableParam ::updateFromString ("IOTOFBase.segmentedInnerTOF=true;IOTOFBase.segmentedOuterTOF=true;IOTOFBase.enableForwardTOF=false;IOTOFBase.enableBackwardTOF=false" );
9989
10090 auto seg = o2 ::iotof ::Segmentation ::Instance ();
10191
@@ -133,48 +123,15 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
133123
134124 digTree -> GetEntry (0 );
135125
136- // MC tracks
137- TFile * kineFile = TFile ::Open (kinefile .data ());
138- TTree * kineTree = (TTree * )kineFile -> Get ("o2sim" );
139- std ::vector < std ::vector < o2 ::MCTrack > * > mcTracksPerEvent (nevH , nullptr );
140- std ::vector < std ::vector < o2 ::TrackReference > * > mcTracksRefsPerEvent (nevH , nullptr );
141- kineTree -> SetBranchAddress ("MCTrack" , & mcTracksPerEvent [0 ]);
142- kineTree -> SetBranchAddress ("TrackRefs" , & mcTracksRefsPerEvent [0 ]);
143-
144- TH1F * hGenHitsEta [2 ][2 ] = {{
145- new TH1F ("hGenHitsEtaPrmL0" , "hGenHitsEtaPrmL0" , 40 , -2 , 2 ),
146- new TH1F ("hGenHitsEtaSecL0" , "hGenHitsEtaSecL0" , 40 , -2 , 2 ),
147- }, {
148- new TH1F ("hGenHitsEtaPrmL1" , "hGenHitsEtaPrmL1" , 40 , -2 , 2 ),
149- new TH1F ("hGenHitsEtaSecL1" , "hGenHitsEtaSecL1" , 40 , -2 , 2 ),
150- }};
151-
152126 // Load all MC hit events upfront and build the hit lookup map.
153127 for (int im = 0 ; im < nevH ; ++ im ) {
154128 hitTree -> SetBranchAddress ("TF3Hit" , & hitArray [im ]);
155129 hitTree -> GetEntry (im );
156- kineTree -> SetBranchAddress ("MCTrack" , & mcTracksPerEvent [im ]);
157- kineTree -> SetBranchAddress ("TrackRefs" , & mcTracksRefsPerEvent [im ]);
158- kineTree -> GetEntry (im );
159130 auto& mc2hit = mc2hitVec [im ];
160131 for (int ih = hitArray [im ]-> size (); ih -- ;) {
161132 const auto& hit = (* hitArray [im ])[ih ];
162133 uint64_t key = (uint64_t (hit .GetTrackID ()) << 32 ) + hit .GetDetectorID ();
163134 mc2hit .emplace (key , ih );
164-
165- auto & mcTrack = mcTracksPerEvent [im ]-> at (hit .GetTrackID ());
166- bool isPrimary = mcTrack .isPrimary ();
167-
168- int layer = gman -> getIOTOFLayer (hit .GetDetectorID ());
169- if (layer == 0 && isPrimary ) {
170- hGenHitsEta [0 ][0 ]-> Fill (mcTrack .GetEta ());
171- } else if (layer == 0 && !isPrimary ) {
172- hGenHitsEta [0 ][1 ]-> Fill (mcTrack .GetEta ());
173- } else if (layer == 1 && isPrimary ) {
174- hGenHitsEta [1 ][0 ]-> Fill (mcTrack .GetEta ());
175- } else if (layer == 1 && !isPrimary ) {
176- hGenHitsEta [1 ][1 ]-> Fill (mcTrack .GetEta ());
177- }
178135 }
179136 }
180137
@@ -185,21 +142,11 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
185142 plabelsArr -> copyandflatten (labels );
186143
187144 // LOOP on : ROFRecord array
188- TH1F * hRecoDigitEta [2 ][2 ] = {{
189- new TH1F ("hRecoDigitEtaPrmL0" , "hRecoDigitEtaPrmL0" , 40 , -2 , 2 ),
190- new TH1F ("hRecoDigitEtaSecL0" , "hRecoDigitEtaSecL0" , 40 , -2 , 2 ),
191- }, {
192- new TH1F ("hRecoDigitEtaPrmL1" , "hRecoDigitEtaPrmL1" , 40 , -2 , 2 ),
193- new TH1F ("hRecoDigitEtaSecL1" , "hRecoDigitEtaSecL1" , 40 , -2 , 2 ),
194- }};
195-
196- std ::unordered_map < uint64_t , std ::vector < int >> hitDigitMap ;
197145 for (unsigned int iROF = 0 ; iROF < rofArr .size (); ++ iROF ) {
198146
199147 const unsigned int rofIndex = rofArr [iROF ].getFirstEntry ();
200148 const unsigned int rofNEntries = rofArr [iROF ].getNEntries ();
201149
202- std ::unordered_map < int , std ::set < uint64_t >> tracksWithDigits ;
203150 // LOOP on : digits array
204151 for (unsigned int iDigit = rofIndex ; iDigit < rofIndex + rofNEntries ; iDigit ++ ) {
205152 if (iDigit % 1000 == 0 ) {
@@ -229,11 +176,10 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
229176 }
230177
231178 int trID = lab .getTrackID ();
232- int evtID = lab .getEventID ();
233179
234180 const auto gloD = gman -> getMatrixL2G (chipID )(locD ); // convert to global
235181
236- std ::unordered_map < uint64_t , int > * mc2hit = & mc2hitVec [evtID ];
182+ std ::unordered_map < uint64_t , int > * mc2hit = & mc2hitVec [lab . getEventID () ];
237183
238184 // get MC info
239185 uint64_t key = (uint64_t (trID ) << 32 ) + chipID ;
@@ -245,7 +191,7 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
245191 }
246192
247193 ////// HITS
248- Hit & hit = (* hitArray [evtID ])[hitEntry -> second ];
194+ Hit & hit = (* hitArray [lab . getEventID () ])[hitEntry -> second ];
249195
250196 auto xyzLocE = gman -> getMatrixL2G (chipID ) ^ (hit .GetPos ()); // inverse conversion from global to local
251197 auto xyzLocS = gman -> getMatrixL2G (chipID ) ^ (hit .GetPosStart ());
@@ -274,21 +220,6 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
274220 locH .X () - locD .X (), locH .Z () - locD .Z ()); /// difference in x and z between the hit and the digit in the local frame
275221 nt2 -> Fill (chipID , gloD .Z (), locHS .X () - locHE .X (), locHS .Z () - locHE .Z ()); /// differences between local hit start and hit end positions
276222
277- // Check if key is already in the set of tracks with digits,
278- // else we double count digits in efficiency calculation
279- // when using stepping
280- if (tracksWithDigits [evtID ].find (key ) == tracksWithDigits [evtID ].end ()) {
281- tracksWithDigits [evtID ].insert (key );
282- int digitLayer = gman -> getIOTOFLayer (chipID );
283- auto& mcTrack = mcTracksPerEvent [evtID ]-> at (trID );
284- bool isPrimary = mcTrack .isPrimary ();
285- hRecoDigitEta [digitLayer ][isPrimary ? 0 : 1 ]-> Fill (mcTrack .GetEta ());
286- }
287-
288- // Fill the hitDigitMap for later analysis
289- // Hit key from event ID and hit index
290- uint64_t hitKey = (uint64_t (evtID ) << 32 ) + hitEntry -> second ;
291- hitDigitMap [hitKey ].push_back (iDigit );
292223 } // end loop on digits array
293224
294225 } // end loop on ROFRecords
@@ -319,13 +250,13 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
319250 auto canvdXdZ = new TCanvas ("canvdXdZ" , "" , 1600 , 800 );
320251 canvdXdZ -> Divide (2 , 1 );
321252 canvdXdZ -> cd (1 );
322- nt -> Draw ("dx:dz>>h_dx_vs_dz_ITOF(1000 , -0.05 , 0.05, 1000 , -0.05 , 0.05 )" , "id >= 0 && id < 1920" , "colz" );
253+ nt -> Draw ("dx:dz>>h_dx_vs_dz_ITOF(600 , -0.03 , 0.03, 600 , -0.03 , 0.03 )" , "id >= 0 && id < 1920" , "colz" );
323254 addTLines (0.01 );
324255 auto h = (TH2F * )gPad -> GetPrimitive ("h_dx_vs_dz_ITOF" );
325256 Info ("ITOF" , "RMS(dx)=%.1f mu" , h -> GetRMS (2 ) * 1e4 );
326257 Info ("ITOF" , "RMS(dz)=%.1f mu" , h -> GetRMS (1 ) * 1e4 );
327258 canvdXdZ -> cd (2 );
328- nt -> Draw ("dx:dz>>h_dx_vs_dz_OTOF(1000 , -0.05 , 0.05, 1000 , -0.05 , 0.05 )" , "id >= 1920 && id < 55488" , "colz" );
259+ nt -> Draw ("dx:dz>>h_dx_vs_dz_OTOF(600 , -0.03 , 0.03, 600 , -0.03 , 0.03 )" , "id >= 1920 && id < 55488" , "colz" );
329260 addTLines (0.01 );
330261 h = (TH2F * )gPad -> GetPrimitive ("h_dx_vs_dz_OTOF" );
331262 Info ("OTOF" , "RMS(dx)=%.1f mu" , h -> GetRMS (2 ) * 1e4 );
@@ -352,72 +283,5 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root",
352283 canvdXdZHit -> SaveAs ("trkdigits_dxH_vs_dzH.pdf" );
353284
354285 f -> Write ();
355-
356- std ::string trackName [2 ] = {"Prm" , "Sec" };
357- f -> mkdir ("PrmTrkLayer0" );
358- f -> mkdir ("SecTrkLayer0" );
359- f -> mkdir ("PrmTrkLayer1" );
360- f -> mkdir ("SecTrkLayer1" );
361- for (int layer = 0 ; layer < 2 ; ++ layer ) {
362- for (int type = 0 ; type < 2 ; ++ type ) {
363- f -> cd (Form ("%sTrkLayer%d" , trackName [type ].c_str (), layer ));
364- hGenHitsEta [layer ][type ]-> Write ();
365- hRecoDigitEta [layer ][type ]-> Write ();
366- TH1F * hEffDigitEta = static_cast < TH1F * > (hRecoDigitEta [layer ][type ]-> Clone ("hEffDigitEta" ));
367- hEffDigitEta -> Divide (hGenHitsEta [layer ][type ]);
368- // Set errors
369- for (int bin = 1 ; bin <= hEffDigitEta -> GetNbinsX (); ++ bin ) {
370- double eff = hEffDigitEta -> GetBinContent (bin );
371- double nGen = hGenHitsEta [layer ][type ]-> GetBinContent (bin );
372- double err = 0.0 ;
373- if (nGen > 0 ) {
374- err = std ::sqrt (eff * (1 - eff ) / nGen );
375- }
376- hEffDigitEta -> SetBinError (bin , err );
377- }
378- hEffDigitEta -> SetTitle (";#eta;Digit Efficiency" );
379- hEffDigitEta -> Write ();
380- delete hEffDigitEta ;
381- }
382- }
383-
384- // Plot avg fraction of charge collected by digits for
385- // each hit vs eta, should reflect the digit efficiency
386- for (int layer = 0 ; layer < 2 ; ++ layer ) {
387- for (int type = 0 ; type < 2 ; ++ type ) {
388-
389- f -> cd (Form ("%sTrkLayer%d" , trackName [type ].c_str (), layer ));
390- TH2F * hFracCharge = new TH2F (Form ("hFracCharge_Layer%d_Type%d" , layer , type ), ";Fraction of charge collected by digits;Entries" , 40 , -2 , 2 , 200 , 0 , 1 );
391-
392- for (const auto& hitDigitPair : hitDigitMap ) {
393-
394- uint64_t hitKey = hitDigitPair .first ;
395- int evtID = static_cast < int > (hitKey >> 32 );
396- int hitIndex = static_cast < int > (hitKey & 0xFFFFFFFF );
397- const auto& hit = (* hitArray [evtID ])[hitIndex ];
398-
399- int hitLayer = gman -> getIOTOFLayer (hit .GetDetectorID ());
400- if (hitLayer != layer ) continue ;
401-
402- float energyLoss = hit .GetEnergyLoss (); // in GeV
403- int charge = static_cast < int > (energyLoss * 2.77778e+08 );
404-
405- auto& mcTrack = mcTracksPerEvent [evtID ]-> at (hit .GetTrackID ());
406- bool isPrimary = mcTrack .isPrimary ();
407- if ((isPrimary ? 0 : 1 ) != type ) continue ;
408-
409- const auto& digitIndices = hitDigitPair .second ;
410- float totalDigitCharge = 0.0f ;
411- for (int digitIndex : digitIndices ) {
412- totalDigitCharge += (* digArr )[digitIndex ].getCharge ();
413- }
414- float fracCharge = totalDigitCharge / charge ;
415- hFracCharge -> Fill (mcTrack .GetEta (), fracCharge );
416- }
417- hFracCharge -> Write ();
418- delete hFracCharge ;
419- }
420- }
421-
422286 f -> Close ();
423287}
0 commit comments