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