QwAnalysis
QwComptonPhotonDetector.cc
Go to the documentation of this file.
1 /**
2  * \file QwComptonPhotonDetector.cc
3  *
4  * \brief Implementation of the analysis of Compton photon detector data
5  *
6  * \author W. Deconinck
7  * \date 2009-09-04 18:06:23
8  * \ingroup QwCompton
9  *
10  * The QwComptonPhotonDetector class is defined as a parity subsystem that
11  * contains all data modules of the photon detector (SIS3320, V775, V792).
12  * It reads in a channel map and pedestal file, and defines the histograms
13  * and output trees.
14  *
15  */
16 
18 
19 // System headers
20 #include <stdexcept>
21 
22 // Qweak headers
23 #include "QwLog.h"
24 #include "QwParameterFile.h"
25 
26 
27 // Register this subsystem with the factory
29 
30 
32 {
33  // Define command line options
34 }
35 
37 {
38  // Handle command line options
39 }
40 
41 /**
42  * Load the channel map
43  * @param mapfile Map file
44  * @return Zero if successful
45  */
47 {
48  Int_t subbank = -1; // subbank index
49  Int_t current_roc_id = -1; // current ROC id
50  Int_t current_bank_id = -1; // current bank id
51 
52  Int_t current_logical_accum = 0;
53  std::vector<TString> name;
54  std::vector<std::vector<TString> > accums;
55  std::vector<std::vector<Double_t> > weights;
56 
57  // Open the file
58  QwParameterFile mapstr(mapfile.Data());
59  fDetectorMaps.insert(mapstr.GetParamFileNameContents());
60 
61  while (mapstr.ReadNextLine()) {
62  mapstr.TrimComment(); // Remove everything after a comment character
63  mapstr.TrimWhitespace(); // Get rid of leading and trailing whitespace
64  if (mapstr.LineIsEmpty()) continue;
65 
66  TString varname, varvalue;
67  if (mapstr.HasVariablePair("=",varname,varvalue)) {
68  // This is a declaration line. Decode it.
69  varname.ToLower();
70 
71  if (varname == "roc") {
72  current_roc_id = QwParameterFile::GetUInt(varvalue);
73  RegisterROCNumber(current_roc_id,0);
74 
75  } else if (varname == "bank") {
76  current_bank_id = QwParameterFile::GetUInt(varvalue);
77  RegisterSubbank(current_bank_id);
78  subbank = GetSubbankIndex(current_roc_id,current_bank_id);
79 
80  } else if (varname == "begin") {
81  // Add new logical accumulator
82  name.resize(current_logical_accum+1);
83  accums.resize(current_logical_accum+1);
84  weights.resize(current_logical_accum+1);
85  // Read to end of this block
86  while(mapstr.ReadNextLine()) {
87  mapstr.TrimComment(); // Remove everything after a comment character
88  mapstr.TrimWhitespace(); // Get rid of leading and trailing whitespace
89  if (mapstr.LineIsEmpty()) continue;
90 
91  // Loop over block
92  if (mapstr.HasVariablePair("=",varname,varvalue)) {
93  varname.ToLower();
94  if (varname == "end") {
95  current_logical_accum++;
96  break;
97  } else if (varname == "name") {
98  name[current_logical_accum] = varvalue;
99  }
100  } else {
101  accums[current_logical_accum].push_back(mapstr.GetTypedNextToken<TString>());
102  weights[current_logical_accum].push_back(mapstr.GetTypedNextToken<Double_t>());
103  }
104  }
105  }
106 
107  } else {
108  // Break this line into tokens to process it.
109  TString modtype = mapstr.GetTypedNextToken<TString>();
110  UInt_t modnum = mapstr.GetTypedNextToken<UInt_t>();
111  UInt_t channum = mapstr.GetTypedNextToken<UInt_t>();
112  TString dettype = mapstr.GetTypedNextToken<TString>();
113  TString name = mapstr.GetTypedNextToken<TString>();
114  modtype.ToUpper();
115  dettype.ToUpper();
116 
117  // Push a new record into the element array
118  if (modtype == "SIS3320") {
119  // Register data channel type
120  fMapping[subbank] = kSamplingADC;
121  // Increase module mapping size
122  if (modnum >= fSamplingADC_Mapping[subbank].size())
123  fSamplingADC_Mapping[subbank].resize(modnum+1);
124  // Increase channel mapping size
125  if (channum >= fSamplingADC_Mapping[subbank].at(modnum).size())
126  fSamplingADC_Mapping[subbank].at(modnum).resize(channum+1,-1);
127  // Search whether this module/channel is already registered
128  for (SamplingADC_Mapping_t::iterator iter = fSamplingADC_Mapping.begin();
129  iter != fSamplingADC_Mapping.end(); iter++) {
130  if (iter->first != subbank &&
131  iter->second.size() > modnum &&
132  iter->second.at(modnum).size() > channum &&
133  iter->second.at(modnum).at(channum) >= 0) {
134  QwMessage << "Connecting SIS3320 " << name << "/" << dettype
135  << std::hex
136  << " in ROC 0x" << current_roc_id << ", bank 0x" << current_bank_id
137  << std::dec
138  << " to existing SIS3320." << QwLog::endl;
139  fSamplingADC_Mapping[subbank].at(modnum).at(channum) =
140  iter->second.at(modnum).at(channum);
141  }
142  }
143  // Register new SIS3320
144  if (fSamplingADC_Mapping[subbank].at(modnum).at(channum) < 0) {
145  QwMessage << "Registering SIS3320 " << name << "/" << dettype
146  << std::hex
147  << " in ROC 0x" << current_roc_id << ", bank 0x" << current_bank_id
148  << std::dec
149  << " at mod " << modnum << ", chan " << channum
150  << QwLog::endl;
151  UInt_t index = fSamplingADC.size();
152  fSamplingADC_Mapping[subbank].at(modnum).at(channum) = index;
153  fSamplingADC.push_back(QwSIS3320_Channel(channum, name));
154  fSamplingADC.at(index).SetNumberOfAccumulators(6);
155  fSamplingADC.at(index).InitializeChannel(channum, name);
156  }
157 
158  } else if (modtype == "V792") {
159  // Register data channel type
160  fMapping[subbank] = kIntegratingADC;
161  // Add to mapping
162  if (modnum >= fMultiQDC_Mapping[subbank].size())
163  fMultiQDC_Mapping[subbank].resize(modnum+1);
164  if (channum >= fMultiQDC_Mapping[subbank].at(modnum).size())
165  fMultiQDC_Mapping[subbank].at(modnum).resize(channum+1,-1);
166  // Add scaler channel
167  if (fMultiQDC_Mapping[subbank].at(modnum).at(channum) < 0) {
168  QwMessage << "Registering V792 " << name
169  << std::hex
170  << " in ROC 0x" << current_roc_id << ", bank 0x" << current_bank_id
171  << std::dec
172  << " at mod " << modnum << ", chan " << channum
173  << QwLog::endl;
174  UInt_t index = fMultiQDC_Channel.size();
175  fMultiQDC_Mapping[subbank].at(modnum).at(channum) = index;
176  fMultiQDC_Channel.push_back(QwPMT_Channel(name));
177  fMultiQDC_Channel.at(index).SetModule(modnum);
178  fMultiQDC_Channel.at(index).SetSubbankID(current_bank_id);
179  }
180 
181  } else if (modtype == "V775") {
182  // Register data channel type
183  fMapping[subbank] = kIntegratingTDC;
184  // Add to mapping
185  if (modnum >= fMultiTDC_Mapping[subbank].size())
186  fMultiTDC_Mapping[subbank].resize(modnum+1);
187  if (channum >= fMultiTDC_Mapping[subbank].at(modnum).size())
188  fMultiTDC_Mapping[subbank].at(modnum).resize(channum+1,-1);
189  // Add scaler channel
190  if (fMultiTDC_Mapping[subbank].at(modnum).at(channum) < 0) {
191  QwMessage << "Registering V775 " << name
192  << std::hex
193  << " in ROC 0x" << current_roc_id << ", bank 0x" << current_bank_id
194  << std::dec
195  << " at mod " << modnum << ", chan " << channum
196  << QwLog::endl;
197  UInt_t index = fMultiTDC_Channel.size();
198  fMultiTDC_Mapping[subbank].at(modnum).at(channum) = index;
199  fMultiTDC_Channel.push_back(QwPMT_Channel(name));
200  fMultiTDC_Channel.at(index).SetModule(modnum);
201  fMultiTDC_Channel.at(index).SetSubbankID(current_bank_id);
202  }
203 
204  } // end of switch by modtype
205 
206  } // end of if for token line
207  } // end of while over parameter file
208 
209  // Now create the logical accumulators
210  for (size_t logical = 0; logical < name.size(); logical++) {
211  for (size_t adc = 0; adc < fSamplingADC.size(); adc++) {
212  fSamplingADC[adc].AddLogicalAccumulator(name[logical],accums[logical],weights[logical]);
213  }
214  }
215 
216  return 0;
217 }
218 
219 /**
220  * Load the event cuts
221  * @param filename Event cuts file
222  * @return Zero if successful
223  */
224 Int_t QwComptonPhotonDetector::LoadEventCuts(TString & filename)
225 {
226  return 0;
227 }
228 
229 /**
230  * Load the input parameters
231  * @param pedestalfile Input parameters file
232  * @return Zero if successful
233  */
235 {
236  // Open the file
237  QwParameterFile mapstr(pedestalfile.Data());
238  fDetectorMaps.insert(mapstr.GetParamFileNameContents());
239  while (mapstr.ReadNextLine()) {
240  mapstr.TrimComment(); // Remove everything after a comment character
241  mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces
242 
243  TString varname = "";
244  Double_t varped = 0.0;
245  Double_t varcal = 1.0;
246 
247  if (mapstr.LineIsEmpty()) continue;
248  else {
249  varname = mapstr.GetTypedNextToken<TString>(); // name of the channel
250  varname.ToLower();
251  varname.Remove(TString::kBoth,' ');
252  varped = mapstr.GetTypedNextToken<Double_t>(); // value of the pedestal
253  varcal = mapstr.GetTypedNextToken<Double_t>(); // value of the calibration factor
254  QwVerbose << varname << ": " << QwLog::endl;
255  }
256 
257  Bool_t found = kFALSE;
258  for (size_t i = 0; i < fSamplingADC.size() && !found; i++) {
259  TString localname = fSamplingADC[i].GetElementName();
260  localname.ToLower();
261  if (localname == varname) {
262  QwMessage << "Setting pedestal and calibration of sampling ADC " << localname
263  << " to " << varped << " and " << varcal << "." << QwLog::endl;
264  fSamplingADC[i].SetPedestal(varped);
265  fSamplingADC[i].SetCalibrationFactor(varcal);
266  found = kTRUE;
267  }
268  } // end of loop over all sampling ADC channels
269 
270  } // end of loop reading all lines of the pedestal file
271 
272  return 0;
273 }
274 
275 
276 /**
277  * Randomize this event with the given helicity
278  * @param helicity Helicity of this event (default is zero)
279  */
281 {
282  // Randomize all gQwSIS3320 buffers
283  for (size_t i = 0; i < fSamplingADC.size(); i++)
284  fSamplingADC[i].RandomizeEventData(helicity);
285 
286  // Randomize all MQwV775TDC buffers
287  //for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
288  // fMultiTDC_Channel[i].RandomizeEventData(helicity);
289 
290  // Randomize all MQwV792ADC buffers
291  //for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
292  // fMultiQDC_Channel[i].RandomizeEventData(helicity);
293 }
294 
295 
296 /**
297  * Encode this event into a CODA buffer
298  * @param buffer Buffer to append data to
299  */
300 void QwComptonPhotonDetector::EncodeEventData(std::vector<UInt_t> &buffer)
301 {
302  std::vector<UInt_t> elements;
303  elements.clear();
304 
305  // Get all buffers in the order they are defined in the map file
306  for (size_t i = 0; i < fSamplingADC.size(); i++)
307  fSamplingADC[i].EncodeEventData(elements);
308 
309  // If there is element data, generate the subbank header
310  std::vector<UInt_t> subbankheader;
311  std::vector<UInt_t> rocheader;
312  if (elements.size() > 0) {
313 
314  // Form CODA subbank header
315  subbankheader.clear();
316  subbankheader.push_back(elements.size() + 1); // subbank size
317  subbankheader.push_back((fCurrentBank_ID << 16) | (0x01 << 8) | (1 & 0xff));
318  // subbank tag | subbank type | event number
319 
320  // Form CODA bank/roc header
321  rocheader.clear();
322  rocheader.push_back(subbankheader.size() + elements.size() + 1); // bank/roc size
323  rocheader.push_back((fCurrentROC_ID << 16) | (0x10 << 8) | (1 & 0xff));
324  // bank tag == ROC | bank type | event number
325 
326  // Add bank header, subbank header and element data to output buffer
327  buffer.insert(buffer.end(), rocheader.begin(), rocheader.end());
328  buffer.insert(buffer.end(), subbankheader.begin(), subbankheader.end());
329  buffer.insert(buffer.end(), elements.begin(), elements.end());
330  }
331 }
332 
333 
334 /**
335  * Process the event buffer for this subsystem
336  * @param roc_id ROC ID
337  * @param bank_id Subbank ID
338  * @param buffer Buffer to read from
339  * @param num_words Number of words left in buffer
340  * @return Number of words read
341  */
342 Int_t QwComptonPhotonDetector::ProcessEvBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t* buffer, UInt_t num_words)
343 {
344  UInt_t words_read = 0;
345 
346  // Get the subbank index (or -1 when no match)
347  Int_t subbank = GetSubbankIndex(roc_id, bank_id);
348 
349  if (subbank >= 0 && num_words > 0) {
350 
351  // We want to process this ROC. Begin looping through the data.
352 
353  switch (fMapping[subbank]) {
354 
355  // Sampling ADCs
356  case kSamplingADC:
357  {
358  for (size_t modnum = 0; modnum < fSamplingADC_Mapping[subbank].size(); modnum++) {
359  for (size_t channum = 0; channum < fSamplingADC_Mapping[subbank].at(modnum).size(); channum++) {
360  Int_t index = fSamplingADC_Mapping[subbank].at(modnum).at(channum);
361  if (index >= 0) {
362  words_read += fSamplingADC[index].ProcessEvBuffer(&(buffer[words_read]), num_words - words_read);
363  }
364  }
365  }
366  break;
367  }
368 
369  // Integrating ADCs and TDCs
370  case kIntegratingADC:
371  case kIntegratingTDC:
372  {
373  // Read header word
374  UInt_t header = buffer[words_read++];
375  if ((header & 0xbad00dc0) == 0xbad00dc0)
376  break; // Bad ADC/TDC
377 
378  // Parse number of events
379  //UInt_t num_events = 0;
380  //if ((header & 0xda000dc0) == 0xda000dc0)
381  // num_events = (buffer[0] & 0x00FF0000) >> 16;
382  // TODO Multihit functionality
383 
384  // Loop over buffered events
385  for (size_t i = words_read; i < num_words; i++) {
386 
387  // Decode this word as a V775 TDC / V792 QDC word
388  DecodeTDCWord(buffer[i]);
389 
390  // Is this a valid V775 TDC / V792 QDC data word?
391  if (! IsValidDataword()) continue;
392 
393  // Is there an QDC channel registered for this slot and channel?
394  for (size_t modnum = 0; modnum < fMultiQDC_Mapping[subbank].size(); modnum++) {
395  UInt_t channum = GetTDCChannelNumber();
396  if (channum < fMultiQDC_Mapping[subbank].at(modnum).size()) {
397  Int_t index = fMultiQDC_Mapping[subbank].at(modnum).at(channum);
398  if (index >= 0) {
399  fMultiQDC_Channel.at(index).SetValue(GetTDCData());
400  QwDebug << "QDC " << std::hex << subbank << " "
401  << modnum << "," << channum << ": " << std::dec
402  << GetTDCData() << QwLog::endl;
403  }
404  }
405  }
406 
407  // Is there an TDC channel registered for this slot and channel?
408  for (size_t modnum = 0; modnum < fMultiTDC_Mapping[subbank].size(); modnum++) {
409  UInt_t channum = GetTDCChannelNumber();
410  if (channum < fMultiTDC_Mapping[subbank].at(channum).size()) {
411  Int_t index = fMultiTDC_Mapping[subbank].at(modnum).at(channum);
412  if (index >= 0) {
413  fMultiTDC_Channel.at(index).SetValue(GetTDCData());
414  QwDebug << "TDC " << std::hex << subbank << " "
415  << modnum << "," << channum << ": " << std::dec
416  << GetTDCData() << QwLog::endl;
417  }
418  }
419  }
420 
421  } // end of loop over buffered events
422 
423  words_read = num_words;
424  break;
425  }
426 
427  // Unknown data channel type
428  case kUnknown:
429  default:
430  {
431  QwError << "QwComptonPhotonDetector: Unknown data channel type" << QwLog::endl;
432  break;
433  }
434  }
435 
436  // Check for leftover words
437  if (num_words != words_read) {
438  QwError << "QwComptonPhotonDetector: There were "
439  << num_words - words_read
440  << " leftover words after decoding everything we recognize"
441  << std::hex
442  << " in ROC " << roc_id << ", bank " << bank_id << "."
443  << std::dec
444  << QwLog::endl;
445  }
446  }
447 
448  return words_read;
449 }
450 
451 
452 /**
453  * Process the single event cuts
454  * @return
455  */
457 {
458  QwDebug << "QwComptonPhotonDetector::SingleEventCuts()" << QwLog::endl;
459  return IsGoodEvent();
460 }
461 
462 
463 /**
464  * Process this event
465  */
467 {
468  for (size_t i = 0; i < fSamplingADC.size(); i++)
470  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
472  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
474 }
475 
476 
477 /**
478  * Process the configuration buffer for this subsystem
479  * @param roc_id ROC ID
480  * @param bank_id Subbank ID
481  * @param buffer Buffer to read from
482  * @param num_words Number of words left in buffer
483  * @return Number of words read
484  */
485 Int_t QwComptonPhotonDetector::ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t* buffer, UInt_t num_words)
486 {
487  return 0;
488 }
489 
490 
491 /**
492  * Check whether this is a good event
493  * @return True if the event is good
494  */
496 {
497  Bool_t test = kTRUE;
498 
499  for(size_t i=0;i<fSamplingADC.size();i++)
500  test &= fSamplingADC[i].IsGoodEvent();
501 // for(size_t i=0;i<fMultiTDC_Channel.size();i++)
502 // test &= fMultiTDC_Channel[i].IsGoodEvent();
503 // for(size_t i=0;i<fMultiQDC_Channel.size();i++)
504 // test &= fMultiQDC_Channel[i].IsGoodEvent();
505 
506  if (!test) std::cerr << "This is not a good event!" << std::endl;
507  return test;
508 }
509 
510 
511 /**
512  * Clear the event data in this subsystem
513  */
515 {
516  // Clear all sampling ADC channels
517  for (size_t i = 0; i < fSamplingADC.size(); i++)
519 
520  // Clear all TDC and QDC channels
521  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
523  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
525 
526  fGoodEventCount = 0;
527 }
528 
529 /**
530  * Assignment operator
531  * @param value Right-hand side
532  * @return Left-hand side
533  */
535 {
536  if (CompareADC(value)) {
537  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*>(value);
538  for (size_t i = 0; i < input->fSamplingADC.size(); i++)
539  this->fSamplingADC[i] = input->fSamplingADC[i];
540  }
541 
542  if (CompareTDC(value)) {
543  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*>(value);
544  for (size_t i = 0; i < input->fMultiTDC_Channel.size();i++)
545  this->fMultiTDC_Channel[i] = input->fMultiTDC_Channel[i];
546  }
547 
548  if (CompareQDC(value)) {
549  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*>(value);
550  for (size_t i = 0; i < input->fMultiQDC_Channel.size();i++)
551  this->fMultiQDC_Channel[i] = input->fMultiQDC_Channel[i];
552  }
553 
554  return *this;
555 }
556 
557 /**
558  * Addition-assignment operator
559  * @param value Right-hand side
560  * @return Left-hand side
561  */
563 {
564  if (Compare(value)) {
565  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*>(value);
566  for (size_t i = 0; i < input->fSamplingADC.size(); i++)
567  this->fSamplingADC[i] += input->fSamplingADC[i];
568  }
569  return *this;
570 }
571 
572 /**
573  * Subtraction-assignment operator
574  * @param value Right-hand side
575  * @return Left-hand side
576  */
578 {
579  if (Compare(value)) {
580  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*> (value);
581  for (size_t i = 0; i < input->fSamplingADC.size(); i++)
582  this->fSamplingADC[i] -= input->fSamplingADC[i];
583  }
584  return *this;
585 }
586 
587 /**
588  * Summation
589  * @param value1 First value
590  * @param value2 Second value
591  */
593 {
594  if (Compare(value1) && Compare(value2)) {
595  *this = value1;
596  *this += value2;
597  }
598 }
599 
600 /**
601  * Difference
602  * @param value1 First value
603  * @param value2 Second value
604  */
606 {
607  if (Compare(value1) && Compare(value2)) {
608  *this = value1;
609  *this -= value2;
610  }
611 }
612 
613 /**
614  * Determine the ratio of two photon detectors
615  * @param numer Numerator
616  * @param denom Denominator
617  */
619 {
620  if (Compare(numer) && Compare(denom)) {
621  QwComptonPhotonDetector* innumer = dynamic_cast<QwComptonPhotonDetector*> (numer);
622  QwComptonPhotonDetector* indenom = dynamic_cast<QwComptonPhotonDetector*> (denom);
623  for (size_t i = 0; i < innumer->fSamplingADC.size(); i++)
624  this->fSamplingADC[i].Ratio(innumer->fSamplingADC[i], indenom->fSamplingADC[i]);
625  }
626 }
627 
628 /**
629  * Scale the photon detector
630  * @param factor Scale factor
631  */
632 void QwComptonPhotonDetector::Scale(Double_t factor)
633 {
634  for (size_t i = 0; i < fSamplingADC.size(); i++)
635  fSamplingADC[i].Scale(factor);
636 }
637 
638 /**
639  * Accumulate the running sum
640  */
642 {
643  if (Compare(value)) {
644  fGoodEventCount++;
645  *this += value;
646  }
647 }
648 
649 /**
650  * Normalize the running sum
651  */
653 {
654  if (fGoodEventCount <= 0) {
655  Scale(0);
656  } else {
657  Scale(1.0/fGoodEventCount);
658  }
659 }
660 
661 /**
662  * Compare two QwComptonPhotonDetector objects
663  * @param value Object to compare with
664  * @return kTRUE if the object is equal
665  */
667 {
668  // Immediately fail on null objects
669  if (value == 0) return kFALSE;
670 
671  // Continue testing on actual object
672  Bool_t result = kTRUE;
673  if (typeid(*value) != typeid(*this)) {
674  result = kFALSE;
675 
676  } else {
677  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*> (value);
678  if (input->fSamplingADC.size() != fSamplingADC.size()) {
679  result = kFALSE;
680  } else {
681  if (input->fMultiTDC_Channel.size() != fMultiTDC_Channel.size()) {
682  result = kFALSE;
683  } else {
684  if (input->fMultiQDC_Channel.size() != fMultiQDC_Channel.size()) {
685  result = kFALSE;
686  }
687  }
688  }
689  }
690  return result;
691 }
692 
693 /**
694  * Compare two QwComptonPhotonDetector ADC objects
695  * @param value Object to compare with
696  * @return kTRUE if the object is equal
697  */
699 {
700  // Immediately fail on null objects
701  if (value == 0) return kFALSE;
702 
703  // Continue testing on actual object
704  Bool_t result = kTRUE;
705  if (typeid(*value) != typeid(*this)) {
706  result = kFALSE;
707 
708  } else {
709  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*> (value);
710  if (input->fSamplingADC.size() != fSamplingADC.size()) {
711  result = kFALSE;
712  }
713  }
714  return result;
715 }
716 
717 /**
718  * Compare two QwComptonPhotonDetector TDC objects
719  * @param value Object to compare with
720  * @return kTRUE if the object is equal
721  */
723 {
724  // Immediately fail on null objects
725  if (value == 0) return kFALSE;
726 
727  // Continue testing on actual object
728  Bool_t result = kTRUE;
729  if (typeid(*value) != typeid(*this)) {
730  result = kFALSE;
731 
732  } else {
733  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*> (value);
734  if (input->fMultiTDC_Channel.size() != fMultiTDC_Channel.size()) {
735  result = kFALSE;
736  }
737  }
738  return result;
739 }
740 
741 /**
742  * Compare two QwComptonPhotonDetector QDC objects
743  * @param value Object to compare with
744  * @return kTRUE if the object is equal
745  */
747 {
748  // Immediately fail on null objects
749  if (value == 0) return kFALSE;
750 
751  // Continue testing on actual object
752  Bool_t result = kTRUE;
753  if (typeid(*value) != typeid(*this)) {
754  result = kFALSE;
755 
756  } else {
757  QwComptonPhotonDetector* input = dynamic_cast<QwComptonPhotonDetector*> (value);
758  if (input->fMultiQDC_Channel.size() != fMultiQDC_Channel.size()) {
759  result = kFALSE;
760  }
761  }
762  return result;
763 }
764 
765 /**
766  * Construct the histograms
767  * @param folder Folder in which the histograms will be created
768  * @param prefix Prefix with information about the type of histogram
769  */
770 void QwComptonPhotonDetector::ConstructHistograms(TDirectory *folder, TString &prefix)
771 {
772  for (size_t i = 0; i < fSamplingADC.size(); i++)
773  fSamplingADC[i].ConstructHistograms(folder, prefix);
774  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
775  fMultiTDC_Channel[i].ConstructHistograms(folder,prefix);
776  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
777  fMultiQDC_Channel[i].ConstructHistograms(folder,prefix);
778 }
779 
780 /**
781  * Fill the histograms with data
782  */
784 {
785  for (size_t i = 0; i < fSamplingADC.size(); i++)
787  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
789  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
791 }
792 
793 /**
794  * Construct the tree
795  * @param folder Folder in which the tree will be created
796  * @param prefix Prefix with information about the type of histogram
797  */
798 void QwComptonPhotonDetector::ConstructTree(TDirectory *folder, TString &prefix)
799 {
800  folder->cd();
801  fTree = new TTree("ComptonPhoton", "Compton Photon Detector");
802  fTree->Branch("nevents",&fTree_fNEvents,"nevents/I");
803 }
804 
805 /**
806  * Delete the tree
807  */
809 {
810  delete fTree;
811 }
812 
813 /**
814  * Fill the tree with data
815  */
817 {
818  for (size_t i = 0; i < fSamplingADC.size(); i++) {
819  fTree_fNEvents = fSamplingADC[i].GetNumberOfEvents();
820  fTree->Fill();
821  }
822 }
823 
824 /**
825  * Construct the tree
826  * @param tree Pointer to the tree in which the branches will be created
827  * @param prefix Prefix with information about the type of histogram
828  * @param values
829  */
830 void QwComptonPhotonDetector::ConstructBranchAndVector(TTree *tree, TString & prefix, std::vector <Double_t> &values)
831 {
832  for (size_t i = 0; i < fSamplingADC.size(); i++)
833  fSamplingADC[i].ConstructBranchAndVector(tree, prefix, values);
834  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
835  fMultiTDC_Channel[i].ConstructBranchAndVector(tree, prefix, values);
836  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
837  fMultiQDC_Channel[i].ConstructBranchAndVector(tree, prefix, values);
838 }
839 
840 /**
841  * Fill the tree with data
842  * @param values
843  */
844 void QwComptonPhotonDetector::FillTreeVector(std::vector<Double_t> &values) const
845 {
846  for (size_t i = 0; i < fSamplingADC.size(); i++)
847  fSamplingADC[i].FillTreeVector(values);
848  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
850  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
852 }
853 
854 /**
855  * Print the value for the subcomponents
856  */
858 {
859  for (size_t i = 0; i < fSamplingADC.size(); i++)
861  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++)
863  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++)
865 }
866 
867 /**
868  * Print some debugging output for the subcomponents
869  */
871 {
873 
874  QwOut << " there are " << fSamplingADC.size() << " sampling ADCs" << QwLog::endl;
875  QwOut << " there are " << fMultiTDC_Channel.size() << " integrating TDCs" << QwLog::endl;
876  QwOut << " there are " << fMultiQDC_Channel.size() << " integrating ADCs" << QwLog::endl;
877 
878  for (size_t i = 0; i < fSamplingADC.size(); i++) {
879  QwOut << " sampling ADC " << i << ":";
880  fSamplingADC[i].PrintInfo();
881  }
882  for (size_t i = 0; i < fMultiTDC_Channel.size(); i++) {
883  QwOut << " integrating TDC " << i << ":";
884  fMultiTDC_Channel[i].PrintInfo();
885  }
886  for (size_t i = 0; i < fMultiQDC_Channel.size(); i++) {
887  QwOut << " integrating ADC " << i << ":";
888  fMultiQDC_Channel[i].PrintInfo();
889  }
890 }
891 
892 /**
893  * Get the SIS3320 channel for this photon detector
894  * @param name Name of the SIS3320 channel
895  * @return Pointer to the SIS3320 channel
896  */
898 {
899  if (! fSamplingADC.empty()) {
900  for (std::vector<QwSIS3320_Channel>::iterator adc = fSamplingADC.begin(); adc != fSamplingADC.end(); ++adc) {
901  if (adc->GetElementName() == name) {
902  return &(*adc);
903  }
904  }
905  }
906  return 0;
907 }
Int_t GetSubbankIndex() const
Definition: VQwSubsystem.h:303
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
std::vector< QwPMT_Channel > fMultiTDC_Channel
std::map< TString, TString > fDetectorMaps
Definition: VQwSubsystem.h:322
Class for the decoding of the SIS3320 sampling ADC data.
QwSIS3320_Channel * GetSIS3320Channel(const TString name)
#define QwOut
Predefined log drain for explicit output.
Definition: QwLog.h:35
std::vector< QwPMT_Channel > fMultiQDC_Channel
UInt_t GetTDCChannelNumber()
Definition: MQwV775TDC.h:43
Int_t LoadInputParameters(TString pedestalfile)
Int_t LoadEventCuts(TString &filename)
UInt_t GetTDCData()
Definition: MQwV775TDC.h:44
void Ratio(VQwSubsystem *numer, VQwSubsystem *denom)
void Sum(VQwSubsystem *value1, VQwSubsystem *value2)
Int_t fTree_fNEvents
Expert tree fields.
An options class.
Definition: QwOptions.h:133
static UInt_t GetUInt(const TString &varvalue)
std::map< Int_t, ChannelType_t > fMapping
void AccumulateRunningSum(VQwSubsystem *value)
VQwSubsystem & operator=(VQwSubsystem *value)
VQwSubsystem & operator-=(VQwSubsystem *value)
#define QwVerbose
Predefined log drain for verbose messages.
Definition: QwLog.h:55
void EncodeEventData(std::vector< UInt_t > &buffer)
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
Definition: VQwSubsystem.h:209
Bool_t CompareQDC(VQwSubsystem *source)
void Difference(VQwSubsystem *value1, VQwSubsystem *value2)
IntegratingTDC_Mapping_t fMultiTDC_Mapping
#define QwDebug
Predefined log drain for debugging output.
Definition: QwLog.h:60
void ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector< Double_t > &values)
VQwSubsystem & operator+=(VQwSubsystem *value)
static void DefineOptions()
Define options function (note: no virtual static functions in C++)
Definition: VQwSubsystem.h:88
A logfile class, based on an identical class in the Hermes analyzer.
void ProcessOptions(QwOptions &options)
Process the command line options.
void DecodeTDCWord(UInt_t &word, const UInt_t roc_id=0)
Definition: MQwV775TDC.cc:53
void RandomizeEventData(int helicity=0)
virtual void PrintInfo() const
Print some information about the subsystem.
Bool_t Compare(VQwSubsystem *source)
std::vector< QwSIS3320_Channel > fSamplingADC
Bool_t CompareADC(VQwSubsystem *source)
The pure virtual base class of all subsystems.
Definition: VQwSubsystem.h:59
Int_t ProcessEvBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
Int_t ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
SamplingADC_Mapping_t fSamplingADC_Mapping
Int_t fCurrentROC_ID
ROC ID that is currently being processed.
Definition: VQwSubsystem.h:325
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
Class for the analysis of Compton photon detector data.
virtual void ConstructTree()
Construct the tree for this subsystem.
Definition: VQwSubsystem.h:257
void FillTreeVector(std::vector< Double_t > &values) const
Int_t LoadChannelMap(TString mapfile)
Bool_t CompareTDC(VQwSubsystem *source)
Int_t fCurrentBank_ID
Bank ID that is currently being processed.
Definition: VQwSubsystem.h:326
IntegratingADC_Mapping_t fMultiQDC_Mapping
Bool_t IsValidDataword()
Definition: MQwV775TDC.h:39
#define RegisterSubsystemFactory(A)
Definition: QwFactory.h:230
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40