Skip to content
112 changes: 75 additions & 37 deletions Common/TableProducer/zdcExtraTableProducer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,18 @@ struct ZdcExtraTableProducer {
// Event selections
Configurable<bool> cfgEvSelSel8{"cfgEvSelSel8", true, "Event selection: sel8"};
Configurable<float> cfgEvSelVtxZ{"cfgEvSelVtxZ", 10, "Event selection: zVtx"};
Configurable<bool> cfgEvSelsDoOccupancySel{"cfgEvSelsDoOccupancySel", true, "Event selection: do occupancy selection"};
Configurable<bool> cfgEvSelsDoOccupancySel{"cfgEvSelsDoOccupancySel", false, "Event selection: do occupancy selection"};
Configurable<float> cfgEvSelsMaxOccupancy{"cfgEvSelsMaxOccupancy", 10000, "Event selection: set max occupancy"};
Configurable<bool> cfgEvSelsNoSameBunchPileupCut{"cfgEvSelsNoSameBunchPileupCut", true, "Event selection: no same bunch pileup cut"};
Configurable<bool> cfgEvSelsIsGoodZvtxFT0vsPV{"cfgEvSelsIsGoodZvtxFT0vsPV", true, "Event selection: is good ZVTX FT0 vs PV"};
Configurable<bool> cfgEvSelsNoCollInTimeRangeStandard{"cfgEvSelsNoCollInTimeRangeStandard", true, "Event selection: no collision in time range standard"};
Configurable<bool> cfgEvSelsIsVertexITSTPC{"cfgEvSelsIsVertexITSTPC", true, "Event selection: is vertex ITSTPC"};
Configurable<bool> cfgEvSelsIsGoodITSLayersAll{"cfgEvSelsIsGoodITSLayersAll", true, "Event selection: is good ITS layers all"};
Configurable<bool> cfgEvSelsNoSameBunchPileupCut{"cfgEvSelsNoSameBunchPileupCut", false, "Event selection: no same bunch pileup cut"};
Configurable<bool> cfgEvSelsIsGoodZvtxFT0vsPV{"cfgEvSelsIsGoodZvtxFT0vsPV", false, "Event selection: is good ZVTX FT0 vs PV"};
Configurable<bool> cfgEvSelsNoCollInTimeRangeStandard{"cfgEvSelsNoCollInTimeRangeStandard", false, "Event selection: no collision in time range standard"};
Configurable<bool> cfgEvSelsIsVertexITSTPC{"cfgEvSelsIsVertexITSTPC", false, "Event selection: is vertex ITSTPC"};
Configurable<bool> cfgEvSelsIsGoodITSLayersAll{"cfgEvSelsIsGoodITSLayersAll", false, "Event selection: is good ITS layers all"};
// Calibration settings
Configurable<float> cfgCalibrationDownscaling{"cfgCalibrationDownscaling", 1.f, "Percentage of events to be saved to derived table"};

HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject};
// Output settings
Configurable<bool> cfgSaveQaHistos{"cfgSaveQaHistos", false, "Flag to save QA histograms"};

enum SelectionCriteria {
evSel_zvtx,
Expand All @@ -83,8 +84,27 @@ struct ZdcExtraTableProducer {
nEventSelections
};

HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject};

void init(InitContext const&)
{

registry.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}});
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_allEvents + 1, "All events");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_zvtx + 1, "vtxZ");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kIsGoodITSLayersAll");

// Skip histogram registration if QA flag is false
if (!cfgSaveQaHistos) {
return;
}

registry.add("ZNApmc", "ZNApmc; ZNA PMC; Entries", {HistType::kTH1F, {{nBins, -0.5, maxZN}}});
registry.add("ZNCpmc", "ZNCpmc; ZNC PMC; Entries", {HistType::kTH1F, {{nBins, -0.5, maxZN}}});
registry.add("ZNApm1", "ZNApm1; ZNA PM1; Entries", {HistType::kTH1F, {{nBins, -0.5, maxZN}}});
Expand All @@ -100,17 +120,6 @@ struct ZdcExtraTableProducer {

registry.add("ZNACentroid", "ZNA Centroid; X; Y", {HistType::kTH2F, {{50, -1.5, 1.5}, {50, -1.5, 1.5}}});
registry.add("ZNCCentroid", "ZNC Centroid; X; Y", {HistType::kTH2F, {{50, -1.5, 1.5}, {50, -1.5, 1.5}}});

registry.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}});
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_allEvents + 1, "All events");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_zvtx + 1, "vtxZ");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC");
registry.get<TH1>(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kIsGoodITSLayersAll");
}

