QwAnalysis
QwVQWK_Channel.cc
Go to the documentation of this file.
1 #include "QwVQWK_Channel.h"
2 
3 // System headers
4 #include <stdexcept>
5 
6 // Qweak headers
7 #include "QwLog.h"
8 #include "QwUnits.h"
9 #include "QwBlinder.h"
10 #include "QwHistogramHelper.h"
11 #include "QwDBInterface.h"
12 
13 const Bool_t QwVQWK_Channel::kDEBUG = kFALSE;
14 
15 const Int_t QwVQWK_Channel::kWordsPerChannel = 6;
16 const Int_t QwVQWK_Channel::kMaxChannels = 8;
17 
18 /*! Conversion factor to translate the average bit count in an ADC
19  * channel into average voltage.
20  * The base factor is roughly 76 uV per count, and zero counts corresponds
21  * to zero voltage.
22  * Store as the exact value for 20 V range, 18 bit ADC.
23  */
24 const Double_t QwVQWK_Channel::kVQWK_VoltsPerBit = (20./(1<<18));
25 
26 /*! Static member function to return the word offset within a data buffer
27  * given the module number index and the channel number index.
28  * @param moduleindex Module index within this buffer; counts from zero
29  * @param channelindex Channel index within this module; counts from zero
30  * @return The number of words offset to the beginning of this
31  * channel's data from the beginning of the VQWK buffer.
32  */
33 Int_t QwVQWK_Channel::GetBufferOffset(Int_t moduleindex, Int_t channelindex){
34  Int_t offset = -1;
35  if (moduleindex<0 ){
36  QwError << "QwVQWK_Channel::GetBufferOffset: Invalid module index,"
37  << moduleindex
38  << ". Must be zero or greater."
39  << QwLog::endl;
40  } else if (channelindex<0 || channelindex>kMaxChannels){
41  QwError << "QwVQWK_Channel::GetBufferOffset: Invalid channel index,"
42  << channelindex
43  << ". Must be in range [0," << kMaxChannels << "]."
44  << QwLog::endl;
45  } else {
46  offset = ( (moduleindex * kMaxChannels) + channelindex )
48  }
49  return offset;
50  }
51 
52 
53 /********************************************************/
55 {
56  Bool_t fEventIsGood=kTRUE;
57  Bool_t bStatus;
58  if (bEVENTCUTMODE>0){//Global switch to ON/OFF event cuts set at the event cut file
59 
60  if (bDEBUG)
61  QwWarning<<" QwQWVK_Channel "<<GetElementName()<<" "<<GetNumberOfSamples()<<QwLog::endl;
62 
63  // Sample size check
64  bStatus = MatchNumberOfSamples(fNumberOfSamples_map);//compare the default sample size with no.of samples read by the module
65  if (!bStatus) {
67  }
68 
69  // Check SW and HW return the same sum
70  bStatus = (GetRawHardwareSum() == GetRawSoftwareSum());
71  //fEventIsGood = bStatus;
72  if (!bStatus) {
74  }
75 
76 
77 
78  //check sequence number
80  if (fSequenceNo_Counter==0 || GetSequenceNumber()==0){//starting the data run
82  }
83 
84  if (!MatchSequenceNumber(fSequenceNo_Prev)){//we have a sequence number error
85  fEventIsGood=kFALSE;
87  if (bDEBUG) QwWarning<<" QwQWVK_Channel "<<GetElementName()<<" Sequence number previous value = "<<fSequenceNo_Prev<<" Current value= "<< GetSequenceNumber()<<QwLog::endl;
88  }
89 
91 
92  //Checking for HW_sum is returning same value.
94  //std::cout<<" BCM hardware sum is different "<<std::endl;
97  }else
98  fADC_Same_NumEvt++;//hw_sum is same increment the counter
99 
100  //check for the hw_sum is giving the same value
101  if (fADC_Same_NumEvt>0){//we have ADC stuck with same value
102  if (bDEBUG) QwWarning<<" BCM hardware sum is same for more than "<<fADC_Same_NumEvt<<" time consecutively "<<QwLog::endl;
104  }
105 
106  //check for the hw_sum is zero
107  if (GetRawHardwareSum()==0){
109  }
110  if (!fEventIsGood)
111  fSequenceNo_Counter=0;//resetting the counter after ApplyHWChecks() a failure
112 
114  if (bDEBUG)
115  QwWarning << this->GetElementName()<<" "<<GetRawHardwareSum() << "Saturating VQWK invoked! " <<TMath::Abs(GetRawHardwareSum())*kVQWK_VoltsPerBit/fNumberOfSamples<<" Limit "<<GetVQWKSaturationLimt() << QwLog::endl;
117  }
118 
119  }
120  else {
121  fGoodEventCount = 1;
122  fErrorFlag = 0;
123  }
124 
125  return fErrorFlag;
126 }
127 
128 
129 /********************************************************/
132  fErrorCount_sample++; //increment the hw error counter
133  if ( (kErrorFlag_SW_HW & fErrorFlag)==kErrorFlag_SW_HW)
134  fErrorCount_SW_HW++; //increment the hw error counter
135  if ( (kErrorFlag_Sequence & fErrorFlag)==kErrorFlag_Sequence)
136  fErrorCount_Sequence++; //increment the hw error counter
137  if ( (kErrorFlag_SameHW & fErrorFlag)==kErrorFlag_SameHW)
138  fErrorCount_SameHW++; //increment the hw error counter
139  if ( (kErrorFlag_ZeroHW & fErrorFlag)==kErrorFlag_ZeroHW)
140  fErrorCount_ZeroHW++; //increment the hw error counter
141  if ( (kErrorFlag_VQWK_Sat & fErrorFlag)==kErrorFlag_VQWK_Sat)
142  fErrorCount_HWSat++; //increment the hw saturation error counter
143  if ( ((kErrorFlag_EventCut_L & fErrorFlag)==kErrorFlag_EventCut_L)
144  || ((kErrorFlag_EventCut_U & fErrorFlag)==kErrorFlag_EventCut_U)){
145  fNumEvtsWithEventCutsRejected++; //increment the event cut error counter
146  }
147 }
148 
149 /********************************************************/
150 
151 void QwVQWK_Channel::InitializeChannel(TString name, TString datatosave)
152 {
153  SetElementName(name);
154  SetDataToSave(datatosave);
157 
158  kFoundPedestal = 0;
159  kFoundGain = 0;
160 
161  fPedestal = 0.0;
162  fCalibrationFactor = 1.0;
163 
164  fBlocksPerEvent = 4;
165 
166  fTreeArrayIndex = 0;
168 
169  ClearEventData();
170 
173  fNumberOfSamples = 0;
174 
175  // Use internal random variable by default
177 
178  // Mock drifts
179  fMockDriftAmplitude.clear();
180  fMockDriftFrequency.clear();
181  fMockDriftPhase.clear();
182 
183  // Mock asymmetries
184  fMockAsymmetry = 0.0;
185  fMockGaussianMean = 0.0;
186  fMockGaussianSigma = 0.0;
187 
188  // Event cuts
189  fULimit=0;
190  fLLimit=0;
192 
193  fErrorFlag=0;//Initialize the error flag
194  fErrorConfigFlag=0;//Initialize the error config. flag
195 
196  //init error counters//
197  fErrorCount_sample = 0;
198  fErrorCount_SW_HW = 0;
200  fErrorCount_SameHW = 0;
201  fErrorCount_ZeroHW = 0;
202  fErrorCount_HWSat = 0;
203 
204  fRunningSum = 0;
205 
206  fADC_Same_NumEvt = 0;
207  fSequenceNo_Prev = 0;
210 
211  fGoodEventCount = 0;
212 
213  bEVENTCUTMODE = 0;
214 
215  //std::cout<< "name = "<<name<<" error count same _HW = "<<fErrorCount_SameHW <<std::endl;
216  return;
217 }
218 
219 /********************************************************/
220 
221 void QwVQWK_Channel::InitializeChannel(TString subsystem, TString instrumenttype, TString name, TString datatosave){
222  InitializeChannel(name,datatosave);
223  SetSubsystemName(subsystem);
224  SetModuleType(instrumenttype);
225  //PrintInfo();
226 }
227 
229  UInt_t value = 0;
230  if (paramfile.ReturnValue("sample_size",value)){
231  SetDefaultSampleSize(value);
232  } else {
233  QwWarning << "VQWK Channel "
234  << GetElementName()
235  << " cannot set the default sample size."
236  << QwLog::endl;
237  }
238 };
239 
240 
242 {
243  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
244  fBlock_raw[i] = 0;
245  fBlock[i] = 0.0;
246  fBlockM2[i] = 0.0;
247  fBlockError[i] = 0.0;
248  }
251  fHardwareBlockSum = 0.0;
252  fHardwareBlockSumM2 = 0.0;
254  fSequenceNumber = 0;
255  fNumberOfSamples = 0;
256  fGoodEventCount = 0;
257  fErrorFlag=0;
258  return;
259 }
260 
261 void QwVQWK_Channel::RandomizeEventData(int helicity, double time)
262 {
263  // The blocks are assumed to be independent measurements
264  Double_t* block = new Double_t[fBlocksPerEvent];
265  Double_t sqrt_fBlocksPerEvent = 0.0;
266  sqrt_fBlocksPerEvent = sqrt(fBlocksPerEvent);
267 
268  // Calculate drift (if time is not specified, it stays constant at zero)
269  Double_t drift = 0.0;
270  for (UInt_t i = 0; i < fMockDriftFrequency.size(); i++) {
271  drift += fMockDriftAmplitude[i] * sin(2.0 * Qw::pi * fMockDriftFrequency[i] * time + fMockDriftPhase[i]);
272  }
273 
274  // Calculate signal
275  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
276  block[i] =
277  fMockGaussianMean * (1 + helicity * fMockAsymmetry) / fBlocksPerEvent
278  + fMockGaussianSigma / sqrt_fBlocksPerEvent * GetRandomValue()
279  + drift / fBlocksPerEvent;
280  }
281 
282  SetEventData(block);
283 
284  delete block;
285  return;
286 }
287 
288 void QwVQWK_Channel::SetHardwareSum(Double_t hwsum, UInt_t sequencenumber)
289 {
290  Double_t* block = new Double_t[fBlocksPerEvent];
291  for (Int_t i = 0; i < fBlocksPerEvent; i++)
292  block[i] = hwsum / fBlocksPerEvent;
293  SetEventData(block);
294 
295  delete block;
296  return;
297 }
298 
299 
300 // SetEventData() is used by the mock data generator to turn "model"
301 // data values into their equivalent raw data. It should be used
302 // nowhere else. -- pking, 2010-09-16
303 void QwVQWK_Channel::SetEventData(Double_t* block, UInt_t sequencenumber)
304 {
305  fHardwareBlockSum = 0.0;
306  fHardwareBlockSumM2 = 0.0; // second moment is zero for single events
307  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
308  fBlock[i] = block[i];
309  fBlockM2[i] = 0.0; // second moment is zero for single events
310  fHardwareBlockSum += block[i];
311  }
312 
313  fSequenceNumber = sequencenumber;
314  fNumberOfSamples = 16680;
315 
316  Double_t thispedestal = 0.0;
317  thispedestal = fPedestal * fNumberOfSamples;
318 
320  for (Int_t i = 0; i < fBlocksPerEvent; i++)
321  {
322  fBlock_raw[i] = Int_t(fBlock[i] / fCalibrationFactor + thispedestal / (fBlocksPerEvent * 1.));
324  }
325  // fHardwareBlockSum_raw = fHardwareBlockSum / fCalibrationFactor + thispedestal;
327 
328  return;
329 }
330 
331 void QwVQWK_Channel::EncodeEventData(std::vector<UInt_t> &buffer)
332 {
333  Long_t localbuf[6] = {0};
334 
335  if (IsNameEmpty()) {
336  // This channel is not used, but is present in the data stream.
337  // Skip over this data.
338  } else {
339  // localbuf[4] = 0;
340  for (Int_t i = 0; i < 4; i++) {
341  localbuf[i] = fBlock_raw[i];
342  // localbuf[4] += localbuf[i]; // fHardwareBlockSum_raw
343  }
344  // The following causes many rounding errors and skips due to the check
345  // that fHardwareBlockSum_raw == fSoftwareBlockSum_raw in IsGoodEvent().
346  localbuf[4] = fHardwareBlockSum_raw;
347  localbuf[5] = (fNumberOfSamples << 16 & 0xFFFF0000)
348  | (fSequenceNumber << 8 & 0x0000FF00);
349 
350  for (Int_t i = 0; i < 6; i++){
351  buffer.push_back(localbuf[i]);
352  }
353  }
354 }
355 
356 
357 
358 Int_t QwVQWK_Channel::ProcessEvBuffer(UInt_t* buffer, UInt_t num_words_left, UInt_t index)
359 {
360  UInt_t words_read = 0;
361  UInt_t localbuf[kWordsPerChannel] = {0};
362  // The conversion from UInt_t to Double_t discards the sign, so we need an intermediate
363  // static_cast from UInt_t to Int_t.
364  Int_t localbuf_signed[kWordsPerChannel] = {0};
365 
366  if (IsNameEmpty()){
367  // This channel is not used, but is present in the data stream.
368  // Skip over this data.
369  words_read = fNumberOfDataWords;
370  } else if (num_words_left >= fNumberOfDataWords)
371  {
372  for (Int_t i=0; i<kWordsPerChannel; i++){
373  localbuf[i] = buffer[i];
374  localbuf_signed[i] = static_cast<Int_t>(localbuf[i]);
375  }
376 
378  for (Int_t i=0; i<fBlocksPerEvent; i++){
379  fBlock_raw[i] = localbuf_signed[i];
381  }
382  fHardwareBlockSum_raw = localbuf_signed[4];
383 
384  /* Permanent change in the structure of the 6th word of the ADC readout.
385  * The upper 16 bits are the number of samples, and the upper 8 of the
386  * lower 16 are the sequence number. This matches the structure of
387  * the ADC readout in block read mode, and now also in register read mode.
388  * P.King, 2007sep04.
389  */
390  fSequenceNumber = (localbuf[5]>>8) & 0xFF;
391  fNumberOfSamples = (localbuf[5]>>16) & 0xFFFF;
392 
393  words_read = fNumberOfDataWords;
394 
395  } else
396  {
397  std::cerr << "QwVQWK_Channel::ProcessEvBuffer: Not enough words!"
398  << std::endl;
399  }
400  return words_read;
401 }
402 
403 
404 
406 {
407  if (fNumberOfSamples == 0 && fHardwareBlockSum_raw == 0) {
408  // There isn't valid data for this channel. Just flag it and
409  // move on.
410  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
411  fBlock[i] = 0.0;
412  fBlockM2[i] = 0.0;
413  }
414  fHardwareBlockSum = 0.0;
415  fHardwareBlockSumM2 = 0.0;
417  } else if (fNumberOfSamples == 0) {
418  // This is probably a more serious problem.
419  QwWarning << "QwVQWK_Channel::ProcessEvent: Channel "
420  << this->GetElementName().Data()
421  << " has fNumberOfSamples==0 but has valid data in the hardware sum. "
422  << "Flag this as an error."
423  << QwLog::endl;
424  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
425  fBlock[i] = 0.0;
426  fBlockM2[i] = 0.0;
427  }
428  fHardwareBlockSum = 0.0;
429  fHardwareBlockSumM2 = 0.0;
431  } else {
432  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
433  fBlock[i] = fCalibrationFactor * ( (1.0 * fBlock_raw[i] * fBlocksPerEvent / fNumberOfSamples) - fPedestal );
434  fBlockM2[i] = 0.0; // second moment is zero for single events
435  }
437  fHardwareBlockSumM2 = 0.0; // second moment is zero for single events
438  }
439  return;
440 }
441 
443 {
444  //Double_t avgVolts = (fBlock[0]+fBlock[1]+fBlock[2]+fBlock[3])*kVQWK_VoltsPerBit/fNumberOfSamples;
445  Double_t avgVolts = fHardwareBlockSum * kVQWK_VoltsPerBit / fNumberOfSamples;
446  //std::cout<<"QwVQWK_Channel::GetAverageVolts() = "<<avgVolts<<std::endl;
447  return avgVolts;
448 
449 }
450 
452 {
453  std::cout<<"***************************************"<<"\n";
454  std::cout<<"Subsystem "<<GetSubsystemName()<<"\n"<<"\n";
455  std::cout<<"Beam Instrument Type: "<<GetModuleType()<<"\n"<<"\n";
456  std::cout<<"QwVQWK channel: "<<GetElementName()<<"\n"<<"\n";
457  std::cout<<"fPedestal= "<< fPedestal<<"\n";
458  std::cout<<"fCalibrationFactor= "<<fCalibrationFactor<<"\n";
459  std::cout<<"fBlocksPerEvent= "<<fBlocksPerEvent<<"\n"<<"\n";
460  std::cout<<"fSequenceNumber= "<<fSequenceNumber<<"\n";
461  std::cout<<"fNumberOfSamples= "<<fNumberOfSamples<<"\n";
462  std::cout<<"fBlock_raw ";
463 
464  for (Int_t i = 0; i < fBlocksPerEvent; i++)
465  std::cout << " : " << fBlock_raw[i];
466  std::cout<<"\n";
467  std::cout<<"fHardwareBlockSum_raw= "<<fHardwareBlockSum_raw<<"\n";
468  std::cout<<"fSoftwareBlockSum_raw= "<<fSoftwareBlockSum_raw<<"\n";
469  std::cout<<"fBlock ";
470  for (Int_t i = 0; i < fBlocksPerEvent; i++)
471  std::cout << " : " << fBlock[i];
472  std::cout << std::endl;
473 
474  std::cout << "fHardwareBlockSum = "<<fHardwareBlockSum << std::endl;
475  std::cout << "fHardwareBlockSumM2 = "<<fHardwareBlockSumM2 << std::endl;
476  std::cout << "fHardwareBlockSumError = "<<fHardwareBlockSumError << std::endl;
477 
478  return;
479 }
480 
481 void QwVQWK_Channel::ConstructHistograms(TDirectory *folder, TString &prefix)
482 {
483  // If we have defined a subdirectory in the ROOT file, then change into it.
484  if (folder != NULL) folder->cd();
485 
486  if (IsNameEmpty()){
487  // This channel is not used, so skip filling the histograms.
488  } else {
489  // Now create the histograms.
490  if (prefix == TString("asym_")
491  || prefix == TString("diff_")
492  || prefix == TString("yield_"))
494 
495  TString basename, fullname;
496  basename = prefix + GetElementName();
497 
498  if(fDataToSave==kRaw)
499  {
500  fHistograms.resize(8+2+1, NULL);
501  size_t index=0;
502  for (Int_t i=0; i<fBlocksPerEvent; i++){
503  fHistograms[index] = gQwHists.Construct1DHist(basename+Form("_block%d_raw",i));
504  fHistograms[index+1] = gQwHists.Construct1DHist(basename+Form("_block%d",i));
505  index += 2;
506  }
507  fHistograms[index] = gQwHists.Construct1DHist(basename+Form("_hw_raw"));
508  fHistograms[index+1] = gQwHists.Construct1DHist(basename+Form("_hw"));
509  index += 2;
510  fHistograms[index] = gQwHists.Construct1DHist(basename+Form("_sw-hw_raw"));
511  }
512  else if(fDataToSave==kDerived)
513  {
514  fHistograms.resize(4+1+1, NULL);
515  Int_t index=0;
516  for (Int_t i=0; i<fBlocksPerEvent; i++){
517  fHistograms[index] = gQwHists.Construct1DHist(basename+Form("_block%d",i));
518  index += 1;
519  }
520  fHistograms[index] = gQwHists.Construct1DHist(basename+Form("_hw"));
521  index += 1;
522  fHistograms[index] = gQwHists.Construct1DHist(basename+Form("_dev_err"));
523  index += 1;
524  }
525  else
526  {
527  // this is not recognized
528  }
529 
530  }
531 }
532 
534 {
535  Int_t index=0;
536 
537  if (IsNameEmpty())
538  {
539  // This channel is not used, so skip creating the histograms.
540  } else
541  {
542  if(fDataToSave==kRaw)
543  {
544  for (Int_t i=0; i<fBlocksPerEvent; i++)
545  {
546  if (fHistograms[index] != NULL && (fErrorFlag)==0)
547  fHistograms[index]->Fill(this->GetRawBlockValue(i));
548  if (fHistograms[index+1] != NULL && (fErrorFlag)==0)
549  fHistograms[index+1]->Fill(this->GetBlockValue(i));
550  index+=2;
551  }
552  if (fHistograms[index] != NULL && (fErrorFlag)==0)
553  fHistograms[index]->Fill(this->GetRawHardwareSum());
554  if (fHistograms[index+1] != NULL && (fErrorFlag)==0)
555  fHistograms[index+1]->Fill(this->GetHardwareSum());
556  index+=2;
557  if (fHistograms[index] != NULL && (fErrorFlag)==0)
558  fHistograms[index]->Fill(this->GetRawSoftwareSum()-this->GetRawHardwareSum());
559  }
560  else if(fDataToSave==kDerived)
561  {
562  for (Int_t i=0; i<fBlocksPerEvent; i++)
563  {
564  if (fHistograms[index] != NULL && (fErrorFlag)==0)
565  fHistograms[index]->Fill(this->GetBlockValue(i));
566  index+=1;
567  }
568  if (fHistograms[index] != NULL && (fErrorFlag)==0)
569  fHistograms[index]->Fill(this->GetHardwareSum());
570  index+=1;
571  if (fHistograms[index] != NULL){
573  fHistograms[index]->Fill(kErrorFlag_sample);
574  if ( (kErrorFlag_SW_HW & fErrorFlag)==kErrorFlag_SW_HW)
575  fHistograms[index]->Fill(kErrorFlag_SW_HW);
576  if ( (kErrorFlag_Sequence & fErrorFlag)==kErrorFlag_Sequence)
577  fHistograms[index]->Fill(kErrorFlag_Sequence);
578  if ( (kErrorFlag_ZeroHW & fErrorFlag)==kErrorFlag_ZeroHW)
579  fHistograms[index]->Fill(kErrorFlag_ZeroHW);
580  if ( (kErrorFlag_VQWK_Sat & fErrorFlag)==kErrorFlag_VQWK_Sat)
581  fHistograms[index]->Fill(kErrorFlag_VQWK_Sat);
582  if ( (kErrorFlag_SameHW & fErrorFlag)==kErrorFlag_SameHW)
583  fHistograms[index]->Fill(kErrorFlag_SameHW);
584  }
585 
586  }
587 
588  }
589 }
590 
591 void QwVQWK_Channel::ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector<Double_t> &values)
592 {
593 
594  if (IsNameEmpty()){
595  // This channel is not used, so skip setting up the tree.
596  } else {
597  TString basename = prefix + GetElementName();
598  fTreeArrayIndex = values.size();
599 
600  TString list="";
601 
607  bDevice_Error_Code=gQwHists.MatchVQWKElementFromList(GetSubsystemName().Data(), GetModuleType().Data(), "Device_Error_Code");
609 
610  if (bHw_sum){
611  values.push_back(0.0);
612  list += "hw_sum/D";
613  }
614  if (bBlock){
615  values.push_back(0.0);
616  list += ":block0/D";
617 
618  values.push_back(0.0);
619  list += ":block1/D";
620 
621  values.push_back(0.0);
622  list += ":block2/D";
623 
624  values.push_back(0.0);
625  list += ":block3/D";
626  }
627 
628  if (bNum_samples){
629  values.push_back(0.0);
630  list += ":num_samples/D";
631  }
632 
633  if (bDevice_Error_Code){
634  values.push_back(0.0);
635  list += ":Device_Error_Code/D";
636  }
637 
638  if(fDataToSave==kRaw)
639  {
640  if (bHw_sum_raw){
641  values.push_back(0.0);
642  list += ":hw_sum_raw/D";
643  }
644  if (bBlock_raw){
645  values.push_back(0.0);
646  list += ":block0_raw/D";
647 
648  values.push_back(0.0);
649  list += ":block1_raw/D";
650 
651  values.push_back(0.0);
652  list += ":block2_raw/D";
653 
654  values.push_back(0.0);
655  list += ":block3_raw/D";
656  }
657  if (bSequence_number){
658  values.push_back(0.0);
659  list += ":sequence_number/D";
660  }
661  }
662 
663  fTreeArrayNumEntries = values.size() - fTreeArrayIndex;
664 
666 
667  if (list=="hw_sum/D")//this is for the RT mode
668  list=basename+"/D";
669 
670  if (kDEBUG)
671  QwMessage <<"base name "<<basename<<" List "<<list<< QwLog::endl;
672  tree->Branch(basename, &(values[fTreeArrayIndex]), list);
673  }
674 
675  if (kDEBUG){
676  std::cerr << "QwVQWK_Channel::ConstructBranchAndVector: fTreeArrayIndex==" << fTreeArrayIndex
677  << "; fTreeArrayNumEntries==" << fTreeArrayNumEntries
678  << "; values.size()==" << values.size()
679  << "; list==" << list
680  << std::endl;
681  }
682  }
683  //exit(1);
684  return;
685 }
686 
687 void QwVQWK_Channel::ConstructBranch(TTree *tree, TString &prefix)
688 {
689  if (IsNameEmpty()){
690  // This channel is not used, so skip setting up the tree.
691  } else {
692  TString basename = prefix + GetElementName();
693  tree->Branch(basename,&fHardwareBlockSum,basename+"/D");
694  if (kDEBUG){
695  std::cerr << "QwVQWK_Channel::ConstructBranchAndVector: fTreeArrayIndex==" << fTreeArrayIndex
696  << "; fTreeArrayNumEntries==" << fTreeArrayNumEntries
697  << std::endl;
698  }
699  }
700  return;
701 }
702 
703 
704 void QwVQWK_Channel::FillTreeVector(std::vector<Double_t> &values) const
705 {
706  if (IsNameEmpty()) {
707  // This channel is not used, so skip filling the tree vector.
708  } else if (fTreeArrayNumEntries <= 0) {
709  if (bDEBUG) std::cerr << "QwVQWK_Channel::FillTreeVector: fTreeArrayNumEntries=="
710  << fTreeArrayNumEntries << std::endl;
711  } else if (values.size() < fTreeArrayIndex+fTreeArrayNumEntries){
712  if (bDEBUG) std::cerr << "QwVQWK_Channel::FillTreeVector: values.size()=="
713  << values.size()
714  << "; fTreeArrayIndex+fTreeArrayNumEntries=="
716  << std::endl;
717  } else {
718  UInt_t index = fTreeArrayIndex;
719  //hw_sum
720  if (bHw_sum)
721  values[index++] = this->GetHardwareSum();
722 
723  if (bBlock){
724  for (Int_t i=0; i<fBlocksPerEvent; i++){
725  //blocki
726  values[index++] = this->GetBlockValue(i);
727  }
728  }
729 
730  //num_samples
731  if (bNum_samples)
732  values[index++] = this->fNumberOfSamples;
733 
734  //Device_Error_Code
735  if (bDevice_Error_Code)
736  values[index++] = (this->fErrorFlag);
737 
738  if(fDataToSave==kRaw)
739  {
740  //hw_sum_raw
741  if (bHw_sum_raw)
742  values[index++] = this->GetRawHardwareSum();
743 
744  if (bBlock_raw){
745  for (Int_t i=0; i<fBlocksPerEvent; i++){
746  //blocki_raw
747  values[index++] = this->GetRawBlockValue(i);
748  }
749  }
750 
751  //sequence_number
752  if (bSequence_number)
753  values[index++]=this->fSequenceNumber;
754  }
755  }
756 }
757 
758 // VQwDataElement& QwVQWK_Channel::operator= (const VQwDataElement& data_value)
759 // {
760 // QwVQWK_Channel * value;
761 // value=(QwVQWK_Channel *)&data_value;
762 // if(this ==value) return *this;
763 
764 // if (!IsNameEmpty())
765 // {
766 // for (Int_t i=0; i<fBlocksPerEvent; i++){
767 // this->fBlock_raw[i] = value->fBlock_raw[i];
768 // this->fBlock[i] = value->fBlock[i];
769 // this->fBlockM2[i] = value->fBlockM2[i];
770 // }
771 // this->fHardwareBlockSum_raw = value->fHardwareBlockSum_raw;
772 // this->fSoftwareBlockSum_raw = value->fSoftwareBlockSum_raw;
773 // this->fHardwareBlockSum = value->fHardwareBlockSum;
774 // this->fHardwareBlockSumM2 = value->fHardwareBlockSumM2;
775 // this->fHardwareBlockSumError = value->fHardwareBlockSumError;
776 // this->fGoodEventCount=value->fGoodEventCount;
777 // this->fNumberOfSamples = value->fNumberOfSamples;
778 // this->fSequenceNumber = value->fSequenceNumber;
779 // this->fErrorFlag = (value->fErrorFlag);
780 // }
781 
782 // return *this;
783 // }
784 
785 
786 
788 {
789  if(this ==&value) return *this;
790 
791  if (!IsNameEmpty()) {
793  for (Int_t i=0; i<fBlocksPerEvent; i++){
794  this->fBlock_raw[i] = value.fBlock_raw[i];
795  this->fBlock[i] = value.fBlock[i];
796  this->fBlockM2[i] = value.fBlockM2[i];
797  }
800  this->fHardwareBlockSum = value.fHardwareBlockSum;
803  this->fNumberOfSamples = value.fNumberOfSamples;
804  this->fSequenceNumber = value.fSequenceNumber;
805 
806 
807  }
808  return *this;
809 }
810 
812  Double_t scale)
813 {
814  if(this == &value) return;
815 
816  if (!IsNameEmpty()) {
817  for (Int_t i=0; i<fBlocksPerEvent; i++){
818  this->fBlock_raw[i] = value.fBlock_raw[i]; // Keep this?
819  this->fBlock[i] = value.fBlock[i] * scale;
820  this->fBlockM2[i] = value.fBlockM2[i] * scale * scale;
821  }
822  this->fHardwareBlockSum_raw = value.fHardwareBlockSum_raw; // Keep this?
823  this->fSoftwareBlockSum_raw = value.fSoftwareBlockSum_raw; // Keep this?
824  this->fHardwareBlockSum = value.fHardwareBlockSum * scale;
825  this->fHardwareBlockSumM2 = value.fHardwareBlockSumM2 * scale * scale;
826  this->fHardwareBlockSumError = value.fHardwareBlockSumError; // Keep this?
827  this->fGoodEventCount = value.fGoodEventCount;
828  this->fNumberOfSamples = value.fNumberOfSamples;
829  this->fSequenceNumber = value.fSequenceNumber;
830  this->fErrorFlag = value.fErrorFlag;
831  }
832 }
833 
835 {
836  const QwVQWK_Channel* tmpptr;
837  tmpptr = dynamic_cast<const QwVQWK_Channel*>(valueptr);
838  if (tmpptr!=NULL){
839  *this = *tmpptr;
840  } else {
841  TString loc="Standard exception from QwVQWK_Channel::AssignValueFrom = "
842  +valueptr->GetElementName()+" is an incompatable type.";
843  throw std::invalid_argument(loc.Data());
844  }
845 }
847 {
848  const QwVQWK_Channel* tmpptr;
849  tmpptr = dynamic_cast<const QwVQWK_Channel*>(valueptr);
850  if (tmpptr!=NULL){
851  *this += *tmpptr;
852  } else {
853  TString loc="Standard exception from QwVQWK_Channel::AddValueFrom = "
854  +valueptr->GetElementName()+" is an incompatable type.";
855  throw std::invalid_argument(loc.Data());
856  }
857 }
859 {
860  const QwVQWK_Channel* tmpptr;
861  tmpptr = dynamic_cast<const QwVQWK_Channel*>(valueptr);
862  if (tmpptr!=NULL){
863  *this -= *tmpptr;
864  } else {
865  TString loc="Standard exception from QwVQWK_Channel::SubtractValueFrom = "
866  +valueptr->GetElementName()+" is an incompatable type.";
867  throw std::invalid_argument(loc.Data());
868  }
869 }
871 {
872  const QwVQWK_Channel* tmpptr;
873  tmpptr = dynamic_cast<const QwVQWK_Channel*>(valueptr);
874  if (tmpptr!=NULL){
875  *this *= *tmpptr;
876  } else {
877  TString loc="Standard exception from QwVQWK_Channel::MultiplyBy = "
878  +valueptr->GetElementName()+" is an incompatable type.";
879  throw std::invalid_argument(loc.Data());
880  }
881 }
883 {
884  const QwVQWK_Channel* tmpptr;
885  tmpptr = dynamic_cast<const QwVQWK_Channel*>(valueptr);
886  if (tmpptr!=NULL){
887  *this /= *tmpptr;
888  } else {
889  TString loc="Standard exception from QwVQWK_Channel::DivideBy = "
890  +valueptr->GetElementName()+" is an incompatable type.";
891  throw std::invalid_argument(loc.Data());
892  }
893 }
894 
895 
897 {
898  QwVQWK_Channel result = *this;
899  result += value;
900  return result;
901 }
902 
904 {
905  if (!IsNameEmpty()) {
906  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
907  this->fBlock[i] += value.fBlock[i];
908  this->fBlock_raw[i] += value.fBlock_raw[i];
909  this->fBlockM2[i] = 0.0;
910  }
913  this->fHardwareBlockSum += value.fHardwareBlockSum;
914  this->fHardwareBlockSumM2 = 0.0;
915  this->fNumberOfSamples += value.fNumberOfSamples;
916  this->fSequenceNumber = 0;
917  this->fErrorFlag |= (value.fErrorFlag);
918 
919  }
920 
921  return *this;
922 }
923 
925 {
926  QwVQWK_Channel result = *this;
927  result -= value;
928  return result;
929 }
930 
932 {
933  if (!IsNameEmpty()){
934  for (Int_t i=0; i<fBlocksPerEvent; i++){
935  this->fBlock[i] -= value.fBlock[i];
936  this->fBlock_raw[i] = 0;
937  this->fBlockM2[i] = 0.0;
938  }
939  this->fHardwareBlockSum_raw = 0;
940  this->fSoftwareBlockSum_raw = 0;
941  this->fHardwareBlockSum -= value.fHardwareBlockSum;
942  this->fHardwareBlockSumM2 = 0.0;
943  this->fNumberOfSamples += value.fNumberOfSamples;
944  this->fSequenceNumber = 0;
945  this->fErrorFlag |= (value.fErrorFlag);
946  }
947 
948  return *this;
949 }
950 
952 {
953  QwVQWK_Channel result = *this;
954  result *= value;
955  return result;
956 }
957 
959 {
960  if (!IsNameEmpty()){
961  for (Int_t i=0; i<fBlocksPerEvent; i++){
962  this->fBlock[i] *= value.fBlock[i];
963  this->fBlock_raw[i] *= value.fBlock_raw[i];
964  this->fBlockM2[i] = 0.0;
965  }
968  this->fHardwareBlockSum *= value.fHardwareBlockSum;
969  this->fHardwareBlockSumM2 = 0.0;
970  this->fNumberOfSamples *= value.fNumberOfSamples;
971  this->fSequenceNumber = 0;
972  this->fErrorFlag |= (value.fErrorFlag);
973  }
974 
975  return *this;
976 }
977 
979 {
980  const QwVQWK_Channel* tmpptr;
981  tmpptr = dynamic_cast<const QwVQWK_Channel*>(source);
982  if (tmpptr!=NULL){
983  *this += *tmpptr;
984  } else {
985  TString loc="Standard exception from QwVQWK_Channel::operator+= "
986  +source->GetElementName()+" "
987  +this->GetElementName()+" are not of the same type";
988  throw(std::invalid_argument(loc.Data()));
989  }
990  return *this;
991 }
993 {
994  const QwVQWK_Channel* tmpptr;
995  tmpptr = dynamic_cast<const QwVQWK_Channel*>(source);
996  if (tmpptr!=NULL){
997  *this -= *tmpptr;
998  } else {
999  TString loc="Standard exception from QwVQWK_Channel::operator-= "
1000  +source->GetElementName()+" "
1001  +this->GetElementName()+" are not of the same type";
1002  throw(std::invalid_argument(loc.Data()));
1003  }
1004  return *this;
1005 }
1007 {
1008  const QwVQWK_Channel* tmpptr;
1009  tmpptr = dynamic_cast<const QwVQWK_Channel*>(source);
1010  if (tmpptr!=NULL){
1011  *this *= *tmpptr;
1012  } else {
1013  TString loc="Standard exception from QwVQWK_Channel::operator*= "
1014  +source->GetElementName()+" "
1015  +this->GetElementName()+" are not of the same type";
1016  throw(std::invalid_argument(loc.Data()));
1017  }
1018  return *this;
1019 }
1021 {
1022  const QwVQWK_Channel* tmpptr;
1023  tmpptr = dynamic_cast<const QwVQWK_Channel*>(source);
1024  if (tmpptr!=NULL){
1025  *this /= *tmpptr;
1026  } else {
1027  TString loc="Standard exception from QwVQWK_Channel::operator/= "
1028  +source->GetElementName()+" "
1029  +this->GetElementName()+" are not of the same type";
1030  throw(std::invalid_argument(loc.Data()));
1031  }
1032  return *this;
1033 }
1034 
1035 
1036 void QwVQWK_Channel::Sum(const QwVQWK_Channel &value1, const QwVQWK_Channel &value2)
1037 {
1038  *this = value1;
1039  *this += value2;
1040 }
1041 
1043 {
1044  *this = value1;
1045  *this -= value2;
1046 }
1047 
1048 void QwVQWK_Channel::Ratio(const QwVQWK_Channel &numer, const QwVQWK_Channel &denom)
1049 {
1050  if (!IsNameEmpty()) {
1051  *this = numer;
1052  *this /= denom;
1053 
1054  // Set the raw values to zero.
1055  for (Int_t i = 0; i < fBlocksPerEvent; i++) fBlock_raw[i] = 0;
1058  // Remaining variables
1060  fSequenceNumber = 0;
1062  fErrorFlag = (numer.fErrorFlag|denom.fErrorFlag);
1063  }
1064 }
1065 
1067 {
1068  // In this function, leave the "raw" variables untouched.
1069  //
1070  Double_t ratio;
1071  Double_t variance;
1072  if (!IsNameEmpty()) {
1073  // The variances are calculated using the following formula:
1074  // Var[ratio] = ratio^2 (Var[numer] / numer^2 + Var[denom] / denom^2)
1075  //
1076  // This requires that both the numerator and denominator are non-zero!
1077  //
1078  for (Int_t i = 0; i < 4; i++) {
1079  if (this->fBlock[i] != 0.0 && denom.fBlock[i] != 0.0){
1080  ratio = (this->fBlock[i]) / (denom.fBlock[i]);
1081  variance = ratio * ratio *
1082  (this->fBlockM2[i] / this->fBlock[i] / this->fBlock[i]
1083  + denom.fBlockM2[i] / denom.fBlock[i] / denom.fBlock[i]);
1084  fBlock[i] = ratio;
1085  fBlockM2[i] = variance;
1086  } else if (this->fBlock[i] == 0.0) {
1087  this->fBlock[i] = 0.0;
1088  this->fBlockM2[i] = 0.0;
1089  } else {
1090  QwVerbose << "Attempting to divide by zero block in "
1091  << GetElementName() << QwLog::endl;
1092  fBlock[i] = 0.0;
1093  fBlockM2[i] = 0.0;
1094  }
1095  }
1096  if (this->fHardwareBlockSum != 0.0 && denom.fHardwareBlockSum != 0.0){
1097  ratio = (this->fHardwareBlockSum) / (denom.fHardwareBlockSum);
1098  variance = ratio * ratio *
1100  + denom.fHardwareBlockSumM2 / denom.fHardwareBlockSum / denom.fHardwareBlockSum);
1101  fHardwareBlockSum = ratio;
1102  fHardwareBlockSumM2 = variance;
1103  } else if (this->fHardwareBlockSum == 0.0) {
1104  fHardwareBlockSum = 0.0;
1105  fHardwareBlockSumM2 = 0.0;
1106  } else {
1107  QwVerbose << "Attempting to divide by zero sum in "
1108  << GetElementName() << QwLog::endl;
1109  fHardwareBlockSumM2 = 0.0;
1110  }
1111  // Remaining variables
1112  // Don't change fNumberOfSamples, fSequenceNumber, fGoodEventCount,
1113  // 'OR' the HW error codes in the fErrorFlag values together.
1114  fErrorFlag |= (denom.fErrorFlag);//mix only the hardware error codes
1115  }
1116 
1117  // Nanny
1119  QwWarning << "Angry Nanny: NaN detected in " << GetElementName() << QwLog::endl;
1120 
1121  return *this;
1122 }
1123 
1124 void QwVQWK_Channel::Product(const QwVQWK_Channel &value1, const QwVQWK_Channel &value2)
1125 {
1126  if (!IsNameEmpty()){
1127  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
1128  this->fBlock[i] = (value1.fBlock[i]) * (value2.fBlock[i]);
1129  this->fBlock_raw[i] = 0;
1130  // For a single event the second moment is still zero
1131  this->fBlockM2[i] = 0.0;
1132  }
1133 
1134  // For a single event the second moment is still zero
1135  this->fHardwareBlockSumM2 = 0.0;
1136 
1137  this->fSoftwareBlockSum_raw = 0;
1139  this->fHardwareBlockSum = value1.fHardwareBlockSum * value2.fHardwareBlockSum;
1140  this->fNumberOfSamples = value1.fNumberOfSamples;
1141  this->fSequenceNumber = 0;
1142  this->fErrorFlag = (value1.fErrorFlag|value2.fErrorFlag);
1143  }
1144  return;
1145 }
1146 
1147 /**
1148 This function will add a offset to the hw_sum and add the same offset for blocks.
1149  */
1151 {
1152  if (!IsNameEmpty()){
1153  fHardwareBlockSum += offset;
1154  for (Int_t i=0; i<fBlocksPerEvent; i++) fBlock[i] += offset;
1155  }
1156  return;
1157 }
1158 
1159 void QwVQWK_Channel::Scale(Double_t scale)
1160 {
1161  if (!IsNameEmpty())
1162  {
1163  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
1164  fBlock[i] *= scale;
1165  fBlockM2[i] *= scale * scale;
1166  }
1167  fHardwareBlockSum *= scale;
1168  fHardwareBlockSumM2 *= scale * scale;
1169  }
1170 }
1171 
1172 
1174 {
1175  *this /= denom;
1176 }
1177 
1178 
1179 
1180 
1181 
1182 
1183 /** Moments and uncertainty calculation on the running sums and averages
1184  * The calculation of the first and second moments of the running sum is not
1185  * completely straightforward due to numerical instabilities associated with
1186  * small variances and large average values. The naive computation taking
1187  * the difference of the square of the average and the average of the squares
1188  * leads to the subtraction of two very large numbers to get a small number.
1189  *
1190  * Alternative algorithms (including for higher order moments) are supplied in
1191  * Pebay, Philippe (2008), "Formulas for Robust, One-Pass Parallel Computation
1192  * of Covariances and Arbitrary-Order Statistical Moments", Technical Report
1193  * SAND2008-6212, Sandia National Laboratories.
1194  * http://infoserve.sandia.gov/sand_doc/2008/086212.pdf
1195  *
1196  * In the following formulas the moments \f$ M^1 \f$ and \f$ M^2 \f$ are defined
1197  * \f{eqnarray}
1198  * M^1 & = & \frac{1}{n} \sum^n y \\
1199  * M^2 & = & \sum^n (y - \mu)
1200  * \f}
1201  *
1202  * Recurrence relations for the addition of a single event:
1203  * \f{eqnarray}
1204  * M^1_n & = & M^1_{n-1} + \frac{y - M^1_{n-1}}{n} \\
1205  * M^2_n & = & M^2_{n-1} + (y - M^1_{n-1})(y - M^1_n)
1206  * \f}
1207  *
1208  * For the addition of an already accumulated sum:
1209  * \f{eqnarray}
1210  * M^1 & = & M^1_1 + n_2 \frac{M^1_2 - M^1_1}{n} \\
1211  * M^2 & = & M^2_1 + M^2_2 + n_1 n_2 \frac{(M^1_2 - M^1_1)^2}{n}
1212  * \f}
1213  *
1214  * In these recursive formulas we start from \f$ M^1 = y \f$ and \f$ M^2 = 0 \f$.
1215  *
1216  * To calculate the mean and standard deviation we use
1217  * \f{eqnarray}
1218  * \mu & = & M^1 \\
1219  * \sigma^2 & = & \frac{1}{n} M^2
1220  * \f}
1221  * The standard deviation is a biased estimator, but this is what ROOT uses.
1222  * Better would be to divide by \f$ (n-1) \f$.
1223  *
1224  * We use the formulas provided there for the calculation of the first and
1225  * second moments (i.e. average and variance).
1226  */
1227 /**
1228  * Accumulate the running moments M1 and M2
1229  * @param value Object (single event or accumulated) to add to running moments
1230  * @param count Number of good events in value
1231  */
1233 {
1234  // Store pointer to running sum
1235  if (value.fRunningSum == 0) {
1236  QwVQWK_Channel* vqwk = const_cast<QwVQWK_Channel*>(&value);
1237  vqwk->fRunningSum = this;
1238  }
1239 
1240  // Moment calculations
1241  Bool_t berror=kTRUE;//only needed for deaccumulation (stability check purposes)
1242 
1243  /*
1244  note:
1245  The AccumulateRunningSum is called on a dedicated subsystem array object and for the standard running avg computations
1246  we only need value.fErrorFlag==0 events to be included in the running avg. So the "berror" conditions is only used for the stability check purposes.
1247 
1248  The need for this check below came due to fact that when routine DeaccumulateRunningSum is called the errorflag is updated with
1249  the kBeamStabilityError flag (+ configuration flags for global errors) and need to make sure we remove this flag and any configuration flags before
1250  checking the (fErrorFlag != 0) condition
1251 
1252  See how the stability check is implemented in the QwEventRing class
1253 
1254  Rakitha
1255  */
1256 
1257  if (count==-1 && value.fErrorFlag>0){
1258  berror=(((value.fErrorFlag) & 0xFFFFFFF) == 0); //The operation value.fErrorFlag & 0xFFFFFFF set the stability failed error bit to zero //-value.fErrorConfigFlag
1259  if (GetElementName()=="qwk_enegy"){//qwk_target_EffectiveCharge
1260  PrintValue();
1261  }
1262  }
1263 
1264 
1265 
1266  Int_t n1 = fGoodEventCount;
1267  Int_t n2 = count;
1268  // If there are no good events, check the error flag
1269  if (n2 == 0 && (value.fErrorFlag) == 0) {
1270  n2 = 1;
1271  //one event is removed from the sum (Deaccumulation)
1272  }else if (n2 == -1 && berror) { //check only single event cut errors except stability fail flag since by the time the value is deaccumulated this could be flagged as stability failed error.
1273  n2 = -1;
1274  }else
1275  n2 = -100;//ignore it
1276  Int_t n = n1 + n2;
1277  // Set up variables
1278  Double_t M11 = fHardwareBlockSum;
1279  Double_t M12 = value.fHardwareBlockSum;
1280  Double_t M22 = value.fHardwareBlockSumM2;
1281  if (n2 == 0) {
1282  // no good events for addition
1283 
1284  return;
1285  } else if (n2 == -1) {
1286  // simple version for removal of single event from the sum
1287  fGoodEventCount--;
1288  //QwMessage<<"Deaccumulate before "<<QwLog::endl;
1289  if (n>0){
1290  fHardwareBlockSum -= (M12 - M11) / n;
1291  fHardwareBlockSumM2 -= (M12 - M11)
1292  * (M12 - fHardwareBlockSum); // note: using updated mean
1293  // and for individual blocks
1294  for (Int_t i = 0; i < 4; i++) {
1295  M11 = fBlock[i];
1296  M12 = value.fBlock[i];
1297  M22 = value.fBlockM2[i];
1298  fBlock[i] -= (M12 - M11) / n;
1299  fBlockM2[i] -= (M12 - M11) * (M12 - fBlock[i]); // note: using updated mean
1300  }
1301  }else if (n==0){
1302  //QwMessage<<"Deaccumulate at zero "<<QwLog::endl;
1303  /*
1304  //Need any fail safe check for Deaccumulation????
1305  */
1306  }
1307 
1308  } else if (n2 == 1) {
1309  // simple version for addition of single event
1310  fGoodEventCount++;
1311  fHardwareBlockSum += (M12 - M11) / n;
1312  fHardwareBlockSumM2 += (M12 - M11)
1313  * (M12 - fHardwareBlockSum); // note: using updated mean
1314  // and for individual blocks
1315  for (Int_t i = 0; i < 4; i++) {
1316  M11 = fBlock[i];
1317  M12 = value.fBlock[i];
1318  M22 = value.fBlockM2[i];
1319  fBlock[i] += (M12 - M11) / n;
1320  fBlockM2[i] += (M12 - M11) * (M12 - fBlock[i]); // note: using updated mean
1321  }
1322  } else if (n2 > 1) {
1323  // general version for addition of multi-event sets
1324  fGoodEventCount += n2;
1325  fHardwareBlockSum += n2 * (M12 - M11) / n;
1326  fHardwareBlockSumM2 += M22 + n1 * n2 * (M12 - M11) * (M12 - M11) / n;
1327  // and for individual blocks
1328  for (Int_t i = 0; i < 4; i++) {
1329  M11 = fBlock[i];
1330  M12 = value.fBlock[i];
1331  M22 = value.fBlockM2[i];
1332  fBlock[i] += n2 * (M12 - M11) / n;
1333  fBlockM2[i] += M22 + n1 * n2 * (M12 - M11) * (M12 - M11) / n;
1334  }
1335  }
1336 
1337  // Nanny
1339  QwWarning << "Angry Nanny: NaN detected in " << GetElementName() << QwLog::endl;
1340 
1341 
1342 
1343 
1344 }
1345 
1346 
1348 {
1349  /*
1350  if (GetElementName()=="qwk_engy"){//qwk_target_EffectiveCharge
1351  PrintValue();
1352  }
1353  */
1354 
1355  if (fGoodEventCount <= 0)
1356  {
1357  for (Int_t i = 0; i < fBlocksPerEvent; i++) {
1358  fBlockError[i] = 0.0;
1359  }
1360  fHardwareBlockSumError = 0.0;
1361  }
1362  else
1363  {
1364  // We use a biased estimator by dividing by n. Use (n - 1) to get the
1365  // unbiased estimator for the standard deviation.
1366  //
1367  // Note we want to calculate the error here, not sigma:
1368  // sigma = sqrt(M2 / n);
1369  // error = sigma / sqrt (n) = sqrt(M2) / n;
1370  for (Int_t i = 0; i < fBlocksPerEvent; i++)
1371  fBlockError[i] = sqrt(fBlockM2[i]) / fGoodEventCount;
1373  //Stability check 83951872
1374  if ((fStability>0) &&( (fErrorConfigFlag & kStabilityCut)==kStabilityCut)){//check to see the channel has stability cut activated in the event cut file
1375  /*
1376  //for Debugging
1377  PrintValue();
1378  */
1379  if (GetValueWidth()>fStability){//if the width is greater than the stability required flag the event
1381  }else
1382  fErrorFlag=0;
1383  }
1384 
1385  }
1386 }
1387 
1388 
1390 {
1391  QwMessage << std::setprecision(4)
1392  << std::setw(18) << std::left << GetSubsystemName() << " "
1393  << std::setw(18) << std::left << GetModuleType() << " "
1394  << std::setw(18) << std::left << GetElementName() << " "
1395  << std::setw(12) << std::left << GetHardwareSum() << "+/- "
1396  << std::setw(12) << std::left << GetHardwareSumError() << " sig "
1397  << std::setw(12) << std::left << GetHardwareSumWidth() << " "
1398  << std::setw(10) << std::left << GetGoodEventCount() << " "
1399  << std::setw(12) << std::left << GetBlockValue(0) << "+/- "
1400  << std::setw(12) << std::left << GetBlockErrorValue(0) << " "
1401  << std::setw(12) << std::left << GetBlockValue(1) << "+/- "
1402  << std::setw(12) << std::left << GetBlockErrorValue(1) << " "
1403  << std::setw(12) << std::left << GetBlockValue(2) << "+/- "
1404  << std::setw(12) << std::left << GetBlockErrorValue(2) << " "
1405  << std::setw(12) << std::left << GetBlockValue(3) << "+/- "
1406  << std::setw(12) << std::left << GetBlockErrorValue(3) << " "
1407  << std::setw(12) << std::left << fGoodEventCount << " "
1408  << QwLog::endl;
1409  /*
1410  //for Debudding
1411  << std::setw(12) << std::left << fErrorFlag << " err "
1412  << std::setw(12) << std::left << fErrorConfigFlag << " c-err "
1413 
1414  */
1415 }
1416 
1417 std::ostream& operator<< (std::ostream& stream, const QwVQWK_Channel& channel)
1418 {
1419  stream << channel.GetHardwareSum();
1420  return stream;
1421 }
1422 
1423 /**
1424  * Blind this channel as an asymmetry
1425  * @param blinder Blinder
1426  */
1427 void QwVQWK_Channel::Blind(const QwBlinder *blinder)
1428 {
1429  if (!IsNameEmpty()) {
1430  if (blinder->IsBlinderOkay() && ((fErrorFlag)==0) ){
1431  for (Int_t i = 0; i < fBlocksPerEvent; i++)
1432  blinder->BlindValue(fBlock[i]);
1433  blinder->BlindValue(fHardwareBlockSum);
1434  } else {
1435  blinder->ModifyThisErrorCode(fErrorFlag);
1436  for (Int_t i = 0; i < fBlocksPerEvent; i++) fBlock[i] = 0.0;
1437  fHardwareBlockSum = 0.0;
1438  }
1439  }
1440  return;
1441 }
1442 
1443 /**
1444  * Blind this channel as a difference with specified yield
1445  * @param blinder Blinder
1446  * @param yield Corresponding yield
1447  */
1448 void QwVQWK_Channel::Blind(const QwBlinder *blinder, const QwVQWK_Channel& yield)
1449 {
1450  if (!IsNameEmpty()) {
1451  if (blinder->IsBlinderOkay() && ((fErrorFlag) ==0) ){
1452  for (Int_t i = 0; i < fBlocksPerEvent; i++)
1453  blinder->BlindValue(fBlock[i], yield.fBlock[i]);
1455  } else {
1456  blinder->ModifyThisErrorCode(fErrorFlag);//update the HW error code
1457  for (Int_t i = 0; i < fBlocksPerEvent; i++) fBlock[i] = 0.0;
1458  fHardwareBlockSum = 0.0;
1459  }
1460  }
1461  return;
1462 }
1463 
1465 {
1466 
1467  Bool_t status = kTRUE;
1468  if (!IsNameEmpty()){
1469  status = (fSequenceNumber==seqnum);
1470  }
1471  return status;
1472 }
1473 
1475 {
1476  Bool_t status = kTRUE;
1477  if (!IsNameEmpty()){
1478  status = (fNumberOfSamples==numsamp);
1479  if (! status){
1480  if (bDEBUG)
1481  std::cerr << "QwVQWK_Channel::MatchNumberOfSamples: Channel "
1482  << GetElementName()
1483  << " had fNumberOfSamples==" << fNumberOfSamples
1484  << " and was supposed to have " << numsamp
1485  << std::endl;
1486  // PrintChannel();
1487  }
1488  }
1489  return status;
1490 }
1491 
1492 Bool_t QwVQWK_Channel::ApplySingleEventCuts(Double_t LL,Double_t UL)//only check to see HW_Sum is within these given limits
1493 {
1494  Bool_t status = kFALSE;
1495 
1496  if (LL==0 && UL==0){
1497  status=kTRUE;
1498  } else if (GetHardwareSum()<=UL && GetHardwareSum()>=LL){
1499  if ((fErrorFlag & kPreserveError)!=0)
1500  status=kTRUE;
1501  else
1502  status=kFALSE;//If the device HW is failed
1503  }
1504  std::cout<<(this->fErrorFlag & kPreserveError)<<std::endl;
1505  return status;
1506 }
1507 
1508 Bool_t QwVQWK_Channel::ApplySingleEventCuts()//This will check the limits and update event_flags and error counters
1509 {
1510  Bool_t status;
1511 
1512  if (bEVENTCUTMODE>=2){//Global switch to ON/OFF event cuts set at the event cut file
1513 
1514  if (fULimit==0 && fLLimit==0){
1515  status=kTRUE;
1516  } else if (GetHardwareSum()<=fULimit && GetHardwareSum()>=fLLimit){
1517  if ((fErrorFlag)==0)
1518  status=kTRUE;
1519  else
1520  status=kFALSE;//If the device HW is failed
1521  }
1522  else{
1523  if (GetHardwareSum()> fULimit)
1525  else
1527  status=kFALSE;
1528  }
1529 
1530  if (bEVENTCUTMODE==3){
1531  status=kTRUE; //Update the event cut fail flag but pass the event.
1532  }
1533 
1534 
1535  }
1536  else{
1537  status=kTRUE;
1538  //fErrorFlag=0;//we need to keep the device error codes
1539  }
1540 
1541  return status;
1542 }
1543 
1545 {
1546  TString message;
1547  message = Form("%30s","Device name");
1548  message += Form("%9s", "HW Sat");
1549  message += Form("%9s", "Sample");
1550  message += Form("%9s", "SW_HW");
1551  message += Form("%9s", "Sequence");
1552  message += Form("%9s", "SameHW");
1553  message += Form("%9s", "ZeroHW");
1554  message += Form("%9s", "EventCut");
1555  QwMessage << "---------------------------------------------------------------------------------------------" << QwLog::endl;
1556  QwMessage << message << QwLog::endl;
1557  QwMessage << "---------------------------------------------------------------------------------------------" << QwLog::endl;
1558  return;
1559 }
1560 
1562 {
1563  QwMessage << "---------------------------------------------------------------------------------------------" << QwLog::endl;
1564  return;
1565 }
1566 
1568 {
1569  TString message;
1571  message = Form("%30s", GetElementName().Data());
1572  message += Form("%9d", fErrorCount_HWSat);
1573  message += Form("%9d", fErrorCount_sample);
1574  message += Form("%9d", fErrorCount_SW_HW);
1575  message += Form("%9d", fErrorCount_Sequence);
1576  message += Form("%9d", fErrorCount_SameHW);
1577  message += Form("%9d", fErrorCount_ZeroHW);
1578  message += Form("%9d", fNumEvtsWithEventCutsRejected);
1579 
1580  if((fDataToSave == kRaw) && (!kFoundPedestal||!kFoundGain)){
1581  message += " >>>>> No Pedestal or Gain in map file";
1582  }
1583 
1584  QwMessage << message << QwLog::endl;
1585  }
1586  return;
1587 }
1588 
1589 void QwVQWK_Channel::ScaledAdd(Double_t scale, const VQwHardwareChannel *value)
1590 {
1591  const QwVQWK_Channel* input = dynamic_cast<const QwVQWK_Channel*>(value);
1592 
1593  // follows same steps as += but w/ scaling factor
1594  if(input!=NULL && !IsNameEmpty()){
1595  // QwWarning << "Adding " << input->GetElementName()
1596  // << " to " << GetElementName()
1597  // << " with scale factor " << scale
1598  // << QwLog::endl;
1599  // PrintValue();
1600  // input->PrintValue();
1601  for(Int_t i = 0; i < fBlocksPerEvent; i++){
1602  this -> fBlock[i] += scale * input->fBlock[i];
1603  this->fBlock_raw[i] = 0;
1604  this -> fBlockM2[i] = 0.0;
1605  }
1606  this->fHardwareBlockSum_raw = 0;
1607  this->fSoftwareBlockSum_raw = 0;
1608  this -> fHardwareBlockSum += scale * input->fHardwareBlockSum;
1609  this -> fHardwareBlockSumM2 = 0.0;
1610  this -> fNumberOfSamples += input->fNumberOfSamples;
1611  this -> fSequenceNumber = 0;
1612  this -> fErrorFlag |= (input->fErrorFlag);
1613  }
1614  // QwWarning << "Finsihed with addition" << QwLog::endl;
1615  // PrintValue();
1616 }
1617 
1618 void QwVQWK_Channel::AddErrEntriesToList(std::vector<QwErrDBInterface> &row_list)
1619 {
1620 
1621  // TString message;
1622  // message = Form("%30s",GetElementName().Data());
1623  // message += Form("%9d", fErrorCount_HWSat);
1624  // message += Form("%9d", fErrorCount_sample);
1625  // message += Form("%9d", fErrorCount_SW_HW);
1626  // message += Form("%9d", fErrorCount_Sequence);
1627  // message += Form("%9d", fErrorCount_SameHW);
1628  // message += Form("%9d", fErrorCount_ZeroHW);
1629  // message += Form("%9d", fNumEvtsWithEventCutsRejected);
1630  // QwMessage << message << QwLog::endl;
1631 
1632  // kErrorFlag_VQWK_Sat =0x1; //VQWK Saturation Cut. Currently saturation limit is set to +/-8.5V
1633  // kErrorFlag_sample =0x2; //If sample size mis-matches with the default value in the map file.
1634  // kErrorFlag_SW_HW =0x4; //If software sum and hardware sum are not equal.
1635  // kErrorFlag_Sequence =0x8; //If the ADC sequence number is not incrementing properly
1636  // kErrorFlag_SameHW =0x10; //If ADC value keep returning the same value
1637  // kErrorFlag_ZeroHW =0x20; //Check to see ADC is returning zero
1638 
1639 
1640 
1641  // kErrorFlag_EventCut_L =0x40; //Flagged if lower limit of the event cut has failed
1642  // kErrorFlag_EventCut_U =0x80; //Flagged if upper limit of the event cut has failed
1643  // >>>>>> fNumEvtsWithEventCutsRejected
1644 
1645 
1646  // outside QwVQWK_Channel
1647  // kErrorFlag_BlinderFail = 0x0200;// in Decimal 512 to identify the blinder fail flag
1648  // kStabilityCutError = 0x10000000;// in Decimal 2^28 to identify the stability cut failure
1649 
1650  // This is my modified mysql DB, Thursday, December 8 16:40:36 EST 2011, jhlee
1651  // Error code must be matched to MySQL DB
1652  //
1653  // mysql> select * from error_code;
1654  // +---------------+------------------------------+
1655  // | error_code_id | quantity |
1656  // +---------------+------------------------------+
1657  // | 1 | kErrorFlag_VQWK_Sat |
1658  // | 2 | kErrorFlag_sample |
1659  // | 3 | kErrorFlag_SW_HW |
1660  // | 4 | kErrorFlag_Sequence |
1661  // | 5 | kErrorFlag_SameHW |
1662  // | 6 | kErrorFlag_ZeroHW |
1663  // | 7 | kErrorFlag_EventCut_Rejected |
1664  // | 8 | kErrorFlag_EventCut_L |
1665  // | 9 | kErrorFlag_EventCut_U |
1666  // | 10 | kErrorFlag_BlinderFail |
1667  // | 11 | kStabilityCutError |
1668  // +---------------+------------------------------+
1669  // 11 rows in set (0.00 sec)
1670 
1671 
1672  QwErrDBInterface row;
1673  TString name = GetElementName();
1674 
1675  row.Reset();
1676  row.SetDeviceName(name);
1677  row.SetErrorCodeId(1);
1678  row.SetN(fErrorCount_HWSat);
1679  row_list.push_back(row);
1680 
1681  row.Reset();
1682  row.SetDeviceName(name);
1683  row.SetErrorCodeId(2);
1684  row.SetN(fErrorCount_sample);
1685  row_list.push_back(row);
1686 
1687  row.Reset();
1688  row.SetDeviceName(name);
1689  row.SetErrorCodeId(3);
1690  row.SetN(fErrorCount_SW_HW);
1691  row_list.push_back(row);
1692 
1693 
1694  row.Reset();
1695  row.SetDeviceName(name);
1696  row.SetErrorCodeId(4);
1698  row_list.push_back(row);
1699 
1700 
1701  row.Reset();
1702  row.SetDeviceName(name);
1703  row.SetErrorCodeId(5);
1704  row.SetN(fErrorCount_SameHW);
1705  row_list.push_back(row);
1706 
1707  row.Reset();
1708  row.SetDeviceName(name);
1709  row.SetErrorCodeId(6);
1710  row.SetN(fErrorCount_ZeroHW);
1711  row_list.push_back(row);
1712 
1713 
1714  row.Reset();
1715  row.SetDeviceName(name);
1716  row.SetErrorCodeId(7);
1718  row_list.push_back(row);
1719  return;
1720 
1721 }
static const double pi
Angles: base unit is radian.
Definition: QwUnits.h:102
static const Int_t kWordsPerChannel
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
static const UInt_t kErrorFlag_SW_HW
Definition: QwTypes.h:160
Int_t ProcessEvBuffer(UInt_t *buffer, UInt_t num_words_left, UInt_t index=0)
Decode the event data from a CODA buffer.
static const UInt_t kErrorFlag_ZeroHW
Definition: QwTypes.h:163
void ProcessEvent()
Process the event data according to pedestal and calibration factor.
Int_t GetRawSoftwareSum() const
Bool_t ApplySingleEventCuts()
Int_t fErrorCount_Sequence
sequence number check
size_t GetNumberOfSamples() const
UInt_t GetGoodEventCount() const
void RandomizeEventData(int helicity=0.0, double time=0.0)
Internally generate random event data.
Int_t fErrorCount_sample
for sample size check
Short_t fBlocksPerEvent
void AssignValueFrom(const VQwDataElement *valueptr)
std::ostream & operator<<(std::ostream &out, const QwColor &color)
Output stream operator which uses the enum-to-escape-code mapping.
Definition: QwColor.h:153
Int_t ApplyHWChecks()
static const UInt_t kErrorFlag_sample
Definition: QwTypes.h:159
Double_t GetHardwareSumWidth() const
const Bool_t & IsBlinderOkay() const
Definition: QwBlinder.h:193
QwVQWK_Channel & operator=(const QwVQWK_Channel &value)
void BlindValue(Double_t &value) const
Asymmetry blinding.
Definition: QwBlinder.h:124
Double_t GetHardwareSumError() const
void Ratio(const QwVQWK_Channel &numer, const QwVQWK_Channel &denom)
void ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector< Double_t > &values)
void AssignScaledValue(const QwVQWK_Channel &value, Double_t scale)
Bool_t IsNameEmpty() const
Is the name of this element empty?
UInt_t fNumberOfDataWords
Number of raw data words in this data element.
Class for blinding data, adapted from G0 blinder class.
Definition: QwBlinder.h:64
Bool_t MatchNumberOfSamples(size_t numsamp)
std::vector< Double_t > fMockDriftPhase
Harmonic drift phase.
Definition: MQwMockable.h:96
void PrintInfo() const
Print multiple lines of information about this data element.
std::vector< Double_t > fMockDriftFrequency
Harmonic drift frequency.
Definition: MQwMockable.h:95
static const UInt_t kErrorFlag_SameHW
Definition: QwTypes.h:162
Double_t fHardwareBlockSumM2
Second moment of the hardware sum.
std::vector< TH1_ptr > fHistograms
Histograms associated with this data element.
Definition: MQwHistograms.h:46
void SetEventData(Double_t *block, UInt_t sequencenumber=0)
void DivideBy(const VQwHardwareChannel *valueptr)
#define QwVerbose
Predefined log drain for verbose messages.
Definition: QwLog.h:55
void SetDefaultSampleSize(size_t num_samples_map)
Double_t fMockGaussianSigma
Sigma of normal distribution.
Definition: MQwMockable.h:93
void Scale(Double_t Offset)
Int_t fErrorCount_ZeroHW
check to see ADC returning zero
Double_t fHardwareBlockSumError
Uncertainty on the hardware sum.
void SetDataToSave(TString datatosave)
Set the flag indicating if raw or derived values are in this data element.
Int_t fErrorCount_SW_HW
HW_sum==SW_sum check.
void ConstructBranch(TTree *tree, TString &prefix)
size_t fNumberOfSamples_map
Number of samples in the expected to read through the module. This value is set in the QwBeamline map...
Int_t fHardwareBlockSum_raw
Module-based sum of the four sub-blocks as read from the module.
Int_t GetRawHardwareSum() const
VQwHardwareChannel & operator/=(const VQwHardwareChannel *input)
void SetNumberOfDataWords(const UInt_t &numwords)
Set the number of data words in this data element.
Bool_t bDevice_Error_Code
Bool_t ReturnValue(const std::string keyname, T &retvalue)
TString GetModuleType() const
Return the type of the beam instrument.
size_t fSequenceNumber
Event sequence number for this channel.
static void PrintErrorCounterHead()
Int_t fErrorCount_HWSat
check to see ADC channel is saturated
void SetHardwareSum(Double_t hwsum, UInt_t sequencenumber=0)
const QwVQWK_Channel operator*(const QwVQWK_Channel &value) const
const QwVQWK_Channel operator-(const QwVQWK_Channel &value) const
Int_t fSoftwareBlockSum_raw
Sum of the data in the four sub-blocks raw.
void ConstructHistograms(TDirectory *folder, TString &prefix)
Construct the histograms for this data element.
Bool_t MatchDeviceParamsFromList(const std::string &devicename)
void SetNumberOfSubElements(const size_t elements)
Set the number of data words in this data element.
bool fUseExternalRandomVariable
Flag to use an externally provided normal random variable.
Definition: MQwMockable.h:86
static const Bool_t kDEBUG
Int_t fSequenceNo_Counter
Internal counter to keep track of the sequence number.
The pure virtual base class of all data elements.
QwVQWK_Channel & operator*=(const QwVQWK_Channel &value)
void ModifyThisErrorCode(UInt_t &errorcode) const
Definition: QwBlinder.h:119
Double_t fHardwareBlockSum
Module-based sum of the four sub-blocks.
Double_t fBlockError[4]
Uncertainty on the sub-block.
void PrintValue() const
Print single line of value and error of this data element.
A logfile class, based on an identical class in the Hermes analyzer.
Double_t GetRandomValue()
Definition: MQwMockable.cc:54
void SetSubsystemName(TString sysname)
Set the name of the inheriting subsystem name.
Bool_t MatchVQWKElementFromList(const std::string &subsystemname, const std::string &moduletype, const std::string &devicename)
static const UInt_t kErrorFlag_Sequence
Definition: QwTypes.h:161
void ScaledAdd(Double_t scale, const VQwHardwareChannel *value)
void ClearEventData()
Clear the event data in this element.
Double_t fPrev_HardwareBlockSum
Previous Module-based sum of the four sub-blocks.
Double_t fMockGaussianMean
Mean of normal distribution.
Definition: MQwMockable.h:92
Bool_t bSequence_number
QwVQWK_Channel & operator-=(const QwVQWK_Channel &value)
Int_t fBlock_raw[4]
Array of the sub-block data as read from the module.
Int_t fErrorCount_SameHW
check to see ADC returning same HW value
Int_t GetRawBlockValue(size_t blocknum) const
Int_t fSequenceNo_Prev
Keep the sequence number of the last event.
void FillTreeVector(std::vector< Double_t > &values) const
Double_t GetAverageVolts() const
TString GetSubsystemName() const
Return the name of the inheriting subsystem name.
std::vector< Double_t > fMockDriftAmplitude
Harmonic drift amplitude.
Definition: MQwMockable.h:94
void SetElementName(const TString &name)
Set the name of this element.
static const UInt_t kPreserveError
Definition: QwTypes.h:179
UInt_t fErrorFlag
This the standard error code generated for the channel that contains the global/local/stability flags...
Double_t fMockAsymmetry
Helicity asymmetry.
Definition: MQwMockable.h:91
QwVQWK_Channel * fRunningSum
Pointer to the running sum for this channel.
void SetN(UInt_t in)
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
void PrintErrorCounters() const
report number of events failed due to HW and event cut failure
static const UInt_t kBeamStabilityError
Definition: QwTypes.h:174
A class for blinding data, adapted from G0 blinder class.
void FillHistograms()
Fill the histograms for this data element.
UInt_t fErrorConfigFlag
contains the global/local/stability flags
void Product(const QwVQWK_Channel &value1, const QwVQWK_Channel &value2)
Double_t GetBlockValue(size_t blocknum) const
void Sum(const QwVQWK_Channel &value1, const QwVQWK_Channel &value2)
void SetErrorCodeId(UInt_t in)
Int_t fNumEvtsWithEventCutsRejected
Counts the Event cut rejected events.
virtual VQwHardwareChannel & operator=(const VQwHardwareChannel &value)
Arithmetic assignment operator: Should only copy event-based data.
static const Double_t kVQWK_VoltsPerBit
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void SetModuleType(TString ModuleType)
set the type of the beam instrument
static const UInt_t kErrorFlag_EventCut_L
Definition: QwTypes.h:164
Int_t fGoodEventCount
Number of good events accumulated in this element.
Double_t fBlockM2[4]
Second moment of the sub-block.
virtual const TString & GetElementName() const
Get the name of this element.
void AddValueFrom(const VQwHardwareChannel *valueptr)
void Difference(const QwVQWK_Channel &value1, const QwVQWK_Channel &value2)
Double_t GetBlockErrorValue(size_t blocknum) const
size_t fPreviousSequenceNumber
Previous event sequence number for this channel.
void SetDeviceName(TString &in)
void MultiplyBy(const VQwHardwareChannel *valueptr)
Int_t fADC_Same_NumEvt
Keep track of how many events with same ADC value returned.
QwVQWK_Channel & operator+=(const QwVQWK_Channel &value)
void EncodeEventData(std::vector< UInt_t > &buffer)
Encode the event data into a CODA buffer.
static void PrintErrorCounterTail()
size_t fNumberOfSamples
Number of samples read through the module.
static Int_t GetBufferOffset(Int_t moduleindex, Int_t channelindex)
size_t GetSequenceNumber() const
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
static const Bool_t bDEBUG
debugging display purposes
Double_t GetValueWidth() const
Double_t GetHardwareSum() const
void InitializeChannel(TString name, TString datatosave)
Initialize the fields in this object.
Double_t fBlock[4]
Array of the sub-block data.
void AddChannelOffset(Double_t Offset)
void AddErrEntriesToList(std::vector< QwErrDBInterface > &row_list)
static const UInt_t kStabilityCut
Definition: QwTypes.h:178
void IncrementErrorCounters()
const QwVQWK_Channel operator+(const QwVQWK_Channel &value) const
static const UInt_t kErrorFlag_VQWK_Sat
Definition: QwTypes.h:158
Double_t GetVQWKSaturationLimt()
TH1F * Construct1DHist(const TString &inputfile, const TString &name_title)
Bool_t MatchSequenceNumber(size_t seqnum)
static const Int_t kMaxChannels
static const UInt_t kErrorFlag_EventCut_U
Definition: QwTypes.h:165
void CalculateRunningAverage()
void SubtractValueFrom(const VQwHardwareChannel *valueptr)
void Blind(const QwBlinder *blinder)
Blind this channel as an asymmetry.
void LoadChannelParameters(QwParameterFile &paramfile)
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40
void AccumulateRunningSum(const QwVQWK_Channel &value)