er  dev
ERDigiCleaner.cxx
1 /********************************************************************************
2  * Copyright (C) Joint Institute for Nuclear Research *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 #include "ERDigiCleaner.h"
9 
10 #include <set>
11 
12 #include "FairLogger.h"
13 #include "FairRun.h"
14 
15 #include "ERSupport.h"
16 #include "ERRunAna.h"
17 #include "ERDigi.h"
18 #include "ERNDDigi.h"
19 
20 //--------------------------------------------------------------------------------------------------
22  : ERTask("ERDigiCleaner") {
23  fAvailibleRunManagers.push_back("ERRunAna");
24 }
25 //--------------------------------------------------------------------------------------------------
26 void ERDigiCleaner::Recalibrate(
27  const TString& detectorName, const TString& stationName,
28  const TString& previousTimeCalFile, const TString& timeCalFile,
29  const TString& previousAmpCalFile, const TString& ampCalFile,
30  ChannelMapping* raw2SimChannelsMapping/* = nullptr*/) {
31  fStationsRecalibrations.emplace_back(
32  detectorName, stationName,
33  previousTimeCalFile != "" ? ReadCalFile(previousTimeCalFile) : nullptr,
34  timeCalFile != "" ? ReadCalFile(timeCalFile) : nullptr,
35  previousAmpCalFile != "" ? ReadCalFile(previousAmpCalFile) : nullptr,
36  ampCalFile != "" ? ReadCalFile(ampCalFile) : nullptr,
37  nullptr, nullptr,
38  raw2SimChannelsMapping);
39 }
40 //--------------------------------------------------------------------------------------------------
41 void ERDigiCleaner::RecalibrateWithTAC(
42  const TString& detectorName, const TString& stationName,
43  const TString& previousTimeCalFile, const TString& timeCalFile,
44  const TString& previousAmpCalFile, const TString& ampCalFile,
45  const TString& previousTACCalFile, const TString& TACCalFile,
46  ChannelMapping* raw2SimChannelsMapping/* = nullptr*/) {
47  fStationsRecalibrations.emplace_back(
48  detectorName, stationName,
49  previousTimeCalFile != "" ? ReadCalFile(previousTimeCalFile) : nullptr,
50  timeCalFile != "" ? ReadCalFile(timeCalFile) : nullptr,
51  previousAmpCalFile != "" ? ReadCalFile(previousAmpCalFile) : nullptr,
52  ampCalFile != "" ? ReadCalFile(ampCalFile) : nullptr,
53  previousTACCalFile != "" ? ReadCalFile(previousTACCalFile) : nullptr,
54  TACCalFile != "" ? ReadCalFile(TACCalFile) : nullptr,
55  raw2SimChannelsMapping);
56 }
57 //--------------------------------------------------------------------------------------------------
58 void ERDigiCleaner::SetChannelCuts(
59  const TString& detectorName, const TString& stationName,
60  const std::map<ERChannel, TCutG*>& channelGCuts, const std::map<ERChannel, Double_t>& channelMinAmp,
61  const std::map<ERChannel, Double_t>& channelMaxAmp, const std::map<ERChannel, Double_t>& channelMinTime,
62  const std::map<ERChannel, Double_t>& channelMaxTime, const ChannelMapping* raw2SimChannelsMapping /*= nullptr*/) {
63  fStationsCuts.emplace_back(detectorName, stationName, channelGCuts, channelMinAmp, channelMaxAmp,
64  channelMinTime, channelMaxTime, raw2SimChannelsMapping);
65 }
66 //--------------------------------------------------------------------------------------------------
67 InitStatus ERDigiCleaner::Init() {
68  FairRootManager* ioman = FairRootManager::Instance();
69  if ( ! ioman ) Fatal("Init", "No FairRootManager");
70  if (dynamic_cast<ERBeamTimeEventHeader*>(ioman->GetObject("EventHeader."))) {
71  fInputHeader = new ERBeamTimeEventHeader();
72  ioman->GetInTree()->SetBranchAddress("EventHeader.",&fInputHeader);
73  }
74  TList* allBranchNames = ioman->GetBranchNameList();
75  TIter nextBranch(allBranchNames);
76  while (TObjString* branchNameObj = (TObjString*)nextBranch()) {
77  std::string branchName = std::string(branchNameObj->GetString().Data());
78  fInputDigis[branchName] = static_cast<TClonesArray*>(ioman->GetObject(TString(branchName)));
79  ioman->Register(TString(branchName), "Digis", fInputDigis[branchName], kTRUE);
80  }
81  return kSUCCESS;
82 }
83 //--------------------------------------------------------------------------------------------------
84 void ERDigiCleaner::Exec(Option_t*) {
85  if (fInputHeader)
86  CopyEventHeader();
87  if (fLonelyMWPCClusterCondition && AreFewClustersInMWPC()) {
88  dynamic_cast<ERRunAna*>(fRun)->MarkFill(kFALSE);
89  Reset();
90  return;
91  }
92  Recalibration();
93  ApplyChannelCuts();
94  ApplyStationMultiplicities();
95 }
96 //--------------------------------------------------------------------------------------------------
97 void ERDigiCleaner::CopyEventHeader() {
98  FairRun* run = FairRun::Instance();
99  ERBeamTimeEventHeader* header = dynamic_cast<ERBeamTimeEventHeader*>(run->GetEventHeader());
100  if (!header)
101  return;
102  header->SetTrigger(fInputHeader->GetTrigger());
103 }
104 //--------------------------------------------------------------------------------------------------
105 bool ERDigiCleaner::AreFewClustersInMWPC(){
106  const auto isMWPCBranch = [](const TString& branchName) {
107  const std::list<std::string> mwpcBranches = {
108  "BeamDetMWPCDigiX1", "BeamDetMWPCDigiX2", "BeamDetMWPCDigiY1", "BeamDetMWPCDigiY2"};
109  return std::find(mwpcBranches.begin(), mwpcBranches.end(), branchName) != mwpcBranches.end();
110  };
111  for (const auto& digiBranchNameAndCollection : fInputDigis) {
112  const auto branchName = digiBranchNameAndCollection.first;
113  if (!isMWPCBranch(branchName))
114  continue;
115  const auto& digis = digiBranchNameAndCollection.second;
116  std::set<Int_t> wireNumbers; // ordered
117  for (Int_t iDigi(0); iDigi < digis->GetEntriesFast(); iDigi++) {
118  const auto wireNumber = static_cast<ERDigi*>(digis->At(iDigi))->Channel();
119  wireNumbers.insert(wireNumber);
120  }
121  const auto wireCount = wireNumbers.size();
122  if (wireCount < 2)
123  continue;
124  const auto& firstNumber = *wireNumbers.begin();
125  const auto& lastNumber = *wireNumbers.rbegin();
126  if (lastNumber - firstNumber >= wireCount)
127  return true;
128  }
129  return false;
130 }
131 //--------------------------------------------------------------------------------------------------
132 void ERDigiCleaner::Recalibration() {
133  for (auto& recalibrationTask : fStationsRecalibrations) {
134  auto branchNameAndDigis = GetBranchNameAndDigis(recalibrationTask.fDetectorName,
135  recalibrationTask.fStationName);
136  if (!branchNameAndDigis.second) {
137  LOG(FATAL) << "[Recalibration] Digi branch for station " << recalibrationTask.fStationName
138  << " of detector " << recalibrationTask.fDetectorName
139  << " not found." << FairLogger::endl;
140  }
141  LOG(DEBUG) << "[Recalibration] Station " << recalibrationTask.fStationName << " of detector "
142  << recalibrationTask.fDetectorName << FairLogger::endl;
143  const auto& branchName = branchNameAndDigis.first;
144  auto& digis = branchNameAndDigis.second;
145  auto& prevTimeCalibration = recalibrationTask.fPreviousTimeCalibration;
146  auto& timeCalibration = recalibrationTask.fTimeCalibration;
147  auto& prevAmpCalibration = recalibrationTask.fPreviousAmpCalibration;
148  auto& ampCalibration = recalibrationTask.fAmpCalibration;
149  auto& prevTACCalibration = recalibrationTask.fPreviousTACCalibration;
150  auto& TACCalibration = recalibrationTask.fTACCalibration;
151  for (Int_t iDigi(0); iDigi < digis->GetEntriesFast(); iDigi++) {
152  // linear calibration: res = table[channel][0] + table[channel][1] * raw
153  auto digi = dynamic_cast<ERDigi*>(digis->At(iDigi));
154  if (!digi) {
155  LOG(FATAL) << "[Recalibration] Recalibration is not available for branch " << branchName << FairLogger::endl;
156  }
157  const auto channel = GetChannelNumber(digi->Channel(), recalibrationTask.fSim2RawChannelMapping);
158  if (prevTimeCalibration && timeCalibration) {
159  if (channel >= prevTimeCalibration->GetNrows() || channel >= timeCalibration->GetNrows()) {
160  LOG(FATAL) << "[Recalibration] Channel " << channel << " not found time in calibration tables of station "
161  << recalibrationTask.fStationName << " of detector "
162  << recalibrationTask.fDetectorName << FairLogger::endl;
163  }
164  const auto rawTime = (digi->Time() - (*prevTimeCalibration)[channel][0])
165  / (*prevTimeCalibration)[channel][1];
166  const auto newTime = (*timeCalibration)[channel][0] + (*timeCalibration)[channel][1] * rawTime;
167  LOG(DEBUG) << "[Recalibration] Time: channel = " << channel <<", previous a = " << (*prevTimeCalibration)[channel][0]
168  << ", previous b = " << (*prevTimeCalibration)[channel][1] << " new a = " << (*timeCalibration)[channel][0]
169  << ", new b = " << (*timeCalibration)[channel][1] << ", previous = " << digi->Time()
170  << ", raw = " << rawTime << ", new time = " << newTime << FairLogger::endl;
171  digi->SetTime(newTime);
172  }
173  if (prevAmpCalibration && ampCalibration) {
174  if (channel >= prevAmpCalibration->GetNrows() || channel >= ampCalibration->GetNrows()) {
175  LOG(FATAL) << "[Recalibration] Channel " << channel << " not found in amp calibration tables of station "
176  << recalibrationTask.fStationName << " of detector "
177  << recalibrationTask.fDetectorName << FairLogger::endl;
178  }
179  const auto rawEdep = (digi->Edep() - (*prevAmpCalibration)[channel][0])
180  / (*prevAmpCalibration)[channel][1];
181  const auto newEdep = (*ampCalibration)[channel][0] + (*ampCalibration)[channel][1] * rawEdep;
182  LOG(DEBUG) << "[Recalibration] Edep: channel = " << channel << ", previous a = " << (*prevAmpCalibration)[channel][0]
183  << ", previous b = " << (*prevAmpCalibration)[channel][1] << " new a = " << (*ampCalibration)[channel][0]
184  << ", new b = " << (*ampCalibration)[channel][1] <<", previous = " << digi->Edep()
185  << ", raw = " << rawEdep << ", new = " << newEdep << FairLogger::endl;
186  digi->SetEdep(newEdep);
187  }
188  if (prevTACCalibration && TACCalibration) {
189  if (channel >= prevTACCalibration->GetNrows() || channel >= TACCalibration->GetNrows()) {
190  LOG(FATAL) << "[Recalibration] Channel " << channel << " not found in TAC calibration tables of station "
191  << recalibrationTask.fStationName << " of detector "
192  << recalibrationTask.fDetectorName << FairLogger::endl;
193  }
194  auto* NDDigi = dynamic_cast<ERNDDigi*>(digi);
195  if (!NDDigi)
196  LOG(FATAL) << "[Recalibration] You are trying to recalibrate TAC, but digi is not ERNDDigi" << FairLogger::endl;
197  const auto rawTAC = (NDDigi->TAC() - (*prevTACCalibration)[channel][0])
198  / (*prevTACCalibration)[channel][1];
199  const auto newTAC = (*TACCalibration)[channel][0] + (*TACCalibration)[channel][1] * rawTAC;
200  LOG(DEBUG) << "[Recalibration] TAC: channel = " << channel << ", previous a = " << (*prevTACCalibration)[channel][0]
201  << ", previous b = " << (*prevTACCalibration)[channel][1] << " new a = " << (*TACCalibration)[channel][0]
202  << ", new b = " << (*TACCalibration)[channel][1] <<", previous = " << NDDigi->TAC()
203  << ", raw = " << rawTAC << ", new = " << newTAC << FairLogger::endl;
204  NDDigi->SetTAC(newTAC);
205  }
206  }
207  }
208 }
209 //--------------------------------------------------------------------------------------------------
210 void ERDigiCleaner::ApplyChannelCuts() {
211  if (fStationsCuts.empty())
212  return;
213  auto tofBranchAndDigi = GetBranchNameAndDigis("BeamDet", "ToFDigi2");
214  if (!tofBranchAndDigi.second)
215  LOG(FATAL) << "Digi branch for TOF2 station not found." << FairLogger::endl;
216  const auto tofTime = static_cast<ERDigi*>(tofBranchAndDigi.second->At(0))->Time();
217  for (const auto& stationCuts : fStationsCuts) {
218  auto branchNameAndDigis = GetBranchNameAndDigis(stationCuts.fDetectorName,
219  stationCuts.fStationName);
220  auto& digis = branchNameAndDigis.second;
221  if (!digis) {
222  LOG(FATAL) << "Digi branch for station " << stationCuts.fStationName
223  << " of detector " << stationCuts.fDetectorName
224  << " not found." << FairLogger::endl;
225  }
226  const auto branchName = branchNameAndDigis.first;
227  std::list<TObject*> digisToRemove;
228  for (Int_t iDigi(0); iDigi < digis->GetEntriesFast(); iDigi++) {
229  auto* digi = dynamic_cast<ERDigi*>(digis->At(iDigi));
230  if (!digi) {
231  LOG(FATAL) << "Recalibration is not available for branch " << branchName << FairLogger::endl;
232  }
233  const auto channel = GetChannelNumber(digi->Channel(), stationCuts.fSim2RawChannelMapping);
234  const auto time = digi->Time() - tofTime;
235  const auto edep = digi->Edep();
236  const auto& channelsGCuts = stationCuts.fChannelGCuts;
237  if (channelsGCuts.find(channel) != channelsGCuts.end()) {
238  if (!channelsGCuts.at(channel)->IsInside(time, edep)) {
239  digisToRemove.push_back(digi);
240  continue;
241  }
242  }
243  const auto& channelsMinAmp = stationCuts.fChannelMinAmp;
244  if (channelsMinAmp.find(channel) != channelsMinAmp.end()) {
245  if (channelsMinAmp.at(channel) > edep) {
246  digisToRemove.push_back(digi);
247  continue;
248  }
249  }
250  const auto& channelsMaxAmp = stationCuts.fChannelMaxAmp;
251  if (channelsMaxAmp.find(channel) != channelsMaxAmp.end()) {
252  if (channelsMaxAmp.at(channel) < edep) {
253  digisToRemove.push_back(digi);
254  continue;
255  }
256  }
257  const auto& channelsMinTime = stationCuts.fChannelMinTime;
258  if (channelsMinTime.find(channel) != channelsMinTime.end()) {
259  if (channelsMinTime.at(channel) > time) {
260  digisToRemove.push_back(digi);
261  continue;
262  }
263  }
264  const auto& channelsMaxTime = stationCuts.fChannelMaxTime;
265  if (channelsMaxTime.find(channel) != channelsMaxTime.end()) {
266  if (channelsMaxTime.at(channel) < time) {
267  digisToRemove.push_back(digi);
268  continue;
269  }
270  }
271  }
272  for (auto* digi : digisToRemove) {
273  digis->Remove(digi);
274  }
275  digis->Compress();
276  }
277 }
278 //--------------------------------------------------------------------------------------------------
279 void ERDigiCleaner::ApplyStationMultiplicities() {
280  for (const auto detStationMultiplicity : fStationsMultiplicities) {
281  const auto detectorAndStation = detStationMultiplicity.first;
282  const auto detectorName = detectorAndStation.first;
283  const auto stationName = detectorAndStation.second;
284  const auto multiplicityRange = detStationMultiplicity.second;
285  auto branchNameAndDigis = GetBranchNameAndDigis(detectorName, stationName);
286  auto* digi = branchNameAndDigis.second;
287  if (!digi) {
288  LOG(FATAL) << "Digi branch for station " << detectorName
289  << " of detector " << stationName << " not found." << FairLogger::endl;
290  }
291  if (digi->GetEntriesFast() < multiplicityRange.first || digi->GetEntriesFast() > multiplicityRange.second) {
292  digi->Clear();
293  }
294  }
295 }
296 //--------------------------------------------------------------------------------------------------
297 std::pair<std::string, TClonesArray*> ERDigiCleaner::GetBranchNameAndDigis(
298  const TString& detectorName, const TString& stationName) {
299  for (const auto& digiBranchNameAndCollection : fInputDigis) {
300  const auto branchName = digiBranchNameAndCollection.first;
301  if (TString(branchName).Contains(detectorName) && TString(branchName).Contains(stationName))
302  return digiBranchNameAndCollection;
303  }
304  return std::make_pair(std::string(), nullptr);
305 }
306 //--------------------------------------------------------------------------------------------------
308  for (const auto& digiBranchNameAndCollection : fInputDigis) {
309  digiBranchNameAndCollection.second->Clear();
310  }
311 }
312 //--------------------------------------------------------------------------------------------------
313 ERDigiCleaner::RecalibrationTask::RecalibrationTask(const TString& detectorName, const TString& stationName,
314  TMatrixD* previousTimeCalibration, TMatrixD* timeCalibration,
315  TMatrixD* previousAmpCalibration, TMatrixD* ampCalibration,
316  TMatrixD* previousTACCalibration /*= nullptr*/, TMatrixD* TACCalibration/*= nullptr*/,
317  ChannelMapping* raw2SimChannelsMapping/* = nullptr*/)
318 : fDetectorName(detectorName), fStationName(stationName),
319 fPreviousAmpCalibration(previousAmpCalibration),
320 fAmpCalibration(ampCalibration),
321 fPreviousTimeCalibration(previousTimeCalibration),
322 fTimeCalibration(timeCalibration),
323 fPreviousTACCalibration(previousTACCalibration),
324 fTACCalibration(TACCalibration) {
325  if (raw2SimChannelsMapping) {
326  fSim2RawChannelMapping = new ChannelMapping();
327  for (const auto raw2sim : *raw2SimChannelsMapping) {
328  (*fSim2RawChannelMapping)[raw2sim.second] = raw2sim.first;
329  }
330  }
331 }
332 //--------------------------------------------------------------------------------------------------
333 ERDigiCleaner::StationCuts::StationCuts(const TString& detectorName, const TString& stationName,
334  const std::map<ERChannel, TCutG*>& channelGCuts,
335  const std::map<ERChannel, Double_t>& channelMinAmp,
336  const std::map<ERChannel, Double_t>& channelMaxAmp,
337  const std::map<ERChannel, Double_t>& channelMinTime,
338  const std::map<ERChannel, Double_t>& channelMaxTime,
339  const ChannelMapping* raw2SimChannelsMapping/* = nullptr*/)
340  : fDetectorName(detectorName), fStationName(stationName),
341  fChannelGCuts(channelGCuts), fChannelMinAmp(channelMinAmp),
342  fChannelMaxAmp(channelMaxAmp), fChannelMinTime(channelMinTime),
343  fChannelMaxTime(channelMaxTime)
344 {
345  if (raw2SimChannelsMapping) {
346  fSim2RawChannelMapping = new ChannelMapping();
347  for (const auto raw2sim : *raw2SimChannelsMapping) {
348  (*fSim2RawChannelMapping)[raw2sim.second] = raw2sim.first;
349  }
350  }
351 }
352 //--------------------------------------------------------------------------------------------------
Definition: ERDigi.h:15
virtual void Exec(Option_t *opt)
virtual void Reset()
virtual InitStatus Init()
FairRun * fRun
Pointer to run manager object.
Definition: ERTask.h:63
std::vector< TString > fAvailibleRunManagers
Run managers that are availible for this task.
Definition: ERTask.h:64
Base abstract class for all tasks in er.
Definition: ERTask.h:27