JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwBPMStripline.cc
Go to the documentation of this file.
1/*!
2 * \file QwBPMStripline.cc
3 * \brief Stripline beam position monitor template implementation
4 */
5
6#include "QwBPMStripline.h"
7
8// System headers
9#include <stdexcept>
10
11// ROOT headers
12#include "ROOT/RNTupleModel.hxx"
13#include "ROOT/RField.hxx"
14
15// Qweak headers
16#ifdef __USE_DATABASE__
17#include "QwDBInterface.h"
18#endif // __USE_DATABASE__
19#include "QwVQWK_Channel.h"
20#include "QwScaler_Channel.h"
21#include "QwMollerADC_Channel.h"
22
23/* Position calibration factor, transform ADC counts in mm*/
24//const Double_t QwBPStripline::kQwStriplineCalibration = 18.77;
25//const Double_t QwBPMStripline::kRotationCorrection = 1./1.414;
26template<typename T>
27const TString QwBPMStripline<T>::subelement[4]={"XP","XM","YP","YM"};
28
29/**
30 * \brief Initialize this BPM stripline with a detector name.
31 * \param name Detector name used for subchannel naming.
32 */
33template<typename T>
35{
36 Short_t i=0;
37 Bool_t localdebug = kFALSE;
38
39
41
42 for(i=kXAxis;i<kNumAxes;i++)
43 fAbsPos[i].InitializeChannel(name+kAxisLabel[i],"derived");
44
45 fEffectiveCharge.InitializeChannel(name+"WS","derived");
46 fEllipticity.InitializeChannel(name+"Elli","derived");
47
48 for(i=0;i<4;i++) {
49 fWire[i].InitializeChannel(name+subelement[i],"raw");
50 if(localdebug)
51 std::cout<<" Wire ["<<i<<"]="<<fWire[i].GetElementName()<<"\n";
52 }
53
54 for(i=kXAxis;i<kNumAxes;i++) fRelPos[i].InitializeChannel(name+"Rel"+kAxisLabel[i],"derived");
55
56 bFullSave=kTRUE;
57
58 return;
59}
60
61/**
62 * \brief Initialize this BPM stripline with subsystem and module type.
63 * \param subsystem Subsystem identifier.
64 * \param name Detector name used for subchannel naming.
65 * \param type Module type tag used in ROOT foldering.
66 */
67template<typename T>
68void QwBPMStripline<T>::InitializeChannel(TString subsystem, TString name,
69 TString type)
70{
71 SetModuleType(type);
72 InitializeChannel(subsystem, name);
73}
74
75/**
76 * \brief Initialize this BPM stripline with subsystem and name.
77 * \param subsystem Subsystem identifier.
78 * \param name Detector name used for subchannel naming.
79 */
80template<typename T>
81void QwBPMStripline<T>::InitializeChannel(TString subsystem, TString name)
82{
83 Short_t i=0;
84 Bool_t localdebug = kFALSE;
85
87
88 for(i=kXAxis;i<kNumAxes;i++)
89 fAbsPos[i].InitializeChannel(subsystem, "QwBPMStripline", name+kAxisLabel[i],"derived");
90
91 fEffectiveCharge.InitializeChannel(subsystem, "QwBPMStripline", name+"WS","derived");
92 fEllipticity.InitializeChannel(subsystem, "QwBPMStripline", name+"Elli","derived");
93
94 for(i=0;i<4;i++) {
95 fWire[i].InitializeChannel(subsystem, "QwBPMStripline", name+subelement[i],"raw");
96 if(localdebug)
97 std::cout<<" Wire ["<<i<<"]="<<fWire[i].GetElementName()<<"\n";
98 }
99
100 for(i=kXAxis;i<kNumAxes;i++) fRelPos[i].InitializeChannel(subsystem, "QwBPMStripline", name+"Rel"+kAxisLabel[i],"derived");
101
102 bFullSave=kTRUE;
103
104 return;
105}
106
107/** \brief Clear event-scoped data in all channels of this BPM. */
108template<typename T>
110{
111 Short_t i=0;
112
113 for(i=0;i<4;i++) fWire[i].ClearEventData();
114
115 for(i=kXAxis;i<kNumAxes;i++){
116 fAbsPos[i].ClearEventData();
117 fRelPos[i].ClearEventData();
118 }
119 fEffectiveCharge.ClearEventData();
120 fEllipticity.ClearEventData();
121
122 return;
123}
124
125
126/**
127 * \brief Apply hardware checks across all wires and derived channels.
128 * \return kTRUE if no hardware error was detected; otherwise kFALSE.
129 */
130template<typename T>
132{
133 Bool_t eventokay=kTRUE;
134
135 UInt_t deviceerror=0;
136 for(Short_t i=0;i<4;i++)
137 {
138 deviceerror|= fWire[i].ApplyHWChecks(); //OR the error code from each wire
139 eventokay &= (deviceerror & 0x0);//AND with 0 since zero means HW is good.
140
141 // if (bDEBUG) std::cout<<" Inconsistent within BPM terminals wire[ "<<i<<" ] "<<std::endl;
142 // if (bDEBUG) std::cout<<" wire[ "<<i<<" ] sequence num "<<fWire[i].GetSequenceNumber()<<" sample size "<<fWire[i].GetNumberOfSamples()<<std::endl;
143 }
144
145 return eventokay;
146}
147
148
149/** \brief Increment error counters for all internal channels. */
150template<typename T>
152{
153 Short_t i=0;
154
155 for(i=0;i<4;i++) fWire[i].IncrementErrorCounters();
156 for(i=kXAxis;i<kNumAxes;i++) {
157 fRelPos[i].IncrementErrorCounters();
158 fAbsPos[i].IncrementErrorCounters();
159 }
160 fEffectiveCharge.IncrementErrorCounters();
161 fEllipticity.IncrementErrorCounters();
162}
163
164/** \brief Print error counters for all internal channels. */
165template<typename T>
167{
168 Short_t i=0;
169
170 for(i=0;i<4;i++) fWire[i].PrintErrorCounters();
171 for(i=kXAxis;i<kNumAxes;i++) {
172 fRelPos[i].PrintErrorCounters();
173 fAbsPos[i].PrintErrorCounters();
174 }
175 fEffectiveCharge.PrintErrorCounters();
176 fEllipticity.PrintErrorCounters();
177}
178
179/** \brief Aggregate and return the event-cut error flag for this BPM. */
180template<typename T>
182 Short_t i=0;
183 UInt_t error=0;
184 for(i=0;i<4;i++) error|=fWire[i].GetEventcutErrorFlag();
185 for(i=kXAxis;i<kNumAxes;i++) {
186 error|=fRelPos[i].GetEventcutErrorFlag();
187 error|=fAbsPos[i].GetEventcutErrorFlag();
188 }
189 error|=fEffectiveCharge.GetEventcutErrorFlag();
190 error|=fEllipticity.GetEventcutErrorFlag();
191 return error;
192}
193
194/** \brief Update and return the aggregated event-cut error flag. */
195template<typename T>
197{
198 Short_t i=0;
199 UInt_t error1=0;
200 UInt_t error2=0;
201 for(i=0;i<4;i++){
202 error1 |= fWire[i].GetErrorCode();
203 error2 |= fWire[i].GetEventcutErrorFlag();
204 }
205 for(i=kXAxis;i<kNumAxes;i++) {
206 fRelPos[i].UpdateErrorFlag(error1);
207 fAbsPos[i].UpdateErrorFlag(error1);
208 error2|=fRelPos[i].GetEventcutErrorFlag();
209 error2|=fAbsPos[i].GetEventcutErrorFlag();
210 }
211 fEffectiveCharge.UpdateErrorFlag(error1);
212 error2|=fEffectiveCharge.GetEventcutErrorFlag();
213 fEllipticity.UpdateErrorFlag(error1);
214 error2|=fEllipticity.GetEventcutErrorFlag();
215 return error2;
216};
217
218
219/**
220 * \brief Check for burp failures against another BPM of the same type.
221 * \param ev_error Reference BPM to compare against.
222 * \return kTRUE if a burp failure was detected; otherwise kFALSE.
223 */
224template<typename T>
226 Short_t i=0;
227 Bool_t burpstatus = kFALSE;
228 try {
229 if(typeid(*ev_error)==typeid(*this)) {
230 //std::cout<<" Here in QwBPMStripline::CheckForBurpFail \n";
231 if (this->GetElementName()!="") {
232 const QwBPMStripline<T>* value_bpm = dynamic_cast<const QwBPMStripline<T>* >(ev_error);
233 for(i=0;i<4;i++){
234 burpstatus |= fWire[i].CheckForBurpFail(&(value_bpm->fWire[i]));
235 }
236 for(i=kXAxis;i<kNumAxes;i++) {
237 burpstatus |= fRelPos[i].CheckForBurpFail(&(value_bpm->fRelPos[i]));
238 burpstatus |= fAbsPos[i].CheckForBurpFail(&(value_bpm->fAbsPos[i]));
239 }
240 burpstatus |= fEffectiveCharge.CheckForBurpFail(&(value_bpm->fEffectiveCharge));
241 burpstatus |= fEllipticity.CheckForBurpFail(&(value_bpm->fEllipticity));
242 }
243 } else {
244 TString loc="Standard exception from QwBPMStripline::CheckForBurpFail :"+
245 ev_error->GetElementName()+" "+this->GetElementName()+" are not of the "
246 +"same type";
247 throw std::invalid_argument(loc.Data());
248 }
249 } catch (std::exception& e) {
250 std::cerr<< e.what()<<std::endl;
251 }
252 return burpstatus;
253};
254
255
256template<typename T>
258 Short_t i=0;
259 try {
260 if(typeid(*ev_error)==typeid(*this)) {
261 // std::cout<<" Here in QwBPMStripline::UpdateErrorFlag \n";
262 if (this->GetElementName()!="") {
263 const QwBPMStripline<T>* value_bpm = dynamic_cast<const QwBPMStripline<T>* >(ev_error);
264 for(i=0;i<4;i++){
265 fWire[i].UpdateErrorFlag(value_bpm->fWire[i]);
266 }
267 for(i=kXAxis;i<kNumAxes;i++) {
268 fRelPos[i].UpdateErrorFlag(value_bpm->fRelPos[i]);
269 fAbsPos[i].UpdateErrorFlag(value_bpm->fAbsPos[i]);
270 }
271 fEffectiveCharge.UpdateErrorFlag(value_bpm->fEffectiveCharge);
272 fEllipticity.UpdateErrorFlag(value_bpm->fEllipticity);
273 }
274 } else {
275 TString loc="Standard exception from QwBPMStripline::UpdateErrorFlag :"+
276 ev_error->GetElementName()+" "+this->GetElementName()+" are not of the "
277 +"same type";
278 throw std::invalid_argument(loc.Data());
279 }
280 } catch (std::exception& e) {
281 std::cerr<< e.what()<<std::endl;
282 }
283};
284
285
286template<typename T>
288{
289 Bool_t status=kTRUE;
290 Int_t i=0;
291
292 UInt_t element_error_code[2];
293 //Event cuts for four wires
294 for(i=0;i<4;i++){
295 if (fWire[i].ApplySingleEventCuts()){ //for RelX
296 status&=kTRUE;
297 }
298 else{
299 status&=kFALSE;
300 if (bDEBUG) std::cout<<" Abs X event cut failed ";
301 }
302 }
303
304 //Get the rex/abs X event cut error flag from xm and xp
305 element_error_code[kXAxis] = GetSubelementByName("xm")->GetErrorCode() | GetSubelementByName("xp")->GetErrorCode();
306 //Get the rex/abs Y event cut error flag from ym and yp
307 element_error_code[kYAxis] = GetSubelementByName("ym")->GetErrorCode() | GetSubelementByName("yp")->GetErrorCode();
308 //Update the error flags for rel and abs positions
309 fRelPos[kXAxis].UpdateErrorFlag(element_error_code[kXAxis]);
310 fRelPos[kYAxis].UpdateErrorFlag(element_error_code[kYAxis]);
311 fAbsPos[kXAxis].UpdateErrorFlag(element_error_code[kXAxis]);
312 fAbsPos[kYAxis].UpdateErrorFlag(element_error_code[kYAxis]);
313 //update the sum of error flags of all wires to the charge element
314 fEffectiveCharge.UpdateErrorFlag(element_error_code[kXAxis]|element_error_code[kYAxis]);
315 fEllipticity.UpdateErrorFlag(element_error_code[kXAxis]|element_error_code[kYAxis]);
316
317
318
319 //Event cuts for Relative X & Y
320 for(i=kXAxis;i<kNumAxes;i++){
321 if (fRelPos[i].ApplySingleEventCuts()){ //for RelX
322 status&=kTRUE;
323 }
324 else{
325 status&=kFALSE;
326 if (bDEBUG) std::cout<<" Rel X event cut failed ";
327 }
328 }
329
330 for(i=kXAxis;i<kNumAxes;i++){
331 if (fAbsPos[i].ApplySingleEventCuts()){ //for RelX
332 status&=kTRUE;
333 }
334 else{
335 status&=kFALSE;
336 if (bDEBUG) std::cout<<" Abs X event cut failed ";
337 }
338 }
339
340 //Event cuts for four wire sum (EffectiveCharge) are already ORed when EffectiveCharge is calculated
341 if (fEffectiveCharge.ApplySingleEventCuts()){
342 status&=kTRUE;
343 }
344 if (fEllipticity.ApplySingleEventCuts()){
345 status&=kTRUE;
346 }
347 else{
348 status&=kFALSE;
349 if (bDEBUG) std::cout<<"EffectiveCharge event cut failed ";
350 }
351 return status;
352}
353
354template<typename T>
356{
357 VQwHardwareChannel* tmpptr = NULL;
358 ch_name.ToLower();
359 if (ch_name=="xp"){
360 tmpptr = &fWire[0];
361 }else if (ch_name=="xm"){
362 tmpptr = &fWire[1];
363 }else if (ch_name=="yp"){
364 tmpptr = &fWire[2];
365 }else if (ch_name=="ym"){
366 tmpptr = &fWire[3];
367 }else if (ch_name=="relx"){
368 tmpptr = &fRelPos[0];
369 }else if (ch_name=="rely"){
370 tmpptr = &fRelPos[1];
371 }else if (ch_name=="absx" || ch_name=="x" ){
372 tmpptr = &fAbsPos[0];
373 }else if (ch_name=="absy" || ch_name=="y"){
374 tmpptr = &fAbsPos[1];
375 }else if (ch_name=="effectivecharge" || ch_name=="charge"){
376 tmpptr = &fEffectiveCharge;
377 }else if (ch_name=="ellipticity" || ch_name=="elli"){
378 tmpptr = &fEllipticity;
379 } else {
380 TString loc="QwBPMStripline::GetSubelementByName for"
381 + this->GetElementName() + " was passed "
382 + ch_name + ", which is an unrecognized subelement name.";
383 throw std::invalid_argument(loc.Data());
384 }
385 return tmpptr;
386}
387
388/*
389template<typename T>
390void QwBPMStripline<T>::SetSingleEventCuts(TString ch_name, Double_t minX, Double_t maxX)
391{
392 VQwHardwareChannel* tmpptr = GetSubelementByName(ch_name);
393 QwMessage << ch_name
394 << " LL " << minX <<" UL " << maxX <<QwLog::endl;
395 tmpptr->SetSingleEventCuts(minX,maxX);
396}
397*/
398
399template<typename T>
400void QwBPMStripline<T>::SetSingleEventCuts(TString ch_name, UInt_t errorflag,Double_t minX, Double_t maxX, Double_t stability, Double_t burplevel){
401 errorflag|=kBPMErrorFlag;//update the device flag
402 if (ch_name=="xp"){
403 QwMessage<<"XP LL " << minX <<" UL " << maxX <<QwLog::endl;
404 QwError<<"***************************inside QwBPStripline "<<typeid(this).name()<<QwLog::endl;
405 fWire[0].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
406
407 }else if (ch_name=="xm"){
408 QwMessage<<"XM LL " << minX <<" UL " << maxX <<QwLog::endl;
409 fWire[1].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
410
411 }else if (ch_name=="yp"){
412 QwMessage<<"YP LL " << minX <<" UL " << maxX <<QwLog::endl;
413 fWire[2].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
414
415 }else if (ch_name=="ym"){
416 QwMessage<<"YM LL " << minX <<" UL " << maxX <<QwLog::endl;
417 fWire[3].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
418
419 }else if (ch_name=="relx"){
420 QwMessage<<"RelX LL " << minX <<" UL " << maxX <<QwLog::endl;
421 fRelPos[0].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
422
423 }else if (ch_name=="rely"){
424 QwMessage<<"RelY LL " << minX <<" UL " << maxX <<QwLog::endl;
425 fRelPos[1].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
426
427 } else if (ch_name=="absx"){
428 //cuts for the absolute x and y
429 QwMessage<<"AbsX LL " << minX <<" UL " << maxX <<QwLog::endl;
430 fAbsPos[0].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
431
432 }else if (ch_name=="absy"){
433 QwMessage<<"AbsY LL " << minX <<" UL " << maxX <<QwLog::endl;
434 fAbsPos[1].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
435
436 }else if (ch_name=="effectivecharge"){
437 QwMessage<<"EffectveQ LL " << minX <<" UL " << maxX <<QwLog::endl;
438 fEffectiveCharge.SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
439
440 }else if (ch_name=="ellipticity"){
441 QwMessage<<"Ellipticity LL " << minX <<" UL " << maxX <<QwLog::endl;
442 fEllipticity.SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
443 }
444}
445
446
447template<typename T>
449{
450 Bool_t localdebug = kFALSE;
451 static T numer("numerator","derived"), denom("denominator","derived");
452 static T tmp1("tmp1","derived"), tmp2("tmp2","derived");
453 static T tmp3("tmp3","derived"), tmp4("tmp4","derived");
454 static T tmp5("tmp3","derived");
455 static T rawpos[2] = {T("rawpos_0","derived"),T("rawpos_1","derived")};
456
457 Short_t i = 0;
458
460 /**First apply HW checks and update HW error flags.
461 Calling this routine here and not in ApplySingleEventCuts
462 makes a difference for a BPMs because they have derived devices.
463 */
464
465 fEffectiveCharge.ClearEventData();
466 fEllipticity.ClearEventData();
467
468 for(i=0;i<4;i++)
469 {
470 fWire[i].ProcessEvent();
472 if (i<2)
473 {
475 }
476 else
477 {
479 }
480 }
482 fEllipticity.Scale(0.5*fQwStriplineCalibration*fQwStriplineCalibration); // Include 2*k/sigma scale factor here
483
484 /**
485 To obtain the beam position in X and Y in the CEBAF coordinates, we use the following equations
486
487 (XP - AlphaX XM)
488 RelX (bpm coordinates) = fQwStriplineCalibration x GainX x ----------------
489 (XP + AlphaX XM)
490
491 (YP - AplhaY YM)
492 RelY (bpm coordinates) = fQwStriplineCalibration x GainY x ----------------
493 (YP + AlphaY YM)
494
495 To get back to accelerator coordinates, rotate anti-clockwise around +Z by phi degrees (angle w.r.t X axis).
496
497 RelX (accelerator coordinates) = cos(phi) RelX - sin(phi)RelY
498
499 RelY (accelerator coordinates) = sin(phi) RelX + cos(Phi)RelY
500
501 The Ellipticity is calculated as coefficients*(xp+xm-yp-ym)/(xp+xm+yp+ym)
502 where the coefficients are ~ 2*k/sigma, k = stripline calibration, sigma = BPM effective size
503 */
504
505 for(i=kXAxis;i<kNumAxes;i++)
506 {
507// fWire[i*2+1].PrintInfo();
508 fWire[i*2+1].Scale(fRelativeGains[i]);
509// fWire[i*2+1].PrintInfo();
510 numer.Difference(fWire[i*2],fWire[i*2+1]);
511 denom.Sum(fWire[i*2],fWire[i*2+1]);
512 rawpos[i].Ratio(numer,denom);
513 rawpos[i].Scale(fQwStriplineCalibration);
514
515 if(localdebug)
516 {
517 std::cout<<" stripline name="<<fElementName<<std::endl;
518 // std::cout<<" event number= "<<fWire[i*2].GetSequenceNumber()<<std::endl;
519 std::cout<<" hw Wire["<<i*2<<"]="<<fWire[i*2].GetValue()<<" ";
520 std::cout<<" hw relative gain * Wire["<<i*2+1<<"]="<<fWire[i*2+1].GetValue()<<"\n";
521 std::cout<<" Relative gain["<<i<<"]="<<fRelativeGains[i]<<"\n";
522 std::cout<<" hw numerator= "<<numer.GetValue()<<" ";
523 std::cout<<" hw denominator= "<<denom.GetValue()<<"\n";
524 std::cout<<" Rotation = "<<fRotationAngle<<std::endl;
525 }
526 }
527
528 for(i=kXAxis;i<kNumAxes;i++){
529 tmp1.AssignScaledValue(rawpos[i], fCosRotation);
530// tmp1.PrintInfo();
531 tmp2.AssignScaledValue(rawpos[1-i], fSinRotation);
532 if (i == kXAxis) {
533 fRelPos[i].Difference(tmp1,tmp2);
534 } else {
535 fRelPos[i].Sum(tmp1,tmp2);
536 }
537 }
538
539
540 for(i=kXAxis;i<kNumAxes;i++){
541 fAbsPos[i] = fRelPos[i];
542 fAbsPos[i].AddChannelOffset(fPositionCenter[i]);
543 fAbsPos[i].Scale(1.0/fGains[i]);
544
545// Start from here.....................................
546
547 if(localdebug)
548 {
549 std::cout<<" hw fRelPos["<<kAxisLabel[i]<<"]="<<fRelPos[i].GetValue()<<"\n";
550 std::cout<<" hw fOffset["<<kAxisLabel[i]<<"]="<<fPositionCenter[i]<<"\n";
551 std::cout<<" hw fAbsPos["<<kAxisLabel[i]<<"]="<<fAbsPos[i].GetValue()<<"\n \n";
552 }
553
554 }
555 // Ellipticity gets corrected by the BPM central axis relative positions
556 tmp3.Product(fRelPos[kXAxis],fRelPos[kXAxis]);
557 tmp4.Product(fRelPos[kYAxis],fRelPos[kYAxis]);
558 tmp5.Difference(tmp3,tmp4);
559 tmp5.Scale(-1.0*0.250014); // FIXME Does this correction factor need a BPM specific (i.e. BSEN) scaling factor? - It already includes BSENfactor^2 because it is made of post-BSENfactor scaled X and Y values, so lets assume its ok for now
560 fEllipticity.Sum(fEllipticity,tmp5); // Correction to ellipticity (only 1st order correction)
561
562 return;
563}
564
565
566template<typename T>
567Int_t QwBPMStripline<T>::ProcessEvBuffer(UInt_t* buffer, UInt_t word_position_in_buffer,UInt_t index)
568{
569 if(index<4)
570 {
571 fWire[index].ProcessEvBuffer(buffer,word_position_in_buffer);
572 }
573 else
574 {
575 std::cerr <<
576 "QwBPMStripline::ProcessEvBuffer(): attempt to fill in raw data for a wire that doesn't exist \n";
577 }
578 return word_position_in_buffer;
579}
580
581
582
583template<typename T>
585{
586 for (Short_t i = 0; i < 2; i++) {
587 fAbsPos[i].PrintValue();
588 fRelPos[i].PrintValue();
589 }
590 fEffectiveCharge.PrintValue();
591 fEllipticity.PrintValue();
592}
593
594
595template<typename T>
597{
598
599 QwMessage << "void QwBPMStripline<T>::WritePromptSummary() const test " << QwLog::endl;
600 // for (Short_t i = 0; i < 2; i++) {
601 // fAbsPos[i].PrintValue();
602 // fRelPos[i].PrintValue();
603 // }
604 return;
605}
606
607
608template<typename T>
610{
611 Short_t i = 0;
612 for (i = 0; i < 4; i++) fWire[i].PrintInfo();
613 for (i = 0; i < 2; i++) {
614 fRelPos[i].PrintInfo();
615 fAbsPos[i].PrintInfo();
616 }
617 fEffectiveCharge.PrintInfo();
618 fEllipticity.PrintInfo();
619}
620
621
622template<typename T>
624{
625 TString thisname;
626 if(subindex<4&&subindex>-1)
627 thisname=fWire[subindex].GetElementName();
628 else
629 std::cerr<<"QwBPMStripline::GetSubElementName for "<<
630 GetElementName()<<" this subindex doesn't exists \n";
631
632 return thisname;
633}
634
635template<typename T>
637{
638 subname.ToUpper();
639 UInt_t localindex = kInvalidSubelementIndex;
640 for(Short_t i=0;i<4;i++) if(subname==subelement[i])localindex=i;
641
642 if(localindex==kInvalidSubelementIndex)
643 std::cerr << "QwBPMStripline::GetSubElementIndex is unable to associate the string -"
644 <<subname<<"- to any index"<<std::endl;
645 return localindex;
646}
647
648template<typename T>
650{
651 for(Short_t i=kXAxis;i<kNumAxes;i++){
652 fAbsPos[i]= fRelPos[i];
653 fAbsPos[i].AddChannelOffset(fPositionCenter[i]);
654 }
655 // For Z, the absolute position will be the offset we are reading from the
656 // geometry map file. Since we are not putting that to the tree it is not
657 // treated as a vqwk channel.
658}
659
660
661template<typename T>
663{
664 *(dynamic_cast<QwBPMStripline<T>*>(this)) =
665 *(dynamic_cast<const QwBPMStripline<T>*>(&value));
666 return *this;
667}
668
669template<typename T>
671{
672 VQwBPM::operator= (value);
673
674 this->bRotated=value.bRotated;
675 if (GetElementName()!=""){
676 Short_t i = 0;
678 this->fEllipticity=value.fEllipticity;
679 for(i=0;i<4;i++) this->fWire[i]=value.fWire[i];
680 for(i=kXAxis;i<kNumAxes;i++) {
681 this->fRelPos[i]=value.fRelPos[i];
682 this->fAbsPos[i]=value.fAbsPos[i];
683 }
684 }
685 return *this;
686}
687
688template<typename T>
690{
691 *(dynamic_cast<QwBPMStripline<T>*>(this)) +=
692 *(dynamic_cast<const QwBPMStripline<T>*>(&value));
693 return *this;
694}
695
696template<typename T>
698{
699
700 if (GetElementName()!=""){
701 Short_t i = 0;
703 this->fEllipticity+=value.fEllipticity;
704 for(i=0;i<4;i++) this->fWire[i]+=value.fWire[i];
705 for(i=kXAxis;i<kNumAxes;i++) {
706 this->fRelPos[i]+=value.fRelPos[i];
707 this->fAbsPos[i]+=value.fAbsPos[i];
708 }
709 }
710 return *this;
711}
712
713template<typename T>
715{
716 *(dynamic_cast<QwBPMStripline<T>*>(this)) -=
717 *(dynamic_cast<const QwBPMStripline<T>*>(&value));
718 return *this;
719}
720template<typename T>
722{
723
724 if (GetElementName()!=""){
725 Short_t i = 0;
727 this->fEllipticity-=value.fEllipticity;
728 for(i=0;i<4;i++) this->fWire[i]-=value.fWire[i];
729 for(i=kXAxis;i<kNumAxes;i++) {
730 this->fRelPos[i]-=value.fRelPos[i];
731 this->fAbsPos[i]-=value.fAbsPos[i];
732 }
733 }
734 return *this;
735}
736
737template<typename T>
739{
740 Ratio(*dynamic_cast<QwBPMStripline<T>*>(&numer),
741 *dynamic_cast<QwBPMStripline<T>*>(&denom));
742}
743
744template<typename T>
746{
747 // this function is called when forming asymmetries. In this case what we actually want for the
748 // stripline is the difference only not the asymmetries
749
750 *this=numer;
751 this->fEffectiveCharge.Ratio(numer.fEffectiveCharge,denom.fEffectiveCharge);
752 this->fEllipticity.Ratio(numer.fEllipticity,denom.fEllipticity);
753}
754
755
756
757template<typename T>
758void QwBPMStripline<T>::Scale(Double_t factor)
759{
760 Short_t i = 0;
761 fEffectiveCharge.Scale(factor);
762 fEllipticity.Scale(factor);
763
764 for(i=0;i<4;i++) fWire[i].Scale(factor);
765 for(Short_t i=kXAxis;i<kNumAxes;i++){
766 fRelPos[i].Scale(factor);
767 fAbsPos[i].Scale(factor);
768 }
769}
770
771
772template<typename T>
774{
775 Short_t i = 0;
776 for (i = 0; i < 4; i++){
777 fWire[i].CalculateRunningAverage();
778 }
779
780 for (i = 0; i < 2; i++){
781 fRelPos[i].CalculateRunningAverage();
782 fAbsPos[i].CalculateRunningAverage();
783 }
784 fEffectiveCharge.CalculateRunningAverage();
785 fEllipticity.CalculateRunningAverage();
786}
787
788
789template<typename T>
790void QwBPMStripline<T>::AccumulateRunningSum(const VQwBPM& value, Int_t count, Int_t ErrorMask)
791{
792 AccumulateRunningSum(*dynamic_cast<const QwBPMStripline<T>* >(&value), count, ErrorMask);
793}
794
795template<typename T>
796void QwBPMStripline<T>::AccumulateRunningSum(const QwBPMStripline<T>& value, Int_t count, Int_t ErrorMask)
797{
798 Short_t i = 0;
799 for (i = 0; i < 4; i++){
800 fWire[i].AccumulateRunningSum(value.fWire[i], count, ErrorMask);
801 }
802 for (i = 0; i < 2; i++){
803 fRelPos[i].AccumulateRunningSum(value.fRelPos[i], count, ErrorMask);
804 fAbsPos[i].AccumulateRunningSum(value.fAbsPos[i], count, ErrorMask);
805 }
806 fEffectiveCharge.AccumulateRunningSum(value.fEffectiveCharge, count, ErrorMask);
807 fEllipticity.AccumulateRunningSum(value.fEllipticity, count, ErrorMask);
808}
809template<typename T>
811 DeaccumulateRunningSum(*dynamic_cast<QwBPMStripline<T>* >(&value), ErrorMask);
812};
813
814template<typename T>
816 Short_t i = 0;
817 for (i = 0; i < 4; i++){
818 fWire[i].DeaccumulateRunningSum(value.fWire[i], ErrorMask);
819 }
820 for (i = 0; i < 2; i++){
821 fRelPos[i].DeaccumulateRunningSum(value.fRelPos[i], ErrorMask);
822 fAbsPos[i].DeaccumulateRunningSum(value.fAbsPos[i], ErrorMask);
823 }
824 fEffectiveCharge.DeaccumulateRunningSum(value.fEffectiveCharge, ErrorMask);
825 fEllipticity.DeaccumulateRunningSum(value.fEllipticity, ErrorMask);
826};
827
828template<typename T>
829void QwBPMStripline<T>::ConstructHistograms(TDirectory *folder, TString &prefix)
830{
831
832 if (GetElementName()=="") {
833 // This channel is not used, so skip filling the histograms.
834 } else {
835 fEffectiveCharge.ConstructHistograms(folder, prefix);
836 fEllipticity.ConstructHistograms(folder, prefix);
837 TString thisprefix=prefix;
838
839 if(prefix.Contains("asym_"))
840 thisprefix.ReplaceAll("asym_","diff_");
841 this->SetRootSaveStatus(prefix);
842 Short_t i = 0;
843 if(bFullSave) {
844 for(i=0;i<4;i++) fWire[i].ConstructHistograms(folder, thisprefix);
845 }
846 for(i=kXAxis;i<kNumAxes;i++) {
847 fRelPos[i].ConstructHistograms(folder, thisprefix);
848 fAbsPos[i].ConstructHistograms(folder, thisprefix);
849 }
850 }
851 return;
852}
853
854template<typename T>
856{
857 if (GetElementName()=="") {
858 // This channel is not used, so skip filling the histograms.
859 }
860 else {
861 fEffectiveCharge.FillHistograms();
862 fEllipticity.FillHistograms();
863 Short_t i = 0;
864 if(bFullSave) {
865 for(i=0;i<4;i++) fWire[i].FillHistograms();
866 }
867 for(i=kXAxis;i<kNumAxes;i++){
868 fRelPos[i].FillHistograms();
869 fAbsPos[i].FillHistograms();
870 }
871 //No data for z position
872 }
873 return;
874}
875
876template<typename T>
878{
879 if (GetElementName()==""){
880 // This channel is not used, so skip constructing trees.
881 }
882 else {
883 TString thisprefix=prefix;
884 if(prefix.Contains("asym_"))
885 thisprefix.ReplaceAll("asym_","diff_");
886
887 this->SetRootSaveStatus(prefix);
888
889 fEffectiveCharge.ConstructBranchAndVector(tree,prefix,values);
890 fEllipticity.ConstructBranchAndVector(tree,prefix,values);
891 Short_t i = 0;
892 if(bFullSave) {
893 for(i=0;i<4;i++) fWire[i].ConstructBranchAndVector(tree,thisprefix,values);
894 }
895 for(i=kXAxis;i<kNumAxes;i++) {
896 // 2018dec20, pking: Do not output the relative positions to Trees
897 // fRelPos[i].ConstructBranchAndVector(tree,thisprefix,values);
898 fAbsPos[i].ConstructBranchAndVector(tree,thisprefix,values);
899 }
900
901 }
902 return;
903}
904
905template<typename T>
906void QwBPMStripline<T>::ConstructBranch(TTree *tree, TString &prefix)
907{
908 if (GetElementName()==""){
909 // This channel is not used, so skip constructing trees.
910 }
911 else {
912 TString thisprefix=prefix;
913 if(prefix.Contains("asym_"))
914 thisprefix.ReplaceAll("asym_","diff_");
915
916 this->SetRootSaveStatus(prefix);
917
918 fEffectiveCharge.ConstructBranch(tree,prefix);
919 fEllipticity.ConstructBranch(tree,prefix);
920 Short_t i = 0;
921 if(bFullSave) {
922 for(i=0;i<4;i++) fWire[i].ConstructBranch(tree,thisprefix);
923 }
924 for(i=kXAxis;i<kNumAxes;i++) {
925 // 2018dec20, pking: Do not output the relative positions to Trees
926 // fRelPos[i].ConstructBranch(tree,thisprefix);
927 fAbsPos[i].ConstructBranch(tree,thisprefix);
928 }
929
930 }
931 return;
932}
933
934template<typename T>
935void QwBPMStripline<T>::ConstructBranch(TTree *tree, TString &prefix, QwParameterFile& modulelist)
936{
937 TString devicename;
938 /*
939 QwMessage <<" QwBCM::ConstructBranch "<<QwLog::endl;
940 modulelist.RewindToFileStart();
941 while (modulelist.ReadNextLine()){
942 modulelist.TrimComment('!'); // Remove everything after a '!' character.
943 modulelist.TrimWhitespace(); // Get rid of leading and trailing spaces.
944 QwMessage <<" "<<modulelist.GetLine()<<" ";
945 }
946 QwMessage <<QwLog::endl;
947 */
948 devicename=GetElementName();
949 devicename.ToLower();
950 if (GetElementName()==""){
951 // This channel is not used, so skip filling the histograms.
952 } else
953 {
954 if (modulelist.HasValue(devicename)){
955 TString thisprefix=prefix;
956 if(prefix.Contains("asym_"))
957 thisprefix.ReplaceAll("asym_","diff_");
958
959 this->SetRootSaveStatus(prefix);
960
961 fEffectiveCharge.ConstructBranch(tree,prefix);
962 fEllipticity.ConstructBranch(tree,prefix);
963 Short_t i = 0;
964 if(bFullSave) {
965 for(i=0;i<4;i++) fWire[i].ConstructBranch(tree,thisprefix);
966 }
967 for(i=kXAxis;i<kNumAxes;i++) {
968 // 2018dec20, pking: Do not output the relative positions to Trees
969 // fRelPos[i].ConstructBranch(tree,thisprefix);
970 fAbsPos[i].ConstructBranch(tree,thisprefix);
971 }
972
973 QwMessage <<" Tree leaves added to "<<devicename<<" Corresponding channels"<<QwLog::endl;
974 }
975 // this functions doesn't do anything yet
976 }
977
978 return;
979}
980
981
982template<typename T>
984{
985 if (GetElementName()=="") {
986 // This channel is not used, so skip filling the tree.
987 }
988 else {
989 fEffectiveCharge.FillTreeVector(values);
990 fEllipticity.FillTreeVector(values);
991 Short_t i = 0;
992 if(bFullSave) {
993 for(i=0;i<4;i++) fWire[i].FillTreeVector(values);
994 }
995 for(i=kXAxis;i<kNumAxes;i++){
996 // 2018dec20, pking: Do not output the relative positions to Trees
997 // fRelPos[i].FillTreeVector(values);
998 fAbsPos[i].FillTreeVector(values);
999 }
1000 }
1001 return;
1002}
1003
1004#ifdef HAS_RNTUPLE_SUPPORT
1005template<typename T>
1006void QwBPMStripline<T>::ConstructNTupleAndVector(std::unique_ptr<ROOT::RNTupleModel>& model, TString& prefix, std::vector<Double_t>& values, std::vector<std::shared_ptr<Double_t>>& fieldPtrs)
1007{
1008 if (GetElementName()==""){
1009 // This channel is not used, so skip constructing RNTuple.
1010 }
1011 else {
1012 TString thisprefix=prefix;
1013 if(prefix.Contains("asym_"))
1014 thisprefix.ReplaceAll("asym_","diff_");
1015
1016 this->SetRootSaveStatus(prefix);
1017
1018 fEffectiveCharge.ConstructNTupleAndVector(model, prefix, values, fieldPtrs);
1019 fEllipticity.ConstructNTupleAndVector(model, prefix, values, fieldPtrs);
1020 Short_t i = 0;
1021 if(bFullSave) {
1022 for(i=0;i<4;i++) fWire[i].ConstructNTupleAndVector(model, thisprefix, values, fieldPtrs);
1023 }
1024 for(i=kXAxis;i<kNumAxes;i++) {
1025 // 2018dec20, pking: Do not output the relative positions to RNTuple
1026 // fRelPos[i].ConstructNTupleAndVector(model, thisprefix, values, fieldPtrs);
1027 fAbsPos[i].ConstructNTupleAndVector(model, thisprefix, values, fieldPtrs);
1028 }
1029 }
1030}
1031
1032template<typename T>
1033void QwBPMStripline<T>::FillNTupleVector(std::vector<Double_t>& values) const
1034{
1035 if (GetElementName()=="") {
1036 // This channel is not used, so skip filling the RNTuple.
1037 }
1038 else {
1039 fEffectiveCharge.FillNTupleVector(values);
1040 fEllipticity.FillNTupleVector(values);
1041 Short_t i = 0;
1042 if(bFullSave) {
1043 for(i=0;i<4;i++) fWire[i].FillNTupleVector(values);
1044 }
1045 for(i=kXAxis;i<kNumAxes;i++){
1046 // 2018dec20, pking: Do not output the relative positions to RNTuple
1047 // fRelPos[i].FillNTupleVector(values);
1048 fAbsPos[i].FillNTupleVector(values);
1049 }
1050 }
1051}
1052#endif
1053
1054template<typename T>
1056{
1057 Short_t i = 0;
1058 // bEVENTCUTMODE=bcuts;
1059 for (i=0;i<4;i++) fWire[i].SetEventCutMode(bcuts);
1060 for (i=kXAxis;i<kNumAxes;i++) {
1061 fRelPos[i].SetEventCutMode(bcuts);
1062 fAbsPos[i].SetEventCutMode(bcuts);
1063 }
1064 fEffectiveCharge.SetEventCutMode(bcuts);
1065 fEllipticity.SetEventCutMode(bcuts);
1066}
1067
1068
1069template<typename T>
1071{
1072 for(size_t i=kXAxis;i<kNumAxes;i++) {
1073 T relpos(fRelPos[i]);
1074 relpos = fRelPos[i]; // data
1075 fBPMElementList.push_back(relpos);
1076 T abspos(fAbsPos[i]);
1077 abspos = fAbsPos[i]; // dfor(i=kXAxis;i<kNumAxes;i++){
1078 fAbsPos[i] = fRelPos[i];
1079 fAbsPos[i].AddChannelOffset(fPositionCenter[i]);
1080 fAbsPos[i].Scale(1.0/fGains[i]);
1081
1082 fBPMElementList.push_back(abspos);
1083 }
1084 T bpm_sub_element(fEffectiveCharge);
1085 bpm_sub_element = fEffectiveCharge;
1086 fBPMElementList.push_back(bpm_sub_element);
1087 T bpm_sub_element_elli(fEllipticity);
1088 bpm_sub_element_elli = fEllipticity;
1089 fBPMElementList.push_back(bpm_sub_element_elli);
1090}
1091
1092#ifdef __USE_DATABASE__
1093template<typename T>
1094std::vector<QwDBInterface> QwBPMStripline<T>::GetDBEntry()
1095{
1096 std::vector <QwDBInterface> row_list;
1097 row_list.clear();
1098
1099 for(size_t i=0;i<2;i++) {
1100 fRelPos[i].AddEntriesToList(row_list);
1101 fAbsPos[i].AddEntriesToList(row_list);
1102 }
1103 fEffectiveCharge.AddEntriesToList(row_list);
1104 fEllipticity.AddEntriesToList(row_list);
1105 return row_list;
1106}
1107
1108
1109template<typename T>
1110std::vector<QwErrDBInterface> QwBPMStripline<T>::GetErrDBEntry()
1111{
1112 std::vector <QwErrDBInterface> row_list;
1113 row_list.clear();
1114
1115 for(size_t i=0;i<2;i++) {
1116 fRelPos[i].AddErrEntriesToList(row_list);
1117 fAbsPos[i].AddErrEntriesToList(row_list);
1118 }
1119 fEffectiveCharge.AddErrEntriesToList(row_list);
1120 fEllipticity.AddErrEntriesToList(row_list);
1121 return row_list;
1122}
1123#endif // __USE_DATABASE__
1124
1125
1126/**********************************
1127 * Mock data generation routines
1128 **********************************/
1129
1130template<typename T>
1131void QwBPMStripline<T>::SetRandomEventParameters(Double_t meanX, Double_t sigmaX, Double_t meanY, Double_t sigmaY)
1132{
1133 //fAbsPos[kXAxis].SetMockDataAsDiff();
1134 //fAbsPos[kYAxis].SetMockDataAsDiff();
1135
1136 fAbsPos[kXAxis].SetRandomEventParameters(meanX, sigmaX);
1137 fAbsPos[kYAxis].SetRandomEventParameters(meanY, sigmaY);
1138
1139 for(int i = 0; i < 4; i++){
1140 fWire[i].CopyParameters(&fAbsPos[0]);
1141 }
1142
1143/* // Average values of the signals in the stripline ADCs
1144 Double_t sumX = 3.5; // These are just guesses, but I made X and Y different
1145 Double_t sumY = 4.1; // to make it more interesting for the analyzer...
1146
1147 // Rotate the requested position if necessary (this is not tested yet)
1148 if (bRotated) {
1149 Double_t rotated_meanX = (meanX*fCosRotation - meanY*fSinRotation);// / fRotationCorrection;
1150 Double_t rotated_meanY = (meanX*fSinRotation + meanY*fCosRotation);// / fRotationCorrection;
1151 meanX = rotated_meanX;
1152 meanY = rotated_meanY;
1153 }
1154
1155 // Determine the asymmetry from the position
1156 Double_t meanXP = (1.0 + meanX / fQwStriplineCalibration) * sumX / 2.0;
1157 Double_t meanXM = (1.0 - meanX / fQwStriplineCalibration) * sumX / 2.0; // = sumX - meanXP;
1158 Double_t meanYP = (1.0 + meanY / fQwStriplineCalibration) * sumY / 2.0;
1159 Double_t meanYM = (1.0 - meanY / fQwStriplineCalibration) * sumY / 2.0; // = sumY - meanYP;
1160
1161 // Determine the spread of the asymmetry (this is not tested yet)
1162 // (negative sigma should work in the QwVQWK_Channel, but still using fabs)
1163 Double_t sigmaXP = fabs(sumX * sigmaX / meanX);
1164 Double_t sigmaXM = sigmaXP;
1165 Double_t sigmaYP = fabs(sumY * sigmaY / meanY);
1166 Double_t sigmaYM = sigmaYP;
1167
1168 // Propagate these parameters to the ADCs
1169 fWire[0].SetRandomEventParameters(meanXP, sigmaXP);
1170 fWire[1].SetRandomEventParameters(meanXM, sigmaXM);
1171 fWire[2].SetRandomEventParameters(meanYP, sigmaYP);
1172 fWire[3].SetRandomEventParameters(meanYM, sigmaYM);
1173*/
1174
1175}
1176
1177
1178template<typename T>
1179void QwBPMStripline<T>::RandomizeEventData(int helicity, double time)
1180{
1181
1182/* First randomize AbsX and AbsY, then go backwards through the steps of QwBPMStripline<T>::ProcessEvent() to get the randomized wire values.*/
1183
1184 size_t i;
1185 static T numer("numerator","derived"), denom("denominator","derived");
1186 static T tmp1("tmp1","derived"), tmp2("tmp2","derived");
1187 static T rawpos[2] = {T("rawpos_0","derived"),T("rawpos_1","derived")};
1188
1189 // std::cout << "In QwBPMStripline<T>::RandomizeEventData" << std::endl;
1190 for(i=kXAxis;i<kNumAxes;i++){
1191 fAbsPos[i].RandomizeEventData(helicity, time);
1192 //fAbsPos[i].PrintInfo();
1193 }
1194 this->FillRawEventData();
1195}
1196
1197
1198template<typename T>
1200
1201 //Bool_t ldebug=kFALSE;
1202 //Double_t asym=0.0, meanX=0.0, sigmaX=0.0, meanY=0.0, sigmaY=0.0;
1203
1204 Double_t xres=0.0, yres=0.0;
1205
1206 if (paramfile.GetLine().find("resolution")!=std::string::npos){
1207 paramfile.GetNextToken();
1208 xres = paramfile.GetTypedNextToken<Double_t>();
1209 yres = paramfile.GetTypedNextToken<Double_t>();
1210 this->SetResolution(xres, yres);
1211 } else {
1212// again, if we have asymmetry for each coord, we can use the mockable load function acting on fAbsPos[xaxis, yaxis]
1213/*
1214 asym = paramfile.GetTypedNextToken<Double_t>();
1215 meanX = paramfile.GetTypedNextToken<Double_t>();
1216 sigmaX = paramfile.GetTypedNextToken<Double_t>();
1217 meanY = paramfile.GetTypedNextToken<Double_t>();
1218 sigmaY = paramfile.GetTypedNextToken<Double_t>();
1219
1220 if (ldebug==1) {
1221 std::cout << "#################### \n";
1222 std::cout << "asym, meanX, sigmaX, meanY, sigmaY \n" << std::endl;
1223 std::cout << asym << " / "
1224 << meanX << " / "
1225 << sigmaX << " / "
1226 << meanY << " / "
1227 << sigmaY << " / "
1228 << std::endl;
1229 }
1230 this->SetRandomEventParameters(meanX, sigmaX, meanY, sigmaY);
1231 this->SetRandomEventAsymmetry(asym);
1232*/
1233 for(size_t i=kXAxis;i<kNumAxes;i++){
1234 //std::cout << "In QwBPMStripline: ChannelName = " << GetElementName() << std::endl;
1235 fAbsPos[i].SetMockDataAsDiff();
1236 fAbsPos[i].LoadMockDataParameters(paramfile);
1237 }
1238 }
1239}
1240
1241
1242template<typename T>
1244 for(size_t i=kXAxis;i<kNumAxes;i++){
1245 fAbsPos[i].SmearByResolution(fResolution[i]);
1246 }
1247}
1248template<typename T>
1250 // std::cout << this->GetElementName() << " resolution on axis(" << iaxis << ")==" << fResolution[iaxis] << std::endl;
1251 fAbsPos[iaxis].SmearByResolution(fResolution[iaxis]);
1252}
1253
1254template<typename T>
1256{
1257 //std::cout << "*******In QwBPMStripline::FillRawEventData for channel:\t" << this->GetElementName() << std::endl;
1258 // XP = XM*(A+tmpX)/(A-tmpX);
1259
1260 size_t i;
1261 static T numer("numerator","derived"), denom("denominator","derived");
1262 static T tmp1("tmp1","derived"), tmp2("tmp2","derived");
1263 static T rawpos[2] = {T("rawpos_0","derived"),T("rawpos_1","derived")};
1264 int helicity = 0; double time = 0.0;
1265
1266 numer.CopyParameters(&fAbsPos[0]);
1267 denom.CopyParameters(&fAbsPos[0]);
1268 tmp1.CopyParameters(&fAbsPos[0]);
1269 tmp2.CopyParameters(&fAbsPos[0]);
1270 rawpos[0].CopyParameters(&fAbsPos[0]);
1271 rawpos[1].CopyParameters(&fAbsPos[0]);
1272
1273 for(i=kXAxis;i<kNumAxes;i++){
1274 //fAbsPos[i].PrintValue();
1275 fRelPos[i] = fAbsPos[i];
1276 fRelPos[i].Scale(fGains[i]);
1277 fRelPos[i].AddChannelOffset(-1.0*fPositionCenter[i]);
1278 //fRelPos[i].PrintValue();
1279 }
1280
1281 for(i=kXAxis; i<kNumAxes; i++){
1282 tmp1.AssignScaledValue(fRelPos[i], fCosRotation);
1283 tmp2.AssignScaledValue(fRelPos[1-i], fSinRotation);
1284 //std::cout << "CosRotation: " << fCosRotation << std::endl;
1285 //std::cout << "SinRotation: " << fSinRotation << std::endl;
1286 if (i == kXAxis) {
1287 rawpos[i].Sum(tmp1,tmp2);
1288 } else {
1289 rawpos[i].Difference(tmp1,tmp2);
1290 }
1291 }
1292
1293 for(i=kXAxis; i<kNumAxes; i++){
1294 numer.AssignScaledValue(rawpos[i],1.0);
1295 numer.AddChannelOffset(fQwStriplineCalibration);
1296 denom.AssignScaledValue(rawpos[i],-1.0);
1297 denom.AddChannelOffset(fQwStriplineCalibration);
1298 tmp2.SetRandomEventParameters(5.0, 0.005);
1299 // tmp2.SetRandomEventParameters(5.0, 0.0);
1300 tmp2.RandomizeEventData(helicity, time);
1301 tmp1.Ratio(numer,denom);
1302 if (tmp1.GetValue()<1.0){
1303 fWire[i*2+1].AssignScaledValue(tmp2, 1.0);
1304 fWire[i*2].Product(tmp1, tmp2);
1305 } else {
1306 fWire[i*2].AssignScaledValue(tmp2, 1.0);
1307 fWire[i*2+1].Ratio(tmp2, tmp1);
1308 }
1309
1310 //fWire[i*2].PrintValue();
1311 //fWire[i*2+1].PrintValue();
1312 fWire[i*2].CopyParameters(&fAbsPos[0]);
1313 fWire[i*2+1].CopyParameters(&fAbsPos[0]);
1314 fWire[i*2].SetRawEventData();
1315 fWire[i*2+1].SetRawEventData();
1316 //std::cout << "*******In QwBPMStripline::FillRawEventData for channel:\t" << this->GetElementName() << std::endl;
1317 //fWire[i*2].PrintInfo();
1318 //fWire[i*2+1].PrintInfo();
1319 }
1320
1321
1322/* for (Short_t i=0; i<4; i++) {
1323 std::cout << "wire " <<i<< std::endl;
1324 fWire[i].RandomizeEventData(helicity, time);
1325 fWire[i].PrintInfo();
1326 fWire[i].SetRawEventData();
1327 fWire[i].PrintInfo();
1328 }
1329*/
1330 return;
1331}
1332
1333
1334template<typename T>
1335void QwBPMStripline<T>::SetEventData(Double_t* relpos, UInt_t sequencenumber)
1336{
1337 for (Short_t i=0; i<2; i++){
1338 //fRelPos[i].SetHardwareSum(relpos[i], sequencenumber);
1339 }
1340
1341 return;
1342}
1343
1344
1345template<typename T>
1346void QwBPMStripline<T>::EncodeEventData(std::vector<UInt_t> &buffer)
1347{
1348 for (Short_t i=0; i<4; i++) fWire[i].EncodeEventData(buffer);
1349}
1350
1351
1352template<typename T>
1354{
1355 for(Short_t i=0;i<4;i++) fWire[i].SetDefaultSampleSize((size_t)sample_size);
1356 return;
1357}
1358
1359
1360template<typename T>
1361void QwBPMStripline<T>::SetSubElementPedestal(Int_t j, Double_t value)
1362{
1363 fWire[j].SetPedestal(value);
1364 return;
1365}
1366
1367template<typename T>
1369{
1370 fWire[j].SetCalibrationFactor(value);
1371 return;
1372}
1373
1374
1375template class QwBPMStripline<QwVQWK_Channel>;
1376template class QwBPMStripline<QwSIS3801_Channel>;
Base and derived classes for scaler channel data handling.
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#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
static const UInt_t kInvalidSubelementIndex
Definition QwTypes.h:198
Database interface for QwIntegrationPMT and subsystems.
Stripline beam position monitor implementation.
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Configuration file parser with flexible tokenization and search capabilities.
T GetTypedNextToken()
Get next token into specific type.
Bool_t HasValue(TString &vname)
std::string GetLine()
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.
Definition QwRootFile.h:53
VQwDataElement()
Default constructor.
TString fElementName
Name of this data element.
virtual const TString & GetElementName() const
Get the name of this element.
void SetModuleType(TString ModuleType)
set the type of the beam instrument
Abstract base for concrete hardware channels implementing dual-operator pattern.
Templated concrete stripline beam position monitor implementation.
void SetSubElementCalibrationFactor(Int_t j, Double_t value) override
void AccumulateRunningSum(const QwBPMStripline &value, Int_t count=0, Int_t ErrorMask=0xFFFFFFF)
Bool_t ApplyHWChecks()
Apply hardware checks across all wires and derived channels.
void LoadMockDataParameters(QwParameterFile &paramfile) override
std::array< T, 4 > fWire
void PrintInfo() const override
Print multiple lines of information about this data element.
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 ProcessEvent() override
void CalculateRunningAverage() override
void SetEventCutMode(Int_t bcuts) override
void RandomizeEventData(int helicity=0, double time=0.0) override
UInt_t UpdateErrorFlag() override
Update and return the aggregated event-cut error flag.
UInt_t GetEventcutErrorFlag() override
Aggregate and return the event-cut error flag for this BPM.
std::array< T, 2 > fAbsPos
void SetRandomEventParameters(Double_t meanX, Double_t sigmaX, Double_t meanY, Double_t sigmaY) override
void ApplyResolutionSmearing() override
VQwHardwareChannel * GetSubelementByName(TString ch_name) override
static UInt_t GetSubElementIndex(TString subname)
VQwBPM & operator-=(const VQwBPM &value) override
void GetAbsolutePosition() override
void Scale(Double_t factor) override
void SetEventData(Double_t *block, UInt_t sequencenumber)
void WritePromptSummary(QwPromptSummary *ps, TString type)
static const TString subelement[4]
std::vector< T > fBPMElementList
Bool_t ApplySingleEventCuts() override
void ConstructBranch(TTree *tree, TString &prefix) override
void ConstructHistograms(TDirectory *folder, TString &prefix) override
Construct the histograms for this data element.
void EncodeEventData(std::vector< UInt_t > &buffer) override
VQwBPM & operator+=(const VQwBPM &value) override
void InitializeChannel(TString name)
Initialize this BPM stripline with a detector name.
void Ratio(VQwBPM &numer, VQwBPM &denom) override
void SetSingleEventCuts(TString ch_name, UInt_t errorflag, Double_t minX, Double_t maxX, Double_t stability, Double_t burplevel)
void FillHistograms() override
Fill the histograms for this data element.
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values) override
void SetDefaultSampleSize(Int_t sample_size) override
void FillTreeVector(QwRootTreeBranchVector &values) const override
Bool_t CheckForBurpFail(const VQwDataElement *ev_error) override
Check for burp failures against another BPM of the same type.
void PrintValue() const override
Print single line of value and error of this data element.
void IncrementErrorCounters() override
Increment error counters for all internal channels.
TString GetSubElementName(Int_t subindex) override
void SetSubElementPedestal(Int_t j, Double_t value) override
void DeaccumulateRunningSum(VQwBPM &value, Int_t ErrorMask=0xFFFFFFF) override
void PrintErrorCounters() const override
Print error counters for all internal channels.
void ClearEventData() override
Clear event-scoped data in all channels of this BPM.
void FillRawEventData() override
std::array< T, 2 > fRelPos
Double_t fPositionCenter[3]
Definition VQwBPM.h:328
EBeamPositionMonitorAxis
Definition VQwBPM.h:72
@ kXAxis
Definition VQwBPM.h:72
@ kYAxis
Definition VQwBPM.h:72
@ kNumAxes
Definition VQwBPM.h:72
Double_t fResolution[2]
Definition VQwBPM.h:342
Double_t fQwStriplineCalibration
Definition VQwBPM.h:329
void SetRootSaveStatus(TString &prefix)
Definition VQwBPM.cc:220
static const TString kAxisLabel[2]
Definition VQwBPM.h:25
virtual void SetResolution(Double_t resolutionX, Double_t resolutionY)
Definition VQwBPM.h:256
Double_t fGains[2]
Definition VQwBPM.h:332
Double_t fRotationAngle
Definition VQwBPM.h:337
Double_t fCosRotation
Definition VQwBPM.h:338
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
static const Bool_t bDEBUG
Definition VQwBPM.h:350
Bool_t bFullSave
Definition VQwBPM.h:348
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