FlyoDoc_2011 Pisa 2011 by GmP --- 011
|
00001 /*************************************************************************** 00002 * Copyright (C) 2005 by Giuseppe Pierazzini Pisa 20.02.05 * 00003 * pierazzini@unipi.it * 00004 * F l y o * 00005 * Epsi/NA48 * 00006 ***************************************************************************/ 00007 /* Authors G.Pierazzini - G.Ruggiero */ 00008 00009 #include "parm.h" 00010 #include "apparato.h" 00011 #include "gmatrix.h" 00012 #include "evento.h" 00013 #include "reazione.h" 00014 #include "clusgmp.h" 00015 00016 00017 using namespace GmpConst; 00018 00019 using namespace std; 00020 00021 int errordebug=-1; 00022 00023 HitClus Hitp[4]; 00024 00025 // DEFINITION OF CONSTANT VARIABLES 00026 00027 //const double TrgmpStraw::HIGHLEVEL = 5.; 00028 00030 // CONSTRUCTOR & DESTRUCTOR // 00032 TrgmpStraw::TrgmpStraw() 00033 { 00034 00035 ntrk=-1; 00036 ncls0=ncls1=ncls2=ncls3=0; 00037 00038 if (Mnp33!=0) z_centro_mag= Mnp33->Get_Centro().z; 00039 else {cout<<"\n Error... Mnp33 not defined ....exit "<<endl; 00040 Gout<<"\n Error... Mnp33 not defined ....exit "<<endl; 00041 exit(0);} 00042 00043 Gout<<"\n\n Class TrgmpStraw done with Z_mag "<< z_centro_mag; 00044 00045 00046 // Pointers to the cluster in each group of chamber 00047 pcl0=ChambClus[0]; 00048 pcl1=ChambClus[1]; 00049 pcl2=ChambClus[2]; 00050 pcl3=ChambClus[3]; 00051 } 00052 TrgmpStraw::~TrgmpStraw() 00053 {} 00054 00055 00056 00058 // MAKE TRACK // 00059 // NOTA 00061 void TrgmpStraw::Make_Trk() 00062 { 00063 00064 static int codemask[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; 00065 00066 int c0ok,c1ok,c2ok,c3ok, nchamb,nsingle; 00067 int c0flag[30],c1flag[30],c2flag[30],c3flag[30]; // flags to kill the used cluster 00068 for (int i=0;i<30;i++)c0flag[i]=c1flag[i]=c2flag[i]=c3flag[i]=1;// flags set 00069 00070 double chicut=3.; 00071 ntrk=-1; 00072 00073 00074 // Find the Cluster number in straw chambers.. 00075 00076 ncls0=ncls1=ncls2=ncls3=0; 00077 if ( pcl0!=0 ) ncls0=pcl0->nclust+1; 00078 if ( pcl1!=0 ) ncls1=pcl1->nclust+1; 00079 if ( pcl2!=0 ) ncls2=pcl2->nclust+1; 00080 if ( pcl3!=0 ) ncls3=pcl3->nclust+1; 00081 00082 00083 int maxcamere=0;// camere coinvolte. 00084 if (ncls0 >-1) maxcamere++; 00085 if (ncls1 >-1) maxcamere++; 00086 if (ncls2 >-1) maxcamere++; 00087 if (ncls3 >-1) maxcamere++; 00088 if (maxcamere <3) return; // minimum 3 chambers 00089 00090 int Single_esiste=pcl0->single_plans+pcl1->single_plans+pcl2->single_plans+pcl3->single_plans; 00091 00092 00093 for (int VisCam=maxcamere; VisCam>2;VisCam--) 00094 { 00095 for (nsingle=0;nsingle<VisCam-1;nsingle++) // single plan loop 00096 { 00097 if (Single_esiste==0&&nsingle>0) continue; 00098 00099 int Istart=0; 00100 if (VisCam <4)Istart=-1; 00101 00102 for ( int ic0=Istart;ic0<ncls0;ic0++) 00103 { 00104 c0ok=0; 00105 if (ic0>-1&&c0flag[ic0]>-1) 00106 { 00107 Hitp[0]= pcl0->Clus[ic0]; 00108 c0ok=1;// prima camera 00109 } 00110 00111 else Hitp[0].mask=Hitp[0].planes=0; 00112 00113 for ( int ic1=Istart;ic1<ncls1;ic1++) 00114 { 00115 c1ok=0; 00116 if (ic1>-1&&c1flag[ic1]>-1) { 00117 Hitp[1]= pcl1->Clus[ic1]; 00118 c1ok=2; // seconda camera 00119 00120 } 00121 else Hitp[1].mask=Hitp[1].planes=0; 00122 00123 00124 for ( int ic2=Istart;ic2<ncls2;ic2++) 00125 { 00126 c2ok=0; 00127 if (ic2>-1&&c2flag[ic2]>-1) { 00128 Hitp[2]= pcl2->Clus[ic2]; 00129 c2ok=4; // terza camera 00130 } 00131 else Hitp[2].mask=Hitp[2].planes=0; 00132 00133 for ( int ic3=Istart;ic3<ncls3;ic3++) 00134 { 00135 c3ok=0; 00136 if (ic3>-1&&c3flag[ic3]>-1) { 00137 Hitp[3]= pcl3->Clus[ic3]; 00138 c3ok=8; 00139 } 00140 else Hitp[3].mask=Hitp[3].planes=0; 00141 00143 short int mask_cam; 00144 mask_cam=c0ok+c1ok+c2ok+c3ok; 00145 nchamb=codemask[mask_cam]; 00146 if (nchamb!=VisCam) continue; // no enough active chamber 00147 00148 //verifica della configurazione per trattare i cluster con un piano 00149 TrkNow.used_plans=0; 00150 if (Single_esiste>0) 00151 if (Verify(mask_cam,nsingle)<0) continue; 00152 00153 // fitting data 00154 00155 // double chiq= Fitting(mask_cam,Hitp); 00156 00157 double chiq= Fitting(mask_cam); 00158 00159 if (Eventi_Fatti==errordebug) 00160 Gout<<"\n Ev "<< Eventi_Fatti <<" chiq "<<chiq 00161 <<" camere "<< VisCam 00162 <<" Single_esite "<<Single_esiste <<" Single "<<nsingle 00163 00164 <<" msk "<< Hitp[0].mask <<" "<< Hitp[1].mask <<" "<< Hitp[2].mask <<" "<< Hitp[3].mask 00165 <<" Ic.. "<<ic0<<" "<<ic1 <<" "<<ic2 <<" "<<ic3<<flush; 00166 00167 00168 //save track 00169 if (chiq>-0.001&&chiq<chicut) 00170 { 00171 ntrk++; 00172 // save traccia 00173 00174 Traccia[ntrk]=TrkNow; 00175 Traccia[ntrk].id=ntrk; 00176 Traccia[ntrk].camere=nchamb; 00177 Traccia[ntrk].single=nsingle; 00178 Traccia[ntrk].ic0=ic0; 00179 Traccia[ntrk].ic1=ic1; 00180 Traccia[ntrk].ic2=ic2; 00181 Traccia[ntrk].ic3=ic3; 00182 if (ic0>-1) { 00183 c0flag[ic0]=-1; 00184 c0ok=0; 00185 } 00186 if (ic1>-1) { 00187 c1flag[ic1]=-1; 00188 c1ok=0; 00189 } 00190 if (ic2>-1) { 00191 c2flag[ic2]=-1; 00192 c2ok=0; 00193 } 00194 if (ic3>-1) { 00195 c3flag[ic3]=-1; 00196 c3ok=0; 00197 } 00198 } 00199 } 00200 } 00201 } 00202 } 00203 } 00204 } 00205 00206 00207 charge_all=0; 00208 00209 for (int i=0;i<ntrk+1;i++) 00210 { 00211 charge_all+=Traccia[i].charge; 00212 00213 // Traccia[i].Print_Trk(); 00214 00215 } 00216 00217 Track2Root(); 00218 00219 00220 } 00221 00222 //===================================================================== 00223 //================================F I T T I N G ======================= 00224 00225 double TrgmpStraw::Fitting(short int mask_cam) //,HitClus *//Hitp) 00226 { 00227 00228 // Gout<<"\n\n Ev "<< Eventi_Fatti<<" Fitting mask " << mask; 00229 00230 int uno=0; 00231 double z_zmg[4]; 00232 double pcam=0; 00233 unsigned short mskc=1; 00234 00235 gmatrix F(8,5),Y(8,1); 00236 00237 00238 for (int icm=0;icm<4;icm++) 00239 { 00240 if ( (mask_cam&mskc)>0) { // la camera esiste... 00241 pcam++; 00242 int idc=icm*2; 00243 double dzmg=Hitp[icm].Xcls.z-z_centro_mag; 00244 z_zmg[icm]=dzmg; 00245 int piani=Hitp[icm].planes; 00246 00247 // code to fill F and Y when there is more than 1 plan 00248 if (piani>1) { 00249 dzmg=Hitp[icm].Xcls.z-z_centro_mag; 00250 Y(idc,0) =Hitp[icm].Xcls.x; 00251 Y(idc+1,0)=Hitp[icm].Xcls.y; 00252 F(idc,2)=F(idc+1,0)=1.; 00253 00254 if (icm<2) { 00255 F(idc,3)=F(idc+1,1)=dzmg; 00256 } 00257 else { 00258 F(idc,4)=F(idc+1,1)=dzmg; 00259 00260 } 00261 } 00262 00263 // code to fill F and Y when there is only one plan 00264 else 00265 { 00266 short int mask_plan=Hitp[icm].mask; 00267 double cosa=1.,sena=0.; 00268 uno++; 00269 00270 00271 if (mask_plan&1) { 00272 cosa=SINCOS45; 00273 sena=SINCOS45; 00274 } 00275 else if (mask_plan&2) { 00276 cosa=SINCOS45; 00277 sena=-SINCOS45; 00278 } 00279 else if (mask_plan&4) { 00280 cosa=1.; 00281 sena=0.; 00282 } 00283 else if (mask_plan&8) { 00284 cosa=0.; 00285 sena=-1.; 00286 } 00287 F(idc,0)=sena; 00288 F(idc,1)=dzmg*sena; 00289 F(idc,2)=cosa; 00290 if (icm<2)F(idc,3)=dzmg*cosa; 00291 else F(idc,4)=dzmg*cosa; 00292 Y(idc,0) =Hitp[icm].Filo+Hitp[icm].Centro.x*SINCOS45 ; 00293 } 00294 } 00295 mskc*=2; 00296 00297 } 00298 // F and Y matrix done 00299 00300 if (pcam<3.0) return -1.0; // at least tree chambers... 00301 00302 //=============== calcolo dei Y-values 00303 00304 gmatrix M(5,5), Noto(5,1), X(5,1); 00305 00306 // debug ===== 00307 00308 if (Eventi_Fatti==errordebug) 00309 { 00310 Gout<<"\n Fitting Ev "<<Eventi_Fatti<<" mask_cam "<<mask_cam 00311 <<" msk "<< Hitp[0].mask <<" "<< Hitp[1].mask <<" "<< Hitp[2].mask <<" "<< Hitp[3].mask; 00312 F.Print("F"); 00313 Y.Print("Y"); 00314 } 00315 // end debug ===== 00316 00317 M=(~F)*F; 00318 M.Det(); 00319 if (Eventi_Fatti==errordebug) M.Print("M");// debug ===== 00320 00321 if (fabs(M.detrm)<100000.) { 00322 Gout<<"\n Fitting mtx ERROR Ev Deteminante nullo!!!! "<<Eventi_Fatti<<" mask_cam "<<mask_cam 00323 <<" msk "<< Hitp[0].mask <<" "<< Hitp[1].mask <<" "<< Hitp[2].mask <<" "<< Hitp[3].mask; 00324 return -50; 00325 } 00326 00327 Noto=(~F)*Y; 00328 X= (!M)*Noto; 00329 00330 //====== get the X-parameters by name 00331 double ymg,tgyz,xmg,tgxz_before,tgxz_after; 00332 ymg =X(0,0); // at magnet 00333 xmg =X(2,0); // at magnet 00334 tgyz =X(1,0); 00335 tgxz_before=X(3,0); 00336 tgxz_after =X(4,0); 00337 // 00338 double chiq=0; 00339 gmatrix DY(8,1),sumq(1,1); 00340 00341 DY=Y-(F*X); 00342 sumq= (~DY)*DY; 00343 chiq=sumq(0,0); 00344 00345 // debug ===== 00346 if (Eventi_Fatti==errordebug) { 00347 Y.Print("Y"); 00348 DY.Print("DY"); 00349 Gout<<"\n Ev "<<Eventi_Fatti<<" chiq "<<chiq; 00350 } 00351 // end debug ===== 00352 00353 00354 if (pcam==4.0&&chiq> 1.) return -2.; 00355 if (pcam==3.0&&chiq> 0.7) return -3.; 00356 00357 // test di convergenza in y verso la zona di decadimento 00358 double zby_y= z_centro_mag-ymg/tgyz; 00359 if (zby_y<9000.||zby_y>18700.)return -10; 00360 00361 // test di convergenza in x verso la zona di decadimento 00362 00363 double xb=0.0,zb=10000.; // il beam passa per x =0 a z=10000 00364 double tgxb=-0.00124; // inclinazione del beam (nota negativo) 00365 double zby_x= ((xmg-xb)-tgxz_before*z_centro_mag +tgxb*zb)/(tgxb-tgxz_before); 00366 // if (uno>0)Gout<<"\n Zby_x "<<zby_x<<" chiq "<<chiqy; 00367 if (zby_x<9000.||zby_x>18700.)return -11; 00368 00369 00370 // ==================== calcolo del momento =========== 00371 gvet Versor_in(tgxz_before,tgyz,1.); 00372 Versor_in=Versor_in.NVerso(); 00373 double cdip=sqrt(Versor_in.x*Versor_in.x+Versor_in.z*Versor_in.z); 00374 double kik=Mnp33->Get_Kik(); 00375 double pinc= (kik/ (atan(tgxz_after)-atan(tgxz_before )) )/cdip; 00376 double charge=1.; 00377 if (pinc<0.0)charge=-1.; 00378 00379 00380 // Gout<<"\nEv fit "<<Eventi_Fatti<<" parms "<<ymg<<" "<<tgyz<<" "<<xmg<<" " <<tgxz_before<<" " <<tgxz_after; 00381 00382 // define ============ TrkNow ==================== 00383 pinc=abs(pinc); 00384 00385 TrkNow.mask=mask_cam; 00386 00387 TrkNow.msk0= Hitp[0].mask; 00388 TrkNow.msk1= Hitp[1].mask; 00389 TrkNow.msk2= Hitp[2].mask; 00390 TrkNow.msk3= Hitp[3].mask; 00391 TrkNow.zby_y=zby_y; 00392 TrkNow.zby_x=zby_x; 00393 TrkNow.chiq_fit= chiq; 00394 TrkNow.Xmg.setv(xmg,ymg,z_centro_mag); 00395 TrkNow.P_in=Versor_in*pinc; 00396 gvet Versor_out(tgxz_after,tgyz,1.); 00397 Versor_out=Versor_out.NVerso(); 00398 TrkNow.P_out=Versor_out*pinc; 00399 TrkNow.charge=charge; 00400 00401 // estrapolazione traccia all'odoscopio X 00402 double dkam= (hodox->Get_Cface().z-z_centro_mag)/Versor_out.z; 00403 TrkNow.Xhodx=TrkNow.Xmg+dkam*Versor_out; 00404 00405 // estrapolazione traccia al calorimetro 00406 double dlkr= (lkry->Get_Cface().z-z_centro_mag)/Versor_out.z; 00407 TrkNow.Xlkr=TrkNow.Xmg+dlkr*Versor_out; 00408 00409 00410 00411 00412 00413 return chiq; // return chiq; 00414 } 00415 //==================================================================================== 00416 00417 int TrgmpStraw::Verify(short int mask_cam,int single) 00418 00419 { 00420 00421 //test the number of single plans accepted 00422 // for 4 active chambers we accept up to two different single planes but both two == to Y (8) 00423 // for 3 active chambers we accept up to two different single planes but not == to Y (8) 00424 00425 unsigned short mskc=1; 00426 unsigned short msklast=0; 00427 unsigned short mskplan=0; 00428 TrkNow.used_plans=0; 00429 int singlepiani=0; 00430 for (int icm=0;icm<4;icm++) 00431 { 00432 if ( (mask_cam&mskc)>0) { // la camera esiste... 00433 short int mskpl= Hitp[icm].mask; 00434 if (single==1&&mskpl==8) return -1; // the y plan is not usefull in only trhee plans 00435 if (mskpl==1||mskpl==2||mskpl==4||mskpl==8) 00436 { 00437 if (msklast==8 && mskpl==8) return -1; 00438 singlepiani++; 00439 msklast=mskpl; 00440 mskplan=(mskplan|mskpl); 00441 } 00442 if (singlepiani>single) return -1; 00443 } 00444 mskc*=2; 00445 } 00446 TrkNow.used_plans=mskplan; 00447 00448 // if (single==0&&msklast!=0) return -1; 00449 00450 return 1; 00451 00452 } 00453 00454 00455 00456 //================= 00457 void Track::Print_Trk() 00458 { 00459 Gout<<"\nEv "<<Eventi_Fatti<<" id "<<id<<" ch "<<charge<<" msk "<<mask<<" cam "<<camere<<" SINGL "<<single 00460 <<" msk: "<<msk0<<" "<<msk1<<" "<<msk2<<" "<<msk3 00461 <<" chiq "<<chiq_fit; 00462 Xmg.print("Xmg"); 00463 Gout<<" Ic.. "<<ic0<<" "<<ic1 <<" "<<ic2 <<" "<<ic3 ; 00464 P_in.print("P_in"); 00465 P_out.print("P_out"); 00466 Gout<<" Kik "<<(P_out-P_in).px; 00467 00468 } 00469 // ================ 00470 00471 void TrgmpStraw::Track2Root() 00472 { 00473 //int ntrk,mask[MAXTRACK],camere[MAXTRACK],ic0[MAXTRACK],ic1[MAXTRACK],ic2[MAXTRACK],ic3[MAXTRACK]; 00474 // float chiq[MAXTRACK], charge[MAXTRACK], xmg[MAXTRACK], ymg[MAXTRACK], px[MAXTRACK],py[MAXTRACK],pz[MAXTRACK]; 00475 ntrk_done=ntrk+1; 00476 00477 for (int i=0;i<ntrk_done;i++) 00478 { 00479 Trk2Root.id[i]= Traccia[i].id; 00480 Trk2Root.mask[i]= Traccia[i].mask; 00481 Trk2Root.camere[i]=Traccia[i].camere; 00482 Trk2Root.single[i]=Traccia[i].single; 00483 Trk2Root.usepl[i]=Traccia[i].used_plans; 00484 Trk2Root.ic0[i]= Traccia[i].ic0; 00485 Trk2Root.ic1[i]= Traccia[i].ic1; 00486 Trk2Root.ic2[i]= Traccia[i].ic2; 00487 Trk2Root.ic3[i]= Traccia[i].ic3; 00488 Trk2Root.zbyy[i]= Traccia[i].zby_y; 00489 Trk2Root.zbyx[i]= Traccia[i].zby_x; 00490 Trk2Root.chiq[i]= Traccia[i].chiq_fit; 00491 Trk2Root.charge[i]=Traccia[i].charge; 00492 Trk2Root.xmg[i]= Traccia[i].Xmg.x; 00493 Trk2Root.ymg[i]= Traccia[i].Xmg.y; 00494 Trk2Root.p[i]= Traccia[i].P_in.mom; 00495 Trk2Root.py[i]= Traccia[i].P_in.py; 00496 Trk2Root.pxin[i]= Traccia[i].P_in.px; 00497 Trk2Root.pzin[i]= Traccia[i].P_in.pz; 00498 Trk2Root.pxout[i]= Traccia[i].P_out.px; 00499 Trk2Root.pzout[i]= Traccia[i].P_out.pz; 00500 Trk2Root.xhodx[i]= Traccia[i].Xhodx.x; 00501 Trk2Root.yhodx[i]= Traccia[i].Xhodx.y; 00502 Trk2Root.xlkr[i]= Traccia[i].Xlkr.x; 00503 Trk2Root.ylkr[i]= Traccia[i].Xlkr.y; 00504 00505 00506 00507 } 00508 00509 00510 } 00511 00512 00513 00514