Project
Loading...
Searching...
No Matches
AlignRecordSpec.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#include <filesystem>
12#include <sstream>
13
15
19#include "MathUtils/Utils.h"
29#include "Framework/DataTypes.h"
33#include "Framework/Task.h"
34#include "FT0Base/Geometry.h"
41#include "MCHAlign/Aligner.h"
55
56#include <TTree.h>
57#include <TChain.h>
58
59const int fgNCh = 10;
60const int fgNDetElemCh[fgNCh] = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26};
61const int fgSNDetElemCh[fgNCh + 1] = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156};
62
63namespace o2
64{
65namespace mch
66{
67
68using namespace o2;
69using namespace o2::framework;
70using namespace o2::framework::expressions;
71
72using namespace std;
73using std::cout;
74using std::endl;
77
79{
80 public:
81 //_________________________________________________________________________________________________
82 AlignRecordTask(std::shared_ptr<DataRequest> dataRequest, std::shared_ptr<base::GRPGeomRequest> ccdbRequest, bool useMC = true)
83 : mDataRequest(dataRequest), mCCDBRequest(ccdbRequest), mUseMC(useMC) {}
84
85 //_________________________________________________________________________________________________
87 {
88
89 LOG(info) << "initializing align record maker";
90 mTrackCount = 0;
91 mTrackMatched = 0;
92 if (mCCDBRequest) {
94 } else {
95 auto grpFile = ic.options().get<std::string>("grp-file");
96 if (std::filesystem::exists(grpFile)) {
97 const auto grp = parameters::GRPObject::loadFrom(grpFile);
102 } else {
103 LOG(fatal) << "GRP file doesn't exist!";
104 }
105 }
106
107 // Configuration for alignment object
108 mAlign.SetDoEvaluation(false);
109 mAlign.DisableRecordWriter();
110 mAlign.SetAllowedVariation(0, 2.0);
111 mAlign.SetAllowedVariation(1, 0.3);
112 mAlign.SetAllowedVariation(2, 0.002);
113 mAlign.SetAllowedVariation(3, 2.0);
114
115 // Configuration for track fitter
116 const auto& trackerParam = TrackerParam::Instance();
117 trackFitter.setBendingVertexDispersion(trackerParam.bendingVertexDispersion);
118 trackFitter.setChamberResolution(trackerParam.chamberResolutionX, trackerParam.chamberResolutionY);
119 trackFitter.smoothTracks(true);
120 trackFitter.useChamberResolution();
121 mImproveCutChi2 = 2. * trackerParam.sigmaCutForImprovement * trackerParam.sigmaCutForImprovement;
122
123 // Configuration for chamber fixing
124 auto input_fixchambers = ic.options().get<string>("fix-chamber");
125 std::stringstream string_chambers(input_fixchambers);
126 string_chambers >> std::ws;
127 while (string_chambers.good()) {
128 string substr;
129 std::getline(string_chambers, substr, ',');
130 LOG(info) << Form("%s%d", "Fixing chamber: ", std::stoi(substr));
131 mAlign.FixChamber(std::stoi(substr));
132 }
133
134 // Init for output saving
135 auto OutputRecFileName = ic.options().get<string>("output-record-data");
136 auto OutputConsFileName = ic.options().get<string>("output-record-constraint");
137 mAlign.init(OutputRecFileName, OutputConsFileName);
138
139 ic.services().get<CallbackService>().set<CallbackService::Id::Stop>([this]() {
140 LOG(info) << "Saving records into ROOT file";
141 LOG(info) << "Nb of records to be saved: " << mTrackCount;
142 LOG(info) << "Nb of matched MCH-MID tracks: " << mTrackMatched;
143 mAlign.terminate();
144 });
145 }
146
147 //_________________________________________________________________________________________________
149 {
151 if (mCCDBRequest && base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
152 if (matcher == framework::ConcreteDataMatcher("GLO", "GRPMAGFIELD", 0)) {
156 }
157
158 if (matcher == framework::ConcreteDataMatcher("GLO", "GEOMALIGN", 0)) {
159 LOG(info) << "Loading reference geometry from CCDB";
160 transformation = geo::transformationFromTGeoManager(*gGeoManager);
161 for (int i = 0; i < 156; i++) {
162 int iDEN = GetDetElemId(i);
163 transform[iDEN] = transformation(iDEN);
164 }
165 }
166 }
167 }
168
169 //_________________________________________________________________________________________________
171 {
172 if (mCCDBRequest) {
174 }
175
177 recoData.collectData(pc, *mDataRequest.get());
178
179 const auto& mchTracks = recoData.getMCHTracks();
180 const auto& mchmidMatches = recoData.getMCHMIDMatches();
181 const auto& mchClusters = recoData.getMCHTrackClusters();
182 mTrackMatched += mchmidMatches.size();
183
184 for (auto const& mchmidMatch : mchmidMatches) {
185
186 int mchTrackID = mchmidMatch.getMCHRef().getIndex();
187 const auto& mchTrack = mchTracks[mchTrackID];
188 int first = mchTrack.getFirstClusterIdx();
189 int last = mchTrack.getLastClusterIdx();
190 int Ncluster = last - first + 1;
191
192 if (Ncluster <= 9) {
193 continue;
194 }
195
196 mch::Track convertedTrack;
197
198 for (int i = first; i <= last; i++) {
199 const auto& cluster = mchClusters[i];
200 convertedTrack.createParamAtCluster(cluster);
201 }
202
203 // Erase removable track
204 if (!RemoveTrack(convertedTrack)) {
205 mAlign.ProcessTrack(convertedTrack, transformation, false, weightRecord);
206 mTrackCount += 1;
207 pc.outputs().snapshot(Output{"MUON", "RECORD_MCHMID", 0}, mAlign.GetRecord());
208 }
209 }
210 }
211
212 private:
213 //_________________________________________________________________________________________________
214 bool RemoveTrack(mch::Track& track)
215 {
216 bool removeTrack = false;
217
218 try {
219 trackFitter.fit(track, false);
220 } catch (exception const& e) {
221 removeTrack = true;
222 return removeTrack;
223 }
224
225 auto itStartingParam = std::prev(track.rend());
226
227 while (true) {
228 try {
229 trackFitter.fit(track, true, false, (itStartingParam == track.rbegin()) ? nullptr : &itStartingParam);
230 } catch (exception const&) {
231 removeTrack = true;
232 break;
233 }
234
235 double worstLocalChi2 = -1.0;
236
237 track.tagRemovableClusters(0x1F, false);
238 auto itWorstParam = track.end();
239
240 for (auto itParam = track.begin(); itParam != track.end(); ++itParam) {
241 if (itParam->getLocalChi2() > worstLocalChi2) {
242 worstLocalChi2 = itParam->getLocalChi2();
243 itWorstParam = itParam;
244 }
245 }
246
247 if (worstLocalChi2 < mImproveCutChi2) {
248 break;
249 }
250
251 if (!itWorstParam->isRemovable()) {
252 removeTrack = true;
253 track.removable();
254 break;
255 }
256
257 auto itNextParam = track.removeParamAtCluster(itWorstParam);
258 auto itNextToNextParam = (itNextParam == track.end()) ? itNextParam : std::next(itNextParam);
259 itStartingParam = track.rbegin();
260
261 if (track.getNClusters() < 10) {
262 removeTrack = true;
263 break;
264 } else {
265 while (itNextToNextParam != track.end()) {
266 if (itNextToNextParam->getClusterPtr()->getChamberId() != itNextParam->getClusterPtr()->getChamberId()) {
267 itStartingParam = std::make_reverse_iterator(++itNextParam);
268 break;
269 }
270 ++itNextToNextParam;
271 }
272 }
273 }
274
275 if (!removeTrack) {
276 for (auto& param : track) {
277 param.setParameters(param.getSmoothParameters());
278 param.setCovariances(param.getSmoothCovariances());
279 }
280 }
281
282 return removeTrack;
283 }
284
285 //_________________________________________________________________________________________________
286 Int_t GetDetElemId(Int_t iDetElemNumber)
287 {
288 // make sure detector number is valid
289 if (!(iDetElemNumber >= fgSNDetElemCh[0] &&
290 iDetElemNumber < fgSNDetElemCh[fgNCh])) {
291 LOG(fatal) << "Invalid detector element number: " << iDetElemNumber;
292 }
294 // get chamber and element number in chamber
295 int iCh = 0;
296 int iDet = 0;
297 for (int i = 1; i <= fgNCh; i++) {
298 if (iDetElemNumber < fgSNDetElemCh[i]) {
299 iCh = i;
300 iDet = iDetElemNumber - fgSNDetElemCh[i - 1];
301 break;
302 }
303 }
304
305 // make sure detector index is valid
306 if (!(iCh > 0 && iCh <= fgNCh && iDet < fgNDetElemCh[iCh - 1])) {
307 LOG(fatal) << "Invalid detector element id: " << 100 * iCh + iDet;
308 }
309
310 // add number of detectors up to this chamber
311 return 100 * iCh + iDet;
312 }
313
314 std::shared_ptr<base::GRPGeomRequest> mCCDBRequest;
315 std::shared_ptr<DataRequest> mDataRequest;
316 GID::mask_t mInputSources;
317 bool mUseMC = true;
319 TGeoManager* geo;
320
321 mch::TrackFitter trackFitter;
322 double mImproveCutChi2{};
323 int mTrackCount{};
324 int mTrackMatched{};
325 mch::Aligner mAlign{};
326 Double_t weightRecord{1.0};
327 std::vector<o2::fwdalign::MillePedeRecord> mRecords;
328
329 map<int, math_utils::Transform3D> transform;
330 mch::geo::TransformationCreator transformation;
331};
332
333//_________________________________________________________________________________________________
335{
336 auto dataRequest = std::make_shared<DataRequest>();
338 dataRequest->requestMCHClusters(false);
339 dataRequest->requestTracks(src, useMC);
340
341 vector<OutputSpec> outputSpecs{};
342 auto ccdbRequest = disableCCDB ? nullptr : std::make_shared<base::GRPGeomRequest>(false, // orbitResetTime
343 false, // GRPECS=true
344 false, // GRPLHCIF
345 true, // GRPMagField
346 false, // askMatLUT
348 dataRequest->inputs,
349 true); // query only once all objects except mag.field
350
351 outputSpecs.emplace_back("MUON", "RECORD_MCHMID", 0, Lifetime::Sporadic);
352
353 return DataProcessorSpec{
354 "mch-align-record",
355 dataRequest->inputs,
356 outputSpecs,
357 AlgorithmSpec{adaptFromTask<AlignRecordTask>(dataRequest, ccdbRequest, useMC)},
358 Options{{"geo-file", VariantType::String, o2::base::NameConf::getAlignedGeomFileName(), {"Name of the reference geometry file"}},
359 {"grp-file", VariantType::String, o2::base::NameConf::getGRPFileName(), {"Name of the grp file"}},
360 {"fix-chamber", VariantType::String, "", {"Chamber fixing, ex 1,2,3"}},
361 {"output-record-data", VariantType::String, "recDataFile.root", {"Option for name of output record file for data"}},
362 {"output-record-constraint", VariantType::String, "recConsFile.root", {"Option for name of output record file for constraint"}}}};
363}
364
365} // namespace mch
366} // namespace o2
Definition of the base alignment parameters class.
const int fgSNDetElemCh[fgNCh+1]
const int fgNCh
const int fgNDetElemCh[fgNCh]
Definition of the process for creating alignment record during reconstruction.
General auxilliary methods.
Definition of the MCH cluster minimal structure.
Base track model for the Barrel, params only, w/o covariance.
Definition of the Names Generator class.
Definition of the GeometryManager class.
int32_t i
Header of the AggregatedRunInfo struct.
Helper for geometry and GRP related CCDB requests.
Header of the General Run Parameters object for B field values.
Header of the General Run Parameters object.
Global Forward Muon tracks.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Configurable parameters for MCH tracking.
Definition of a class to fit a track to a set of clusters.
Class to perform MFT MCH (and MID) matching.
Class to perform TOF matching to global tracks.
Class to store the data of single track processing.
Definition of tools for track extrapolation.
Definition of the MUON track.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
Result of refitting TPC-ITS matched track.
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static std::string getAlignedGeomFileName(const std::string_view prefix="")
Definition NameConf.cxx:46
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 mask_t getSourcesMask(const std::string_view srcList)
void snapshot(const Output &spec, T const &object)
ServiceRegistryRef services()
Definition InitContext.h:34
ConfigParamRegistry const & options()
Definition InitContext.h:33
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
void finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj)
void run(framework::ProcessingContext &pc)
AlignRecordTask(std::shared_ptr< DataRequest > dataRequest, std::shared_ptr< base::GRPGeomRequest > ccdbRequest, bool useMC=true)
void init(framework::InitContext &ic)
void SetBFieldOn(bool value)
Set flag for Magnetic field On/Off.
Definition Aligner.h:199
void SetAllowedVariation(int iPar, double value)
Definition Aligner.cxx:1267
o2::fwdalign::MillePedeRecord & GetRecord()
Definition Aligner.h:303
void SetDoEvaluation(bool value)
set to true to do refit evaluation
Definition Aligner.h:205
void init(TString DataRecFName="millerecords.root", TString ConsRecFName="milleconstraints.root")
Definition Aligner.cxx:195
void FixChamber(int iCh, unsigned int parameterMask=ParAll)
Definition Aligner.cxx:577
void ProcessTrack(Track &track, const o2::mch::geo::TransformationCreator &transformation, Bool_t doAlignment, Double_t weight=1)
Definition Aligner.cxx:376
void DisableRecordWriter()
Definition Aligner.h:319
static void useExtrapV2(bool extrapV2=true)
Switch to Runge-Kutta extrapolation v2.
Definition TrackExtrap.h:50
static bool isFieldON()
Return true if the field is switched ON.
Definition TrackExtrap.h:47
static void setField()
Class to fit a track to a set of clusters.
Definition TrackFitter.h:31
void setChamberResolution(double ex, double ey)
Definition TrackFitter.h:91
void useChamberResolution()
Use the chamber resolution instead of cluster resolution during the fit.
Definition TrackFitter.h:54
void setBendingVertexDispersion(double ey)
Set the vertex dispersion in y direction used for the track covariance seed.
Definition TrackFitter.h:44
void smoothTracks(bool smooth)
Enable/disable the smoother (and the saving of related parameters)
Definition TrackFitter.h:47
void fit(Track &track, bool smooth=true, bool finalize=true, std::list< TrackParam >::reverse_iterator *itStartingParam=nullptr, bool skipLocalChi2Calculation=false)
track for internal use
Definition Track.h:33
TrackParam & createParamAtCluster(const Cluster &cluster)
Definition Track.cxx:42
void tagRemovableClusters(uint8_t requestedStationMask, bool request2ChInSameSt45)
Definition Track.cxx:136
int getNClusters() const
Return the number of attached clusters.
Definition Track.h:44
auto rend()
Return a reverse iterator passing the track parameters at first cluster.
Definition Track.h:64
auto end()
Return an iterator passing the track parameters at last cluster.
Definition Track.h:58
auto begin()
Return an iterator to the track parameters at clusters (point to the first one)
Definition Track.h:55
void removable(bool removable=true)
set the flag telling if this track should be deleted
Definition Track.h:95
auto rbegin()
Return a reverse iterator to the track parameters at clusters (point to the last one)
Definition Track.h:61
auto removeParamAtCluster(std::list< TrackParam >::iterator &itParam)
Remove the given track parameters from the internal list and return an iterator to the parameters tha...
Definition Track.h:70
static GRPObject * loadFrom(const std::string &grpFileName="")
GLenum src
Definition glcorearb.h:1767
GLenum GLfloat param
Definition glcorearb.h:271
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
TransformationCreator transformationFromTGeoManager(const TGeoManager &geo)
std::function< o2::math_utils::Transform3D(int detElemId)> TransformationCreator
o2::framework::DataProcessorSpec getAlignRecordSpec(bool useMC, bool disableCCDB=false)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"