17 using namespace Diana;
25 fCoincidenceWindow = GetDouble(
"CoincidenceWindow", 0.100);
26 fCoincidenceRadius = GetDouble(
"CoincidenceRadius", 1200.);
28 fEnergyLabel = GetString(
"EnergyLabel",
"ApplyCalibration@Energy");
29 vector<string> defaults;
30 fPSALabels = GetVectorString(
"PSALabels",defaults);
31 std::string timeVariableStr = GetString(
"TimeVariable",
"Raw");
32 if(timeVariableStr ==
"Raw") {
33 fTimeVariable = TV_RAW;
34 }
else if(timeVariableStr ==
"OF") {
35 fTimeVariable = TV_OF;
37 Warn(
"Unrecognized time variable, setting it to Raw");
38 fTimeVariable = TV_RAW;
42 GlobalHandle<QInt> dHandle(
"Dataset");
43 GlobalData().Get(
"",&dHandle,
"");
44 fDataset = dHandle.Get();
46 fSyncTime = GetBool(
"SyncTime",
false);
48 fSyncType = GetString(
"SyncType",
"coincidence");
49 if (fSyncType ==
"coincidence")
51 fSyncSource = GetString(
"SyncSource",
"jitter.txt");
52 fSyncTowerSource = GetString(
"SyncTowerSource",
"jitter_tower.txt");
54 else if (fSyncType ==
"delay")
56 fSyncTowerSource = GetString(
"SyncTowerSource",
"jitter_tower.txt");
59 Warn(
"Unrecognized SyncType variable, setting it to default (coincidence)");
60 fSyncType =
"coincidence";
63 fOkInvalidTotalEnergy = GetBool(
"OkInvalidTotalEnergy",
false,
false);
67 fUseRunningWindow = GetBool(
"UseRunningWindow",
true);
68 fStorePosition = GetBool(
"StorePosition",
true,
false);
72 ev.Require<
QHeader>(
"DAQ",
"Header");
73 if(!fPSALabels.empty()) {
74 for(
size_t p = 0; p < fPSALabels.size(); p++) {
75 ev.RequireByLabel<
QDouble>(fPSALabels[p]);
78 ev.RequireByLabel<
QDouble>(fEnergyLabel);
80 fOFLabel = GetString(
"OFLabel",
"COF");
81 if(fTimeVariable == TV_OF) ev.Require<
QDouble>(fOFLabel,
"Jitter");
88 const int run = hdr.
GetRun();
94 GlobalData().Get(
"DAQ",&
rHandle,
"");
100 bool validTotalEnergy =
true;
102 GetEventEnergy(ev,tot_ene,validTotalEnergy);
108 double LargestDeltaT = 0;
110 const double time = GetTime(ev);
114 std::map<double,int> indices;
115 for(
size_t i = 0; i < n_neighbours.
Size(); i++) {
116 double o_time = GetTime(n_neighbours[i]);
117 if(indices.find(o_time) != indices.end()) o_time+=(i+1)*1.e-09;
122 std::map<double,int>::const_iterator index = indices.begin();
123 while(index != indices.end()) {
126 radius = GetDistanceMm(ev, &n_neighbours[index->second]);
127 if( radius <= fCoincidenceRadius )neighbours.
Push(&n_neighbours[index->second]);
132 int leftIndex = 1, rightIndex = -1;
133 double l_time = time, r_time = time;
134 for(
int i =
int(neighbours.
Size())-1; i >= 0; i--) {
135 const double o_time = GetTime(neighbours[i]);
136 const double deltaT = o_time - l_time;
138 if(fabs(deltaT) < fCoincidenceWindow) {
139 if(fUseRunningWindow)
140 l_time = GetTime(neighbours[i]);
143 }
else if(fabs(deltaT) < fCoincidenceWindow) {
147 for(
size_t i = leftIndex; i < neighbours.
Size(); i++) {
148 const double o_time = GetTime(neighbours[i]);
149 const double deltaT = o_time - r_time;
151 if(fabs(deltaT) < fCoincidenceWindow) {
152 if(fUseRunningWindow)
153 r_time = GetTime(neighbours[i]);
156 }
else if(fabs(deltaT) < fCoincidenceWindow) {
174 double maxradius = 0.;
175 for(
int i = leftIndex; i <= rightIndex; i++) {
176 const QEvent& other = neighbours[i];
178 const double o_time = GetTime(neighbours[i]);
180 const double deltaT = o_time - time;
184 GetEventEnergy(other,o_energy,validEnergy);
185 validTotalEnergy&=validEnergy;
207 double o_radius = GetDistanceMm(ev,&other);
208 if(o_radius > maxradius)maxradius = o_radius;
210 if(fabs(deltaT) > fabs(LargestDeltaT))
211 LargestDeltaT = deltaT;
212 if(fabs(deltaT) < fabs(SmallestDeltaT))
213 SmallestDeltaT = deltaT;
218 for(
size_t p = 0; p < fPSALabels.size(); p++) {
250 double time = double(header.
GetTime().GetFromStartRunNs())/1e09;
251 double preTriggerTime = 0;
253 switch(fTimeVariable) {
261 time += ofjitter/1000;
268 if(fSyncTime && fSyncType ==
"coincidence") {
269 const int channel = pi.GetChannelId();
273 GlobalData().Get(
"JitterByCoincidence",&jHandle,fSyncSource);
275 if(!jHandle.IsValid()) {
276 if(fBlackList.count(
channel))
return time;
278 Error(
"Channel %d, has no jitter. Cannot be synced: %s",
channel,jHandle.GetError().GetDescription().c_str());
282 const QJitter& jitters = jHandle.Get();
286 GlobalData().Get(
"JitterByDelay",&jdhandle,fSyncTowerSource);
288 if(!jdhandle.IsValid()) {
289 Error(
"Reference channel %d, has no jitter. The relative tower cannot be synced: %s",jitters.
fRefChannel,jdhandle.GetError().GetDescription().c_str());
293 const QJitter& jittersTower = jdhandle.Get();
294 time = time + jitters.
fJitter - jittersTower.
fJitter/1000. + preTriggerTime;
299 if(fSyncTime && fSyncType ==
"delay") {
300 const int channel = pi.GetChannelId();
304 GlobalData().Get(
"JitterByDelay",&jHandle,fSyncTowerSource);
306 if(!jHandle.IsValid()) {
307 if(fBlackList.count(
channel))
return time;
309 Error(
"Channel %d, has no jitter. Cannot be synced: %s",
channel,jHandle.GetError().GetDescription().c_str());
313 const QJitter& jitters = jHandle.Get();
314 time = time - jitters.
fJitter/1000. + preTriggerTime;
323 Diana::QEventLabel branchToSelect = fEnergyLabel;
324 Diana::ReadHandle<Diana::QDouble> evHandle(branchToSelect.GetName().c_str());
326 ev.Get(branchToSelect.GetOwner().c_str(),evHandle);
332 if(fOkInvalidTotalEnergy) {
333 if(evHandle.IsValid()) {
334 energy = evHandle.Get();
342 energy = evHandle.Get();
347 const int ch1 = ev.Get<
QPulseInfo>(
"DAQ",
"PulseInfo").GetChannelId();
348 const int ch2 = coincident->Get<
QPulseInfo>(
"DAQ",
"PulseInfo").GetChannelId();
356 double x1,y1,z1,x2,y2,z2;
357 x1 = fChannelPositionX[ch1];
358 y1 = fChannelPositionY[ch1];
359 z1 = fChannelPositionZ[ch1];
360 x2 = fChannelPositionX[ch2];
361 y2 = fChannelPositionY[ch2];
362 z2 = fChannelPositionZ[ch2];
363 return sqrt(
pow(x1-x2,2) +
pow(y1-y2,2) +
pow(z1-z2,2) );
QRunDataHandle rHandle(753)
Diana::QComplex pow(const Diana::QComplex &z, double a)
Raise a complex number to a real power.
#define REGISTER_MODULE(clazz)
Version of MCoincidenceMultiplicity that uses neighbours.
void Do(Diana::QEvent &ev, const Diana::QEventList &neighbours)
Do method.
void GetEventEnergy(const Diana::QEvent &ev, double &energy, bool &valid) const
Get the energy of the event. Throws if event is invalid and fOkInvalidTotalEnergy is false.
double GetDistanceMm(const Diana::QEvent &ev, const Diana::QEvent *coincident)
Get the distance in mm between the centers of the main and the coincident crystals.
double GetTime(const Diana::QEvent &ev)
Get time of the event.
base types wrapped into a QObject. Currently implemented types are QInt QDouble and QFloat....
int fFarthestCoincidentIndex
int fNearestCoincidentIndex
std::vector< QCoincidentChannel > fCoincidentChannels
data of coincident channel
std::vector< double > fPSAVariables
list of references to const QEvent (s)
void Push(const QEvent *obj)
add a QEvent
size_t Size() const
number of QEvent (s)
const Q & GetByLabel(const QEventLabel &label) const
Get a QObject in read mode by label.
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
unsigned int GetReadNumber() const
return the event number as read by the current reader.
global handle for jitter by coincidence
Raw event: bolometer channel, trigger positions and types.
const int & GetChannelId() const
Get ChannelId.
global handle for QRunData
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...