template <typename TCollision>
Expand Down Expand Up @@ -176,7 +185,7 @@ struct ZdcExtraTableProducer {
void process(ColEvSels const& cols, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcs*/)
{
// collision-based event selection
int nTowers = 4; // number of ZDC towers
constexpr int NTowers = 4; // number of ZDC towers

for (auto const& collision : cols) {
const auto& foundBC = collision.foundBC_as<BCsRun3>();
Expand All @@ -185,6 +194,24 @@ struct ZdcExtraTableProducer {

uint8_t evSelection = eventSelected(collision);

// add event selection
if (cfgEvSelSel8 && !(evSelection & (1 << evSel_sel8)))
continue;
if (!(evSelection & (1 << evSel_zvtx)))
continue;
if (cfgEvSelsDoOccupancySel && !(evSelection & (1 << evSel_occupancy)))
continue;
if (cfgEvSelsNoSameBunchPileupCut && !(evSelection & (1 << evSel_kNoSameBunchPileup)))
continue;
if (cfgEvSelsIsGoodZvtxFT0vsPV && !(evSelection & (1 << evSel_kIsGoodZvtxFT0vsPV)))
continue;
if (cfgEvSelsNoCollInTimeRangeStandard && !(evSelection & (1 << evSel_kNoCollInTimeRangeStandard)))
continue;
if (cfgEvSelsIsVertexITSTPC && !(evSelection & (1 << evSel_kIsVertexITSTPC)))
continue;
if (cfgEvSelsIsGoodITSLayersAll && !(evSelection & (1 << evSel_kIsGoodITSLayersAll)))
continue;

float centrality = collision.centFT0C();

// To assure that ZN have a genuine signal (tagged by the relative TDC)
Expand All @@ -196,6 +223,7 @@ struct ZdcExtraTableProducer {
//
double tdcZNC = zdc.timeZNC();
double tdcZNA = zdc.timeZNA();

// OR we can select a narrow window in both ZN TDCs using the configurable parameters
if (tdcCut) { // a narrow TDC window is set
if ((tdcZNC >= tdcZNmincut) && (tdcZNC <= tdcZNmaxcut)) {
Expand All @@ -219,29 +247,34 @@ struct ZdcExtraTableProducer {
double pmqZNA[4] = {};
//
if (isZNChit) {
for (int it = 0; it < nTowers; it++) {
for (int it = 0; it < NTowers; it++) {
pmqZNC[it] = (zdc.energySectorZNC())[it];
sumZNC += pmqZNC[it];
}
registry.get<TH1>(HIST("ZNCpmc"))->Fill(pmcZNC);
registry.get<TH1>(HIST("ZNCpm1"))->Fill(pmqZNC[0]);
registry.get<TH1>(HIST("ZNCpm2"))->Fill(pmqZNC[1]);
registry.get<TH1>(HIST("ZNCpm3"))->Fill(pmqZNC[2]);
registry.get<TH1>(HIST("ZNCpm4"))->Fill(pmqZNC[3]);
registry.get<TH1>(HIST("ZNCsumq"))->Fill(sumZNC);

if (cfgSaveQaHistos) {
registry.get<TH1>(HIST("ZNCpmc"))->Fill(pmcZNC);
registry.get<TH1>(HIST("ZNCpm1"))->Fill(pmqZNC[0]);
registry.get<TH1>(HIST("ZNCpm2"))->Fill(pmqZNC[1]);
registry.get<TH1>(HIST("ZNCpm3"))->Fill(pmqZNC[2]);
registry.get<TH1>(HIST("ZNCpm4"))->Fill(pmqZNC[3]);
registry.get<TH1>(HIST("ZNCsumq"))->Fill(sumZNC);
}
}
if (isZNAhit) {
for (int it = 0; it < nTowers; it++) {
for (int it = 0; it < NTowers; it++) {
pmqZNA[it] = (zdc.energySectorZNA())[it];
sumZNA += pmqZNA[it];
}
//
registry.get<TH1>(HIST("ZNApmc"))->Fill(pmcZNA);
registry.get<TH1>(HIST("ZNApm1"))->Fill(pmqZNA[0]);
registry.get<TH1>(HIST("ZNApm2"))->Fill(pmqZNA[1]);
registry.get<TH1>(HIST("ZNApm3"))->Fill(pmqZNA[2]);
registry.get<TH1>(HIST("ZNApm4"))->Fill(pmqZNA[3]);
registry.get<TH1>(HIST("ZNAsumq"))->Fill(sumZNA);
if (cfgSaveQaHistos) {
registry.get<TH1>(HIST("ZNApmc"))->Fill(pmcZNA);
registry.get<TH1>(HIST("ZNApm1"))->Fill(pmqZNA[0]);
registry.get<TH1>(HIST("ZNApm2"))->Fill(pmqZNA[1]);
registry.get<TH1>(HIST("ZNApm3"))->Fill(pmqZNA[2]);
registry.get<TH1>(HIST("ZNApm4"))->Fill(pmqZNA[3]);
registry.get<TH1>(HIST("ZNAsumq"))->Fill(sumZNA);
}
}

// Q-vectors (centroid) calculation
Expand All @@ -257,8 +290,7 @@ struct ZdcExtraTableProducer {
float numXZNA = 0., numYZNA = 0., denZNA = 0.;

// Calculate weighted sums of the x and y coordinates
constexpr int kNTowers = 4; // number of ZDC towers
for (int i = 0; i < kNTowers; i++) {
for (int i = 0; i < NTowers; i++) {
if (pmqZNC[i] > 0.) {
float wZNC = std::pow(pmqZNC[i], kAlpha);
numXZNC -= X[i] * wZNC; // numerator x (minus sign due to opposite orientation of ZNC)
Expand Down Expand Up @@ -307,8 +339,14 @@ struct ZdcExtraTableProducer {
centroidZNA[0] = 999.;
centroidZNA[1] = 999.;
}
registry.get<TH2>(HIST("ZNCCentroid"))->Fill(centroidZNC[0], centroidZNC[1]);
registry.get<TH2>(HIST("ZNACentroid"))->Fill(centroidZNA[0], centroidZNA[1]);
if (cfgSaveQaHistos) {
if (isZNChit) {
registry.get<TH2>(HIST("ZNCCentroid"))->Fill(centroidZNC[0], centroidZNC[1]);
}
if (isZNAhit) {
registry.get<TH2>(HIST("ZNACentroid"))->Fill(centroidZNA[0], centroidZNA[1]);
}
}

auto vz = collision.posZ();
auto vx = collision.posX();
Expand Down
Loading