/// Declare some of the raw and basic plots that are going to be used in the /// analysis of the data. These include raw and calibrated energy spectra, /// information about the run time, and count rates on the detectors. This /// also calls the DeclarePlots method that is present in all of the /// Analyzers and Processors. void DetectorDriver::DeclarePlots() { histo_.DeclareHistogram1D(D_HIT_SPECTRUM, S7, "channel hit spectrum"); histo_.DeclareHistogram2D(DD_RUNTIME_SEC, SD, S7, "run time - s"); histo_.DeclareHistogram2D(DD_RUNTIME_MSEC, SD, S7, "run time - ms"); try { if (Globals::get()->HasRawHistogramsDefined()) { histo_.DeclareHistogram1D(D_NUMBER_OF_EVENTS, S4, "event counter"); histo_.DeclareHistogram1D(D_HAS_TRACE, S8, "channels with traces"); histo_.DeclareHistogram1D(D_SUBEVENT_GAP, SE, "Time Between Channels in 10 ns / bin"); histo_.DeclareHistogram1D(D_EVENT_LENGTH, SE, "Event Length in ns"); histo_.DeclareHistogram1D(D_EVENT_GAP, SE, "Time Between Events in ns"); histo_.DeclareHistogram1D(D_EVENT_MULTIPLICITY, S7, "Number of Channels Event"); histo_.DeclareHistogram1D(D_BUFFER_END_TIME,SE, "Buffer Length in ns"); DetectorLibrary *modChan = DetectorLibrary::get(); DetectorLibrary::size_type maxChan = modChan->size(); for (DetectorLibrary::size_type i = 0; i < maxChan; i++) { if (!modChan->HasValue(i)) continue; stringstream idstr; const ChannelConfiguration &id = modChan->at(i); idstr << "M" << modChan->ModuleFromIndex(i) << " C" << modChan->ChannelFromIndex(i) << " - " << id.GetType() << ":" << id.GetSubtype() << " L" << id.GetLocation(); histo_.DeclareHistogram1D(D_RAW_ENERGY + i, SE, ("RawE " + idstr.str()).c_str()); histo_.DeclareHistogram1D(D_FILTER_ENERGY + i, SE, ("FilterE " + idstr.str()).c_str()); histo_.DeclareHistogram1D(D_SCALAR + i, SE, ("Scalar " + idstr.str()).c_str()); histo_.DeclareHistogram1D(D_CAL_ENERGY + i, SE, ("CalE " + idstr.str()).c_str()); } } for (const auto &analyzer : vecAnalyzer) analyzer->DeclarePlots(); for (const auto &processor : vecProcess) processor->DeclarePlots(); } catch (exception &e) { cout << Display::ErrorStr("Exception caught at DetectorDriver::DeclarePlots") << endl; throw; } }
void DetectorDriver::DeclarePlots() { try { DeclareHistogram1D(D_HIT_SPECTRUM, S7, "channel hit spectrum"); DeclareHistogram2D(DD_RUNTIME_SEC, SE, S6, "run time - s"); DeclareHistogram2D(DD_RUNTIME_MSEC, SE, S7, "run time - ms"); if(Globals::get()->hasRaw()) { DetectorLibrary* modChan = DetectorLibrary::get(); DeclareHistogram1D(D_NUMBER_OF_EVENTS, S4, "event counter"); DeclareHistogram1D(D_HAS_TRACE, S8, "channels with traces"); DeclareHistogram2D(DD_BUFFER_START_TIME, SE, S6, "dead time - 0.1%"); DeclareHistogram2D(DD_DEAD_TIME_CUMUL, SE, S6, "dead time - cumul"); DeclareHistogram1D(D_SUBEVENT_GAP, SE, "time btwn chan-in event,10ns bin"); DeclareHistogram1D(D_EVENT_LENGTH, SE, "time length of event, 10 ns bin"); DeclareHistogram1D(D_EVENT_GAP, SE, "time between events, 10 ns bin"); DeclareHistogram1D(D_EVENT_MULTIPLICITY, S7, "number of channels in event"); DeclareHistogram1D(D_BUFFER_END_TIME, SE, "length of buffer, 1 ms bin"); DetectorLibrary::size_type maxChan = modChan->size(); for (DetectorLibrary::size_type i = 0; i < maxChan; i++) { if (!modChan->HasValue(i)) { continue; } stringstream idstr; const Identifier &id = modChan->at(i); idstr << "M" << modChan->ModuleFromIndex(i) << " C" << modChan->ChannelFromIndex(i) << " - " << id.GetType() << ":" << id.GetSubtype() << " L" << id.GetLocation(); DeclareHistogram1D(D_RAW_ENERGY + i, SE, ("RawE " + idstr.str()).c_str() ); DeclareHistogram1D(D_FILTER_ENERGY + i, SE, ("FilterE " + idstr.str()).c_str() ); DeclareHistogram1D(D_SCALAR + i, SE, ("Scalar " + idstr.str()).c_str() ); if (Globals::get()->revision() == "A") DeclareHistogram1D(D_TIME + i, SE, ("Time " + idstr.str()).c_str() ); DeclareHistogram1D(D_CAL_ENERGY + i, SE, ("CalE " + idstr.str()).c_str() ); } } for (vector<TraceAnalyzer *>::const_iterator it = vecAnalyzer.begin(); it != vecAnalyzer.end(); it++) { (*it)->DeclarePlots(); } for (vector<EventProcessor *>::const_iterator it = vecProcess.begin(); it != vecProcess.end(); it++) { (*it)->DeclarePlots(); } } catch (exception &e) { cout << "Exception caught at DetectorDriver::DeclarePlots" << endl; cout << "\t" << e.what() << endl; exit(EXIT_FAILURE); } }
/*! \brief extract channel information from raw data ReadBuffData extracts channel information from the raw data arrays and places it into a structure called evt. A pointer to each of the evt objects is placed in the eventlist vector for later time sorting. \param [in] buf : the buffer to process \param [in] bufLen : the length of the buffer \param [in] eventList : the event list to add the extracted buffer to \return An unused integer */ int ReadBuffDataD(word_t *buf, unsigned long *bufLen, vector<ChanEvent*> &eventList) { // multiplier for high bits of 48-bit time static const double HIGH_MULT = pow(2., 32.); word_t modNum; unsigned long numEvents = 0; word_t *bufStart = buf; /* Determine the number of words in the buffer */ *bufLen = *buf++; /* Read the module number */ modNum = *buf++; ChanEvent *lastVirtualChannel = NULL; if(*bufLen > 0) { // check if the buffer has data if(*bufLen == 2) { // this is an empty channel return 0; } do { ChanEvent *currentEvt = new ChanEvent; // decoding event data... see pixie16app.c // buf points to the start of channel data word_t chanNum = (buf[0] & 0x0000000F); word_t slotNum = (buf[0] & 0x000000F0) >> 4; word_t crateNum = (buf[0] & 0x00000F00) >> 8; word_t headerLength = (buf[0] & 0x0001F000) >> 12; word_t eventLength = (buf[0] & 0x1FFE0000) >> 17; currentEvt->virtualChannel = ((buf[0] & 0x20000000) != 0); currentEvt->saturatedBit = ((buf[0] & 0x40000000) != 0); currentEvt->pileupBit = ((buf[0] & 0x80000000) != 0); // Rev. D header lengths not clearly defined in pixie16app_defs //! magic numbers here for now // make some sanity checks if(headerLength == stats.headerLength) { // this is a manual statistics block inserted by the poll program stats.DoStatisticsBlock(&buf[1], modNum); buf += eventLength; numEvents = readbuff::STATS; continue; } if(headerLength != 4 && headerLength != 8 && headerLength != 12 && headerLength != 16) { cout << " Unexpected header length: " << headerLength << endl; cout << " Buffer " << modNum << " of length " << *bufLen << endl; cout << " CHAN:SLOT:CRATE " << chanNum << ":" << slotNum << ":" << crateNum << endl; // advance to next event and continue // buf += EventLength; // continue; // skip the rest of this buffer return readbuff::ERROR; //return numEvents; } word_t lowTime = buf[1]; word_t highTime = buf[2] & 0x0000FFFF; word_t cfdTime = (buf[2] & 0xFFFF0000) >> 16; word_t energy = buf[3] & 0x0000FFFF; word_t traceLength = (buf[3] & 0xFFFF0000) >> 16; if(headerLength == 8 || headerLength == 16) { // skip the onboard partial sums for now // trailing, leading, gap, baseline } if(headerLength >= 12) { int offset = headerLength - 8; for(int i=0; i < currentEvt->numQdcs; i++) { currentEvt->qdcValue[i] = buf[offset + i]; } } // one last sanity check if(traceLength / 2 + headerLength != eventLength) { cout << " Bad event length (" << eventLength << ") does not correspond with length of header (" << headerLength << ") and length of trace (" << traceLength << ")" << endl; buf += eventLength; continue; } // handle multiple crates modNum += 100 * crateNum; currentEvt->chanNum = chanNum; currentEvt->modNum = modNum; if(currentEvt->virtualChannel) { DetectorLibrary* modChan = DetectorLibrary::get(); currentEvt->modNum += modChan->GetPhysicalModules(); if(modChan->at(modNum, chanNum).HasTag("construct_trace")) { lastVirtualChannel = currentEvt; } } currentEvt->energy = energy; //KM 2012-10-24 reinstating removal of saturated if(currentEvt->saturatedBit) currentEvt->energy = 16383; currentEvt->trigTime = lowTime; currentEvt->cfdTime = cfdTime; currentEvt->eventTimeHi = highTime; currentEvt->eventTimeLo = lowTime; currentEvt->time = highTime * HIGH_MULT + lowTime; buf += headerLength; /* Check if trace data follows the channel header */ if(traceLength > 0) { // sbuf points to the beginning of trace data halfword_t *sbuf = (halfword_t *)buf; currentEvt->trace.reserve(traceLength); if(currentEvt->saturatedBit) currentEvt->trace.SetValue("saturation", 1); if(lastVirtualChannel != NULL && lastVirtualChannel->trace.empty()) { lastVirtualChannel->trace.assign(traceLength, 0); } // Read the trace data (2-bytes per sample, i.e. 2 samples per word) for(unsigned int k = 0; k < traceLength; k ++) { currentEvt->trace.push_back(sbuf[k]); if(lastVirtualChannel != NULL) { lastVirtualChannel->trace[k] += sbuf[k]; } } buf += traceLength / 2; } eventList.push_back(currentEvt); numEvents++; } while(buf < bufStart + *bufLen); } else { // if buffer has data
/*! \brief extract channel information from raw data ReadBuffData extracts channel information from the raw data arrays and places it into a structure called evt. A pointer to each of the evt objects is placed in the eventlist vector for later time sorting. \param [in] buf : the buffer to process \param [in] bufLen : the length of the buffer \param [in] eventList : the event list to add the extracted buffer to \return An unused integer */ int ReadBuffDataF(word_t *buf, unsigned long *bufLen, vector<ChanEvent*> &eventList) { // multiplier for high bits of 48-bit time static const double HIGH_MULT = pow(2., 32.); word_t modNum; unsigned long numEvents = 0; word_t *bufStart = buf; /* Determine the number of words in the buffer */ *bufLen = *buf++; /* Read the module number */ modNum = *buf++; ChanEvent *lastVirtualChannel = NULL; if(*bufLen > 0) { // check if the buffer has data if(*bufLen == 2) { // this is an empty channel return 0; } do { ChanEvent *currentEvt = new ChanEvent; // decoding event data... see pixie16app.c // buf points to the start of channel data //Decode the first header word word_t chanNum = (buf[0] & 0x0000000F); word_t slotNum = (buf[0] & 0x000000F0) >> 4; word_t crateNum = (buf[0] & 0x00000F00) >> 8; word_t headerLength = (buf[0] & 0x0001F000) >> 12; word_t eventLength = (buf[0] & 0x7FFE0000) >> 17; currentEvt->pileupBit = (buf[0] & 0x80000000) != 0; // Sanity check if(headerLength == stats.headerLength) { // this is a manual statistics block inserted poll stats.DoStatisticsBlock(&buf[1], modNum); buf += eventLength; numEvents = readbuff::STATS; continue; } //Decode the second header word word_t lowTime = buf[1]; //Decode the third header word word_t highTime = buf[2] & 0x0000FFFF; word_t cfdTime = (buf[2] & 0x3FFF0000) >> 16; currentEvt->cfdTrigSource = ((buf[2] & 0x40000000) != 0); currentEvt->cfdForceTrig = ((buf[2] & 0x80000000) != 0); //Decode the foruth header word word_t energy = buf[3] & 0x0000FFFF; word_t traceLength = (buf[3] & 0x7FFF0000) >> 16; currentEvt->saturatedBit = ((buf[3] & 0x80000000) != 0); int offset = headerLength - 8; switch(headerLength) { case 4: case 6: case 8: case 10: break; case 12: case 14: case 16: case 18: for(int i=0; i < currentEvt->numQdcs; i++) currentEvt->qdcValue[i] = buf[offset + i]; break; default: cerr << " Unexpected header length: " << headerLength << endl; cerr << " Buffer " << modNum << " of length " << *bufLen << endl; cerr << " CHAN:SLOT:CRATE " << chanNum << ":" << slotNum << ":" << crateNum << endl; return readbuff::ERROR; break; } // one last sanity check if(traceLength / 2 + headerLength != eventLength) { cerr << " Bad event length (" << eventLength << ") does not correspond with length of header (" << headerLength << ") and length of trace (" << traceLength << ")" << endl; buf += eventLength; continue; } // handle multiple crates modNum += 100 * crateNum; currentEvt->chanNum = chanNum; currentEvt->modNum = modNum; if(currentEvt->virtualChannel) { DetectorLibrary* modChan = DetectorLibrary::get(); currentEvt->modNum += modChan->GetPhysicalModules(); if(modChan->at(modNum, chanNum).HasTag("construct_trace")) { lastVirtualChannel = currentEvt; } } currentEvt->energy = energy; if(currentEvt->saturatedBit) currentEvt->energy = 16383; currentEvt->trigTime = lowTime; currentEvt->cfdTime = cfdTime; currentEvt->eventTimeHi = highTime; currentEvt->eventTimeLo = lowTime; currentEvt->time = highTime * HIGH_MULT + lowTime; buf += headerLength; /* Check if trace data follows the channel header */ if(traceLength > 0) { // sbuf points to the beginning of trace data halfword_t *sbuf = (halfword_t *)buf; currentEvt->trace.reserve(traceLength); if(currentEvt->saturatedBit) currentEvt->trace.SetValue("saturation", 1); if(lastVirtualChannel != NULL && lastVirtualChannel->trace.empty()) { lastVirtualChannel->trace.assign(traceLength, 0); } // Read the trace data (2-bytes per sample, i.e. 2 samples per word) for(unsigned int k = 0; k < traceLength; k ++) { currentEvt->trace.push_back(sbuf[k]); if(lastVirtualChannel != NULL) { lastVirtualChannel->trace[k] += sbuf[k]; } } buf += traceLength / 2; } eventList.push_back(currentEvt); numEvents++; } while(buf < bufStart + *bufLen); } else { // if buffer has data