RhoRhoPHOTOSUserTreeAnalysis.C

00001 //#include "UserTreeAnalysis.H"   // remove if copied to user working directory
00002 #include <stdio.h>
00003 #include <assert.h>
00004 #include <math.h>
00005 #include <vector>
00006 #include <iostream>
00007 #include "MC4Vector.H"
00008 #include "HEPParticle.H"
00009 #include "TH1.h"
00010 #include "Setup.H"
00011 #include "TObjArray.h"
00012 #include "TMath.h"
00013 
00014 using namespace std;
00015 // Limits for particular user histograms
00016 int L[6] = { 5000000,5000000,2000000,2000000,1000000,1000000 };
00017 
00018 // very similar to  MC_FillUserHistogram from Generate.cxx
00019 inline void fillUserHisto(char *name,double val, double weight=1.0, 
00020                           double min=Setup::bin_min[0][0], 
00021                           double max=Setup::bin_max[0][0])
00022 {
00023         TH1D *h=(TH1D*)(Setup::user_histograms->FindObject(name));
00024         if(!h){
00025                 h=new TH1D(name,name,Setup::nbins[0][0],min,max);
00026                 if(!h) return;
00027                 Setup::user_histograms->Add(h);
00028                 //      printf("user histogram created %s\n", name);
00029         }
00030         h->Fill(val,weight);
00031 }
00032 
00033 double normalised_cross_product(double * v1, double * v2, double * result)
00034 {
00035         result[0] = v1[1]*v2[2] - v1[2]*v2[1];
00036         result[1] = v1[2]*v2[0] - v1[0]*v2[2];
00037         result[2] = v1[0]*v2[1] - v1[1]*v2[0];
00038 
00039         double normalisation = sqrt(result[0]*result[0]
00040                               +result[1]*result[1]
00041                               +result[2]*result[2]);
00042 
00043         for(int i=0;i<3;i++)
00044                 result[i]=result[i]/normalisation;
00045 
00046         return normalisation;
00047 }
00048 
00049 double dot_product(double *v1, double *v2)
00050 {
00051         return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
00052 }
00053 
00054 double dot_product(MC4Vector v1, MC4Vector v2)
00055 {
00056         return v1.GetX1()*v2.GetX1()+v1.GetX2()*v2.GetX2()+v1.GetX3()*v2.GetX3();
00057 }
00058 
00059 double magnitude(double *v)
00060 {
00061         return sqrt(dot_product(v,v));
00062 }
00063 
00064 
00065 //see RhoRhoUserTreeAnalysis in TAUOLA
00066 /** Main function. This does not take any parameters. It assumes
00067         the events are something -> tau+ tau-, then tau -> pi+/- pi0 nu */
00068 int RhoRhoPHOTOSUserTreeAnalysis(HEPParticle *mother,HEPParticleList *stableDaughters, int nparams, double *params)
00069 {
00070         assert(mother!=0);
00071         assert(stableDaughters!=0);
00072 
00073         HEPParticleListIterator daughters(*stableDaughters);
00074 
00075         //make temporary 4 vectors for the pions
00076         double pi_plus[4]={0};
00077         double pi_minus[4]={0};
00078         double pi0_plus[4]={0};
00079         double pi0_minus[4]={0};
00080 
00081         MC4Vector d_pi0_plus;
00082         MC4Vector d_pi0_minus;
00083         MC4Vector d_pi_plus;
00084         MC4Vector d_pi_minus;
00085         MC4Vector d_gamma;
00086         MC4Vector temp;
00087 
00088         //make temporary variables to store the center of mass of
00089         //the rho+ rho- pair.
00090         double cm_px=0;
00091         double cm_py=0;
00092         double cm_pz=0;
00093         double cm_e=0;
00094 
00095         double photon_e = 0;
00096 
00097         //loop over all daughters and sort them by type, filling the
00098         //temporary variables.
00099         for (HEPParticle *part=daughters.first(); part!=0; part=daughters.next())
00100         {
00101                 temp = part->GetP4();
00102                 if(part->GetPDGId()!=16&&part->GetPDGId()!=-16)
00103                 {
00104                         //Get the center of mass
00105                         cm_px+=part->GetPx();
00106                         cm_py+=part->GetPy();
00107                         cm_pz+=part->GetPz();
00108                         cm_e+=part->GetE();
00109                 }
00110 
00111                 //Initialize the particle arrays
00112                 switch(part->GetPDGId())
00113                 {
00114                 case 211:
00115                         d_pi_plus.Set(&temp);
00116                         d_pi_plus.SetM(part->GetM());   
00117                         break;
00118                 case -211:
00119                         d_pi_minus.Set(&temp);
00120                         d_pi_minus.SetM(part->GetM());
00121                         break;
00122                 case 111: //fill the pi0's randomly for the moment.
00123                         if(d_pi0_minus.GetX1()==0&&d_pi0_minus.GetX2()==0&&d_pi0_minus.GetX3()==0)
00124                         {
00125                                 d_pi0_minus.Set(&temp);
00126                                 d_pi0_minus.SetM(part->GetM());
00127                         }
00128                         else
00129                         {
00130                                 d_pi0_plus.Set(&temp);
00131                                 d_pi0_plus.SetM(part->GetM());
00132                         }       
00133                         break;
00134                 case 22:
00135                         d_gamma.Set(&temp);
00136                         d_gamma.SetM(0);
00137                         // Only the hardest photon counts
00138                         if(photon_e>d_gamma.GetX0()) return 0;
00139                         photon_e=d_gamma.GetX0();
00140                         // Skip photons with energy < 10MeV
00141                         if(photon_e<0.01) photon_e=0;
00142                         break;  
00143                 default:
00144                         break;
00145                 }
00146         }
00147 
00148         //Now check which pi0 is associated with
00149         //which pi+/-. Use the angle to decide.
00150         double costheta1 = dot_product(d_pi_plus,d_pi0_plus)/(d_pi_plus.Length()*d_pi0_plus.Length());
00151         double costheta2 = dot_product(d_pi_minus,d_pi0_plus)/(d_pi_minus.Length()*d_pi0_plus.Length());
00152 
00153 
00154         if(costheta1<costheta2) //if necessary, change the pi0 vectors
00155         {
00156                 MC4Vector temp;
00157                 temp.Set(&d_pi0_plus);
00158                 temp.SetM(d_pi0_plus.GetM());
00159                 d_pi0_plus.Set(&d_pi0_minus);
00160                 d_pi0_plus.SetM(d_pi0_minus.GetM());
00161                 d_pi0_minus.Set(&temp);
00162                 d_pi0_minus.SetM(temp.GetM());
00163         }
00164 
00165         //Now boost everything into the rho+ rho- center of mass frame.
00166         double cm_mass = sqrt(cm_e*cm_e-cm_px*cm_px-cm_py*cm_py-cm_pz*cm_pz);
00167 
00168         d_pi0_plus.Boost(cm_px,cm_py,cm_pz,cm_e,cm_mass);
00169         d_pi0_minus.Boost(cm_px,cm_py,cm_pz,cm_e,cm_mass);
00170         d_pi_plus.Boost(cm_px,cm_py,cm_pz,cm_e,cm_mass);
00171         d_pi_minus.Boost(cm_px,cm_py,cm_pz,cm_e,cm_mass);
00172         d_gamma.Boost(cm_px,cm_py,cm_pz,cm_e,cm_mass);
00173 
00174         pi0_plus[0]=d_pi0_plus.GetX1();
00175         pi0_plus[1]=d_pi0_plus.GetX2();
00176         pi0_plus[2]=d_pi0_plus.GetX3();
00177         pi0_plus[3]=d_pi0_plus.GetM();
00178 
00179         pi_plus[0]=d_pi_plus.GetX1();
00180         pi_plus[1]=d_pi_plus.GetX2();
00181         pi_plus[2]=d_pi_plus.GetX3();
00182         pi_plus[3]=d_pi_plus.GetM();
00183 
00184         pi0_minus[0]=d_pi0_minus.GetX1();
00185         pi0_minus[1]=d_pi0_minus.GetX2();
00186         pi0_minus[2]=d_pi0_minus.GetX3();
00187         pi0_minus[3]=d_pi0_minus.GetM();
00188 
00189         pi_minus[0]=d_pi_minus.GetX1();
00190         pi_minus[1]=d_pi_minus.GetX2();
00191         pi_minus[2]=d_pi_minus.GetX3();
00192         pi_minus[3]=d_pi_minus.GetM();
00193 
00194         /******* calculate acoplanarity (theta) *****/
00195 
00196         //normal to the plane spanned by pi+ pi0 
00197         double n_plus[3];
00198         normalised_cross_product(pi_plus,pi0_plus,n_plus);
00199 
00200         //normal to the plane spanned by pi- pi0
00201         double n_minus[3];
00202         normalised_cross_product(pi_minus,pi0_minus,n_minus);
00203 
00204         //get the angle
00205         double theta = acos(dot_product(n_plus,n_minus));
00206 
00207         //make theta go between 0 and 2 pi.
00208         double pi_minus_n_plus = dot_product(pi_minus,n_plus)/magnitude(pi_minus);    
00209         if(pi_minus_n_plus>0)
00210                 theta=2*M_PI-theta;
00211 
00212         /*********** calculate C/D reco  (y1y2 in the paper) ***/
00213 
00214         //boost vectors back to the lab frame
00215         d_pi0_plus.Boost(-cm_px,-cm_py,-cm_pz,cm_e,cm_mass);
00216         d_pi_plus.Boost(-cm_px,-cm_py,-cm_pz,cm_e,cm_mass);
00217         d_pi0_minus.Boost(-cm_px,-cm_py,-cm_pz,cm_e,cm_mass);
00218         d_pi_minus.Boost(-cm_px,-cm_py,-cm_pz,cm_e,cm_mass);
00219 
00220         //construct effective tau 4 vectors (without neutrino)
00221         double e_tau = 120.0/2.0;
00222         double m_tau = 1.78;
00223         double p_mag_tau = sqrt(e_tau*e_tau - m_tau*m_tau);
00224 
00225         MC4Vector p_tau_plus = d_pi_plus + d_pi0_plus;
00226         MC4Vector p_tau_minus = d_pi_minus + d_pi0_minus;
00227 
00228         double norm_plus = p_mag_tau/p_tau_plus.Length();
00229         double norm_minus = p_mag_tau/p_tau_minus.Length();
00230 
00231         p_tau_plus.SetX0(e_tau);
00232         p_tau_plus.SetX1(norm_plus*p_tau_plus.GetX1());
00233         p_tau_plus.SetX2(norm_plus*p_tau_plus.GetX2());
00234         p_tau_plus.SetX3(norm_plus*p_tau_plus.GetX3());
00235         p_tau_plus.SetM(m_tau);
00236 
00237         p_tau_minus.SetX0(e_tau);
00238         p_tau_minus.SetX1(norm_minus*p_tau_minus.GetX1());
00239         p_tau_minus.SetX2(norm_minus*p_tau_minus.GetX2());
00240         p_tau_minus.SetX3(norm_minus*p_tau_minus.GetX3());
00241         p_tau_minus.SetM(m_tau);
00242 
00243         //boost to the (reco) tau's frames
00244         d_pi0_plus.BoostP(p_tau_plus);
00245         d_pi_plus.BoostP(p_tau_plus);
00246         d_pi0_minus.BoostP(p_tau_minus);
00247         d_pi_minus.BoostP(p_tau_minus);
00248 
00249         //calculate y1 and y2
00250         double y1=(d_pi_plus.GetX0()-d_pi0_plus.GetX0())/(d_pi_plus.GetX0()+d_pi0_plus.GetX0());
00251         double y2=(d_pi_minus.GetX0()-d_pi0_minus.GetX0())/(d_pi_minus.GetX0()+d_pi0_minus.GetX0());
00252         
00253         //make seperate plots for different photon energy ranges
00254         if(photon_e==0)
00255         {
00256                 if(y1*y2>0)
00257                 {
00258                         if(L[0]<=0) return 0;
00259                         L[0]--;
00260                         char name[] = "acoplanarity-angle-C-no-photon";
00261                         fillUserHisto(name,theta,1.0,0,2*M_PI);
00262                 }
00263                 else
00264                 {
00265                         if(L[1]<=0) return 0;
00266                         L[1]--;
00267                         char name[] = "acoplanarity-angle-D-no-photon";
00268                         fillUserHisto(name,theta,1.0,0,2*M_PI);
00269                 }
00270 
00271         }
00272         if(photon_e>0&&photon_e<1.0)
00273         {
00274                 if(y1*y2>0)
00275                 {
00276                         if(L[2]<=0) return 0;
00277                         L[2]--;
00278                         char name[] = "acoplanarity-angle-C-photon-up-to-1-GeV";
00279                         fillUserHisto(name,theta,1.0,0,2*M_PI);
00280                 }
00281                 else
00282                 {
00283                         if(L[3]<=0) return 0;
00284                         L[3]--;
00285                         char name[] = "acoplanarity-angle-D-photon-up-to-1-GeV";
00286                         fillUserHisto(name,theta,1.0,0,2*M_PI);
00287                 }
00288         }
00289         if(photon_e>1.0)
00290         {
00291                 if(y1*y2>0)
00292                 {
00293                         if(L[4]<=0) return 0;
00294                         L[4]--;
00295                         char name[] = "acoplanarity-angle-C-photon-over-1-GeV";
00296                         fillUserHisto(name,theta,1.0,0,2*M_PI);
00297                 }
00298                 else
00299                 {
00300                         if(L[5]<=0) return 0;
00301                         L[5]--;
00302                         char name[] = "acoplanarity-angle-D-photon-over-1-GeV";
00303                         fillUserHisto(name,theta,1.0,0,2*M_PI);
00304                 }
00305         }
00306         
00307         return 0;
00308 };
00309 
Generated on Sun Oct 20 20:23:56 2013 for C++InterfacetoPHOTOS by  doxygen 1.6.3