11 : fArrayOfDigits(nullptr)
12 , fBmnHodoEvent(nullptr)
18 LOG(detail) << Form(
"BmnHodoReconstructor: isExp %i", fIsExp);
21void BmnHodoReconstructor::ParseConfig(
const std::string& inputFile)
23 std::string fullPath = std::string(getenv(
"VMCWORKDIR")) +
"/parameters/hodo/" + inputFile;
24 std::ifstream input(fullPath);
25 if (!input.is_open()) {
26 LOG(error) <<
"BmnHodoReconstructor::ParseConfig: Cannot open file " << fullPath;
33 }
catch (
const std::exception& e) {
34 LOG(error) <<
"BmnHodoReconstructor::ParseConfig: Failed to parse JSON: " << e.what();
39 std::string comment = j.
value(
"comment",
"none");
41 LOG(debug) <<
"BmnHodoReconstructor::ParseConfig. Version: " <<
version;
42 LOG(debug) <<
"BmnHodoReconstructor::ParseConfig. Comment: " << comment;
44 fuoResolutionMap.clear();
45 for (
const auto& entry : j[
"calibration"]) {
46 int strip = entry[
"strip"];
47 int side = entry[
"side"];
48 int gain = entry[
"gain"];
49 double stochastic = entry[
"stochastic"];
50 double constant = entry[
"constant"];
53 Kernel resolution(stochastic, constant);
54 fuoResolutionMap.emplace(address, resolution);
60 std::string fullPath = std::string(getenv(
"VMCWORKDIR")) +
"/parameters/hodo/" + cuts;
61 std::ifstream test(fullPath);
62 if (!test.is_open()) {
63 LOG(warn) << Form(
"BmnHodoReconstructor: cuts file not found: %s. Using default (no cuts).", fullPath.c_str());
69 LOG(info) << Form(
"BmnHodoReconstructor: cuts loaded from %s (isExp=%d)", fullPath.c_str(), fIsExp);
83 fpFairRootMgr = FairRootManager::Instance();
85 LOG(error) <<
"BmnHodoReconstructor::Init(): FairRootManager instance is nullptr! Task will be deactivated";
90 fArrayOfDigits = (TClonesArray*)fpFairRootMgr->GetObject((fIsExp) ?
"HodoDigi" :
"HodoDigit");
91 if (!fArrayOfDigits) {
92 LOG(error) <<
"BmnHodoReconstructor::Init(): branch with Digits not found! Task will be deactivated";
98 fBmnHodoEvent->
reset();
99 fpFairRootMgr->RegisterAny(
"HodoEvent", fBmnHodoEvent, kTRUE);
100 fpFairRootMgr->Register(
"HodoEvent",
"Hodo", fBmnHodoEvent, kFALSE);
102 LOG(debug) <<
"Hodo Reconstructor ready";
114 auto stripMap = BuildFilteredStripMap();
116 for (
auto& [strip_id, digis] : stripMap) {
117 double numerator = 0.0;
118 double denominator = 0.0;
119 double integrator = 0.0;
121 for (
auto* digit : digis) {
122 auto address = digit->GetAddress();
123 auto it = fuoResolutionMap.find(address);
124 if (it == fuoResolutionMap.end())
127 const double signal = digit->GetSignal();
128 const double sigma = it->second.sigma(signal);
132 const double weight = 1.0 / (sigma * sigma);
133 numerator += signal * weight;
134 denominator += weight;
136 integrator += (
static_cast<BmnHodoDigi*
>(digit))->fSignalIntegral * weight;
139 if (denominator > 0) {
140 auto* strip = fBmnHodoEvent->
GetStrip(strip_id);
141 strip->
SetSignal(numerator / denominator);
143 strip->SetSignalIntegral(integrator / denominator);
145 strip->SetSignalIntegral(strip->GetSignal());
147 LOG(debug4) << Form(
"Strip %d skipped: no valid resolution info", strip_id);
153 fworkTime += sw.RealTime();
156std::vector<BmnHodoDigit*> BmnHodoReconstructor::GetDenoisedDigis()
158 std::vector<BmnHodoDigit*> denoised;
159 denoised.reserve(fArrayOfDigits->GetEntriesFast());
161 for (
int i = 0, n = fArrayOfDigits->GetEntriesFast();
i < n; ++
i) {
167 denoised.push_back(
d);
173 denoised.push_back(
d);
177 LOG(debug4) << Form(
"Hodo denoise: kept %zu / %d (%.1f%%)%s", denoised.size(), fArrayOfDigits->GetEntriesFast(),
178 100.0 * denoised.size() / std::max(1, fArrayOfDigits->GetEntriesFast()),
179 fCuts ?
"" :
" [no cuts applied]");
183std::vector<BmnHodoDigit*> BmnHodoReconstructor::DesaturateDigis(
const std::vector<BmnHodoDigit*>& input)
const
185 std::unordered_map<uint32_t, std::vector<BmnHodoDigit*>> byStrip;
186 byStrip.reserve(input.size());
188 for (
auto*
d : input)
189 byStrip[
d->GetStripId()].push_back(
d);
191 std::vector<BmnHodoDigit*>
result;
192 result.reserve(input.size());
194 for (
auto& [strip, vec] : byStrip) {
195 const bool hasClean = std::any_of(vec.begin(), vec.end(), [](
auto*
d) { return !d->GetIsSaturated(); });
199 if (!
d->GetIsSaturated())
203 std::vector<BmnHodoDigit*> lowGain;
205 if (
d->GetGain() == 0)
206 lowGain.push_back(
d);
209 if (!lowGain.empty()) {
210 chosen = *std::min_element(lowGain.begin(), lowGain.end(),
211 [](
auto* a,
auto* b) { return a->GetSignal() < b->GetSignal(); });
213 chosen = *std::min_element(vec.begin(), vec.end(),
214 [](
auto* a,
auto* b) { return a->GetSignal() < b->GetSignal(); });
222std::vector<BmnHodoDigit*> BmnHodoReconstructor::ResolvePileup(
const std::vector<BmnHodoDigit*>& input)
224 std::unordered_map<uint32_t, std::vector<BmnHodoDigi*>> byAddr;
225 byAddr.reserve(input.size());
227 for (
auto*
d : input)
230 std::vector<BmnHodoDigit*> resolved;
231 resolved.reserve(byAddr.size());
233 for (
auto& [addr, vec] : byAddr) {
235 auto* strip = fBmnHodoEvent->
GetStrip(strip_id);
237 if (vec.size() == 1) {
238 auto*
d = vec.front();
241 resolved.push_back(
d);
243 auto* minAmp = *std::min_element(vec.begin(), vec.end(),
244 [](
auto* a,
auto* b) { return a->GetSignal() < b->GetSignal(); });
246 resolved.push_back(minAmp);
253std::unordered_map<uint32_t, std::vector<BmnHodoDigit*>> BmnHodoReconstructor::BuildFilteredStripMap()
256 auto denoised = GetDenoisedDigis();
259 auto desat = DesaturateDigis(denoised);
262 std::vector<BmnHodoDigit*> processed = (fIsExp) ? ResolvePileup(desat) : desat;
265 std::unordered_map<uint32_t, std::vector<BmnHodoDigit*>> stripMap;
266 stripMap.reserve(processed.size());
267 for (
auto* digi : processed)
268 stripMap[digi->GetStripId()].push_back(digi);
278 resultTree->Branch(
"HodoEvent", &fBmnHodoEvent);
284 printf(
"Work time of BmnHodoReconstructor: %4.2f sec.\n", fworkTime);
const Float_t d
Z-ccordinate of the first GEM-station.
static uint32_t GetStripId(uint32_t address)
Return Strip id from address.
static uint32_t GetAddress(uint32_t StripId, uint32_t StripSide, uint32_t Gain)
Return address from system ID, StripId, StripSide, Gain.
Data class for BmnHodo digital signal processing.
Class for Bmn Hodo data container in event.
BmnHodoStrip * GetStrip(uint8_t strip_id)
void SetRecoCutsFile(const std::string &cuts)
BmnHodoReconstructor(const std::string &config, bool isExp)
virtual void OnlineWrite(const std::unique_ptr< TTree > &resultTree)
Write task resul to tree.
virtual InitStatus Init()
virtual void Exec(Option_t *opt)
void SetPileUpStatus(PileUp pileUp)
void SetSignal(float Signal)
a class to store JSON values
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Int_t GetAddress(UInt_t unit=0, UInt_t ladder=0, UInt_t halfladder=0, UInt_t module=0, UInt_t sensor=0, UInt_t side=0, UInt_t version=kCurrentVersion)
Construct address.
bool PassExp(const BmnHodoDigi *d) const
static BmnHodoCuts Load(const std::string &file, bool isExp)
bool PassSim(const BmnHodoDigit *d) const