Project
Loading...
Searching...
No Matches
PrimaryVertexingSpec.cxx
Go to the documentation of this file.
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
13
14#include <TMap.h>
15#include <TObjString.h>
16#include <vector>
17#include <TStopwatch.h>
40
41using namespace o2::framework;
44
45namespace o2
46{
47namespace vertexing
48{
49
50namespace o2d = o2::dataformats;
51
53{
54 public:
55 PrimaryVertexingSpec(std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> gr, GTrackID::mask_t src, bool skip, bool validateWithIR, bool useMC)
56 : mDataRequest(dr), mGGCCDBRequest(gr), mTrackSrc(src), mSkip(skip), mUseMC(useMC), mValidateWithIR(validateWithIR) {}
57 ~PrimaryVertexingSpec() override = default;
58 void init(InitContext& ic) final;
59 void run(ProcessingContext& pc) final;
60 void endOfStream(EndOfStreamContext& ec) final;
61 void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final;
62
63 private:
64 void updateTimeDependentParams(ProcessingContext& pc);
65 void storeConfigs(ProcessingContext& pc);
66 std::shared_ptr<DataRequest> mDataRequest;
67 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
69 GTrackID::mask_t mTrackSrc{};
70 bool mSkip{false};
71 bool mUseMC{false};
72 bool mValidateWithIR{false};
73 float mITSROFrameLengthMUS = 0.;
74 float mITSROFBiasMUS = 0.;
75 TStopwatch mTimer;
76};
77
79{
80 mTimer.Stop();
81 mTimer.Reset();
83 mVertexer.setValidateWithIR(mValidateWithIR);
84 auto dumpDir = ic.options().get<std::string>("pool-dumps-directory");
85 if (!(dumpDir.empty() || dumpDir == "/dev/null") && !o2::utils::Str::pathIsDirectory(dumpDir)) {
86 throw std::runtime_error(fmt::format("directory {} for raw data dumps does not exist", dumpDir));
87 }
88 mVertexer.setPoolDumpDirectory(dumpDir);
89 mVertexer.setTrackSources(mTrackSrc);
90}
91
93{
94 double timeCPU0 = mTimer.CpuTime(), timeReal0 = mTimer.RealTime();
95 mTimer.Start(false);
96 std::vector<PVertex> vertices;
97 std::vector<GIndex> vertexTrackIDs;
98 std::vector<V2TRef> v2tRefs;
99 std::vector<o2::MCEventLabel> lblVtx;
100
101 if (!mSkip) {
103 recoData.collectData(pc, *mDataRequest.get()); // select tracks of needed type, with minimal cuts, the real selected will be done in the vertexer
104 updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions
105 storeConfigs(pc);
106 std::vector<TrackWithTimeStamp> tracks;
107 std::vector<o2::MCCompLabel> tracksMCInfo;
108 std::vector<o2d::GlobalTrackID> gids;
109 auto maxTrackTimeError = PVertexerParams::Instance().maxTimeErrorMUS;
110 auto trackMaxX = PVertexerParams::Instance().trackMaxX;
111 auto minIBHits = PVertexerParams::Instance().minIBHits;
112 auto halfROFITS = 0.5 * mITSROFrameLengthMUS + mITSROFBiasMUS;
113 auto hw2ErrITS = 2.f / std::sqrt(12.f) * mITSROFrameLengthMUS; // conversion from half-width to error for ITS
114
115 auto creator = [maxTrackTimeError, hw2ErrITS, halfROFITS, trackMaxX, minIBHits, &tracks, &gids, &recoData](auto& _tr, GTrackID _origID, float t0, float terr) {
116 if constexpr (isBarrelTrack<decltype(_tr)>()) {
117 if (!_origID.includesDet(DetID::ITS) || _tr.getX() > trackMaxX) {
118 return true; // just in case this selection was not done on RecoContainer filling level
119 }
120 auto itsID = recoData.getITSContributorGID(_origID);
121 if ((itsID.getSource() == GTrackID::ITS && o2::math_utils::numberOfBitsSet(recoData.getITSTrack(itsID).getPattern() & 7) < minIBHits) ||
122 (itsID.getSource() == GTrackID::ITSAB && o2::math_utils::numberOfBitsSet(recoData.getITSABRef(itsID).pattern & 7) < minIBHits)) { // do not accept ITSAB tracklets
123 return true;
124 }
125 if constexpr (isITSTrack<decltype(_tr)>()) {
126 t0 += halfROFITS; // ITS time is supplied in \mus as beginning of ROF
127 terr *= hw2ErrITS; // error is supplied as a half-ROF duration, convert to \mus
128 }
129 // for all other barrel tracks the time is in \mus with gaussian error
130 if (terr < maxTrackTimeError) {
131 tracks.emplace_back(TrackWithTimeStamp{_tr, {t0, terr}});
132 gids.emplace_back(_origID);
133 }
134 }
135 return true;
136 };
137
138 recoData.createTracksVariadic(creator, mTrackSrc); // create track sample considered for vertexing
139
140 if (mUseMC) {
141 recoData.fillTrackMCLabels(gids, tracksMCInfo);
142 }
143 mVertexer.setStartIR(recoData.startIR);
144 static std::vector<InteractionCandidate> ft0Data;
145 if (mValidateWithIR) { // select BCs for validation
146 ft0Data.clear();
148 auto ft0all = recoData.getFT0RecPoints();
149 for (const auto& ftRP : ft0all) {
150 if (ft0Params.isSelected(ftRP)) {
151 ft0Data.emplace_back(InteractionCandidate{ftRP.getInteractionRecord(),
152 float(ftRP.getInteractionRecord().differenceInBC(recoData.startIR) * o2::constants::lhc::LHCBunchSpacingMUS),
153 float(ftRP.getTrigger().getAmplA() + ftRP.getTrigger().getAmplC()),
155 }
156 }
157 }
158 mVertexer.process(tracks, gids, ft0Data, vertices, vertexTrackIDs, v2tRefs, tracksMCInfo, lblVtx);
159
160 // flag vertices using UPC ITS mode
161 auto itsrofs = recoData.getITSTracksROFRecords();
162 std::vector<bool> itsTrUPC(recoData.getITSTracks().size());
163 for (auto& rof : itsrofs) {
164 if (rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
165 for (int i = rof.getFirstEntry(); i < rof.getFirstEntry() + rof.getNEntries(); i++) {
166 itsTrUPC[i] = true;
167 }
168 }
169 }
170 int nv = vertices.size();
171 for (int iv = 0; iv < nv; iv++) {
172 int idMin = v2tRefs[iv].getFirstEntry(), idMax = idMin + v2tRefs[iv].getEntries();
173 int nits = 0, nitsUPC = 0;
174 for (int id = idMin; id < idMax; id++) {
175 auto gid = recoData.getITSContributorGID(vertexTrackIDs[id]);
176 if (gid.getSource() == GIndex::ITS) {
177 nits++;
178 if (itsTrUPC[gid.getIndex()]) {
179 nitsUPC++;
180 }
181 }
182 }
183 if (nitsUPC > nits / 2) {
184 vertices[iv].setFlags(PVertex::UPCMode);
185 }
186 }
187 } else {
188 storeConfigs(pc);
189 }
190
191 pc.outputs().snapshot(Output{"GLO", "PVTX", 0}, vertices);
192 pc.outputs().snapshot(Output{"GLO", "PVTX_CONTIDREFS"}, v2tRefs);
193 pc.outputs().snapshot(Output{"GLO", "PVTX_CONTID", 0}, vertexTrackIDs);
194
195 if (mUseMC) {
196 pc.outputs().snapshot(Output{"GLO", "PVTX_MCTR", 0}, lblVtx);
197 }
198
199 mTimer.Stop();
200 LOGP(info, "Found {} PVs, Time CPU/Real:{:.3f}/{:.3f} (DBScan: {:.4f}, Finder:{:.4f}, MADSel:{:.4f}, Rej.Debris:{:.4f}, Reattach:{:.4f}) | {} trials for {} TZ-clusters, max.trials: {}, Slowest TZ-cluster: {} ms of mult {} | NInitial:{}, Rejections: NoFilledBC:{}, NoIntCand:{}, Debris:{}, Quality:{}, ITSOnly:{}",
201 vertices.size(), mTimer.CpuTime() - timeCPU0, mTimer.RealTime() - timeReal0,
202 mVertexer.getTimeDBScan().CpuTime(), mVertexer.getTimeVertexing().CpuTime(), mVertexer.getTimeMADSel().CpuTime(), mVertexer.getTimeDebris().CpuTime(),
203 mVertexer.getTimeReAttach().CpuTime(), mVertexer.getTotTrials(), mVertexer.getNTZClusters(), mVertexer.getMaxTrialsPerCluster(),
204 mVertexer.getLongestClusterTimeMS(), mVertexer.getLongestClusterMult(), mVertexer.getNIniFound(),
205 mVertexer.getNKilledBCValid(), mVertexer.getNKilledIntCand(), mVertexer.getNKilledDebris(), mVertexer.getNKilledQuality(), mVertexer.getNKilledITSOnly());
206}
207
208void PrimaryVertexingSpec::storeConfigs(ProcessingContext& pc)
209{
210 static bool first = true;
211 if (first) {
212 first = false;
213 const auto& confPV = PVertexerParams::Instance();
218 TMap md;
219 md.SetOwnerKeyValue();
220 md.Add(new TObjString(confPV.getName().c_str()), new TObjString(o2::conf::ConfigurableParam::asJSON(confPV.getName()).c_str()));
221 md.Add(new TObjString(confMV.getName().c_str()), new TObjString(o2::conf::ConfigurableParam::asJSON(confMV.getName()).c_str()));
222 pc.outputs().snapshot(Output{"META", "PVERTEXER", 0}, md);
223 }
224 }
225}
226
228{
229 mVertexer.end();
230 LOGF(info, "Primary vertexing total timing: Cpu: %.3e Real: %.3e s in %d slots",
231 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
232}
233
235{
237 return;
238 }
239 // Note: strictly speaking, for Configurable params we don't need finaliseCCDB check, the singletons are updated at the CCDB fetcher level
240 if (matcher == ConcreteDataMatcher("ITS", "ALPIDEPARAM", 0)) {
241 LOG(info) << "ITS Alpide param updated";
243 par.printKeyValues();
244 return;
245 }
246 if (matcher == ConcreteDataMatcher("GLO", "MEANVERTEX", 0)) {
247 LOG(info) << "Imposing new MeanVertex: " << ((const o2::dataformats::MeanVertexObject*)obj)->asString();
249 return;
250 }
251}
252
253void PrimaryVertexingSpec::updateTimeDependentParams(ProcessingContext& pc)
254{
256 static bool initOnceDone = false;
257 if (!initOnceDone) { // this params need to be queried only once
258 initOnceDone = true;
259 // Note: reading of the ITS AlpideParam needed for ITS timing is done by the RecoContainer
262 if (!grp->isDetContinuousReadOut(DetID::ITS)) {
263 mITSROFrameLengthMUS = alpParams.roFrameLengthTrig / 1.e3; // ITS ROFrame duration in \mus
264 } else {
265 mITSROFrameLengthMUS = alpParams.roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3; // ITS ROFrame duration in \mus
266 }
267 mITSROFBiasMUS = alpParams.roFrameBiasInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3;
268 if (o2::base::GRPGeomHelper::instance().getGRPECS()->getRunType() != o2::parameters::GRPECSObject::RunType::COSMICS) {
269 mVertexer.setBunchFilling(o2::base::GRPGeomHelper::instance().getGRPLHCIF()->getBunchFilling());
270 }
271 mVertexer.setITSROFrameLength(mITSROFrameLengthMUS);
272 mVertexer.init();
274 PVertexerParams::Instance().printKeyValues();
275 }
276 }
277 // we may have other params which need to be queried regularly
279}
280
281DataProcessorSpec getPrimaryVertexingSpec(GTrackID::mask_t src, bool skip, bool validateWithFT0, bool useMC, bool useGeom)
282{
283 std::vector<OutputSpec> outputs;
284 auto dataRequest = std::make_shared<DataRequest>();
285
286 dataRequest->requestTracks(src, useMC);
287 if (validateWithFT0 && src[GTrackID::FT0]) {
288 dataRequest->requestFT0RecPoints(false);
289 }
290
291 outputs.emplace_back("GLO", "PVTX", 0, Lifetime::Timeframe);
292 outputs.emplace_back("GLO", "PVTX_CONTID", 0, Lifetime::Timeframe);
293 outputs.emplace_back("GLO", "PVTX_CONTIDREFS", 0, Lifetime::Timeframe);
294
295 if (useMC) {
296 outputs.emplace_back("GLO", "PVTX_MCTR", 0, Lifetime::Timeframe);
297 }
298
299 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
300 true, // GRPECS=true
301 true, // GRPLHCIF
302 true, // GRPMagField
303 true, // askMatLUT
305 dataRequest->inputs,
306 true);
307 dataRequest->inputs.emplace_back("meanvtx", "GLO", "MEANVERTEX", 0, Lifetime::Condition, ccdbParamSpec("GLO/Calib/MeanVertex", {}, 1));
308
309 outputs.emplace_back("META", "PVERTEXER", 0, Lifetime::Sporadic);
310
311 return DataProcessorSpec{
312 "primary-vertexing",
313 dataRequest->inputs,
314 outputs,
315 AlgorithmSpec{adaptFromTask<PrimaryVertexingSpec>(dataRequest, ggRequest, src, skip, validateWithFT0, useMC)},
316 Options{{"pool-dumps-directory", VariantType::String, "", {"Destination directory for the tracks pool dumps"}}}};
317}
318
319} // namespace vertexing
320} // namespace o2
Wrapper container for different reconstructed object types.
Definition of the GeometryManager class.
Definition of the FIT RecPoints class.
int32_t i
Helper for geometry and GRP related CCDB requests.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the Names Generator class.
Primary vertex finder.
Wrapper container for different reconstructed object types.
Result of refitting TPC-ITS matched track.
Reference on ITS/MFT clusters set.
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static std::string getConfigOutputFileName(const std::string &procName, const std::string &confName="", bool json=true)
Definition NameConf.cxx:120
static std::string asJSON(std::string const &keyOnly="")
static void write(std::string const &filename, std::string const &keyOnly="")
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
static constexpr ID ITS
Definition DetID.h:63
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
void setTrackSources(GTrackID::mask_t s)
auto getNIniFound() const
Definition PVertexer.h:129
int process(const TR &tracks, const gsl::span< o2d::GlobalTrackID > gids, const gsl::span< InteractionCandidate > intCand, std::vector< PVertex > &vertices, std::vector< o2d::VtxTrackIndex > &vertexTrackIDs, std::vector< V2TRef > &v2tRefs, const gsl::span< const o2::MCCompLabel > lblTracks, std::vector< o2::MCEventLabel > &lblVtx)
Definition PVertexer.h:336
auto getTotTrials() const
Definition PVertexer.h:120
void setStartIR(const o2::InteractionRecord &ir)
set InteractionRecods for the beginning of the TF
Definition PVertexer.h:76
auto getLongestClusterMult() const
Definition PVertexer.h:122
auto getLongestClusterTimeMS() const
Definition PVertexer.h:123
TStopwatch & getTimeDebris()
Definition PVertexer.h:133
auto getMaxTrialsPerCluster() const
Definition PVertexer.h:121
auto getNKilledITSOnly() const
Definition PVertexer.h:128
TStopwatch & getTimeVertexing()
Definition PVertexer.h:132
TStopwatch & getTimeMADSel()
Definition PVertexer.h:134
auto getNKilledQuality() const
Definition PVertexer.h:127
void setPoolDumpDirectory(const std::string &d)
Definition PVertexer.h:137
auto getNTZClusters() const
Definition PVertexer.h:119
auto getNKilledDebris() const
Definition PVertexer.h:126
void setBunchFilling(const o2::BunchFilling &bf)
void setValidateWithIR(bool v)
Definition PVertexer.h:90
TStopwatch & getTimeReAttach()
Definition PVertexer.h:135
TStopwatch & getTimeDBScan()
Definition PVertexer.h:131
auto getNKilledBCValid() const
Definition PVertexer.h:124
void setMeanVertex(const o2d::MeanVertexObject *v)
Definition PVertexer.h:98
void setITSROFrameLength(float v)
Definition PVertexer.h:108
auto getNKilledIntCand() const
Definition PVertexer.h:125
void run(ProcessingContext &pc) final
PrimaryVertexingSpec(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, GTrackID::mask_t src, bool skip, bool validateWithIR, bool useMC)
~PrimaryVertexingSpec() override=default
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
GLenum src
Definition glcorearb.h:1767
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
constexpr double LHCBunchSpacingMUS
constexpr double LHCBunchSpacingNS
Definition of a container to keep/associate and arbitrary number of labels associated to an index wit...
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
o2::framework::DataProcessorSpec getPrimaryVertexingSpec(o2::dataformats::GlobalTrackID::mask_t src, bool skip, bool validateWithFT0, bool useMC, bool useGeom)
create a processor spec
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string name
The name of the associated DataProcessorSpec.
Definition DeviceSpec.h:50
size_t inputTimesliceId
The time pipelining id of this particular device.
Definition DeviceSpec.h:68
bool isSelected(const RecPoints &rp) const
GTrackID getITSContributorGID(GTrackID source) const
void createTracksVariadic(T creator, GTrackID::mask_t srcSel=GTrackID::getSourcesMask("all")) const
const o2::itsmft::TrkClusRef & getITSABRef(GTrackID gid) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
void fillTrackMCLabels(const gsl::span< GTrackID > gids, std::vector< o2::MCCompLabel > &mcinfo) const
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
uint16_t pattern
layers pattern
Definition TrkClusRef.h:29
static bool pathIsDirectory(const std::string_view p)
generic track with timestamp
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"