17#ifdef __USE_DATABASE__
46 QwError <<
"QwMollerADC_Channel::GetBufferOffset: Invalid module index,"
48 <<
". Must be zero or greater."
51 QwError <<
"QwMollerADC_Channel::GetBufferOffset: Invalid channel index,"
66 Bool_t fEventIsGood=kTRUE;
242 <<
" cannot set the default sample size."
274 Double_t drift = 0.0;
373 fNumberOfSamples = fNumberOfSamples_map;
374 fHardwareBlockSum_raw = 0;
377 for (Int_t i = 0; i < fBlocksPerEvent; i++)
379 Double_t block_raw = (fBlock[i] / fCalibrationFactor + fPedestal) * fNumberOfSamples / (fBlocksPerEvent * 1.0);
380 if (std::abs(block_raw) >= pow(2,29)) {
381 block_raw = std::copysign(pow(2,29)-1, block_raw);
382 QwWarning <<
"QwMollerADC_Channel::SetRawEventData: Overflow in conversion to raw data for channel "
383 << this->GetElementName() <<
": ("
384 <<
"fBlock[i] = " << fBlock[i] <<
" / "
385 <<
"fCalibrationFactor = " << fCalibrationFactor <<
" + "
386 <<
"fPedestal = " << fPedestal <<
") * "
387 <<
"fNumberOfSamples = " << fNumberOfSamples <<
" / "
388 <<
"fBlocksPerEvent = " << fBlocksPerEvent <<
". "
389 <<
"Capping value to " << block_raw <<
"."
392 fBlock_raw[i] = Int_t(block_raw);
393 fHardwareBlockSum_raw += fBlock_raw[i];
395 double_t block = fBlock[i] / fCalibrationFactor;
396 double_t sigma = fMockGaussianSigma / fCalibrationFactor;
397 fBlockSumSq_raw[i] = (sigma*sigma + block*block)*fNumberOfSamples_map / (fBlocksPerEvent * 1.0);
398 fBlock_min[i] = (block - 3.0 * sigma) * double_t(fNumberOfSamples_map) / (fBlocksPerEvent * 1.0);
399 fBlock_max[i] = (block + 3.0 * sigma) * double_t(fNumberOfSamples_map) / (fBlocksPerEvent * 1.0);
401 fBlockSumSq_raw[4] += fBlockSumSq_raw[i];
402 fBlock_min[4] = TMath::Min(fBlock_min[i],fBlock_min[4]);
403 fBlock_max[4] = TMath::Max(fBlock_max[i],fBlock_max[4]);
408 fSoftwareBlockSum_raw = fHardwareBlockSum_raw;
422 for (Int_t i = 0; i < 4; i++) {
442 buffer.push_back(localbuf[i]);
451 UInt_t words_read = 0;
464 localbuf[i] = buffer[i];
465 localbuf_signed[i] =
static_cast<Int_t
>(localbuf[i]);
492 std::cerr <<
"QwMollerADC_Channel::ProcessEvBuffer: Not enough words!"
514 QwWarning <<
"QwMollerADC_Channel::ProcessEvent: Channel "
516 <<
" has fNumberOfSamples==0 but has valid data in the hardware sum. "
517 <<
"Flag this as an error."
548 std::cout<<
"***************************************"<<
"\n";
550 std::cout<<
"Beam Instrument Type: "<<
GetModuleType()<<
"\n"<<
"\n";
552 std::cout<<
"fPedestal= "<<
fPedestal<<
"\n";
557 std::cout<<
"fBlock_raw ";
564 std::cout<<
"fBlock ";
566 std::cout <<
" : " <<std::setprecision(8) <<
fBlock[i];
567 std::cout << std::endl;
569 std::cout <<
"fHardwareBlockSum = "<<std::setprecision(8) <<
fHardwareBlockSum << std::endl;
579 if (folder != NULL) folder->cd();
690 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length()) +
GetElementName();
723 values.
push_back(
"Device_Error_Code",
'i');
737 for (
int i = 0; i < 4; i++) {
739 values.
push_back(Form(
"SumSq_%d", i),
'L');
740 values.
push_back(Form(
"RawMin_%d", i),
'I');
741 values.
push_back(Form(
"RawMax_%d", i),
'I');
746 values.
push_back(
"sequence_number",
'i');
754 if (
gQwHists.MatchDeviceParamsFromList(basename.Data())
759 if (leaf_list ==
"hw_sum/D")
760 leaf_list = basename+
"/D";
769 std::cerr <<
"QwMollerADC_Channel::ConstructBranchAndVector: fTreeArrayIndex==" <<
fTreeArrayIndex
771 <<
"; values.size()==" << values.
size()
772 <<
"; list==" << leaf_list
785 std::cerr <<
"QwMollerADC_Channel::ConstructBranchAndVector: fTreeArrayIndex==" <<
fTreeArrayIndex
797 if (
bDEBUG) std::cerr <<
"QwMollerADC_Channel::FillTreeVector: fTreeArrayNumEntries=="
800 if (
bDEBUG) std::cerr <<
"QwMollerADC_Channel::FillTreeVector: values.size()=="
802 <<
"; fTreeArrayIndex+fTreeArrayNumEntries=="
846 for (
int i = 0; i < 4; i++) {
859#ifdef HAS_RNTUPLE_SUPPORT
860void QwMollerADC_Channel::ConstructNTupleAndVector(std::unique_ptr<ROOT::RNTupleModel>& model, TString& prefix, std::vector<Double_t>& values, std::vector<std::shared_ptr<Double_t>>& fieldPtrs)
886 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length()) +
GetElementName();
892 values.resize(values.size() + 1, 0.0);
893 fieldPtrs.push_back(model->MakeField<Double_t>(basename.Data()));
902 values.push_back(0.0);
903 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_hw_sum").Data()));
904 values.push_back(0.0);
905 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_hw_sum_m2").Data()));
906 values.push_back(0.0);
907 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_hw_sum_err").Data()));
912 values.push_back(0.0);
913 fieldPtrs.push_back(model->MakeField<Double_t>((basename + Form(
"_block%d", i)).Data()));
918 values.push_back(0.0);
919 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_num_samples").Data()));
923 values.push_back(0.0);
924 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_Device_Error_Code").Data()));
933 size_t numElements = 0;
951 size_t oldSize = values.size();
952 values.resize(oldSize + numElements, 0.0);
953 fieldPtrs.reserve(fieldPtrs.size() + numElements);
958 fieldPtrs.push_back(model->MakeField<Double_t>(basename.Data()));
963 fieldPtrs.push_back(model->MakeField<Double_t>((basename + Form(
"_block%d", i)).Data()));
969 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_num_samples").Data()));
974 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_Device_Error_Code").Data()));
980 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_raw").Data()));
985 fieldPtrs.push_back(model->MakeField<Double_t>((basename + Form(
"_block%d_raw", i)).Data()));
989 for(
int i = 0; i < 4; i++){
990 fieldPtrs.push_back(model->MakeField<Double_t>((basename + Form(
"_sumsq%d_low", i)).Data()));
991 fieldPtrs.push_back(model->MakeField<Double_t>((basename + Form(
"_sumsq%d_high", i)).Data()));
992 fieldPtrs.push_back(model->MakeField<Double_t>((basename + Form(
"_min%d", i)).Data()));
993 fieldPtrs.push_back(model->MakeField<Double_t>((basename + Form(
"_max%d", i)).Data()));
998 fieldPtrs.push_back(model->MakeField<Double_t>((basename +
"_sequence_number").Data()));
1006void QwMollerADC_Channel::FillNTupleVector(std::vector<Double_t>& values)
const
1011 if (
bDEBUG) std::cerr <<
"QwMollerADC_Channel::FillNTupleVector: fTreeArrayNumEntries=="
1014 if (
bDEBUG) std::cerr <<
"QwMollerADC_Channel::FillNTupleVector: values.size()=="
1016 <<
"; fTreeArrayIndex+fTreeArrayNumEntries=="
1064 for(
int i = 0; i < 4; i++){
1080 if(
this ==&value)
return *
this;
1111 if(
this == &value)
return;
1136 TString loc=
"Standard exception from QwMollerADC_Channel::AssignValueFrom = "
1138 throw std::invalid_argument(loc.Data());
1148 TString loc=
"Standard exception from QwMollerADC_Channel::AddValueFrom = "
1150 throw std::invalid_argument(loc.Data());
1160 TString loc=
"Standard exception from QwMollerADC_Channel::SubtractValueFrom = "
1162 throw std::invalid_argument(loc.Data());
1172 TString loc=
"Standard exception from QwMollerADC_Channel::MultiplyBy = "
1174 throw std::invalid_argument(loc.Data());
1184 TString loc=
"Standard exception from QwMollerADC_Channel::DivideBy = "
1186 throw std::invalid_argument(loc.Data());
1272 TString loc=
"Standard exception from QwMollerADC_Channel::operator+= "
1275 throw(std::invalid_argument(loc.Data()));
1286 TString loc=
"Standard exception from QwMollerADC_Channel::operator-= "
1289 throw(std::invalid_argument(loc.Data()));
1300 TString loc=
"Standard exception from QwMollerADC_Channel::operator*= "
1303 throw(std::invalid_argument(loc.Data()));
1314 TString loc=
"Standard exception from QwMollerADC_Channel::operator/= "
1317 throw(std::invalid_argument(loc.Data()));
1360 for (Int_t i = 0; i < 4; i++) {
1363 variance = ratio * ratio *
1368 }
else if (this->
fBlock[i] == 0.0) {
1372 QwVerbose <<
"Attempting to divide by zero block in "
1380 variance = ratio * ratio *
1389 QwVerbose <<
"Attempting to divide by zero sum in "
1587 }
else if (n2 == -1) {
1595 for (Int_t i = 0; i < 4; i++) {
1599 fBlock[i] -= (M12 - M11) / n;
1602 }
else if (n == 1) {
1609 for (Int_t i = 0; i < 4; i++) {
1613 fBlock[i] -= (M12 - M11) / n;
1615 if (fabs(
fBlockM2[i]) < 10.*std::numeric_limits<double>::epsilon())
1618 }
else if (n == 0) {
1626 for (Int_t i = 0; i < 4; i++) {
1632 if (fabs(
fBlock[i]) < 10.*std::numeric_limits<double>::epsilon())
1634 if (fabs(
fBlockM2[i]) < 10.*std::numeric_limits<double>::epsilon())
1640 }
else if (n2 == 1) {
1647 for (Int_t i = 0; i < 4; i++) {
1651 fBlock[i] += (M12 - M11) / n;
1654 }
else if (n2 > 1) {
1660 for (Int_t i = 0; i < 4; i++) {
1664 fBlock[i] += n2 * (M12 - M11) / n;
1665 fBlockM2[i] += M22 + n1 * n2 * (M12 - M11) * (M12 - M11) / n;
1719 << std::setw(12) << std::left <<
GetBlockValue(0) <<
" +/- "
1721 << std::setw(12) << std::left <<
GetBlockValue(1) <<
" +/- "
1723 << std::setw(12) << std::left <<
GetBlockValue(2) <<
" +/- "
1725 << std::setw(12) << std::left <<
GetBlockValue(3) <<
" +/- "
1789 Bool_t status = kTRUE;
1798 Bool_t status = kTRUE;
1803 std::cerr <<
"QwMollerADC_Channel::MatchNumberOfSamples: Channel "
1806 <<
" and was supposed to have " << numsamp
1816 Bool_t status = kFALSE;
1869 message = Form(
"%30s",
"Device name");
1870 message += Form(
"%9s",
"HW Sat");
1871 message += Form(
"%9s",
"Sample");
1872 message += Form(
"%9s",
"SW_HW");
1873 message += Form(
"%9s",
"Sequence");
1874 message += Form(
"%9s",
"SameHW");
1875 message += Form(
"%9s",
"ZeroHW");
1876 message += Form(
"%9s",
"EventCut");
1877 QwMessage <<
"---------------------------------------------------------------------------------------------" <<
QwLog::endl;
1879 QwMessage <<
"---------------------------------------------------------------------------------------------" <<
QwLog::endl;
1885 QwMessage <<
"---------------------------------------------------------------------------------------------" <<
QwLog::endl;
1903 message +=
" >>>>> No Pedestal or Gain in map file";
1932 }
else if (input == NULL && value != NULL) {
1933 TString loc=
"Standard exception from QwMollerADC_Channel::ScaledAdd "
1936 throw(std::invalid_argument(loc.Data()));
1948 TString loc=
"Standard exception from QwMollerADC_Channel::CopyParameters"
1951 throw(std::invalid_argument(loc.Data()));
1955#ifdef __USE_DATABASE__
1966 row_list.push_back(row);
1972 row_list.push_back(row);
1978 row_list.push_back(row);
1985 row_list.push_back(row);
1992 row_list.push_back(row);
1998 row_list.push_back(row);
2005 row_list.push_back(row);
Physical units and constants for Qweak analysis.
Helper functions and utilities for ROOT histogram management.
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
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.
Decoding and management for Moller ADC channels (6x32-bit datawords)
static const UInt_t kBeamStabilityError
static const UInt_t kErrorFlag_ZeroHW
static const UInt_t kStabilityCut
static const UInt_t kErrorFlag_EventCut_L
static const UInt_t kErrorFlag_EventCut_U
static const UInt_t kErrorFlag_SW_HW
static const UInt_t kErrorFlag_sample
static const UInt_t kPreserveError
static const UInt_t kErrorFlag_VQWK_Sat
static const UInt_t kErrorFlag_SameHW
static const UInt_t kErrorFlag_Sequence
Database interface for QwIntegrationPMT and subsystems.
std::ostream & operator<<(std::ostream &stream, const QwMollerADC_Channel &channel)
__attribute__((no_sanitize("signed-integer-overflow"))) void QwMollerADC_Channel
A class for blinding data, adapted from G0 blinder class.
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.
bool fUseExternalRandomVariable
Flag to use an externally provided normal random variable.
Double_t fMockGaussianSigma
Sigma of normal distribution.
Double_t fMockGaussianMean
Mean of normal distribution.
std::vector< Double_t > fMockDriftPhase
Harmonic drift phase.
Double_t GetRandomValue()
void SetDeviceName(TString &in)
void SetErrorCodeId(UInt_t in)
Bool_t MatchVQWKElementFromList(const std::string &subsystemname, const std::string &moduletype, const std::string &devicename)
static std::ostream & endl(std::ostream &)
End of the line.
Concrete hardware channel for Moller ADC modules (6x32-bit words)
Long64_t fBlockSumSq_raw[5]
Int_t GetRawSoftwareSum() const
Int_t ProcessEvBuffer(UInt_t *buffer, UInt_t num_words_left, UInt_t index=0) override
Decode the event data from a CODA buffer.
Double_t GetHardwareSumM2() const
const QwMollerADC_Channel operator*(const QwMollerADC_Channel &value) const
void AssignValueFrom(const VQwDataElement *valueptr) override
Int_t fErrorCount_SW_HW
HW_sum==SW_sum check.
VQwHardwareChannel & operator/=(const VQwHardwareChannel &input) override
void AddChannelOffset(Double_t Offset)
void SetHardwareSum(Double_t hwsum, UInt_t sequencenumber=0)
static void PrintErrorCounterHead()
void LoadChannelParameters(QwParameterFile ¶mfile) override
Bool_t bDevice_Error_Code
QwMollerADC_Channel & operator+=(const QwMollerADC_Channel &value)
UInt_t fSequenceNumber
Event sequence number for this channel.
void RandomizeEventData(int helicity=0.0, double time=0.0) override
Internally generate random event data.
static const Bool_t kDEBUG
QwMollerADC_Channel & operator=(const QwMollerADC_Channel &value)
Double_t fPrev_HardwareBlockSum
Previous Module-based sum of the four sub-blocks.
QwMollerADC_Channel & operator*=(const QwMollerADC_Channel &value)
const QwMollerADC_Channel operator-(const QwMollerADC_Channel &value) const
Bool_t ApplySingleEventCuts() override
void MultiplyBy(const VQwHardwareChannel *valueptr) override
Double_t fBlockError[4]
Uncertainty on the sub-block.
void PrintValue() const override
Print single line of value and error of this data element.
void ScaledAdd(Double_t scale, const VQwHardwareChannel *value) override
void Sum(const QwMollerADC_Channel &value1, const QwMollerADC_Channel &value2)
void ProcessEvent() override
Process the event data according to pedestal and calibration factor.
Int_t fSequenceNo_Counter
Internal counter to keep track of the sequence number.
Int_t GetRawBlockValue(size_t blocknum) const
QwMollerADC_Channel & operator-=(const QwMollerADC_Channel &value)
void PrintErrorCounters() const override
report number of events failed due to HW and event cut failure
Bool_t MatchSequenceNumber(size_t seqnum)
Double_t fHardwareBlockSum
Module-based sum of the four sub-blocks.
void InitializeChannel(TString name, TString datatosave) override
Initialize the fields in this object.
Double_t GetBlockErrorValue(size_t blocknum) const
Int_t fErrorCount_sample
for sample size check
static const Int_t kMaxChannels
UInt_t fNumberOfSamples_map
Number of samples in the expected to read through the module. This value is set in the QwBeamline map...
void SetDefaultSampleSize(size_t num_samples_map)
void Blind(const QwBlinder *blinder)
Blind this channel as an asymmetry.
Int_t fErrorCount_ZeroHW
check to see ADC returning zero
void ArcTan(const QwMollerADC_Channel &value)
void DivideBy(const VQwHardwareChannel *valueptr) override
Int_t fNumEvtsWithEventCutsRejected
Counts the Event cut rejected events.
void SetEventData(Double_t *block, UInt_t sequencenumber=0)
void Scale(Double_t Offset) override
Double_t GetMollerADCSaturationLimt()
Int_t fErrorCount_HWSat
check to see ADC channel is saturated
void Ratio(const QwMollerADC_Channel &numer, const QwMollerADC_Channel &denom)
void CopyParameters(const VQwHardwareChannel *valueptr) override
void SetRawEventData() override
Int_t fSoftwareBlockSum_raw
Sum of the data in the four sub-blocks raw.
Int_t fBlock_raw[4]
Array of the sub-block data as read from the module.
static const Double_t kTimePerSample
void EncodeEventData(std::vector< UInt_t > &buffer) override
Encode the event data into a CODA buffer.
void AddValueFrom(const VQwHardwareChannel *valueptr) override
static Int_t GetBufferOffset(Int_t moduleindex, Int_t channelindex)
Int_t fErrorCount_SameHW
check to see ADC returning same HW value
void FillHistograms() override
Fill the histograms for this data element.
Double_t fBlockM2[4]
Second moment of the sub-block.
Int_t GetRawHardwareSum() const
Int_t ApplyHWChecks() override
Int_t fErrorCount_Sequence
sequence number check
static void PrintErrorCounterTail()
Int_t fHardwareBlockSum_raw
Module-based sum of the four sub-blocks as read from the module.
void ConstructHistograms(TDirectory *folder, TString &prefix) override
Construct the histograms for this data element.
UInt_t fPreviousSequenceNumber
Previous event sequence number for this channel.
static const Int_t kWordsPerChannel
Double_t GetValueWidth() const
void IncrementErrorCounters() override
Double_t fHardwareBlockSumError
Uncertainty on the hardware sum.
Double_t GetBlockValue(size_t blocknum) const
Double_t fBlock[4]
Array of the sub-block data.
void PrintInfo() const override
Print multiple lines of information about this data element.
void SubtractValueFrom(const VQwHardwareChannel *valueptr) override
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values) override
Double_t GetHardwareSum() const
void FillTreeVector(QwRootTreeBranchVector &values) const override
Int_t fADC_Same_NumEvt
Keep track of how many events with same ADC value returned.
size_t GetNumberOfSamples() const
void CalculateRunningAverage() override
void AccumulateRunningSum(const QwMollerADC_Channel &value, Int_t count=0, Int_t ErrorMask=0xFFFFFFF)
const QwMollerADC_Channel operator+(const QwMollerADC_Channel &value) const
static const Bool_t bDEBUG
debugging display purposes
Double_t GetHardwareSumWidth() const
Double_t GetAverageVolts() const
Int_t fSequenceNo_Prev
Keep the sequence number of the last event.
void Product(const QwMollerADC_Channel &value1, const QwMollerADC_Channel &value2)
void AssignScaledValue(const QwMollerADC_Channel &value, Double_t scale)
void SmearByResolution(double resolution) override
Double_t fHardwareBlockSumM2
Second moment of the hardware sum.
static const Double_t kMollerADC_VoltsPerBit
void ClearEventData() override
Clear the event data in this element.
void Difference(const QwMollerADC_Channel &value1, const QwMollerADC_Channel &value2)
size_t GetSequenceNumber() const
UInt_t fNumberOfSamples
Number of samples read through the module.
Bool_t MatchNumberOfSamples(size_t numsamp)
Double_t GetHardwareSumError() const
void ConstructBranch(TTree *tree, TString &prefix) override
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)
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.
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
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.
virtual void AddErrEntriesToList(std::vector< QwErrDBInterface > &)
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.
Data blinding utilities for parity violation analysis.
const Bool_t & IsBlinderOkay() const
void ModifyThisErrorCode(UInt_t &errorcode) const
void BlindValue(Double_t &value) const
Asymmetry blinding.
static constexpr const Double_t kValue_BlinderFail