JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
VQwDataElement.h
Go to the documentation of this file.
1/*!
2 * \file VQwDataElement.h
3 * \brief Definition of the pure virtual base class of all data elements
4 *
5 * \author P. M. King
6 * \date 2007-05-08 15:40
7 */
8
9#pragma once
10
11// System headers
12#include <vector>
13#include <iostream>
14#include <stdexcept>
15#include <string>
16
17// Root headers
18#include "Rtypes.h"
19#include "TString.h"
20#include "TDirectory.h"
21
22// Qweak headers
23#include "QwLog.h"
24#include "QwTypes.h"
25#include "MQwHistograms.h"
26
27class QwParameterFile;
30
31/**
32 * \class VQwDataElement
33 * \ingroup QwAnalysis
34 * \brief The pure virtual base class of all data elements
35 *
36 * This abstract base defines the fundamental interface for all data-carrying
37 * objects in the JAPAN-MOLLER framework. It establishes the dual-operator
38 * architectural pattern where derived classes must implement both type-specific
39 * and polymorphic versions of arithmetic operations.
40 *
41 * \par Architectural Design - Dual-Operator Pattern:
42 * VQwDataElement enforces a specific design where operators, Sum, Difference,
43 * Ratio, SetSingleEventCuts, and CheckForBurpFail are **non-virtual and throw
44 * runtime errors** in the base class. This forces derived classes to implement
45 * the complete dual-operator pattern:
46 *
47 * - **Type-specific operators**: `Derived& operator+=(const Derived&)`
48 * - **Polymorphic operators**: `Base& operator+=(const Base&)` that delegate
49 * via dynamic_cast to the type-specific version
50 *
51 * \par Implementation Requirements:
52 * Derived classes must override:
53 * - `operator+=`, `operator-=` (both type-specific and polymorphic versions)
54 * - `Sum()`, `Difference()`, `Ratio()` (both versions)
55 * - `SetSingleEventCuts()`, `CheckForBurpFail()` (both versions)
56 * - `UpdateErrorFlag()` (with appropriate delegation)
57 *
58 * \par Representative Example:
59 * See QwVQWK_Channel for the canonical implementation of this pattern.
60 * It demonstrates the complete dual-operator approach with proper
61 * dynamic_cast delegation and error handling.
62 *
63 * \par Error Handling Strategy:
64 * Base class methods throw std::runtime_error to catch implementation
65 * gaps early during development. This prevents silent fallbacks and
66 * ensures all derived classes implement the required functionality.
67 *
68 * \dot
69 * digraph example {
70 * node [shape=box, fontname=Helvetica, fontsize=10];
71 * VQwDataElement [ label="VQwDataElement\n(throws on operators)" URL="\ref VQwDataElement"];
72 * QwVQWK_Channel [ label="QwVQWK_Channel\n(canonical example)" URL="\ref QwVQWK_Channel"];
73 * QwMollerADC_Channel [ label="QwMollerADC_Channel" URL="\ref QwMollerADC_Channel"];
74 * VQwDataElement -> QwVQWK_Channel;
75 * VQwDataElement -> QwMollerADC_Channel;
76 * }
77 * \enddot
78 */
80 public:
81 /// Flag to be used to decide which data needs to be histogrammed and
82 /// entered in the tree
84
85
86 public:
87
88 /// Default constructor
99 /// Copy constructor
110 /// Virtual destructor
111 ~VQwDataElement() override { };
112
113 void CopyFrom(const VQwDataElement& value){
115 // fNumberOfDataWords = value.fNumberOfDataWords;
118 fModuleType = value.fModuleType;
119 fErrorFlag = value.fErrorFlag;
121 }
122
123 /*! \brief Is the name of this element empty? */
124 Bool_t IsNameEmpty() const { return fElementName.IsNull(); }
125 /*! \brief Set the name of this element */
126 void SetElementName(const TString &name) { fElementName = name; }
127 /*! \brief Get the name of this element */
128 virtual const TString& GetElementName() const { return fElementName; }
129
130 virtual void LoadChannelParameters(QwParameterFile & /*paramfile*/){};
131
132 virtual void LoadMockDataParameters(QwParameterFile & /*paramfile*/) {
133 std::cerr << "LoadMockDataParameters is not defined!" << std::endl;
134 };
135
136 /*! \brief Clear the event data in this element */
137 virtual void ClearEventData(){
138 fErrorFlag=0;
139 };
140 /*! \brief Process the CODA event buffer for this element */
141 virtual Int_t ProcessEvBuffer(UInt_t* buffer, UInt_t num_words_left, UInt_t subelement=0) = 0;
142
143 /*! \brief Get the number of data words in this data element */
145
146 UInt_t GetGoodEventCount() const { return fGoodEventCount; };
147
148
149 virtual void AssignValueFrom(const VQwDataElement* /*valueptr*/){
150 std::cerr << "Operation AssignValueFrom not defined!" << std::endl;
151 };
152
153 /*! \brief Addition-assignment operator */
155 { throw std::runtime_error(std::string("VQwDataElement::operator+= not implemented for ") + GetElementName().Data()); }
156 /*! \brief Subtraction-assignment operator */
158 { throw std::runtime_error(std::string("VQwDataElement::operator-= not implemented for ") + GetElementName().Data()); }
159
160 /*! \brief Sum operator (base class fallback throws runtime error) */
161 void Sum(const VQwDataElement & /*value1*/, const VQwDataElement & /*value2*/)
162 { throw std::runtime_error("Sum not implemented for this data element type"); }
163 /*! \brief Difference operator (base class fallback throws runtime error) */
164 void Difference(const VQwDataElement & /*value1*/, const VQwDataElement & /*value2*/)
165 { throw std::runtime_error("Difference not implemented for this data element type"); }
166 /*! \brief Ratio operator (base class fallback throws runtime error) */
167 void Ratio(const VQwDataElement & /*numer*/, const VQwDataElement & /*denom*/)
168 { throw std::runtime_error("Ratio not implemented for this data element type"); }
169
170 /*! \brief Construct the histograms for this data element */
171 virtual void ConstructHistograms(TDirectory *folder, TString &prefix) = 0;
172 /*! \brief Fill the histograms for this data element */
173 virtual void FillHistograms() = 0;
174
175 /*! \brief Print single line of value and error of this data element */
176 virtual void PrintValue() const { }
177 /*! \brief Print multiple lines of information about this data element */
178 virtual void PrintInfo() const { std::cout << GetElementName() << std::endl; }
179
180
181 /*! \brief set the upper and lower limits (fULimit and fLLimit), stability % and the error flag on this channel */
182 void SetSingleEventCuts(UInt_t /*errorflag*/,Double_t /*min*/, Double_t /*max*/, Double_t /*stability*/){throw std::runtime_error("SetSingleEventCuts not implemented for this data element type");};
183 /*! \brief report number of events failed due to HW and event cut failure */
184 virtual void PrintErrorCounters() const {};
185
186 Bool_t CheckForBurpFail(const VQwDataElement * /*ev_error*/){
187 throw std::runtime_error(std::string("CheckForBurpFail not implemented for this data element type ") + typeid(*this).name());
188 };
189
190 /*! \brief return the error flag on this channel/device*/
191 virtual UInt_t GetEventcutErrorFlag(){
192 //first condition check for global/local status and second condition check to see non-zero HW error codes
194 // we care only about global cuts
195 //std::cout<<"fErrorFlag "<<(fErrorFlag & kGlobalCut)<<std::endl;
196 return fErrorFlag+fErrorConfigFlag;//pass the error codes and configuration codes
197 }
198 return 0;
199 }
200
201 /// \brief Update the error flag based on the error flags of internally
202 /// contained objects
203 /// Return parameter is the "Eventcut Error Flag".
204 virtual UInt_t UpdateErrorFlag() {return GetEventcutErrorFlag();};
205
206 // These are related to those hardware channels that need to normalize
207 // to an external clock
208 virtual void SetNeedsExternalClock(Bool_t /*needed*/) {}; // Default is No!
209 virtual Bool_t NeedsExternalClock() { return kFALSE; }; // Default is No!
210 virtual std::string GetExternalClockName() { return ""; }; // Default is none
211 virtual void SetExternalClockPtr( const VQwHardwareChannel* /*clock*/) {};
212 virtual void SetExternalClockName( const std::string /*name*/) {};
213 virtual Double_t GetNormClockValue() { return 1.;}
214
215
216
217 /*! \brief Return the name of the inheriting subsystem name*/
218 TString GetSubsystemName() const {
219 return fSubsystemName;
220 }
221
222 /*! \brief Set the name of the inheriting subsystem name*/
223 void SetSubsystemName(TString sysname){
224 fSubsystemName=sysname;
225 }
226
227 /*! \brief Return the type of the beam instrument*/
228 TString GetModuleType() const {
229 return fModuleType;
230 }
231
232 /*! \brief set the type of the beam instrument*/
233 void SetModuleType(TString ModuleType){
234 fModuleType=ModuleType;
235 }
236
237 protected:
238 /*! \brief Set the number of data words in this data element */
239 void SetNumberOfDataWords(const UInt_t &numwords) {fNumberOfDataWords = numwords;}
240
241 /// Arithmetic assignment operator: Should only copy event-based data
243 if(this != &value){
246 fErrorFlag = value.fErrorFlag;
247 }
248 return *this;
249 }
250
251 // The most basic version of UpdateErrorFlag, which should get hidden
252 // by all the derived class versions.
253 void UpdateErrorFlag(const UInt_t& error){
254 fErrorFlag |= (error);
255 };
256
257 protected:
258 TString fElementName; ///< Name of this data element
259 UInt_t fNumberOfDataWords; ///< Number of raw data words in this data element
260 UInt_t fGoodEventCount; ///< Number of good events accumulated in this element
261
262
263 // Name of the inheriting subsystem
265 // Data module Type
266 TString fModuleType;
267
268 /*! \name Event error flag */
269 /*! \brief This the standard error code generated for the channel that contains the global/local/stability flags and the Device error code (Unique error code for HW failures)*/
270// @{
272 UInt_t fErrorConfigFlag; ///<contains the global/local/stability flags
273//@}
274}; // class VQwDataElement
A logfile class, based on an identical class in the Hermes analyzer.
Mix-in class for histogram management functionality.
Basic data types and constants used throughout the Qweak analysis framework.
static const UInt_t kGlobalCut
Definition QwTypes.h:182
const TString QwBPMStripline< T >::subelement[4]
MQwHistograms & operator=(const MQwHistograms &value)
MQwHistograms()
Default constructor.
Configuration file parser with flexible tokenization and search capabilities.
A helper class to manage a vector of branch entries for ROOT trees.
Definition QwRootFile.h:53
VQwDataElement(const VQwDataElement &value)
Copy constructor.
virtual Double_t GetNormClockValue()
void CopyFrom(const VQwDataElement &value)
void UpdateErrorFlag(const UInt_t &error)
UInt_t fGoodEventCount
Number of good events accumulated in this element.
virtual void PrintErrorCounters() const
report number of events failed due to HW and event cut failure
VQwDataElement()
Default constructor.
virtual void ClearEventData()
Clear the event data in this element.
UInt_t fErrorConfigFlag
contains the global/local/stability flags
virtual void PrintValue() const
Print single line of value and error of this data element.
virtual void SetExternalClockPtr(const VQwHardwareChannel *)
VQwDataElement & operator+=(const VQwDataElement &)
Addition-assignment operator.
virtual void FillHistograms()=0
Fill the histograms for this data element.
void SetSubsystemName(TString sysname)
Set the name of the inheriting subsystem name.
virtual UInt_t UpdateErrorFlag()
Update the error flag based on the error flags of internally contained objects Return parameter is th...
virtual UInt_t GetEventcutErrorFlag()
return the error flag on this channel/device
void Ratio(const VQwDataElement &, const VQwDataElement &)
Ratio operator (base class fallback throws runtime error)
virtual void PrintInfo() const
Print multiple lines of information about this data element.
void SetNumberOfDataWords(const UInt_t &numwords)
Set the number of data words in this data element.
TString fElementName
Name of this data element.
UInt_t fNumberOfDataWords
Number of raw data words in this data element.
virtual void LoadChannelParameters(QwParameterFile &)
virtual void LoadMockDataParameters(QwParameterFile &)
virtual const TString & GetElementName() const
Get the name of this element.
void SetSingleEventCuts(UInt_t, Double_t, Double_t, Double_t)
set the upper and lower limits (fULimit and fLLimit), stability % and the error flag on this channel
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.
size_t GetNumberOfDataWords()
Get the number of data words in this data element.
Bool_t IsNameEmpty() const
Is the name of this element empty?
virtual void AssignValueFrom(const VQwDataElement *)
VQwDataElement & operator=(const VQwDataElement &value)
Arithmetic assignment operator: Should only copy event-based data.
virtual void SetNeedsExternalClock(Bool_t)
virtual void ConstructHistograms(TDirectory *folder, TString &prefix)=0
Construct the histograms for this data element.
VQwDataElement & operator-=(const VQwDataElement &)
Subtraction-assignment operator.
void Sum(const VQwDataElement &, const VQwDataElement &)
Sum operator (base class fallback throws runtime error)
virtual Int_t ProcessEvBuffer(UInt_t *buffer, UInt_t num_words_left, UInt_t subelement=0)=0
Process the CODA event buffer for this element.
virtual void SetExternalClockName(const std::string)
void Difference(const VQwDataElement &, const VQwDataElement &)
Difference operator (base class fallback throws runtime error)
virtual Bool_t NeedsExternalClock()
virtual std::string GetExternalClockName()
Bool_t CheckForBurpFail(const VQwDataElement *)
~VQwDataElement() override
Virtual destructor.
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.