/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*
*/
#ifndef ROOTFITTER_HH
#define ROOTFITTER_HH
// C++ headers
#include
#include
// ROOT headers
#include "TMatrixD.h"
// MAUS headers
#include "src/common_cpp/Recon/SciFi/SimpleLine.hh"
#include "src/common_cpp/Recon/SciFi/SimpleCircle.hh"
#include "src/common_cpp/Recon/SciFi/SimpleHelix.hh"
/** @namespace RootFitter
*
* ROOT fitting routines written for the scifi pattern recognition.
*/
namespace RootFitter {
struct MinuitSZParameters {
int handedness {0}; //NOLINT(*)
int maxFunctionCalls {1000000}; //NOLINT(*)
int maxIterations {100000}; //NOLINT(*)
int searchNStepsNormal {100}; //NOLINT(*)
int searchNStepsLowRadius {200}; //NOLINT(*)
double lowRadius {10.0}; //NOLINT(*)
double maxSZChisq {50.0}; //NOLINT(*)
double patRecSZCut {65.0}; //NOLINT(*)
double stepSize {0.01}; //NOLINT(*)
double tolerance {0.001}; //NOLINT(*)
double dsdzLowerLimit {-0.35}; //NOLINT(*)
double dsdzUpperLimit {0.35}; //NOLINT(*)
};
/** @brief Fit a straight line using the ROOT TLinearFit class
* @param[in] x x coordinates (the indepepndent variable)
* @param[in] y y coordinates (the depepndent variable)
* @param[in] yerr Errors on the y coordinates
* @param[out] line The fit result including errors
* @param[out] cov_matrix The 2*2 covariance matrix of the returned parameters
*/
bool FitLineLinear(const std::vector& x, const std::vector& y,
const std::vector& yerr, MAUS::SimpleLine& line, TMatrixD& cov_matrix);
/** @brief Fit a circle using the ROOT MINUIT minimiser class
* @param[in] x x coordinates (a dependent variable)
* @param[in] y y coordinates (a depepndent variable)
* @param[out] circ The fit result
* @param[out] cov_matrix The 3*3 covariance matrix of the returned parameters
*/
bool FitCircleMinuit(const std::vector& x, const std::vector& y,
const std::vector& err,
MAUS::SimpleCircle& circ, TMatrixD& cov_matrix);
/** @brief Fit a helix using the ROOT MINUIT minimiser class.
*
* Fit a helix using the ROOT MINUIT minimiser class.
* pStart holds xc (circle centre in x), yc (circle centre in y), the radius and dsdz, which
* seed MINUIT. xc, yc and radius are fixed, that is MINUIT will not improve them, just use them
* to help fit dsdz. The dsdz seed is not currently used by the algorithm, as a scan of the dsdz
* chisq function is performed to find the approximate global minima which then seeds MINUIT. If
* the track handedness (rotation direction) is supplied, this will be used by the scan function
* to exclude unphysical minima (those where dsdz has the wrong sign).
*
* The MINUIT algorithm used for the minimisation in MIGRAD.
*
* @param[in] x x coordinates (a dependent variable)
* @param[in] y y coordinates (a depepndent variable)
* @param[in] z z coordinates (the independent variable)
* @param[in] pStart double array of xc, yc, R, dsdz which seeds the parameters for MINUIT
* @param[out] helix The fit result
* @param[in] handedness Track rotation direction, if set to 1 or -1 used to help dsdz scan func
* @param[in] cut The pattern recongition longitundal chisq cut, used by the dsdz scan function
*/
bool FitHelixMinuit(const std::vector& x, const std::vector& y,
const std::vector& z, const std::vector& err,
const double* pStart, const MinuitSZParameters& cfg,
MAUS::SimpleHelix& helix);
/** Scan the chisq function to find the rough location of the global minimum to seed MINUIT
* (otherwise it gets stuck in local minima).
* It will take minimum chisq value, unless we have an expected handedness (i.e. dsdz sign)
* supplied in which case we will use that to exclude wrong sign candidates.
*
* @param[in] pStart 4D double array holding xc, yx, radius, dsdz_initial_seed
* @param[in] handedness Particle rotation direction
* @param[in] cut The chisq per dof cut from pattern recognition
* @param[in] Chi2Function std::function used to calculate the chisq
* @return The optimised dsdz_seed (hopefully for the rough global minimum of the chisq func)
*/
double LocateGlobalChiSqMinimum(const double* pStart, const MinuitSZParameters& cfg,
std::function Chi2Function); //NOLINT(*)
}
#endif