1010// or submit itself to any jurisdiction.
1111
1212#include " ITSStudies/ITSBeamBackgroundStudy.h"
13+ #include " ITSStudies/ITSStudiesConfigParam.h"
1314#include " DataFormatsGlobalTracking/RecoContainer.h"
1415#include " DetectorsBase/GRPGeomHelper.h"
1516#include " DataFormatsParameters/GRPObject.h"
1920#include " DataFormatsITSMFT/CompCluster.h"
2021#include " DataFormatsITSMFT/ROFRecord.h"
2122#include " DataFormatsITSMFT/TopologyDictionary.h"
23+ #include " ITSBase/GeometryTGeo.h"
24+ #include " ITSMFTReconstruction/ChipMappingITS.h"
2225
2326#include < set>
2427#include < algorithm>
2528#include < limits>
29+ #include < cmath>
30+ #include < cstdint>
2631
2732#include < TTree.h>
2833#include < TH2.h>
@@ -57,16 +62,16 @@ class ITSBeamBackgroundStudy : public Task
5762 void updateTimeDependentParams (ProcessingContext& pc);
5863
5964 private:
65+ void prepareOutput ();
6066 void getClusterPatterns (gsl::span<const o2::itsmft::CompClusterExt>&, gsl::span<const unsigned char >&, const o2::itsmft::TopologyDictionary&);
6167 std::vector<o2::itsmft::ClusterPattern> mPatterns ;
6268
6369 // ITS layout
64- int NStaves[ 7 ] = { 12 , 16 , 20 , 24 , 30 , 42 , 48 } ;
65- int N_STAVES_IB = 48 ;
66- int N_CHIP_IB = 432 ;
70+ static constexpr int N_CHIP_IB = o2::itsmft::ChipMappingITS::getNChips(o2::itsmft::ChipMappingITS:: IB ) ;
71+ o2::itsmft::ChipMappingITS mChipMapping ;
72+ o2::its::GeometryTGeo* mGeom = nullptr ;
6773
6874 // Utilities
69- int ChipToLayer (int chip);
7075 double ChipToPhi (int chip);
7176 bool searchBCfromMap (std::map<long , std::set<int >>& BCperorbit, long target_orbit, int target_bc);
7277
@@ -81,7 +86,7 @@ class ITSBeamBackgroundStudy : public Task
8186 int mStrobeFallBack = 594 ;
8287 int mStrobe = mStrobeFallBack ;
8388
84- // TODO: the following should be make configurable
89+ // TODO: the following should be made configurable
8590
8691 std::pair<double , double > TimeWindowZDC = std::make_pair(5 ., 11 .);
8792 std::pair<double , double > TimeWindowZNAr = std::make_pair(5.64507 , 9.64507 );
@@ -92,8 +97,9 @@ class ITSBeamBackgroundStudy : public Task
9297 int targetClusterMinCol = 128 ; // definition of anomalous cluster
9398 int targetClusterMaxRow = 29 ; // definition of anomalous cluster
9499
95- int mDumpEveryTF = 10 ; // use -1 to save only at the end
96- int mSkimmedOnlyAfterTF = 15000 ;
100+ int mDumpEveryTF = ITSBeamBackgroundStudyParamConfig::Instance().dumpEveryTF;
101+ int mSkimmedOnlyAfterTF = ITSBeamBackgroundStudyParamConfig::Instance().skimmedOnlyAfterTF;
102+ bool mSaveClusterParameters = ITSBeamBackgroundStudyParamConfig::Instance().saveClusterParameters;
97103 std::string mOutputChip = " chipevents" ;
98104 std::string mOutoutChipSkim = " chipeventstarget" ;
99105
@@ -111,6 +117,10 @@ class ITSBeamBackgroundStudy : public Task
111117 long Torbit;
112118 int Tchip;
113119 double Tphi;
120+ // Cluster vectors share the input cluster order within this chip/ROF.
121+ // Positions are global: phi in radians [-pi, pi], r and z in cm.
122+ std::vector<float > TclusterPhi, TclusterR, TclusterZ;
123+ std::vector<int > TclusterSize, TclusterColSpan, TclusterRowSpan;
114124 int TZDCtag;
115125 int Tnhit, Tnclus, Tnhit_no1pix, Tnclus_no1pix;
116126 int Tnclus_s20, Tnclus_s100, Tnclus_s150;
@@ -123,25 +133,30 @@ class ITSBeamBackgroundStudy : public Task
123133
124134void ITSBeamBackgroundStudy::updateTimeDependentParams (ProcessingContext& pc)
125135{
126- // o2::base::GRPGeomHelper::instance().checkUpdates(pc);
127- // static bool initOnceDone = false;
128- // if (!initOnceDone) { // this param need to be queried only once
129- // initOnceDone = true;
130- // // mGeom = o2::its::GeometryTGeo::Instance();
131- // // mGeom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G));
132- // }
136+ o2::base::GRPGeomHelper::instance ().checkUpdates (pc);
137+ if (mSaveClusterParameters ) {
138+ mGeom = o2::its::GeometryTGeo::Instance ();
139+ mGeom ->fillMatrixCache (o2::math_utils::bit2Mask (o2::math_utils::TransformType::L2G ));
140+ }
133141}
134142
135143void ITSBeamBackgroundStudy::init (InitContext& ic)
136144{
137145 LOGP (info, " Initializing ITSBeamBackgroundStudy" );
146+ o2::base::GRPGeomHelper::instance ().setRequest (mGGCCDBRequest );
138147 LOGP (info, " Fetching ClusterDictionary" );
139148 auto & mgr = o2::ccdb::BasicCCDBManager::instance ();
140149 mgr.setURL (" http://alice-ccdb.cern.ch" );
141150 mgr.setTimestamp (o2::ccdb::getCurrentTimestamp ());
142151 mDict = mgr.get <o2::itsmft::TopologyDictionary>(" ITS/Calib/ClusterDictionary" );
143152
153+ prepareOutput ();
154+ }
155+
156+ void ITSBeamBackgroundStudy::prepareOutput ()
157+ {
144158 LOGP (info, " Setting up trees and histograms. They will be dumped on file every {} TFs" , mDumpEveryTF );
159+ LOGP (info, " Skimmed-only output after TF {}; saving cluster parameters: {}" , mSkimmedOnlyAfterTF , mSaveClusterParameters );
145160
146161 TimeWindowCut = new TH1F (" ZDC bkg region" , " ZNAr, ZNCr, -ZNAl, -ZNCl" , 8 , 0 , 8 );
147162 TimeWindowCut->SetBinContent (1 , TimeWindowZNAr.first );
@@ -177,6 +192,14 @@ void ITSBeamBackgroundStudy::init(InitContext& ic)
177192 ITSChipEvtTree->Branch (" bc" , &Tbc, " bc/I" );
178193 ITSChipEvtTree->Branch (" chip" , &Tchip, " chip/I" );
179194 ITSChipEvtTree->Branch (" phi" , &Tphi, " phi/D" );
195+ if (mSaveClusterParameters ) {
196+ ITSChipEvtTree->Branch (" cluster_phi" , &TclusterPhi);
197+ ITSChipEvtTree->Branch (" cluster_r" , &TclusterR);
198+ ITSChipEvtTree->Branch (" cluster_z" , &TclusterZ);
199+ ITSChipEvtTree->Branch (" cluster_size" , &TclusterSize);
200+ ITSChipEvtTree->Branch (" cluster_colspan" , &TclusterColSpan);
201+ ITSChipEvtTree->Branch (" cluster_rowspan" , &TclusterRowSpan);
202+ }
180203 ITSChipEvtTree->Branch (" zdctag" , &TZDCtag, " zdctag/I" );
181204 ITSChipEvtTree->Branch (" nhit" , &Tnhit, " nhit/I" );
182205 ITSChipEvtTree->Branch (" nhit_no1pix" , &Tnhit_no1pix, " nhit_no1pix/I" );
@@ -273,14 +296,14 @@ void ITSBeamBackgroundStudy::run(ProcessingContext& pc)
273296
274297 o2::globaltracking::RecoContainer recoData;
275298 recoData.collectData (pc, *mDataRequest .get ());
276- // updateTimeDependentParams(pc);
299+ updateTimeDependentParams (pc);
277300 LOGP (info, " Calling process() for TF: {}" , mTFn );
278301 process (recoData);
279302}
280303
281304void ITSBeamBackgroundStudy::finaliseCCDB (ConcreteDataMatcher& matcher, void * obj)
282305{
283- return ;
306+ o2::base::GRPGeomHelper::instance (). finaliseCCDB (matcher, obj) ;
284307}
285308
286309// Custom area
@@ -512,9 +535,11 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData
512535 std::set<int > AvailableChips{};
513536 std::map<int , std::vector<int >> MAPsize{}; // MAP[chip] = {list if sizes}
514537 std::map<int , std::vector<int >> MAPcols{}; // MAP[chip] = {list of column span}
515- std::map<int , int > MAPntarget{}; // MAP[chip] = number of bad clusters in chip
516- std::map<int , int > MAPcoo_mincol{}; // MAP[chip] = minimum of column coordinate
517- std::map<int , int > MAPcoo_maxcol{}; // MAP[chip] = maximum of (column coordinate + colspan)
538+ std::map<int , std::vector<int >> MAProws{}; // MAP[chip] = {list of row span}
539+ std::map<int , std::vector<o2::math_utils::Point3D<float >>> MAPcoordinates{};
540+ std::map<int , int > MAPntarget{}; // MAP[chip] = number of bad clusters in chip
541+ std::map<int , int > MAPcoo_mincol{}; // MAP[chip] = minimum of column coordinate
542+ std::map<int , int > MAPcoo_maxcol{}; // MAP[chip] = maximum of (column coordinate + colspan)
518543
519544 // Finally loop over clusters
520545 int ntarget_in_rof = 0 ;
@@ -525,7 +550,7 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData
525550 auto chipid = compClus.getSensorID ();
526551
527552 // Analyze only IB
528- if (ChipToLayer (chipid) > 2 ) {
553+ if (o2::itsmft::ChipMappingITS::getLayer (chipid) > 2 ) {
529554 continue ;
530555 }
531556
@@ -534,7 +559,7 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData
534559 int coo_col = (int )compClus.getCol ();
535560 int coo_row = (int )compClus.getRow ();
536561
537- auto patti = patternsInRof[iclus];
562+ const auto & patti = patternsInRof[iclus];
538563 int npix = patti.getNPixels ();
539564 int colspan = patti.getColumnSpan ();
540565 int rowspan = patti.getRowSpan ();
@@ -550,6 +575,17 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData
550575
551576 MAPsize[chipid].push_back (npix);
552577 MAPcols[chipid].push_back (colspan);
578+ if (mSaveClusterParameters ) {
579+ MAProws[chipid].push_back (rowspan);
580+ // Grouped topologies store a rounded COG in the compact cluster; invalid
581+ // pattern IDs store the bounding-box corner instead.
582+ const auto pattID = compClus.getPatternID ();
583+ auto local = pattID == o2::itsmft::CompCluster::InvalidPatternID
584+ ? mDict ->getClusterCoordinates <float >(compClus, patti, false )
585+ : (mDict ->isGroup (pattID) ? mDict ->getClusterCoordinates <float >(compClus, patti)
586+ : mDict ->getClusterCoordinates <float >(compClus));
587+ MAPcoordinates[chipid].push_back (mGeom ->getMatrixL2G (chipid)(local));
588+ }
553589 if (colspan >= targetClusterMinCol && rowspan <= targetClusterMaxRow) {
554590 // Anomalous cluster found
555591 MAPntarget[chipid] += 1 ;
@@ -560,7 +596,7 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData
560596
561597 } // end of loop over clusters in rof
562598
563- if (ntarget_in_rof == 0 && mTFn > mSkimmedOnlyAfterTF + 2 ) { // extra 2 to avoid edge effects?
599+ if (ntarget_in_rof == 0 && static_cast < int64_t >( mTFn ) > static_cast < int64_t >( mSkimmedOnlyAfterTF ) + 2 ) { // extra 2 to avoid edge effects?
564600 // do not need extra computations for this rof since it will not be saved in any case
565601 continue ;
566602 }
@@ -588,6 +624,19 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData
588624 Tphi = ChipToPhi (ic);
589625
590626 Tnclus = MAPsize[ic].size ();
627+ if (mSaveClusterParameters ) {
628+ TclusterSize = MAPsize[ic]; // Save before sorting the sizes for the summaries.
629+ TclusterColSpan = MAPcols[ic];
630+ TclusterRowSpan = MAProws[ic];
631+ TclusterPhi.clear ();
632+ TclusterR.clear ();
633+ TclusterZ.clear ();
634+ for (const auto & global : MAPcoordinates[ic]) {
635+ TclusterPhi.push_back (std::atan2 (global.Y (), global.X ()));
636+ TclusterR.push_back (std::hypot (global.X (), global.Y ()));
637+ TclusterZ.push_back (global.Z ());
638+ }
639+ }
591640 Tmincol = MAPcoo_mincol[ic];
592641 Tmaxcol = MAPcoo_maxcol[ic];
593642
@@ -644,38 +693,12 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData
644693 } // end of loop over ROFs
645694}
646695
647- // TODO: To be improved using geometry tools
648- int ITSBeamBackgroundStudy::ChipToLayer (int chip)
649- {
650- if (chip < 108 ) {
651- return 0 ;
652- }
653- if (chip < 252 ) {
654- return 1 ;
655- }
656- if (chip < 432 ) {
657- return 2 ;
658- }
659- if (chip < 3120 ) {
660- return 3 ;
661- }
662- if (chip < 6480 ) {
663- return 4 ;
664- }
665- if (chip < 14712 ) {
666- return 5 ;
667- }
668- return 6 ;
669- }
670-
671- // TODO: To be improved using geometry tools
672696double ITSBeamBackgroundStudy::ChipToPhi (int chip)
673697{
674- int staveinlayer = (int )(chip / 9 );
675- for (int il = 0 ; il < ChipToLayer (chip); il++) {
676- staveinlayer -= NStaves[il];
677- }
678- return 2 . * TMath::Pi () * (0.5 + staveinlayer) / NStaves[ChipToLayer (chip)];
698+ int layer, stave, substave, module , chipInModule;
699+ mChipMapping .expandChipInfoSW (chip, layer, stave, substave, module , chipInModule);
700+ const int staveInLayer = stave - o2::itsmft::ChipMappingITS::getFirstStavesOnLr (layer);
701+ return 2 . * TMath::Pi () * (0.5 + staveInLayer) / o2::itsmft::ChipMappingITS::getNStavesOnLr (layer);
679702}
680703
681704bool ITSBeamBackgroundStudy::searchBCfromMap (std::map<long , std::set<int >>& BCperorbit, long its_orbit, int its_bc)
@@ -729,16 +752,19 @@ DataProcessorSpec getITSBeamBackgroundStudy(mask_t srcTracksMask, mask_t srcClus
729752
730753 dataRequest->requestTracks (srcTracksMask, useMC);
731754
732- auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false , // orbitResetTime
733- true , // GRPECS=true
734- false , // GRPLHCIF
735- false , // GRPMagField
736- false , // askMatLUT
737- o2::base::GRPGeomRequest::Aligned, // geometry
755+ const auto geometry = ITSBeamBackgroundStudyParamConfig::Instance ().saveClusterParameters
756+ ? o2::base::GRPGeomRequest::Aligned
757+ : o2::base::GRPGeomRequest::None;
758+ auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false , // orbitResetTime
759+ true , // GRPECS=true
760+ false , // GRPLHCIF
761+ false , // GRPMagField
762+ false , // askMatLUT
763+ geometry,
738764 dataRequest->inputs ,
739765 true );
740766 return DataProcessorSpec{
741- " its-beambkg-study" ,
767+ " its-beambkg-study-task " ,
742768 dataRequest->inputs ,
743769 outputs,
744770 AlgorithmSpec{adaptFromTask<ITSBeamBackgroundStudy>(dataRequest, ggRequest, useMC)},
0 commit comments