Back to index

CTriggerServer.C

 
//----------------------------------------------------------------------------- 
//  $Header: /asis/offline/ceres/cool/project/RCS/CTriggerServer.C,v 3.0 1996/10/02 09:39:50 voigt Exp $ 
// 
//  COOL Program Library   
//  Copyright (C) CERES collaboration, 1996 
// 
//  Implementation of class CTriggerServer. 
// 
//----------------------------------------------------------------------------- 
#include <iostream.h> 
#include <limits.h> 
#include <stdlib.h> 
#include "CTriggerServer.h"  
 
 
unsigned hashString(const RWCString& str)  
{  
   return str.hash(); 
} 
 
 
CTriggerServer::CTriggerServer(const char* setupFile)  
{ 
   // 
   //  Create and read setup 
   // 
   setup = new CTriggerSetup; 
   if (setupFile == 0) { 
      CString setupName = CString(C_DEFAULT_SETUP_PATH)+ 
                          CString(C_SETUPFILE_TRIGGER); 
      setup->read(setupName.data()); 
   } 
   else 
      setup->read(setupFile); 
    
   trigPatt[trigFLT ] = new RWTValHashDictionary<RWCString, unsigned long>(hashString); 
   trigPatt[trigMAIN] = new RWTValHashDictionary<RWCString, unsigned long>(hashString); 
    
   readTriggerConfiguration();		// read trigger pattern (separate file) 
 
   // 
   // reset all warning flags 
   // 
   for (int i=0; i<100; i++) 
      warned[i] = False; 
} 
 
 
CTriggerServer::~CTriggerServer()  
{ 
   trigPatt[trigFLT ]->clear(); 
   trigPatt[trigMAIN]->clear(); 
   delete [] trigPatt; 
    
   for (int i=0; i<MaxHTDCChannels; i++) { 
      hTDC[i].clear(); 
   } 
   delete hTDC; 
   delete setup;  
} 
 
 
CTriggerServer::CTriggerServer(const CTriggerServer &) // this should never be called 
{ 
   trigPatt[trigFLT ] = new RWTValHashDictionary<RWCString, unsigned long>(hashString); 
   trigPatt[trigMAIN] = new RWTValHashDictionary<RWCString, unsigned long>(hashString); 
    
   trigPatt[trigFLT ]->clear(); 
   trigPatt[trigMAIN]->clear(); 
   delete [] trigPatt; 
} 
 
 
CTriggerServer & CTriggerServer::operator = (const CTriggerServer &) 
{ 
   return *this; 
} 
 
 
CBoolean CTriggerServer::update(CEventServer& es) 
{ 
   unpackTriggerPattern(es); 
   if (!md.unpack(es)) return False;     // unpack multiplicity detector 
   if (!unpackHTDC(es)) return False;    // unpack historyTDC 
   return True; 
} 
 
 
void CTriggerServer::listSetup(ostream& ost) const 
{ 
   ost << "\nSetup listing of trigger server" << endl; 
   CString line('=', 46); 
   ost << line << endl; 
   setup->list(ost); 
} 
 
 
// ============================== multiplicity ========================== 
 
float CTriggerServer::getMultiplicity() 
{ 
   return md.getMultiplicity();                                  // get mult from MD 
} 
 
// ========================= cleanup using HTDC ========================= 
 
CBoolean CTriggerServer::unpackHTDC(CEventServer& es) 
{ 
   int i; 
 
   for (i=0; i<MaxHTDCChannels; i++) {         // remove old contents 
      hTDC[i].clear(); 
   } 
    
   const CLabel *evt = es.getLabel(HTDC, Evt);          // get pointer to current event 
   if (evt == 0) { 
      cerr << "CTriggerServer::unpackHTDC():\n"; 
      cerr << "\tERROR\n"; 
      cerr << "\tLabel HTDC not found. No further action.\n"; 
      return False; 
   } 
    
   unsigned long *data = (unsigned long *) evt->getData(); // that's where the data starts 
   if (data == 0) { 
      cerr << "CTriggerServer::unpackHTDC():\n"; 
      cerr << "\tERROR\n"; 
      cerr << "\tData in label HTDC not found. No further action.\n"; 
      return False; 
   } 
   int chan = 0; 
   int time = 0; 
   for (i=1; i<evt->getSize(); i++) {          // skip the status word (word 0) 
      chan = int((data[i]>>17) & 0x0f);        // get channel number 
      if (chan < MaxHTDCChannels) { 
         time = int((data[i]) & 0xffff);       // time info 
         hTDC[chan].insert(time);              // intrinsically convert to float 
      }  
      else { 
	 if (chan >= 100 || (chan < 100 && !warned[chan])) { 
	    cerr << "CTriggerServer::unpackHTDC():\n"; 
	    cerr << "\tWARNING\n"; 
	    cerr << "\tIllegal channel '" << chan << "' found. Further warnings will be supressed\n"; 
	    warned[chan] = True; 
	 } 
      } 
   }    
   return True; 
} // end CTriggerServer::unpackHTDC 
 
 
int CTriggerServer::isBadN2Interaction(int tBC1, int tMB) 
{ 
   int  BC1_min        = setup->getLowerEdgeBC1Window(); 
   int  BC1_max        = setup->getUpperEdgeBC1Window(); 
   int  min_bias_min   = setup->getLowerEdgeMinBiasWindow(); 
   int  min_bias_max   = setup->getUpperEdgeMinBiasWindow(); 
   int  N2_min         = setup->getLowerEdgeN2Window(); 
   int  N2_max         = setup->getUpperEdgeN2Window(); 
    
   int t0DownStream    = setup->getT0DownStream(); 
   int t0BC1           = (BC1_max + BC1_min)/2; 
   int t0MinBias       = (min_bias_max + min_bias_min)/2; 
    
   if (getNumberInWindow(htdcBC1, BC1_min, BC1_max) == 0) 
      return noBeamParticle; 
 
   if (getNumberInWindow(htdcN2, N2_min, N2_max) == 0) 
      return noN2Interaction; 
 
   if (getNumberInWindow(htdcMinBias, min_bias_min, min_bias_max) == 0) 
      return noMinBias; 
 
   if (getNumberInWindow(htdcBC1, t0BC1 - tBC1, t0BC1 + tBC1)  > 1) { 
      timeOfSecondBeamParticle = getMinTime(htdcBC1, t0BC1 - tBC1, t0BC1 + tBC1); 
      return beamPileUp; 
   } 
 
   if (getNumberInWindow(htdcMinBias, t0MinBias - tMB, t0MinBias + tMB)  > 1) 
      return minBiasPileUp; 
 
   if (getNumberInWindow(htdcDownStream, t0DownStream - tMB, t0DownStream + tMB) > 0) 
      return downstramInteractionPileUp; 
    
   return 0; 
} 
 
