Ejemplo n.º 1
0
/// 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;
    }
}
Ejemplo n.º 2
0
/*! \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
Ejemplo n.º 3
0
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);
    }
}
Ejemplo n.º 4
0
/*! \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
Ejemplo n.º 5
0
extern "C" void hissub_(unsigned short *ibuf[],unsigned short *nhw)
#endif
{
    static float hz = sysconf(_SC_CLK_TCK); // get the number of clock ticks per second
    static clock_t clockBegin; // initialization time
    static struct tms tmsBegin;

    vector<ChanEvent*> eventList; // vector to hold the events

    /* Pointer to singleton DetectorLibrary class */
    DetectorLibrary* modChan = DetectorLibrary::get();
    /* Pointer to singleton DetectorDriver class */
    DetectorDriver* driver = DetectorDriver::get();

    // local version of ibuf pointer
    word_t *lbuf;

    int retval = 0; // return value from various functions
    
    unsigned long bufLen;
    
    /*
      Various event counters
    */
    unsigned long numEvents = 0;
    static int counter = 0; // the number of times this function is called
    static int evCount;     // the number of times data is passed to ScanList
    static unsigned int lastVsn; // the last vsn read from the data
    time_t theTime = 0;

    /*
      Assign the local variable lbuf to the variable ibuf which is passed into
      the routine.  The difference between the new and old pixie16 readouts is
      the type of the variable and source of the variable ibuf.

      In the new readout ibuf is from a C++ function and is of type unsigned int*
      In the old readout ibuf is from a Fortran function and is of type
      unsigned short*

      This results in two different assignment statements depending on 
      the readout.
    */
#ifdef newreadout
    lbuf=(word_t *)ibuf[0];
#else
    lbuf=(word_t *)ibuf; //old readout
