BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
reco_processor.cxx
Go to the documentation of this file.
1#include "BmnCSCHitMaker.h"
2#include "BmnFHCalReconstructor.h"
3#include "BmnFillTrigInfoDst.h"
4#include "BmnGemStripHitMaker.h"
5#include "BmnGlobalTracking.h"
6#include "BmnNewFieldMap.h"
7#include "BmnSiBTHitMaker.h"
8#include "BmnSiliconHitMaker.h"
9#include "BmnStsVectorFinder.h"
10#include "BmnTask.h"
11#include "BmnToCbmHitConverter.h"
12#include "BmnTof1HitProducer.h"
13// #include "BmnTof701HitProducer.h"
14// #include "BmnTofHitProducer.h"
15#include "CbmKF.h"
16#include "CbmL1.h"
17#include "GeoSetup.h"
18#include "UniRun.h"
19
20#include <FairRootFileSink.h>
21#include <FairRunAna.h>
22#include <RootSerializer.h>
23#include <TBranchElement.h>
24#include <TFile.h>
25#include <TKey.h>
26#include <TRandom2.h>
27#include <TString.h>
28#include <TTree.h>
29#include <fairmq/Device.h>
30#include <fairmq/runDevice.h>
31#include <string>
32
33namespace bpo = boost::program_options;
34
35namespace bmn::online
36{
37struct ReconstructionProcessor : fair::mq::Device
38{
39 protected:
40 static constexpr auto INPUT_CHANNEL_NAME = "in-channel";
41 static constexpr auto OUTPUT_CHANNEL_NAME = "out-channel";
42
44
45 void InitTask() override
46 {
47 fRunAna = std::make_unique<FairRunAna>();
48 fRunAna->SetGenerateRunInfo(kFALSE);
49
50 fRunAna->SetSink(new FairRootFileSink("help.root"));
51 FairRootManager::Instance()->InitSink();
52
53 fRunPeriod = fConfig->GetValue<Int_t>("run-period");
54
55 fRegisteredBranches.clear();
56 fTasks.clear();
57 }
58
59 void ResetTask() override { fTasks.clear(); }
60
61 Bool_t SetupExperimentalRun(std::unique_ptr<TTree>& inputTree, Int_t& runNumber)
62 {
63 LOG(info) << "Setup experimental run...";
64
65 GeoSetup gSetup;
66 auto setupTag = gSetup.GetLastApprovedSetupTag(TString::Format("run%d", fRunPeriod).Data());
67 if (gSetup.LoadSetupToGeoManager(setupTag)) {
68 LOG(error) << "Could not load geometry '" << setupTag << "' from the Geometry Database";
69 return kFALSE;
70 }
71
72 auto currentRun = std::unique_ptr<UniRun>(UniRun::GetRun(fRunPeriod, runNumber));
73 if (!currentRun)
74 return kFALSE;
75
76 auto magneticFieldVoltage = currentRun->GetFieldVoltage();
77 if (!magneticFieldVoltage) {
78 LOG(error) << "No field voltage was found for run " << fRunPeriod << ":" << runNumber;
79 return kFALSE;
80 }
81
82 Double_t mapCurrent = (fRunPeriod == 8) ? 112.0 : (fRunPeriod == 7) ? 55.87 : 0.0;
83 Double_t magneticFieldScale = 0.;
84 if (*magneticFieldVoltage < 10) {
85 magneticFieldScale = 0;
86 } else {
87 magneticFieldScale = (*magneticFieldVoltage) / mapCurrent;
88 }
89
90 auto magneticField = new BmnNewFieldMap("FieldMap_1900_extrap_noPed.root");
91 magneticField->SetScale(magneticFieldScale);
92 magneticField->Init();
93 fRunAna->SetField(magneticField);
94
95 TString target = "-";
96 if (currentRun->GetTargetParticle() != "")
97 target = currentRun->GetTargetParticle();
98
99 auto beam = currentRun->GetBeamParticle();
100
101 LOG(info) << "Complete!";
102
103 LOG(info) << "Experimental run summary:";
104 LOG(info) << "\tPeriod: run" << fRunPeriod;
105 LOG(info) << "\tNumber: " << runNumber;
106 LOG(info) << "\tBeam: " << beam;
107 LOG(info) << "\tTarget: " << target;
108 LOG(info) << "\tMagnetic field scale: " << setprecision(4) << magneticFieldScale;
109 LOG(info) << "\tGeometry setup: " << setupTag;
110
111 return kTRUE;
112 }
113
114 void RegisterBranches(std::unique_ptr<TTree>& inputTree)
115 {
116 fRegisteredBranches.clear();
117
118 auto branches = inputTree->GetListOfBranches();
119 for (Long64_t branchIndex = 0; branchIndex < branches->GetEntriesFast(); branchIndex++) {
120 auto branch = static_cast<TBranchElement*>(branches->At(branchIndex));
121 if (strcmp(branch->GetClassName(), "TClonesArray") == 0) {
122 fRegisteredBranches[branch->GetName()] = std::make_unique<TClonesArray>(branch->GetClonesName());
123 }
124 }
125
126 for (auto& branch : fRegisteredBranches) {
127 FairRootManager::Instance()->RegisterInputObject(branch.first.c_str(), branch.second.get());
128 }
129 }
130
131 void UploadData(std::unique_ptr<TTree>& inputTree)
132 {
133 for (auto& branch : fRegisteredBranches) {
134 branch.second->Delete();
135 auto tmp = branch.second.get();
136 if (inputTree->SetBranchAddress(branch.first.c_str(), &tmp)) {
137 LOG(warning) << "Registered branch '" << branch.first << "' not found in input tree!";
138 }
139 }
140
141 inputTree->GetEntry(0);
142 }
143
145 {
146 LOG(info) << "Initializing reconstruction tasks...";
147
148 fTasks.clear();
149
150 // Pileup Event Classification
151 //! no inheritance from BmnTask
152 // auto eventSelector = std::make_unique<BmnEventSelector>();
153 // eventSelector->SetRunId(runNumber);
154 // eventSelector->SetInputFileName("$VMCWORKDIR/input/eventSelector_calib_run8.root");
155 // fTasks.push_back(std::move(eventSelector));
156
157 // Fill basic trigger information
158 auto triggerInfo = std::make_unique<BmnFillTrigInfoDst>(kTRUE);
159 fTasks.push_back(std::move(triggerInfo));
160
161 // Hits in front of the target
162 auto sibtHM = std::make_unique<BmnSiBTHitMaker>(fRunPeriod, runNumber, kTRUE);
163 sibtHM->SetHitMatching(kFALSE);
164 fTasks.push_back(std::move(sibtHM));
165
166 // Silicon hit finder
167 auto siliconHM = std::make_unique<BmnSiliconHitMaker>(fRunPeriod, runNumber, kTRUE);
168 siliconHM->SetHitMatching(kFALSE);
169 fTasks.push_back(std::move(siliconHM));
170
171 // GEM hit finder
172 auto gemHM = std::make_unique<BmnGemStripHitMaker>(fRunPeriod, runNumber, kTRUE);
173 gemHM->SetHitMatching(kFALSE);
174 fTasks.push_back(std::move(gemHM));
175
176 // CSC hit finder
177 auto cscHM = std::make_unique<BmnCSCHitMaker>(fRunPeriod, runNumber, kTRUE);
178 cscHM->SetHitMatching(kFALSE);
179 fTasks.push_back(std::move(cscHM));
180
181 // TOF1 hit finder
182 auto tof1HP = std::make_unique<BmnTof1HitProducer>("TOF400", kTOF1, kFALSE, 0, kFALSE);
183 tof1HP->SetPeriodRun(fRunPeriod, runNumber);
184 fTasks.push_back(std::move(tof1HP));
185
186 // TOF701 hit finder
187 auto tof700HP = std::make_unique<BmnTof1HitProducer>("TOF700", kTOF701, kFALSE, 0, kFALSE);
188 tof700HP->SetPeriodRun(fRunPeriod, runNumber);
189 fTasks.push_back(std::move(tof700HP));
190
191 // Legacy
192 // // TOF2 hit finder
193 // auto tof2HP = std::make_unique<BmnTofHitProducer>("TOF", "TOF700_geometry_run8.txt", kFALSE, 0, kFALSE);
194 // tof2HP->SetTimeResolution(0.115);
195 // tof2HP->SetProtonTimeCorrectionFile("bmn_run9687_digi_calibration.root");
196 // tof2HP->SetMCTimeFile("TOF700_MC_xenon_dcmsmm_time_run8.txt");
197 // // 0 - minimal time, 1 - maximal amplitude
198 // tof2HP->SetMainStripSelection(0);
199 // // 0 - Petukhov, 1 - Panin SRC, 2 - Petukhov Argon (default), 3 - Petukhov Xenon (preliminary)
200 // tof2HP->SetSelectXYCalibration(3);
201 // // minimal digit time
202 // tof2HP->SetTimeMin(-2.f);
203 // // Maximal digit time
204 // tof2HP->SetTimeMax(+50.f);
205 // // Abs maximal difference for small chambers
206 // tof2HP->SetDiffTimeMaxSmall(1.2f);
207 // // Abs maximal difference for big chambers
208 // tof2HP->SetDiffTimeMaxBig(3.5f);
209 // fTasks.push_back(std::move(tof2HP));
210
211 auto fhcalReco = std::make_unique<BmnFHCalReconstructor>(kTRUE, kTRUE);
212 fhcalReco->SetRecoCutsFile("FHCAL_reco_cuts_period8.txt");
213 fTasks.push_back(std::move(fhcalReco));
214
215 // auto scwallReco = std::make_unique<BmnScWallReconstructor>(kTRUE, kTRUE);
216 // scwallReco->SetRecoCutsFile("SCWALL_reco_cuts_period8.txt");
217 // fTasks.push_back(std::move(scwallReco));
218
219 // auto hodoReco = std::make_unique<BmnHodoReconstructor>("", kTRUE);
220 // hodoReco->SetRecoCutsFile("HODO_reco_cuts_period8.txt");
221 // fTasks.push_back(std::move(hodoReco));
222
223 // auto ndetReco = std::make_unique<BmnNdetReconstructor>(kTRUE, kTRUE);
224 // ndetReco->SetRecoCutsFile("NDET_reco_cuts_period8.txt");
225 // fTasks.push_back(std::move(ndetReco));
226
227 // auto vacReco = std::make_unique<BmnVacWallReconstructor>();
228 // fTasks.push_back(std::move(vacReco));
229
230 // Inner Tracking
231 auto innerTrackBranchName = "StsVector";
232 auto hitConverter = std::make_unique<BmnToCbmHitConverter>(0, kTRUE);
233 hitConverter->EnableAlignment(kFALSE);
234 hitConverter->SetFixedErrors(0.08 / sqrt(12) * 1.2, 0.1234, 0.01 / sqrt(12), 0.1234);
235 fTasks.push_back(std::move(hitConverter));
236
237 auto kalmanFilter = std::make_unique<CbmKF>();
238 fTasks.push_back(std::move(kalmanFilter));
239
240 auto l1Tracking = std::make_unique<CbmL1>();
241 l1Tracking->SetMaterialBudgetFileName("");
242 fTasks.push_back(std::move(l1Tracking));
243
244 auto vectorFinder = std::make_unique<BmnStsVectorFinder>();
245 vectorFinder->SetMatBudgetFileName("$VMCWORKDIR/parameters/sts_matbudget_run8.root");
246
247 //! no inheritance from BmnTask
248 // auto stsMatchTracks = std::make_unique<BmnStsMatchTracks>(0);
249 // stsMatchTracks->SetTrackBranch(innerTrackBranchName);
250 // fTasks.push_back(std::move(stsMatchTracks));
251
252 //! no inheritance from BmnTask
253 // auto beamTF = std::make_unique<BmnBeamTracking>(fRunPeriod);
254 // fTasks.push_back(std::move(beamTF));
255
256 // auto pvFinder = std::make_unique<CbmPVFinderKF>();
257 // auto findVertex = std::make_unique<CbmFindPrimaryVertex>(pvFinder);
258 // findVertex->SetTrackBranch(innerTrackBranchName);
259 // fTasks.push_back(std::move(findVertex));
260
261 // auto pvMPD = std::make_unique<BmnKFPrimaryVertexFinder>();
262 // fTasks.push_back(std::move(pvMPD));
263
264 // auto combPV = std::make_unique<BmnCombineVertexFinder>();
265 // fTasks.push_back(std::move(combPV));
266
267 //! no inheritance from BmnTask
268 // auto pidAnalyzer = std::make_unique<BmnPid>();
269 // fTasks.push_back(std::move(pidAnalyzer));
270
271 // auto centralityClustering =
272 // std::make_unique<CentralityClusterizer>("XeCsI@3.8AGeV_MBT_7clusters_period8.root");
273 // fTasks.push_back(std::move(centralityClustering));
274
275 auto glTF = std::make_unique<BmnGlobalTracking>();
276 glTF->SetInnerTracksBranchName(innerTrackBranchName);
277 fTasks.push_back(std::move(glTF));
278
279 for (auto&& task : fTasks) {
280 task->SetVerbose(0);
281 task->InitTask();
282 };
283
284 LOG(info) << "Complete!";
285 }
286
287 Bool_t HandleData(fair::mq::MessagePtr& inputMessage, Int_t)
288 {
289 std::unique_ptr<TTree> inputTree(nullptr);
290 RootSerializer().Deserialize(*inputMessage, inputTree);
291
292 if (fCurrentEvent == 0) {
293 Int_t runNumber = -1;
294 if (!SetupExperimentalRun(inputTree, runNumber))
295 return kFALSE;
296 RegisterBranches(inputTree);
298 }
299
300 UploadData(inputTree);
301
302 LOG(info) << "Event #" << fCurrentEvent;
303
304 auto resultTree = std::make_unique<TTree>();
305 for (auto&& task : fTasks) {
306 task->Exec("0");
307 task->OnlineWrite(resultTree);
308 }
309
310 auto message = NewMessage();
311 RootSerializer().Serialize(*message, resultTree);
312
313 if (Send(message, OUTPUT_CHANNEL_NAME) < 0) {
314 LOG(error) << "Sending message failed!";
315 return kFALSE;
316 }
317
319
320 return kTRUE;
321 }
322
323 private:
326
327 std::vector<std::unique_ptr<BmnTask>> fTasks;
328 std::unordered_map<std::string, std::unique_ptr<TClonesArray>> fRegisteredBranches;
329
330 std::unique_ptr<FairRunAna> fRunAna;
331};
332} // namespace bmn::online
333
334void addCustomOptions(bpo::options_description& options)
335{
336 auto op = options.add_options();
337
338 op("run-period", bpo::value<Int_t>()->default_value(8), "BM@N Run period");
339}
340
341std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions&)
342{
343 return std::make_unique<bmn::online::ReconstructionProcessor>();
344}
bool Bool_t
int Int_t
constexpr Bool_t kFALSE
double Double_t
long long Long64_t
constexpr Bool_t kTRUE
@ kTOF1
@ kTOF701
Field Map does not have any symmetries w.r.t coordinate axises.
GeoSetup class.
Definition GeoSetup.h:40
int LoadSetupToGeoManager(string_view setup_tag)
Load selected geometry setup from the Local Geometry Database and create gGeoManager instance.
Definition GeoSetup.cxx:512
string GetLastApprovedSetupTag(string_view tag_prefix)
Get tag for the last approved setup corresponding to the pattern.
Definition GeoSetup.cxx:122
static TString Format(const char *fmt,...)
static UniRun * GetRun(int period_number, int run_number)
get run from the database
Definition UniRun.cxx:161
RVec< PromoteType< T > > sqrt(const RVec< T > &v)
std::unique_ptr< fair::mq::Device > getDevice(fair::mq::ProgOptions &)
void addCustomOptions(bpo::options_description &options)
std::vector< std::unique_ptr< BmnTask > > fTasks
Bool_t HandleData(fair::mq::MessagePtr &inputMessage, Int_t)
Bool_t SetupExperimentalRun(std::unique_ptr< TTree > &inputTree, Int_t &runNumber)
void InitializeReconstructionTasks(Int_t runNumber)
static constexpr auto OUTPUT_CHANNEL_NAME
void UploadData(std::unique_ptr< TTree > &inputTree)
void RegisterBranches(std::unique_ptr< TTree > &inputTree)
std::unordered_map< std::string, std::unique_ptr< TClonesArray > > fRegisteredBranches
std::unique_ptr< FairRunAna > fRunAna