9 #include "QDetChannelCollectionHandle.hh"
21 using namespace Diana;
26 if(FILE* file = fopen(name.c_str(),
"r")) {
35 fEventNumber(eventNumber), fTag(tag), fChannel(
channel), fTime(time), fEnergy(energy) {
39 return a->fTime <
b->fTime;
49 Panic(
"Negative CoincidenceRadius! No multiplet would be created!");
55 fEnergyLabel = GetString(
"EnergyLabel",
"ApplyCalibration@Energy");
56 vector<string> defaults;
57 fPSALabels = GetVectorString(
"PSALabels", defaults);
59 std::string timeVariableStr = GetString(
"TimeVariable",
"Raw");
60 if( timeVariableStr ==
"Raw" ) {
62 }
else if( timeVariableStr ==
"OF" ) {
66 Warn(
"Unrecognized time variable, setting it to Raw");
73 fSyncType = GetString(
"SyncType",
"coincidence");
75 fSyncSource = GetString(
"SyncSource",
"jitter.txt");
80 Warn(
"Unrecognized SyncType variable, setting it to default (coincidence)");
82 fSyncSource = GetString(
"SyncSource",
"jitter.txt");
98 for(
size_t p = 0; p <
fPSALabels.size(); p++ ) {
105 fOFLabel = GetString(
"OFLabel",
"COF");
121 while(getline(fCPFile, line)) {
130 Panic(
"UseChannelPosition = true but ASCII file %s does not exist. Modify ChannelPositionFile in cfg or set UseChannelPosition to false.",
fChannelPositionFile.c_str() );
133 Warn(
"UseChannelPosition = false. Will skip all space-based selections.");
142 const int run = hdr.
GetRun();
143 const int chan = pi.GetChannelId();
148 GlobalHandle<QInt> dHandle(
"Dataset");
149 GlobalData().Get(
"", &dHandle,
"");
156 GlobalData().Get(
"DAQ", &
rHandle,
"");
162 QDetChannelCollectionHandle dccHandle;
163 dccHandle.SetRun(run);
164 GlobalData().Get(
"",&dccHandle,
"");
166 int tower = dccHandle.Get().Get(chan).fTd.fTdTower;
167 int floor = dccHandle.Get().Get(chan).fTd.fTdFloor;
168 int position = dccHandle.Get().Get(chan).fTd.fTdPos;
175 if( GetIteration() == 1 ) {
178 ULong64_t evNumber = pi.GetMasterSample().GetEventNumber();
179 ULong64_t tag = evNumber*100 + tower;
189 double LargestDeltaT = 0;
191 double tot_energy = energy;
197 ULong64_t thisTag = pi.GetMasterSample().GetEventNumber()*100 + tower;
217 std::set<int> tnSelected;
218 std::set<int>::iterator tnSelIT;
222 for(
int s = m-1; s>= 0; s-- )
225 double oTime = tn->
fTime;
226 double deltaT = oTime - eTime;
230 tnSelected.insert( s );
239 double oTime = tn->
fTime;
240 double deltaT = oTime - eTime;
244 tnSelected.insert( s );
253 std::set<int> tnSpaceBasedAccepted;
254 for( tnSelIT = tnSelected.begin(); tnSelIT != tnSelected.end(); ++tnSelIT )
260 tnSpaceBasedAccepted.insert( *tnSelIT );
262 int EmergencyStop = -988;
265 if( EmergencyStop >= 0 )
266 Panic(
"Infinite loop detected! Due to bug in SpaceBased with RunningRadius");
267 std::set<int>::iterator tnSBA_IT;
269 AddedNewEvent =
false;
270 for( tnSBA_IT = tnSpaceBasedAccepted.begin(); tnSBA_IT != tnSpaceBasedAccepted.end(); ++tnSBA_IT )
274 for( tnSelIT = tnSelected.begin(); tnSelIT != tnSelected.end(); ++tnSelIT )
278 if( oDistance <
fCoincidenceRadius && tnSpaceBasedAccepted.end() == tnSpaceBasedAccepted.find( *tnSelIT ) )
280 tnSpaceBasedAccepted.insert( *tnSelIT );
281 AddedNewEvent =
true;
290 }
while( AddedNewEvent );
293 tnSelected = tnSpaceBasedAccepted;
295 double MaximumDistance = 0.;
296 std::set<int>::iterator tnSelIT_i;
297 std::set<int>::iterator tnSelIT_j;
298 for( tnSelIT_i = tnSelected.begin(); tnSelIT_i != tnSelected.end(); ++tnSelIT_i)
302 if( iDistance > MaximumDistance )
303 MaximumDistance = iDistance;
304 for( tnSelIT_j = tnSelected.begin(); tnSelIT_j != tnSelected.end(); ++tnSelIT_j)
307 if( *tnSelIT_i >= *tnSelIT_j )
311 if( ijDistance > MaximumDistance )
312 MaximumDistance = ijDistance;
318 if( tnSelected.size() > 0 && MaximumDistance < 1e-3){
319 Debug(
"Detected event with multiplicity > 1 and Radius < 0.001 mm. Tag %d. This is a normal behaviour.",thisTag);
333 for( tnSelIT = tnSelected.begin(); tnSelIT != tnSelected.end(); ++tnSelIT )
336 double oTime = tn->
fTime;
339 double deltaT = oTime - time;
342 if( fabs(deltaT) > fabs(LargestDeltaT) )
343 LargestDeltaT = deltaT;
344 if( fabs(deltaT) < fabs(SmallestDeltaT) )
345 SmallestDeltaT = deltaT;
346 tot_energy += oEnergy;
371 if( GetIteration() == 1 ) {
395 double time = double(header.
GetTime().GetFromStartRunNs())/1e09;
404 const QOFData&
of = ev.
Get<QOFData>(
fOFLabel.c_str(),
"OFData");
406 time +=
of.GetDelay()/1000 - double(pi.GetMasterSample().GetSampleIndex())/samplingFrequency;
414 const int channel = pi.GetChannelId();
418 GlobalData().Get(
"JitterByCoincidence",&jHandle,
fSyncSource);
420 if(!jHandle.IsValid()) {
423 Error(
"Channel %d, has no jitter. Cannot be synced: %s",
channel,jHandle.GetError().GetDescription().c_str());
427 const QJitter& jitters = jHandle.Get();
433 if(!jdhandle.IsValid()) {
434 Error(
"Reference channel %d, has no jitter. The relative tower cannot be synced: %s",jitters.
fRefChannel,jdhandle.GetError().GetDescription().c_str());
438 const QJitter& jittersTower = jdhandle.Get();
448 const int channel = pi.GetChannelId();
454 if(!jHandle.IsValid()) {
457 Error(
"Channel %d, has no jitter. Cannot be synced: %s",
channel,jHandle.GetError().GetDescription().c_str());
461 const QJitter& jitters = jHandle.Get();
462 time = time - jitters.
fJitter/1000.;
470 double x1,y1,z1,x2,y2,z2;
477 return sqrt(
pow(x1-x2,2) +
pow(y1-y2,2) +
pow(z1-z2,2) );
QOptimumFilter of(ap, an,-1, false)
QRunDataHandle rHandle(753)
chanRunData fSamplingFrequency
REGISTER_MODULE(MFastCoincidence)
bool FileExists(const std::string &name)
bool timeSort(TimeNeighbour *a, TimeNeighbour *b)
Diana::QComplex pow(const Diana::QComplex &z, double a)
Raise a complex number to a real power.
TimeVariable fTimeVariable
std::string fChannelPositionFile
std::map< int, double > fChannelPositionZ
void Init(Diana::QEvent &ev)
double GetTime(const Diana::QEvent &ev)
std::map< int, int > ChannelTowerMap
std::map< int, double > fChannelPositionY
double fCoincidenceWindow
double GetDistanceMmChannel(const int ch1, const int ch2)
void Do(Diana::QEvent &ev)
std::map< int, double > fChannelPositionX
std::map< int, ChannelInfo > fSyncTimeDifference
std::vector< TimeNeighbour * > timeNeighbours
std::vector< std::string > fPSALabels
std::set< int > fBlackList
double fCoincidenceRadius
std::map< int, int > ChannelPositionMap
std::map< int, int > ChannelFloorMap
std::string fSyncTowerSource
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
const Q & GetByLabel(const QEventLabel &label) const
Get a QObject in read mode by label.
void RequireByLabel(const QEventLabel &label) const
notify the QEvent that we need a QObject, if not found an exception is thrown
void Require(const std::string &owner, const std::string &name) const
notify the QEvent that we need a QObject, if not found an exception is thrown
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
void Add(WriteHandle< Q > &handle)
Add a QObject to the event.
global handle for jitter by coincidence
Raw event: bolometer channel, trigger positions and types.
global handle for QRunData
const QChannelRunData & GetChannelRunData(const int channel) const
get channel based run data quantities
TimeNeighbour(ULong64_t, ULong64_t, int, double, double)
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...