1 | /* ************************************************************************************* */ |
---|
2 | /* Thrust_func_collection.C */ |
---|
3 | /* */ |
---|
4 | /* Author: Consorti Valerio, valerio.consorti@physik.uni-freiburg.de */ |
---|
5 | /* created: June 2010 */ |
---|
6 | /* Description: A small collection of functions to compute the transverse thrust. */ |
---|
7 | /* The thrust value is normalized in the range [0,1] where 1 is for */ |
---|
8 | /* perfectly spherical events and 0 is for "pencil like" events */ |
---|
9 | /* */ |
---|
10 | /* ************************************************************************************* */ |
---|
11 | |
---|
12 | #include "Thrust_func_collection.h" |
---|
13 | |
---|
14 | //A modified step function used to compute the thrust axis |
---|
15 | double Thrust_func_collection::epsilon(double x){ |
---|
16 | if(x>=0) return 1; |
---|
17 | if(x<0) return -1; |
---|
18 | return -99; |
---|
19 | } |
---|
20 | |
---|
21 | //This function return the transverse thrust value for a given thrust axis |
---|
22 | double Thrust_func_collection::thrustService(TVector2 &n, std::vector<TVector2> &obj){ |
---|
23 | double num=0; |
---|
24 | double den=0; |
---|
25 | |
---|
26 | for(unsigned int i=0; i<obj.size(); i++){ |
---|
27 | num+=TMath::Abs(n*obj[i]); |
---|
28 | den+=obj[i].Mod(); |
---|
29 | } |
---|
30 | |
---|
31 | if(den==0) return -99; |
---|
32 | return num/den; |
---|
33 | } |
---|
34 | |
---|
35 | |
---|
36 | //Main function where the thrust axis which maximize the transverse thrust value is computed |
---|
37 | vector<double> Thrust_func_collection::Calc_Thrust(std::vector<TLorentzVector> &Vector) { |
---|
38 | vector<double> vec0; |
---|
39 | |
---|
40 | if(Vector.size()==1) return vec0; |
---|
41 | |
---|
42 | std::vector<TVector2> obj; |
---|
43 | |
---|
44 | for(unsigned int index=0; index<Vector.size(); index++){ |
---|
45 | obj.push_back(Vector[index].Vect().XYvector()); |
---|
46 | } |
---|
47 | |
---|
48 | if(obj.size()==0) return vec0; |
---|
49 | |
---|
50 | TVector2 n; |
---|
51 | TVector2 np1(obj[0]); |
---|
52 | TVector2 np1T; |
---|
53 | np1=np1.Unit(); |
---|
54 | bool loop_controller=true; |
---|
55 | |
---|
56 | int iloop=0; |
---|
57 | int iloop2=0; |
---|
58 | double thrust_old=0; |
---|
59 | double thrust_new=-1; |
---|
60 | double thrust_new_T=-1; |
---|
61 | double thrust_larger=0; |
---|
62 | double thrust_larger_T = 0.; |
---|
63 | TVector2 np1_choose, np1T_choose; |
---|
64 | double T=-99; |
---|
65 | double TT=-99; |
---|
66 | int n_lar_T_with_same_value=0; |
---|
67 | |
---|
68 | //Initializing Thrust axis. By default it use the leading jet direction to initialize the thrust axis |
---|
69 | for(unsigned int i=1; i<obj.size();i++) np1+=obj[i]; |
---|
70 | if(np1.X()==0 && np1.Y()==0) np1.Set(obj[0]); |
---|
71 | np1=np1.Unit(); |
---|
72 | |
---|
73 | |
---|
74 | //Computing transverse Thrust value. To ensure the convergence the algorithm requires to obtain 3 times the same maximum transverse Thrust value using 3 different initializations for the thrust axis |
---|
75 | do{ |
---|
76 | loop_controller=true; |
---|
77 | |
---|
78 | //changing thrust axis initialization after the first loop |
---|
79 | if(iloop2>0){ |
---|
80 | np1.Set(1.,0.); |
---|
81 | np1=np1.Rotate((iloop2-1)); |
---|
82 | np1=np1.Unit(); |
---|
83 | } |
---|
84 | iloop=0; |
---|
85 | |
---|
86 | //loop to find the axis which maximize the transverse Thrust value |
---|
87 | do{ |
---|
88 | n=np1; |
---|
89 | iloop++; |
---|
90 | |
---|
91 | if(iloop==1000){ |
---|
92 | loop_controller=false; |
---|
93 | thrust_new=-1; |
---|
94 | break; |
---|
95 | } |
---|
96 | |
---|
97 | thrust_old=thrustService(np1,obj); |
---|
98 | |
---|
99 | //the axis which maximize the thrust value is the result of the convergence of this series |
---|
100 | for(unsigned int i=0; i<obj.size(); i++){ |
---|
101 | np1+=epsilon(n*obj[i])*obj[i]; |
---|
102 | } |
---|
103 | |
---|
104 | np1=np1.Unit(); |
---|
105 | thrust_new=thrustService(np1,obj); |
---|
106 | //Add by me!!! |
---|
107 | np1T.Set(-np1.Y(),np1.X()); |
---|
108 | thrust_new_T = thrustService(np1T,obj); |
---|
109 | |
---|
110 | }while(fabs(thrust_new-thrust_old)>10e-18); |
---|
111 | |
---|
112 | |
---|
113 | if(thrust_new>thrust_larger && loop_controller ){ |
---|
114 | thrust_larger=thrust_new; |
---|
115 | thrust_larger_T=thrust_new_T;//Add by me |
---|
116 | np1_choose = np1; |
---|
117 | np1T_choose = np1T; |
---|
118 | n_lar_T_with_same_value=0; |
---|
119 | } |
---|
120 | |
---|
121 | |
---|
122 | if(fabs((thrust_new-thrust_larger)<10e-18) && loop_controller ) n_lar_T_with_same_value++; |
---|
123 | |
---|
124 | iloop2++; |
---|
125 | |
---|
126 | loop_controller=true; |
---|
127 | |
---|
128 | if(iloop2==1000){ |
---|
129 | loop_controller=false; |
---|
130 | std::cout<<"Thrust Computation: convergence 2 failed after: "<<iloop2<<" loop"<<std::endl; |
---|
131 | std::cout<<"n_lar_T_with_same_value: "<<n_lar_T_with_same_value<<std::endl; |
---|
132 | std::cout<<"(1-thrust_larger)/(1-2/TMath::Pi()): "<<(1-thrust_larger)/(1-2/TMath::Pi())<<std::endl; |
---|
133 | std::cout<<"Vector.size(): "<<Vector.size()<<std::endl; |
---|
134 | std::cout<<"i pt px py pxobj pyobj"<<std::endl; |
---|
135 | for(unsigned int i=0; i<Vector.size();i++){ |
---|
136 | std::cout<<i<<" "<<Vector[i].Pt()<<" "<<Vector[i].Px()<<" "<<Vector[i].Py()<<" "<<obj[i].X()<<" "<<obj[i].Y()<<std::endl; |
---|
137 | } |
---|
138 | return vec0; |
---|
139 | } |
---|
140 | //to accept the thrust value we require: |
---|
141 | //1- it has to be into [2/pi,1] which is the range for the transverse thrust |
---|
142 | //2- The maximum thrust value has to be obtain 3 times using 3 different initializations for the trust axis |
---|
143 | |
---|
144 | }while( ( thrust_larger<2/TMath::Pi() || n_lar_T_with_same_value<3 ) && loop_controller==true ); |
---|
145 | |
---|
146 | T=thrust_larger; |
---|
147 | TT=thrust_larger_T; |
---|
148 | |
---|
149 | if(T<0 || T>1){ |
---|
150 | if(Vector.size()>1){ |
---|
151 | std::cout<<"Thrust Computation: ERROR, thrust value out of range: "<<T<<std::endl; |
---|
152 | |
---|
153 | std::cout<<"i pt px py pxobj pyobj"<<std::endl; |
---|
154 | for(unsigned int i=0; i<Vector.size();i++){ |
---|
155 | std::cout<<i<<" "<<Vector[i].Pt()<<" "<<Vector[i].Px()<<" "<<Vector[i].Py()<<" "<<obj[i].X()<<" "<<obj[i].Y()<<std::endl; |
---|
156 | } |
---|
157 | } |
---|
158 | return vec0; |
---|
159 | } |
---|
160 | |
---|
161 | vector<double> res; |
---|
162 | res.push_back(T); |
---|
163 | res.push_back(TT); |
---|
164 | return res; |
---|
165 | |
---|
166 | } |
---|
167 | |
---|