30 #include "Math/Factory.h" 
   34 namespace RestFrames {
 
   37                          const std::string& stitle,
 
   40     m_Npair(N_vis_inv_pair)
 
   42     m_minimizer = ROOT::Math::Factory::CreateMinimizer(
"Minuit2", 
"Combined");
 
   43     m_minimizer->SetMaxFunctionCalls(10000000);
 
   44     m_minimizer->SetMaxIterations(100000);
 
   45     m_minimizer->SetTolerance(0.001);
 
   46     m_minimizer->SetPrintLevel(0);
 
   48     m_functor = 
new ROOT::Math::Functor(
this, &MinMassDiffInvJigsaw::EvaluateMetric, 3);
 
   49     m_minimizer->SetFunction(*m_functor);
 
   51     m_minimizer->SetVariable(0, 
"phi1", 0., 0.001);
 
   52     m_minimizer->SetVariable(1, 
"phi2", 0., 0.001);
 
   53     m_minimizer->SetVariable(2, 
"phi3", 0., 0.001);
 
   56   MinMassDiffInvJigsaw::~MinMassDiffInvJigsaw(){
 
   70     TLorentzVector PvisTOT(0.,0.,0.,0.);
 
   72     for(
int i = 0; i < m_Npair; i++){
 
   73       m_Pvis.push_back(GetDependancyStates(i+m_Npair).GetFourVector());
 
   79     TVector3 Boost = PvisTOT.BoostVector();
 
   80     for(
int i = 0; i < m_Npair; i++){
 
   81       m_Pvis[i].Boost(-Boost);
 
   83       ECM += sqrt(m_Pvis[i].P()*m_Pvis[i].P() + Minv*Minv);
 
   91       return SetSpirit(
false);
 
   97     double Minv = INV.M();
 
   99     TLorentzVector VIS(0.,0.,0.,0.);
 
  101     for(
int i = 0; i < m_Npair; i++){
 
  102       m_Pvis.push_back(GetDependancyStates(i).GetFourVector());
 
  107     TVector3 BoostCM = (VIS+INV).BoostVector();
 
  110     for(
int i = 0; i < m_Npair; i++)
 
  111       m_Pvis[i].Boost(-BoostCM);
 
  114     TVector3 BoostVIS = VIS.BoostVector();
 
  117     for(
int i = 0; i < m_Npair; i++){
 
  119       m_Pinv.push_back(m_Pvis[i]);
 
  120       m_Pinv[i].Boost(-BoostVIS);
 
  121       m_Pinv[i].SetVectM(m_Pinv[i].Vect(), m_Minv[i]);
 
  125     TVector3 BoostINV = INV.BoostVector();
 
  126     for(
int i = 0; i < m_Npair; i++)
 
  127       m_Pvis[i].Boost(-BoostINV);
 
  130       TVector3 Vdiff = (m_Pvis[0].Vect()-m_Pvis[1].Vect()).Unit();
 
  131       double pinv = GetP(Minv, m_Minv[0], m_Minv[1]);
 
  132       m_Pinv[0].SetVectM( pinv*Vdiff, m_Minv[0]);
 
  133       m_Pinv[1].SetVectM(-pinv*Vdiff, m_Minv[1]);
 
  135       double k = GetPScale(Minv);
 
  136       for(
int i = 0; i < m_Npair; i++)
 
  137     m_Pinv[i].SetVectM(k*m_Pinv[i].Vect(), m_Minv[i]);
 
  140     ApplyOptimalRotation();
 
  143     for(
int i = 0; i < m_Npair; i++){
 
  144       m_Pinv[i].Boost(BoostINV);
 
  145       m_Pinv[i].Boost(BoostCM);
 
  149     return SetSpirit(
true);
 
  153   double MinMassDiffInvJigsaw::GetPScale(
double Minv){
 
  154     std::vector<double> Pinv2;
 
  158     for(
int i = 0; i < m_Npair; i++){
 
  159       Pinv2.push_back(m_Pinv[i].P()*m_Pinv[i].P());
 
  160       Ek += sqrt(m_Minv[i]*m_Minv[i]+Pinv2[i]);
 
  163     if(fk > Minv || Ek <= 0.) 
return 0.;
 
  169     while(fabs(dk2) >= 1e-10 && count < 100){
 
  172       for(
int i = 0; i < m_Npair; i++){
 
  173     Ek = sqrt(m_Minv[i]*m_Minv[i]+k2*Pinv2[i]);
 
  175     dfk += Ek > 0 ? Pinv2[i]/Ek : 0.;
 
  182     return sqrt(std::max(0.,k2));
 
  186   void MinMassDiffInvJigsaw::ApplyOptimalRotation(){
 
  188     m_Z.SetXYZ(0.,0.,0.);
 
  191     while(m_Z.Mag() <= 0. && index < m_Npair){
 
  192       m_Z = m_Pinv[index].Vect().Cross(m_Pvis[index].Vect());
 
  199       for(
int i = 0; i < m_Npair; i++){
 
  200     if(m_Z.Dot(m_Pvis[i].Vect().Unit()) > 1e-8){
 
  204     if(m_Z.Dot(m_Pinv[i].Vect().Unit()) > 1e-8){
 
  211     m_minimizer->SetVariableValue(0, 0.);
 
  212     m_minimizer->SetVariableValue(1, 0.);
 
  213     m_minimizer->SetVariableValue(2, 0.);
 
  216       m_minimizer->FixVariable(1);
 
  217       m_minimizer->FixVariable(2);
 
  219       m_minimizer->ReleaseVariable(1);
 
  220       m_minimizer->ReleaseVariable(2);
 
  221       m_X.SetXYZ(0.,0.,0.);
 
  222       for(
int i = 0; i < m_Npair; i++)
 
  223     m_X += m_Pvis[i].Vect() - m_Pinv[i].Vect();
 
  226     m_X = m_Pvis[0].Vect().Cross(m_Z);
 
  229       m_Y = m_Z.Cross(m_X).Unit();
 
  232     m_minimizer->Minimize();
 
  233     if(m_minimizer->Status() > 0 && !m_2D){
 
  238       m_minimizer->SetVariableValue(0, 0.);
 
  239       m_minimizer->SetVariableValue(1, 0.);
 
  240       m_minimizer->SetVariableValue(2, 0.);
 
  241       m_minimizer->Minimize();
 
  244     const double* PHIs = m_minimizer->X();
 
  246     for(
int i = 0; i < m_Npair; i++){
 
  247       m_Pinv[i].Rotate(PHIs[0], m_Z);
 
  249     m_Pinv[i].Rotate(PHIs[1], m_Y);
 
  250     m_Pinv[i].Rotate(PHIs[2], m_X);
 
  257   double MinMassDiffInvJigsaw::EvaluateMetric(
const double* param){
 
  258     std::vector<TLorentzVector> Pinv;
 
  259     for(
int i = 0; i < m_Npair; i++){
 
  260       Pinv.push_back(m_Pinv[i]);
 
  261       Pinv[i].Rotate(param[0], m_Z);
 
  263     Pinv[i].Rotate(param[1], m_Y);
 
  264     Pinv[i].Rotate(param[2], m_X);
 
  266       Pinv[i] += m_Pvis[i];
 
  269     for(
int i = 0; i < m_Npair-1; i++){
 
  270       for(
int j = i+1; j < m_Npair; j++){
 
  271     diff += (Pinv[i].M()-Pinv[j].M())*(Pinv[i].M()-Pinv[j].M());