99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
1111
12- // / \file zdcTaskInterCalib.cxx
13- // / \brief Task for ZDC tower inter-calibration
14- // / \author chiara.oppedisano@cern.ch
12+ // / \file zdcExtraTableProducer.cxx
13+ // / \brief Task creating table with ZDC PMTs energies and calculated centroid (Q-vector) to be used for spectator plane measurement
14+ // / \author Chiara Oppedisano <chiara.oppedisano@cern.ch>, INFN Torino
15+ // / \author Uliana Dmitrieva <uliana.dmitrieva@cern.ch>, INFN Torino
1516
1617#include " Common/CCDB/EventSelectionParams.h"
1718#include " Common/DataModel/Centrality.h"
1819#include " Common/DataModel/EventSelection.h"
19- #include " Common/DataModel/ZDCInterCalib .h"
20+ #include " Common/DataModel/ZDCExtra .h"
2021
2122#include < Framework/AnalysisDataModel.h>
2223#include < Framework/AnalysisHelpers.h>
2930#include < Framework/runDataProcessing.h>
3031
3132#include < TH1.h>
33+ #include < TH2.h>
3234
3335#include < cstdint>
3436
@@ -40,17 +42,18 @@ using namespace o2::aod::evsel;
4042using BCsRun3 = soa::Join<aod::BCs, aod::Timestamps, aod::BcSels, aod::Run3MatchedToBCSparse>;
4143using ColEvSels = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Cs>;
4244
43- struct ZdcTaskInterCalib {
45+ struct ZdcExtraTableProducer {
4446
45- Produces<aod::ZDCInterCalib> zTab ;
47+ Produces<aod::ZdcExtras> zdcextras ;
4648
4749 // Configurable parameters
4850 //
4951 Configurable<int > nBins{" nBins" , 400 , " n bins" };
5052 Configurable<float > maxZN{" maxZN" , 399.5 , " Max ZN signal" };
5153 Configurable<bool > tdcCut{" tdcCut" , false , " Flag for TDC cut" };
5254 Configurable<float > tdcZNmincut{" tdcZNmincut" , -2.5 , " Min ZN TDC cut" };
53- Configurable<float > tdcZNmaxcut{" tdcZNmaxcut" , -2.5 , " Max ZN TDC cut" };
55+ Configurable<float > tdcZNmaxcut{" tdcZNmaxcut" , 2.5 , " Max ZN TDC cut" };
56+ Configurable<bool > cfgUsePMC{" cfgUsePMC" , true , " Use common PM (true) or sum of PMs (false) " };
5457 // Event selections
5558 Configurable<bool > cfgEvSelSel8{" cfgEvSelSel8" , true , " Event selection: sel8" };
5659 Configurable<float > cfgEvSelVtxZ{" cfgEvSelVtxZ" , 10 , " Event selection: zVtx" };
@@ -92,6 +95,9 @@ struct ZdcTaskInterCalib {
9295 registry.add (" ZNAsumq" , " ZNAsumq; ZNA uncalib. sum PMQ; Entries" , {HistType::kTH1F , {{nBins, -0.5 , maxZN}}});
9396 registry.add (" ZNCsumq" , " ZNCsumq; ZNC uncalib. sum PMQ; Entries" , {HistType::kTH1F , {{nBins, -0.5 , maxZN}}});
9497
98+ registry.add (" ZNACentroid" , " ZNACentroid; ZNA Centroid; X; Y" , {HistType::kTH2F , {{50 , -1.5 , 1.5 }, {50 , -1.5 , 1.5 }}});
99+ registry.add (" ZNCCentroid" , " ZNCCentroid; ZNC Centroid; X; Y" , {HistType::kTH2F , {{50 , -1.5 , 1.5 }, {50 , -1.5 , 1.5 }}});
100+
95101 registry.add (" hEventCount" , " Number of Event; Cut; #Events Passed Cut" , {HistType::kTH1D , {{nEventSelections, 0 , nEventSelections}}});
96102 registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_allEvents + 1 , " All events" );
97103 registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_zvtx + 1 , " vtxZ" );
@@ -101,7 +107,7 @@ struct ZdcTaskInterCalib {
101107 registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_kIsGoodZvtxFT0vsPV + 1 , " kIsGoodZvtxFT0vsPV" );
102108 registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_kNoCollInTimeRangeStandard + 1 , " kNoCollInTimeRangeStandard" );
103109 registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_kIsVertexITSTPC + 1 , " kIsVertexITSTPC" );
104- registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_kIsGoodITSLayersAll + 1 , " kkIsGoodITSLayersAll " );
110+ registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_kIsGoodITSLayersAll + 1 , " kIsGoodITSLayersAll " );
105111 }
106112
107113 template <typename TCollision>
@@ -206,18 +212,8 @@ struct ZdcTaskInterCalib {
206212 //
207213 double sumZNC = 0 ;
208214 double sumZNA = 0 ;
209- double pmqZNC[4 ] = {
210- 0 ,
211- 0 ,
212- 0 ,
213- 0 ,
214- };
215- double pmqZNA[4 ] = {
216- 0 ,
217- 0 ,
218- 0 ,
219- 0 ,
220- };
215+ double pmqZNC[4 ] = {};
216+ double pmqZNA[4 ] = {};
221217 //
222218 if (isZNChit) {
223219 for (int it = 0 ; it < nTowers; it++) {
@@ -244,15 +240,87 @@ struct ZdcTaskInterCalib {
244240 registry.get <TH1>(HIST (" ZNApm4" ))->Fill (pmqZNA[3 ]);
245241 registry.get <TH1>(HIST (" ZNAsumq" ))->Fill (sumZNA);
246242 }
247- if (isZNAhit || isZNChit)
248- zTab (pmcZNA, pmqZNA[0 ], pmqZNA[1 ], pmqZNA[2 ], pmqZNA[3 ], tdcZNC, pmcZNC, pmqZNC[0 ], pmqZNC[1 ], pmqZNC[2 ], pmqZNC[3 ], tdcZNA, centrality, foundBC.timestamp (), evSelection);
243+
244+ // Q-vectors (centroid) calculation
245+ // kBeamEne -- LHC Run 3 Pb-Pb collision energy (5.36 TeV per nucleon pair)
246+ constexpr float kBeamEne = 5.36 * 0.5 ;
247+
248+ // Provide coordinates of centroid over ZN (side C) front face
249+ constexpr float X[4 ] = {-1.75 , 1.75 , -1.75 , 1.75 };
250+ constexpr float Y[4 ] = {-1.75 , -1.75 , 1.75 , 1.75 };
251+ constexpr float kAlpha = 0.395 ; // saturation correction
252+
253+ float numXZNC = 0 ., numYZNC = 0 ., denZNC = 0 .;
254+ float numXZNA = 0 ., numYZNA = 0 ., denZNA = 0 .;
255+
256+ // Calculate weighted sums of the x and y coordinates
257+ constexpr int kNTowers = 4 ; // number of ZDC towers
258+ for (int i = 0 ; i < kNTowers ; i++) {
259+ if (pmqZNC[i] > 0 .) {
260+ float wZNC = std::pow (pmqZNC[i], kAlpha );
261+ numXZNC -= X[i] * wZNC; // numerator x (minus sign due to opposite orientation of ZNC)
262+ numYZNC += Y[i] * wZNC; // numerator y
263+ denZNC += wZNC; // denominator
264+ }
265+ if (pmqZNA[i] > 0 .) {
266+ float wZNA = std::pow (pmqZNA[i], kAlpha );
267+ numXZNA += X[i] * wZNA; // numerator x
268+ numYZNA += Y[i] * wZNA; // numerator y
269+ denZNA += wZNA; // denominator
270+ }
271+ }
272+ // Calculate centroid coordinates (in cm) with correction factor c depending on the number of spectator nucleons (nSpec)
273+
274+ float zncCommon = 0 ;
275+ float znaCommon = 0 ;
276+
277+ // Use sum of PMTs (cfgUsePMC == false) when common PMT is saturated
278+ if (cfgUsePMC) {
279+ zncCommon = pmcZNC;
280+ znaCommon = pmcZNA;
281+ } else {
282+ zncCommon = sumZNC;
283+ znaCommon = sumZNA;
284+ }
285+
286+ float centroidZNC[2 ], centroidZNA[2 ];
287+
288+ if (denZNC != 0 .) {
289+ float nSpecnC = zncCommon / kBeamEne ;
290+ float cZNC = 1.89358 - 0.71262 / (nSpecnC + 0.71789 );
291+ centroidZNC[0 ] = cZNC * numXZNC / denZNC;
292+ centroidZNC[1 ] = cZNC * numYZNC / denZNC;
293+ } else {
294+ centroidZNC[0 ] = 999 .;
295+ centroidZNC[1 ] = 999 .;
296+ }
297+ //
298+ if (denZNA != 0 .) {
299+ float nSpecnA = znaCommon / kBeamEne ;
300+ float cZNA = 1.89358 - 0.71262 / (nSpecnA + 0.71789 );
301+ centroidZNA[0 ] = cZNA * numXZNA / denZNA;
302+ centroidZNA[1 ] = cZNA * numYZNA / denZNA;
303+ } else {
304+ centroidZNA[0 ] = 999 .;
305+ centroidZNA[1 ] = 999 .;
306+ }
307+ registry.get <TH2>(HIST (" ZNCCentroid" ))->Fill (centroidZNC[0 ], centroidZNC[1 ]);
308+ registry.get <TH2>(HIST (" ZNACentroid" ))->Fill (centroidZNA[0 ], centroidZNA[1 ]);
309+
310+ auto vz = collision.posZ ();
311+ auto vx = collision.posX ();
312+ auto vy = collision.posY ();
313+
314+ if (isZNAhit || isZNChit) {
315+ zdcextras (pmcZNA, pmqZNA[0 ], pmqZNA[1 ], pmqZNA[2 ], pmqZNA[3 ], tdcZNA, centroidZNA[0 ], centroidZNA[1 ], pmcZNC, pmqZNC[0 ], pmqZNC[1 ], pmqZNC[2 ], pmqZNC[3 ], tdcZNC, centroidZNC[0 ], centroidZNC[1 ], centrality, vx, vy, vz, foundBC.timestamp (), evSelection);
316+ }
249317 }
250318 }
251319 }
252320};
253321
254- WorkflowSpec defineDataProcessing (ConfigContext const & cfgc) // o2-linter: disable=name/file-cpp
322+ WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
255323{
256324 return WorkflowSpec{
257- adaptAnalysisTask<ZdcTaskInterCalib >(cfgc)};
325+ adaptAnalysisTask<ZdcExtraTableProducer >(cfgc)};
258326}
0 commit comments