ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtKinematics.cxx
Go to the documentation of this file.
1 #include "AtKinematics.h"
2 
3 #include <Rtypes.h> // for TGenericClassInfo
4 #include <TError.h> // for Error
5 #include <TMath.h> // for Power, Sqrt
6 #include <TMatrixTUtils.h> // for TMatrixTRow
7 
8 #include <algorithm> // for max
9 #include <cassert> // for assert
10 #include <cmath> // for pow, sqrt, cos
11 #include <cstdlib> // for exit
12 #include <iostream> // for operator<<, basic_ostream, basic_ostream<>::__os...
13 #include <utility> // for mov
15 
17 {
18 
19  std::cout << " AtTools::AtKinematics: Initializing Kinematical Fit matrices "
20  << "\n";
21 
22  auto alpha0 = std::make_unique<TMatrixD>(4 * fNumParticles, 1);
23  fAlphaP.push_back(std::move(alpha0));
24 
25  for (auto i = 0; i < fNumParticles; ++i) {
26  auto alpha = std::make_unique<TMatrixD>(4, 1);
27  fAlphaP.push_back(std::move(alpha));
28  }
29 }
30 
31 std::tuple<Double_t, Double_t> AtTools::AtKinematics::GetMomFromBrho(Double_t M, Double_t Z, Double_t brho)
32 {
33 
34  const Double_t M_Ener = M * 931.49401 / 1000.0;
35  Double_t p = brho * Z * (2.99792458 / 10.0); // In GeV
36  Double_t E = TMath::Sqrt(TMath::Power(p, 2) + TMath::Power(M_Ener, 2)) - M_Ener;
37  if (fVerbosity == 1)
38  std::cout << " Brho : " << brho << " - p : " << p << " - E : " << E << "\n";
39  return std::make_tuple(p, E);
40 }
41 
42 Double_t AtTools::AtKinematics::TwoBodyEx(Double_t m1, Double_t m2, Double_t m3, Double_t m4, Double_t K_proj,
43  Double_t thetalab, Double_t K_eject)
44 {
45  // in this definition: m1(projectile); m2(target); m3(ejectile); and m4(recoil);
46  double Et1 = K_proj + m1;
47  double Et2 = m2;
48  double Et3 = K_eject + m3;
49  // double Et4 = Et1 + Et2 - Et3;
50  double m4_ex, Ex, theta_cm;
51  double s, t, u; //---Mandelstam variables
52 
53  s = pow(m1, 2) + pow(m2, 2) + 2 * m2 * Et1;
54  u = pow(m2, 2) + pow(m3, 2) - 2 * m2 * Et3;
55 
56  m4_ex = sqrt((cos(thetalab) * omega(s, pow(m1, 2), pow(m2, 2)) * omega(u, pow(m2, 2), pow(m3, 2)) -
57  (s - pow(m1, 2) - pow(m2, 2)) * (pow(m2, 2) + pow(m3, 2) - u)) /
58  (2 * pow(m2, 2)) +
59  s + u - pow(m2, 2));
60  Ex = m4_ex - m4;
61 
62  // t = pow(m2, 2) + pow(m4_ex, 2) - 2 * m2 * Et4;
63 
64  // for inverse kinematics Note: this angle corresponds to the recoil
65  /*theta_cm = TMath::Pi() - acos((pow(s, 2) + s * (2 * t - pow(m1, 2) - pow(m2, 2) - pow(m3, 2) - pow(m4_ex, 2)) +
66  (pow(m1, 2) - pow(m2, 2)) * (pow(m3, 2) - pow(m4_ex, 2))) /
67  (omega(s, pow(m1, 2), pow(m2, 2)) * omega(s, pow(m3, 2), pow(m4_ex, 2))));
68 
69 
70  THcm = theta_cm*TMath::RadToDeg();
71  */
72  return Ex;
73 }
74 
75 Double_t AtTools::AtKinematics::omega(Double_t x, Double_t y, Double_t z)
76 {
77  return sqrt(x * x + y * y + z * z - 2 * x * y - 2 * y * z - 2 * x * z);
78 }
79 
80 std::vector<double> AtTools::AtKinematics::KinematicalFit(std::vector<double> &parameters)
81 {
82  // Kinematic Fitting based on https://www.phys.ufl.edu/~avery/fitting.html
83  // Input vector is composed by 4 four-momentum vectors of (projectile,ejectile,proton1,proton2)
84  // Output vector contains the fitted coordinates in the same order
85 
86  std::vector<Double_t> parOut;
87 
88  Int_t rowDim = fAlphaP[0]->GetNrows();
89  std::cout << " Row dimension " << rowDim << "\n";
90  if (rowDim != fNumParticles * 4 || rowDim != parameters.size()) {
91  std::cerr << " Wrong matrix/parameter dimension. Aborting... "
92  << "\n";
93  std::exit(0);
94  }
95 
96  ResetMatrices();
97 
98  for (auto i = 0; i < fNumParticles; ++i) {
99  for (auto j = 0; j < 4; ++j) {
100  (*fAlphaP.at(i + 1))[j][0] = parameters[i * 4 + j];
101  }
102  (*fAlphaP.at(0)).SetSub(i * 4, 0, (*fAlphaP.at(i + 1)));
103  }
104 
105  TMatrixD *alpha;
106  TMatrixD dalpha(4 * fNumParticles, 1); // delta alpha
107  dalpha.Zero();
108  alpha = fAlphaP.at(0).get();
109 
110  // alpha->Print();
111 
112  TMatrixD chi2(1, 1);
113  chi2.Zero();
114 
115  TMatrixD Cov = CalculateCovariance();
116 
117  double weighting = 0.05;
118 
119  for (auto i = 0; i < fNumIterations; i++) {
120 
121  TMatrixD D = CalculateD(alpha);
122  TMatrixD Dt = D;
123  Dt.T();
124  TMatrixD Vd = D * Cov * Dt;
125  Vd.Invert();
126  Cov = Cov - Cov * Dt * Vd * D * Cov * weighting;
127 
128  // calculate labmda
129  TMatrixD d = Calculated(alpha);
130  TMatrixD temp1 = (d + D * dalpha);
131  TMatrixD lambda = Vd * temp1;
132 
133  // calculate chi2
134  TMatrixD lambdaT = lambda;
135  chi2 = lambdaT.T() * temp1;
136 
137  // calculate alpha
138  *alpha = *fAlphaP.at(0).get() - weighting * Cov * Dt * lambda;
139  dalpha = *alpha - *fAlphaP.at(0).get();
140  *fAlphaP.at(0).get() = *alpha;
141 
142  // std::cout<<" chi2 "<<chi2[0][0]<<"\n";
143 
144  if (fabs(chi2[0][0]) < 1.0)
145  break;
146  }
147 
148  for (auto i = 0; i < 4 * fNumParticles; ++i)
149  parOut.push_back((*alpha)[i][0]);
150 
151  return parOut;
152 }
153 
154 TMatrixD AtTools::AtKinematics::Calculated(TMatrixD *alpha)
155 {
156  TMatrixD dval(4, 1);
157  dval.Zero();
158  double mt = fTargetMass * 931.494; // target mass
159 
160  double mout1 = 0.0;
161  double mout2 = 0.0;
162  double mout3 = 0.0;
163  double mout4 = 0.0;
164 
165  // Exit channel momentum
166  for (auto i = 1; i < fNumParticles; ++i) {
167  mout1 += (*alpha)[4 * i][0];
168  mout2 += (*alpha)[4 * i + 1][0];
169  mout3 += (*alpha)[4 * i + 2][0];
170  mout4 += (*alpha)[4 * i + 3][0];
171  // std::cout<<mout1<<"\n";
172  }
173 
174  double h1 = (*alpha)[0][0] - mout1; // momentum conservation X
175  double h2 = (*alpha)[1][0] - mout2; // momentum conservation Y
176  double h3 = (*alpha)[2][0] - mout3; // momentum conservation Z
177  double h4 = (*alpha)[3][0] + mt - mout4; // Total Energy conservation
178 
179  dval[0][0] = h1;
180  dval[1][0] = h2;
181  dval[2][0] = h3;
182  dval[3][0] = h4;
183 
184  // dval.Print();
185 
186  return dval;
187 }
188 
189 TMatrixD AtTools::AtKinematics::CalculateD(TMatrixD *alpha)
190 {
191 
192  TMatrixD Dval(4, 4 * fNumParticles);
193  Dval.Zero();
194 
195  for (auto i = 0; i < fNumParticles; ++i) {
196  TMatrixD Dsub(4, 4);
197  Dsub.Zero();
198 
199  Dsub[0][0] = 1;
200  for (int j = 1; j < 4; j++)
201  Dsub[j][j] = -1;
202 
203  Dval.SetSub(0, i * 4, Dsub);
204  }
205 
206  // Dval.Print();
207 
208  return Dval;
209 }
210 
211 TMatrixD AtTools::AtKinematics::CalculateCovariance()
212 {
213  TMatrixD Vval(4 * fNumParticles, 4 * fNumParticles);
214  Vval.Zero();
215 
216  for (auto i = 0; i < fNumParticles; ++i) {
217  TMatrixD Vsub(4, 4);
218  Vsub.Zero();
219 
220  for (int j = 0; j < 4; j++)
221  Vsub[j][j] = 0.1;
222 
223  Vval.SetSub(i * 4, i * 4, Vsub);
224  }
225 
226  // Vval.Print();
227 
228  return Vval;
229 }
230 
231 void AtTools::AtKinematics::ResetMatrices()
232 {
233  for (auto &alpha : fAlphaP)
234  alpha->Zero();
235 }
236 
237 void AtTools::AtKinematics::PrintMatrices()
238 {
239  for (auto &alpha : fAlphaP)
240  alpha->Print();
241 }
242 
244 
249 double GetGamma(double KE, double m1, double m2)
250 {
251  double num = KE * KE + 2 * (m1 + m2) * (KE + m1);
252  double denom = 2 * m1 * (KE + m1 + m2);
253  return num / denom;
254 }
255 
259 double GetVelocity(double gamma)
260 {
261  return GetBeta(gamma) * TMath::C() * 1e-7;
262 }
263 
267 double GetBeta(double gamma)
268 {
269  return std::sqrt(gamma * gamma - 1) / gamma;
270 }
274 double GetBeta(double p, double m)
275 {
276  return p / std::sqrt(p * p + m * m);
277 }
278 double GetBeta(double p, int A)
279 {
280  return GetBeta(p, AtoE(A));
281 }
282 
283 double GetGamma(double beta)
284 {
285  assert(beta >= 0 && beta <= 1);
286  return 1 / std::sqrt(1 - beta * beta);
287 }
288 
292 double GetRelMom(double gamma, double mass)
293 {
294  return std::sqrt(gamma * gamma - 1) * mass;
295 }
296 
300 double AtoE(double Amu)
301 {
302  return Amu * 931.5;
303 }
304 double EtoA(double mass)
305 {
306  return mass / 931.5;
307 }
308 
309 } // namespace AtTools::Kinematics
AtTools::Kinematics::EtoA
double EtoA(double mass)
Definition: AtKinematics.cxx:304
AtTools::Kinematics::AtoE
double AtoE(double Amu)
Definition: AtKinematics.cxx:300
AtTools::Kinematics
Definition: AtKinematics.cxx:243
AtTools::AtKinematics
Definition: AtKinematics.h:27
AtTools::AtKinematics::AtKinematics
AtKinematics()
Definition: AtKinematics.cxx:16
AtTools::Kinematics::GetGamma
double GetGamma(double KE, double m1, double m2)
Definition: AtKinematics.cxx:249
ClassImp
ClassImp(AtTools::AtKinematics)
AtTools::Kinematics::GetRelMom
double GetRelMom(double gamma, double mass)
Definition: AtKinematics.cxx:292
AtKinematics.h
AtTools::AtKinematics::KinematicalFit
std::vector< double > KinematicalFit(std::vector< double > &parameters)
Definition: AtKinematics.cxx:80
AtTools::AtKinematics::omega
Double_t omega(Double_t x, Double_t y, Double_t z)
Definition: AtKinematics.cxx:75
y
const double * y
Definition: lmcurve.cxx:20
AtTools::AtKinematics::GetMomFromBrho
std::tuple< Double_t, Double_t > GetMomFromBrho(Double_t A, Double_t Z, Double_t brho)
Returns momentum (in GeV) from Brho assuming M (amu) and Z;.
Definition: AtKinematics.cxx:31
AtTools::Kinematics::GetBeta
double GetBeta(double gamma)
Definition: AtKinematics.cxx:267
AtTools::Kinematics::GetVelocity
double GetVelocity(double gamma)
Definition: AtKinematics.cxx:259
AtTools::AtKinematics::TwoBodyEx
Double_t TwoBodyEx(Double_t m1, Double_t m2, Double_t m3, Double_t m4, Double_t K_proj, Double_t thetalab, Double_t K_eject)
Definition: AtKinematics.cxx:42