8#include <boost/algorithm/string.hpp>
114 Int_t kMaxWords = 32;
117 QwError <<
"QwScaler_Channel::GetBufferOffset: Invalid scaler index,"
119 <<
". Must be zero or greater."
121 }
else if (scalerindex<0 || wordindex>kMaxWords){
122 QwError <<
"QwScaler_Channel::GetBufferOffset: Invalid word index,"
124 <<
". Must be in range [0," << kMaxWords <<
"]."
127 offset = (header + kMaxWords)*scalerindex + header + wordindex ;
142 std::string varvalue;
144 boost::to_lower(varvalue);
150template<
unsigned int data_mask,
unsigned int data_shift>
156 buffer.push_back( 0 );
158 buffer.push_back( ((this->
fValue_Raw<<data_shift)&data_mask) );
164template<
unsigned int data_mask,
unsigned int data_shift>
168 UInt_t words_read = 0;
174 fHeader = (buffer[0] & ~data_mask);
175 fValue_Raw = ((buffer[0] & data_mask) >> data_shift);
200 QwWarning <<
"VQwScaler_Channel::ProcessEvent: "
201 <<
"Missing the reference clock, "
203 <<
", for data element "
217 << std::setw(12) << std::left <<
GetValue() <<
" +/- "
233 if (folder != NULL) folder->cd();
261template<
unsigned int data_mask,
unsigned int data_shift>
270 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length()) +
GetElementName();
279 values.
push_back(
"Device_Error_Code",
'i');
282 if ((~data_mask) != 0){
288 if (
gQwHists.MatchDeviceParamsFromList(basename.Data()))
300 tree->Branch(basename, &
fValue, basename+
"/D");
304template<
unsigned int data_mask,
unsigned int data_shift>
311 static bool warned =
false;
313 QwError <<
"VQwScaler_Channel::FillTreeVector: fTreeArrayNumEntries=="
319 QwError <<
"VQwScaler_Channel::FillTreeVector: values.size()=="
321 <<
"; fTreeArrayIndex+fTreeArrayNumEntries=="
336 if ((~data_mask) != 0){
343#ifdef HAS_RNTUPLE_SUPPORT
344template<
unsigned int data_mask,
unsigned int data_shift>
351 SetDataToSaveByPrefix(prefix);
353 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length()) + GetElementName();
354 fTreeArrayIndex = values.size();
357 size_t numElements = 2;
358 if (fDataToSave == kMoments) numElements += 3;
359 if (fDataToSave == kRaw) {
361 if ((~data_mask) != 0) numElements += 1;
365 size_t oldSize = values.size();
366 values.resize(oldSize + numElements, 0.0);
367 fieldPtrs.reserve(fieldPtrs.size() + numElements);
370 fieldPtrs.push_back(model->MakeField<Double_t>(basename.Data()));
372 if (fDataToSave == kMoments) {
373 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_m2").Data()));
374 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_err").Data()));
375 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_num_samples").Data()));
379 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_Device_Error_Code").Data()));
381 if(fDataToSave==kRaw){
382 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_raw").Data()));
384 if ((~data_mask) != 0){
385 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_header").Data()));
389 fTreeArrayNumEntries = values.size() - fTreeArrayIndex;
393template<
unsigned int data_mask,
unsigned int data_shift>
398 }
else if (fTreeArrayNumEntries < 0) {
399 QwError <<
"QwScaler_Channel::FillNTupleVector: fTreeArrayNumEntries=="
401 }
else if (fTreeArrayNumEntries == 0) {
402 static bool warned =
false;
404 QwError <<
"QwScaler_Channel::FillNTupleVector: fTreeArrayNumEntries=="
405 << fTreeArrayNumEntries <<
" (no construction done?)" <<
QwLog::endl;
409 }
else if (values.size() < fTreeArrayIndex+fTreeArrayNumEntries) {
410 QwError <<
"QwScaler_Channel::FillNTupleVector: values.size()=="
411 << values.size() <<
" name: " << fElementName
412 <<
"; fTreeArrayIndex+fTreeArrayNumEntries=="
413 << fTreeArrayIndex <<
'+' << fTreeArrayNumEntries <<
'='
414 << fTreeArrayIndex+fTreeArrayNumEntries
417 size_t index = fTreeArrayIndex;
418 values[index++] = this->fValue;
419 if (fDataToSave == kMoments) {
420 values[index++] = fValueM2;
421 values[index++] = fValueError;
422 values[index++] = fGoodEventCount;
424 values[index++] = this->fErrorFlag;
425 if(fDataToSave==kRaw){
426 values[index++] = this->fValue_Raw;
427 if ((~data_mask) != 0){
428 values[index++] = this->fHeader;
442 TString loc=
"Standard exception from VQwScaler_Channel::AssignValueFrom = "
444 throw std::invalid_argument(loc.Data());
454 TString loc=
"Standard exception from VQwScaler_Channel::AddValueFrom = "
456 throw std::invalid_argument(loc.Data());
466 TString loc=
"Standard exception from VQwScaler_Channel::SubtractValueFrom = "
468 throw std::invalid_argument(loc.Data());
478 TString loc=
"Standard exception from VQwScaler_Channel::MultiplyBy = "
480 throw std::invalid_argument(loc.Data());
491 TString loc=
"Standard exception from VQwScaler_Channel::DivideBy = "
493 throw std::invalid_argument(loc.Data());
499 if(
this == &value)
return *
this;
563 }
catch(
const std::exception& e) {
564 TString loc=
"Standard exception from VQwScaler_Channel::operator+= "
567 throw(std::invalid_argument(loc.Data()));
578 TString loc=
"Standard exception from VQwScaler_Channel::operator-= "
581 throw(std::invalid_argument(loc.Data()));
592 TString loc=
"Standard exception from VQwScaler_Channel::operator*= "
595 throw(std::invalid_argument(loc.Data()));
606 TString loc=
"Standard exception from VQwScaler_Channel::operator/= "
609 throw(std::invalid_argument(loc.Data()));
654 variance = ratio * ratio *
659 }
else if (this->
fValue == 0.0) {
663 QwVerbose <<
"Attempting to divide by zero in "
826 Double_t M12 = value.
fValue;
831 }
else if (n2 == -1) {
835 fValue -= (M12 - M11) / n;
839 fValue -= (M12 - M11) / n;
842 if (fabs(
fValueM2) < 10.*std::numeric_limits<double>::epsilon())
847 if (fabs(
fValue) < 10.*std::numeric_limits<double>::epsilon())
849 if (fabs(
fValueM2) < 10.*std::numeric_limits<double>::epsilon())
854 }
else if (n2 == 1) {
857 fValue += (M12 - M11) / n;
862 fValue += n2 * (M12 - M11) / n;
863 fValueM2 += M22 + n1 * n2 * (M12 - M11) * (M12 - M11) / n;
890 <<
" events with a hardware failure."
896 <<
" events rejected by Event Cuts."
909 }
else if (input == NULL && value != NULL) {
910 TString loc=
"Standard exception from VQwScaler_Channel::ScaledAdd "
913 throw(std::invalid_argument(loc.Data()));
Helper functions and utilities for ROOT histogram management.
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
Base and derived classes for scaler channel data handling.
A logfile class, based on an identical class in the Hermes analyzer.
#define QwVerbose
Predefined log drain for verbose messages.
#define QwError
Predefined log drain for errors.
#define QwWarning
Predefined log drain for warnings.
#define QwMessage
Predefined log drain for regular messages.
ROOT file and tree management wrapper classes.
static const UInt_t kErrorFlag_ZeroHW
static const UInt_t kErrorFlag_EventCut_L
static const UInt_t kErrorFlag_EventCut_U
static const UInt_t kPreserveError
static const double pi
Angles: base unit is radian.
std::vector< TH1_ptr > fHistograms
Histograms associated with this data element.
std::vector< Double_t > fMockDriftAmplitude
Harmonic drift amplitude.
std::vector< Double_t > fMockDriftFrequency
Harmonic drift frequency.
Double_t fMockAsymmetry
Helicity asymmetry.
Double_t fMockGaussianSigma
Sigma of normal distribution.
Double_t fMockGaussianMean
Mean of normal distribution.
std::vector< Double_t > fMockDriftPhase
Harmonic drift phase.
void SetRandomEventParameters(Double_t mean, Double_t sigma)
Set the normal random event parameters.
Double_t GetRandomValue()
static std::ostream & endl(std::ostream &)
End of the line.
Configuration file parser with flexible tokenization and search capabilities.
Bool_t ReturnValue(const std::string keyname, T &retvalue)
A helper class to manage a vector of branch entries for ROOT trees.
size_type size() const noexcept
std::string LeafList(size_type start_index=0) const
void push_back(const std::string &name, const char type='D')
void SetValue(size_type index, Double_t val)
static const Bool_t kDEBUG
void Difference(VQwScaler_Channel &value1, VQwScaler_Channel &value2)
void InitializeChannel(TString name, TString datatosave="raw") override
Initialize the fields in this object.
Double_t GetValueError() const
void Product(VQwScaler_Channel &numer, VQwScaler_Channel &denom)
void ProcessEvent() override
Bool_t fIsDifferentialScaler
void ClearEventData() override
Clear the event data in this element.
void Scale(Double_t Offset) override
Bool_t NeedsExternalClock() override
void AddValueFrom(const VQwHardwareChannel *valueptr) override
Double_t fClockNormalization
void LoadChannelParameters(QwParameterFile ¶mfile) override
void SubtractValueFrom(const VQwHardwareChannel *valueptr) override
void ConstructHistograms(TDirectory *folder, TString &prefix) override
Construct the histograms for this data element.
Bool_t ApplySingleEventCuts() override
void RandomizeEventData(int helicity=0, double time=0.0) override
Internally generate random event data.
void ConstructBranch(TTree *tree, TString &prefix) override
VQwScaler_Channel & operator=(const VQwScaler_Channel &value)
Int_t fNumEvtsWithHWErrors
void Sum(VQwScaler_Channel &value1, VQwScaler_Channel &value2)
void SetExternalClockName(const std::string name) override
void FillHistograms() override
Fill the histograms for this data element.
VQwHardwareChannel & operator/=(const VQwHardwareChannel &input) override
Bool_t fNeedsExternalClock
void PrintInfo() const override
Print multiple lines of information about this data element.
static Int_t GetBufferOffset(Int_t scalerindex, Int_t wordindex, UInt_t header=1)
void PrintErrorCounters() const override
report number of events failed due to HW and event cut failure
void ScaledAdd(Double_t scale, const VQwHardwareChannel *value) override
std::string fNormChannelName
void SmearByResolution(double resolution) override
void SetRawEventData() override
void MultiplyBy(const VQwHardwareChannel *valueptr) override
Int_t ApplyHWChecks() override
VQwScaler_Channel & operator+=(const VQwScaler_Channel &value)
virtual Bool_t IsDifferentialScaler()
Double_t GetValueWidth() const
const VQwHardwareChannel * fNormChannelPtr
void PrintValue() const override
Print single line of value and error of this data element.
void SetEventData(Double_t value)
VQwScaler_Channel & operator*=(const VQwScaler_Channel &value)
void CalculateRunningAverage() override
void Ratio(const VQwScaler_Channel &numer, const VQwScaler_Channel &denom)
Double_t GetValue() const
void DivideBy(const VQwHardwareChannel *valueptr) override
VQwScaler_Channel & operator-=(const VQwScaler_Channel &value)
Int_t fNumEvtsWithEventCutsRejected
Int_t GetRawValue() const
void AddChannelOffset(Double_t Offset)
void IncrementErrorCounters() override
void AssignValueFrom(const VQwDataElement *valueptr) override
void AssignScaledValue(const VQwScaler_Channel &value, Double_t scale)
void AccumulateRunningSum(const VQwScaler_Channel &value, Int_t count=0, Int_t ErrorMask=0xFFFFFFF)
Templated concrete scaler channel with configurable data masking.
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values) override
Int_t ProcessEvBuffer(UInt_t *buffer, UInt_t num_words_left, UInt_t index=0) override
Process the CODA event buffer for this element.
virtual VQwHardwareChannel * Clone() const
void EncodeEventData(std::vector< UInt_t > &buffer) override
Encode the event data into a CODA buffer.
void FillTreeVector(QwRootTreeBranchVector &values) const override
UInt_t fGoodEventCount
Number of good events accumulated in this element.
VQwDataElement()
Default constructor.
UInt_t fErrorConfigFlag
contains the global/local/stability flags
void SetSubsystemName(TString sysname)
Set the name of the inheriting subsystem name.
TString fElementName
Name of this data element.
virtual const TString & GetElementName() const
Get the name of this element.
UInt_t fErrorFlag
This the standard error code generated for the channel that contains the global/local/stability flags...
void SetElementName(const TString &name)
Set the name of this element.
Bool_t IsNameEmpty() const
Is the name of this element empty?
TString GetSubsystemName() const
Return the name of the inheriting subsystem name.
UInt_t GetGoodEventCount() const
TString GetModuleType() const
Return the type of the beam instrument.
void SetModuleType(TString ModuleType)
set the type of the beam instrument
Abstract base for concrete hardware channels implementing dual-operator pattern.
void SetDataToSave(TString datatosave)
Set the flag indicating if raw or derived values are in this data element.
Double_t fCalibrationFactor
void SetNumberOfSubElements(const size_t elements)
Set the number of data words in this data element.
size_t fTreeArrayNumEntries
VQwHardwareChannel & operator=(const VQwHardwareChannel &value)
Arithmetic assignment operator: Should only copy event-based data.
void SetNumberOfDataWords(const UInt_t &numwords)
Set the number of data words in this data element.
UInt_t fNumberOfDataWords
Number of raw data words in this data element.
void SetDataToSaveByPrefix(const TString &prefix)
Set the flag indicating if raw or derived values are in this data element based on prefix.