Diana Software
MCoincidenceTiming.cc
Go to the documentation of this file.
1 #include "MCoincidenceTiming.hh"
2 #include <algorithm>
3 #include "QDbDetector.hh"
4 #include "QError.hh"
5 #include "QEvent.hh"
6 #include "QFiltersData.hh"
7 #include "QMainPulse.hh"
8 #include "QOBData.hh"
9 #include "QRawEvent.hh"
10 #include "QRunData.hh"
11 
12 using std::vector;
13 
15 
17 {
18  const QRawEvent& raw = ev->GetRawEvent();
19  const QMainPulse& pulse = raw.GetPulse();
20  fChannel = pulse.GetChannelId();
21  fEventNumber = raw.GetEventNumber();
22  fHeaterChannel = -1;
23  fPassed = ev->GetFilters().GetPassed();
24  fPulseTimeOffset = ev->GetOB().GetStartTimeOffset();
25  fRelative = -1;
26  fTimeFromStartRunNs = raw.GetTime().GetFromStartRunNs();
27 }
28 
29 void MCoincidenceTiming::EventInfo::ApplyOffset(double samplingPeriod)
30 {
31  long long offsetNs = (long long) (fPulseTimeOffset * samplingPeriod * 1e9);
32  fTimeFromStartRunNs += offsetNs;
33 }
34 
36  : QModule("CoincidenceTiming",s)
37 {
38 }
39 
41 {
42 }
43 
45 {
46  if (GetIteration() == 1) {
47  fIsRunDataLoaded = false;
48 
49  fUsePulseStartTimeOffset = GetBool("UsePulseStartTimeOffset", false);
50  fTimeWindow = GetDouble("TimeWindow", 0.050);
51  fDetectorSetupFile = GetString("DetectorSetupFile","DB");
52  fFilteredEventsType = GetString("FilteredEventsType", "", false);
53  }
54 }
55 
57 {
58  const QRawEvent& raw = ev->GetRawEvent();
59  int thisRun = raw.GetRun();
60 
61  EventInfo thisEvent(ev);
62 
63  // Fill fRelatedMap with heater channels and relatives
64  if (fRelatedMap.count(thisEvent.fChannel) == 0) {
65  try {
66  fRelatedMap[thisEvent.fChannel].fHeaterChan
67  = QDbDetector::GetPulserId(thisRun, thisEvent.fChannel,
69  }
70  catch (const QError& err) {
71  Info("%s", err.GetDescription().c_str());
72  fRelatedMap[thisEvent.fChannel].fHeaterChan = -1;
73  }
74 
75  vector<int> relatives;
76  try {
77  relatives = QDbDetector::GetRelativeChannels(thisRun,
78  thisEvent.fChannel,
80  }
81  catch (const QError& err) {
82  Info("%s", err.GetDescription().c_str());
83  }
84 
85  if (relatives.size() > 0) {
86  fRelatedMap[thisEvent.fChannel].fRelative = relatives[0];
87  }
88  else {
89  fRelatedMap[thisEvent.fChannel].fRelative = -1;
90  }
91  }
92 
93  thisEvent.fHeaterChannel = fRelatedMap[thisEvent.fChannel].fHeaterChan;
94  thisEvent.fRelative = fRelatedMap[thisEvent.fChannel].fRelative;
95 
97  if (!fIsRunDataLoaded) {
98  if ( const QRunData *runData = dynamic_cast<const QRunData*>(
99  SeqAuxData().GetQObject("RunData")) ) {
100  double samplingFrequency = runData->GetSamplingFrequency();
101  fSamplingPeriod = 0;
102  if (samplingFrequency != 0) {
103  fSamplingPeriod = 1.0 / samplingFrequency;
104  }
105  }
106  fIsRunDataLoaded = true;
107  }
108  thisEvent.ApplyOffset(fSamplingPeriod);
109  }
110 
111  if (GetIteration() == 1) {
112  fEventList.push_back(thisEvent);
113  }
114  else if (GetIteration() == 2) {
115  double timeSinceEvent_SameChannel = -999;
116  double timeSinceEvent_DifferentChannel = -999;
117  double timeUntilEvent_SameChannel = -999;
118  double timeUntilEvent_DifferentChannel = -999;
119 
120  int numberOfCoincidentEvents = 0;
121  int numberOfCoincidentEvents_SameHeaterGroup = 0;
122 
123  int thisIndex = fEventListIndex[thisEvent.fEventNumber];
124  int index = thisIndex;
125  double timeDifference = 0;
126 
127  bool previousEventFound_SameChannel = false;
128  bool previousEventFound_DifferentChannel = false;
129  bool nextEventFound_SameChannel = false;
130  bool nextEventFound_DifferentChannel = false;
131  bool allFound = false;
132 
133  // Look backward
134  index = thisIndex - 1;
135  while (index >= 0 && (!allFound || timeDifference < fTimeWindow)) {
136  const EventInfo& earlierEvent = fEventList[index];
137  if (earlierEvent.fPassed) {
138  timeDifference = (thisEvent.fTimeFromStartRunNs
139  - earlierEvent.fTimeFromStartRunNs) / 1e9;
140  if (!previousEventFound_SameChannel
141  && earlierEvent.fChannel == thisEvent.fChannel) {
142  timeSinceEvent_SameChannel = timeDifference;
143  previousEventFound_SameChannel = true;
144  }
145  if (!previousEventFound_DifferentChannel
146  && earlierEvent.fChannel != thisEvent.fChannel
147  && earlierEvent.fChannel != thisEvent.fRelative) {
148  timeSinceEvent_DifferentChannel = timeDifference;
149  previousEventFound_DifferentChannel = true;
150  }
151  if (timeDifference < fTimeWindow
152  && earlierEvent.fChannel != thisEvent.fChannel
153  && earlierEvent.fChannel != thisEvent.fRelative) {
154  ++numberOfCoincidentEvents;
155  if (earlierEvent.fHeaterChannel
156  == thisEvent.fHeaterChannel) {
157  ++numberOfCoincidentEvents_SameHeaterGroup;
158  }
159  }
160  }
161  --index;
162  allFound = previousEventFound_SameChannel
163  && previousEventFound_DifferentChannel;
164  }
165 
166  // Look forward
167  index = thisIndex + 1;
168  timeDifference = 0;
169  allFound = false;
170  while (index < (int) fEventList.size()
171  && (!allFound || timeDifference < fTimeWindow)) {
172  const EventInfo& laterEvent = fEventList[index];
173  if (laterEvent.fPassed) {
174  timeDifference = (laterEvent.fTimeFromStartRunNs
175  - thisEvent.fTimeFromStartRunNs) / 1e9;
176  if (!nextEventFound_SameChannel
177  && laterEvent.fChannel == thisEvent.fChannel) {
178  timeUntilEvent_SameChannel = timeDifference;
179  nextEventFound_SameChannel = true;
180  }
181  if (!nextEventFound_DifferentChannel
182  && laterEvent.fChannel != thisEvent.fChannel
183  && laterEvent.fChannel != thisEvent.fRelative) {
184  timeUntilEvent_DifferentChannel = timeDifference;
185  nextEventFound_DifferentChannel = true;
186  }
187  if (timeDifference < fTimeWindow
188  && laterEvent.fChannel != thisEvent.fChannel
189  && laterEvent.fChannel != thisEvent.fRelative) {
190  ++numberOfCoincidentEvents;
191  if (laterEvent.fHeaterChannel
192  == thisEvent.fHeaterChannel) {
193  ++numberOfCoincidentEvents_SameHeaterGroup;
194  }
195  }
196  }
197  ++index;
198  allFound = nextEventFound_SameChannel
199  && nextEventFound_DifferentChannel;
200  }
201  ev->AuxData().SetDouble(
202  "TimeSince" + fFilteredEventsType + "Event_SameChannel",
203  timeSinceEvent_SameChannel, "save"
204  );
205  ev->AuxData().SetDouble(
206  "TimeSince" + fFilteredEventsType + "Event_DifferentChannel",
207  timeSinceEvent_DifferentChannel, "save"
208  );
209  ev->AuxData().SetDouble(
210  "TimeUntil" + fFilteredEventsType + "Event_SameChannel",
211  timeUntilEvent_SameChannel, "save"
212  );
213  ev->AuxData().SetDouble(
214  "TimeUntil" + fFilteredEventsType + "Event_DifferentChannel",
215  timeUntilEvent_DifferentChannel, "save"
216  );
217  ev->AuxData().SetInt(
218  "NumberOfCoincident" + fFilteredEventsType + "Events",
219  numberOfCoincidentEvents, "save"
220  );
221  ev->AuxData().SetInt(
222  "NumberOfCoincident" + fFilteredEventsType
223  + "Events_SameHeaterGroup",
224  numberOfCoincidentEvents_SameHeaterGroup, "save"
225  );
226  }
227 
228  return ev;
229 }
230 
232 {
233  if (GetIteration() == 1) {
234  // Sort the event list by time
235  sort(fEventList.begin(), fEventList.end());
236  // Build the index by event number
237  for (unsigned int index = 0; index != fEventList.size(); ++index) {
238  int eventNumber = fEventList[index].fEventNumber;
239  fEventListIndex[eventNumber] = index;
240  }
241  SetRunAgain(true);
242  }
243 }
err
Definition: CheckOF.C:114
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
void ApplyOffset(double samplingPeriod)
Module to identify coincident events.
MCoincidenceTiming(QSequence *s)
constructor
std::string fDetectorSetupFile
detector setup file for DB alternative
void Init()
Init method.
std::string fFilteredEventsType
Description of filtered events.
std::vector< EventInfo > fEventList
List of events passing the filter(s)
double fSamplingPeriod
Sampling period from QRunData.
double fTimeWindow
Time interval in which to search for coincident events.
void Done()
Done method.
std::map< int, unsigned int > fEventListIndex
Index for fEventList based on event number.
virtual ~MCoincidenceTiming()
destructor
std::map< int, ChannelInfo > fRelatedMap
map of channels with their heater channel and relative channel on the same crystal
bool fIsRunDataLoaded
Whether or not QRunData has been loaded.
QEvent * Do(QEvent *ev)
Do method.
bool fUsePulseStartTimeOffset
Whether or not to adjust time of event based on pulse slewing.
const std::string & GetString(const std::string &parname, const std::string &defVal, bool warnCfg=true) const
Get a string parameter from config file ( see GetDouble() )
Definition: QBaseModule.cc:297
unsigned int GetIteration() const
Get Current sequence iteration.
Definition: QBaseModule.hh:122
void Info(const char *descr,...) const
Send an info message (information) with printf syntax.
Definition: QBaseModule.hh:218
double GetDouble(const std::string &parname, double defVal, bool warnCfg=true) const
Get a double parameter from config file.
Definition: QBaseModule.cc:184
bool GetBool(const std::string &parname, bool defVal, bool warnCfg=true) const
Get a bool parameter from config file ( see GetDouble() )
Definition: QBaseModule.cc:256
void SetRunAgain(bool b)
Set that the sequence will be reiterated.
Definition: QBaseModule.hh:120
error class with error type and description
Definition: QError.hh:115
diana event
Definition: QEvent.hh:46
Base class for diana modules.
Definition: QModule.hh:54
Basic run based info.
Definition: QRunData.hh:20
Diana Reconstruction program.
Definition: QSequence.hh:40