1010// or submit itself to any jurisdiction.
1111
1212#include < bitset>
13- #include " Common/DataModel/FT0Corrected.h"
1413#include " Framework/ConfigParamSpec.h"
1514#include " Framework/runDataProcessing.h"
1615#include " Framework/AnalysisTask.h"
17- #include " Common/DataModel/EventSelection.h"
1816#include " Framework/AnalysisDataModel.h"
17+ #include " Framework/HistogramRegistry.h"
18+ #include " Common/DataModel/FT0Corrected.h"
19+ #include " Common/DataModel/EventSelection.h"
1920#include " CommonConstants/LHCConstants.h"
2021#include " CommonConstants/PhysicsConstants.h"
2122#include " DataFormatsFT0/Digit.h"
23+ #include " CCDB/BasicCCDBManager.h"
24+ #include " CollisionTypeHelper.h"
25+ #include " TRandom3.h"
2226
2327using namespace o2 ;
2428using namespace o2 ::framework;
25-
2629using namespace o2 ::aod;
27- struct FT0CorrectedTable {
30+
31+ struct ft0CorrectedTable {
32+ // Configurables
33+ Configurable<float > resoFT0A{" resoFT0A" , 20 .f , " FT0A resolution" };
34+ Configurable<float > resoFT0C{" resoFT0C" , 20 .f , " FT0C resolution" };
35+ Configurable<bool > addHistograms{" addHistograms" , false , " Add QA histograms" };
36+ Configurable<int > cfgCollisionSystem{" collisionSystem" , -2 , " Collision system: -2 (use cfg values), -1 (autoset), 0 (pp), 1 (PbPb), 2 (XeXe), 3 (pPb)" };
37+ Configurable<std::string> cfgUrl{" ccdb-url" , " http://alice-ccdb.cern.ch" , " url of the ccdb repository" };
38+ Configurable<std::string> cfgPathGrpLhcIf{" ccdb-path-grplhcif" , " GLO/Config/GRPLHCIF" , " Path on the CCDB for the GRPLHCIF object" };
39+ Configurable<int64_t > cfgTimestamp{" ccdb-timestamp" , -1 , " timestamp of the object" };
40+ Service<o2::ccdb::BasicCCDBManager> ccdb;
41+
42+ // Producer
2843 Produces<o2::aod::FT0sCorrected> table;
2944 using BCsWithMatchings = soa::Join<aod::BCs, aod::Run3MatchedToBCSparse>;
3045 using CollisionEvSel = soa::Join<aod::Collisions, aod::EvSels>::iterator;
46+ static constexpr float invLightSpeedCm2NS = 1 .f / o2::constants::physics::LightSpeedCm2NS;
3147
32- void process (BCsWithMatchings const &, soa::Join<aod::Collisions, aod::EvSels> const & collisions, aod::FT0s const &)
48+ HistogramRegistry histos{" Histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
49+ void init (o2::framework::InitContext&)
3350 {
51+ if (doprocessStandard && doprocessWithBypassFT0timeInMC) {
52+ LOG (fatal) << " Both processStandard and processWithBypassFT0timeInMC are enabled. Pick one of the two" ;
53+ }
54+ if (!doprocessStandard && !doprocessWithBypassFT0timeInMC) {
55+ LOG (fatal) << " No process is enabled. Pick one" ;
56+ }
57+ ccdb->setURL (cfgUrl);
58+ ccdb->setTimestamp (cfgTimestamp);
59+ ccdb->setCaching (true );
60+ ccdb->setLocalObjectValidityChecking ();
61+ // Not later than now objects
62+ ccdb->setCreatedNotAfter (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ());
63+
64+ if (!addHistograms) {
65+ return ;
66+ }
67+ histos.add (" t0A" , " t0A" , kTH1D , {{1000 , -1 , 1 , " t0A (ns)" }});
68+ histos.add (" t0C" , " t0C" , kTH1D , {{1000 , -1 , 1 , " t0C (ns)" }});
69+ histos.add (" t0AC" , " t0AC" , kTH1D , {{1000 , -1000 , 1000 , " t0AC (ns)" }});
70+ histos.add (" deltat0AC" , " deltat0AC" , kTH1D , {{1000 , -10 , 10 , " #Deltat0AC (ns)" }});
71+ if (doprocessWithBypassFT0timeInMC) {
72+ histos.add (" MC/deltat0A" , " t0A" , kTH1D , {{1000 , -50 , 50 , " t0A (ps)" }});
73+ histos.add (" MC/deltat0C" , " t0C" , kTH1D , {{1000 , -50 , 50 , " t0C (ps)" }});
74+ histos.add (" MC/deltat0AC" , " t0AC" , kTH1D , {{1000 , -50 , 50 , " t0AC (ps)" }});
75+ }
76+ }
77+
78+ void processStandard (soa::Join<aod::Collisions, aod::EvSels> const & collisions,
79+ BCsWithMatchings const &,
80+ aod::FT0s const &)
81+ {
82+ table.reserve (collisions.size ());
83+ float t0A = 1e10f;
84+ float t0C = 1e10f;
3485 for (auto & collision : collisions) {
35- float vertexPV = collision. posZ () ;
36- float vertex_corr = vertexPV / o2::constants::physics::LightSpeedCm2NS ;
37- float t0A = 1e10 ;
38- float t0C = 1e10 ;
86+ t0A = 1e10f ;
87+ t0C = 1e10f ;
88+ const float vertexPV = collision. posZ () ;
89+ const float vertex_corr = vertexPV * invLightSpeedCm2NS ;
3990 constexpr float dummyTime = 30 .; // Due to HW limitations time can be only within range (-25,25) ns, dummy time is around 32 ns
4091 if (collision.has_foundFT0 ()) {
41- auto ft0 = collision.foundFT0 ();
42- std::bitset<8 > triggers = ft0.triggerMask ();
43- bool ora = triggers[o2::ft0::Triggers::bitA];
44- bool orc = triggers[o2::ft0::Triggers::bitC];
92+ const auto & ft0 = collision.foundFT0 ();
93+ const std::bitset<8 >& triggers = ft0.triggerMask ();
94+ const bool ora = triggers[o2::ft0::Triggers::bitA];
95+ const bool orc = triggers[o2::ft0::Triggers::bitC];
4596 LOGF (debug, " triggers OrA %i OrC %i " , ora, orc);
4697 LOGF (debug, " T0A = %f, T0C %f, vertex_corr %f" , ft0.timeA (), ft0.timeC (), vertex_corr);
4798 if (ora && ft0.timeA () < dummyTime) {
@@ -52,11 +103,100 @@ struct FT0CorrectedTable {
52103 }
53104 }
54105 LOGF (debug, " T0 collision time T0A = %f, T0C = %f" , t0A, t0C);
106+ if (addHistograms) {
107+ histos.fill (HIST (" t0A" ), t0A);
108+ histos.fill (HIST (" t0C" ), t0C);
109+ histos.fill (HIST (" t0AC" ), (t0A + t0C) * 0 .5f );
110+ histos.fill (HIST (" deltat0AC" ), t0A - t0C);
111+ }
112+ table (t0A, t0C);
113+ }
114+ }
115+ PROCESS_SWITCH (ft0CorrectedTable, processStandard, " Process standard table (default)" , true );
116+
117+ void processWithBypassFT0timeInMC (soa::Join<aod::Collisions, aod::EvSels, aod::McCollisionLabels> const & collisions,
118+ soa::Join<BCsWithMatchings, aod::Timestamps> const & bcs,
119+ aod::FT0s const &,
120+ aod::McCollisions const &)
121+ {
122+ if (cfgCollisionSystem.value == -1 ) {
123+ o2::parameters::GRPLHCIFData* grpo = ccdb->template getForTimeStamp <o2::parameters::GRPLHCIFData>(cfgPathGrpLhcIf,
124+ bcs.iteratorAt (0 ).timestamp ());
125+ cfgCollisionSystem.value = CollisionSystemType::getCollisionTypeFromGrp (grpo);
126+ switch (cfgCollisionSystem.value ) {
127+ case CollisionSystemType::kCollSyspp :
128+ resoFT0A.value = 24 .f ;
129+ resoFT0C.value = 24 .f ;
130+ break ;
131+ case CollisionSystemType::kCollSysPbPb :
132+ resoFT0A.value = 5 .65f ;
133+ resoFT0C.value = 5 .65f ;
134+ break ;
135+ default :
136+ break ;
137+ }
138+ }
139+ table.reserve (collisions.size ());
140+ float t0A = 1e10f;
141+ float t0C = 1e10f;
142+ float eventtimeMC = 1e10f;
143+ float posZMC = 0 ;
144+ bool hasMCcoll = false ;
145+
146+ for (auto & collision : collisions) {
147+ hasMCcoll = false ;
148+ eventtimeMC = 1e10f;
149+ t0A = 1e10f;
150+ t0C = 1e10f;
151+ posZMC = 0 ;
152+ const float vertexPV = collision.posZ ();
153+ const float vertex_corr = vertexPV * invLightSpeedCm2NS;
154+ constexpr float dummyTime = 30 .; // Due to HW limitations time can be only within range (-25,25) ns, dummy time is around 32 ns
155+ if (collision.has_mcCollision ()) {
156+ hasMCcoll = true ;
157+ const auto & collisionMC = collision.mcCollision ();
158+ eventtimeMC = collisionMC.t ();
159+ posZMC = collisionMC.posZ ();
160+ }
161+ if (collision.has_foundFT0 ()) {
162+ const auto & ft0 = collision.foundFT0 ();
163+ const std::bitset<8 >& triggers = ft0.triggerMask ();
164+ const bool ora = triggers[o2::ft0::Triggers::bitA];
165+ const bool orc = triggers[o2::ft0::Triggers::bitC];
166+
167+ if (ora && ft0.timeA () < dummyTime) {
168+ t0A = ft0.timeA ();
169+ if (hasMCcoll) {
170+ const float diff = eventtimeMC - posZMC * invLightSpeedCm2NS + gRandom ->Gaus (0 .f , resoFT0A);
171+ t0A = diff;
172+ }
173+ t0A += vertex_corr;
174+ }
175+ if (orc && ft0.timeC () < dummyTime) {
176+ t0C = ft0.timeC ();
177+ if (hasMCcoll) {
178+ const float diff = eventtimeMC + posZMC * invLightSpeedCm2NS + gRandom ->Gaus (0 .f , resoFT0C);
179+ t0C = diff;
180+ }
181+ t0C -= vertex_corr;
182+ }
183+ }
184+ LOGF (debug, " T0 collision time T0A = %f, T0C = %f" , t0A, t0C);
185+ if (addHistograms) {
186+ histos.fill (HIST (" t0A" ), t0A);
187+ histos.fill (HIST (" t0C" ), t0C);
188+ histos.fill (HIST (" t0AC" ), (t0A + t0C) * 0 .5f );
189+ histos.fill (HIST (" deltat0AC" ), t0A - t0C);
190+ if (hasMCcoll) {
191+ histos.fill (HIST (" MC/deltat0A" ), (t0A - eventtimeMC) * 1000 .f );
192+ histos.fill (HIST (" MC/deltat0C" ), (t0C - eventtimeMC) * 1000 .f );
193+ histos.fill (HIST (" MC/deltat0AC" ), ((t0A + t0C) * 0 .5f - eventtimeMC) * 1000 .f );
194+ }
195+ }
55196 table (t0A, t0C);
56197 }
57198 }
199+ PROCESS_SWITCH (ft0CorrectedTable, processWithBypassFT0timeInMC, " Process MC with bypass of the AO2D information. Use with care!" , false );
58200};
59- WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
60- {
61- return WorkflowSpec{adaptAnalysisTask<FT0CorrectedTable>(cfgc, TaskName{" ft0-corrected-table" })};
62- }
201+
202+ WorkflowSpec defineDataProcessing (ConfigContext const & cfgc) { return WorkflowSpec{adaptAnalysisTask<ft0CorrectedTable>(cfgc)}; }
0 commit comments