ZmumuAnalysis.C

00001 /*
00002    UserTreeAnalysis implementation
00003 
00004    Details regarding the working of the analysis itself are given below,
00005    just after the function header.
00006 */
00007 
00008 //#include "UserTreeAnalysis.H"   // remove if copied to user working directory
00009 #include <stdio.h>
00010 #include <assert.h>
00011 #include <math.h>
00012 #include "MC4Vector.H"
00013 #include "HEPParticle.H"
00014 #include "TH1.h"
00015 #include "Setup.H"
00016 #include "TObjArray.h"
00017 #include "TMath.h"
00018 #define PI 3.141592653
00019 
00020 inline bool ifSofty(int Id,int nparams, double *params){
00021   if (nparams<5 && Id==22) return true;   // to remove photons only
00022   for (int i=nparams-1; i>3; i--)
00023     if (Id==params[i]) return true;       // to remove all what is in params from nparams down to 4
00024   return false;
00025 }
00026 
00027 // very similar to  MC_FillUserHistogram from Generate.cxx
00028 inline void fillUserHisto(char *name,double val, double weight=1.0, 
00029                           double min=Setup::bin_min[0][0], 
00030                           double max=Setup::bin_max[0][0]){
00031 
00032     TH1D *h=(TH1D*)(Setup::user_histograms->FindObject(name));
00033     if(!h){
00034       h=new TH1D(name,name,Setup::nbins[0][0],min,max);
00035       if(!h) return;
00036       Setup::user_histograms->Add(h);
00037       //      printf("user histogram created %s\n", name);
00038 }
00039     h->Fill(val,weight);
00040 
00041 }
00042 double angle(double X, double Y){
00043 
00044  
00045     double  an=0.0; 
00046     double R=sqrt(X*X+Y*Y); 
00047     //    if(R<pow(10,-20)) printf(" angle this time X %f\n", 10000*X);
00048     if(R<pow(10,-20)) return an;
00049 
00050     if(TMath::Abs(X)/R<0.8) 
00051     { 
00052         an=acos(X/R);
00053         if(Y<0 && an>0) an=-an;
00054         if(Y>0 && an<0) an=-an; 
00055     }
00056     else 
00057     { 
00058       an=asin(Y/R);
00059       if(X<0 && an>=0.)  an=PI-an; 
00060       else if(X<0.)      an=-PI-an; 
00061        
00062     } 
00063   return an;
00064 }
00065 
00066 int ZmumuAnalysis(HEPParticle *mother,HEPParticleList *stableDaughters, int nparams, double *params)
00067 {
00068   // THIS IS EXAMPLE of userTreeAnalysis. It acts on list of particle X (under our MC-test) final
00069   // daughters. Of course in real life many options may need to be introduced by the user.
00070     // PARAMETERS:
00071     // params[0] threshold on Energy (or p_T) of particle expressed as a fraction of mother's 
00072     //           Energy (or p_T) in mother's frame. If not specified - default is 0.05 
00073     //           Note that setting it to zero is possible.
00074     // params[1] maximum number of left soft-suspected particles. 
00075     //           0: (default) all listed particles are removed, even if hard
00076     //           1: 2:  one two etc  removable particles are kept (at most)
00077     //          -1: this option is off, all hard particles stay.
00078     // params[2] control tag on discriminating particles, 
00079     //           0: (default) Energy in decaying particle rest frame
00080     //           1: Energy in lab frame
00081     //           2: p_T with respect to beam direction in lab frame.
00082     // params[3] type of action to be applied on removed daughters 
00083     //           0: (default) nothing is done, they are lost
00084     //           1:  algorithm as in studies on PHOTOS is used, see papers P. Golonka and Z. Was.
00085     // params[4] from this paramter on PDG id-s of particles to be removed can be added. 
00086     //           Default is that only photons are removed.
00087     // To get to origin of our particle (mother) one need to go after UserEventAnalysis,
00088     // instructive example will be given later. 
00089     assert(mother!=0);
00090     assert(stableDaughters!=0);
00091 
00092 
00093     double threshold=0.05, leftmax=0.0, selector=0.0, actLost=0.0; 
00094     if (nparams>0 && params==0)  return -1;
00095     if (nparams>0) threshold=params[0]; 
00096     if (nparams>1) leftmax  =params[1]; 
00097     if (nparams>2) selector =params[2]; 
00098     if (nparams>3) actLost  =params[3]; 
00099 
00100     
00101     HEPParticleList *lostDaughters=new HEPParticleList;    
00102     double pt_limit=threshold*mother->GetM();
00103 
00104     HEPParticleListIterator daughters (*stableDaughters);
00105     int nphot=0;
00106     double ephot=pow(10,22);
00107     bool redo=false;
00108     for (HEPParticle *part=daughters.first(); part!=0; (redo)? part=part:part=daughters.next() ) {
00109       if(redo) redo=false;
00110         MC4Vector d4(part->GetE(),part->GetPx(),part->GetPy(),part->GetPz(),part->GetM());
00111         // boost to mother's frame:
00112         d4.Boost(mother->GetPx(),mother->GetPy(),mother->GetPz(),mother->GetE(),mother->GetM());
00113 
00114 
00115 
00116         double p_t=d4.GetX0();  // default
00117         switch ((int) selector)
00118         {
00119         case 1: p_t=part->GetE(); break;
00120         case 2: p_t=d4.Xt(); break;
00121         }
00122 
00123 
00124         if(ifSofty(part->GetPDGId(),nparams,params)) nphot++;
00125         if ( ifSofty(part->GetPDGId(),nparams,params) && p_t < pt_limit) {
00126           //      printf("Odrzucamy! %i\n",count++);
00127           nphot=0;
00128             lostDaughters->push_back(part);
00129             stableDaughters->remove(part);
00130             part=daughters.first();
00131             redo=true;
00132             continue;
00133         }
00134         if( ifSofty(part->GetPDGId(),nparams,params) && ephot>p_t) ephot=p_t;
00135     }
00136     while(nphot>(int) leftmax)
00137     {
00138       double ephot1=pow(10,22);
00139       redo=false;
00140       for (HEPParticle *part=daughters.first(); part!=0; (redo)? part=part:part=daughters.next() ) {
00141         if(redo) redo=false;
00142         MC4Vector d4(part->GetE(),part->GetPx(),part->GetPy(),part->GetPz(),part->GetM());
00143         // boost to mother's frame:
00144         d4.Boost(mother->GetPx(),mother->GetPy(),mother->GetPz(),mother->GetE(),mother->GetM());
00145 
00146 
00147         double p_t=d4.GetX0();  // default
00148         switch ((int) selector)
00149         {
00150         case 1: p_t=part->GetE(); break;
00151         case 2: p_t=d4.Xt(); break;
00152         }
00153 
00154 
00155         if ( ifSofty(part->GetPDGId(),nparams,params) && p_t == ephot) {
00156 
00157           nphot--;
00158             lostDaughters->push_back(part);
00159             stableDaughters->remove(part);
00160             ephot1=pow(10,22);
00161              part=daughters.first();
00162              redo=true;
00163              continue;
00164         }
00165         if( ifSofty(part->GetPDGId(),nparams,params) && ephot1>p_t) ephot1=p_t;
00166       }
00167       ephot=ephot1;
00168 
00169     }
00170 
00171     // ##############################################################
00172     // SPECIAL CASE - ordered or symmetrical photons
00173     //                This code changes order of photons
00174     // ##############################################################
00175     HEPParticleListIterator symmetry (*stableDaughters);
00176     HEPParticle *phot1 = NULL;
00177     HEPParticle *phot2 = NULL;
00178     for (HEPParticle *part=symmetry.first(); part!=0; part=symmetry.next() )
00179     {
00180       if(part->GetPDGId()==22)
00181       {
00182         if(!phot1) phot1=part;
00183         else
00184         {
00185           phot2=part;
00186           break;
00187         }
00188       }
00189     }
00190     if(phot1 && phot2)
00191     {
00192       if(phot1->GetE()<phot2->GetE()) // for ordered photons
00193       //if( rand()*1.0/RAND_MAX > 0.5) // for photon symmetrization
00194       {
00195         double buf_x = phot1->GetPx();
00196         double buf_y = phot1->GetPy();
00197         double buf_z = phot1->GetPz();
00198         double buf_e = phot1->GetE();
00199 
00200         phot1->SetPx(phot2->GetPx());
00201         phot1->SetPy(phot2->GetPy());
00202         phot1->SetPz(phot2->GetPz());
00203         phot1->SetE (phot2->GetE() );
00204 
00205         phot2->SetPx(buf_x);
00206         phot2->SetPy(buf_y);
00207         phot2->SetPz(buf_z);
00208         phot2->SetE (buf_e);
00209       }
00210     }
00211  
00212     // ##############################################################
00213     // here functionality of removig some daughters is finished
00214     // now we reconsider what to do with them
00215     // ##############################################################
00216     // delete lostDaughters;
00217     // return 1; 
00218 
00219 
00220     // ##############################################################
00221     // Now: What to do with lost daughters?
00222     // ##############################################################
00223     //    lostDaughters->ls();
00224     int version=(int) actLost;
00225         
00226     switch(version)
00227       {
00228       case 1:  // add lost to charged
00229         {
00230           HEPParticleListIterator lost (*lostDaughters);
00231           for (HEPParticle *lostpart=lost.first(); lostpart!=0; lostpart=lost.next() ) {
00232             HEPParticle* Best=0;
00233             double searchvirt=pow(10.0,22);
00234             MC4Vector VV;
00235             for( HEPParticle *part=daughters.first(); part!=0; part=daughters.next() ){
00236               if(part->GetCharge()==0) continue;
00237               VV=lostpart->GetP4()+part->GetP4();
00238               VV.AdjustM();
00239               if (VV.GetM()<searchvirt) {searchvirt=VV.GetM(); Best=part;}
00240             }
00241             if(Best) {
00242               Best->SetPx(Best->GetPx()+lostpart->GetPx());
00243               Best->SetPy(Best->GetPy()+lostpart->GetPy());
00244               Best->SetPz(Best->GetPz()+lostpart->GetPz());
00245               Best->SetE (Best->GetE ()+lostpart->GetE ());
00246             }
00247           }
00248         break;
00249         }
00250       default: break; // do nothing
00251       }
00252 
00253     delete lostDaughters;
00254 
00255     
00256     bool activateUserHist=true;
00257     if(!activateUserHist) return 1;
00258 
00259     // segmet of user defined histograms
00260 
00261     double X=mother->GetPx(), Y=mother->GetPy(), Z=mother->GetPz(); 
00262     // double E=mother->GetE(),  MM=mother->GetM();
00263 
00264 
00265     double pt=sqrt(X*X+Y*Y);
00266     double eta=log((sqrt(pt*pt+Z*Z)+TMath::Abs(Z))/pt);
00267     if(Z<0 && eta>0) eta=-eta;
00268     if(Z>0 && eta<0) eta=-eta;
00269     double phi=angle(X,Y);
00270     char hist1[] = "mother-PT";
00271     char hist2[] = "mother-eta";
00272     char hist3[] = "mother-phi";
00273     fillUserHisto(hist1,pt,1.0,0.0,100.0);
00274     fillUserHisto(hist2,eta,1.0,-8.0,8.0);
00275     fillUserHisto(hist3,phi,1.0,-PI,PI);
00276     return 1;
00277 }
00278 
Generated on Sun Oct 20 20:23:56 2013 for C++InterfacetoPHOTOS by  doxygen 1.6.3