2626#include "DataFormatsTPC/TrackCuts.h"
2727#include "DetectorsCalibration/Utils.h"
2828#include "Framework/Logger.h"
29+ #include "DetectorsBase/GRPGeomHelper.h"
2930#include "Framework/Task.h"
31+ #include "DetectorsBase/Propagator.h"
3032#include "Framework/DataProcessorSpec.h"
3133#include "Framework/ConfigParamRegistry.h"
3234#include "TPCWorkflow/ProcessingHelpers.h"
@@ -40,20 +42,27 @@ namespace o2::tpc
4042class MIPTrackFilterDevice : public Task
4143{
4244 public:
45+ MIPTrackFilterDevice(std::shared_ptr<o2::base::GRPGeomRequest> gr) : mGRPGeomRequest(gr) {}
46+
4347 void init(framework::InitContext& ic) final;
4448 void run(ProcessingContext& pc) final;
4549 void endOfStream(EndOfStreamContext& eos) final;
50+ void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final;
4651
4752 private:
4853 void sendOutput(DataAllocator& output);
4954
55+ std::shared_ptr<o2::base::GRPGeomRequest> mGRPGeomRequest;
5056 TrackCuts mCuts{}; ///< Tracks cuts object
5157 std::vector<TrackTPC> mMIPTracks; ///< Filtered MIP tracks
5258 unsigned int mProcessEveryNthTF{1}; ///< process every Nth TF only
5359 int mMaxTracksPerTF{-1}; ///< max number of MIP tracks processed per TF
5460 uint32_t mTFCounter{0}; ///< counter to keep track of the TFs
5561 int mProcessNFirstTFs{0}; ///< number of first TFs which are not sampled
62+ float mDCACut{-1}; ///< DCA cut
5663 bool mSendDummy{false}; ///< send empty data in case TF is skipped
64+
65+ bool acceptDCA(const TrackTPC& track);
5766};
5867
5968void MIPTrackFilterDevice::init(framework::InitContext& ic)
@@ -89,6 +98,10 @@ void MIPTrackFilterDevice::init(framework::InitContext& ic)
8998 mCuts.setdEdxMin(mindEdx);
9099 mCuts.setdEdxMax(maxdEdx);
91100 mCuts.setCutLooper(cutLoopers);
101+
102+ mDCACut = ic.options().get<float>("dca-cut");
103+
104+ o2::base::GRPGeomHelper::instance().setRequest(mGRPGeomRequest);
92105}
93106
94107void MIPTrackFilterDevice::run(ProcessingContext& pc)
@@ -102,6 +115,7 @@ void MIPTrackFilterDevice::run(ProcessingContext& pc)
102115 }
103116 return;
104117 }
118+ o2::base::GRPGeomHelper::instance().checkUpdates(pc);
105119
106120 const auto tracks = pc.inputs().get<gsl::span<TrackTPC>>("tracks");
107121 const auto nTracks = tracks.size();
@@ -111,7 +125,7 @@ void MIPTrackFilterDevice::run(ProcessingContext& pc)
111125 std::vector<size_t> indices;
112126 indices.reserve(nTracks);
113127 for (size_t i = 0; i < nTracks; ++i) {
114- if (mCuts.goodTrack(tracks[i])) {
128+ if (mCuts.goodTrack(tracks[i]) && acceptDCA(tracks[i]) ) {
115129 indices.emplace_back(i);
116130 }
117131 }
@@ -135,33 +149,66 @@ void MIPTrackFilterDevice::run(ProcessingContext& pc)
135149 mMIPTracks.emplace_back(tracks[indices[i]]);
136150 }
137151 } else {
138- std::copy_if(tracks.begin(), tracks.end(), std::back_inserter(mMIPTracks), [this](const auto& track) { return mCuts.goodTrack(track); });
152+ std::copy_if(tracks.begin(), tracks.end(), std::back_inserter(mMIPTracks), [this](const auto& track) { return mCuts.goodTrack(track) && acceptDCA(track) ; });
139153 }
140154
141155 LOGP(info, "Filtered {} MIP tracks out of {} total tpc tracks", mMIPTracks.size(), tracks.size());
142156 sendOutput(pc.outputs());
143157 mMIPTracks.clear();
144158}
145159
160+ void MIPTrackFilterDevice::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
161+ {
162+ if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
163+ return;
164+ }
165+ }
166+
146167void MIPTrackFilterDevice::sendOutput(DataAllocator& output) { output.snapshot(Output{header::gDataOriginTPC, "MIPS", 0}, mMIPTracks); }
147168
148169void MIPTrackFilterDevice::endOfStream(EndOfStreamContext& eos)
149170{
150171 LOG(info) << "Finalizig MIP Tracks filter";
151172}
152173
174+ bool MIPTrackFilterDevice::acceptDCA(const TrackTPC& track)
175+ {
176+ if (mDCACut < 0) {
177+ return true;
178+ }
179+
180+ auto propagator = o2::base::Propagator::Instance();
181+ o2::gpu::gpustd::array<float, 2> dca;
182+ const o2::math_utils::Point3D<float> refPoint{0, 0, 0};
183+ o2::track::TrackPar propTrack(track);
184+ const auto ok = propagator->propagateToDCABxByBz(refPoint, propTrack, 2., o2::base::Propagator::MatCorrType::USEMatCorrLUT, &dca);
185+ const auto dcar = std::abs(dca[0]);
186+
187+ return ok && (dcar < mDCACut);
188+ }
189+
153190DataProcessorSpec getMIPTrackFilterSpec()
154191{
155192 std::vector<OutputSpec> outputs;
156193 outputs.emplace_back(header::gDataOriginTPC, "MIPS", 0, Lifetime::Sporadic);
157194
195+ std::vector<InputSpec> inputs;
196+ inputs.emplace_back("tracks", "TPC", "TRACKS");
197+
198+ auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
199+ true, // GRPECS=true
200+ false, // GRPLHCIF
201+ true, // GRPMagField
202+ true, // askMatLUT
203+ o2::base::GRPGeomRequest::Aligned, // geometry
204+ inputs,
205+ true);
206+
158207 return DataProcessorSpec{
159208 "tpc-miptrack-filter",
160- Inputs{
161- InputSpec{"tracks", "TPC", "TRACKS"},
162- },
209+ inputs,
163210 outputs,
164- adaptFromTask<MIPTrackFilterDevice>(),
211+ adaptFromTask<MIPTrackFilterDevice>(ggRequest ),
165212 Options{
166213 {"min-momentum", VariantType::Double, 0.35, {"minimum momentum cut"}},
167214 {"max-momentum", VariantType::Double, 0.55, {"maximum momentum cut"}},
@@ -172,7 +219,9 @@ DataProcessorSpec getMIPTrackFilterSpec()
172219 {"maxTracksPerTF", VariantType::Int, -1, {"Maximum number of processed tracks per TF (-1 for processing all tracks)"}},
173220 {"process-first-n-TFs", VariantType::Int, 1, {"Number of first TFs which are not sampled"}},
174221 {"send-dummy-data", VariantType::Bool, false, {"Send empty data in case TF is skipped"}},
175- {"dont-cut-loopers", VariantType::Bool, false, {"Do not cut loopers by comparing zout-zin"}}}};
222+ {"dont-cut-loopers", VariantType::Bool, false, {"Do not cut loopers by comparing zout-zin"}},
223+ {"dca-cut", VariantType::Float, 3.f, {"DCA cut in cm, < 0 to disable"}},
224+ }};
176225}
177226
178227} // namespace o2::tpc
0 commit comments