|
| 1 | +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. |
| 2 | +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. |
| 3 | +// All rights not expressly granted are reserved. |
| 4 | +// |
| 5 | +// This software is distributed under the terms of the GNU General Public |
| 6 | +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". |
| 7 | +// |
| 8 | +// In applying this license CERN does not waive the privileges and immunities |
| 9 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 10 | +// or submit itself to any jurisdiction. |
| 11 | + |
| 12 | +/// \file centrality.cxx |
| 13 | +/// \brief Task to produce the centrality tables associated to each of the required centrality estimators |
| 14 | + |
| 15 | +#include "Framework/runDataProcessing.h" |
| 16 | +#include "Framework/AnalysisTask.h" |
| 17 | +#include "Framework/AnalysisDataModel.h" |
| 18 | +#include "Framework/RunningWorkflowInfo.h" |
| 19 | +#include "Common/DataModel/Multiplicity.h" |
| 20 | +#include "Common/DataModel/Centrality_new.h" |
| 21 | +#include <CCDB/BasicCCDBManager.h> |
| 22 | +#include <TH1F.h> |
| 23 | +#include <TF1.h> |
| 24 | + |
| 25 | +using namespace o2; |
| 26 | +using namespace o2::framework; |
| 27 | + |
| 28 | +struct CentralityTableTask { |
| 29 | + Produces<aod::CentV0Ms> centVOM; |
| 30 | + Produces<aod::CentSPDs> centSPD; |
| 31 | + Produces<aod::CentCL0s> centCL1; |
| 32 | + Produces<aod::CentCL1s> centCL2; |
| 33 | + Service<o2::ccdb::BasicCCDBManager> ccdb; |
| 34 | + |
| 35 | + Configurable<int> estV0M{"estV0M", -1, {"Produces centrality percentiles using V0 multiplicity. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; |
| 36 | + Configurable<int> estSPD{"estSPD", -1, {"Produces centrality percentiles using SPD tracklets multiplicity. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; |
| 37 | + Configurable<int> estCL0{"estCL0", -1, {"Produces centrality percentiles using CL0 multiplicity. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; |
| 38 | + Configurable<int> estCL1{"estCL1", -1, {"Produces centrality percentiles using CL1 multiplicity. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; |
| 39 | + |
| 40 | + int mRunNumber; |
| 41 | + bool mV0MCallibrationStored; |
| 42 | + TH1* mhVtxAmpCorrV0A; |
| 43 | + TH1* mhVtxAmpCorrV0C; |
| 44 | + TH1* mhMultSelCalibV0M; |
| 45 | + |
| 46 | + void init(InitContext& context) |
| 47 | + { |
| 48 | + /* Checking the tables which are requested in the workflow and enabling them */ |
| 49 | + auto& workflows = context.services().get<RunningWorkflowInfo const>(); |
| 50 | + for (DeviceSpec device : workflows.devices) { |
| 51 | + for (auto input : device.inputs) { |
| 52 | + auto enable = [&input](const std::string detector, Configurable<int>& flag) { |
| 53 | + const std::string table = "Cent" + detector + "s"; |
| 54 | + if (input.matcher.binding == table) { |
| 55 | + if (flag < 0) { |
| 56 | + flag.value = 1; |
| 57 | + LOGF(info, "Auto-enabling table: %s", table.c_str()); |
| 58 | + } else if (flag > 0) { |
| 59 | + flag.value = 1; |
| 60 | + LOGF(info, "Table %s already enabled", table.c_str()); |
| 61 | + } else { |
| 62 | + LOGF(info, "Table %s disabled", table.c_str()); |
| 63 | + } |
| 64 | + } |
| 65 | + }; |
| 66 | + enable("V0M", estV0M); |
| 67 | + enable("SPD", estSPD); |
| 68 | + enable("CL0", estCL0); |
| 69 | + enable("CL1", estCL1); |
| 70 | + } |
| 71 | + } |
| 72 | + ccdb->setURL("http://alice-ccdb.cern.ch"); |
| 73 | + ccdb->setCaching(true); |
| 74 | + ccdb->setLocalObjectValidityChecking(); |
| 75 | + mRunNumber = 0; |
| 76 | + mV0MCallibrationStored = false; |
| 77 | + mhVtxAmpCorrV0A = nullptr; |
| 78 | + mhVtxAmpCorrV0C = nullptr; |
| 79 | + mhMultSelCalibV0M = nullptr; |
| 80 | + } |
| 81 | + |
| 82 | + void process(soa::Join<aod::Collisions, aod::Mults>::iterator const& collision, aod::BCsWithTimestamps const&, aod::Tracks const& tracks) |
| 83 | + { |
| 84 | + /* check the previous run number */ |
| 85 | + auto bc = collision.bc_as<aod::BCsWithTimestamps>(); |
| 86 | + if (bc.runNumber() != mRunNumber) { |
| 87 | + LOGF(debug, "timestamp=%llu", bc.timestamp()); |
| 88 | + TList* callst = ccdb->getForTimeStamp<TList>("Users/v/victor/Centrality", bc.timestamp()); |
| 89 | + |
| 90 | + if (callst != nullptr) { |
| 91 | + auto zvtxcalib = [callst](const char* tpname, const char* hname) { |
| 92 | + TProfile* tp = (TProfile*)callst->FindObject(tpname); |
| 93 | + TH1* h = new TH1F(TString::Format("%s", hname), TString::Format("%s;#it{z}_{vtx}", hname), |
| 94 | + tp->GetNbinsX(), tp->GetXaxis()->GetBinLowEdge(1), tp->GetXaxis()->GetBinUpEdge(tp->GetNbinsX())); |
| 95 | + TF1 one = TF1("one", "1", tp->GetXaxis()->GetBinLowEdge(1), tp->GetXaxis()->GetBinUpEdge(tp->GetNbinsX())); |
| 96 | + h->Reset(); |
| 97 | + h->Add(&one, tp->GetMean(2)); |
| 98 | + h->Divide(tp); |
| 99 | + return h; |
| 100 | + }; |
| 101 | + auto multcalib = [callst](const char* ccdbhname, const char* hname) { |
| 102 | + TH1* h = (TH1*)callst->FindObject(ccdbhname)->Clone(hname); |
| 103 | + return h; |
| 104 | + }; |
| 105 | + if (estV0M == 1) { |
| 106 | + mhVtxAmpCorrV0A = zvtxcalib("hVtx_fAmplitude_V0A", "zvtxCalibV0A"); |
| 107 | + mhVtxAmpCorrV0C = zvtxcalib("hVtx_fAmplitude_V0C", "zvtxCalibV0C"); |
| 108 | + mhMultSelCalibV0M = multcalib("hMultSelCalib_V0M", "MultSelCalibV0M"); |
| 109 | + if ((mhVtxAmpCorrV0A != nullptr) and (mhVtxAmpCorrV0C != nullptr) and (mhMultSelCalibV0M != nullptr)) { |
| 110 | + mV0MCallibrationStored = true; |
| 111 | + } |
| 112 | + } |
| 113 | + if (estSPD == 1) { |
| 114 | + LOGF(fatal, "Calibraltion information estimated from SPD tracklets still not available"); |
| 115 | + } |
| 116 | + if (estCL0 == 1) { |
| 117 | + LOGF(fatal, "Calibraltion information estimated from CL0 still not available"); |
| 118 | + } |
| 119 | + if (estCL1 == 1) { |
| 120 | + LOGF(fatal, "Calibraltion information estimated from CL1 still not available"); |
| 121 | + } |
| 122 | + if (mV0MCallibrationStored) { |
| 123 | + mRunNumber = bc.runNumber(); |
| 124 | + } |
| 125 | + } else { |
| 126 | + /* we dont change the run number to keep trying */ |
| 127 | + mV0MCallibrationStored = false; |
| 128 | + LOGF(error, "Centrality calibration is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); |
| 129 | + } |
| 130 | + } |
| 131 | + if (estV0M == 1) { |
| 132 | + float centV0M = 105.0f; |
| 133 | + if (mV0MCallibrationStored) { |
| 134 | + float v0m = collision.multV0A() * mhVtxAmpCorrV0A->GetBinContent(mhVtxAmpCorrV0A->FindFixBin(collision.posZ())) + |
| 135 | + collision.multV0C() * mhVtxAmpCorrV0C->GetBinContent(mhVtxAmpCorrV0C->FindFixBin(collision.posZ())); |
| 136 | + centV0M = mhMultSelCalibV0M->GetBinContent(mhMultSelCalibV0M->FindFixBin(v0m)); |
| 137 | + } |
| 138 | + LOGF(info, "centV0M=%.0f", centV0M); |
| 139 | + // fill centrality columns |
| 140 | + centVOM(centV0M); |
| 141 | + } |
| 142 | + } |
| 143 | +}; |
| 144 | + |
| 145 | +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) |
| 146 | +{ |
| 147 | + return WorkflowSpec{ |
| 148 | + adaptAnalysisTask<CentralityTableTask>(cfgc, TaskName{"centrality-table"})}; |
| 149 | +} |
0 commit comments