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}
358
Base and derived classes for scaler channel data handling.
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 Moller ADC channels (6x32-bit datawords)
Decoding and management for VQWK ADC channels (6x32-bit datawords)
static const UInt_t kBPMErrorFlag
Definition QwTypes.h:170
Combined beam position monitor using weighted average.
Stripline beam position monitor implementation.
Virtual base class for beam position monitors.
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