Project
Loading...
Searching...
No Matches
BarrelAlignmentSpec.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 <vector>
15#include <string>
16#include <filesystem>
17#include <TMethodCall.h>
18#include <TStopwatch.h>
19#include <TROOT.h>
20#include <TSystem.h>
21#include "TMethodCall.h"
24#include "Align/Controller.h"
25#include "Align/AlignConfig.h"
40#include "GPUO2Interface.h"
41#include "GPUO2InterfaceUtils.h"
42#include "GPUParam.h"
43#include "Headers/DataHeader.h"
45#include "Framework/Task.h"
49
50#include <boost/interprocess/sync/named_semaphore.hpp>
51
52/*
53#include "DataFormatsITSMFT/TopologyDictionary.h"
54#include "DataFormatsTPC/Constants.h"
55#include "ReconstructionDataFormats/GlobalTrackAccessor.h"
56#include "ReconstructionDataFormats/TrackTPCITS.h"
57#include "ReconstructionDataFormats/MatchInfoTOF.h"
58#include "ReconstructionDataFormats/TrackTPCTOF.h"
59#include "DataFormatsITS/TrackITS.h"
60#include "DataFormatsITSMFT/CompCluster.h"
61#include "DataFormatsITSMFT/ROFRecord.h"
62#include "DataFormatsITSMFT/TopologyDictionary.h"
63#include "DataFormatsTPC/TrackTPC.h"
64#include "DataFormatsTPC/ClusterNative.h"
65#include "DataFormatsTPC/WorkflowHelper.h"
66#include "ITSBase/GeometryTGeo.h"
67#include "ITSMFTBase/DPLAlpideParam.h"
68*/
69
70using namespace o2::framework;
71using namespace o2::globaltracking;
72using namespace o2::align;
73
76
77namespace o2
78{
79namespace align
80{
81
83{
84 public:
85 enum PostProc { WriteResults = 0x1 << 0,
86 CheckConstaints = 0x1 << 1,
87 GenPedeFiles = 0x1 << 2,
88 LabelPedeResults = 0x1 << 3 };
89 BarrelAlignmentSpec(GTrackID::mask_t srcMP, std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> ggrec, const o2::tpc::CorrectionMapsLoaderGloOpts& tpcOpt,
90 DetID::mask_t detmask, bool cosmic, int postprocess, bool useMC, bool loadTPCCalib)
91 : mDataRequest(dr), mGRPGeomRequest(ggrec), mMPsrc{srcMP}, mDetMask{detmask}, mCosmic(cosmic), mPostProcessing(postprocess), mUseMC(useMC), mLoadTPCCalib(loadTPCCalib)
92 {
93 mTPCCorrMapsLoader.setLumiScaleType(tpcOpt.lumiType);
94 mTPCCorrMapsLoader.setLumiScaleMode(tpcOpt.lumiMode);
95 }
96 ~BarrelAlignmentSpec() override = default;
97 void init(InitContext& ic) final;
98 void run(ProcessingContext& pc) final;
99 void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final;
101
102 private:
103 void updateTimeDependentParams(ProcessingContext& pc);
104 std::string mIniParFile{};
105 bool mUseIniParErrors = true;
106 bool mUseMC = false;
107 bool mIgnoreCCDBAlignment = false;
108 bool mCosmic = false;
109 bool mLoadTPCCalib = false;
110 int mLane = 0;
111 int mPostProcessing = 0; // special mode of extracting alignment or constraints check
112 GTrackID::mask_t mMPsrc{};
113 DetID::mask_t mDetMask{};
114 std::unique_ptr<Controller> mController;
115 std::shared_ptr<DataRequest> mDataRequest;
116 std::shared_ptr<o2::base::GRPGeomRequest> mGRPGeomRequest;
117 std::string mConfMacro{};
118 std::unique_ptr<TMethodCall> mUsrConfMethod;
119 std::unique_ptr<o2::trd::TrackletTransformer> mTRDTransformer;
120 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
121 std::unique_ptr<o2::gpu::GPUParam> mTPCParam;
122
123 o2::tpc::VDriftHelper mTPCVDriftHelper{};
124 o2::tpc::CorrectionMapsLoader mTPCCorrMapsLoader{};
125
126 //
127 TStopwatch mTimer;
128};
129
131{
132 mTimer.Stop();
133 mTimer.Reset();
135
136 int dbg = ic.options().get<int>("debug-output");
137 mLane = ic.services().get<const o2::framework::DeviceSpec>().inputTimesliceId;
138 mController = std::make_unique<Controller>(mDetMask, mMPsrc, mCosmic, mUseMC, mLane);
139 if (dbg) {
140 mController->setDebugOutputLevel(dbg);
141 }
142
143 mConfMacro = ic.options().get<std::string>("config-macro");
144 if (!mConfMacro.empty()) {
145 if (!std::filesystem::exists(mConfMacro)) {
146 LOG(fatal) << "Requested user macro " << mConfMacro << " does not exist";
147 }
148 std::string tmpmacro = mConfMacro + "+";
149 TString cmd = gSystem->GetMakeSharedLib();
150 cmd += " -O0 -g -ggdb";
151 // protect macro compilation by semaphore (to avoid problems in the pipelined code)
152 {
153 boost::interprocess::named_semaphore* sem = nullptr;
154 std::string semhashedstring{};
155 std::hash<std::string> hasher;
156 semhashedstring = "align_macro_" + std::to_string(hasher(mConfMacro)).substr(0, 16);
157 try {
158 sem = new boost::interprocess::named_semaphore(boost::interprocess::open_or_create_t{}, semhashedstring.c_str(), 1);
159 } catch (std::exception e) {
160 LOGP(error, "Exception occurred during {} compilation semaphore setup", tmpmacro);
161 sem = nullptr;
162 }
163 if (sem) {
164 sem->wait(); // wait until we can enter (no one else there)
165 }
166 gSystem->SetMakeSharedLib(cmd.Data());
167 auto res = gROOT->LoadMacro(tmpmacro.c_str());
168 if (sem) {
169 sem->post();
170 if (sem->try_wait()) { // if nobody else is waiting remove the semaphore resource
171 sem->post();
172 boost::interprocess::named_semaphore::remove(semhashedstring.c_str());
173 }
174 }
175 if (res) {
176 LOG(fatal) << "Failed to load user macro " << tmpmacro;
177 }
178 }
179 std::filesystem::path mpth(mConfMacro);
180 mConfMacro = mpth.stem();
181 mUsrConfMethod = std::make_unique<TMethodCall>();
182 mUsrConfMethod->InitWithPrototype(mConfMacro.c_str(), "o2::align::Controller*, int");
183 }
184 mIgnoreCCDBAlignment = ic.options().get<bool>("ignore-ccdb-alignment");
185 if (!mPostProcessing) {
186 if (mLoadTPCCalib) {
187 mTPCCorrMapsLoader.init(ic);
188 }
189 if (GTrackID::includesDet(DetID::TRD, mMPsrc)) {
190 mTRDTransformer.reset(new o2::trd::TrackletTransformer);
191 if (ic.options().get<bool>("apply-xor")) {
192 mTRDTransformer->setApplyXOR();
193 }
194 auto prevShift = mTRDTransformer->isShiftApplied();
195 if (getenv("ALIEN_JDL_LPMPRODUCTIONTYPE") && std::strcmp(getenv("ALIEN_JDL_LPMPRODUCTIONTYPE"), "MC") == 0) {
196 // apply artificial pad shift in case non-ideal alignment is used to compensate for shift in current alignment from real data
197 mTRDTransformer->setApplyShift(false);
198 }
199 LOGP(info, "Old TRD shift : {} new : {}", prevShift, mTRDTransformer->isShiftApplied());
200 mController->setTRDTransformer(mTRDTransformer.get());
201 }
202 mController->setAllowAfterburnerTracks(ic.options().get<bool>("allow-afterburner-tracks"));
203 }
204
205 mIniParFile = ic.options().get<std::string>("initial-params-file");
206 mUseIniParErrors = !ic.options().get<bool>("ignore-initial-params-errors");
207 if (mPostProcessing && !(mPostProcessing != GenPedeFiles) && (mIniParFile.empty() || mIniParFile == "none")) {
208 LOGP(warn, "Postprocessing {} is requested but the initial-params-file is not provided", mPostProcessing);
209 }
210}
211
212void BarrelAlignmentSpec::updateTimeDependentParams(ProcessingContext& pc)
213{
215 auto tinfo = pc.services().get<o2::framework::TimingInfo>();
216 if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) {
217 if (mController->getDebugOutputLevel()) {
218 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(fmt::format("mpDebug_{}_{:08d}_{:010d}.root", mLane, tinfo.runNumber, tinfo.tfCounter).c_str(), "recreate");
219 mController->setDebugStream(mDBGOut.get());
220 }
221 if (!mIgnoreCCDBAlignment) {
222 for (auto id = DetID::First; id <= DetID::Last; id++) {
223 const auto* alg = o2::base::GRPGeomHelper::instance().getAlignment(id);
224 if (alg && !alg->empty()) {
226 }
227 gGeoManager->RefreshPhysicalNodes(false);
228 }
229 } else {
230 LOG(warn) << "CCDB alignment is NOT applied to ideal geometry";
231 }
232 if (!mController->getInitGeomDone()) {
233 mController->initDetectors();
234 }
235 if (mTRDTransformer) { // need geometry loaded
236 mTRDTransformer->init();
237 }
238
239 if (!(mIniParFile.empty() || mIniParFile == "none")) {
240 mController->readParameters(mIniParFile, mUseIniParErrors);
241 mController->applyAlignmentFromMPSol();
242 }
243
244 // call this in the very end
245 if (mUsrConfMethod) {
246 int dummyPar = 0, ret = -1;
247 Controller* tmpPtr = mController.get();
248 const void* args[2] = {&tmpPtr, &dummyPar};
249 mUsrConfMethod->Execute(nullptr, args, 2, &ret);
250 if (ret != 0) {
251 LOG(fatal) << "Execution of user method config method " << mConfMacro << " failed with " << ret;
252 }
253 }
255 o2::base::PropagatorD::Instance()->setTGeoFallBackAllowed(false);
256 }
257 if (GTrackID::includesDet(DetID::TRD, mMPsrc) && mTRDTransformer) {
258 pc.inputs().get<o2::trd::CalVdriftExB*>("calvdexb"); // just to trigger the finaliseCCDB
259 }
260 if (mLoadTPCCalib) {
261
262 static float prevField = 1e-6;
263 float newField = o2::base::Propagator::Instance()->getNominalBz();
264 if (prevField != newField) {
265 prevField = newField;
266 if (mDetMask[DetID::TPC]) {
267 mTPCParam.reset(new o2::gpu::GPUParam);
268 mTPCParam->SetDefaults(o2::base::Propagator::Instance()->getNominalBz());
269 mController->setTPCParam(mTPCParam.get());
270 }
271 }
272
273 mTPCVDriftHelper.extractCCDBInputs(pc);
274 mTPCCorrMapsLoader.extractCCDBInputs(pc);
275 bool updateMaps = false;
276 if (mTPCCorrMapsLoader.isUpdated()) {
277 mTPCCorrMapsLoader.acknowledgeUpdate();
278 updateMaps = true;
279 }
280 mController->setTPCCorrMaps(&mTPCCorrMapsLoader);
281 if (mTPCVDriftHelper.isUpdated()) {
282 LOGP(info, "Updating TPC fast transform map with new VDrift factor of {} wrt reference {} and DriftTimeOffset correction {} wrt {} from source {}",
283 mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift,
284 mTPCVDriftHelper.getVDriftObject().timeOffsetCorr, mTPCVDriftHelper.getVDriftObject().refTimeOffset,
285 mTPCVDriftHelper.getSourceName());
286 mController->setTPCVDrift(mTPCVDriftHelper.getVDriftObject());
287 mTPCVDriftHelper.acknowledgeUpdate();
288 updateMaps = true;
289 }
290 if (updateMaps) {
291 mTPCCorrMapsLoader.updateVDrift(mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift, mTPCVDriftHelper.getVDriftObject().getTimeOffset());
292 }
293 }
294}
295
297{
299 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
300 auto* its = mController->getDetector(o2::detectors::DetID::ITS);
301 if (its) {
302 LOG(info) << "cluster dictionary updated";
303 ((AlignableDetectorITS*)its)->setITSDictionary((const o2::itsmft::TopologyDictionary*)obj);
304 return;
305 }
306 }
307 if (matcher == ConcreteDataMatcher("TRD", "CALVDRIFTEXB", 0)) {
308 LOG(info) << "CalVdriftExB object has been updated";
309 mTRDTransformer->setCalVdriftExB((const o2::trd::CalVdriftExB*)obj);
310 return;
311 }
312 if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) {
313
314 return;
315 }
316 if (mTPCCorrMapsLoader.accountCCDBInputs(matcher, obj)) {
317 return;
318 }
319}
320
322{
323 mTimer.Start(false);
324 if (mPostProcessing) { // special mode, no data processing
325 updateTimeDependentParams(pc);
326 if (mController->getInstanceID() == 0) {
327 if (mPostProcessing & PostProc::CheckConstaints) {
328 mController->addAutoConstraints();
329 mController->checkConstraints();
330 }
331 if (mPostProcessing & PostProc::WriteResults) {
332 mController->writeCalibrationResults();
333 }
334 }
336 } else {
337 RecoContainer recoData;
338 recoData.collectData(pc, *mDataRequest.get());
339 updateTimeDependentParams(pc); // call after collectData !!!
340 mController->setRecoContainer(&recoData);
341 mController->setTimingInfo(pc.services().get<o2::framework::TimingInfo>());
342 if (mCosmic) {
343 mController->processCosmic();
344 } else {
345 mController->process();
346 }
347 }
348 mTimer.Stop();
349}
350
352{
353 auto inst = ec.services().get<const o2::framework::DeviceSpec>().inputTimesliceId;
354 if (!mPostProcessing) {
355 LOGP(info, "Barrel alignment data pereparation total timing: Cpu: {:.3e} Real: {:.3e} s in {} slots, instance {}", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1, inst);
356 mController->closeMPRecOutput();
357 mController->closeMilleOutput();
358 mController->closeResidOutput();
359 }
360 if (inst == 0) {
361 if (!mPostProcessing || (mPostProcessing & PostProc::GenPedeFiles)) {
362 LOG(info) << "Writing millepede control files";
363 if (!mPostProcessing) {
364 mController->terminate(); // finalize data stat
365 }
366 mController->addAutoConstraints();
367 mController->genPedeSteerFile();
368 mController->getStat().print();
369 } else if (mPostProcessing & PostProc::LabelPedeResults) {
370 mController->writeLabeledPedeResults();
371 }
372 }
373 mDBGOut.reset();
374}
375
376DataProcessorSpec getBarrelAlignmentSpec(GTrackID::mask_t srcMP, GTrackID::mask_t src, DetID::mask_t dets, DetID::mask_t skipDetClusters, bool enableCosmic, int postprocess, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts)
377{
378 std::vector<OutputSpec> outputs;
379 auto dataRequest = std::make_shared<DataRequest>();
380 bool loadTPCCalib = false;
381 Options opts{
382 ConfigParamSpec{"apply-xor", o2::framework::VariantType::Bool, false, {"flip the 8-th bit of slope and position (for processing TRD CTFs from 2021 pilot beam)"}},
383 ConfigParamSpec{"allow-afterburner-tracks", VariantType::Bool, false, {"allow using ITS-TPC afterburner tracks"}},
384 ConfigParamSpec{"ignore-ccdb-alignment", VariantType::Bool, false, {"do not aplly CCDB alignment to ideal geometry"}},
385 ConfigParamSpec{"initial-params-file", VariantType::String, "", {"initial parameters file"}},
386 ConfigParamSpec{"config-macro", VariantType::String, "", {"configuration macro with signature (o2::align::Controller*, int) to execute from init"}},
387 ConfigParamSpec{"ignore-initial-params-errors", VariantType::Bool, false, {"ignore initial params (if any) errors for precondition"}},
388 ConfigParamSpec{"debug-output", VariantType::Int, 0, {"produce debugging output root files"}}};
389 if (!postprocess) {
390 dataRequest->requestTracks(src, useMC);
391 dataRequest->requestClusters(src, false, skipDetClusters);
392 dataRequest->requestPrimaryVertices(useMC);
393 if (GTrackID::includesDet(DetID::TRD, srcMP)) {
394 dataRequest->inputs.emplace_back("calvdexb", "TRD", "CALVDRIFTEXB", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/CalVdriftExB"));
395 }
396 if (enableCosmic) {
397 dataRequest->requestCoscmicTracks(useMC);
398 }
399 if (src[DetID::TPC] && !skipDetClusters[DetID::TPC]) {
400 o2::tpc::VDriftHelper::requestCCDBInputs(dataRequest->inputs);
401 o2::tpc::CorrectionMapsLoader::requestCCDBInputs(dataRequest->inputs, opts, sclOpts);
402 loadTPCCalib = true;
403 }
404 }
405 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(true, // orbitResetTime
406 true, // GRPECS=true
407 false, // GRPLHCIF
408 true, // GRPMagField
409 true, // askMatLUT
411 dataRequest->inputs,
412 false, // ask update once (except field)
413 true, // init PropagatorD
414 "ITS,TPC,TRD,TOF"); // alignment objects to apply
415 return DataProcessorSpec{
416 "barrel-alignment",
417 dataRequest->inputs,
418 outputs,
419 AlgorithmSpec{adaptFromTask<BarrelAlignmentSpec>(srcMP, dataRequest, ccdbRequest, sclOpts, dets, enableCosmic, postprocess, useMC, loadTPCCalib)},
420 opts};
421}
422
423} // namespace align
424} // namespace o2
Configuration file for global alignment.
ITS detector wrapper.
Steering class for the global alignment.
Helper class to access load maps from CCDB.
Wrapper container for different reconstructed object types.
Definition of the ClusterTopology class.
Definition of the GeometryManager class.
Helper for geometry and GRP related CCDB requests.
Header of the General Run Parameters object.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the Names Generator class.
uint32_t res
Definition RawData.h:0
Wrapper container for different reconstructed object types.
Helper class to extract VDrift from different sources.
void init(InitContext &ic) final
~BarrelAlignmentSpec() override=default
BarrelAlignmentSpec(GTrackID::mask_t srcMP, std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > ggrec, const o2::tpc::CorrectionMapsLoaderGloOpts &tpcOpt, DetID::mask_t detmask, bool cosmic, int postprocess, bool useMC, bool loadTPCCalib)
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void run(ProcessingContext &pc) final
void checkUpdates(o2::framework::ProcessingContext &pc)
auto getAlignment(o2::detectors::DetID det) const
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static bool applyAlignment(const std::vector< o2::detectors::AlignParam > &algPars)
misalign geometry with alignment objects from the array, optionaly check overlaps
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:143
void printKeyValues(bool showProv=true, bool useLogger=false) const final
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 First
Definition DetID.h:94
static constexpr ID TRD
Definition DetID.h:65
static constexpr ID Last
if extra detectors added, update this !!!
Definition DetID.h:92
static constexpr ID TPC
Definition DetID.h:64
ServiceRegistryRef services()
Definition InitContext.h:34
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
void extractCCDBInputs(o2::framework::ProcessingContext &pc)
void updateVDrift(float vdriftCorr, float vdrifRef, float driftTimeOffset=0)
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs, std::vector< o2::framework::ConfigParamSpec > &options, const CorrectionMapsLoaderGloOpts &gloOpts)
recalculate inverse correction
void init(o2::framework::InitContext &ic)
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs, bool laser=true, bool itstpcTgl=true)
void extractCCDBInputs(o2::framework::ProcessingContext &pc, bool laser=true, bool itstpcTgl=true)
const VDriftCorrFact & getVDriftObject() const
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
static std::string_view getSourceName(Source s)
bool isUpdated() const
GLenum src
Definition glcorearb.h:1767
framework::DataProcessorSpec getBarrelAlignmentSpec(o2::dataformats::GlobalTrackID::mask_t srcMP, o2::dataformats::GlobalTrackID::mask_t src, o2::detectors::DetID::mask_t dets, o2::detectors::DetID::mask_t skipDetClusters, bool enableCosmic, int postproc, bool useMC, const o2::tpc::CorrectionMapsLoaderGloOpts &sclOpts)
create a processor spec
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
@ Me
Only quit this data processor.
std::vector< ConfigParamSpec > Options
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
int lumiType
what estimator to used for corrections scaling: 0: no scaling, 1: CTP, 2: IDC
int lumiMode
what corrections method to use: 0: classical scaling, 1: Using of the derivative map,...
float refTimeOffset
additive time offset reference (\mus)
float refVDrift
reference vdrift for which factor was extracted
float getTimeOffset() const
float timeOffsetCorr
additive time offset correction (\mus)
float corrFact
drift velocity correction factor (multiplicative)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"