#endif

    /* Initialize the scan program before the first event */
    if (counter==0) {
        /* Retrieve the current time for use later to determine the total
	 * running time of the analysis.
	 */
        clockBegin = times(&tmsBegin);

	cout << "First buffer at " << clockBegin << " sys time" << endl;
        /* After completion the descriptions of all channels are in the modChan
	 * vector, the DetectorDriver and rawevent have been initialized with the
	 * detectors that will be used in this analysis.
	 */
    cout << "Using event width " << pixie::eventInSeconds * 1e6 << " us" << endl
         << "                  " << pixie::eventWidth
         << " in pixie16 clock tics." << endl;

	modChan->PrintUsedDetectors(rawev);
    if (verbose::MAP_INIT)
        modChan->PrintMap();

	driver->Init(rawev);
    
	/* Make a last check to see that everything is in order for the driver 
	 * before processing data
	 */
	if ( !driver->SanityCheck() ) {
	    cout << "Detector driver did not pass sanity check!" << endl;
	    exit(EXIT_FAILURE);
	}

        lastVsn=-1; // set last vsn to -1 so we expect vsn 0 first 	

	cout << "Init done at " << times(&tmsBegin) << " sys time." << endl;
    }
    counter++;
 
    unsigned int nWords=0;  // buffer counter, reset only for new buffer
 
    // true if the buffer being analyzed is split across a spill from pixie
    bool multSpill;

    do {
	word_t vsn = U_DELIMITER;
	bool fullSpill=false; //true if spill had all vsn's
        multSpill=false;  //assume all buffers are not split between spills    

        /* while the current location in the buffer has not gone beyond the end
         * of the buffer (ignoring the last three delimiters, continue reading
	 */
        while (nWords < (nhw[0]/2 - 6)) {
            /*
              Retrieve the record length and the vsn number
            */
            word_t lenRec = lbuf[nWords];
            vsn = lbuf[nWords+1];
            
            /* If the record length is -1 (after end of spill), increment the
	       location in the buffer by two and start over with the while loop
	     */
            if (lenRec == U_DELIMITER) {
                nWords += 2;  // increment two whole words and try again
                continue;                         
            }
	    // Buffer with vsn 1000 was inserted with the time for superheavy exp't
	    if (vsn == clockVsn) {
	      memcpy(&theTime, &lbuf[nWords+2], sizeof(time_t));
	      nWords += lenRec;
	    }
            /*
              If the record length is 6, this is an empty channel.
	      Skip this vsn and continue with the next
            */
	    //! Revision specific, so move to ReadBuffData
            if (lenRec==6) {
                nWords += lenRec+1; // one additional word for delimiter
                lastVsn=vsn;
                continue;
            }
            
            /* If both the current vsn inspected is within an acceptable 
	       range, begin reading the buffer.
            */
            if ( vsn < modChan->GetPhysicalModules()  ) {
	        if ( lastVsn != U_DELIMITER) {
		    // the modules should be read out cyclically
		    if ( ((lastVsn+1) % modChan->GetPhysicalModules() ) != vsn ) {
#ifdef VERBOSE
			cout << " MISSING BUFFER " << vsn << "/" 
                 << modChan->GetPhysicalModules()
			     << " -- lastVsn = " << lastVsn << "  " 
			     << ", length = " << lenRec << endl;
#endif
                        RemoveList(eventList);
                        fullSpill=true;
                    }
                }
                /* Read the buffer.  After read, the vector eventList will 
		   contain pointers to all channels that fired in this buffer
                */

                retval= ReadBuffData(&lbuf[nWords], &bufLen, eventList);

                
                /* If the return value is less than the error code, 
		   reading the buffer failed for some reason.  
		   Print error message and reset variables if necessary
                */
                if ( retval <= readbuff::ERROR ) {
		    cout << " READOUT PROBLEM " << retval 
			 << " in event " << counter << endl;
                    if ( retval == readbuff::ERROR ) {
			cout << "  Remove list " << lastVsn << " " << vsn << endl;
                        RemoveList(eventList); 	                        
                    }
                    return;
                } else if ( retval == 0 ) {
		    // empty buffers are regular in Rev. D data
		    // cout << " EMPTY BUFFER" << endl;
		  nWords += lenRec + 1;
		  lastVsn = vsn;
		  continue;
                  //  return;
                } else if ( retval > 0 ) {		
		  /* increment the total number of events observed */
		  numEvents += retval;
                }
                /* Update the variables that are keeping track of what has been
		   analyzed and increment the location in the current buffer
                */
                lastVsn = vsn;
                nWords += lenRec+1; // one extra word for delimiter
            } else {
		// bail out if we have lost our place,		
		//   (bad vsn) and process events     
		if (vsn != 9999 && vsn != clockVsn) {
#ifdef VERBOSE	    
		    cout << "UNEXPECTED VSN " << vsn << endl;
#endif
		}
		break;
	    }
        } // while still have words
	if (nWords > nhw[0] / 2 - 6) {
	    cout << "This actually happens!" << endl;	    
	}
        
        /* If the vsn is 9999 this is the end of a spill, signal this buffer
	   for processing and determine if the buffer is split between spills.
        */
        if ( vsn == 9999 || vsn == clockVsn ) {
            fullSpill = true;
            nWords += 3;//skip it
            if (lbuf[nWords+1] != U_DELIMITER) {
		cout << "this actually happens!" << endl;
                multSpill = true;
            }
            lastVsn=U_DELIMITER;
        }
        
        /* if there are events to process, continue */
        if( numEvents>0 ) {
	    if (fullSpill) { 	  // if full spill process events
		// sort the vector of pointers eventlist according to time
		double lastTimestamp = (*(eventList.rbegin()))->GetTime();

		sort(eventList.begin(),eventList.end(),CompareTime);
		driver->CorrelateClock(lastTimestamp, theTime);

		/* once the vector of pointers eventlist is sorted based on time,
		   begin the event processing in ScanList()
		*/
		ScanList(eventList, rawev);

		/* once the eventlist has been scanned, remove it from memory
		   and reset the number of events to zero and update the event
		   counter
		*/

		evCount++;		
		/*
		  every once in a while (when evcount is a multiple of 1000)
		  print the time elapsed doing the analysis
		*/
		if(evCount % 1000 == 0 || evCount == 1) {
		    tms tmsNow;
		    clock_t clockNow = times(&tmsNow);

		    if (theTime != 0) {
			cout << " data read up to poll status time " << ctime(&theTime);
		    }
		    cout << "   buffer = " << evCount << ", user time = " 
			 << (tmsNow.tms_utime - tmsBegin.tms_utime) / hz
			 << ", system time = " 
			 << (tmsNow.tms_stime - tmsBegin.tms_stime) / hz
			 << ", real time = "
			 << (clockNow - clockBegin) / hz 
			 << ", ts = " << lastTimestamp << endl;
		}		
		RemoveList(eventList);
		numEvents=0;
	    } // end fullSpill 
	    else {
		cout << "Spill split between buffers" << endl;
		return; //! this tosses out all events read into the vector so far
	    }	    
        }  // end numEvents > 0
        else if (retval != readbuff::STATS) {
	    cout << "bad buffer, numEvents = " << numEvents << endl;
            return;
        }
        
    } while (multSpill); // end while loop over multiple spills
    return;      
}
Ejemplo n.º 6
0
/**
 * Reads in QDC parameters from an input file
 *   The file format allows comment lines at the beginning
 *   Followed by QDC lengths 
 *   Which QDC to use for position calculation
 *     followed by the amount to scale the [0,1] result by to physical units
 *   And min and max values of the normalized QDC for each location in form:
 *      <location> <min> <max>
 *   Note that QDC 0 is considered to be a baseline section of the trace for
 *     baseline removal for the other QDCs
 */
