JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
VQwBPM.cc
Go to the documentation of this file.
1/*!
2 * \file VQwBPM.cc
3 * \brief Virtual base class implementation for beam position monitors
4 *
5 * Base helper implementations for BPMs (beam position monitors). Contains
6 * small utility methods shared by concrete BPM types plus factory helpers.
7 * Documentation-only edits; runtime behavior unchanged.
8 */
9
10#include "VQwBPM.h"
11
12// System headers
13#include <stdexcept>
14
15// Qweak headers
16#include "QwLog.h"
17#include "QwBPMStripline.h"
18#include "QwCombinedBPM.h"
19#include "QwVQWK_Channel.h"
20#include "QwScaler_Channel.h"
21#include "QwMollerADC_Channel.h"
22
23
24/* With X being vertical up and Z being the beam direction toward the beamdump */
25const TString VQwBPM::kAxisLabel[2]={"X","Y"};
26
27
28/*!
29 * \brief Initialize common BPM state and set the element name.
30 * \param name Element name to assign to this BPM.
31 *
32 * Initializes position center array to zero and sets the element name.
33 * This is the base initialization common to all BPM types.
34 */
35void VQwBPM::InitializeChannel(TString name)
36{
37 Short_t i = 0;
38
39 for(i=0;i<3;i++) fPositionCenter[i] = 0.0;
40
41 SetElementName(name);
42
43 return;
44}
45
46/*!
47 * \brief Store geometry/survey offsets for absolute position calibration.
48 * \param Xoffset X-axis survey offset in mm.
49 * \param Yoffset Y-axis survey offset in mm.
50 * \param Zoffset Z-axis survey offset in mm.
51 *
52 * Reads position offsets from geometry map file for absolute position
53 * calibration. These offsets correct for known mechanical installation
54 * differences from ideal positions.
55 */
56void VQwBPM::GetSurveyOffsets(Double_t Xoffset, Double_t Yoffset, Double_t Zoffset)
57{
58 // Read in the position offsets from the geometry map file
59 for(Short_t i=0;i<3;i++) fPositionCenter[i]=0.0;
60 fPositionCenter[0]=Xoffset;
61 fPositionCenter[1]=Yoffset;
62 fPositionCenter[2]=Zoffset;
63 return;
64}
65
66
67/*!
68 * \brief Apply per-detector electronic calibration and relative gains.
69 * \param BSENfactor Beam sensitivity factor for position calibration.
70 * \param AlphaX Relative gain correction factor for X position.
71 * \param AlphaY Relative gain correction factor for Y position.
72 *
73 * Reads electronic factors from calibration file and applies stripline-specific
74 * calibrations. BSENfactor is scaled by 18.81 to convert to mm/V, and a
75 * correction factor of 0.250014 is applied for stripline geometry.
76 */
77void VQwBPM::GetElectronicFactors(Double_t BSENfactor, Double_t AlphaX, Double_t AlphaY)
78{
79 // Read in the electronic factors from the file
80 Bool_t ldebug = kFALSE;
81
82 fQwStriplineCalibration = BSENfactor*18.81;
83 fQwStriplineCorrection = 0.250014;
84
85 fRelativeGains[0]=AlphaX;
86 fRelativeGains[1]=AlphaY;
87
88 if(ldebug){
89 std::cout<<"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
90 std::cout<<this->GetElementName();
91 std::cout<<"\nfQwStriplineCalibration = "<<fQwStriplineCalibration<<std::endl;
92 std::cout<<"\nfQwStriplineCorrection = "<<fQwStriplineCorrection<<std::endl;
93 std::cout<<"AlphaX = "<<fRelativeGains[0]<<std::endl;
94 std::cout<<"AlphaY = "<<fRelativeGains[1]<<std::endl;
95
96 }
97 return;
98}
99
100/*!
101 * \brief Set detector rotation angle and update cached trigonometric values.
102 * \param rotation_angle Rotation angle in degrees (positive = clockwise from beam's perspective).
103 *
104 * Sets the BPM rotation angle and pre-computes sin/cos values for efficient
105 * coordinate transformations. Rotation is applied to correct for mechanical
106 * installation angles that differ from ideal orientation.
107 */
108void VQwBPM::SetRotation(Double_t rotation_angle){
109 // Read the rotation angle in degrees (to beam right)
110 Bool_t ldebug = kFALSE;
111 fSinRotation = 0;
112 fCosRotation = 0;
113 fRotationAngle = rotation_angle;
114 fSinRotation = TMath::Sin(fRotationAngle*(TMath::DegToRad()));
115 fCosRotation = TMath::Cos(fRotationAngle*(TMath::DegToRad()));
116
117 if(ldebug){
118 std::cout<<"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
119 std::cout<<this->GetElementName();
120 std::cout<<" is rotated by angle = "<<rotation_angle<<std::endl;
121
122 }
123}
124
125/** Disable rotation, restoring accelerator coordinates (0 degrees). */
127 // Turn off rotation. This object is already in accelerator coordinates.
128 fRotationAngle = 0.0;
130 bRotated=kFALSE;
131}
132
133/** Configure position-dependent gains (X or Y). */
134void VQwBPM::SetGains(TString pos, Double_t value){
135 if(pos.Contains("X")) fGains[0] = value;
136 if(pos.Contains("Y")) fGains[1] = value;
137}
138
139void VQwBPM::SetSingleEventCuts(TString ch_name, Double_t minX, Double_t maxX)
140{
141 VQwHardwareChannel* tmpptr = GetSubelementByName(ch_name);
142 QwMessage << GetElementName() << " " << ch_name
143 << " LL " << minX <<" UL " << maxX <<QwLog::endl;
144 tmpptr->SetSingleEventCuts(minX,maxX);
145}
146
147void VQwBPM::SetSingleEventCuts(TString ch_name, UInt_t errorflag,Double_t minX, Double_t maxX, Double_t stability, Double_t burplevel)
148{
149 VQwHardwareChannel* tmpptr = GetSubelementByName(ch_name);
150 errorflag|=kBPMErrorFlag;//update the device flag
151 QwMessage << GetElementName() << " " << ch_name
152 << " LL " << minX <<" UL " << maxX <<QwLog::endl;
153 tmpptr->SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
154}
155
157{
158 if (GetElementName()!=""){
161 bRotated = value.bRotated;
165 fGoodEvent = value.fGoodEvent;
166 // fDeviceErrorCode = value.fDeviceErrorCode;
167 // bFullSave = value.bFullSave;
168 for(size_t axis=kXAxis;axis<kNumAxes;axis++){
171 }
172 // Copy Z center position
173 this->fPositionCenter[2]=value.fPositionCenter[2];
174 }
175 return *this;
176}
177
178// VQwBPM& VQwBPM::operator+= (const VQwBPM &value)
179// {
180// if (GetElementName()!=""){
181// this->fEffectiveCharge+=value.fEffectiveCharge;
182// for(Short_t i=kXAxis;i<kNumAxes;i++) this->fAbsPos[i]+=value.fAbsPos[i];
183// }
184// return *this;
185// }
186
187// VQwBPM& VQwBPM::operator-= (const VQwBPM &value)
188// {
189// if (GetElementName()!=""){
190// this->fEffectiveCharge-=value.fEffectiveCharge;
191// for(Short_t i=kXAxis;i<kNumAxes;i++) this->fAbsPos[i]-=value.fAbsPos[i];
192// }
193// return *this;
194// }
195
196
197// void VQwBPM::Sum(VQwBPM &value1, VQwBPM &value2)
198// {
199// *this = value1;
200// *this += value2;
201// }
202
203// void VQwBPM::Difference(VQwBPM &value1, VQwBPM &value2)
204// {
205// *this = value1;
206// *this -= value2;
207// }
208
209
210// void VQwBPM::Scale(Double_t factor)
211// {
212// fEffectiveCharge_base->Scale(factor);
213// for(Short_t i = 0;i<2;i++)fAbsPos_base[i]->Scale(factor);
214// return;
215// }
216
217
218
219
220void VQwBPM::SetRootSaveStatus(TString &prefix)
221{
222 if(prefix.Contains("diff_")||prefix.Contains("yield_")|| prefix.Contains("asym_"))
223 bFullSave=kFALSE;
224
225 return;
226}
227
228// void VQwBPM::PrintValue() const
229// {
230// Short_t i;
231// for (i = 0; i < 2; i++) fAbsPos_base[i]->PrintValue();
232// fEffectiveCharge_base->PrintValue();
233
234// return;
235// }
236
237// void VQwBPM::PrintInfo() const
238// {
239// Short_t i = 0;
240// for (i = 0; i < 4; i++) fAbsPos_base[i]->PrintInfo();
241// fEffectiveCharge_base->PrintInfo();
242// }
243
244
245// void VQwBPM::CalculateRunningAverage()
246// {
247// Short_t i = 0;
248// for (i = 0; i < 2; i++) fAbsPos_base[i]->CalculateRunningAverage();
249// fEffectiveCharge_base->CalculateRunningAverage();
250
251// return;
252// }
253
254
255// void VQwBPM::AccumulateRunningSum(const VQwBPM& value)
256// {
257// // TODO This is unsafe, see QwBeamline::AccumulateRunningSum
258// Short_t i = 0;
259// for (i = 0; i < 2; i++) fAbsPos_base[i]->AccumulateRunningSum(value.fAbsPos_base[i]);
260// fEffectiveCharge_base->AccumulateRunningSum(value.fEffectiveCharge_base);
261// return;
262// }
263
264/**
265 * \brief A fast way of creating a BPM stripline of specified type
266 */
267VQwBPM* VQwBPM::CreateStripline(TString subsystemname, TString name, TString type)
268{
269 Bool_t localDebug = kFALSE;
270 type.ToUpper();
271 if( localDebug ) QwMessage<<"Creating BPM of type: "<<type<<" with name: "<<
272 name<<". Subsystem Name: " <<subsystemname<<"\n";
273 // (jc2) As a first try, let's do this the ugly way (but rather very
274 // simple), just list out the types of BPM's supported by this code!!!
275 if( type == "VQWK") {
276 return new QwBPMStripline<QwVQWK_Channel>(subsystemname,name,type);
277 } else if ( type == "SIS3801" ) {
278 return new QwBPMStripline<QwSIS3801_Channel>(subsystemname,name,type);
279 } else if ( type == "SCALER" || type == "SIS3801D24" ) {
280 return new QwBPMStripline<QwSIS3801D24_Channel>(subsystemname,name,type);
281 } else if ( type == "MOLLERADC" ) {
282 return new QwBPMStripline<QwMollerADC_Channel>(subsystemname,name,type);
283 } else { // Unsupported one!
284 QwWarning << "BPM of type="<<type<<" is UNSUPPORTED!!\n";
285 exit(-1);
286 }
287}
288
290{
291 Bool_t localDebug = kFALSE;
292 TString type = source.GetModuleType();
293 type.ToUpper();
294 if( localDebug ) QwMessage<<"Creating BPM of type: "<<type << QwLog::endl;
295 // (jc2) As a first try, let's do this the ugly way (but rather very
296 // simple), just list out the types of BPM's supported by this code!!!
297 if( type == "VQWK") {
298 return new QwBPMStripline<QwVQWK_Channel>(dynamic_cast<const QwBPMStripline<QwVQWK_Channel>&>(source));
299 } else if ( type == "SIS3801" ) {
300 return new QwBPMStripline<QwSIS3801_Channel>(dynamic_cast<const QwBPMStripline<QwSIS3801_Channel>&>(source));
301 } else if ( type == "SCALER" || type == "SIS3801D24" ) {
302 return new QwBPMStripline<QwSIS3801D24_Channel>(dynamic_cast<const QwBPMStripline<QwSIS3801D24_Channel>&>(source));
303 } else if ( type == "MOLLERADC" ) {
304 return new QwBPMStripline<QwMollerADC_Channel>(dynamic_cast<const QwBPMStripline<QwMollerADC_Channel>&>(source));
305 } else { // Unsupported one!
306 QwWarning << "BPM of type="<<type<<" is UNSUPPORTED!!\n";
307 exit(-1);
308 }
309}
310
311/**
312 * \brief A fast way of creating a BPM stripline of specified type
313 */
314VQwBPM* VQwBPM::CreateCombo(TString subsystemname, TString name,
315 TString type)
316{
317 Bool_t localDebug = kFALSE;
318 type.ToUpper();
319 if( localDebug ) QwMessage<<"Creating CombinedBPM of type: "<<type<<" with name: "<<
320 name<<". Subsystem Name: " <<subsystemname<<"\n";
321 // (jc2) As a first try, let's do this the ugly way (but rather very
322 // simple), just list out the types of BPM's supported by this code!!!
323 if( type == "VQWK") {
324 return new QwCombinedBPM<QwVQWK_Channel>(subsystemname,name,type);
325 } else if (type == "SIS3801" ) { // Default SCALER channel
326 return new QwCombinedBPM<QwSIS3801_Channel>(subsystemname,name,type);
327 } else if ( type == "SCALER" || type == "SIS3801D24" ) {
328 return new QwCombinedBPM<QwSIS3801D24_Channel>(subsystemname,name,type);
329 } else if ( type == "MOLLERADC" ) {
330 return new QwCombinedBPM<QwMollerADC_Channel>(subsystemname,name,type);
331 } else { // Unsupported one!
332 QwWarning << "BPM of type="<<type<<" is UNSUPPORTED!!\n";
333 exit(-1);
334 }
335}
336
338{
339 Bool_t localDebug = kFALSE;
340 TString type = source.GetModuleType();
341 type.ToUpper();
342 if( localDebug ) QwMessage<<"Creating CombinedBCM of type: "<<type<< QwLog::endl;
343 // (jc2) As a first try, let's do this the ugly way (but rather very
344 // simple), just list out the types of BCM's supported by this code!!!
345 if( type == "VQWK") {
346 return new QwCombinedBPM<QwVQWK_Channel>(dynamic_cast<const QwCombinedBPM<QwVQWK_Channel>&>(source));
347 } else if ( type == "SIS3801" ) { // Default SCALER channel
348 return new QwCombinedBPM<QwSIS3801_Channel>(dynamic_cast<const QwCombinedBPM<QwSIS3801_Channel>&>(source));
349 } else if ( type == "SCALER" || type == "SIS3801D24" ) {
350 return new QwCombinedBPM<QwSIS3801D24_Channel>(dynamic_cast<const QwCombinedBPM<QwSIS3801D24_Channel>&>(source));
351 } else if ( type == "MOLLERADC" ) {
352 return new QwCombinedBPM<QwMollerADC_Channel>(dynamic_cast<const QwCombinedBPM<QwMollerADC_Channel>&>(source));
353 } else { // Unsupported one!
354 QwWarning << "BPM of type="<<type<<" is UNSUPPORTED!!\n";
355 exit(-1);
356 }
357}
A logfile class, based on an identical class in the Hermes analyzer.
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
Decoding and management for VQWK ADC channels (6x32-bit datawords)
static const UInt_t kBPMErrorFlag
Definition QwTypes.h:170
Decoding and management for Moller ADC channels (6x32-bit datawords)
Base and derived classes for scaler channel data handling.
Stripline beam position monitor implementation.
Virtual base class for beam position monitors.
Combined beam position monitor using weighted average.
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
virtual const TString & GetElementName() const
Get the name of this element.
void SetElementName(const TString &name)
Set the name of this element.
TString GetModuleType() const
Return the type of the beam instrument.
Abstract base for concrete hardware channels implementing dual-operator pattern.
void SetSingleEventCuts(Double_t min, Double_t max)
Set the upper and lower limits (fULimit and fLLimit) for this channel.
Double_t fPositionCenter[3]
Definition VQwBPM.h:328
friend class QwCombinedBPM
Definition VQwBPM.h:66
@ kXAxis
Definition VQwBPM.h:72
@ kNumAxes
Definition VQwBPM.h:72
friend class QwBPMStripline
Definition VQwBPM.h:65
void GetSurveyOffsets(Double_t Xoffset, Double_t Yoffset, Double_t Zoffset)
Store geometry/survey offsets for absolute position calibration.
Definition VQwBPM.cc:56
void SetRotation(Double_t)
Set detector rotation angle and update cached trigonometric values.
Definition VQwBPM.cc:108
Double_t fQwStriplineCalibration
Definition VQwBPM.h:329
void SetRootSaveStatus(TString &prefix)
Definition VQwBPM.cc:220
static const TString kAxisLabel[2]
Definition VQwBPM.h:25
Double_t fGains[2]
Definition VQwBPM.h:332
Double_t fRotationAngle
Definition VQwBPM.h:337
Double_t fCosRotation
Definition VQwBPM.h:338
void SetSingleEventCuts(TString, Double_t, Double_t)
Definition VQwBPM.cc:139
static VQwBPM * CreateCombo(TString subsystemname, TString type, TString name)
A fast way of creating a BPM stripline of specified type.
Definition VQwBPM.cc:314
Double_t fRelativeGains[2]
Definition VQwBPM.h:331
void InitializeChannel(TString name)
Initialize common BPM state and set the element name.
Definition VQwBPM.cc:35
Bool_t fGoodEvent
Definition VQwBPM.h:345
void SetRotationOff()
Definition VQwBPM.cc:126
void GetElectronicFactors(Double_t BSENfactor, Double_t AlphaX, Double_t AlphaY)
Apply per-detector electronic calibration and relative gains.
Definition VQwBPM.cc:77
virtual VQwHardwareChannel * GetSubelementByName(TString ch_name)=0
void SetGains(TString pos, Double_t value)
Definition VQwBPM.cc:134
Bool_t bFullSave
Definition VQwBPM.h:348
Double_t fQwStriplineCorrection
Definition VQwBPM.h:330
static VQwBPM * CreateStripline(TString subsystemname, TString type, TString name)
A fast way of creating a BPM stripline of specified type.
Definition VQwBPM.cc:267
static const TString axis[3]
Definition VQwBPM.h:333
virtual VQwBPM & operator=(const VQwBPM &value)=0
Definition VQwBPM.cc:156
Bool_t bRotated
Definition VQwBPM.h:336
VQwBPM()
Definition VQwBPM.h:76
Double_t fSinRotation
Definition VQwBPM.h:339