3333#endif
3434
3535void CreateDictionaries (bool saveDeltas = false,
36+ float probThreshold = 1e-6 ,
37+ std ::string clusDictFile = "" ,
3638 std ::string clusfile = "o2clus_its.root" ,
3739 std ::string hitfile = "o2sim_HitsITS.root" ,
3840 std ::string collContextfile = "collisioncontext.root" ,
@@ -57,6 +59,11 @@ void CreateDictionaries(bool saveDeltas = false,
5759 std ::unordered_map < int , int > hadronicMCMap ; // mapping from MC event entry to hadronic event ID
5860 std ::vector < HitVec * > hitVecPool ;
5961 std ::vector < MC2HITS_map > mc2hitVec ;
62+ o2 ::itsmft ::TopologyDictionary clusDictOld ;
63+ if (!clusDictFile .empty ()) {
64+ clusDictOld .readFromFile (clusDictFile );
65+ LOGP (info , "Loaded external cluster dictionary with {} entries from {}" , clusDictOld .getSize (), clusDictFile );
66+ }
6067
6168 TFile * fout = nullptr ;
6269 TNtuple * nt = nullptr ;
@@ -132,6 +139,10 @@ void CreateDictionaries(bool saveDeltas = false,
132139 clusTree -> SetBranchAddress ("ITSClustersMC2ROF" , & mc2rofVecP );
133140 }
134141 clusTree -> GetEntry (0 );
142+ if (clusTree -> GetEntries () > 1 && !hitfile .empty ()) {
143+ LOGP (error , "Hits are provided but the cluster tree containes {} entries, looks like real data" );
144+ return ;
145+ }
135146
136147 // Topologies dictionaries: 1) all clusters 2) signal clusters only 3) noise clusters only
137148 BuildTopologyDictionary completeDictionary ;
@@ -165,99 +176,112 @@ void CreateDictionaries(bool saveDeltas = false,
165176 }
166177 } // << build min and max MC events used by each ROF
167178
168- auto pattIdx = patternsPtr -> cbegin ();
169- for (int irof = 0 ; irof < nROFRec ; irof ++ ) {
170- const auto& rofRec = rofRecVec [irof ];
179+ for (Long64_t ient = 0 ; ient < clusTree -> GetEntries (); ient ++ ) {
180+ clusTree -> GetEntry (ient );
181+ nROFRec = (int )rofRecVec .size ();
182+ LOGP (info , "Processing TF {} with {} ROFs and {} clusters" , ient , nROFRec , clusArr -> size ());
183+ auto pattIdx = patternsPtr -> cbegin ();
184+ for (int irof = 0 ; irof < nROFRec ; irof ++ ) {
185+ const auto& rofRec = rofRecVec [irof ];
171186
172- rofRec .print ();
187+ // rofRec.print();
173188
174- if (clusLabArr ) { // >> read and map MC events contributing to this ROF
175- for (int im = mcEvMin [irof ]; im <= mcEvMax [irof ]; im ++ ) {
176- if (!hitVecPool [im ]) {
177- hitTree -> SetBranchAddress ("ITSHit" , & hitVecPool [im ]);
178- hitTree -> GetEntry (im );
179- auto& mc2hit = mc2hitVec [im ];
180- const auto* hitArray = hitVecPool [im ];
181- for (int ih = hitArray -> size (); ih -- ;) {
182- const auto& hit = (* hitArray )[ih ];
183- uint64_t key = (uint64_t (hit .GetTrackID ()) << 32 ) + hit .GetDetectorID ();
184- mc2hit .emplace (key , ih );
189+ if (clusLabArr ) { // >> read and map MC events contributing to this ROF
190+ for (int im = mcEvMin [irof ]; im <= mcEvMax [irof ]; im ++ ) {
191+ if (!hitVecPool [im ]) {
192+ hitTree -> SetBranchAddress ("ITSHit" , & hitVecPool [im ]);
193+ hitTree -> GetEntry (im );
194+ auto& mc2hit = mc2hitVec [im ];
195+ const auto* hitArray = hitVecPool [im ];
196+ for (int ih = hitArray -> size (); ih -- ;) {
197+ const auto& hit = (* hitArray )[ih ];
198+ uint64_t key = (uint64_t (hit .GetTrackID ()) << 32 ) + hit .GetDetectorID ();
199+ mc2hit .emplace (key , ih );
200+ }
185201 }
186202 }
187- }
188- } // << cache MC events contributing to this ROF
203+ } // << cache MC events contributing to this ROF
189204
190- for (int icl = 0 ; icl < rofRec .getNEntries (); icl ++ ) {
191- int clEntry = rofRec .getFirstEntry () + icl ; // entry of icl-th cluster of this ROF in the vector of clusters
192- // do we read MC data?
205+ for (int icl = 0 ; icl < rofRec .getNEntries (); icl ++ ) {
206+ int clEntry = rofRec .getFirstEntry () + icl ; // entry of icl-th cluster of this ROF in the vector of clusters
207+ // do we read MC data?
193208
194- const auto& cluster = (* clusArr )[clEntry ];
209+ const auto& cluster = (* clusArr )[clEntry ];
210+ o2 ::itsmft ::ClusterPattern pattern ;
195211
196- if (cluster .getPatternID () != CompCluster ::InvalidPatternID ) {
197- LOG (warning ) << "Encountered patternID = " << cluster .getPatternID () << " != " << CompCluster ::InvalidPatternID ;
198- LOG (warning ) << "Clusters have already been generated with a dictionary! Quitting" ;
199- return ;
200- }
201-
202- ClusterTopology topology ;
203- o2 ::itsmft ::ClusterPattern pattern (pattIdx );
204- topology .setPattern (pattern );
212+ if (cluster .getPatternID () != CompCluster ::InvalidPatternID ) {
213+ if (clusDictOld .getSize () == 0 ) {
214+ LOG (error ) << "Encountered patternID = " << cluster .getPatternID () << " != " << CompCluster ::InvalidPatternID ;
215+ LOG (error ) << "Clusters have already been generated with a dictionary which was not provided" ;
216+ return ;
217+ }
218+ if (clusDictOld .isGroup (cluster .getPatternID ())) {
219+ pattern .acquirePattern (pattIdx );
220+ } else {
221+ pattern = clusDictOld .getPattern (cluster .getPatternID ());
222+ }
223+ } else {
224+ pattern .acquirePattern (pattIdx );
225+ }
226+ ClusterTopology topology ;
227+ topology .setPattern (pattern );
205228
206- float dX = BuildTopologyDictionary ::IgnoreVal , dZ = BuildTopologyDictionary ::IgnoreVal ;
207- if (clusLabArr ) {
208- const auto& lab = (clusLabArr -> getLabels (clEntry ))[0 ];
209- auto srcID = lab .getSourceID ();
210- if (lab .isValid () && srcID != QEDSourceID ) { // use MC truth info only for non-QED and non-noise clusters
211- auto trID = lab .getTrackID ();
212- const auto& mc2hit = mc2hitVec [lab .getEventID ()];
213- const auto* hitArray = hitVecPool [lab .getEventID ()];
214- Int_t chipID = cluster .getSensorID ();
215- uint64_t key = (uint64_t (trID ) << 32 ) + chipID ;
216- auto hitEntry = mc2hit .find (key );
217- if (hitEntry != mc2hit .end ()) {
218- const auto& hit = (* hitArray )[hitEntry -> second ];
219- if (minPtMC < 0.f || hit .GetMomentum ().Perp2 () > minPtMC2 ) {
220- auto locH = gman -> getMatrixL2G (chipID ) ^ (hit .GetPos ()); // inverse conversion from global to local
221- auto locHsta = gman -> getMatrixL2G (chipID ) ^ (hit .GetPosStart ());
222- locH .SetXYZ (0.5 * (locH .X () + locHsta .X ()), 0.5 * (locH .Y () + locHsta .Y ()), 0.5 * (locH .Z () + locHsta .Z ()));
223- const auto locC = o2 ::itsmft ::TopologyDictionary ::getClusterCoordinates (cluster , pattern , false );
224- dX = locH .X () - locC .X ();
225- dZ = locH .Z () - locC .Z ();
226- if (saveDeltas ) {
227- nt -> Fill (topology .getHash (), dX , dZ );
228- }
229- if (checkOutliers > 0. ) {
230- if (std ::abs (dX ) > topology .getRowSpan () * o2 ::itsmft ::SegmentationAlpide ::PitchRow * checkOutliers ||
231- std ::abs (dZ ) > topology .getColumnSpan () * o2 ::itsmft ::SegmentationAlpide ::PitchCol * checkOutliers ) { // ignore outlier
232- dX = dZ = BuildTopologyDictionary ::IgnoreVal ;
229+ float dX = BuildTopologyDictionary ::IgnoreVal , dZ = BuildTopologyDictionary ::IgnoreVal ;
230+ if (clusLabArr ) {
231+ const auto& lab = (clusLabArr -> getLabels (clEntry ))[0 ];
232+ auto srcID = lab .getSourceID ();
233+ if (lab .isValid () && srcID != QEDSourceID ) { // use MC truth info only for non-QED and non-noise clusters
234+ auto trID = lab .getTrackID ();
235+ const auto& mc2hit = mc2hitVec [lab .getEventID ()];
236+ const auto* hitArray = hitVecPool [lab .getEventID ()];
237+ Int_t chipID = cluster .getSensorID ();
238+ uint64_t key = (uint64_t (trID ) << 32 ) + chipID ;
239+ auto hitEntry = mc2hit .find (key );
240+ if (hitEntry != mc2hit .end ()) {
241+ const auto& hit = (* hitArray )[hitEntry -> second ];
242+ if (minPtMC < 0.f || hit .GetMomentum ().Perp2 () > minPtMC2 ) {
243+ auto locH = gman -> getMatrixL2G (chipID ) ^ (hit .GetPos ()); // inverse conversion from global to local
244+ auto locHsta = gman -> getMatrixL2G (chipID ) ^ (hit .GetPosStart ());
245+ locH .SetXYZ (0.5 * (locH .X () + locHsta .X ()), 0.5 * (locH .Y () + locHsta .Y ()), 0.5 * (locH .Z () + locHsta .Z ()));
246+ const auto locC = o2 ::itsmft ::TopologyDictionary ::getClusterCoordinates (cluster , pattern , false );
247+ dX = locH .X () - locC .X ();
248+ dZ = locH .Z () - locC .Z ();
249+ if (saveDeltas ) {
250+ nt -> Fill (topology .getHash (), dX , dZ );
251+ }
252+ if (checkOutliers > 0. ) {
253+ if (std ::abs (dX ) > topology .getRowSpan () * o2 ::itsmft ::SegmentationAlpide ::PitchRow * checkOutliers ||
254+ std ::abs (dZ ) > topology .getColumnSpan () * o2 ::itsmft ::SegmentationAlpide ::PitchCol * checkOutliers ) { // ignore outlier
255+ dX = dZ = BuildTopologyDictionary ::IgnoreVal ;
256+ }
233257 }
234258 }
259+ } else {
260+ printf ("Failed to find MC hit entry for Tr:%d chipID:%d\n" , trID , chipID );
261+ lab .print ();
235262 }
263+ signalDictionary .accountTopology (topology , dX , dZ );
236264 } else {
237- printf ("Failed to find MC hit entry for Tr:%d chipID:%d\n" , trID , chipID );
238- lab .print ();
265+ noiseDictionary .accountTopology (topology , dX , dZ );
239266 }
240- signalDictionary .accountTopology (topology , dX , dZ );
241- } else {
242- noiseDictionary .accountTopology (topology , dX , dZ );
243267 }
268+ completeDictionary .accountTopology (topology , dX , dZ );
244269 }
245- completeDictionary .accountTopology (topology , dX , dZ );
246- }
247- // clean MC cache for events which are not needed anymore
248- if (clusLabArr ) {
249- int irfNext = irof ;
250- int limMC = irfNext == nROFRec ? hitVecPool .size () : mcEvMin [irfNext ]; // can clean events up to this
251- for (int imc = mcEvMin [irof ]; imc < limMC ; imc ++ ) {
252- delete hitVecPool [imc ];
253- hitVecPool [imc ] = nullptr ;
254- mc2hitVec [imc ].clear ();
270+ // clean MC cache for events which are not needed anymore
271+ if (clusLabArr ) {
272+ int irfNext = irof ;
273+ int limMC = irfNext == nROFRec ? hitVecPool .size () : mcEvMin [irfNext ]; // can clean events up to this
274+ for (int imc = mcEvMin [irof ]; imc < limMC ; imc ++ ) {
275+ delete hitVecPool [imc ];
276+ hitVecPool [imc ] = nullptr ;
277+ mc2hitVec [imc ].clear ();
278+ }
255279 }
256280 }
257281 }
258282 auto dID = o2 ::detectors ::DetID ::ITS ;
259283
260- completeDictionary .setThreshold (0.0001 );
284+ completeDictionary .setThreshold (probThreshold );
261285 completeDictionary .groupRareTopologies ();
262286 completeDictionary .printDictionaryBinary (o2 ::base ::DetectorNameConf ::getAlpideClusterDictionaryFileName (dID , "" ));
263287 completeDictionary .printDictionary (o2 ::base ::DetectorNameConf ::getAlpideClusterDictionaryFileName (dID , "" , "txt" ));
0 commit comments