FlyoDoc_2011 Pisa 2011 by GmP --- 011

flyopunta/src/src_ana/anak3pi.cpp

00001 /***************************************************************************
00002                           anak3pi.cpp  -  description
00003                              -------------------
00004     begin                : Sat Jan 18 2003
00005     copyright            : (C) 2003 by Giuseppe Pierazzini
00006     email                : peppe@unipi.it
00007   ***************************************************************************
00008   *                                                                         *
00009   *   NA48  simulation program.                                             *
00010   *                                                                         *
00011   ***************************************************************************/
00012 #define EPSR     1.0E-200
00013 #define MPIC   0.13956
00014 #define MPICQ  0.019477
00015 #define MASK   0.49367
00016 #define MASKQ  0.24371
00017 #define SS0    0.100714
00018 
00019 #include "flyoh.h"
00020 #include "anak3pi.h"
00021 
00022 #define MIN(x,y,z) ((x)<(y)?(x)<(z)?(x):(z):(y)<(z)?(y):(z))
00023 
00024 using namespace std;
00025 
00027 // if only for three tracks ==> one combination
00028 // but for more tarcks => combinations =  k*(k-1)*(k-2)/3! 
00029 
00030   static  int combine[20][3]=  
00031               { {0,1,2},{0,1,3},{0,2,3},{1,2,3},
00032                 {0,1,4},{0,2,4},{0,3,4},{1,2,4},
00033                 {1,3,4},{2,3,4},{0,1,5},{0,2,5},
00034                 {0,3,5},{0,4,5},{1,2,5},{1,3,5},
00035                 {1,4,5},{2,3,5},{2,4,5},{3,4,5}};
00036 // for n tracks  use the  combinations
00037 //     3                     1
00038 //     4                     1-4
00039 //     5                     1-10
00040 //     6                     1-20
00041 //-----------------------------------------------
00042 //-----------------------------------------------
00043 
00049    AnaK3pi::AnaK3pi()
00050    {
00051     tipo=4;nfit=3;titol="K--> 3 pio_ch";nome="K3pi";
00052     nd=np=0;
00053     maspi=.13956;
00054     Ird0=Ird1=Ird2=0;
00055     Icb0=Icb1=Icb2=0;
00056     Gout<<"\n Attivato il fit di "<<titol;
00057     if(Le_Tracce==0)
00058      {
00059        Gout<<"\n Error.. K3pi analisys ... Tracks non defined!"<<std::endl;  
00060        exit(0); 
00061      }
00062    }
00063    AnaK3pi::~AnaK3pi(){};
00064 
00065 //=============== C h a r g e   t r a c k   F i t ========
00066 int AnaK3pi::Fisica()
00067   {
00068 
00069 
00070   np=nd=0;
00071   np=Le_Tracce->Tot_trk+1; 
00072 //  Gout<<"\n Nhit: "<<np;
00073   if(np<3||np>6){np=0;getta_ch++;return(-1);}
00074   nd=3;
00075   carica=.0;
00076  // define the coupling number (1,4,10,20)
00077    int trial=1;
00078    if(np>3)trial=(np*(np-1)*(np-2))/6;
00079 
00080 
00082    chisq=300.;
00083    for (int i=0;i<trial;i++)
00084    {
00085     count_call++;
00086 // get track index 
00087    Icb0=combine[i][0];
00088    Icb1=combine[i][1];
00089    Icb2=combine[i][2];
00090    
00091   double etot= Tracc[Icb0]->Get_P()[3]+Tracc[Icb1]->Get_P()[3]+Tracc[Icb2]->Get_P()[3];
00092   
00093   if(etot<10. ){getta_en++;continue;}     //return -2;};
00094   carica=Tracc[Icb0]->charge+Tracc[Icb1]->charge+Tracc[Icb2]->charge;
00095   // get the index order...Ird0,Ird1 (same charge as above) Ird3 is the odd charge 
00096    if( carica!=1&&carica!=-1 ) {getta_char++;continue;}
00097 
00098   Ordina(); // ordina le tracce da essere (++-) o (--+)
00099 
00100   P1=Tracc[Ird0]->Get_Pc1();
00101   P2=Tracc[Ird1]->Get_Pc1();
00102   P3=Tracc[Ird2]->Get_Pc1();
00103   if(Vertice()<1){getta_fit++;continue;} //return -3;};
00104   if(chicomb<chisq)
00105     {chisq=chicomb;
00106      charge=carica;
00107      PVsave=PV;
00108      Isv0=Ird0; Isv1=Ird1;Isv2=Ird2;
00109     }
00110    }
00111   if(chisq>200.)return -3; // see Vertice()
00112 
00113   if(trial>1)   // get the saved values by the best fit for trial >1
00114     {Ird0=Isv0;Ird1=Isv1;Ird2=Isv2;
00115      P1=Tracc[Ird0]->Get_Pc1();
00116      P2=Tracc[Ird1]->Get_Pc1();
00117      P3=Tracc[Ird2]->Get_Pc1();
00118      PV=PVsave;
00119     }
00120 
00121 
00122   
00123   pmis[0]=Tracc[Ird0]->ptrk;
00124   pmis[1]=Tracc[Ird1]->ptrk;
00125   pmis[2]=Tracc[Ird2]->ptrk;
00126 
00127 // calcolo il cog at lkr
00128   Cog3p=(Tracc[Ird0]->Xlk*pmis[0]+Tracc[Ird1]->Xlk*pmis[1] +Tracc[Ird2]->Xlk*pmis[2]);
00129   Cog3p/=(pmis[0]+pmis[1]+pmis[2]);
00130   kcog  = Cog3p.XYNorma();
00131   cogm1x=Cog3p[0];
00132   cogm1y=Cog3p[1];     
00133   cogm1 =kcog;
00134   PV.putv(vx,vy,vz);
00135             
00136   V1= P1-PV; V1.Norma();V1=V1.Verso()*pmis[0];
00137   V2= P2-PV; V2.Norma();V2=V2.Verso()*pmis[1];
00138   V3= P3-PV; V3.Norma();V3=V3.Verso()*pmis[2];
00139   
00140 // calcolo della massa invariante
00141   Q1.setvn(V1,maspi);
00142   Q2.setvn(V2,maspi);
00143   Q3.setvn(V3,maspi);
00144   QT=Q1+Q2+Q3;
00145   mkmis=QT.Invar();
00146   pkmis=QT.norma;
00147 
00148   ptksq=(QT&PV).Norma()/PV.norma;        
00149 // Calcolo dei parametri s1,s2,s3,su..
00150 // con rinomalizzazione della massa invariante a quella del k  !!
00151 //
00152 // qvet QC = dQT/dcorr  quadrivettore derivato rispetti alla correzione
00153  
00154    QC.setqn(V1+V2+V3,  Q1.normaq/Q1.e+Q2.normaq/Q2.e+Q3.normaq/Q3.e);
00155 //   QC.print("QC");
00156    double corr=1.- (QT.m-MASK)*QT.m/(QC*QT);  
00157 // Gout<<"\n Correzione = %12.7lf  %12.5lf ",corr,QT*QC);   
00158    Q1.setvn(V1*corr,maspi);
00159    Q2.setvn(V2*corr,maspi);
00160    Q3.setvn(V3*corr,maspi);
00161    QT=Q1+Q2+Q3;  QT.Invar();
00162 //   QT.print("QTcorr");
00163   fi3=atan2(Q3[1],Q3[0]);
00164 
00165   ss[0]=(QT-Q1).Invarq();
00166   ss[1]=(QT-Q2).Invarq();
00167   ss[2]=(QT-Q3).Invarq();   
00168   su = (ss[2]-SS0)/MPICQ;  // u
00169   sv = 0.433013*(ss[1]-ss[0])/MPICQ;  // v  
00170   count_wnt++;
00171   return(1);
00172 
00173 }
00174 
00175 //======================================================================================
00176  int AnaK3pi::Vertice()
00177    {
00178 // calcola il vertice ed il chiq relativo
00179 //     gvet P1,P2,P3,V1,V2,V3;
00180 //     gvet Noto,PV;
00181      
00182      V1= Tracc[Ird0]->Get_Pc2()-P1; V1.Norma();V1=V1.Verso();
00183      V2= Tracc[Ird1]->Get_Pc2()-P2; V2.Norma();V2=V2.Verso();
00184      V3= Tracc[Ird2]->Get_Pc2()-P3; V3.Norma();V3=V3.Verso();
00185      Noto=P1+P2+P3;
00186      Noto-=(V1*(V1%P1)+V2*(V2%P2)+V3*(V3%P3));
00187 //     Noto.print("Noto");
00188 
00189 // matrice righe MV1,MV2,MV3
00190      gvet MV1(3.,0.,0.), MV2(0.,3.,0.),MV3(0.,0.,3.);
00191      MV1-=V1*V1[0] + V2*V2[0] + V3*V3[0];
00192      MV2-=V1*V1[1] + V2*V2[1] + V3*V3[1];
00193      MV3-=V1*V1[2] + V2*V2[2] + V3*V3[2];
00194 
00195 //     gvet VM1,VM2,VM3;    //righe della matrice inversa
00196      VM1= MV2&MV3;        // nota: prodotto vettoriale
00197      double det = MV1%VM1; // determinante
00198      VM1= VM1/det;
00199      VM2= (MV3&MV1)/det;
00200      VM3= (MV1&MV2)/det;
00201      PV.setvn(VM1%Noto,VM2%Noto,VM3%Noto);  // vertice
00202 //calcolo il chiq
00203 // nota:  definizione del chiq
00204 //   chiq = somma distanze quadrate del vertice dalle rette.
00205 //   per normalizzare , ciascuna distamza va divisa per il suo
00206 //   errore. qui non si normalizza..
00207 //   Ricordo comunque che l'errore deriva dagli errori nelle camere 1 e 2
00208 //   quindi sul punto nella camera 1 e nel calcolo del versore di ciascuna
00209 //   retta che dipende dai punti nelle due camere. Prendo gli errori x e y nelle
00210 //   camere tutti uguali, segue:
00211 //    Err=  Sgma*(sqrt( (1+dz/dc)**2 + (dz/dc)**2)   con dz distanza del
00212 //   vertice dalla camera 1(~90 mt) e dc distanza tra le camere 1 e 2 (~11 mt ).
00213 //    approssimativamente   err=sigm*8.2*sqrt(2)
00214 //    con un errore nelle camere di 0.012 cm  ==> err= 0.14 cm
00215 
00216 //     gvet DP1,DP2,DP3;
00217      DP1=PV-P1,DP2=PV-P2,DP3=PV-P3;
00218      double t1=V1%DP1, t2=V2%DP2, t3=V3%DP3;
00219      DP1-=V1*t1; DP2-=V2*t2; DP3-=V3*t3;
00220      DP1.Norma(); DP2.Norma(); DP3.Norma();
00221      chicomb= DP1.normaq + DP2.normaq+ DP3.normaq;
00222 
00223      if(Debugon==1) {
00224      PV.print("Vert");
00225      Gout<<"\n Vertice chiq = "<<chisq<<std::endl;
00226      }
00227      /*     PV.setv(cam2->mx[icp]-cam1->mx[icp],
00228                  cam2->my[icp]-cam1->my[icp],
00229                  cam2->mz[icp]-cam1->mz[icp]);
00230                  */
00231    
00232      if(chicomb>200.)return -3;
00233      return 1;
00234    }
00235 
00236  //----------------------------------------------------
00237    void AnaK3pi::print_scale()
00238     {
00239      Gout<<"\n -----> "<<titol<<" Analysis Summary <-------\n";
00240      Gout<<"\n Fit entries          "<<count_call;
00241      Gout<<"\n Tracks <3 or >6      "<<getta_ch;
00242      Gout<<"\n Wrong charge         "<<getta_char;
00243      Gout<<"\n Killed by energy     "<<getta_en;
00244      Gout<<"\n No good vertex       "<<getta_fit;
00245      Gout<<"\n Good events          "<<count_wnt;
00246      Gout<<"\n\n ======>           d o n e     <============ "<<std::endl;
00247     }
00248 //-------------------------------------------
00249   void AnaK3pi::Ordina()
00250   {
00251    Ird0=Icb0; Ird1=Icb1; Ird2=Icb2;
00252    if(Tracc[Icb0]->charge!=charge) {Ird0=Icb2; Ird1=Icb1; Ird2=Icb0;}
00253    else if(Tracc[Icb1]->charge!=charge) {Ird0=Icb0; Ird1=Icb2; Ird2=Icb1;}
00254    
00255   }
 All Classes Namespaces Files Functions Variables