Skip to content

Commit 493aee0

Browse files
committed
Reapply "Implement particle filtering via NeulandPointFilter"
This reverts commit 7826525.
1 parent 31b7fb3 commit 493aee0

19 files changed

+605
-369
lines changed

.zenodo.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@
324324
"orcid": "0000-0002-6506-8562",
325325
"affiliation": "STFC Daresbury Laboratory, Warrington, United Kingdom"
326326
},
327+
{
328+
"type": "Other",
329+
"name": "Lonzen, Simon",
330+
"affiliation": "Universität zu Köln, 50923 Köln, Germany"
331+
},
327332
{
328333
"type": "Other",
329334
"name": "Lorenz, Enis",

CONTRIBUTORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Jelavic-Malenica, Deša [RBI Zagreb, HR10000 Zagreb, Croatia]
1414
Jenegger, Tobias [Technische Universität München, 85748 Garching, Germany]
1515
Kripko, Aron
1616
Labiche, Marc [https://orcid.org/0000-0002-6506-8562] [STFC Daresbury Laboratory, Warrington, United Kingdom]
17+
Lonzen, Simon
1718
Lorenz, Enis [Technische Universität Darmstadt, Fachbereich Physik, Institut für Kernphysik, 64289 Darmstadt, Germany]
1819
Paschalis, Stefanos [https://orcid.org/0000-0002-9113-3778] [School of Physics, Engineering and Technology, University of York, YO10 5DD York, United Kingdom]
1920
Perea, Angel [Instituto de Estructura de la Materia, CSIC, 28006 Madrid, Spain]

neuland/digitizing/CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ set(SRCS
1818
R3BDigitizingPaddleNeuland.cxx
1919
R3BNeulandHitMon.cxx
2020
R3BNeulandDigitizer.cxx
21-
R3BDigitizingPaddleMock.h
22-
R3BDigitizingChannelMock.h)
21+
R3BNeulandHitMon.cxx
22+
NeulandPointFilter.cxx)
2323

2424
set(HEADERS
2525
R3BDigitizingChannel.h
@@ -31,7 +31,8 @@ set(HEADERS
3131
R3BDigitizingTacQuila.h
3232
R3BDigitizingTamex.h
3333
R3BNeulandDigitizer.h
34-
R3BNeulandHitMon.h)
34+
R3BNeulandHitMon.h
35+
NeulandPointFilter.h)
3536

3637
add_library_with_dictionary(
3738
LIBNAME
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "NeulandPointFilter.h"
2+
3+
void NeulandPointFilter::SetFilter(R3B::Neuland::BitSetParticle filtered_particles)
4+
{
5+
filtered_particles_ = filtered_particles;
6+
}
7+
void NeulandPointFilter::SetFilter(R3B::Neuland::BitSetParticle filtered_particles, double minimum_allowed_energy)
8+
{
9+
filtered_particles_ = filtered_particles;
10+
minimum_allowed_energy_ = minimum_allowed_energy;
11+
}
12+
13+
auto NeulandPointFilter::CheckFiltered(const R3BNeulandPoint& neuland_point) -> bool
14+
{
15+
return (
16+
R3B::Neuland::CheckCriteria(R3B::Neuland::PidToBitSetParticle(neuland_point.GetPID()), filtered_particles_) or
17+
(neuland_point.GetEnergyLoss() < minimum_allowed_energy_));
18+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#pragma once
2+
#include "R3BNeulandPoint.h"
3+
#include <bitset>
4+
5+
namespace R3B::Neuland
6+
{
7+
enum class BitSetParticle : uint32_t
8+
{
9+
none = 0x0000,
10+
proton = 0x0001,
11+
neutron = 0x0002,
12+
electron = 0x0004,
13+
positron = 0x0008,
14+
alpha = 0x0010,
15+
gamma = 0x0020,
16+
meson = 0x0040,
17+
other = 0x40000000
18+
};
19+
20+
const std::unordered_map<int, BitSetParticle> PidToBitSetParticleHash = {
21+
{ 2212, BitSetParticle::proton }, { 2112, BitSetParticle::neutron }, { 11, BitSetParticle::electron },
22+
{ -11, BitSetParticle::positron }, { 1000040020, BitSetParticle::alpha }, { 22, BitSetParticle::gamma },
23+
{ 0, BitSetParticle::none }
24+
};
25+
26+
constexpr auto ParticleBitsetSize = 32U;
27+
28+
using ParticleUType = std::underlying_type_t<BitSetParticle>;
29+
30+
constexpr auto ParticleToBitSet(BitSetParticle particle)
31+
{
32+
return std::bitset<ParticleBitsetSize>{ static_cast<ParticleUType>(particle) };
33+
}
34+
35+
inline auto BitSetToParticle(std::bitset<ParticleBitsetSize> bits) -> BitSetParticle
36+
{
37+
return static_cast<BitSetParticle>(static_cast<uint32_t>(bits.to_ulong()));
38+
}
39+
40+
inline auto CheckCriteria(BitSetParticle particle, BitSetParticle criteria) -> bool
41+
{
42+
return (ParticleToBitSet(particle) & ParticleToBitSet(criteria)) == ParticleToBitSet(particle);
43+
}
44+
45+
inline auto operator|(BitSetParticle left, BitSetParticle right) -> BitSetParticle
46+
{
47+
auto left_bitset = ParticleToBitSet(left);
48+
auto right_bitset = ParticleToBitSet(right);
49+
return BitSetToParticle(left_bitset | right_bitset);
50+
}
51+
52+
inline auto operator&(BitSetParticle left, BitSetParticle right) -> BitSetParticle
53+
{
54+
auto left_bitset = ParticleToBitSet(left);
55+
auto right_bitset = ParticleToBitSet(right);
56+
return BitSetToParticle(left_bitset & right_bitset);
57+
}
58+
59+
inline auto operator~(BitSetParticle particle) -> BitSetParticle
60+
{
61+
return BitSetToParticle(~ParticleToBitSet(particle));
62+
}
63+
64+
inline auto PidToBitSetParticle(int pid) -> BitSetParticle
65+
{
66+
if (pid > 99 and pid < 1000) // NOLINT mesons have three digit pdgs
67+
{
68+
return BitSetParticle::meson;
69+
}
70+
auto pid_to_bitset_hash_iterator = PidToBitSetParticleHash.find(pid);
71+
72+
if (pid_to_bitset_hash_iterator == PidToBitSetParticleHash.end())
73+
{
74+
return BitSetParticle::other;
75+
}
76+
77+
return pid_to_bitset_hash_iterator->second;
78+
}
79+
80+
} // namespace R3B::Neuland
81+
class NeulandPointFilter
82+
{
83+
public:
84+
NeulandPointFilter() = default;
85+
void SetFilter(R3B::Neuland::BitSetParticle filtered_particles);
86+
void SetFilter(R3B::Neuland::BitSetParticle filtered_particles, double minimum_allowed_energy);
87+
[[nodiscard]] auto GetFilter() const -> R3B::Neuland::BitSetParticle { return filtered_particles_; }
88+
[[nodiscard]] auto GetMinimumAllowedEnergy() const -> double { return minimum_allowed_energy_; }
89+
auto CheckFiltered(const R3BNeulandPoint& neuland_point) -> bool;
90+
91+
private:
92+
R3B::Neuland::BitSetParticle filtered_particles_ = R3B::Neuland::BitSetParticle::none;
93+
double minimum_allowed_energy_ = 0; // engergy in GeV
94+
};

neuland/digitizing/R3BNeulandDigitizer.cxx

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "FairRootManager.h"
1717
#include "FairRunAna.h"
1818
#include "FairRuntimeDb.h"
19+
#include "NeulandPointFilter.h"
20+
#include "R3BDataMonitor.h"
1921
#include "TGeoManager.h"
2022
#include "TGeoNode.h"
2123
#include "TH1F.h"
@@ -26,28 +28,25 @@
2628
#include <TFile.h>
2729
#include <iostream>
2830
#include <stdexcept>
31+
#include <string_view>
2932
#include <utility>
3033

31-
R3BNeulandDigitizer::R3BNeulandDigitizer(TString input, TString output)
32-
: R3BNeulandDigitizer(Digitizing::CreateEngine(UsePaddle<NeulandPaddle>(), UseChannel<TacquilaChannel>()),
33-
std::move(input),
34-
std::move(output))
34+
R3BNeulandDigitizer::R3BNeulandDigitizer()
35+
: R3BNeulandDigitizer(Digitizing::CreateEngine(UsePaddle<NeulandPaddle>(), UseChannel<TacquilaChannel>())
36+
37+
)
3538
{
3639
}
3740

38-
R3BNeulandDigitizer::R3BNeulandDigitizer(std::unique_ptr<Digitizing::DigitizingEngineInterface> engine,
39-
TString input,
40-
TString output)
41+
R3BNeulandDigitizer::R3BNeulandDigitizer(std::unique_ptr<Digitizing::DigitizingEngineInterface> engine)
4142
: FairTask("R3BNeulandDigitizer")
42-
, fPoints(std::move(input))
43-
, fHits(std::move(output))
44-
, fDigitizingEngine(std::move(engine))
43+
, digitizing_engine_(std::move(engine))
4544
{
4645
}
4746

4847
void R3BNeulandDigitizer::SetEngine(std::unique_ptr<Digitizing::DigitizingEngineInterface> engine)
4948
{
50-
fDigitizingEngine = std::move(engine);
49+
digitizing_engine_ = std::move(engine);
5150
}
5251

5352
void R3BNeulandDigitizer::SetParContainers()
@@ -64,48 +63,64 @@ void R3BNeulandDigitizer::SetParContainers()
6463
LOG(fatal) << "R3BNeulandDigitizer::SetParContainers: No runtime database";
6564
}
6665

67-
fNeulandGeoPar = dynamic_cast<R3BNeulandGeoPar*>(rtdb->getContainer("R3BNeulandGeoPar"));
68-
if (fNeulandGeoPar == nullptr)
66+
neuland_geo_par_ = dynamic_cast<R3BNeulandGeoPar*>(rtdb->getContainer("R3BNeulandGeoPar"));
67+
if (neuland_geo_par_ == nullptr)
6968
{
7069
LOG(fatal) << "R3BNeulandDigitizer::SetParContainers: No R3BNeulandGeoPar";
7170
}
7271

73-
fDigitizingEngine->Init();
72+
digitizing_engine_->Init();
7473
}
7574

76-
InitStatus R3BNeulandDigitizer::Init()
75+
void R3BNeulandDigitizer::SetNeulandPointFilter(R3B::Neuland::BitSetParticle particle)
76+
{
77+
neuland_point_filter_.SetFilter(particle);
78+
}
79+
void R3BNeulandDigitizer::SetNeulandPointFilter(R3B::Neuland::BitSetParticle particle,
80+
double minimum_allowed_energy_gev)
7781
{
78-
fPoints.Init();
79-
fHits.Init();
82+
neuland_point_filter_.SetFilter(particle, minimum_allowed_energy_gev);
83+
}
8084

85+
auto R3BNeulandDigitizer::Init() -> InitStatus
86+
{
87+
neuland_points_.init();
88+
neuland_hits_.init();
8189
// Initialize control histograms
8290
auto const PaddleMulSize = 3000;
83-
hMultOne = R3B::root_owned<TH1I>(
91+
mult_one_ = data_monitor_.add_hist<TH1I>(
8492
"MultiplicityOne", "Paddle multiplicity: only one PMT per paddle", PaddleMulSize, 0, PaddleMulSize);
85-
hMultTwo = R3B::root_owned<TH1I>(
93+
94+
mult_two_ = data_monitor_.add_hist<TH1I>(
8695
"MultiplicityTwo", "Paddle multiplicity: both PMTs of a paddle", PaddleMulSize, 0, PaddleMulSize);
8796
auto const timeBinSize = 200;
88-
hRLTimeToTrig = R3B::root_owned<TH1F>("hRLTimeToTrig", "R/Ltime-triggerTime", timeBinSize, -100., 100.);
97+
rl_time_to_trig_ = data_monitor_.add_hist<TH1F>("hRLTimeToTrig", "R/Ltime-triggerTime", timeBinSize, -100., 100.);
8998

9099
return kSUCCESS;
91100
}
92101

93102
void R3BNeulandDigitizer::Exec(Option_t* /*option*/)
94103
{
95-
fHits.Reset();
104+
neuland_hits_.clear();
96105
const auto GeVToMeVFac = 1000.;
97106

98107
std::map<UInt_t, Double_t> paddleEnergyDeposit;
99108
// Look at each Land Point, if it deposited energy in the scintillator, store it with reference to the bar
100-
for (const auto& point : fPoints.Retrieve())
109+
for (const auto& point : neuland_points_)
101110
{
102-
if (point->GetEnergyLoss() > 0.)
111+
if (((neuland_point_filter_.GetFilter() != R3B::Neuland::BitSetParticle::none) or
112+
(neuland_point_filter_.GetMinimumAllowedEnergy() != 0)) and
113+
neuland_point_filter_.CheckFiltered(point))
103114
{
104-
const Int_t paddleID = point->GetPaddle();
115+
continue;
116+
}
117+
if (point.GetEnergyLoss() > 0.)
118+
{
119+
const Int_t paddleID = point.GetPaddle();
105120

106121
// Convert position of point to paddle-coordinates, including any rotation or translation
107-
const TVector3 position = point->GetPosition();
108-
const TVector3 converted_position = fNeulandGeoPar->ConvertToLocalCoordinates(position, paddleID);
122+
const TVector3 position = point.GetPosition();
123+
const TVector3 converted_position = neuland_geo_par_->ConvertToLocalCoordinates(position, paddleID);
109124
LOG(debug2) << "NeulandDigitizer: Point in paddle " << paddleID
110125
<< " with global position XYZ: " << position.X() << " " << position.Y() << " " << position.Z();
111126
LOG(debug2) << "NeulandDigitizer: Converted to local position XYZ: " << converted_position.X() << " "
@@ -114,22 +129,22 @@ void R3BNeulandDigitizer::Exec(Option_t* /*option*/)
114129
// Within the paddle frame, the relevant distance of the light from the pmt is always given by the
115130
// X-Coordinate
116131
const Double_t dist = converted_position.X();
117-
fDigitizingEngine->DepositLight(paddleID, point->GetTime(), point->GetLightYield() * GeVToMeVFac, dist);
118-
paddleEnergyDeposit[paddleID] += point->GetEnergyLoss() * GeVToMeVFac;
132+
digitizing_engine_->DepositLight(paddleID, point.GetTime(), point.GetLightYield() * GeVToMeVFac, dist);
133+
paddleEnergyDeposit[paddleID] += point.GetEnergyLoss() * GeVToMeVFac;
119134
} // eloss
120135
} // points
121136

122-
const Double_t triggerTime = fDigitizingEngine->GetTriggerTime();
123-
const auto paddles = fDigitizingEngine->ExtractPaddles();
137+
const Double_t triggerTime = digitizing_engine_->GetTriggerTime();
138+
const auto paddles = digitizing_engine_->ExtractPaddles();
124139

125140
// Fill control histograms
126-
hMultOne->Fill(static_cast<int>(std::count_if(
141+
mult_one_->Fill(static_cast<int>(std::count_if(
127142
paddles.begin(), paddles.end(), [](const auto& keyValue) { return keyValue.second->HasHalfFired(); })));
128143

129-
hMultTwo->Fill(static_cast<int>(std::count_if(
144+
mult_two_->Fill(static_cast<int>(std::count_if(
130145
paddles.begin(), paddles.end(), [](const auto& keyValue) { return keyValue.second->HasFired(); })));
131146

132-
hRLTimeToTrig->Fill(triggerTime);
147+
rl_time_to_trig_->Fill(triggerTime);
133148

134149
// Create Hits
135150
for (const auto& [paddleID, paddle] : paddles)
@@ -144,8 +159,8 @@ void R3BNeulandDigitizer::Exec(Option_t* /*option*/)
144159
for (const auto signal : signals)
145160
{
146161
const TVector3 hitPositionLocal = TVector3(signal.position, 0., 0.);
147-
const TVector3 hitPositionGlobal = fNeulandGeoPar->ConvertToGlobalCoordinates(hitPositionLocal, paddleID);
148-
const TVector3 hitPixel = fNeulandGeoPar->ConvertGlobalToPixel(hitPositionGlobal);
162+
const TVector3 hitPositionGlobal = neuland_geo_par_->ConvertToGlobalCoordinates(hitPositionLocal, paddleID);
163+
const TVector3 hitPixel = neuland_geo_par_->ConvertGlobalToPixel(hitPositionGlobal);
149164

150165
R3BNeulandHit hit(paddleID,
151166
signal.leftChannel.tdc,
@@ -157,30 +172,16 @@ void R3BNeulandDigitizer::Exec(Option_t* /*option*/)
157172
hitPositionGlobal,
158173
hitPixel);
159174

160-
if (fHitFilters.IsValid(hit))
175+
if (neuland_hit_filters_.IsValid(hit))
161176
{
162-
fHits.Insert(std::move(hit));
177+
neuland_hits_.get().emplace_back(std::move(hit));
163178
LOG(debug) << "Adding neuland hit with id = " << paddleID << ", time = " << signal.time
164179
<< ", energy = " << signal.energy;
165180
}
166181
} // loop over all hits for each paddle
167182
} // loop over paddles
168183

169-
LOG(debug) << "R3BNeulandDigitizer: produced " << fHits.Size() << " hits";
170-
}
171-
172-
void R3BNeulandDigitizer::Finish()
173-
{
174-
TDirectory* tmp = gDirectory;
175-
FairRootManager::Instance()->GetOutFile()->cd();
176-
177-
gDirectory->mkdir("R3BNeulandDigitizer");
178-
gDirectory->cd("R3BNeulandDigitizer");
179-
180-
hMultOne->Write();
181-
hMultTwo->Write();
182-
183-
gDirectory = tmp;
184+
LOG(debug) << "R3BNeulandDigitizer: produced " << neuland_hits_.get().size() << " hits";
184185
}
185186

186187
ClassImp(R3BNeulandDigitizer); // NOLINT

0 commit comments

Comments
 (0)