QwAnalysis
QwScaler.cc
Go to the documentation of this file.
1 //
2 // C++ Implementation: QwScaler
3 //
4 // Description: used to collect and process the information from the scaler channel
5 
6 #include "QwScaler.h"
7 
8 // Qweak headers
9 #include "QwParameterFile.h"
10 
11 // Register this subsystem with the factory
13 
14 
16 {
17  // Define command line options
18 }
19 
21 {
22  // Handle command line options
23 }
24 
25 
26 /**
27  * Constructor
28  */
29 QwScaler::QwScaler(const TString& name)
30 : VQwSubsystem(name),VQwSubsystemParity(name)
31 {
32  // Nothing, really
33 }
34 
35 /**
36  * Destructor
37  *
38  * Delete histograms and clean up scaler channel objects
39  */
41 {
42  // Delete scalers
43  for (size_t i = 0; i < fScaler.size(); i++) {
44  delete fScaler.at(i);
45  }
46  fScaler.clear();
47 }
48 
49 
50 /**
51  * Load the channel map
52  * @param mapfile Map file
53  * @return Zero if successful
54  */
55 Int_t QwScaler::LoadChannelMap(TString mapfile)
56 {
57  Int_t current_roc_id = -1; // current ROC id
58  Int_t current_bank_id = -1; // current bank id
59 
60  // Normalization channel (register default token "1")
61  const TString default_norm_channel = "1";
62  fName_Map[default_norm_channel] = -1;
63  Name_to_Scaler_Map_t::iterator current_norm_channel = fName_Map.find(default_norm_channel);
64  double current_norm_factor = 1;
65  // Map with normalizations
66  std::vector<Name_to_Scaler_Map_t::iterator> norm_channel;
67  std::vector<double> norm_factor;
68 
69  // Include header for this scaler bank
70  UInt_t header = 1;
71 
72  // By default the scalers are not differential
73  Bool_t differential = false;
74 
75  // Open the file
76  QwParameterFile mapstr(mapfile.Data());
77  fDetectorMaps.insert(mapstr.GetParamFileNameContents());
78  while (mapstr.ReadNextLine()) {
79  mapstr.TrimComment(); // Remove everything after a comment character.
80  mapstr.TrimWhitespace(); // Get rid of leading and trailing whitespace
81  if (mapstr.LineIsEmpty()) continue;
82 
83  TString varname, varvalue;
84  if (mapstr.HasVariablePair("=", varname, varvalue)) {
85  // This is a declaration line. Decode it.
86  varname.ToLower();
87  UInt_t value = QwParameterFile::GetUInt(varvalue);
88  if (varname == "roc") {
89  current_roc_id = value;
90  RegisterROCNumber(current_roc_id,0);
91  } else if (varname == "bank") {
92  current_bank_id = value;
93  RegisterSubbank(current_bank_id);
94  } else if (varname == "norm") {
95  // Normalization line of format: norm = [ 1 | channel / factor ]
96  string dummy = mapstr.GetNextToken("=");
97  string channame = mapstr.GetNextToken("/");
98  string channorm = mapstr.GetNextToken("/");
99  if (fName_Map.count(channame) == 0) {
100  // assign a temporarily pointer
101  fName_Map[channame] = -1;
102  }
103  current_norm_channel = fName_Map.find(channame);
104  try {
105  current_norm_factor = lexical_cast<double>(channorm);
106  } catch (boost::bad_lexical_cast&) {
107  current_norm_factor = 1;
108  }
109  QwMessage << "Normalization channel: " << channame << QwLog::endl;
110  QwMessage << "Normalization factor: " << current_norm_factor << QwLog::endl;
111  } else if (varname == "header") {
112  // Header for this block of channels
113  header = value;
114  QwMessage << "Number of scaler header words: " << header << QwLog::endl;
115  if (header > 32)
116  QwError << "Is that really what you want?" << QwLog::endl;
117  } else if (varname == "differential") {
118  // Differential scaler
119  try {
120  differential = lexical_cast<bool>(varvalue);
121  } catch (boost::bad_lexical_cast&) {
122  differential = false;
123  }
124  if (differential)
125  QwMessage << "Subsequent scalers will be differential." << QwLog::endl;
126  else
127  QwMessage << "Subsequent scalers will not be differential." << QwLog::endl;
128  }
129 
130  } else {
131 
132  // Break this line into tokens to process it.
133  TString modtype = mapstr.GetTypedNextToken<TString>();
134  UInt_t modnum = mapstr.GetTypedNextToken<UInt_t>();
135  UInt_t channum = mapstr.GetTypedNextToken<UInt_t>();
136  TString dettype = mapstr.GetTypedNextToken<TString>();
137  TString keyword = mapstr.GetTypedNextToken<TString>();
138  modtype.ToUpper();
139  dettype.ToUpper();
140 
141  UInt_t offset = 0;
142  if (modtype == "SIS3801" || modtype == "SIS3801D24" || modtype == "SIS3801D32") {
143  offset = QwSIS3801D24_Channel::GetBufferOffset(modnum, channum, header);
144  } else if (modtype == "STR7200") {
145  offset = QwSIS3801D32_Channel::GetBufferOffset(modnum, channum, header);
146  } else {
147  QwError << "Unrecognized module type " << modtype << QwLog::endl;
148  continue;
149  }
150 
151  // Register data channel type
152  Int_t subbank = GetSubbankIndex(current_roc_id,current_bank_id);
153  if (modnum >= fSubbank_Map[subbank].size())
154  fSubbank_Map[subbank].resize(modnum+1);
155  if (channum >= fSubbank_Map[subbank].at(modnum).size())
156  fSubbank_Map[subbank].at(modnum).resize(channum+1,-1);
157  // Add scaler channel
158  if (fSubbank_Map[subbank].at(modnum).at(channum) < 0) {
159  QwVerbose << "Registering " << modtype << " " << keyword
160  << std::hex
161  << " in ROC 0x" << current_roc_id << ", bank 0x" << current_bank_id
162  << std::dec
163  << " at mod " << modnum << ", chan " << channum
164  << QwLog::endl;
165  size_t index = fScaler.size();
166  VQwScaler_Channel* scaler = 0;
167  if (modtype == "SIS3801" || modtype == "SIS3801D24")
168  scaler = new QwSIS3801D24_Channel(keyword);
169  else if (modtype == "SIS3801D32")
170  scaler = new QwSIS3801D32_Channel(keyword);
171  else if (modtype == "STR7200")
172  scaler = new QwSTR7200_Channel(keyword);
173  else {
174  QwError << "Unrecognized module type " << modtype << QwLog::endl;
175  continue;
176  }
177 
178  // Differential scaler
179  scaler->SetDifferentialScaler(differential);
180 
181  // Register keyword to scaler channel
182  fName_Map[keyword] = index;
183  fSubbank_Map[subbank].at(modnum).at(channum) = index;
184  fModuleChannel_Map[std::pair<Int_t,Int_t>(modnum,channum)] = index;
185  // Store scaler
186  fScaler.push_back(scaler);
187  fNorm.push_back(std::pair<VQwScaler_Channel*,double>((VQwScaler_Channel*)0,1));
188  fBufferOffset.push_back(offset);
189  // Store current normalization
190  norm_channel.push_back(current_norm_channel);
191  norm_factor.push_back(current_norm_factor);
192  }
193  }
194  }
195 
196  // Check for normalization names without actual channels
197  for (Name_to_Scaler_Map_t::iterator iter = fName_Map.begin(); iter != fName_Map.end(); iter++) {
198  if (iter->second == -1 && iter->first != default_norm_channel) {
199  QwError << "Normalization channel " << iter->first << " not found!" << QwLog::endl;
200  }
201  }
202 
203  // Fill normalization structure
204  fNorm.resize(fScaler.size());
205  for (size_t i = 0; i < fScaler.size(); i++) {
206  Int_t norm_index = norm_channel.at(i)->second;
207  if (norm_index < 0) {
208  // No normalization
209  fNorm.at(i).first = 0;
210  fNorm.at(i).second = 1;
211  } else {
212  // Normalization
213  fNorm.at(i).first = fScaler.at(norm_index);
214  fNorm.at(i).second = norm_factor.at(i);
215  // Prevent corruption of normalization channel itself
216  fNorm.at(norm_index).first = 0;
217  fNorm.at(norm_index).second = 1;
218  }
219  }
220 
221  mapstr.Close(); // Close the file (ifstream)
222  return 0;
223 }
224 
225 Int_t QwScaler::LoadInputParameters(TString mapfile)
226 {
227  // Open the file
228  QwParameterFile mapstr(mapfile.Data());
229  fDetectorMaps.insert(mapstr.GetParamFileNameContents());
230  while (mapstr.ReadNextLine()) {
231  mapstr.TrimComment(); // Remove everything after a comment character
232  mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces
233  if (mapstr.LineIsEmpty()) continue;
234 
235  TString varname = mapstr.GetTypedNextToken<TString>(); // name of the channel
236  varname.ToLower();
237  varname.Remove(TString::kBoth,' ');
238  Double_t varped = mapstr.GetTypedNextToken<Double_t>(); // value of the pedestal
239  Double_t varcal = mapstr.GetTypedNextToken<Double_t>(); // value of the calibration factor
240  QwVerbose << varname << ": " << QwLog::endl;
241 
242  if (fName_Map.count(varname) != 0) {
243  Int_t index = fName_Map[varname];
244  QwMessage << "Parameters scaler channel " << varname << ": "
245  << "ped = " << varped << ", "
246  << "cal = " << varcal << QwLog::endl;
247  fScaler[index]->SetPedestal(varped);
248  fScaler[index]->SetCalibrationFactor(varcal);
249  }
250 
251  } // end of loop reading all lines of the pedestal file
252 
253  mapstr.Close(); // Close the file (ifstream)
254  return 0;
255 }
256 
257 /**
258  * Clear the event data in this subsystem
259  */
261 {
262  // Clear all scaler channels
263  for (size_t i = 0; i < fScaler.size(); i++) {
264  fScaler.at(i)->ClearEventData();
265  }
266  // Reset good event count
267  fGoodEventCount = 0;
268 }
269 
270 /**
271  * Process the configuration buffer for this subsystem
272  * @param roc_id ROC ID
273  * @param bank_id Subbank ID
274  * @param buffer Buffer to read from
275  * @param num_words Number of words left in buffer
276  * @return Number of words read
277  */
278 Int_t QwScaler::ProcessConfigurationBuffer(UInt_t roc_id, UInt_t bank_id, UInt_t* buffer, UInt_t num_words)
279 {
280  return 0;
281 }
282 
283 /**
284  * Process the event buffer for this subsystem
285  * @param roc_id ROC ID
286  * @param bank_id Subbank ID
287  * @param buffer Buffer to read from
288  * @param num_words Number of words left in buffer
289  * @return Number of words read
290  */
291 Int_t QwScaler::ProcessEvBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t* buffer, UInt_t num_words)
292 {
293  // TODO fix :-)
294 
295  UInt_t words_read = 0;
296 
297  // Get the subbank index (or -1 when no match)
298  Int_t subbank = GetSubbankIndex(roc_id, bank_id);
299 
300  if (subbank >= 0 && num_words > 0) {
301 
302  // Read header word
303  //UInt_t num_events = buffer[words_read];
304  words_read++;
305  // TODO Multiscaler functionality
306 
307  // Read scalers
308  for (size_t modnum = 0; modnum < fSubbank_Map[subbank].size(); modnum++) {
309  for (size_t channum = 0; channum < fSubbank_Map[subbank].at(modnum).size(); channum++) {
310  Int_t index = fSubbank_Map[subbank].at(modnum).at(channum);
311  if (index >= 0) {
312  UInt_t offset = fBufferOffset.at(index);
313  words_read += fScaler[index]->ProcessEvBuffer(&(buffer[offset]), num_words - offset);
314  }
315  }
316  }
317  words_read = num_words;
318 
319  }
320 
321  return words_read;
322 }
323 
325 {
326  // Process the event
327  for (size_t i = 0; i < fScaler.size(); i++) {
328  fScaler.at(i)->ProcessEvent();
329  }
330 
331  // Normalization
332  for (size_t i = 0; i < fScaler.size(); i++) {
333  if (fNorm.at(i).first) {
334  fScaler.at(i)->Scale(fNorm.at(i).second);
335  fScaler.at(i)->DivideBy(*(fNorm.at(i).first));
336  }
337  }
338 }
339 
340 void QwScaler::ConstructHistograms(TDirectory* folder, TString& prefix)
341 {
342  for(size_t i = 0; i < fScaler.size(); i++) {
343  fScaler.at(i)->ConstructHistograms(folder, prefix);
344  }
345 }
346 
348 {
349  for(size_t i = 0; i < fScaler.size(); i++) {
350  fScaler.at(i)->FillHistograms();
351  }
352 }
353 
354 void QwScaler::ConstructBranchAndVector(TTree *tree, TString & prefix, std::vector <Double_t> &values)
355 {
356  for (size_t i = 0; i < fScaler.size(); i++) {
357  fScaler.at(i)->ConstructBranchAndVector(tree, prefix, values);
358  }
359 }
360 
361 void QwScaler::FillTreeVector(std::vector<Double_t> &values) const
362 {
363  for(size_t i = 0; i < fScaler.size(); i++) {
364  fScaler.at(i)->FillTreeVector(values);
365  }
366 }
367 
368 /**
369  * Assignment operator
370  * @param value Right-hand side
371  * @return Left-hand side
372  */
374 {
375  if (Compare(value)) {
377  QwScaler* input = dynamic_cast<QwScaler*>(value);
378  for (size_t i = 0; i < fScaler.size(); i++) {
379  *(fScaler.at(i)) = *(input->fScaler.at(i));
380  }
381  }
382  return *this;
383 }
384 
385 /**
386  * Addition-assignment operator
387  * @param value Right-hand side
388  * @return Left-hand side
389  */
391 {
392  if (Compare(value)) {
393  QwScaler* input = dynamic_cast<QwScaler*>(value);
394  for (size_t i = 0; i < fScaler.size(); i++) {
395  *(fScaler.at(i)) += *(input->fScaler.at(i));
396  }
397  }
398  return *this;
399 }
400 
401 /**
402  * Subtraction-assignment operator
403  * @param value Right-hand side
404  * @return Left-hand side
405  */
407 {
408  if (Compare(value)) {
409  QwScaler* input = dynamic_cast<QwScaler *> (value);
410  for (size_t i = 0; i < fScaler.size(); i++) {
411  *(fScaler.at(i)) -= *(input->fScaler.at(i));
412  }
413  }
414  return *this;
415 }
416 
417 /**
418  * Summation
419  * @param value1 First value
420  * @param value2 Second value
421  */
423 {
424  if (Compare(value1) && Compare(value2)) {
425  *this = value1;
426  *this += value2;
427  }
428 }
429 
430 /**
431  * Difference
432  * @param value1 First value
433  * @param value2 Second value
434  */
436 {
437  if (Compare(value1) && Compare(value2)) {
438  *this = value1;
439  *this -= value2;
440  }
441 }
442 
443 /**
444  * Determine the ratio of two photon detectors
445  * @param numer Numerator
446  * @param denom Denominator
447  */
449 {
450  if (Compare(numer) && Compare(denom)) {
451  QwScaler* innumer = dynamic_cast<QwScaler*>(numer);
452  QwScaler* indenom = dynamic_cast<QwScaler*>(denom);
453  for (size_t i = 0; i < fScaler.size(); i++) {
454  fScaler.at(i)->Ratio(*(innumer->fScaler.at(i)), *(indenom->fScaler.at(i)));
455  }
456  }
457 }
458 
459 /**
460  * Scale the photon detector
461  * @param factor Scale factor
462  */
463 void QwScaler::Scale(Double_t factor)
464 {
465  for (size_t i = 0; i < fScaler.size(); i++) {
466  fScaler.at(i)->Scale(factor);
467  }
468 }
469 
470 /**
471  * Accumulate the running sum
472  */
474 {
475  if (Compare(value)) {
476  fGoodEventCount++;
477  *this += value;
478  }
479 }
480 
481 /**
482  * Normalize the running sum
483  */
485 {
486  if (fGoodEventCount <= 0) {
487  Scale(0);
488  } else {
489  Scale(1.0/fGoodEventCount);
490  }
491 }
492 
493 Int_t QwScaler::LoadEventCuts(TString filename)
494 {
495  return 0;
496 }
497 
499 {
500  return true;
501 }
502 
504 {
505 }
506 
508 {
509 }
510 
512 {
513  return 0;
514 }
515 
516 Int_t QwScaler::GetChannelIndex(TString channelName, UInt_t module_number)
517 {
518  return 0;
519 }
520 
521 
522 /**
523  * Compare two scaler objects
524  * @param value Object to compare with
525  * @return kTRUE if the object is equal
526  */
528 {
529  // Immediately fail on null objects
530  if (value == 0) return kFALSE;
531 
532  // Continue testing on actual object
533  Bool_t result = kTRUE;
534  if (typeid(*value) != typeid(*this)) {
535  result = kFALSE;
536 
537  } else {
538  QwScaler* input = dynamic_cast<QwScaler*> (value);
539  if (input->fScaler.size() != fScaler.size()) {
540  result = kFALSE;
541  }
542  }
543  return result;
544 }
545 
546 /**
547  * Print some debugging output for the subcomponents
548  */
550 {
552 
553  QwOut << " there are " << fScaler.size() << " scaler channels" << QwLog::endl;
554 
555  for (size_t i = 0; i < fScaler.size(); i++) {
556  QwOut << " scaler " << i << ": ";
557  fScaler.at(i)->PrintInfo();
558  }
559 }
560 
561 /**
562  * Print the value for the subcomponents
563  */
565 {
566  for(size_t i = 0; i < fScaler.size(); i++) {
567  fScaler.at(i)->PrintValue();
568  }
569 }
Bool_t Compare(VQwSubsystem *source)
Definition: QwScaler.cc:527
Int_t GetSubbankIndex() const
Definition: VQwSubsystem.h:303
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
std::map< TString, TString > fDetectorMaps
Definition: VQwSubsystem.h:322
#define QwOut
Predefined log drain for explicit output.
Definition: QwLog.h:35
Int_t LoadChannelMap(TString mapfile)
Definition: QwScaler.cc:55
void FillTreeVector(std::vector< Double_t > &values) const
Fill the tree vector.
Definition: QwScaler.cc:361
void PrintInfo() const
Definition: QwScaler.cc:549
void ProcessEvent()
Definition: QwScaler.cc:324
An options class.
Definition: QwOptions.h:133
static UInt_t GetUInt(const TString &varvalue)
Int_t ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
Definition: QwScaler.cc:278
void PrintErrorCounters() const
Report the number of events failed due to HW and event cut failures.
Definition: QwScaler.cc:507
void ClearEventData()
Definition: QwScaler.cc:260
std::vector< std::pair< VQwScaler_Channel *, double > > fNorm
Definition: QwScaler.h:127
VQwSubsystem & operator=(VQwSubsystem *value)
Definition: QwScaler.cc:373
#define QwVerbose
Predefined log drain for verbose messages.
Definition: QwLog.h:55
Virtual base class for the parity subsystems.
class QwScaler_Channel< 0xffffffff, 0 > QwSTR7200_Channel
Int_t ProcessEvBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
Definition: QwScaler.cc:291
Bool_t ApplySingleEventCuts()
Apply the single event cuts.
Definition: QwScaler.cc:498
Module_Channel_to_Scaler_Map_t fModuleChannel_Map
Definition: QwScaler.h:118
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
Definition: VQwSubsystem.h:209
void FillHistograms()
Fill the histograms for this subsystem.
Definition: QwScaler.cc:347
virtual VQwSubsystem & operator=(VQwSubsystem *value)
Assignment Note: Must be called at the beginning of all subsystems routine call to operator=(VQwSubsy...
Name_to_Scaler_Map_t fName_Map
Definition: QwScaler.h:122
static void DefineOptions()
Define options function (note: no virtual static functions in C++)
Definition: VQwSubsystem.h:88
virtual void SetDifferentialScaler(Bool_t diff)
void IncrementErrorCounters()
Increment the error counters.
Definition: QwScaler.cc:503
VQwSubsystem & operator+=(VQwSubsystem *value)
Definition: QwScaler.cc:390
void PrintValue() const
Definition: QwScaler.cc:564
virtual ~QwScaler()
Destructor.
Definition: QwScaler.cc:40
void CalculateRunningAverage()
Definition: QwScaler.cc:484
virtual void PrintInfo() const
Print some information about the subsystem.
Int_t GetChannelIndex(TString channelName, UInt_t module_number)
Definition: QwScaler.cc:516
UInt_t GetEventcutErrorFlag()
Return the error flag to the top level routines related to stability checks and ErrorFlag updates...
Definition: QwScaler.cc:511
Subbank_to_Scaler_Map_t fSubbank_Map
Definition: QwScaler.h:114
The pure virtual base class of all subsystems.
Definition: VQwSubsystem.h:59
class QwScaler_Channel< 0xffffffff, 0 > QwSIS3801D32_Channel
void Difference(VQwSubsystem *value1, VQwSubsystem *value2)
Definition: QwScaler.cc:435
std::vector< UInt_t > fBufferOffset
Definition: QwScaler.h:126
class QwScaler_Channel< 0x00ffffff, 0 > QwSIS3801D24_Channel
Int_t RegisterSubbank(const UInt_t bank_id)
Tell the object that it will decode data from this sub-bank in the ROC currently open for registratio...
virtual Int_t RegisterROCNumber(const UInt_t roc_id, const UInt_t bank_id=0)
Tell the object that it will decode data from this ROC and sub-bank.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector< Double_t > &values)
Construct the branch and tree vector.
Definition: QwScaler.cc:354
Int_t fGoodEventCount
Definition: QwScaler.h:110
VQwSubsystem & operator-=(VQwSubsystem *value)
Definition: QwScaler.cc:406
void Scale(Double_t factor)
Definition: QwScaler.cc:463
void ProcessOptions(QwOptions &options)
Process the command line options.
Definition: QwScaler.cc:20
void Ratio(VQwSubsystem *value1, VQwSubsystem *value2)
Definition: QwScaler.cc:448
std::vector< VQwScaler_Channel * > fScaler
Definition: QwScaler.h:125
QwScaler()
Private default constructor (not implemented, will throw linker error on use)
Int_t LoadInputParameters(TString pedestalfile)
Mandatory parameter file definition.
Definition: QwScaler.cc:225
void Sum(VQwSubsystem *value1, VQwSubsystem *value2)
Definition: QwScaler.cc:422
#define RegisterSubsystemFactory(A)
Definition: QwFactory.h:230
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40
Int_t LoadEventCuts(TString filename)
Load the event cuts file.
Definition: QwScaler.cc:493
void AccumulateRunningSum(VQwSubsystem *value)
Definition: QwScaler.cc:473