Newer
Older
//*-- Author: Stephen Wood
//////////////////////////////////////////////////////////////////////////
//
// THcDetectorMap
//
// Class to read and Hall C style detector map
// FillMap method builds a map for a specific detector
//
//////////////////////////////////////////////////////////////////////////
#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)
{
// Build a DAQ hardware to detector element map for detector detectorname
// Reads through the entire list of mappings, adding one element to
// detmap for each electronics channel that maps to detectorname.
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;
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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) {
if(mlist.empty()) {
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
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)
{
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// Load a Hall C ENGINE style detector map file. The map file maps
// a given roc, slot/module, and channel # into a given detector id#, plane
// number, counter number and signal type. The mapping between detector
// names and ids is found in the comments at the begging of the map file.
// This method looks for those comments, of the form:
// XXX_ID = n
// to establish that mapping between detector name and detector ID.
//
// Lines of the form
// DETECTOR = n
// ROC = n
// SLOT = n
// are used to establish the module (roc and slot) and the detector
// for the mapping lines that follow.
// The actual mappings are of the form
// subadd, plane, counter [, signal]
// Each of these lines, combined with the detector, roc, slot values
// establish the roc, slot, subadess -> detector, plane, counter#, sigtype map
// Other lines that may be in the map file are
// NSUBADD = n
// BSUB = n
// MASK = hex value
// These define characteristics of the electronics module (# channels,
// The bit number specifying the location of the subaddress in a data word
// and hex mask that the data word is anded with to retrieve data)
static const char* const whtspc = " \t";
ifstream ifile;
ifile.open(fname);
if(!ifile.is_open()) {
static const char* const here = "THcDetectorMap::Load";
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 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());
}
}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
// 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 not used here
//mask = value;
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
} 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();
}
delete vararr; // Discard result of Tokenize
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 << fIDMap[i].name << " " << fIDMap[i].id << endl;
}
cout << endl;