30 #include "Math/Factory.h"
36 MaxProbBreitWignerInvJigsaw::MaxProbBreitWignerInvJigsaw(
const std::string& sname,
37 const std::string& stitle,
39 InvisibleJigsaw(sname, stitle, N_vis_inv_pair, N_vis_inv_pair),
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, &MaxProbBreitWignerInvJigsaw::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);
55 for(
int i = 0; i < m_Npair; i++){
57 m_Width.push_back(-1.);
61 MaxProbBreitWignerInvJigsaw::~MaxProbBreitWignerInvJigsaw(){
66 double MaxProbBreitWignerInvJigsaw::GetMinimumMass()
const {
73 return std::max(0.,GetChildState(0).GetMinimumMass());
75 TLorentzVector PvisTOT(0.,0.,0.,0.);
77 for(
int i = 0; i < m_Npair; i++){
78 m_Pvis.push_back(GetDependancyStates(i+m_Npair).GetFourVector());
84 TVector3 Boost = PvisTOT.BoostVector();
85 for(
int i = 0; i < m_Npair; i++){
86 m_Pvis[i].Boost(-Boost);
87 Minv = std::max(0.,GetChildState(i).GetMinimumMass());
88 ECM += sqrt(m_Pvis[i].P()*m_Pvis[i].P() + Minv*Minv);
94 bool MaxProbBreitWignerInvJigsaw::AnalyzeEvent(){
96 return SetSpirit(
false);
101 TLorentzVector INV = GetParentState().GetFourVector();
102 double Minv = INV.M();
104 TLorentzVector VIS(0.,0.,0.,0.);
106 for(
int i = 0; i < m_Npair; i++){
107 m_Pvis.push_back(GetDependancyStates(i).GetFourVector());
112 TVector3 BoostCM = (VIS+INV).BoostVector();
115 for(
int i = 0; i < m_Npair; i++)
116 m_Pvis[i].Boost(-BoostCM);
119 TVector3 BoostVIS = VIS.BoostVector();
122 for(
int i = 0; i < m_Npair; i++){
123 m_Minv.push_back(std::max(0.,GetChildState(i).GetMinimumMass()));
124 m_Pinv.push_back(m_Pvis[i]);
125 m_Pinv[i].Boost(-BoostVIS);
126 m_Pinv[i].SetVectM(m_Pinv[i].Vect(), m_Minv[i]);
130 TVector3 BoostINV = INV.BoostVector();
131 for(
int i = 0; i < m_Npair; i++)
132 m_Pvis[i].Boost(-BoostINV);
135 TVector3 Vdiff = (m_Pvis[0].Vect()-m_Pvis[1].Vect()).Unit();
136 double pinv = GetP(Minv, m_Minv[0], m_Minv[1]);
137 m_Pinv[0].SetVectM( pinv*Vdiff, m_Minv[0]);
138 m_Pinv[1].SetVectM(-pinv*Vdiff, m_Minv[1]);
140 double k = GetPScale(Minv);
141 for(
int i = 0; i < m_Npair; i++)
142 m_Pinv[i].SetVectM(k*m_Pinv[i].Vect(), m_Minv[i]);
145 ApplyOptimalRotation();
148 for(
int i = 0; i < m_Npair; i++){
149 m_Pinv[i].Boost(BoostINV);
150 m_Pinv[i].Boost(BoostCM);
151 GetChildState(i).SetFourVector(m_Pinv[i]);
154 return SetSpirit(
true);
158 double MaxProbBreitWignerInvJigsaw::GetPScale(
double Minv){
159 std::vector<double> Pinv2;
163 for(
int i = 0; i < m_Npair; i++){
164 Pinv2.push_back(m_Pinv[i].P()*m_Pinv[i].P());
165 Ek += sqrt(m_Minv[i]*m_Minv[i]+Pinv2[i]);
168 if(fk > Minv || Ek <= 0.)
return 0.;
174 while(fabs(dk2) >= 1e-10 && count < 100){
177 for(
int i = 0; i < m_Npair; i++){
178 Ek = sqrt(m_Minv[i]*m_Minv[i]+k2*Pinv2[i]);
180 dfk += Ek > 0 ? Pinv2[i]/Ek : 0.;
187 return sqrt(std::max(0.,k2));
191 void MaxProbBreitWignerInvJigsaw::ApplyOptimalRotation(){
193 m_Z.SetXYZ(0.,0.,0.);
196 while(m_Z.Mag() <= 0. && index < m_Npair){
197 m_Z = m_Pinv[index].Vect().Cross(m_Pvis[index].Vect());
204 for(
int i = 0; i < m_Npair; i++){
205 if(m_Z.Dot(m_Pvis[i].Vect().Unit()) > 1e-8){
209 if(m_Z.Dot(m_Pinv[i].Vect().Unit()) > 1e-8){
216 m_minimizer->SetVariableValue(0, 0.);
217 m_minimizer->SetVariableValue(1, 0.);
218 m_minimizer->SetVariableValue(2, 0.);
221 m_minimizer->FixVariable(1);
222 m_minimizer->FixVariable(2);
224 m_minimizer->ReleaseVariable(1);
225 m_minimizer->ReleaseVariable(2);
226 m_X.SetXYZ(0.,0.,0.);
227 for(
int i = 0; i < m_Npair; i++)
228 m_X += m_Pvis[i].Vect() - m_Pinv[i].Vect();
231 m_X = m_Pvis[0].Vect().Cross(m_Z);
234 m_Y = m_Z.Cross(m_X).Unit();
237 m_minimizer->Minimize();
238 if(m_minimizer->Status() > 0 && !m_2D){
243 m_minimizer->SetVariableValue(0, 0.);
244 m_minimizer->SetVariableValue(1, 0.);
245 m_minimizer->SetVariableValue(2, 0.);
246 m_minimizer->Minimize();
249 const double* PHIs = m_minimizer->X();
251 for(
int i = 0; i < m_Npair; i++){
252 m_Pinv[i].Rotate(PHIs[0], m_Z);
254 m_Pinv[i].Rotate(PHIs[1], m_Y);
255 m_Pinv[i].Rotate(PHIs[2], m_X);
262 double MaxProbBreitWignerInvJigsaw::EvaluateMetric(
const double* param){
263 std::vector<TLorentzVector> Pinv;
264 for(
int i = 0; i < m_Npair; i++){
265 Pinv.push_back(m_Pinv[i]);
266 Pinv[i].Rotate(param[0], m_Z);
268 Pinv[i].Rotate(param[1], m_Y);
269 Pinv[i].Rotate(param[2], m_X);
271 Pinv[i] += m_Pvis[i];
275 TLorentzVector SUM(0.,0.,0.,0.);
276 for(
int i = 0; i < m_Npair; i++)
279 for(
int i = 0; i < m_Npair-1; i++){
281 prob *= GetP((Pinv[i]+SUM).M(), Pinv[i].M(), SUM.M())/M;
285 for(
int i = 0; i < m_Npair; i++){
287 den = Pinv[i].M2()-m_Mass[i]*m_Mass[i];
289 den += m_Mass[i]*m_Mass[i]*m_Width[i]*m_Width[i];
301 void MaxProbBreitWignerInvJigsaw::SetPoleMass(
double mass,
int i){
302 if(i < 0 || i >= m_Npair)
305 m_Mass[i] = std::max(mass, 0.);
308 void MaxProbBreitWignerInvJigsaw::SetWidth(
double width,
int i){
309 if(i < 0 || i >= m_Npair)