R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BNeulandDigitizer.cxx
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2025 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
14#include "R3BNeulandDigitizer.h"
15#include "FairRootManager.h"
16#include "FairRunAna.h"
17#include "FairRuntimeDb.h"
18#include "NeulandPointFilter.h"
19#include "R3BDataMonitor.h"
20#include <R3BShared.h>
21#include <TFile.h>
22#include <range/v3/view.hpp>
23#include <utility>
24
29
30R3BNeulandDigitizer::R3BNeulandDigitizer(std::unique_ptr<Digitizing::DigitizingEngineInterface> engine,
31 std::string_view points_name,
32 std::string_view hits_name,
33 std::string_view cal_hits_name)
34 : FairTask("R3BNeulandDigitizer")
35 , neuland_points_{ points_name }
36 , neuland_hits_{ hits_name }
37 , neuland_cal_hits_{ cal_hits_name }
38 , digitizing_engine_(std::move(engine))
39{
40}
41
42void R3BNeulandDigitizer::SetEngine(std::unique_ptr<Digitizing::DigitizingEngineInterface> engine)
43{
44 digitizing_engine_ = std::move(engine);
45}
46
48{
49 FairRunAna* run = FairRunAna::Instance();
50 if (run == nullptr)
51 {
52 LOG(fatal) << "R3BNeulandDigitizer::SetParContainers: No analysis run";
53 }
54
55 FairRuntimeDb* rtdb = run->GetRuntimeDb();
56 if (rtdb == nullptr)
57 {
58 LOG(fatal) << "R3BNeulandDigitizer::SetParContainers: No runtime database";
59 }
60
61 neuland_geo_par_ = dynamic_cast<R3BNeulandGeoPar*>(rtdb->getContainer("R3BNeulandGeoPar"));
62 if (neuland_geo_par_ == nullptr)
63 {
64 LOG(fatal) << "R3BNeulandDigitizer::SetParContainers: No R3BNeulandGeoPar";
65 }
66
67 digitizing_engine_->Init();
68}
69
71{
72 neuland_point_filter_.SetFilter(particle);
73}
75 double minimum_allowed_energy_gev)
76{
77 neuland_point_filter_.SetFilter(particle, minimum_allowed_energy_gev);
78}
79
80auto R3BNeulandDigitizer::Init() -> InitStatus
81{
82 neuland_points_.init();
83 neuland_hits_.init();
84 neuland_cal_hits_.init();
85 // Initialize control histograms
86 auto const PaddleMulSize = 3000;
87 hist_multi_one_ = data_monitor_.add_hist<TH1I>(
88 "MultiplicityOne", "Paddle multiplicity: only one PMT per paddle", PaddleMulSize, 0, PaddleMulSize);
89
90 hist_multi_two_ = data_monitor_.add_hist<TH1I>(
91 "MultiplicityTwo", "Paddle multiplicity: both PMTs of a paddle", PaddleMulSize, 0, PaddleMulSize);
92 auto const timeBinSize = 200;
93 hist_rl_time_to_trig_ =
94 data_monitor_.add_hist<TH1F>("hRLTimeToTrig", "R/Ltime-triggerTime", timeBinSize, -100., 100.);
95
96 return kSUCCESS;
97}
98
99void R3BNeulandDigitizer::Exec(Option_t* /*option*/)
100{
101 neuland_hits_.clear();
102 const auto GeVToMeVFac = 1000.;
103
104 std::map<UInt_t, Double_t> paddleEnergyDeposit;
105 // Look at each Land Point, if it deposited energy in the scintillator, store it with reference to the bar
106 for (const auto& point : neuland_points_)
107 {
108 if (((neuland_point_filter_.GetFilter() != R3B::Neuland::BitSetParticle::none) or
109 (neuland_point_filter_.GetMinimumAllowedEnergy() != 0)) and
110 neuland_point_filter_.CheckFiltered(point))
111 {
112 continue;
113 }
114 if (point.GetEnergyLoss() > 0.)
115 {
116 const Int_t paddleID = point.GetPaddle();
117
118 // Convert position of point to paddle-coordinates, including any rotation or translation
119 const TVector3 position = point.GetPosition();
120 const TVector3 converted_position = neuland_geo_par_->ConvertToLocalCoordinates(position, paddleID);
121 LOG(debug2) << "NeulandDigitizer: Point in paddle " << paddleID
122 << " with global position XYZ: " << position.X() << " " << position.Y() << " " << position.Z();
123 LOG(debug2) << "NeulandDigitizer: Converted to local position XYZ: " << converted_position.X() << " "
124 << converted_position.Y() << " " << converted_position.Z();
125
126 // Within the paddle frame, the relevant distance of the light from the pmt is always given by the
127 // X-Coordinate
128 const Double_t dist = converted_position.X();
129 digitizing_engine_->DepositLight(paddleID, point.GetTime(), point.GetLightYield() * GeVToMeVFac, dist);
130 paddleEnergyDeposit[paddleID] += point.GetEnergyLoss() * GeVToMeVFac;
131 } // eloss
132 } // points
133
134 const Double_t triggerTime = digitizing_engine_->GetTriggerTime();
135 const auto paddles = digitizing_engine_->ExtractPaddles();
136
137 // Fill control histograms
138 hist_multi_one_->Fill(static_cast<int>(std::count_if(
139 paddles.begin(), paddles.end(), [](const auto& keyValue) { return keyValue.second->HasHalfFired(); })));
140
141 hist_multi_two_->Fill(static_cast<int>(std::count_if(
142 paddles.begin(), paddles.end(), [](const auto& keyValue) { return keyValue.second->HasFired(); })));
143
144 hist_rl_time_to_trig_->Fill(triggerTime);
145
146 // Create Hits
147 neuland_hits_.clear();
148 auto& hits = neuland_hits_.get();
149 for (const auto& [paddleID, paddle] : paddles)
150 {
151 if (!paddle->HasFired())
152 {
153 continue;
154 }
155
156 auto signals = paddle->GetSignals();
157
158 for (const auto& signal : signals)
159 {
160 const TVector3 hitPositionLocal = TVector3(signal.position, 0., 0.);
161 const TVector3 hitPositionGlobal = neuland_geo_par_->ConvertToGlobalCoordinates(hitPositionLocal, paddleID);
162 const TVector3 hitPixel = neuland_geo_par_->ConvertGlobalToPixel(hitPositionGlobal);
163
164 R3BNeulandHit hit(paddleID,
165 signal.leftChannel->tdc,
166 signal.rightChannel->tdc,
167 signal.time,
168 signal.leftChannel->qdcUnSat,
169 signal.rightChannel->qdcUnSat,
170 signal.energy,
171 hitPositionGlobal,
172 hitPixel);
173
174 if (hit_filters_.IsValid(hit))
175 {
176 neuland_hits_.get().emplace_back(std::move(hit));
177 LOG(debug) << "Adding neuland hit with id = " << paddleID << ", time = " << signal.time
178 << ", energy = " << signal.energy;
179 LOG(debug) << "Adding neuland hit with id = " << paddleID
180 << ", tot_l = " << (signal.leftChannel->qdcUnSat * 15) + 14
181 << ", tot_r = " << (signal.rightChannel->qdcUnSat * 15) + 14;
182 }
183 } // loop over all hits for each paddle
184 } // loop over paddles
185
186 if (is_cal_output_)
187 {
188 fill_cal_data(paddles);
189 }
190 LOG(debug) << "R3BNeulandDigitizer: produced " << hits.size() << " hits";
191}
192
193void R3BNeulandDigitizer::fill_cal_data(const std::map<int, std::unique_ptr<R3B::Digitizing::Paddle>>& paddles)
194{
195 neuland_cal_hits_.clear();
196 auto& cal_hits = neuland_cal_hits_.get();
197 for (const auto& [paddleID, paddle] : paddles)
198 {
199 if (!paddle->HasFired())
200 {
201 continue;
202 }
203
204 auto& left_channel = paddle->GetLeftChannelRef();
205 auto& right_channel = paddle->GetRightChannelRef();
206
207 auto left_channel_signals = left_channel.GetCalSignals();
208 auto right_channel_signals = right_channel.GetCalSignals();
209
210 // LOG(error)<< " Sum pmt_peak_: "<<
211 // std::accumulate(right_channel.pmt_peaks_.begin(),right_channel.pmt_peaks_.end(),0)<<std::endl;
212 for (const auto& [left, right] : ranges::zip_view(left_channel_signals, right_channel_signals))
213 {
214
215 auto cal_data = R3B::Neuland::SimCalData{ paddleID, left.tot, right.tot, left.tle, right.tle };
216
217 if (fCalHitFilters.IsValid(cal_data))
218 {
219 cal_hits.push_back(std::move(cal_data));
220 LOG(debug) << "Adding cal with id = " << paddleID << " left tot " << left.tot << " right tot "
221 << right.tot << '\n';
222 }
223 } // loop over all hits for each paddle
224 } // loop over paddles
225
226 LOG(debug) << "R3BNeulandDigitizerCalData: produced " << cal_hits.size() << " hits";
227}
228
230{
231 TDirectory* tmp = gDirectory;
232 FairRootManager::Instance()->GetOutFile()->cd();
233
234 gDirectory->mkdir("R3BNeulandDigitizer");
235 gDirectory->cd("R3BNeulandDigitizer");
236
237 hist_multi_one_->Write();
238 hist_multi_two_->Write();
239
240 gDirectory = tmp;
241}
242
ClassImp(R3BNeulandDigitizer)
NeuLAND digitizing finder task.
auto Init() -> InitStatus override
void Exec(Option_t *) override
void SetParContainers() override
Digitizing::Neuland::TacQuila::Channel TacquilaChannel
void SetEngine(std::unique_ptr< Digitizing::DigitizingEngineInterface > engine)
Digitizing::Neuland::NeulandPaddle NeulandPaddle
Digitizing::UsePaddle< Type > UsePaddle
void SetNeulandPointFilter(R3B::Neuland::BitSetParticle particle)
Digitizing::UseChannel< Type > UseChannel
NeuLAND geometry parameter storage.
void clear() override