Project
Loading...
Searching...
No Matches
FilteringSpec.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 "FilteringSpec.h"
27#include "MathUtils/Utils.h"
37#include "Framework/DataTypes.h"
39#include "Framework/Logger.h"
42#include "FDDBase/Constants.h"
43#include "FT0Base/Geometry.h"
44#include "FV0Base/Geometry.h"
62#include "ZDCBase/Constants.h"
65#include "TOFBase/Utils.h"
66#include "TMath.h"
67#include "MathUtils/Utils.h"
68#include <map>
69#include <unordered_map>
70#include <string>
71#include <vector>
72
73using namespace o2::framework;
74using namespace o2::math_utils::detail;
80
81namespace o2::filtering
82{
83
85{
86 mTimer.Start(false);
88 recoData.collectData(pc, *mDataRequest);
89 updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions
90 mStartIR = recoData.startIR;
91
92 auto primVer2TRefs = recoData.getPrimaryVertexMatchedTrackRefs();
93 /*
94 // examples of accessing different reco data objects
95
96 auto primVertices = recoData.getPrimaryVertices();
97 auto primVerLabels = recoData.getPrimaryVertexMCLabels();
98
99 auto fddChData = recoData.getFDDChannelsData();
100 auto fddRecPoints = recoData.getFDDRecPoints();
101 auto ft0ChData = recoData.getFT0ChannelsData();
102 auto ft0RecPoints = recoData.getFT0RecPoints();
103 auto fv0ChData = recoData.getFV0ChannelsData();
104 auto fv0RecPoints = recoData.getFV0RecPoints();
105
106 auto zdcEnergies = recoData.getZDCEnergy();
107 auto zdcBCRecData = recoData.getZDCBCRecData();
108 auto zdcTDCData = recoData.getZDCTDCData();
109
110 // get calo information
111 auto caloEMCCells = recoData.getEMCALCells();
112 auto caloEMCCellsTRGR = recoData.getEMCALTriggers();
113
114 auto ctpDigits = recoData.getCTPDigits();
115 // std::unique_ptr<o2::steer::MCKinematicsReader> mcReader = std::make_unique<o2::steer::MCKinematicsReader>("collisioncontext.root");
116 */
117
118 // process tracks associated with vertices, note that the last entry corresponds to orphan tracks (no vertex)
119 for (const auto& trackRef : primVer2TRefs) {
120 processTracksOfVertex(trackRef, recoData);
121 }
122
123 if (mNeedToSave) {
124 fillData(recoData);
125 const auto& tinfo = pc.services().get<o2::framework::TimingInfo>();
126 mFTF.header.run = tinfo.runNumber;
127 mFTF.header.firstTForbit = tinfo.firstTForbit;
128 mFTF.header.creationTime = tinfo.creation;
129
130 pc.outputs().snapshot(Output{"GLO", "FILTERED_RECO_TF", 0}, mFTF);
131 clear(); // clear caches, safe after the snapshot
132 }
133
134 mTimer.Stop();
135}
136
138{
139 if (matcher == ConcreteDataMatcher("ITS", "CLUSTERDICT", 0)) {
140 LOG(info) << "ITS cluster dictionary updated";
141 mDictITS = (o2::itsmft::TopologyDictionary*)obj;
142 return;
143 }
144}
145
149
150void FilteringSpec::clear()
151{
152 mNeedToSave = false;
153 mFTF.clear(); // we can clear immidiately after the snapshot
154 mGIDToTableID.clear();
155 mITSTrackIDCache.clear();
156 mITSClusterIDCache.clear();
157}
158
159void FilteringSpec::fillData(const o2::globaltracking::RecoContainer& recoData)
160{
161 // actual data filling
162
163 // ITS tracks
164 if (!mITSTrackIDCache.empty()) {
165 const auto tracksOrig = recoData.getITSTracks();
166 const auto tracksOrigLbl = recoData.getITSTracksMCLabels();
167 const auto clusRefOrig = recoData.getITSTracksClusterRefs();
168 const auto rofsOrig = recoData.getITSTracksROFRecords();
169 auto trIt = mITSTrackIDCache.begin(); // tracks sorted in their ID
170 for (unsigned irof = 0; irof < rofsOrig.size() && trIt != mITSTrackIDCache.end(); irof++) {
171 const auto& rofOrig = rofsOrig[irof];
172 int startID = rofOrig.getFirstEntry(), endID = startID + rofOrig.getNEntries();
173 if (trIt->first >= endID) {
174 continue; // nothing from this ROF is selected
175 }
176 auto& rofSave = mFTF.ITSTrackROFs.emplace_back(rofOrig);
177 rofSave.setFirstEntry(mFTF.ITSTracks.size());
178 while (trIt != mITSTrackIDCache.end() && trIt->first < endID) {
179 trIt->second = mFTF.ITSTracks.size(); // this for the further bookkeeping?
180 const auto& trOr = tracksOrig[trIt->first];
181 auto& trSave = mFTF.ITSTracks.emplace_back(trOr);
182 trSave.setFirstClusterEntry(mFTF.ITSClusterIndices.size()); // N cluster entries is set correctly at creation
183 for (int i = 0; i < trOr.getNClusters(); i++) {
184 int clID = trOr.getClusterEntry(i);
185 mFTF.ITSClusterIndices.push_back(clID); // later will be remapped to actually stored cluster indices
186 mITSClusterIDCache[clID] = 0; // flag used cluster
187 }
188 if (mUseMC) {
189 mFTF.ITSTrackMCTruth.push_back(tracksOrigLbl[trIt->first]);
190 }
191 trIt++;
192 }
193 rofSave.setNEntries(mFTF.ITSTracks.size() - rofSave.getFirstEntry());
194 }
195 }
196 // ITS clusters info for selected tracks
197 if (!mITSClusterIDCache.empty()) {
198 const auto clusOrig = recoData.getITSClusters();
199 const auto pattOrig = recoData.getITSClustersPatterns();
200 const auto rofsOrig = recoData.getITSClustersROFRecords();
201 auto clIt = mITSClusterIDCache.begin(); // clusters sorted in their ID
202 auto pattItOrig = pattOrig.begin(), pattItOrigPrev = pattItOrig;
203 for (unsigned irof = 0; irof < rofsOrig.size() && clIt != mITSClusterIDCache.end(); irof++) {
204 const auto& rofOrig = rofsOrig[irof];
205 int startID = rofOrig.getFirstEntry(), endID = startID + rofOrig.getNEntries();
206 if (clIt->first >= endID) {
207 continue; // nothing from this ROF is selected
208 }
209 auto& rofSave = mFTF.ITSClusterROFs.emplace_back(rofOrig);
210 rofSave.setFirstEntry(mFTF.ITSTracks.size());
211 while (clIt != mITSClusterIDCache.end() && clIt->first < endID) {
212 clIt->second = mFTF.ITSClusters.size(); // new index of the stored cluster
213 const auto& clOr = clusOrig[clIt->first];
214 auto& clSave = mFTF.ITSClusters.emplace_back(clOr);
215 // cluster pattern
216 auto pattID = clOr.getPatternID();
218 if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mDictITS->isGroup(pattID)) {
219 patt.acquirePattern(pattItOrig);
220 }
221 while (pattItOrigPrev != pattItOrig) { // the difference, if any, is the explicitly stored pattern
222 mFTF.ITSClusterPatterns.push_back(*pattItOrigPrev);
223 pattItOrigPrev++;
224 }
225 clIt++;
226 }
227 rofSave.setNEntries(mFTF.ITSClusters.size() - rofSave.getFirstEntry());
228 }
229 }
230 // now remap cluster indices to stored values
231 for (auto& clID : mFTF.ITSClusterIndices) {
232 clID = mITSClusterIDCache[clID];
233 }
234}
235
236void FilteringSpec::processTracksOfVertex(const o2::dataformats::VtxTrackRef& trackRef, const o2::globaltracking::RecoContainer& recoData)
237{
238 auto GIndices = recoData.getPrimaryVertexMatchedTracks(); // Global IDs of all tracks
239 int vtxID = trackRef.getVtxID(); // -1 means that we are processing orphan tracks
240
241 for (int src = GIndex::NSources; src--;) { // loop over all possible types of tracks
242 int start = trackRef.getFirstEntryOfSource(src);
243 int end = start + trackRef.getEntriesOfSource(src);
244 for (int ti = start; ti < end; ti++) {
245 auto& trackIndex = GIndices[ti];
246 if (GIndex::includesSource(src, mInputSources)) { // should we consider this source
247
248 if (trackIndex.isAmbiguous()) { // this trak was matched to multiple vertices
249 const auto res = mGIDToTableID.find(trackIndex);
250 if (res != mGIDToTableID.end()) { // and was already processed
251 if (res->second < 0) { // was selected, just register its vertex
252 // registerVertex // FIXME: will be done once processing of all track types is complete
253 }
254 continue;
255 }
256 }
257 // here we select barrel tracks only (they must have TPC or ITS contributions)
258 if (!trackIndex.includesDet(DetID::ITS) && !trackIndex.includesDet(DetID::TPC)) {
259 continue;
260 }
261
262 int selRes = processBarrelTrack(trackIndex, recoData); // was track selected?
263 if (trackIndex.isAmbiguous()) { // remember decision on this track, if will appear again
264 mGIDToTableID[trackIndex] = selRes; // negative answer means rejection
265 }
266 }
267 }
268 }
269}
270
271int FilteringSpec::processBarrelTrack(GIndex idx, const o2::globaltracking::RecoContainer& recoData)
272{
273 int res = selectTrack(idx, recoData);
274 if (res < 0) {
275 return res;
276 }
277 mNeedToSave = true;
278 auto contributorsGID = recoData.getSingleDetectorRefs(idx);
279 //
280 // here is example of processing the ITS track
281 if (contributorsGID[GID::ITS].isIndexSet()) {
282 mITSTrackIDCache[contributorsGID[GID::ITS]] = 0;
283 }
284
285 return res;
286}
287
288bool FilteringSpec::selectTrack(GIndex id, const o2::globaltracking::RecoContainer& recoData)
289{
291 auto src = id.getSource();
292 if (src == GID::ITSTPCTRDTOF) {
293 t = recoData.getTrack<o2::track::TrackParCov>(recoData.getITSTPCTRDTOFMatches()[id].getTrackRef()); // ITSTPCTRDTOF is ITSTPCTRD + TOF cluster
294 } else if (src == GID::TPCTRDTOF) {
295 t = recoData.getTrack<o2::track::TrackParCov>(recoData.getTPCTRDTOFMatches()[id].getTrackRef()); // TPCTRDTOF is TPCTRD + TOF cluster
296 } else if (src == GID::ITSTPCTOF) {
297 t = recoData.getTrack<o2::track::TrackParCov>(recoData.getTOFMatch(id).getTrackRef()); // ITSTPCTOF is ITSTPC + TOF cluster
298 } else { // for the rest, get the track directly
299 t = recoData.getTrack<o2::track::TrackParCov>(id);
300 }
301 // select on track kinematics, for example, on pT
302 if (t.getPt() < 2.) {
303 return false;
304 }
305 return true;
306}
307
309{
310 LOGF(info, "data filtering total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
311}
312
313void FilteringSpec::updateTimeDependentParams(ProcessingContext& pc)
314{
315 static bool initOnceDone = false;
316 if (!initOnceDone) { // this params need to be queried only once
317 initOnceDone = true;
318 }
319}
320
322{
323 std::vector<OutputSpec> outputs;
324 outputs.emplace_back("GLO", "FILTERED_RECO_TF", 0, o2::framework::Lifetime::Sporadic); // sporadic to avoid sensing TFs which had no selected stuff
325
326 auto dataRequest = std::make_shared<DataRequest>();
327
328 dataRequest->requestTracks(src, useMC);
329 dataRequest->requestPrimaryVertices(useMC);
330 if (src[GID::CTP]) {
331 LOGF(info, "Requesting CTP digits");
332 dataRequest->requestCTPDigits(useMC);
333 }
334 if (enableSV) {
335 dataRequest->requestSecondaryVertices(useMC);
336 }
337 if (src[GID::TPC]) {
338 dataRequest->requestClusters(GIndex::getSourcesMask("TPC"), false); // no need to ask for TOF clusters as they are requested with TOF tracks
339 }
340 if (src[GID::EMC]) {
341 dataRequest->requestEMCALCells(useMC);
342 }
343
344 return DataProcessorSpec{
345 "reco-data-filter",
346 dataRequest->inputs,
347 outputs,
348 AlgorithmSpec{adaptFromTask<FilteringSpec>(src, dataRequest, enableSV, useMC)},
349 Options{/*ConfigParamSpec{"reco-mctracks-only", VariantType::Int, 0, {"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}}*/}};
350}
351
352} // namespace o2::filtering
General auxilliary methods.
Wrapper container for different reconstructed object types.
Base track model for the Barrel, params only, w/o covariance.
Definition of the GeometryManager class.
definition of CTPDigit, CTPInputDigit
Base definition of FV0 geometry.
Definition of the FIT RecPoints class.
int32_t i
Global Forward Muon tracks.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
A helper class to iteratate over all parts of all input routes.
Definition of the MCTrack class.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Utility functions for MC particles.
Definition of the MCH ROFrame record.
MID filtering spec.
Class to perform TOF matching to global tracks.
Definition of the Names Generator class.
Definition of the parameter class for the detector electronics.
Header to collect physics constants.
uint32_t res
Definition RawData.h:0
Definition of the FDD RecPoint class.
Definition of tools for track extrapolation.
Definition of the ITS track.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
Result of refitting TPC-ITS matched track.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
Container class to store energy released in the ZDC.
Container class to store a TDC hit in a ZDC channel.
static mask_t getSourcesMask(const std::string_view srcList)
int getEntriesOfSource(int s) const
Definition VtxTrackRef.h:62
int getFirstEntryOfSource(int s) const
Definition VtxTrackRef.h:55
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
static constexpr ID ITS
Definition DetID.h:63
static constexpr ID TPC
Definition DetID.h:64
void init(InitContext &ic) final
void finaliseCCDB(ConcreteDataMatcher &, void *) final
void run(ProcessingContext &pc) final
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void snapshot(const Output &spec, T const &object)
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
ServiceRegistryRef services()
The services registry associated with this processing context.
void acquirePattern(iterator &pattIt)
static constexpr unsigned short InvalidPatternID
Definition CompCluster.h:46
bool isGroup(int n) const
Returns true if the element corresponds to a group of rare topologies.
GLenum src
Definition glcorearb.h:1767
GLuint GLuint end
Definition glcorearb.h:469
GLuint start
Definition glcorearb.h:469
GLuint id
Definition glcorearb.h:650
DataProcessorSpec getDataFilteringSpec(GID::mask_t src, bool enableSV, bool useMC)
create a processor spec
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
TrackParCovF TrackParCov
Definition Track.h:33
std::vector< o2::itsmft::ROFRecord > ITSClusterROFs
std::vector< o2::its::TrackITS > ITSTracks
std::vector< o2::MCCompLabel > ITSTrackMCTruth
std::vector< o2::itsmft::ROFRecord > ITSTrackROFs
std::vector< int > ITSClusterIndices
std::vector< unsigned char > ITSClusterPatterns
std::vector< o2::itsmft::CompClusterExt > ITSClusters
const U & getTrack(int src, int id) const
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::dataformats::MatchInfoTOF & getTOFMatch(GTrackID id) const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"