int CTriggerServer::getMinTime(int chan, int tlow, int tup) 
{ 
   // 
   // this function returns the smallest time difference between two hits in hTDC[chan], 
   // if they are within the given time window. If there is only one hit, time is set to 0. 
   // 
   CBoolean oneAdditionalHitFound = False; 
   if (hTDC[chan].length() < 2) return 0; 
   int i, j, time; 
   int minTime = INT_MAX; 
   for (i=0; i<hTDC[chan].length(); i++) { 
      if ( hTDC[chan](i) >= tlow && hTDC[chan](i) <= tup ) { 
	 for (j=i+1; j<hTDC[chan].length(); j++) { 
	    if ( hTDC[chan](j) >= tlow && hTDC[chan](j) <= tup ) { 
	       time = abs(hTDC[chan](j) - hTDC[chan](i)); 
	       oneAdditionalHitFound = True; 
	       if (time < minTime) 
		  minTime = time; 
	    } 
	 } 
      } 
   } 
   if (oneAdditionalHitFound) 
      return minTime; 
   else 
      return 0;    
} 
 
int CTriggerServer::getNumberInWindow(int chan, int tlow, int tup) 
{ 
   int num=0; 
   for (int i=0; i<hTDC[chan].length(); i++) { 
      if ( hTDC[chan](i) >= tlow && hTDC[chan](i) <= tup ) 
	 num++; 
   } 
   return num; 
} 
 
 
int CTriggerServer::getBeamInWindow(int tlow, int tup) 
{ 
   return getNumberInWindow(htdcBC1, tlow, tup); 
} 
 
 
int CTriggerServer::getN2InWindow (int tlow, int tup)                  // get # of interactions from HTDC 
{ 
   return getNumberInWindow(htdcN2, tlow, tup); 
} 
 
// ======================= trigger pattern info ========================= 
 
//----------------------------------------------------------------------------- 
//  Construct Trigger 
//  Read trigger pattern from file 
//  Format of the (ascii) file must be: 
//        pattern-id bit name 
//  with 
//  pattern-id  1 or 2  
//  name up to 16 characters 
//  and bit [0-31]  
//  This is the easiest way to cope with some people changing 
//  the trigger pattern every day. 
// 
//----------------------------------------------------------------------------- 
void CTriggerServer::readTriggerConfiguration() 
{ 
   CString filename = CString(C_DEFAULT_SETUP_PATH)+ 
                      CString(C_SETUPFILE_TRIGGERPATTERN); 
    
   ifstream ifs(filename);                          // open file 
   if (!ifs) { 
      cerr << "CTriggerServer::readTriggerConfiguration():\n"; 
      cerr << "\tERROR\n"; 
      cerr << "\tCan't open trigger pattern file '" << filename << "'.\n"; 
      return; 
   } 
   // 
   //  Read pattern 
   // 
   int npat, bit; 
   RWCString name; 
   while (ifs >> npat >> bit >> name, !ifs.eof() && ifs.good() ) { 
      trigPatt[npat-1]->insertKeyAndValue(name, (unsigned long)(1<<bit)); 
   } 
    
} // end  CTriggerServer::readTriggerConfiguration 
 
 
void CTriggerServer::unpackTriggerPattern(CEventServer& es) 
{ 
   const CLabel *evt = es.getLabel(EVNT, Evt);          // get pointer to current event 
   if (evt == 0) {					// not an event, return 
     triggerPattern[trigFLT ] = 0; 
     triggerPattern[trigMAIN] = 0; 
     return; 
   } 
 
   const CWord *data = evt->getData();                  // that's where the data starts 
    
   triggerPattern[trigFLT ] = (int) data[TriggerWord1Position]; 
   triggerPattern[trigMAIN] = (int) data[TriggerWord2Position]; 
    
} // end CTriggerServer::unpackTriggerPattern 
 
 
void CTriggerServer::printTriggerPattern(ostream& os) 
{ 
   RWTValHashDictionaryIterator<RWCString, unsigned long> fltIter (*trigPatt[trigFLT ]); 
   RWTValHashDictionaryIterator<RWCString, unsigned long> mainIter(*trigPatt[trigMAIN]); 
    
   os << "trigger pattern: "; 
    
   while (mainIter()) { 
      if (mainIter.value() & triggerPattern[trigMAIN]) { 
         os << "/" << mainIter.key(); 
      } 
   } 
    
   while (fltIter()) { 
      if (fltIter.value() & triggerPattern[trigFLT ]) { 
         os << "/" << fltIter.key(); 
      } 
   }    
   os << endl;   
} // end CTriggerServer::printTriggerPattern 
 
 
 
 

Back to index