17#ifdef HAS_RNTUPLE_SUPPORT
18#include "ROOT/RNTupleModel.hxx"
19#include "ROOT/RField.hxx"
23#ifdef __USE_DATABASE__
83 fEffectiveCharge.InitializeChannel(subsystem,
"QwCombinedBPM", name+
"WS",
"derived");
177 Bool_t eventokay=kTRUE;
249 for(
size_t i=0;i<
fElement.size();i++){
256 charge_error |=
fElement[i]->GetEffectiveCharge()->GetErrorCode();
269 if (
bDEBUG) std::cout<<
" X Slope event cut failed ";
281 if (
bDEBUG) std::cout<<
" X Intercept event cut failed ";
294 if (
bDEBUG) std::cout<<
" X Intercept event cut failed ";
307 if (
bDEBUG) std::cout<<
" Abs X event cut failed ";
318 if (
bDEBUG) std::cout<<
"EffectiveCharge event cut failed ";
336 for(
size_t i=0;i<
fElement.size();i++){
338 charge_error |=
fElement[i]->GetEffectiveCharge()->GetErrorCode();
368 Bool_t burpstatus = kFALSE;
370 if (
typeid(*ev_error) ==
typeid(*
this)) {
374 for (
int i = 0; i < 2; ++i) {
375 burpstatus |=
fAbsPos[i].CheckForBurpFail(&(value_bpm->
fAbsPos[i]));
376 burpstatus |=
fSlope[i].CheckForBurpFail(&(value_bpm->
fSlope[i]));
383 TString loc =
"Standard exception from QwCombinedBPM::CheckForBurpFail :" +
385 throw std::invalid_argument(loc.Data());
387 }
catch (std::exception& e) {
388 std::cerr << e.what() << std::endl;
398 if (ch_name==
"xslope"){
400 }
else if (ch_name==
"yslope"){
402 }
else if (ch_name==
"xintercept"){
404 }
else if (ch_name==
"yintercept"){
406 }
else if (ch_name==
"xminchisquare"){
408 }
else if (ch_name==
"yminchisquare"){
410 }
else if (ch_name==
"absx" || ch_name==
"x" ){
412 }
else if (ch_name==
"absy" || ch_name==
"y"){
414 }
else if (ch_name==
"effectivecharge" || ch_name==
"charge"){
417 TString loc=
"QwCombinedBPM::GetSubelementByName for"
419 + ch_name +
", which is an unrecognized subelement name.";
420 throw std::invalid_argument(loc.Data());
503 if(
typeid(*ev_error)==
typeid(*
this)) {
516 TString loc=
"Standard exception from QwCombinedBPM::UpdateErrorFlag :"+
519 throw std::invalid_argument(loc.Data());
521 }
catch (std::exception& e) {
522 std::cerr<< e.what()<<std::endl;
531 Bool_t ldebug = kFALSE;
533 static T tmpQADC(
"tmpQADC"), tmpADC(
"tmpADC");
538 if(ldebug) std::cout<<
"QwCombinedBPM:Calculating fixed parameters..\n";
544 for(
size_t i=0;i<
fElement.size();i++){
546 std::cout<<
"*******************************\n";
547 std::cout<<
" QwCombinedBPM: Reading "<<
fElement[i]->GetElementName()<<
" with charge weight ="<<
fQWeights[i]
549 <<
" and y weight ="<<
fYWeights[i]<<
"\n"<<std::flush;
558 std::cout<<
"fElement[" << i <<
"]->GetEffectiveCharge()=="
559 <<
fElement[i]->GetEffectiveCharge()
560 << std::endl << std::flush;
561 fElement[i]->GetEffectiveCharge()->PrintInfo();
562 std::cout<<
"fElement[" << i <<
"]->GetPosition(kXAxis)=="
564 << std::endl << std::flush;
565 std::cout<<
"fElement[" << i <<
"]->GetPosition(kYAxis)=="
567 << std::endl << std::flush;
570 std::cout<<
"fElement[" << i <<
"]->GetEffectiveCharge returns NULL"
575 <<
fElement[i]->GetEffectiveCharge()->GetValue()
576 << std::endl << std::flush;
579 std::cout<<
"copied absolute X position hw_sum from device "
581 std::cout<<
"copied absolute Y position hw_sum from device "
597 std::cout<<
" QwCombinedBPM:: Projected target X position = "<<
fAbsPos[
kXAxis].GetValue()
601 <<
" \nProjected target Y position = "<<
fAbsPos[
kYAxis].GetValue()
629 Bool_t ldebug = kFALSE;
630 static Double_t zpos = 0.0;
632 for(
size_t i=0;i<
fElement.size();i++){
633 zpos =
fElement[i]->GetPositionInZ();
634 A[pos] += zpos*fWeights[i];
635 B[pos] += fWeights[i];
636 D[pos] += zpos*zpos*fWeights[i];
639 m[pos] =
D[pos]*
B[pos]-
A[pos]*
A[pos];
640 erra[pos] =
B[pos]/
m[pos];
641 errb[pos] =
D[pos]/
m[pos];
649 std::cout<<
" A = "<<
A[pos]<<
", B = "<<
B[pos]<<
", D = "<<
D[pos]<<
", m = "<<
m[pos]<<std::endl;
650 std::cout<<
"For least square fit, errors are "<<
erra[pos]
651 <<
"\ncovariance = "<<
covab[pos]<<
"\n\n";
664 <<
"QwCombinedBPM:: Number of devices doesn't match the number of weights."
665 <<
" Exiting calculating parameters for the least squares fit"
669 for(
size_t i=0;i<weight.size();i++){
670 val[i].Scale(weight[i]);
671 sum+=val[i].GetValue();
692 Bool_t ldebug = kFALSE;
693 static Double_t zpos = 0;
694 static T tmp1(
"tmp1",
"derived");
695 static T tmp2(
"tmp2",
"derived");
696 static T tmp3(
"tmp3",
"derived");
701 C[
kXAxis].InitializeChannel(
"cx",
"derived");
702 C[
kYAxis].InitializeChannel(
"cy",
"derived");
703 E[
kXAxis].InitializeChannel(
"ex",
"derived");
704 E[
kYAxis].InitializeChannel(
"ey",
"derived");
706 C[
axis].ClearEventData();
707 E[
axis].ClearEventData();
708 for(
size_t i=0;i<
fElement.size();i++){
709 zpos =
fElement[i]->GetPositionInZ();
710 tmp1.ClearEventData();
712 tmp1.Scale(fWeights[i]);
718 if(ldebug) std::cout<<
"\n A ="<<
A[
axis]
720 <<
" --C ="<<C[
axis].GetValue()
722 <<
" --E ="<<E[
axis].GetValue()<<
"\n";
734 if(ldebug) std::cout<<
" Least Squares Fit Parameters for "<<
axis
735 <<
" are: \n slope = "<<
fSlope[
axis].GetValue()
740 tmp1.ClearEventData();
754 tmp3.ClearEventData();
757 for(
size_t i=0;i<
fElement.size();i++){
758 tmp1.ClearEventData();
759 tmp2.ClearEventData();
772 tmp1.Product(tmp1,tmp1);
774 tmp1.Scale(fWeights[i]*fWeights[i]);
794 return word_position_in_buffer;
1062 TString thisprefix=prefix;
1063 if(prefix.Contains(
"asym_"))
1064 thisprefix.ReplaceAll(
"asym_",
"diff_");
1068 fSlope[
axis].ConstructHistograms(folder, thisprefix);
1070 fAbsPos[
axis].ConstructHistograms(folder, thisprefix);
1104 TString thisprefix=prefix;
1105 if(prefix.Contains(
"asym_"))
1106 thisprefix.ReplaceAll(
"asym_",
"diff_");
1112 fSlope[
axis].ConstructBranchAndVector(tree,thisprefix,values);
1113 fIntercept[
axis].ConstructBranchAndVector(tree,thisprefix,values);
1114 fAbsPos[
axis].ConstructBranchAndVector(tree,thisprefix,values);
1130 TString thisprefix=prefix;
1131 if(prefix.Contains(
"asym_"))
1132 thisprefix.ReplaceAll(
"asym_",
"diff_");
1138 fSlope[
axis].ConstructBranch(tree,thisprefix);
1153 devicename.ToLower();
1159 if (modulelist.
HasValue(devicename)){
1160 TString thisprefix=prefix;
1161 if(prefix.Contains(
"asym_"))
1162 thisprefix.ReplaceAll(
"asym_",
"diff_");
1168 fSlope[
axis].ConstructBranch(tree,thisprefix);
1200#ifdef HAS_RNTUPLE_SUPPORT
1204 if (this->GetElementName()==
""){
1208 TString thisprefix=prefix;
1209 if(prefix.Contains(
"asym_"))
1210 thisprefix.ReplaceAll(
"asym_",
"diff_");
1212 this->SetRootSaveStatus(prefix);
1214 fEffectiveCharge.ConstructNTupleAndVector(model, prefix, values, fieldPtrs);
1215 for(Short_t axis=kXAxis;axis<kNumAxes;axis++){
1216 fSlope[axis].ConstructNTupleAndVector(model, thisprefix, values, fieldPtrs);
1217 fIntercept[axis].ConstructNTupleAndVector(model, thisprefix, values, fieldPtrs);
1218 fAbsPos[axis].ConstructNTupleAndVector(model, thisprefix, values, fieldPtrs);
1219 fMinimumChiSquare[axis].ConstructNTupleAndVector(model, thisprefix, values, fieldPtrs);
1227 if (this->GetElementName()==
""){
1231 fEffectiveCharge.FillNTupleVector(values);
1233 for(Short_t axis=kXAxis;axis<kNumAxes;axis++){
1234 fSlope[axis].FillNTupleVector(values);
1235 fIntercept[axis].FillNTupleVector(values);
1236 fAbsPos[axis].FillNTupleVector(values);
1237 fMinimumChiSquare[axis].FillNTupleVector(values);
1287 static Double_t zpos = 0;
1288 static T tmp1(
"tmp1",
"derived");
1298 fSlope[
axis].RandomizeEventData(helicity, time);
1326 Double_t xres=0.0, yres=0.0;
1328 if (paramfile.
GetLine().find(
"resolution")!=std::string::npos){
1337 if (value==
"xpos") {
1341 else if (value==
"ypos") {
1345 else if (value==
"xslope") {
1349 else if (value==
"yslope") {
1397 Double_t meanXslope, Double_t sigmaXslope, Double_t meanYslope, Double_t sigmaYslope)
1407 fSlope[
kXAxis].SetRandomEventParameters(meanXslope, sigmaXslope);
1408 fSlope[
kYAxis].SetRandomEventParameters(meanYslope, sigmaYslope);
1416#ifdef __USE_DATABASE__
1420 std::vector <QwDBInterface> row_list;
1422 for(
size_t axis=kXAxis;axis<kNumAxes;axis++) {
1423 fAbsPos[axis].AddEntriesToList(row_list);
1424 fSlope[axis].AddEntriesToList(row_list);
1425 fIntercept[axis].AddEntriesToList(row_list);
1426 fMinimumChiSquare[axis].AddEntriesToList(row_list);
1428 fEffectiveCharge.AddEntriesToList(row_list);
1437 std::vector <QwErrDBInterface> row_list;
1439 for(
size_t axis=kXAxis;axis<kNumAxes;axis++) {
1440 fAbsPos[axis].AddErrEntriesToList(row_list);
1441 fSlope[axis].AddErrEntriesToList(row_list);
1442 fIntercept[axis].AddErrEntriesToList(row_list);
1443 fMinimumChiSquare[axis].AddErrEntriesToList(row_list);
Base and derived classes for scaler channel data handling.
#define QwWarning
Predefined log drain for warnings.
#define QwMessage
Predefined log drain for regular messages.
Parameter file parsing and management.
Decoding and management for Moller ADC channels (6x32-bit datawords)
Decoding and management for VQWK ADC channels (6x32-bit datawords)
Database interface for QwIntegrationPMT and subsystems.
Combined beam position monitor using weighted average.
static std::ostream & endl(std::ostream &)
End of the line.
Configuration file parser with flexible tokenization and search capabilities.
T GetTypedNextToken()
Get next token into specific type.
Bool_t HasValue(TString &vname)
std::string GetNextToken(const std::string &separatorchars)
Get next token as a string.
A helper class to manage a vector of branch entries for ROOT trees.
VQwDataElement()
Default constructor.
virtual const TString & GetElementName() const
Get the name of this element.
Abstract base for concrete hardware channels implementing dual-operator pattern.
Template for combined beam position monitor using multiple BPMs.
void GetProjectedPosition(VQwBPM *device) override
void Scale(Double_t factor) override
void FillTreeVector(QwRootTreeBranchVector &values) const override
std::vector< Double_t > fQWeights
VQwBPM & operator-=(const VQwBPM &value) override
Int_t ProcessEvBuffer(UInt_t *buffer, UInt_t word_position_in_buffer, UInt_t indexnumber) override
Process the CODA event buffer for this element.
void DeaccumulateRunningSum(VQwBPM &value, Int_t ErrorMask=0xFFFFFFF) override
void RandomizeEventData(int helicity=0, double time=0.0) override
VQwHardwareChannel * GetSubelementByName(TString ch_name) override
void LoadMockDataParameters(QwParameterFile ¶mfile) override
UInt_t UpdateErrorFlag() override
Update the error flag based on the error flags of internally contained objects Return parameter is th...
std::array< T, 2 > fSlope
Double_t SumOver(std::vector< Double_t > weight, std::vector< T > val)
std::vector< T > fBPMComboElementList
std::vector< Double_t > fYWeights
void InitializeChannel(TString name)
void ConstructHistograms(TDirectory *folder, TString &prefix) override
Construct the histograms for this data element.
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values) override
std::array< T, 2 > fIntercept
void LeastSquareFit(VQwBPM::EBeamPositionMonitorAxis axis, std::vector< Double_t > fWeights)
void Ratio(QwCombinedBPM &numer, QwCombinedBPM &denom)
std::array< T, 2 > fAbsPos
void IncrementErrorCounters() override
Bool_t CheckForBurpFail(const VQwDataElement *ev_error)
void PrintValue() const override
Print single line of value and error of this data element.
void ClearEventData() override
void ProcessEvent() override
Bool_t ApplySingleEventCuts() override
void CalculateFixedParameter(std::vector< Double_t > fWeights, Int_t pos)
std::array< T, 2 > fMinimumChiSquare
void FillHistograms() override
Fill the histograms for this data element.
void SetEventCutMode(Int_t bcuts) override
Inherited from VQwDataElement to set the upper and lower limits (fULimit and fLLimit),...
std::vector< Double_t > fXWeights
VQwBPM & operator+=(const VQwBPM &value) override
Bool_t fixedParamCalculated
void ConstructBranch(TTree *tree, TString &prefix) override
const VQwHardwareChannel * GetEffectiveCharge() const override
void AccumulateRunningSum(const VQwBPM &value, Int_t count=0, Int_t ErrorMask=0xFFFFFFF) override
void SetRandomEventParameters(Double_t meanX, Double_t sigmaX, Double_t meanY, Double_t sigmaY, Double_t meanXslope, Double_t sigmaXslope, Double_t meanYslope, Double_t sigmaYslope) override
UInt_t GetEventcutErrorFlag() override
VQwBPM & operator=(const VQwBPM &value) override
void SetBPMForCombo(const VQwBPM *bpm, Double_t charge_weight, Double_t x_weight, Double_t y_weight, Double_t sumqw) override
void PrintErrorCounters() const override
std::vector< const VQwBPM * > fElement
const VQwHardwareChannel * GetPosition(EBeamPositionMonitorAxis axis) const override
void PrintInfo() const override
Print multiple lines of information about this data element.
void CalculateRunningAverage() override
virtual void ApplyResolutionSmearing()
void SetRootSaveStatus(TString &prefix)
static const TString kAxisLabel[2]
virtual void SetResolution(Double_t resolutionX, Double_t resolutionY)
void InitializeChannel(TString name)
Initialize common BPM state and set the element name.
static const Bool_t bDEBUG
virtual void FillRawEventData()
static const TString axis[3]
virtual VQwBPM & operator=(const VQwBPM &value)=0
virtual const VQwHardwareChannel * GetPosition(EBeamPositionMonitorAxis axis) const
Double_t GetPositionInZ() const