CFEL - ASG Software Suite  2.5.0
CASS
momenta_calculator.cpp
Go to the documentation of this file.
1 //Copyright (C) 2001-2010 Lutz Foucar
2 
3 /**
4  * @file momenta_calculator.cpp file contains the classes that calculate the
5  * momenta of particles from their detector hits.
6  *
7  * @author Lutz Foucar
8  */
9 
10 #include <cmath>
11 #include <iostream>
12 #include <stdexcept>
13 #include <sstream>
14 
15 #include "momenta_calculator.h"
16 #include "spectrometer.h"
17 #include "particle.h"
18 #include "cass_settings.h"
19 
20 
21 //-----------------Constants--------------------------
22 //#define amu_au 1836.15 //Convert Atomic Mass Unit to a.u.
23 //#define Vcm_au 1.9446905050536652707924548855431e-10 //1 a.u. = 5.14220642e9 V/cm
24 //#define ns_au 4.1341373336561364143973749949088e+7 //1 a.u. = 2.418884326505e-8 ns
25 //#define mm_au 1.8897261249935897655251029944769e+7 //1 a.u. = 0.5291772108e-7 mm
26 //#define mmns_au 0,45710289051340228274244496244648 //convert mm/ns in a.u.
27 //#define mmnsns 0.17588201489603770767263287993687e-1 //convert V/cm * C[a.u.]/M[a.u] to mm/ns^2
28 
29 
30 
31 namespace cass
32 {
33 namespace ACQIRIS
34 {
35 namespace UnitConvertion
36 {
37 //@{
38 /** Atomic Units -> SI Units */
39 inline double au2m() {return 5.29177210818E-11;}
40 inline double au2mm() {return au2m()*1E3;}
41 inline double au2s() {return 2.41888432650516E-17;}
42 inline double au2ns() {return au2s()*1E9;}
43 inline double au2mPs() {return 2.187691263373E6;}
44 inline double au2mmPns() {return au2mPs()*1E-6;}
45 inline double au2kg() {return 9.10938215E-31;}
46 //@}
47 //@{
48 /** SI Units -> Atomic Units */
49 inline double mm2au() {return 1./au2mm();}
50 inline double ns2au() {return 1./au2ns();}
51 inline double mmPns2au() {return 1./au2mmPns();}
52 inline double kg2au() {return 1./au2kg();}
53 //@}
54 /** convert V/cm * C[a.u.]/M[a.u] to mm/ns^2 */
55 inline double VPcm2mmPns() {return 0.17588201489603770767263287993687e-1;}
56 /** Atomic mass unit -> SI Unit */
57 inline double amu2kg() {return 1.66053878283E-27;}
58 /** Atomic mass unit -> Atomic Units */
59 inline double amu2au() {return (amu2kg()*kg2au());}
60 /** Atomic Units ->Atomic mass unit */
61 inline double au2amu() {return 1./amu2au();}
62 }
63 inline double Pi() {return 3.1415;}
64 
65 /** calculate Momentum in Detektor Plane
66  *
67  * calculates the momentum of the particle in the detector plane. This is
68  * for the case that a magnetic field is present in the spectrometer.
69  * Usually this is there because one wants to collect all electrons in the
70  * spectrometer.
71  *
72  * First calculate the total momentum in the detector plane. Then we have to
73  * find out where the initial direction of emmision this means we need to
74  * find the angle between the x-axis and the emission angle phi.The angle
75  * depends whether the cyclotron motion is ccw or cw, meaning the B-Field is
76  * pointing into the detektor-plane or out of the detector plane respectivly.
77  *
78  * @param[in] x_mm the x position of the hit in mm
79  * @param[in] y_mm the y position of the hit in mm
80  * @param[in] tof_ns the time of flight of the hit in ns
81  * @param[in] particle the particle properties
82  * @param[out] px_au the x momentum in atomic units
83  * @param[out] py_au the y momentum in atomic units
84  *
85  * @author Lutz Foucar
86  */
87 void getDetPlaneMomenta(double x_mm, double y_mm, double tof_ns, const Particle& particle,
88  double &px_au, double &py_au)
89 {
90  const double tgyr_ns (particle.spectrometer().cyclotronPeriod_ns());
91  const double mass_au (particle.mass_au());
92  const bool rotationClockwise (particle.spectrometer().rotationClockWise());
93  //--convert everything to a.u.--//
94  const double tgyr_au (tgyr_ns * UnitConvertion::ns2au());
95  const double x_au (x_mm * UnitConvertion::mm2au());
96  const double y_au (y_mm * UnitConvertion::mm2au());
97  //--calculate the total momentum in Detektor Plane--//
98  const double wt_total ((2.*Pi()*tof_ns) / (tgyr_ns));
99  //if we already have more than 1 turn, take wt modulo 2*Pi
100  const double wt (fmod(wt_total,2.*Pi()));
101  const double p_total (( sqrt(x_au*x_au + y_au*y_au) * mass_au * Pi() ) / ( sin(0.5*wt) * tgyr_au ));
102  // theta is the angle between x-axis and position on the detektor. The
103  // function atan2 will give values between [-PI..PI] but we need [0..2*PI]
104  double theta = ( atan2(y_mm,x_mm)<0 ) ? atan2(y_mm,x_mm)+ 2.*Pi() : atan2(y_mm,x_mm);
105  //--if the cyc motion is ccw phi is theta - wt/2 if it cw its theta + wt/2--//
106  double phi = (rotationClockwise)? theta + 0.5*wt : theta - 0.5*wt;
107  //--calculate the x and y momenta knowing the initial direction of the total momentum--//
108  px_au = p_total * cos(phi);
109  py_au = p_total * sin(phi);
110 }
111 
112 /** calculate the momentum in the detector plane
113  *
114  * calculate the momentum in the detector plane in case when there is no
115  * magnetic field present. This is simply done by calulating the velocity
116  * of the particle perpendicular to the time of flight axis when it hits
117  * the detector. This is determined by the time if flew and the position it
118  * hit the detector.
119  *
120  * @return the momentum of the particle along the axis
121  * @param axis_mm the position of the hit on the axis in mm
122  * @param tof_ns the time of flight of the hit in ns
123  * @param mass_au the mass of the particle in atomic units
124  *
125  * @author Lutz Foucar
126  */
127 double getDetPlaneMomentum(double axis_mm, double tof_ns, double mass_au)
128 {
129  // std::cout << "getDetPlaneMomentum(): axis_mm '"<<axis_mm<<"' tof '"<<tof_ns<<"' mass '"<<mass_au<<"'"<<std::endl;
130  return ((axis_mm * mass_au) / tof_ns ) * UnitConvertion::mmPns2au();
131 }
132 
133 /** Momentum along time of flight
134  *
135  * this will use a direct direct calculation since there is only one
136  * spectrometer region.
137  *
138  * calculates the acceleration from the E-field in the region, charge and
139  * mass of the particle. The result will be in \f$\frac{mm^2}{ns}\f$. With
140  * this one can calculate the velocity of the particle after it has reached
141  * the detector in \f$\frac{mm}{ns}\f$. After converting \f$\frac{mm}{ns}\f$
142  * to atomic units one simply has to multiply the velocity with the mass in
143  * atomic units to get momentum in atomic units.
144  *
145  * @return the momentum along the time of flight axis in atomic units
146  * @param tof_ns the time of flight of the hit in ns
147  * @param mass_au the mass of the particle in atomic units
148  * @param charge_au the charge of the particle in atomic units
149  * @param sr the spectrometer region through which the particle flys.
150  *
151  * @author Lutz Foucar
152  */
153 double getZMom(double tof_ns, double mass_au, double charge_au, const SpectrometerRegion &sr)
154 {
155  double a (sr.EField_Vpcm() * charge_au/mass_au * UnitConvertion::VPcm2mmPns());
156  double v (sr.length_mm()/tof_ns - 0.5*a*tof_ns);
157  double v_au (v * UnitConvertion::mmPns2au());
158  double p_au (v_au * mass_au);
159  return p_au;
160 }
161 
162 /** helper function for endless SpectrometerRegions
163  *
164  * this helper will calculate the time of flight of a particle with a
165  * given mass and charge in a spectrometer
166  *
167  * @return the time of flight in ns
168  * @param v0 the initial velocity of the particle
169  * @param mass_au the mass of the particle in atomic units
170  * @param charge_au the charge of the particle in atomic units
171  * @param spec the spectrometer through which the particle is flying
172  *
173  * @author Lutz Foucar
174  */
175 double evalFunc(double v0, double mass_au, double charge_au, const Spectrometer &spec)
176 {
177  double tges=0;
178  double v = v0;
179  const Spectrometer::regions_t &sr (spec.regions());
180  for (size_t nReg=0; nReg<sr.size(); ++nReg)
181  {
182  //calculate the accereration from the E-field in the region, charge and mass of the particle//
183  double a = sr[nReg].EField_Vpcm() * charge_au/mass_au * UnitConvertion::VPcm2mmPns(); //the acceleration in Region 1 in mm/ns^2
184  double s = sr[nReg].length_mm(); //the length of this region in mm
185 
186  //calc how long one particle will fly with the given initial velocity//
187  double tt=0;
188  if (std::abs(a) > 1e-8) //if there is an accerlartion
189  tt = (-v + sqrt(v*v + 2.*a*s))/a;
190  else //if there is no accerlaration (eg drift)
191  tt = s/v;
192 
193  //during its time in this Region the particle gained velocity if it wasn't a drift (a=0)
194  //add this additional velocity to its initial velocity
195  v += a*tt;
196 
197  //add the time that the particle stayed in this region to the total time
198  tges += tt;
199  }
200 
201  //return the total time
202  return tges;
203 }
204 
205 /** Momentum along time of flight
206  *
207  * find momentum iterativly. There is no analytical solution for when there
208  * are more than two spectrometer regions through which the particle is
209  * flying.
210  *
211  * We have measured the time of flight of the particle, what we need to find
212  * out is to which initial momentum does this time of flight fit. Since we
213  * have a function that will calculate the time of flight for a given intial
214  * velocity, we can now use this function and vary the intial velocity so long
215  * until the measured time of flight is the same as the calculated time of
216  * flight for a chosen velocity.\n
217  * Our initail guess for the velocity is the velocity the particle would
218  * have, when there is only one spectrometer region. So first calculate the
219  * velocity for when only the first region of the spectrometer would exist.
220  * Then calculate the tof for this velocity and find the next step of the
221  * iteration using Newtons Approximation. This means that we calculate the
222  * slope of the function at the current position. The next iteration is where
223  * the linear function with the slope crosses the right fx0. Do this until
224  * the time of flight is close to the one we measured. Then calculate the
225  * momentum of particle whos velocity gave the right time of flight.
226  *
227  * @return the momentum along the time of flight axis in atomic units only
228  * the tof_ns parameter is non negative. When it is negative return
229  * a high number (1e15)
230  * @param tof_ns the time of flight of the hit in ns
231  * @param mass_au the mass of the particle in atomic units
232  * @param charge_au the charge of the particle in atomic units
233  * @param spectrometer the spectrometer through which the particle is flying
234  *
235  * @author Lutz Foucar
236  */
237 double getZMomIter(double tof_ns, double mass_au, double charge_au, const Spectrometer &spectrometer)
238 {
239  //when a negative time was given return because there will be no good
240  //solution
241  if (tof_ns < 0)
242  return 1e15;
243  const double eField_Vpcm (spectrometer.regions()[0].EField_Vpcm());
244  const double length_mm (spectrometer.regions()[0].length_mm());
245  //calculate the acceleration from the E-field in the region, charge and
246  //mass of the particle
247  double a (eField_Vpcm * charge_au/mass_au * UnitConvertion::VPcm2mmPns());
248  //begin with a v when there would be only one Region//
249  double x0 (length_mm/tof_ns - 0.5*a*tof_ns);
250  double fx0 (evalFunc(x0,mass_au,charge_au,spectrometer));
251  //use Newtons Approximation//
252  while(std::abs(fx0 - tof_ns) > 0.01)
253  {
254  //we need to find the slope of the function at point x0 therefore we need
255  //a second point which is close to x0
256  double x1 (1.1 * x0);
257  double fx1 (evalFunc(x1,mass_au,charge_au,spectrometer));
258  //calculate the slope//
259  double m ((fx0-fx1)/(x0-x1));
260  //the next starting point is the point where the slopeline crosses the
261  //wanted fx0 value, put damping factor of 0.7 in addition
262  x0 = x0 + 0.7*(tof_ns-fx0)/m;
263  fx0 = evalFunc(x0,mass_au,charge_au,spectrometer);
264  }
265  double v_au (x0 * UnitConvertion::mmPns2au());
266  double p_au (v_au * mass_au);
267  return p_au;
268 }
269 
270 
271 
272 
273 ////###########################Momentum along Tof analytical version########
274 ////________________________________________________________________________
275 //double MyMomentaCalculator::getZMomentum(double tof_ns, double acc_mm, double drift_mm,
276 // double charge_au, double mass_au,
277 // double Efeld1_Vpcm, double Efeld2_Vpcm)
278 //{
279 // /***********************************************************************
280 // This function derives the momentum along the time of flight axis for
281 // two regions. Those two regions can have 2 different accerlerations and
282 // two differnt lengths. It does it analyticly using a function that
283 // solves the qubic equation:
284 // (-0.5*a2+0.5*a1)*t1^3 + (a2*t-0.5*a1*t)*t1^2 + (s1+s2-0.5*a2*t^2)*t1 + (-s1*t) = 0
285 // ************************************************************************/
286 //
287 // //--convert all values to a.u.--//
288 // double s1 = acc_mm * mm_au;
289 // double s2 = drift_mm * mm_au;
290 // double t = tof_ns * ns_au;
291 // double q = charge_au;
292 // double mass = mass_au;
293 // double Efeld1_au = Efeld1_Vpcm * Vcm_au;
294 // double Efeld2_au = Efeld2_Vpcm * Vcm_au;
295 //
296 //
297 // double a1 = Efeld1_au * q/mass;
298 // double a2 = Efeld2_au * q/mass;
299 //
300 // double A = (a2*t - 0.5*a1*t) / (-0.5*a2 + 0.5*a1);
301 // double B = (s1 + s2 - 0.5*a2*t*t) / (-0.5*a2 + 0.5*a1);
302 // double C = (- s1*t) / (-0.5*a2 + 0.5*a1);
303 //
304 //
305 // double t1=0; //the variable that we want to solve the function for
306 // double dummy1=0, dummy2=0; //these are needed for the function to work
307 // int nbrL = solve_qubic(A,B,C,&t1,&dummy1,&dummy2); //solve qubic equation
308 //
309 // //--if something went wrong return 0--//
310 // if ((nbrL != 1) || dummy1 || dummy2 || (t1 < 0.))
311 // return 0.;
312 //
313 // //--calculate the momentum from the found t1 value--//
314 // double v0 = (s1/t1) - 0.5*a1*t1;
315 // double mom = v0 * mass;
316 //
317 //
318 // return mom;
319 //}
320 //
321 //#define SWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0) //needed for solve_cubic()
322 ////_________________________________________________________________________________
323 //int MyMomentaCalculator::solve_qubic(double a, double b, double c, double * x0, double * x1, double * x2)
324 //{
325 // /* Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough
326 // *
327 // * This program is free software; you can redistribute it and/or modify
328 // * it under the terms of the GNU General Public License as published by
329 // * the Free Software Foundation; either version 2 of the License, or (at
330 // * your option) any later version.
331 // *
332 // * This program is distributed in the hope that it will be useful, but
333 // * WITHOUT ANY WARRANTY; without even the implied warranty of
334 // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
335 // * General Public License for more details.
336 // *
337 // * You should have received a copy of the GNU General Public License
338 // * along with this program; if not, write to the Free Software
339 // * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
340 // */
341 //
342 // /* solve_cubic.c - finds the real roots of x^3 + a x^2 + b x + c = 0 */
343 //
344 //
345 // double q = (a * a - 3 * b);
346 // double r = (2 * a * a * a - 9 * a * b + 27 * c);
347 //
348 // double Q = q / 9;
349 // double R = r / 54;
350 //
351 // double Q3 = Q * Q * Q;
352 // double R2 = R * R;
353 //
354 // double CR2 = 729 * r * r;
355 // double CQ3 = 2916 * q * q * q;
356 //
357 // if (R == 0 && Q == 0)
358 // {
359 // *x0 = - a / 3 ;
360 // *x1 = - a / 3 ;
361 // *x2 = - a / 3 ;
362 // return 3 ;
363 // }
364 // else if (CR2 == CQ3)
365 // {
366 // /* this test is actually R2 == Q3, written in a form suitable
367 // for exact computation with integers */
368 //
369 // /* Due to finite precision some double roots may be missed, and
370 // considered to be a pair of complex roots z = x +/- epsilon i
371 // close to the real axis. */
372 //
373 // double sqrtQ = sqrt (Q);
374 //
375 // if (R > 0)
376 // {
377 // *x0 = -2 * sqrtQ - a / 3;
378 // *x1 = sqrtQ - a / 3;
379 // *x2 = sqrtQ - a / 3;
380 // }
381 // else
382 // {
383 // *x0 = - sqrtQ - a / 3;
384 // *x1 = - sqrtQ - a / 3;
385 // *x2 = 2 * sqrtQ - a / 3;
386 // }
387 // return 3 ;
388 // }
389 // else if (CR2 < CQ3) /* equivalent to R2 < Q3 */
390 // {
391 // double sqrtQ = sqrt (Q);
392 // double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
393 // double theta = acos (R / sqrtQ3);
394 // double norm = -2 * sqrtQ;
395 // *x0 = norm * cos (theta / 3) - a / 3;
396 // //--orig but need changes due to the missing of M_PI--//
397 //// *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3;
398 //// *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3;
399 // *x1 = norm * cos ((theta + 2.0 * PI) / 3) - a / 3;
400 // *x2 = norm * cos ((theta - 2.0 * PI) / 3) - a / 3;
401 //
402 // /* Sort *x0, *x1, *x2 into increasing order */
403 //
404 // if (*x0 > *x1)
405 // SWAP(*x0, *x1) ;
406 //
407 // if (*x1 > *x2)
408 // {
409 // SWAP(*x1, *x2) ;
410 //
411 // if (*x0 > *x1)
412 // SWAP(*x0, *x1) ;
413 // }
414 //
415 // return 3;
416 // }
417 // else
418 // {
419 // double sgnR = (R >= 0 ? 1 : -1);
420 // double A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0);
421 // double B = Q / A ;
422 // *x0 = A + B - a / 3;
423 // return 1;
424 // }
425 //}
426 ////########################################################################
427 }
428 }
429 
430 
431 
432 
433 
434 //______________________________________________________________________________
435 using namespace cass::ACQIRIS;
436 
438 {
439  using namespace std;
440  s.beginGroup("Corrections");
441  _t0 = s.value("T0",0).toDouble();
442  _pos0 = make_pair(s.value("CorrectX",0).toDouble(),
443  s.value("CorrectY",0).toDouble());
444  _scalefactors = make_pair(s.value("ScaleX",1).toDouble(),
445  s.value("ScaleY",1).toDouble());
446  _angle = s.value("Angle",0).toDouble();
447  _angle = _angle *Pi()/180.;
448  s.endGroup();
449 }
450 
452 {
454  particlehit[x_mm] = dethit[x];
455  particlehit[y_mm] = dethit[y];
456  particlehit[tof_ns] = dethit[t];
457  particlehit[xCor_mm] = particlehit[x_mm] - _pos0.first;
458  particlehit[yCor_mm] = particlehit[y_mm] - _pos0.second;
459  particlehit[xCorScal_mm] = particlehit[xCor_mm] - _scalefactors.first;
460  particlehit[yCorScal_mm] = particlehit[yCor_mm] - _scalefactors.second;
461  particlehit[xCorScalRot_mm] = (particlehit[xCorScal_mm] * cos(_angle) - particlehit[yCorScal_mm] * sin(_angle));
462  particlehit[yCorScalRot_mm] = (particlehit[xCorScal_mm] * sin(_angle) + particlehit[yCorScal_mm] * cos(_angle));
463  particlehit[tofCor_ns] = particlehit[tof_ns] - _t0;
464  return particlehit;
465 }
466 
467 std::tr1::shared_ptr<MomentumCalculator> MomentumCalculator::instance(const MomCalcType &type)
468 {
469  using namespace std::tr1;
470  using namespace std;
471  std::tr1::shared_ptr<MomentumCalculator> momcalc;
472  switch (type)
473  {
474  case PxPyWBField:
475  momcalc = std::tr1::shared_ptr<MomentumCalculator>(new PxPyCalculatorWithBField);
476  break;
477  case PxPyWOBField:
478  momcalc = std::tr1::shared_ptr<MomentumCalculator>(new PxPyCalculatorWithoutBField);
479  break;
480  case PzOneRegion:
481  momcalc = std::tr1::shared_ptr<MomentumCalculator>(new PzCalculatorDirectOneRegion);
482  break;
483  case PzMultipleRegions:
484  momcalc = std::tr1::shared_ptr<MomentumCalculator>(new PzCalculatorMulitpleRegions);
485  break;
486  default:
487  throw invalid_argument("MomentumCalculator::instance(): Momentum calculator type '" +
488  toString(type) + "' not available");
489  break;
490  }
491  return momcalc;
492 }
493 
495 {
496  particlehit[px] = getDetPlaneMomentum(particlehit[xCorScalRot_mm],particlehit[tofCor_ns],particle.mass_au());
497  particlehit[py] = getDetPlaneMomentum(particlehit[yCorScalRot_mm],particlehit[tofCor_ns],particle.mass_au());
498  return particlehit;
499 }
500 
502 {
503  double &px_au (particlehit[px]);
504  double &py_au (particlehit[py]);
505  getDetPlaneMomenta(particlehit[xCorScalRot_mm], particlehit[yCorScalRot_mm], particlehit[tofCor_ns], particle,
506  px_au, py_au);
507  return particlehit;
508 }
509 
511 {
512  particlehit[pz] = getZMom(particlehit[tofCor_ns], particle.mass_au(), particle.charge_au(), particle.spectrometer().regions()[0]);
513  return particlehit;
514 }
515 
517 {
518  particlehit[pz] = getZMomIter(particlehit[tofCor_ns], particle.mass_au(), particle.charge_au(), particle.spectrometer());
519  return particlehit;
520 }
std::vector< double > detectorHit_t
define a detector hit
void loadSettings(CASSSettings &s)
load the settings
double _t0
the correction factor of the time of flight
particleHit_t operator()(const detectorHit_t &dethit) const
correct the position in the detector plane
const regions_t & regions() const
retrieve the regions of the spectrometer
Definition: spectrometer.h:112
double VPcm2mmPns()
convert V/cm * C[a.u.
file contains the classes that calculate the momenta of particles from their detector hits...
double _angle
the angle to rotate the position
double mass_au() const
retrieve the particle properties
Definition: particle.h:122
Settings for CASS.
Definition: cass_settings.h:30
double getZMom(double tof_ns, double mass_au, double charge_au, const SpectrometerRegion &sr)
Momentum along time of flight.
double getZMomIter(double tof_ns, double mass_au, double charge_au, const Spectrometer &spectrometer)
Momentum along time of flight.
double kg2au()
SI Units -> Atomic Units.
STL namespace.
a region of a spectrometer
Definition: spectrometer.h:36
particleHit_t & operator()(const Particle &particle, particleHit_t &particlehit) const
calculate the momenta
double au2s()
Atomic Units -> SI Units.
double amu2kg()
Atomic mass unit -> SI Unit.
double getDetPlaneMomentum(double axis_mm, double tof_ns, double mass_au)
calculate the momentum in the detector plane
particleHit_t & operator()(const Particle &particle, particleHit_t &particlehit) const
calculate the momenta
std::pair< double, double > _pos0
the correction of the position
double length_mm() const
retrieve region properties
Definition: spectrometer.h:48
double au2m()
Atomic Units -> SI Units.
double evalFunc(double v0, double mass_au, double charge_au, const Spectrometer &spec)
helper function for endless SpectrometerRegions
std::vector< double > particleHit_t
define a particle hit
bool rotationClockWise() const
retrieve magnetic field parameter
Definition: spectrometer.h:108
const Spectrometer & spectrometer() const
retrive the spectormeter
Definition: particle.h:118
void getDetPlaneMomenta(double x_mm, double y_mm, double tof_ns, const Particle &particle, double &px_au, double &py_au)
calculate Momentum in Detektor Plane
particleHit_t & operator()(const Particle &particle, particleHit_t &particlehit) const
calculate the momenta
static std::tr1::shared_ptr< MomentumCalculator > instance(const MomCalcType &type)
create instance of requested type
std::vector< SpectrometerRegion > regions_t
typef for better readable code
Definition: spectrometer.h:89
particleHit_t & operator()(const Particle &particle, particleHit_t &particlehit) const
calculate the momenta
double charge_au() const
retrieve the particle properties
Definition: particle.h:123
double amu2au()
Atomic mass unit -> Atomic Units.
double au2mm()
Atomic Units -> SI Units.
double au2amu()
Atomic Units ->Atomic mass unit.
MomCalcType
enum for the types of momcalculators
std::string toString(const Type &t)
convert any type to a string
Definition: cass.h:63
double au2kg()
Atomic Units -> SI Units.
double au2ns()
Atomic Units -> SI Units.
value(const QString &key, const QVariant &defaultValue=QVariant()
double EField_Vpcm() const
retrieve region properties
Definition: spectrometer.h:47
double cyclotronPeriod_ns() const
retrieve magnetic field parameter
Definition: spectrometer.h:106
file contains specialized class that do the settings for cass
a REMI type spectrometer
Definition: spectrometer.h:85
file contains the classes that describe a particle that hit a delayline detector. ...
double au2mmPns()
Atomic Units -> SI Units.
double mmPns2au()
SI Units -> Atomic Units.
A Particle.
Definition: particle.h:70
contains the classes that describe a REMI type spectrometer.
double mm2au()
SI Units -> Atomic Units.
std::pair< double, double > _scalefactors
the correction of the scale
double ns2au()
SI Units -> Atomic Units.
double au2mPs()
Atomic Units -> SI Units.
beginGroup(const QString &prefix)