QwAnalysis
QwMollerDetector.cc
Go to the documentation of this file.
1 /**
2  * \file QwMollerDetector.cc
3  *
4  * \brief Implementation of the analysis of Moller data
5  *
6  * \author Andrew Kubera
7  * \date 2010-06-07
8  * \ingroup QwMoller
9  *
10  *
11  */
12 
13 #include "QwMollerDetector.h"
14 
15 // System headers
16 #include <stdexcept>
17 #include <iomanip>
18 
19 // Qweak headers
20 #include "QwLog.h"
21 #include "QwParameterFile.h"
22 #include "QwScaler_Channel.h"
23 
24 // Register this subsystem with the factory
26 
27 /**
28  * Load the channel map
29  * @param mapfile Map file
30  * @return Zero if successful
31  */
32 
33 Int_t QwMollerDetector::LoadChannelMap(TString mapfile)
34 {
35  TString varname, varvalue;
36  TString modtype, dettype, name, keyword;
37  Int_t modnum, channum;
38  Int_t currentrocread = 0;
39  Int_t currentbankread = 0;
40  Int_t wordsofar = 0;
41  Int_t currentsubbankindex = -1;
42 
43  QwParameterFile mapstr(mapfile.Data()); // Open the file
44  fDetectorMapsNames.push_back(mapstr.GetParamFilename());
45  while (mapstr.ReadNextLine()) {
46  mapstr.TrimComment('!'); // Remove everything after a '!' character.
47  mapstr.TrimWhitespace(); // Get rid of leading and trailing whitespace (spaces or tabs).
48  if (mapstr.LineIsEmpty()) continue;
49 
50  if (mapstr.HasVariablePair("=", varname, varvalue)) {
51  // This is a declaration line. Decode it.
52 
53  varname.ToLower();
54  UInt_t value = QwParameterFile::GetUInt(varvalue);
55  if (varname == "roc") {
56  currentrocread=value;
57  RegisterROCNumber(value,0);
58  } else if (varname == "bank") {
59  currentbankread=value;
60  RegisterSubbank(value);
61  if(currentsubbankindex != GetSubbankIndex(currentrocread,currentbankread)){
62  currentsubbankindex = GetSubbankIndex(currentrocread,currentbankread);
63  }
64  }
65  } else {
66  Bool_t lineok = kTRUE;
67 
68  // Break this line into tokens to process it.
69  modtype = mapstr.GetTypedNextToken<TString>();
70  modnum = mapstr.GetTypedNextToken<Int_t>();
71  channum = mapstr.GetTypedNextToken<Int_t>();
72  dettype = mapstr.GetTypedNextToken<TString>();
73  name = mapstr.GetTypedNextToken<TString>();
74  dettype.ToLower();
75  name.ToLower();
76 
77  QwMollerChannelID newChannelID;
78  newChannelID.fModuleType = modtype;
79  newChannelID.fModuleNumber = modnum;
80  newChannelID.fChannelName = name;
81  newChannelID.fDetectorType = dettype;
82  newChannelID.fChannelNumber = channum;
83  newChannelID.fWordInSubbank = wordsofar;
84 
85  if (modtype == "SIS3801"){
86  wordsofar += 1;
87  }else if(modtype == "SIS7200"){
88  wordsofar += 1;
89  }else if(modtype == "VQWK"){
90  wordsofar += 6;
91  }else {
92  std::cerr << "Unknown module type: " << modtype << ". Skipping channel " << name << '.' << std::endl;
93  lineok = kFALSE;
94  }
95 
96  if (name.Length() == 0){
97  lineok = kFALSE;
98  }
99 
100 // add new modules until current number (modnum) is reached
101  std::size_t chan_size;
102  chan_size = fSTR7200_Channel.size();
103  while ((Int_t) chan_size <= modnum) {
104  std::vector<QwSTR7200_Channel> new_module;
105  fSTR7200_Channel.push_back(new_module);
106  }
107 
108  //change this line if names are supposed to be exclusive, as of now,
109  newChannelID.fIndex = -1; // GetChannelIndex(name, modnum);
110 
111  if (newChannelID.fIndex == -1 && lineok){
112  QwSTR7200_Channel localSTR7200_Channel(newChannelID.fChannelName);
113  fSTR7200_Channel[modnum].push_back(localSTR7200_Channel);
114 // fSTR7200_Channel[modnum][fMollerChannelID.size() - 1].SetDefaultSampleSize(fSample_size);
115  newChannelID.fIndex = fSTR7200_Channel[modnum].size() - 1;
116  //std::cout << name << ':' << newChannelID.fIndex << ':' << wordsofar << '\n';
117  }
118 
119  // Push a new record into the element array
120  if(lineok){
121  fMollerChannelID.push_back(newChannelID);
122  }
123  }
124  } // end looping over parameter file
125 
127 
128 // for (size_t i = 0; i < fMollerChannelID.size(); i++){
129 // std::cout << i << ": " << fMollerChannelID[i].fChannelName << ' ' << fMollerChannelID[i].fChannelNumber << ' ' << fMollerChannelID[i].fIndex << std::endl;
130 // }
131 
132  return 0;
133 }
134 
136 Int_t QwMollerDetector::LoadInputParameters(TString){ return 0;}
138 
139 
140 Int_t QwMollerDetector::ProcessConfigurationBuffer(UInt_t, UInt_t, UInt_t*, UInt_t){
141  return 0;
142 }
143 
144 Int_t QwMollerDetector::ProcessConfigurationBuffer(UInt_t ev_type, UInt_t, UInt_t, UInt_t*, UInt_t)
145 {
146  return 0;
147 }
148 
149 Int_t QwMollerDetector::ProcessEvBuffer(UInt_t ev_type, UInt_t roc_id, UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
150 {
151  return ProcessEvBuffer(roc_id, bank_id, buffer, num_words);
152 }
153 
154 Int_t QwMollerDetector::ProcessEvBuffer(UInt_t roc_id, UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
155 {
156  Int_t index = 0; // GetSubbankIndex(roc_id, bank_id);
157 
158  if (index >= 0 && num_words > 0){
159  //we want to process this ROC
160 
161  //Loop through all the channels as defined in map file.. should be 96 in standard 3 module, 32 channel Moller configuration
162  for(size_t i = 0; i < fMollerChannelID.size(); i++){
163 
164  Int_t wordsLeft = num_words - fMollerChannelID[i].fWordInSubbank;
165 
166 // std::cout << std::dec << fMollerChannelID[i].fChannelName << ' ' << fMollerChannelID[i].fIndex << " in module " << fMollerChannelID[i].fModuleNumber << " has data " << std::hex << buffer[fMollerChannelID[i].fWordInSubbank] << std::dec << std::endl;
167 
168  UInt_t mod_index = fMollerChannelID[i].fModuleNumber;
169  Int_t chan_index = fMollerChannelID[i].fIndex;
170 // char *junk = new char[2];
171  if (mod_index < fSTR7200_Channel.size()) {
172  //mod_index should be less than 3, next_module is reference to vector where the Channel should be located
173  // std::cout << std::hex << buffer[fMollerChannelID[i].fWordInSubbank] << '\n';
174  //std::cin.getline(junk, 1);
175 // std::cout << '(' << mod_index << ',' << chan_index << ')' << buffer[fMollerChannelID[i].fWordInSubbank] - fSTR7200_Channel[mod_index][chan_index].GetValue() << ' ' << std::endl;
176 
177  fSTR7200_Channel[mod_index][chan_index].ProcessEvBuffer(&(buffer[fMollerChannelID[i].fWordInSubbank]), wordsLeft);
178  } else {
179  std::cout << "Problem reading buffer, incorrect structure of map file?" << std::endl;
180  }
181 
182  }
183  }
184 // std::cout << fSTR7200_Channel[2][0].GetValue() << std::endl;
185 // print();
186  return 0;
187 }
188 
189 
190 
192 {
193  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
194  for(size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
195  fSTR7200_Channel[i][j].ProcessEvent();
196  QwSTR7200_Channel tempscaler(fSTR7200_Channel[i][j]);
197  tempscaler = fSTR7200_Channel[i][j];
199  fPrevious_STR7200_Channel[i][j] = tempscaler;
200  // Store a temproary copy of this channel's raw value as a scaler channel
201  // Subtract the corresponding fPrevious_STR7200_Channel from this scaler channel
202  // Put the temprary copy into the fPrevious_STR7200_Channel
203  }
204  }
205 }
206 
207 
208 void QwMollerDetector::ConstructHistograms(TDirectory* folder, TString& prefix){
209  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
210  for(size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
211  fSTR7200_Channel[i][j].ConstructHistograms(folder, prefix);
212  }
213  }
214 }
215 
217  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
218  for(size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
219  fSTR7200_Channel[i][j].FillHistograms();
220  }
221  }
222 }
223 
224 void QwMollerDetector::ConstructBranchAndVector(TTree *tree, TString & prefix, std::vector <Double_t> &values){
225  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
226  for(size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
227  fSTR7200_Channel[i][j].ConstructBranchAndVector(tree, prefix, values);
228  }
229  }
230 }
231 
232 void QwMollerDetector::FillTreeVector(std::vector<Double_t> &values) const {
233  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
234  for(size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
235  fSTR7200_Channel[i][j].FillTreeVector(values);
236  }
237  }
238 }
239 
241  // std::cout << "QwMollerDetector assignment (operator=)" << std::endl;
242  if(Compare(value)){
243  //VQwSubsystem::operator=(value);
244  QwMollerDetector* input = dynamic_cast<QwMollerDetector *> (value);
245  for(size_t i = 0; i < input->fSTR7200_Channel.size(); i++){
246  for(size_t j = 0; j < input->fSTR7200_Channel[i].size(); j++){
247  this->fSTR7200_Channel[i][j] = input->fSTR7200_Channel[i][j];
248  }
249  }
250  }
251  return *this;
252 }
253 
255  //std::cout << "QwMollerDetector addition assignment (operator+=)" << std::endl;
256  if(Compare(value)){
257  QwMollerDetector* input = dynamic_cast<QwMollerDetector *> (value);
258  for(size_t i = 0; i < input->fSTR7200_Channel.size(); i++){
259  for(size_t j = 0; j < input->fSTR7200_Channel[i].size(); j++){
260  this->fSTR7200_Channel[i][j] += input->fSTR7200_Channel[i][j];
261  //std::cout << "+= " << this->fSTR7200_Channel[i][j].GetValue() << std::endl;
262  }
263  }
264  }
265  return *this;
266 }
267 
269  //std::cout << "QwMollerDetector subtraction assignment (operator-=)" << std::endl;
270  if(Compare(value)){
271  QwMollerDetector* input = dynamic_cast<QwMollerDetector *> (value);
272  for(size_t i = 0; i < input->fSTR7200_Channel.size(); i++){
273  for(size_t j = 0; j < input->fSTR7200_Channel[i].size(); j++){
274  this->fSTR7200_Channel[i][j] -= input->fSTR7200_Channel[i][j];
275  }
276  }
277  }
278  return *this;
279 }
280 
282  if (Compare(value1) && Compare(value2)) {
283  *this = value1;
284  *this += value2;
285  }
286 }
287 
289  if (Compare(value1) && Compare(value2)) {
290  *this = value1;
291  *this -= value2;
292  }
293 }
294 
296  if (Compare(value1) && Compare(value2)) {
297  QwMollerDetector* v1 = dynamic_cast<QwMollerDetector *> (value1);
298  QwMollerDetector* v2 = dynamic_cast<QwMollerDetector *> (value2);
299 
300  for(size_t i = 0; i < v1->fSTR7200_Channel.size(); i++){
301  for(size_t j = 0; j < v1->fSTR7200_Channel[i].size(); j++){
302  fSTR7200_Channel[i][j].Ratio(v1->fSTR7200_Channel[i][j],v2->fSTR7200_Channel[i][j]);
303  }
304  }
305  }
306  return;
307 }
308 
309 void QwMollerDetector::Scale(Double_t factor){
310  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
311  for(size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
312  fSTR7200_Channel[i][j].Scale(factor);
313  }
314  }
315 }
316 
318  if (Compare(value)) {
319  QwMollerDetector* v = dynamic_cast<QwMollerDetector*>(value);
320 
321  for (size_t i = 0; i < fSTR7200_Channel.size(); i++){
322  for (size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
323  fSTR7200_Channel[i][j].AccumulateRunningSum(v->fSTR7200_Channel[i][j]);
324  }
325  }
326 
327  }
328 }
329 
331  for (size_t i = 0; i < fSTR7200_Channel.size(); i++){
332  for (size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
333  fSTR7200_Channel[i][j].CalculateRunningAverage();
334  }
335  }
336 }
337 
338 Int_t QwMollerDetector::LoadEventCuts(TString filename){return 0;}
339 
341  std::cout << "QwMoller::ApplySingleEventCuts() ";
342  Bool_t test = kTRUE, test_1 = kTRUE;
343 
344  for (size_t i = 0; i < fSTR7200_Channel.size(); i++){
345  for (size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
346  test_1 = fSTR7200_Channel[i][j].ApplySingleEventCuts();
347  test &= test_1;
348  if(!test_1 && bDEBUG){
349  std::cout << "***** QwMoller::SingleEventCuts()->Channel[" << i << "][" << j << "]:" << fSTR7200_Channel[i][j].GetElementName() << std::endl;
350  }
351  }
352  }
353  return test;
354 }
355 
357  std::cout << "***************QwMoller Error Summary****************" << std::endl;
358  for (size_t i = 0; i < fSTR7200_Channel.size(); i++){
359  for (size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
360  fSTR7200_Channel[i][j].PrintErrorCounters();
361  }
362  }
363  std::cout << "total failed events: " << fQwMollerErrorCount << std::endl;
364  std::cout << "************End QwMoller Error Summary***************" << std::endl;
365 }
366 
368  return 0;
369 }
370 
372  size_t len = 0;
373  for (size_t i = 0; i < fSTR7200_Channel.size(); i++){
374  for (size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
375  len++;
376  }
377  }
378  float *result = new float[len];
379 
380  //float result[96];
381 
382  int n = 0;
383  for (size_t i = 0; i < fSTR7200_Channel.size(); i++){
384  for (size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
385  result[n+j] = fSTR7200_Channel[i][j].GetValue();
386  }
387  n=fSTR7200_Channel[i].size();
388  }
389 
390  return result;
391 }
392 
393 Int_t QwMollerDetector::GetChannelIndex(TString channelName, UInt_t module_number)
394 {
395  Bool_t ldebug=kFALSE;
396 
397  channelName.ToLower();
398 
399  if (ldebug){
400  std::cout << "QwMollerDetector::GetDetectorIndex" << std::endl;
401  std::cout << "module_number: " << module_number << " name=" << channelName << std::endl;
402  }
403 
404  Int_t result = -1;
405  for(size_t i = 0; i < fMollerChannelID.size(); i++){
406  QwMollerChannelID *nextChannel = &fMollerChannelID[i];
407  //std::cout << ' '<< nextChannel->fChannelName << '=' << channelName << ':' << (nextChannel->fChannelName == channelName) << std::endl;
408  if (nextChannel->fChannelName == channelName && nextChannel->fModuleNumber == module_number){
409  result = nextChannel->fIndex;
410  break;
411  }
412  }
413 
414  return result;
415 }
416 
417 
419  //std::cout << "Beginning QwMollerDetector::Compare" << std::endl;
420 
421  if (source == 0) return kFALSE;
422 
423  Bool_t result = kTRUE;
424  if(typeid(*source) != typeid(*this)){
425  result = kFALSE;
426  std::cout << " Type mismatch! This is bypassed for now but should be fixed eventually." << std::endl;
427  } else { //same type, test for # of modules
428  QwMollerDetector* input = dynamic_cast<QwMollerDetector*>(source);
429  if(input->fSTR7200_Channel.size() != fSTR7200_Channel.size()){
430  result = kFALSE;
431  std::cout << " Not the same number of Modules" << std::endl;
432  }else { //same # modules, loop through and make sure each one has same amount of channels
433  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
434  if(input->fSTR7200_Channel[i].size() != fSTR7200_Channel[i].size()){
435  result = kFALSE;
436  std::cout << " Different number of channels in module " << i << std::endl;
437  }
438  }
439  }
440  }
441  return result;
442 }
443 
445  std::cout << " " << fSTR7200_Channel.size() << std::endl;
446  UInt_t max = 0;
447  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
448  UInt_t next = fSTR7200_Channel[i].size();
449  if (next > max){
450  max = next;
451  }
452  }
453 
454  for(size_t i = 0; i < max; i++){
455  std::cout << fMollerChannelID[i].fChannelName << ":\t" << (fMollerChannelID[i].fChannelName.Length() < 14 ? "\t" : "");
456  for(size_t j = 0; j < fSTR7200_Channel.size(); j++){
457 
458  if ( i < fSTR7200_Channel[j].size()){
459  std::cout << "0x" << std::hex << (int)fSTR7200_Channel[j][i].GetValue() << std::dec;
460  } else {
461  std::cout << " ";
462  }
463  std::cout << "\t\t";
464  }
465  std::cout << std::endl;
466  }
467 
468 }
469 
471  for(size_t i = 0; i < fSTR7200_Channel.size(); i++){
472  for(size_t j = 0; j < fSTR7200_Channel[i].size(); j++){
473  fSTR7200_Channel[i][j].PrintValue();
474  }
475  }
476 }
Int_t GetSubbankIndex() const
Definition: VQwSubsystem.h:303
Bool_t ApplySingleEventCuts()
Apply the single event cuts.
Bool_t Compare(VQwSubsystem *source)
void ProcessOptions(QwOptions &options)
Process the command line options.
VQwSubsystem & operator-=(VQwSubsystem *value)
VQwSubsystem & operator+=(VQwSubsystem *value)
void Ratio(VQwSubsystem *value1, VQwSubsystem *value2)
An options class.
Definition: QwOptions.h:133
Int_t LoadChannelMap(TString mapfile)
static UInt_t GetUInt(const TString &varvalue)
float * GetRawChannelArray()
void FillTreeVector(std::vector< Double_t > &values) const
Fill the tree vector.
class QwScaler_Channel< 0xffffffff, 0 > QwSTR7200_Channel
void Sum(VQwSubsystem *value1, VQwSubsystem *value2)
void AccumulateRunningSum(VQwSubsystem *value)
Update the running sums for devices.
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
Definition: VQwSubsystem.h:209
static const Bool_t bDEBUG
void FillHistograms()
Fill the histograms for this subsystem.
A logfile class, based on an identical class in the Hermes analyzer.
void PrintErrorCounters() const
Report the number of events failed due to HW and event cut failures.
Int_t LoadEventCuts(TString &filename)
Int_t GetChannelIndex(TString channelName, UInt_t module_number)
VQwSubsystem & operator=(VQwSubsystem *value)
Assignment Note: Must be called at the beginning of all subsystems routine call to operator=(VQwSubsy...
UInt_t GetEventcutErrorFlag()
Return the error flag to the top level routines related to stability checks and ErrorFlag updates...
Int_t ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
std::vector< std::vector< QwSTR7200_Channel > > fSTR7200_Channel
The pure virtual base class of all subsystems.
Definition: VQwSubsystem.h:59
Implementation of the analysis of Moller data (copied from QwComptonElectronDetector.h)
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.
void Scale(Double_t)
std::vector< QwMollerChannelID > fMollerChannelID
void Difference(VQwSubsystem *value1, VQwSubsystem *value2)
std::vector< TString > fDetectorMapsNames
Definition: VQwSubsystem.h:321
std::vector< std::vector< QwSTR7200_Channel > > fPrevious_STR7200_Channel
void ConstructBranchAndVector(TTree *, TString &, std::vector< double, std::allocator< double > > &)
void CalculateRunningAverage()
Calculate the average for all good events.
void PrintValue() const
Print values of all channels.
Int_t ProcessEvBuffer(UInt_t roc_id, UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
TODO: The non-event-type-aware ProcessEvBuffer routine should be replaced with the event-type-aware v...
Int_t LoadInputParameters(TString pedestalfile)
Mandatory parameter file definition.
#define RegisterSubsystemFactory(A)
Definition: QwFactory.h:230