2 UserTreeAnalysis implementation
4 Details regarding the working of the analysis itself are given below,
5 just after the function header.
8 //#include "UserTreeAnalysis.H" // remove if copied to user working directory
12 #include "MC4Vector.H"
13 #include "HEPParticle.H"
16 #include "TObjArray.h"
18 #define PI 3.141592653
20 inline bool ifSofty(int Id,int nparams, double *params){
21 if (nparams<5 && Id==22) return true; // to remove photons only
22 for (int i=nparams-1; i>3; i--)
23 if (Id==params[i]) return true; // to remove all what is in params from nparams down to 4
27 // very similar to MC_FillUserHistogram from Generate.cxx
28 inline void fillUserHisto(char *name,double val, double weight=1.0,
29 double min=Setup::bin_min[0][0],
30 double max=Setup::bin_max[0][0]){
32 TH1D *h=(TH1D*)(Setup::user_histograms->FindObject(name));
34 h=new TH1D(name,name,Setup::nbins[0][0],min,max);
36 Setup::user_histograms->Add(h);
37 // printf("user histogram created %s\n", name);
42 double angle(double X, double Y){
46 double R=sqrt(X*X+Y*Y);
47 // if(R<pow(10,-20)) printf(" angle this time X %f\n", 10000*X);
48 if(R<pow(10,-20)) return an;
50 if(TMath::Abs(X)/R<0.8)
53 if(Y<0 && an>0) an=-an;
54 if(Y>0 && an<0) an=-an;
59 if(X<0 && an>=0.) an=PI-an;
60 else if(X<0.) an=-PI-an;
66 int ZmumuAnalysis(HEPParticle *mother,HEPParticleList *stableDaughters, int nparams, double *params)
68 // THIS IS EXAMPLE of userTreeAnalysis. It acts on list of particle X (under our MC-test) final
69 // daughters. Of course in real life many options may need to be introduced by the user.
71 // params[0] threshold on Energy (or p_T) of particle expressed as a fraction of mother's
72 // Energy (or p_T) in mother's frame. If not specified - default is 0.05
73 // Note that setting it to zero is possible.
74 // params[1] maximum number of left soft-suspected particles.
75 // 0: (default) all listed particles are removed, even if hard
76 // 1: 2: one two etc removable particles are kept (at most)
77 // -1: this option is off, all hard particles stay.
78 // params[2] control tag on discriminating particles,
79 // 0: (default) Energy in decaying particle rest frame
80 // 1: Energy in lab frame
81 // 2: p_T with respect to beam direction in lab frame.
82 // params[3] type of action to be applied on removed daughters
83 // 0: (default) nothing is done, they are lost
84 // 1: algorithm as in studies on PHOTOS is used, see papers P. Golonka and Z. Was.
85 // params[4] from this paramter on PDG id-s of particles to be removed can be added.
86 // Default is that only photons are removed.
87 // To get to origin of our particle (mother) one need to go after UserEventAnalysis,
88 // instructive example will be given later.
90 assert(stableDaughters!=0);
93 double threshold=0.05, leftmax=0.0, selector=0.0, actLost=0.0;
94 if (nparams>0 && params==0) return -1;
95 if (nparams>0) threshold=params[0];
96 if (nparams>1) leftmax =params[1];
97 if (nparams>2) selector =params[2];
98 if (nparams>3) actLost =params[3];
101 HEPParticleList *lostDaughters=new HEPParticleList;
102 double pt_limit=threshold*mother->GetM();
104 HEPParticleListIterator daughters (*stableDaughters);
106 double ephot=pow(10,22);
108 for (HEPParticle *part=daughters.first(); part!=0; (redo)? part=part:part=daughters.next() ) {
110 MC4Vector d4(part->GetE(),part->GetPx(),part->GetPy(),part->GetPz(),part->GetM());
111 // boost to mother's frame:
112 d4.Boost(mother->GetPx(),mother->GetPy(),mother->GetPz(),mother->GetE(),mother->GetM());
116 double p_t=d4.GetX0(); // default
117 switch ((int) selector)
119 case 1: p_t=part->GetE(); break;
120 case 2: p_t=d4.Xt(); break;
124 if(ifSofty(part->GetPDGId(),nparams,params)) nphot++;
125 if ( ifSofty(part->GetPDGId(),nparams,params) && p_t < pt_limit) {
126 // printf("Odrzucamy! %i\n",count++);
128 lostDaughters->push_back(part);
129 stableDaughters->remove(part);
130 part=daughters.first();
134 if( ifSofty(part->GetPDGId(),nparams,params) && ephot>p_t) ephot=p_t;
136 while(nphot>(int) leftmax)
138 double ephot1=pow(10,22);
140 for (HEPParticle *part=daughters.first(); part!=0; (redo)? part=part:part=daughters.next() ) {
142 MC4Vector d4(part->GetE(),part->GetPx(),part->GetPy(),part->GetPz(),part->GetM());
143 // boost to mother's frame:
144 d4.Boost(mother->GetPx(),mother->GetPy(),mother->GetPz(),mother->GetE(),mother->GetM());
147 double p_t=d4.GetX0(); // default
148 switch ((int) selector)
150 case 1: p_t=part->GetE(); break;
151 case 2: p_t=d4.Xt(); break;
155 if ( ifSofty(part->GetPDGId(),nparams,params) && p_t == ephot) {
158 lostDaughters->push_back(part);
159 stableDaughters->remove(part);
161 part=daughters.first();
165 if( ifSofty(part->GetPDGId(),nparams,params) && ephot1>p_t) ephot1=p_t;
171 // ##############################################################
172 // SPECIAL CASE - ordered or symmetrical photons
173 // This code changes order of photons
174 // ##############################################################
175 HEPParticleListIterator symmetry (*stableDaughters);
176 HEPParticle *phot1 = NULL;
177 HEPParticle *phot2 = NULL;
178 for (HEPParticle *part=symmetry.first(); part!=0; part=symmetry.next() )
180 if(part->GetPDGId()==22)
182 if(!phot1) phot1=part;
192 if(phot1->GetE()<phot2->GetE()) // for ordered photons
193 //if( rand()*1.0/RAND_MAX > 0.5) // for photon symmetrization
195 double buf_x = phot1->GetPx();
196 double buf_y = phot1->GetPy();
197 double buf_z = phot1->GetPz();
198 double buf_e = phot1->GetE();
200 phot1->SetPx(phot2->GetPx());
201 phot1->SetPy(phot2->GetPy());
202 phot1->SetPz(phot2->GetPz());
203 phot1->SetE (phot2->GetE() );
212 // ##############################################################
213 // here functionality of removig some daughters is finished
214 // now we reconsider what to do with them
215 // ##############################################################
216 // delete lostDaughters;
220 // ##############################################################
221 // Now: What to do with lost daughters?
222 // ##############################################################
223 // lostDaughters->ls();
224 int version=(int) actLost;
228 case 1: // add lost to charged
230 HEPParticleListIterator lost (*lostDaughters);
231 for (HEPParticle *lostpart=lost.first(); lostpart!=0; lostpart=lost.next() ) {
233 double searchvirt=pow(10.0,22);
235 for( HEPParticle *part=daughters.first(); part!=0; part=daughters.next() ){
236 if(part->GetCharge()==0) continue;
237 VV=lostpart->GetP4()+part->GetP4();
239 if (VV.GetM()<searchvirt) {searchvirt=VV.GetM(); Best=part;}
242 Best->SetPx(Best->GetPx()+lostpart->GetPx());
243 Best->SetPy(Best->GetPy()+lostpart->GetPy());
244 Best->SetPz(Best->GetPz()+lostpart->GetPz());
245 Best->SetE (Best->GetE ()+lostpart->GetE ());
250 default: break; // do nothing
253 delete lostDaughters;
256 bool activateUserHist=true;
257 if(!activateUserHist) return 1;
259 // segmet of user defined histograms
261 double X=mother->GetPx(), Y=mother->GetPy(), Z=mother->GetPz();
262 // double E=mother->GetE(), MM=mother->GetM();
265 double pt=sqrt(X*X+Y*Y);
266 double eta=log((sqrt(pt*pt+Z*Z)+TMath::Abs(Z))/pt);
267 if(Z<0 && eta>0) eta=-eta;
268 if(Z>0 && eta<0) eta=-eta;
269 double phi=angle(X,Y);
270 char hist1[] = "mother-PT";
271 char hist2[] = "mother-eta";
272 char hist3[] = "mother-phi";
273 fillUserHisto(hist1,pt,1.0,0.0,100.0);
274 fillUserHisto(hist2,eta,1.0,-8.0,8.0);
275 fillUserHisto(hist3,phi,1.0,-PI,PI);