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"
43#include "FDDBase/Constants.h"
44#include "FT0Base/Geometry.h"
45#include "FV0Base/Geometry.h"
63#include "ZDCBase/Constants.h"
66#include "TOFBase/Utils.h"
67#include "TMath.h"
68#include "MathUtils/Utils.h"
69#include <map>
70#include <unordered_map>
71#include <string>
72#include <vector>
73
74using namespace o2::framework;
75using namespace o2::math_utils::detail;
81
82namespace o2::filtering
83{
84
86{
87 mTimer.Start(false);
89 recoData.collectData(pc, *mDataRequest);
90 updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions
91 mStartIR = recoData.startIR;
92
93 auto primVer2TRefs = recoData.getPrimaryVertexMatchedTrackRefs();
94 /*
95 // examples of accessing different reco data objects
96
97 auto primVertices = recoData.getPrimaryVertices();
98 auto primVerLabels = recoData.getPrimaryVertexMCLabels();
99
100 auto fddChData = recoData.getFDDChannelsData();
101 auto fddRecPoints = recoData.getFDDRecPoints();
102 auto ft0ChData = recoData.getFT0ChannelsData();
103 auto ft0RecPoints = recoData.getFT0RecPoints();
104 auto fv0ChData = recoData.getFV0ChannelsData();
105 auto fv0RecPoints = recoData.getFV0RecPoints();
106
107 auto zdcEnergies = recoData.getZDCEnergy();
108 auto zdcBCRecData = recoData.getZDCBCRecData();
109 auto zdcTDCData = recoData.getZDCTDCData();
110
111 // get calo information
112 auto caloEMCCells = recoData.getEMCALCells();
113 auto caloEMCCellsTRGR = recoData.getEMCALTriggers();
114
115 auto ctpDigits = recoData.getCTPDigits();
116 // std::unique_ptr<o2::steer::MCKinematicsReader> mcReader = std::make_unique<o2::steer::MCKinematicsReader>("collisioncontext.root");
117 */
118
119 // process tracks associated with vertices, note that the last entry corresponds to orphan tracks (no vertex)
120 for (const auto& trackRef : primVer2TRefs) {
121 processTracksOfVertex(trackRef, recoData);
122 }
123
124 if (mNeedToSave) {
125 fillData(recoData);
126 const auto& tinfo = pc.services().get<o2::framework::TimingInfo>();
127 mFTF.header.run = tinfo.runNumber;
128 mFTF.header.firstTForbit = tinfo.firstTForbit;
129 mFTF.header.creationTime = tinfo.creation;
130
131 pc.outputs().snapshot(Output{"GLO", "FILTERED_RECO_TF", 0}, mFTF);
132 clear(); // clear caches, safe after the snapshot
133 }
134
135 mTimer.Stop();
136}
137
139{
140 if (matcher == ConcreteDataMatcher("ITS", "CLUSTERDICT", 0)) {
141 LOG(info) << "ITS cluster dictionary updated";
142 mDictITS = (o2::itsmft::TopologyDictionary*)obj;
143 return;
144 }
145}
146
150
151void FilteringSpec::clear()
152{
153 mNeedToSave = false;
154 mFTF.clear(); // we can clear immidiately after the snapshot
155 mGIDToTableID.clear();
156 mITSTrackIDCache.clear();
157 mITSClusterIDCache.clear();
158}
159
160void FilteringSpec::fillData(const o2::globaltracking::RecoContainer& recoData)
161{
162 // actual data filling
163
164 // ITS tracks
165 if (!mITSTrackIDCache.empty()) {
166 const auto tracksOrig = recoData.getITSTracks();
167 const auto tracksOrigLbl = recoData.getITSTracksMCLabels();
168 const auto clusRefOrig = recoData.getITSTracksClusterRefs();
169 const auto rofsOrig = recoData.getITSTracksROFRecords();
170 auto trIt = mITSTrackIDCache.begin(); // tracks sorted in their ID
171 for (unsigned irof = 0; irof < rofsOrig.size() && trIt != mITSTrackIDCache.end(); irof++) {
172 const auto& rofOrig = rofsOrig[irof];
173 int startID = rofOrig.getFirstEntry(), endID = startID + rofOrig.getNEntries();
174 if (trIt->first >= endID) {
175 continue; // nothing from this ROF is selected
176 }
177 auto& rofSave = mFTF.ITSTrackROFs.emplace_back(rofOrig);
178 rofSave.setFirstEntry(mFTF.ITSTracks.size());
179 while (trIt != mITSTrackIDCache.end() && trIt->first < endID) {
180 trIt->second = mFTF.ITSTracks.size(); // this for the further bookkeeping?
181 const auto& trOr = tracksOrig[trIt->first];
182 auto& trSave = mFTF.ITSTracks.emplace_back(trOr);
183 trSave.setFirstClusterEntry(mFTF.ITSClusterIndices.size()); // N cluster entries is set correctly at creation
184 for (int i = 0; i < trOr.getNClusters(); i++) {
185 int clID = trOr.getClusterEntry(i);
186 mFTF.ITSClusterIndices.push_back(clID); // later will be remapped to actually stored cluster indices
187 mITSClusterIDCache[clID] = 0; // flag used cluster
188 }
189 if (mUseMC) {
190 mFTF.ITSTrackMCTruth.push_back(tracksOrigLbl[trIt->first]);
191 }
192 trIt++;
193 }
194 rofSave.setNEntries(mFTF.ITSTracks.size() - rofSave.getFirstEntry());
195 }
196 }
197 // ITS clusters info for selected tracks
198 if (!mITSClusterIDCache.empty()) {
199 const auto clusOrig = recoData.getITSClusters();
200 const auto pattOrig = recoData.getITSClustersPatterns();
201 const auto rofsOrig = recoData.getITSClustersROFRecords();
202 auto clIt = mITSClusterIDCache.begin(); // clusters sorted in their ID
203 auto pattItOrig = pattOrig.begin(), pattItOrigPrev = pattItOrig;
204 for (unsigned irof = 0; irof < rofsOrig.size() && clIt != mITSClusterIDCache.end(); irof++) {
205 const auto& rofOrig = rofsOrig[irof];
206 int startID = rofOrig.getFirstEntry(), endID = startID + rofOrig.getNEntries();
207 if (clIt->first >= endID) {
208 continue; // nothing from this ROF is selected
209 }
210 auto& rofSave = mFTF.ITSClusterROFs.emplace_back(rofOrig);
211 rofSave.setFirstEntry(mFTF.ITSTracks.size());
212 while (clIt != mITSClusterIDCache.end() && clIt->first < endID) {
213 clIt->second = mFTF.ITSClusters.size(); // new index of the stored cluster
214 const auto& clOr = clusOrig[clIt->first];
215 auto& clSave = mFTF.ITSClusters.emplace_back(clOr);
216 // cluster pattern
217 auto pattID = clOr.getPatternID();
219 if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mDictITS->isGroup(pattID)) {
220 patt.acquirePattern(pattItOrig);
221 }
222 while (pattItOrigPrev != pattItOrig) { // the difference, if any, is the explicitly stored pattern
223 mFTF.ITSClusterPatterns.push_back(*pattItOrigPrev);
224 pattItOrigPrev++;
225 }
226 clIt++;
227 }
228 rofSave.setNEntries(mFTF.ITSClusters.size() - rofSave.getFirstEntry());
229 }
230 }
231 // now remap cluster indices to stored values
232 for (auto& clID : mFTF.ITSClusterIndices) {
233 clID = mITSClusterIDCache[clID];
234 }
235}
236
237void FilteringSpec::processTracksOfVertex(const o2::dataformats::VtxTrackRef& trackRef, const o2::globaltracking::RecoContainer& recoData)
238{
239 auto GIndices = recoData.getPrimaryVertexMatchedTracks(); // Global IDs of all tracks
240 int vtxID = trackRef.getVtxID(); // -1 means that we are processing orphan tracks
241
242 for (int src = GIndex::NSources; src--;) { // loop over all possible types of tracks
243 int start = trackRef.getFirstEntryOfSource(src);
244 int end = start + trackRef.getEntriesOfSource(src);
245 for (int ti = start; ti < end; ti++) {
246 auto& trackIndex = GIndices[ti];
247 if (GIndex::includesSource(src, mInputSources)) { // should we consider this source
248
249 if (trackIndex.isAmbiguous()) { // this trak was matched to multiple vertices
250 const auto res = mGIDToTableID.find(trackIndex);
251 if (res != mGIDToTableID.end()) { // and was already processed
252 if (res->second < 0) { // was selected, just register its vertex
253 // registerVertex // FIXME: will be done once processing of all track types is complete
254 }
255 continue;
256 }
257 }
258 // here we select barrel tracks only (they must have TPC or ITS contributions)
259 if (!trackIndex.includesDet(DetID::ITS) && !trackIndex.includesDet(DetID::TPC)) {
260 continue;
261 }
262
263 int selRes = processBarrelTrack(trackIndex, recoData); // was track selected?
264 if (trackIndex.isAmbiguous()) { // remember decision on this track, if will appear again
265 mGIDToTableID[trackIndex] = selRes; // negative answer means rejection
266 }
267 }
268 }
269 }
270}
271
272int FilteringSpec::processBarrelTrack(GIndex idx, const o2::globaltracking::RecoContainer& recoData)
273{
274 int res = selectTrack(idx, recoData);
275 if (res < 0) {
276 return res;
277 }
278 mNeedToSave = true;
279 auto contributorsGID = recoData.getSingleDetectorRefs(idx);
280 //
281 // here is example of processing the ITS track
282 if (contributorsGID[GID::ITS].isIndexSet()) {
283 mITSTrackIDCache[contributorsGID[GID::ITS]] = 0;
284 }
285
286 return res;
287}
288
289bool FilteringSpec::selectTrack(GIndex id, const o2::globaltracking::RecoContainer& recoData)
290{
292 auto src = id.getSource();
293 if (src == GID::ITSTPCTRDTOF) {
294 t = recoData.getTrack<o2::track::TrackParCov>(recoData.getITSTPCTRDTOFMatches()[id].getTrackRef()); // ITSTPCTRDTOF is ITSTPCTRD + TOF cluster
295 } else if (src == GID::TPCTRDTOF) {
296 t = recoData.getTrack<o2::track::TrackParCov>(recoData.getTPCTRDTOFMatches()[id].getTrackRef()); // TPCTRDTOF is TPCTRD + TOF cluster
297 } else if (src == GID::ITSTPCTOF) {
298 t = recoData.getTrack<o2::track::TrackParCov>(recoData.getTOFMatch(id).getTrackRef()); // ITSTPCTOF is ITSTPC + TOF cluster
299 } else { // for the rest, get the track directly
300 t = recoData.getTrack<o2::track::TrackParCov>(id);
301 }
302 // select on track kinematics, for example, on pT
303 if (t.getPt() < 2.) {
304 return false;
305 }
306 return true;
307}
308
310{
311 LOGF(info, "data filtering total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
312}
313
314void FilteringSpec::updateTimeDependentParams(ProcessingContext& pc)
315{
316 static bool initOnceDone = false;
317 if (!initOnceDone) { // this params need to be queried only once
318 initOnceDone = true;
319 }
320}
321
323{
324 std::vector<OutputSpec> outputs;
325 outputs.emplace_back("GLO", "FILTERED_RECO_TF", 0, o2::framework::Lifetime::Sporadic); // sporadic to avoid sensing TFs which had no selected stuff
326
327 auto dataRequest = std::make_shared<DataRequest>();
328
329 dataRequest->requestTracks(src, useMC);
330 dataRequest->requestPrimaryVertices(useMC);
331 if (src[GID::CTP]) {
332 LOGF(info, "Requesting CTP digits");
333 dataRequest->requestCTPDigits(useMC);
334 }
335 if (enableSV) {
336 dataRequest->requestSecondaryVertices(useMC);
337 }
338 if (src[GID::TPC]) {
339 dataRequest->requestClusters(GIndex::getSourcesMask("TPC"), false); // no need to ask for TOF clusters as they are requested with TOF tracks
340 }
341 if (src[GID::EMC]) {
342 dataRequest->requestEMCALCells(useMC);
343 }
344
345 return DataProcessorSpec{
346 "reco-data-filter",
347 dataRequest->inputs,
348 outputs,
349 AlgorithmSpec{adaptFromTask<FilteringSpec>(src, dataRequest, enableSV, useMC)},
350 Options{/*ConfigParamSpec{"reco-mctracks-only", VariantType::Int, 0, {"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}}*/}};
351}
352
353} // 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"