Project
Loading...
Searching...
No Matches
TrackAtVertexSpec.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
16
17#include "TrackAtVertexSpec.h"
18
19#include <chrono>
20#include <stdexcept>
21#include <list>
22
23#include <gsl/span>
24#include <filesystem>
25
26#include <TMath.h>
27#include <TGeoManager.h>
28#include <TGeoGlobalMagField.h>
29
32
36#include "Framework/Lifetime.h"
37#include "Framework/Output.h"
38#include "Framework/Task.h"
39
42#include "MathUtils/Cartesian.h"
43#include "Field/MagneticField.h"
46#include "MCHBase/TrackBlock.h"
49
50namespace o2
51{
52namespace mch
53{
54
55struct TrackAtVtxStruct {
56 TrackParamStruct paramAtVertex{};
57 double dca = 0.;
58 double rAbs = 0.;
59 int mchTrackIdx = 0;
60};
61
62using namespace std;
63using namespace o2::framework;
64
66{
67 public:
68 void initFromGRP(std::string grpFile)
69 {
70 const auto grp = o2::parameters::GRPObject::loadFrom(grpFile);
74 }
75
77 {
78 if (!gGeoManager) {
80 if (!gGeoManager) {
81 throw std::runtime_error("cannot load the geometry");
82 }
83 }
84
85 if (!TGeoGlobalMagField::Instance()->GetField()) {
86 auto l3Current = ic.options().get<float>("l3Current");
87 auto dipoleCurrent = ic.options().get<float>("dipoleCurrent");
88 auto field = o2::field::MagneticField::createFieldMap(l3Current, dipoleCurrent, o2::field::MagneticField::kConvLHC, false,
89 3500., "A-A", "$(O2_ROOT)/share/Common/maps/mfchebKGI_sym.root");
90 TGeoGlobalMagField::Instance()->SetField(field);
91 TGeoGlobalMagField::Instance()->Lock();
93 }
94 }
95
96 //_________________________________________________________________________________________________
98 {
100
101 LOG(info) << "initializing track extrapolation to vertex";
102
103 auto grpFile = ic.options().get<std::string>("grp-file");
104 if (std::filesystem::exists(grpFile)) {
105 initFromGRP(grpFile);
106 } else {
107 initCustom(ic);
108 }
109
110 auto stop = [this]() {
111 LOG(info) << "track propagation to vertex duration = " << mElapsedTime.count() << " s";
112 };
113 ic.services().get<CallbackService>().set<CallbackService::Id::Stop>(stop);
114 }
115
116 //_________________________________________________________________________________________________
118 {
120
121 // get the ROFs, tracks and vertices
122 auto rofs = pc.inputs().get<gsl::span<ROFRecord>>("rofs");
123 auto tracks = pc.inputs().get<gsl::span<TrackMCH>>("tracks");
124 auto vertices = pc.inputs().get<gsl::span<math_utils::Point3D<double>>>("vertices");
125
126 if (vertices.size() != rofs.size()) {
127 throw length_error("number of vertices different from number of events");
128 }
129
130 // for each event, propagate the tracks to the vertex
131 mTracksAtVtx.clear();
132 int iVertex(-1);
133 int nTracksTot(0);
134 for (const auto& rof : rofs) {
135 auto tStart = std::chrono::high_resolution_clock::now();
136 nTracksTot += extrapTracksToVertex(tracks.subspan(rof.getFirstIdx(), rof.getNEntries()), vertices[++iVertex]);
137 auto tEnd = std::chrono::high_resolution_clock::now();
138 mElapsedTime += tEnd - tStart;
139 }
140
141 // create the output message
142 auto msgOut = pc.outputs().make<char>(Output{"MCH", "TRACKSATVERTEX", 0},
143 mTracksAtVtx.size() * sizeof(int) + nTracksTot * sizeof(TrackAtVtxStruct));
144
145 // write the tracks
146 writeTracks(msgOut.data());
147 }
148
149 private:
150 //_________________________________________________________________________________________________
151 int extrapTracksToVertex(gsl::span<const TrackMCH> tracks, const math_utils::Point3D<double>& vertex)
152 {
155
156 auto& tracksAtVtx = mTracksAtVtx.emplace_back();
157 int trackIdx(-1);
158
159 for (const auto& track : tracks) {
160
161 // create a new track at vertex pointing to the current track (index within the current event)
162 auto& trackAtVtx = tracksAtVtx.emplace_back();
163 trackAtVtx.mchTrackIdx = ++trackIdx;
164
165 // extrapolate to vertex
166 TrackParam trackParamAtVertex(track.getZ(), track.getParameters());
167 if (!TrackExtrap::extrapToVertex(trackParamAtVertex, vertex.x(), vertex.y(), vertex.z(), 0., 0.)) {
168 tracksAtVtx.pop_back();
169 continue;
170 }
171 trackAtVtx.paramAtVertex.x = trackParamAtVertex.getNonBendingCoor();
172 trackAtVtx.paramAtVertex.y = trackParamAtVertex.getBendingCoor();
173 trackAtVtx.paramAtVertex.z = trackParamAtVertex.getZ();
174 trackAtVtx.paramAtVertex.px = trackParamAtVertex.px();
175 trackAtVtx.paramAtVertex.py = trackParamAtVertex.py();
176 trackAtVtx.paramAtVertex.pz = trackParamAtVertex.pz();
177 trackAtVtx.paramAtVertex.sign = trackParamAtVertex.getCharge();
178
179 // extrapolate to DCA
180 TrackParam trackParamAtDCA(track.getZ(), track.getParameters());
181 if (!TrackExtrap::extrapToVertexWithoutBranson(trackParamAtDCA, vertex.z())) {
182 tracksAtVtx.pop_back();
183 continue;
184 }
185 double dcaX = trackParamAtDCA.getNonBendingCoor() - vertex.x();
186 double dcaY = trackParamAtDCA.getBendingCoor() - vertex.y();
187 trackAtVtx.dca = TMath::Sqrt(dcaX * dcaX + dcaY * dcaY);
188
189 // extrapolate to the end of the absorber
190 TrackParam trackParamAtRAbs(track.getZ(), track.getParameters());
191 if (!TrackExtrap::extrapToZ(trackParamAtRAbs, -505.)) {
192 tracksAtVtx.pop_back();
193 continue;
194 }
195 double xAbs = trackParamAtRAbs.getNonBendingCoor();
196 double yAbs = trackParamAtRAbs.getBendingCoor();
197 trackAtVtx.rAbs = TMath::Sqrt(xAbs * xAbs + yAbs * yAbs);
198 }
199
200 return tracksAtVtx.size();
201 }
202
203 //_________________________________________________________________________________________________
204 void writeTracks(char* bufferPtr) const
205 {
207
208 for (const auto& tracksAtVtx : mTracksAtVtx) {
209
210 // write the number of tracks
211 int nTracks = tracksAtVtx.size();
212 memcpy(bufferPtr, &nTracks, sizeof(int));
213 bufferPtr += sizeof(int);
214
215 // write the tracks
216 if (nTracks > 0) {
217 memcpy(bufferPtr, tracksAtVtx.data(), nTracks * sizeof(TrackAtVtxStruct));
218 bufferPtr += nTracks * sizeof(TrackAtVtxStruct);
219 }
220 }
221 }
222
223 std::vector<std::vector<TrackAtVtxStruct>> mTracksAtVtx{};
224 std::chrono::duration<double> mElapsedTime{};
225};
226
227//_________________________________________________________________________________________________
229{
230 return DataProcessorSpec{
231 specName,
232 Inputs{InputSpec{"vertices", "MCH", "VERTICES", 0, Lifetime::Timeframe},
233 InputSpec{"rofs", "MCH", "TRACKROFS", 0, Lifetime::Timeframe},
234 InputSpec{"tracks", "MCH", "TRACKS", 0, Lifetime::Timeframe},
235 InputSpec{"clusters", "MCH", "TRACKCLUSTERS", 0, Lifetime::Timeframe}},
236 Outputs{OutputSpec{{"tracksatvertex"}, "MCH", "TRACKSATVERTEX", 0, Lifetime::Timeframe}},
237 AlgorithmSpec{adaptFromTask<TrackAtVertexTask>()},
238 Options{
239 {"grp-file", VariantType::String, o2::base::NameConf::getGRPFileName(), {"Name of the grp file"}},
240 {"l3Current", VariantType::Float, -30000.0f, {"L3 current"}},
241 {"dipoleCurrent", VariantType::Float, -6000.0f, {"Dipole current"}}}};
242}
243
244} // namespace mch
245} // namespace o2
Definition of the GeometryManager class.
uint64_t vertex
Definition RawEventData.h:9
Header of the General Run Parameters object.
Definition of the MCH ROFrame record.
Definition of the MagF class.
Definition of the Names Generator class.
Definition of a data processor to extrapolate the tracks to the vertex.
Definition of the MCH track parameters minimal structure.
Definition of tools for track extrapolation.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
const char * specName
static void loadGeometry(std::string_view geomFilePath="", bool applyMisalignment=false, bool preferAlignedFile=true)
static std::string getGRPFileName(const std::string_view prefix=STANDARDSIMPREFIX)
Definition NameConf.cxx:58
static int initFieldFromGRP(const o2::parameters::GRPMagField *grp, bool verbose=false)
static MagneticField * createFieldMap(float l3Current=-30000., float diCurrent=-6000., Int_t convention=0, Bool_t uniform=kFALSE, float beamenergy=7000, const Char_t *btype="pp", const std::string path=std::string(gSystem->Getenv("VMCWORKDIR"))+std::string("/Common/maps/mfchebKGI_sym.root"))
decltype(auto) make(const Output &spec, Args... args)
ServiceRegistryRef services()
Definition InitContext.h:34
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.
void init(framework::InitContext &ic)
void initCustom(framework::InitContext &ic)
void initFromGRP(std::string grpFile)
void run(framework::ProcessingContext &pc)
static bool extrapToZ(TrackParam &trackParam, double zEnd)
static void setField()
static bool extrapToVertex(TrackParam &trackParam, double xVtx, double yVtx, double zVtx, double errXVtx, double errYVtx)
Definition TrackExtrap.h:61
static bool extrapToVertexWithoutBranson(TrackParam &trackParam, double zVtx)
Definition TrackExtrap.h:73
track parameters for internal use
Definition TrackParam.h:34
static GRPObject * loadFrom(const std::string &grpFileName="")
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > Inputs
std::vector< OutputSpec > Outputs
o2::framework::DataProcessorSpec getTrackAtVertexSpec(const char *specName)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
TrackParamStruct paramAtVertex
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"