#ifndef __JSUMMARYSLICE__JSUMMARYSLICE__ #define __JSUMMARYSLICE__JSUMMARYSLICE__ #include #include "km3net-dataformat/online/JDAQ.hh" #include "km3net-dataformat/online/JDAQClock.hh" #include "km3net-dataformat/online/JDAQSummaryslice.hh" #include "km3net-dataformat/online/JDAQChronometer.hh" #include "JLang/JObjectIterator.hh" #include "JDetector/JDetector.hh" #include "JDetector/JDetectorSimulator.hh" #include "JDetector/JPMTIdentifier.hh" #include "JDetector/JK40DefaultSimulatorInterface.hh" #include "JDetector/JPMTDefaultSimulatorInterface.hh" #include "JDetector/JCLBDefaultSimulatorInterface.hh" #include "JDAQ/JHighRateVeto.hh" /** * \file * * Auxiliaries for creation of summary data. * \author mdejong */ namespace KM3NETDAQ { using JDETECTOR::JDetector; using JDETECTOR::JDetectorSimulator; using JDETECTOR::JPMTDefaultSimulatorInterface; using JLANG::JObjectIterator; /** * Auxiliary class to create summary data. */ struct JSummaryslice : public JDAQSummaryslice { /** * Default constructor. */ JSummaryslice() {} /** * Constructor. * * This constructor blends multiple KM3NETDAQ::JDAQSummaryslice's from an incomplete detector to * a single KM3NETDAQ::JDAQSummaryslice for a complete detector. * * \param chronometer DAQ chronometer * \param input summary data * \param detector detector */ JSummaryslice(const JDAQChronometer& chronometer, JObjectIterator& input, const JDetector& detector) : JDAQSummaryslice(chronometer) { for (JDetector::const_iterator module = detector.begin(); module != detector.end() && input.hasNext(); ) { const JDAQSummaryslice* summary = input.next(); for (const_iterator i = summary->begin(); i != summary->end() && module != detector.end(); ++i, ++module) { push_back(*i); rbegin()->setModuleIdentifier(module->getID()); } } } /** * Constructor. * * This constructor directly creates a KM3NETDAQ::JDAQSummaryslice for a given detector simulation * without the need to create first a KM3NETDAQ::JDAQTimeslice. * * The high-rate veto of a given PMT is set to true when: * - status of the PMT is not JPMTStatus::ON every time during the time slice; or * - specified rate -corrected for the hit survival probability- exceeds KM3NETDAQ::HIGH_RATE_VETO_HZ. * * \param chronometer chronometer * \param simbad detector simulator */ JSummaryslice(const JDAQChronometer& chronometer, const JDetectorSimulator& simbad) : JDAQSummaryslice() { using namespace JPP; using namespace KM3NETDAQ; setDAQChronometer(chronometer); try { const JK40DefaultSimulatorInterface& k40Simulator = dynamic_cast(simbad.getK40Simulator()); const JPMTDefaultSimulatorInterface& pmtSimulator = dynamic_cast(simbad.getPMTSimulator()); const JCLBDefaultSimulatorInterface& clbSimulator = dynamic_cast(simbad.getCLBSimulator()); for (JDetector::const_iterator module = simbad->begin(); module != simbad->end(); ++module) { if (!module->empty()) { push_back(JDAQSummaryFrame(module->getID())); this->rbegin()->setDAQFrameStatus(clbSimulator.getDAQFrameStatus(module->getID())); for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) { const JPMTIdentifier id(module->getID(), pmt); double rate_Hz = k40Simulator.getSinglesRate(id); rate_Hz *= pmtSimulator.getPMTSignalProcessor(id).getSurvivalProbability(NPE); if (rate_Hz > HIGH_RATE_VETO_HZ) { this->rbegin()->setHighRateVeto(pmt, true); } // correct rate for UDP packet loss const int n1 = clbSimulator.getUDPNumberOfReceivedPackets(module->getID()); const int n2 = clbSimulator.getUDPMaximalSequenceNumber (module->getID()); if (n1 < n2 + 1) { rate_Hz *= (double) n1 / (double) (n2 + 1); } this->rbegin()->setRate(pmt, rate_Hz); } } } } catch(const std::exception& error) {}; } /** * Correct measured singles rates for the probability that a hit survives the simulation of the PMT. * * \param simulator PMT simulator */ void correct(const JPMTDefaultSimulatorInterface& simulator) { using namespace JPP; using namespace KM3NETDAQ; for (iterator frame = this->begin(); frame != this->end(); ++frame) { for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) { const JPMTIdentifier id(frame->getModuleID(), pmt); const double P = simulator.getPMTSignalProcessor(id).getSurvivalProbability(NPE); if (P > 0.0) (*frame)[pmt].div(P); else (*frame)[pmt].setValue(0.0); } } } static const int NPE = 1; //!< Number of photo-electrons corresponding to singles rate. }; } #endif