bool PositionProcessor::Init(RawEvent& rawev)
{
    // Call the parent function to handle the standard stuff
    if (!EventProcessor::Init(rawev)) {
        return false;
    }

    DetectorLibrary* modChan = DetectorLibrary::get();

    int numLocationsTop    = modChan->GetNextLocation("ssd", "top");
    int numLocationsBottom = modChan->GetNextLocation("ssd", "bottom");
    if (numLocationsTop != numLocationsBottom) {
        cerr << "Number of top positions (" << numLocationsTop 
            << ") does not match number of bottom positions ("
            << numLocationsBottom << ") in map!" << endl;
        cerr << "  Disabling QDC processor." << endl;

        return (initDone = false);
    }
    numLocations = numLocationsTop;
    if (numLocations > maxNumLocations) {
        cerr << "Number of positions (" << numLocations 
            << ") is larger then maximum number of supported positions ("
            << maxNumLocations << ") in PositionProcessor" << endl;
        cerr << "  Disabling QDC processor." << endl;
        return (initDone = false);
    }
    minNormQdc.resize(numLocations);
    maxNormQdc.resize(numLocations);

    string configFile = "./setup/qdc.txt";
    ifstream in(configFile.c_str());
    if (!in) {
        cerr << "Failed to open the QDC parameter file, QDC processor disabled." << endl;
        return (initDone = false);	
    }

    // Ignore any lines at the beginning that don't have a digit
    // This allows for some comments at the beginning of the file
    int linesIgnored = 0;
    while ( !isdigit(in.peek()) ) {
        in.ignore(1000, '\n');
        linesIgnored++;
    }
    if (linesIgnored != 0) {
        cout << "Ignored " << linesIgnored << " comment lines in " 
            << configFile << endl;
    }

    for (int i=0; i < numQdcs; i++) 
        in >> qdcLen[i];
    partial_sum(qdcLen, qdcLen + numQdcs, qdcPos);
    totLen = qdcPos[numQdcs - 1]  - qdcLen[0];
    // totLen = accumulate(qdcLen + 1, qdcLen + 8, 0);
    
    in >> whichQdc >> posScale;
    
    int numLocationsRead = 0;
    while (true) {
        int location;
        in >> location;
        if (in.eof()) {
            // place this here so a trailing newline is okay in the config file
            break;
        }
        in >> minNormQdc[location] >> maxNormQdc[location];
        numLocationsRead++;
    }

    if (numLocationsRead != numLocations) {
        cerr << "Only read QDC position calibration information from "
            << numLocationsRead << " locations where a total of "
            << numLocations << " was expected!" << endl;
        cerr << "  Disabling position processor." << endl;
        return (initDone = false);
    }
    
    cout << "QDC processor initialized with " << numLocations 
         << " locations operating on " << numQdcs << " QDCs" << endl;
    cout << "QDC #" << whichQdc << " being used for position determination."
         << endl;

    return true;
}