15 #include "TMinuitMinimizer.h" 23 verbosity_(verbosity),
25 useImprovedInitialEstimate_(improved_estimate),
30 TMinuitMinimizer::UseStaticMinuit(
false);
33 double pStart[] = { 0, 0, 0, 0 };
45 for (
const auto &
p : opticalFunctions)
58 rpod.
s_xi_vs_x_d = make_shared<TSpline3>(
"", xDValues.data(), xiValues.data(), xiValues.size());
85 double s_1=0., s_x=0., s_xx=0., s_y=0., s_xy=0.;
86 for (
unsigned int i = 0;
i < vx.size(); ++
i)
90 s_xx += vx[
i] * vx[
i];
92 s_xy += vx[
i] * vy[
i];
95 const double d = s_xx * s_1 - s_x * s_x;
96 a = ( s_1 * s_xy - s_x * s_y) / d;
97 b = (-s_x * s_xy + s_xx * s_y) / d;
123 auto oit = m_rp_optics->find(
rpId);
125 oit->second.optics->transport(k_in, k_out);
128 const double x = k_out.
x - oit->second.x0;
129 const double y = k_out.
y - oit->second.y0;
132 const double x_diff_norm = (x -
track->getX()*1E-1) / (
track->getXUnc()*1E-1);
133 const double y_diff_norm = (y -
track->getY()*1E-1) / (
track->getYUnc()*1E-1);
136 s2 += x_diff_norm*x_diff_norm + y_diff_norm*y_diff_norm;
145 const LHCInfo& lhcInfo, std::ostream& os)
const 148 for (
const auto &it : tracks) {
151 throw cms::Exception(
"ProtonReconstructionAlgorithm") <<
"Optics data not available for RP " <<
152 it->getRPId() <<
", i.e. " <<
CTPPSDetId(it->getRPId()) <<
".";
156 double xi_init = 0., th_x_init = 0.;
159 double x_N = tracks[0]->getX()*1E-1,
160 x_F = tracks[1]->getX()*1E-1;
165 const double a = i_F.ch1*i_N.
la1 - i_N.
ch1*i_F.la1;
166 const double b = i_F.ch0*i_N.
la1 - i_N.
ch0*i_F.la1 + i_F.ch1*i_N.
la0 - i_N.
ch1*i_F.la0 + x_N*i_F.la1 - x_F*i_N.
la1;
167 const double c = x_N*i_F.la0 - x_F*i_N.
la0 + i_F.ch0*i_N.
la0 - i_N.
ch0*i_F.la0;
168 const double D = b*b - 4.*a*
c;
169 const double sqrt_D = (D >= 0.) ?
sqrt(D) : 0.;
171 xi_init = (-b + sqrt_D) / 2. / a;
172 th_x_init = (x_N - i_N.
ch0 - i_N.
ch1 * xi_init) / (i_N.
la0 + i_N.
la1 * xi_init);
175 double s_xi0 = 0., s_1 = 0.;
176 for (
const auto &
track : tracks) {
178 double xi = oit->second.s_xi_vs_x_d->Eval(
track->getX()*1E-1 + oit->second.x0);
184 xi_init = s_xi0 / s_1;
187 if (!std::isfinite(xi_init))
189 if (!std::isfinite(th_x_init))
193 double y[2]={0}, v_y[2]={0}, L_y[2]={0};
194 unsigned int y_idx = 0;
195 for (
const auto &
track : tracks) {
196 if (y_idx >= 2)
break;
200 y[y_idx] =
track->getY()*1E-1 - oit->second.s_y_d_vs_xi->Eval(xi_init);
201 v_y[y_idx] = oit->second.s_v_y_vs_xi->Eval(xi_init);
202 L_y[y_idx] = oit->second.s_L_y_vs_xi->Eval(xi_init);
207 double vtx_y_init = 0.;
208 double th_y_init = 0.;
211 const double det_y = v_y[0] * L_y[1] - L_y[0] * v_y[1];
212 vtx_y_init = (det_y != 0.) ? (L_y[1] * y[0] - L_y[0] * y[1]) / det_y : 0.;
213 th_y_init = (det_y != 0.) ? (v_y[0] * y[1] - v_y[1] * y[0]) / det_y : 0.;
217 th_y_init = (y[1]/L_y[1] + y[0]/L_y[0]) / 2.;
220 if (!std::isfinite(vtx_y_init))
222 if (!std::isfinite(th_y_init))
225 unsigned int armId =
CTPPSDetId((*tracks.begin())->getRPId()).
arm();
229 <<
"ProtonReconstructionAlgorithm::reconstructFromMultiRP(" << armId <<
")" << std::endl
230 <<
" initial estimate: xi_init = " << xi_init <<
", th_x_init = " << th_x_init
231 <<
", th_y_init = " << th_y_init <<
", vtx_y_init = " << vtx_y_init <<
"." << std::endl;
234 fitter_->Config().ParSettings(0).Set(
"xi", xi_init, 0.005);
235 fitter_->Config().ParSettings(1).Set(
"th_x", th_x_init, 2E-6);
236 fitter_->Config().ParSettings(2).Set(
"th_y", th_y_init, 2E-6);
237 fitter_->Config().ParSettings(3).Set(
"vtx_y", vtx_y_init, 10E-6);
240 fitter_->Config().ParSettings(3).Fix();
250 const double *params = result.GetParams();
254 <<
" fit valid=" << result.IsValid()
256 <<
" xi=" << params[0] <<
" +- " << result.Error(0)
257 <<
", th_x=" << params[1] <<
" +-" << result.Error(1)
258 <<
", th_y=" << params[2] <<
" +-" << result.Error(2)
259 <<
", vtx_y=" << params[3] <<
" +-" << result.Error(3)
260 <<
", chiSq = " << result.Chi2() << std::endl;
265 const double sign_z = (armId == 0) ? +1. : -1.;
266 const FP::Point vertex(0., params[3], 0.);
267 const double xi = params[0];
268 const double th_x = params[1];
269 const double th_y = params[2];
270 const double cos_th =
sqrt(1. - th_x*th_x - th_y*th_y);
271 const double p = lhcInfo.
energy() * (1. -
xi);
277 signed int ndf = 2.*tracks.size() - ((
fitVtxY_) ? 4. : 3.);
279 map<unsigned int, signed int> index_map = {
281 {(
unsigned int) FP::Index::th_x, 1},
282 {(
unsigned int) FP::Index::th_y, 2},
283 {(
unsigned int) FP::Index::vtx_y, ((
fitVtxY_) ? 3 : -1)},
284 {(
unsigned int) FP::Index::vtx_x, -1},
288 for (
unsigned int i = 0;
i < (
unsigned int) FP::Index::num_indices; ++
i) {
289 signed int fit_i = index_map[
i];
291 for (
unsigned int j = 0; j < (
unsigned int) FP::Index::num_indices; ++j) {
292 signed int fit_j = index_map[j];
294 cm(
i, j) = (fit_i >= 0 && fit_j >= 0) ? result.CovMatrix(fit_i, fit_j) : 0.;
299 FP::ReconstructionMethod::multiRP,
tracks, result.IsValid());
305 const LHCInfo& lhcInfo, std::ostream& os)
const 310 os <<
"reconstructFromSingleRP(" <<
rpId.arm()*100 +
rpId.station()*10 +
rpId.rp() <<
")" << std::endl;
315 throw cms::Exception(
"ProtonReconstructionAlgorithm") <<
"Optics data not available for RP " << track->getRPId()
316 <<
", i.e. " <<
rpId <<
".";
319 const double x_full = track->getX()*1E-1 + oit->second.x0;
320 const double xi = oit->second.s_xi_vs_x_d->Eval(x_full);
321 const double L_y = oit->second.s_L_y_vs_xi->Eval(xi);
322 const double th_y = track->getY()*1E-1 / L_y;
324 const double ep_x = 1E-6;
325 const double dxi_dx = (oit->second.s_xi_vs_x_d->Eval(x_full + ep_x) -
xi) / ep_x;
326 const double xi_unc =
abs(dxi_dx) * track->getXUnc() * 1E-1;
328 const double ep_xi = 1E-4;
329 const double dL_y_dxi = ( oit->second.s_L_y_vs_xi->Eval(xi + ep_xi) - L_y ) / ep_xi;
330 const double th_y_unc = th_y *
sqrt(
pow(track->getYUnc() / track->getY(), 2.) +
pow(dL_y_dxi * xi_unc / L_y, 2.) );
333 os <<
" xi = " << xi <<
" +- " << xi_unc <<
", th_y = " << th_y <<
" +- " << th_y_unc <<
"." << std::endl;
338 const double sign_z = (
CTPPSDetId(track->getRPId()).
arm() == 0) ? +1. : -1.;
340 const double cos_th =
sqrt(1. - th_y*th_y);
341 const double p = lhcInfo.
energy() * (1. -
xi);
342 const FP::Vector momentum(0., p * th_y, sign_z * p * cos_th);
345 cm((
int)
FP::Index::xi, (
int)FP::Index::xi) = xi_unc * xi_unc;
346 cm((
int)FP::Index::th_y, (
int)FP::Index::th_y) = th_y_unc * th_y_unc;
351 return reco::ForwardProton(0., 0, vertex, momentum, xi, cm, FP::ReconstructionMethod::singleRP, trk,
true);
std::unique_ptr< ROOT::Fit::Fitter > fitter_
fitter object
std::shared_ptr< const TSpline3 > s_xi_vs_x_d
optics data associated with 1 RP
class for calculation of chi^2
ROOT::Math::Plane3D::Vector Vector
reco::ForwardProton reconstructFromSingleRP(const CTPPSLocalTrackLiteRef &track, const LHCInfo &lhcInfo, std::ostream &os) const
run proton reconstruction using single-RP strategy
math::Error< 5 >::type CovarianceMatrix
const std::vector< double > & getXiValues() const
std::map< unsigned int, RPOpticsData > m_rp_optics_
map: RP id –> optics data
double y0
beam vertical position, cm
void init(const LHCInterpolatedOpticalFunctionsSetCollection &opticalFunctions)
const std::vector< std::shared_ptr< const TSpline3 > > & splines() const
std::unique_ptr< ChiSquareCalculator > chiSquareCalculator_
object to calculate chi^2
bool useImprovedInitialEstimate_
double ch0
intercept for linear approximation of
double x0
beam horizontal position, cm
double la1
slope for linear approximation of
reco::ForwardProton reconstructFromMultiRP(const CTPPSLocalTrackLiteRefVector &tracks, const LHCInfo &lhcInfo, std::ostream &os) const
run proton reconstruction using multiple-RP strategy
double operator()(const double *parameters) const
static void doLinearFit(const std::vector< double > &vx, const std::vector< double > &vy, double &b, double &a)
Abs< T >::type abs(const T &t)
proton kinematics description
double la0
intercept for linear approximation of
void transport(const Kinematics &input, Kinematics &output, bool calculateAngles=false) const
transports proton according to the splines
std::shared_ptr< const TSpline3 > s_v_y_vs_xi
DecomposeProduct< arg, typename Div::arg > D
Set of optical functions corresponding to one scoring plane along LHC, including splines for interpol...
ProtonReconstructionAlgorithm(bool fit_vtx_y, bool improved_estimate, unsigned int verbosity)
Base class for CTPPS detector IDs.
std::shared_ptr< const TSpline3 > s_L_y_vs_xi
float const energy() const
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
const LHCInterpolatedOpticalFunctionsSet * optics
double ch1
slope for linear approximation of
std::shared_ptr< const TSpline3 > s_y_d_vs_xi
Power< A, B >::type pow(const A &a, const B &b)
const std::vector< std::vector< double > > & getFcnValues() const