#ifndef _sdet_StationTriggerAlgorithm_h_ #define _sdet_StationTriggerAlgorithm_h_ #include #include #include #include namespace sdet { /** \class StationTriggerAlgorithm StationTriggerAlgorithm.h "sdet/StationTriggerAlgorithm.h" \brief Local station hardware (PLD) and software (T2) trigger algorithm \author Darko Veberic \date 05 Oct 2008 \version $Id$ \ingroup det_interface */ class StationTriggerAlgorithm { public: StationTriggerAlgorithm(const utl::Accumulator::Threshold& t1th, const utl::Accumulator::TimeOverThreshold& tot, const utl::Accumulator::TimeOverThresholdDeconvoluted& totd, const utl::Accumulator::MultiplicityOfPositiveSteps& mops, const utl::Accumulator::Threshold& t2th, const int latchBin, const int traceLength) : fT1ThresholdTrigger(t1th), fTOTTrigger(tot), fTOTdTrigger(totd), fMOPSTrigger(mops), fT2ThresholdTrigger(t2th), fLatchBin(latchBin), fTraceLength(traceLength) { } /** Calculate all triggers. The returned start/stop bounds may reach out of the function parameters start/stop. The reason is TimeDistributions are defined for all integers and limits thus do not make sense. This may not be true for Trace. Check bounds carefully... */ template std::vector Run(const int start, const int stop, const int nTraces, const Trace* const traces) { Clear(); std::vector info; int i = start; do { int pld = sevt::StationTriggerData::ePLDNone; utl::Accumulator::Max isT2Th(false); // find latch triggers first for ( ; i < stop; ++i) { double values[nTraces]; for (int j = 0; j < nTraces; ++j) values[j] = (*traces[j])[i]; isT2Th(fT2ThresholdTrigger(values)); if (fTOTTrigger(values)) { pld |= sevt::StationTriggerData::ePLDLatchTOTA; break; } if (fTOTdTrigger(values)) { pld |= sevt::StationTriggerData::ePLDLatchTOTB; break; } if (fMOPSTrigger(values)){ pld |= sevt::StationTriggerData::ePLDLatchTOTC; break; } if (fT1ThresholdTrigger(values)) { pld |= sevt::StationTriggerData::ePLDLatchThreshold; break; } } // nothing found if (pld == sevt::StationTriggerData::ePLDNone) return info; const int trigLatch = i; const int trigStart = trigLatch - fLatchBin + 1; const int trigStop = trigStart + fTraceLength; const int iMax = std::min(trigStop, stop); // any other triggers in the rest of the triggered trace? for (++i ; i < iMax; ++i) { double values[nTraces]; for (int j = 0; j < nTraces; ++j) values[j] = (*traces[j])[i]; if (fT1ThresholdTrigger(values)) pld |= sevt::StationTriggerData::ePLDThreshold; if (fTOTTrigger(values)) pld |= sevt::StationTriggerData::ePLDTOTA; if (fTOTdTrigger(values)) pld |= sevt::StationTriggerData::ePLDTOTB; if (fMOPSTrigger(values)) pld |= sevt::StationTriggerData::ePLDTOTC; isT2Th(fT2ThresholdTrigger(values)); } info.push_back(StationTriggerInfo(pld, isT2Th.GetMax(), trigStart, trigLatch, trigStop)); } while (i < stop); return info; } template std::vector Run(const int start, const int stop, const std::vector& traces) { return Run(start, stop, traces.size(), &traces[0]); } // RunRecalculation used to recalculate triggers using VEMtraces and FADCtraces (for MOPS trigger) template std::vector RunRecalculation(const int start, const int stop, const int nTraces, const Trace* const traces, const Trace2* const tracesFADC) { Clear(); std::vector info; int i = start; do { int pld = sevt::StationTriggerData::ePLDNone; utl::Accumulator::Max isT2Th(false); // find latch triggers first for ( ; i < stop; ++i) { double values[nTraces]; double valuesFADC[nTraces]; for (int j = 0; j < nTraces; ++j){ values[j] = (*traces[j])[i]; valuesFADC[j] = (*tracesFADC[j])[i]; } isT2Th(fT2ThresholdTrigger(values)); if (fTOTTrigger(values)) { pld |= sevt::StationTriggerData::ePLDLatchTOTA; break; } if (fTOTdTrigger(values)) { pld |= sevt::StationTriggerData::ePLDLatchTOTB; break; } if (fMOPSTrigger(valuesFADC)){ pld |= sevt::StationTriggerData::ePLDLatchTOTC; break; } if (fT1ThresholdTrigger(values)) { pld |= sevt::StationTriggerData::ePLDLatchThreshold; break; } } // nothing found const int trigLatch = i; const int trigStart = trigLatch - fLatchBin + 1; const int trigStop = trigStart + fTraceLength; const int iMax = std::min(trigStop, stop); if (pld == sevt::StationTriggerData::ePLDNone) { info.push_back(StationTriggerInfo(pld, isT2Th.GetMax(), trigStart, trigLatch, trigStop)); return info; } // any other triggers in the rest of the triggered trace? for (++i ; i < iMax; ++i) { double values[nTraces]; for (int j = 0; j < nTraces; ++j) values[j] = (*traces[j])[i]; if (fT1ThresholdTrigger(values)) pld |= sevt::StationTriggerData::ePLDThreshold; if (fTOTTrigger(values)) pld |= sevt::StationTriggerData::ePLDTOTA; if (fTOTdTrigger(values)) pld |= sevt::StationTriggerData::ePLDTOTB; if (fMOPSTrigger(values)) pld |= sevt::StationTriggerData::ePLDTOTC; isT2Th(fT2ThresholdTrigger(values)); } info.push_back(StationTriggerInfo(pld, isT2Th.GetMax(), trigStart, trigLatch, trigStop)); } while (i < stop); return info; } template std::vector RunRecalculation(const int start, const int stop, const std::vector& traces, const std::vector& tracesFADC) { return RunRecalculation(start, stop, traces.size(), &traces[0], &tracesFADC[0]); } void Clear() { fTOTTrigger.Clear(); fTOTdTrigger.Clear(); fMOPSTrigger.Clear(); } private: utl::Accumulator::Threshold fT1ThresholdTrigger; utl::Accumulator::TimeOverThreshold fTOTTrigger; utl::Accumulator::TimeOverThresholdDeconvoluted fTOTdTrigger; utl::Accumulator::MultiplicityOfPositiveSteps fMOPSTrigger; utl::Accumulator::Threshold fT2ThresholdTrigger; int fLatchBin; int fTraceLength; }; } #endif