Skip to content
Snippets Groups Projects
THcDetectorMap.cxx 9.06 KiB
Newer Older
  • Learn to ignore specific revisions
  • //*-- Author: Stephen Wood
    
    //////////////////////////////////////////////////////////////////////////
    //
    // THcDetectorMap
    //
    // Class to read and hold Hall C style detector map
    //
    // Will need method to retrieve all map entries for a given
    // detector id.
    //
    // Not sure we will keep this class, but still need the parsing of the map file
    //
    //////////////////////////////////////////////////////////////////////////
    
    #include "THcDetectorMap.h"
    
    #include "TObjArray.h"
    #include "TObjString.h"
    
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    
    using namespace std;
    
    ClassImp(THcDetectorMap)
    
    inline static bool IsComment( const string& s, string::size_type pos )
    {
      return ( pos != string::npos && pos < s.length() &&
    	   (s[pos] == '!') );
    }
    
    //_____________________________________________________________________________
    
    THcDetectorMap::THcDetectorMap() : fNchans(0), fNIDs(0)
    
    {
    }
    
    //_____________________________________________________________________________
    THcDetectorMap::~THcDetectorMap()
    {
    }
    
    bool THcDetectorMap::compare(const ChaninMod *first, const ChaninMod *second) {
      // This one not used, but we get a link error if we don't include
      // a compare method
          return((first->channel < second->channel)? true: false);
    }
    struct Functor
    {
      bool operator() (const THcDetectorMap::ChaninMod &first, const THcDetectorMap::ChaninMod &second)
      { return((first.channel < second.channel)? true: false);}
    };
    //_____________________________________________________________________________
    Int_t THcDetectorMap::FillMap(THaDetMap *detmap, const char *detectorname)
    // Should probably return a status
    {
      list<ModChanList>::iterator imod;
      list<ChaninMod>::iterator ichan;
      ChaninMod Achan;
      ModChanList Amod;
    
      // Translate detector name into and ID
      // For now just long if then else.  Could get it from the comments
      // at the beginning of the map file.
    
      Int_t did=-1;
      for(Int_t i=0; i < fNIDs; i++) {
        if(strcasecmp(detectorname,fIDMap[i].name) == 0) {
          did = fIDMap[i].id;
          break;
        }
      }
      if(did < 0) {
        cout << "FillMap Error: No detector ID registered for " << detectorname << endl;
        cout << "     Using detector id of 0" << endl;
    
        did = 0;
      }
    
      mlist.clear();
      //  cout << "fNchans=" << fNchans << endl;
      for(Int_t ich=0;ich<fNchans;ich++) {
        if(fTable[ich].did == did) {
          Int_t roc=fTable[ich].roc;
          Int_t slot=fTable[ich].slot;
          Int_t model=fTable[ich].model;
          //      cout << "ROC=" << fTable[ich].roc << "  SLOT=" << fTable[ich].slot
          //	   << " CHANNEL=" << fTable[ich].channel << endl;
          Achan.channel = fTable[ich].channel;
          Achan.plane = fTable[ich].plane;
          Achan.counter = fTable[ich].counter;
          Achan.signal = fTable[ich].signal;
          for(imod=mlist.begin(); imod!= mlist.end(); ++imod) {
    	if((*imod).roc == roc && (*imod).slot == slot) {
    	  //	  cout << "Pushing chan " << Achan.channel << " to " << roc
    	  //	       << " " << slot << endl;
    	  (*imod).clist.push_back(Achan);
    	  break;
    	}
          }
          if(imod == mlist.end()) {
    	Amod.roc = roc;
    	Amod.slot = slot;
    	Amod.model = model;
    	Amod.clist.clear();
    	Amod.clist.push_back(Achan);
    	mlist.push_back(Amod);
    	// 	cout << "New module  " << Achan.channel << " to " << roc
    	//	     << " " << slot << endl;
          }
        }
      }
      if(mlist.size() <= 0) {
        return(-1);
      }
      Functor f;
      for(imod=mlist.begin(); imod!= mlist.end(); ++imod) {
        //    cout << "Slot " << (*imod).slot << endl;
        list<ChaninMod> *clistp = &((*imod).clist);
        clistp->sort(f);//Sort by channel
      }
      // Copy the information to the Hall A style detector map
      // grouping consecutive channels that are all the same plane
      // and signal type
      for(imod=mlist.begin(); imod!= mlist.end(); ++imod) {
        UShort_t roc = (*imod).roc;
        UShort_t slot = (*imod).slot;
        UInt_t model=(*imod).model;
        //    cout << "Slot " << slot << endl;
        list<ChaninMod> *clistp = &((*imod).clist);
        Int_t first_chan = -1;
        Int_t last_chan = -1;
        Int_t last_plane = -1;
        Int_t last_signal = -1;
        Int_t first_counter = -1;
        Int_t last_counter = -1;
        for(ichan=clistp->begin(); ichan!=clistp->end(); ++ichan) {
          Int_t this_chan = (*ichan).channel;
          Int_t this_counter = (*ichan).counter;
          Int_t this_signal = (*ichan).signal;
          Int_t this_plane = (*ichan).plane;
          if(last_chan+1!=this_chan || last_counter+1 != this_counter 
    	 || last_plane != this_plane || last_signal!=this_signal) {
    	if(last_chan >= 0) {
    	  if(ichan != clistp->begin()) {
    	    //	    cout << "AddModule " << slot << " " << first_chan << 
    	    //  " " << last_chan << " " << first_counter << endl;
    	    detmap->AddModule((UShort_t)roc, (UShort_t)slot,
    			      (UShort_t)first_chan, (UShort_t)last_chan, 
    			      (UInt_t) first_counter, model, (Int_t) 0,
    			      (Int_t) -1, (UInt_t)last_plane, (UInt_t)last_signal);
    	  }
    	}
    	first_chan = this_chan;
    	first_counter = this_counter;
          }
          last_chan = this_chan;
          last_counter = this_counter;
          last_plane = this_plane;
          last_signal = this_signal;
          //      cout << "  Channel " << (*ichan).channel << " " <<
          //	(*ichan).plane << " " <<  (*ichan).counter << endl;
        }
        detmap->AddModule((UShort_t)roc, (UShort_t)slot,
    		      (UShort_t)first_chan, (UShort_t)last_chan, 
    		      (UInt_t) first_counter, model, (Int_t) 0,
    		      (Int_t) -1, (UInt_t)last_plane, (UInt_t)last_signal);
      }
      
      return(0);
    }
    
    void THcDetectorMap::Load(const char *fname)
    {
      static const char* const here = "THcDetectorMap::Load";
      static const char* const whtspc = " \t";
    
      ifstream ifile;
    
      ifile.open(fname);
      if(!ifile.is_open()) {
        Error(here, "error opening detector map file %s",fname);
        return;			// Need a success/failure argument?
      }
      string line;
    
      Int_t roc=0;
      Int_t nsubadd=0;
      Int_t mask=0;
      Int_t bsub=0;
      Int_t detector=0;
      Int_t slot=0;
      Int_t model=0;
    
      fNchans = 0;
    
      string::size_type start, pos=0;
    
      char varname[100];
    
      while(getline(ifile,line)) {
        // BLank line or comment
    
        if(line.empty()) continue;
        if((start = line.find_first_not_of( whtspc )) == string::npos) continue;
        if(IsComment(line, start)) { // Check for ID assignments
          // Get rid of all white space
          while((pos=line.find_first_of(whtspc)) != string::npos) {
    	line.erase(pos,1);
          }
          line.erase(0,1);	// Erase "!"
          if(! ((pos=line.find("_ID=")) == string::npos)) {
    	fIDMap[fNIDs].name = new char [pos+1];
    	strncpy(fIDMap[fNIDs].name,line.c_str(),pos);
    	fIDMap[fNIDs].name[pos] = '\0';
    	start = (pos += 4); // Move to after "="
    	while(isdigit(line.at(pos++)));
    	fIDMap[fNIDs++].id = atoi(line.substr(start,pos).c_str());
          }
    
    
        //    cout << "MAPA: " << line << endl;
    
        // Remove comment from line
        while ((pos = line.find_first_of("!", pos+1)) != string::npos) {
          if(IsComment(line, pos)) {
    	line.erase(pos);
    	break;
          }
        }
    
        // Get rid of all white space
        while((pos=line.find_first_of(whtspc)) != string::npos) {
          line.erase(pos,1);
        }
    
        //    cout << "MAPB: " << line << endl;
    
      // Decide if line is ROC/NSUBADD/MASK/BSUB/DETECTOR/SLOT = something
      // or chan, plane, counter[, signal]
    
      
        if((pos=line.find_first_of("=")) != string::npos) { // Setting parameter
          strcpy(varname, (line.substr(0,pos)).c_str());
          Int_t valuestartpos = pos+1;
          Int_t value = atoi(line.substr(valuestartpos).c_str());
          // Some if statements
          if(strcasecmp(varname,"detector")==0) {
    	detector = value;
          } else if (strcasecmp(varname,"roc")==0) {
    	roc = value;
          } else if (strcasecmp(varname,"nsubadd")==0) {
    	nsubadd = value;
          } else if (strcasecmp(varname,"mask")==0) {
    	mask = value;
          } else if (strcasecmp(varname,"bsub")==0) {
    	bsub = value;
          } else if (strcasecmp(varname,"slot")==0) {
    	slot = value;
          }
          if(nsubadd == 96) {
    	model = 1877;
          } else if (nsubadd == 64) {
    	if(bsub == 16) {
    	  model = 1872;
    	} else if(bsub == 17) {
    	  model = 1881;
    	} else {
    	  model = 0;
    	}
          } else {
    	model = 0;
          }
        } else {			// Assume channel definition
          TString values(line.c_str());
          TObjArray *vararr = values.Tokenize(",");
          Int_t nvals = vararr->GetLast()+1;
          if(nvals<3 || nvals>4) {
    	if(nvals > 1) {	// Silent for help, noecho, nodebug, override
    	  cout << "Map file: Invalid value count: " << line << endl;
    	}
    	continue;
          }
          Int_t channel = ((TObjString*)vararr->At(0))->GetString().Atoi();
          Int_t plane = ((TObjString*)vararr->At(1))->GetString().Atoi();
          Int_t counter = ((TObjString*)vararr->At(2))->GetString().Atoi();
          Int_t signal = 0;
          if(nvals==4) {
    	signal= ((TObjString*)vararr->At(3))->GetString().Atoi();
          }
    
          fTable[fNchans].roc=roc;
          fTable[fNchans].slot=slot;
          fTable[fNchans].channel=channel;
          fTable[fNchans].did=detector;
          fTable[fNchans].plane=plane;
          fTable[fNchans].counter=counter;
          fTable[fNchans].signal=signal;
          fTable[fNchans].model=model;
    
          fNchans++;
        }
      }
    
      cout << endl << "   Detector ID Map" << endl << endl;
      for(Int_t i=0; i < fNIDs; i++) {
        cout << i << " ";
        cout << fIDMap[i].name << " " << fIDMap[i].id << endl;
      }
      cout << endl;