Skip to content
Snippets Groups Projects
THcDetectorMap.cxx 9.06 KiB
Newer Older
//*-- 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;