StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
EEsoloPi0.cxx
1 // $Id: EEsoloPi0.cxx,v 1.11 2009/02/04 20:33:21 ogrebeny Exp $
2 
3 #include <assert.h>
4 #include <stdlib.h>
5 
6 
7 #include <TClonesArray.h>
8 #include <TVector3.h>
9 #include <TObjArray.h>
10 #include <TH1.h>
11 #include <TH2.h>
12 
13 #include "EEsoloPi0.h"
14 
15 #include "StEEmcUtil/EEfeeRaw/EEfeeRawEvent.h"
16 #include "StEEmcUtil/EEfeeRaw/EEstarTrig.h"
17 #include "StEEmcUtil/EEfeeRaw/EEmcEventHeader.h"
18 
19 #include "StEEmcUtil/EEfeeRaw/EEfeeDataBlock.h"
20 #include "StEEmcUtil/EEfeeRaw/EEname2Index.h"
21 
22 #include "StEEmcUtil/database/EEmcDbItem.h"
23 
24 
25 #ifdef StRootFREE
26  #include "EEmcDb/EEmcDb.h"
27 #else
28  #include "StEEmcUtil/database/StEEmcDb.h"
29 #endif
30 
31 
32 #include "StEEmcUtil/EEmcGeom/EEmcGeomSimple.h"
33 
34 ClassImp(EEsoloPi0)
35 //--------------------------------------------------
36 //--------------------------------------------------
38 
39  nInpEve=0;
40  HList=0;
41  eeDb=0;
42  dbMapped=-1;
43 
44  geom= new EEmcGeomSimple();
45  set(0,0,0);
46  printf("EEsoloPi0() constructed\n");
47  nClust=0;
48 
49  float XscaleFactor=1;
50  float XseedEnergy=0.8;
51  float XshapeLimit=.7;
52  float XmassLo=0.07, XmassHi=0.22;
53  set(XscaleFactor, XseedEnergy,XshapeLimit,XmassLo,XmassHi);
54  memset(hA,0, sizeof(hA));
55  memset(hR,0, sizeof(hR));
56  memset(hM,0, sizeof(hM));
57 
58 }
59 
60 //--------------------------------------------------
61 //--------------------------------------------------
62 EEsoloPi0::~EEsoloPi0() {/* noop */}
63 
64 //-------------------------------------------------
65 //-------------------------------------------------
66 void EEsoloPi0::initRun(int runID){
67  printf(" EEsoloPi0::initRun(%d)\n",runID);
68 
69  assert(dbMapped<0); // at the moment DB reloading is not implemented/tested,JB
70  dbMapped=runID;
71 }
72 
73 //-------------------------------------------------
74 //-------------------------------------------------
75 //-------------------------------------------------
76 void EEsoloPi0::init(){
77  int i;
78  float Emax=20;
79  TString C="";
80 
81  hA[0]=new TH1F ("tE","Eneregy (GeV) from any tower",100,0.,Emax);
82  hA[1]=new TH1F ("sE","Total Eneregy in event (GeV) (sum from all tower)",100,0.,Emax*24);
83 
84  hA[2]=new TH1F ("cE","cluster Eneregy (GeV) ",200,0.,1.5*Emax);
85 
86  hA[3]=new TH1F ("cSh","Shape: energy ratio highT/cluster",55,0.,1.1);
87  hA[4]=new TH1F ("cN","No. of clusters per event",30,-0.5,29.5);
88  hA[5]=new TH1F ("tT","Transverse Eneregy (GeV) from any tower",100,0.,Emax);
89  hA[6]=0;
90  hA[7]=new TH1F ("ctbSum","CTB ADC sum", 240,0,12000);
91 
92  if(HList) {
93  for(i=0;i<=14;i++) {
94  if(hA[i]==0) continue;
95  HList->Add(hA[i]);
96  }
97  }
98 
99  // Mix/noMix histos
100  hR[0]=0;
101 
102  hR[1]=new TH1F ("invm","Invariant mass of 2 gammas (GeV)",80,0.,1.2);
103 
104  hR[2]=(TH1F*)new TH2F ("d-E","Distance (cm) vs. 2clust energy (GeV)",50,0,1.5*Emax,100,0.,100);
105  hR[3]=(TH1F*)new TH2F ("eta12","eta1 vs. eta2 (bins)",12,0.5,12.5,12,0.5,12.5);
106 
107  hR[4]=(TH1F*)new TH2F ("xyL","Y vs. X (cm) of LOW energy cluster",200,-250.,250,200,-250,250);
108  hR[5]=(TH1F*)new TH2F ("xyH","Y vs. X (cm) of HIGH energy cluster",200,-250.,250,200,-250,250);
109  hR[6]=new TH1F ("oAng","Opening angle/rad of any pair",30,0.,.3);
110 
111 
112  char ttt[100];
113  sprintf(ttt,"cut invM=[%.2f,%.2f]",mLo,mHi);
114  hR[7]=new TH1F ("0ener","Energy (GeV), "+C+ttt,50,0.,Emax/2.);
115  hR[8]=new TH1F ("0eta","Pseudorapidity, "+C+ttt,25,0.,2.5);
116  hR[9]=new TH1F ("0phi","phi/rad, "+C+ttt,30,-3.14,3.14);
117  hR[10]=new TH1F ("0pt","pT (GeV/c), "+C+ttt,50,0.,Emax/4.);
118  hR[11]=(TH1F*)new TH2F ("0xyL","Y vs. X (cm) of LOW energy, "+C+ttt,200,-250.,250,200,-250,250);
119  hR[12]=(TH1F*)new TH2F ("0xyH","Y vs. X (cm) of HIGH energy, "+C+ttt,200,-250.,250,200,-250,250);
120 
121  hR[13]=new TH1F ("ytw","Yield of clusters ;X= iphi+(Eta-1)*60, spiral",721,-.5,720.5);
122 
123  hR[14]=new TH1F ("0ytw","Yield of clusters, "+C+ttt+";X= iphi+(Eta-1)*60, spiral",721,-.5,720.5);
124 
125  hR[15]=(TH1F*)new TH2F ("0d-E","Distance (cm) vs. 2clust energy (GeV), "+C+ttt,50,0,Emax,100,0.,100);
126 
127 
128  hR[24]=new TH1F ("0Ang","Opening angle/rad of pairs "+C+ttt,50,0.,.7);
129  hR[25]=(TH1F*)new TH2F ("invH","Time (minutes) vs. Invariant mass of 2 gammas (GeV)",75,0.,1.5,50,0,100);
130  hR[26]=new TH1F ("0Z","Z=|E1-E2|/sum ,"+C+ttt,25,0.,1.0);
131 
132 
133  for(i=0;i<12;i++) {
134  char t1[100],t2[100];
135  sprintf(t1,"invm%02d",i+1);
136  sprintf(t2,"Invariant mass(GeV), ETA=%d",i+1);
137  hR[27+i]=new TH1F (t1,t2,80,0.,1.2);
138  }
139 
140  for(i=0;i<=38;i++) {
141  TH1F *h1=hR[i];
142  if(h1==0) continue;
143  TH1F *h2=(TH1F *)h1->Clone();
144  TString tt=h2->GetTitle();
145  h2->SetTitle( "MIX: "+tt);
146  tt=h2->GetName();
147  h2->SetName( "X"+tt);
148  h2->SetLineColor(kGreen);
149  hM[i]=h2;
150  if(HList) {
151  HList->Add(h1);
152  HList->Add(h2);
153  }
154  }
155 
156 
157  printf("\nEEsoloPi0::init(), cuts: scaleFactor=%f ch/GeV, seedEnergy=%f GeV ,shapeLimit=%f, mLo=%.2f GeV, mHi=%.2f GeV\n\n",scaleFactor, seedEnergy,shapeLimit,mLo, mHi);
158 
159  // HList->ls();
160 
161 
162  oldClust.eH=0.5;
163  oldClust.eC=0.6;
164  oldClust.k1=1;
165  oldClust.fphi=1.;
166  oldClust.feta=1.;
167 
168 
169  clear();
170  TotN2g=totPi0=totXPi0=0;
171 
172 }
173 
174 //-------------------------------------------------
175 //-------------------------------------------------
176 void EEsoloPi0::clear(){
177  if( nClust>1) {// preserve a random cluster from previous event
178  int j=rand()%nClust;
179  oldClust=clust[j];
180  }
181  memset(soloMip,0,sizeof(soloMip));
182  memset(clust,0,sizeof(clust));
183  nClust=0;
184 
185 }
186 
187 //-------------------------------------------------
188 //-------------------------------------------------
189 //-------------------------------------------------
190 void EEsoloPi0::finish(){
191  float s1=totPi0;
192  float s2=totXPi0;
193  if(s1==0) s1=-1;
194  if(s2==0) s2=-1;
195  float x=s1-s2;
196  float ex=sqrt(s1+s2);
197  printf("s1=%f s2=%f\n",s1,s2);
198  float s2b=x/s2; // signal to background
199  //error calculated assuming s1 & s2 are independent
200  float es2b=s2b*sqrt(1/s1+1/s2);
201 
202  printf("\n EEsoloPi0::finish() TotN2g=%d, totPi0=%d totXPi0=%d \n",TotN2g,totPi0,totXPi0);
203  printf(" Npi0=%.0f + / - %.0f , s2b=%.2f + / - %.3f for invm=[%.2f, %.2f]\n\n", x,ex,s2b,es2b,mLo,mHi);
204 
205 
206 }
207 
208 //-------------------------------------------------
209 //-------------------------------------------------
210 //-------------------------------------------------
211 void EEsoloPi0::print(){
212  printf("\n EEsoloPi0::print()\n soloMip dump:\n");
213  int k0;
214  for(k0=0;k0<MxTw;k0++) {
215  if(soloMip[k0].e<=0) continue;
216  // if(soloMip[k0].key<=0) continue;
217  int ieta=k0%12;
218  int iphi=k0/12;
219  printf("ieta=%d iphi=%d key=%d e=%f id=%d\n",ieta,iphi,soloMip[k0].key,soloMip[k0].e,soloMip[k0].id);
220  }
221 
222  printf("Clusters found:\nid k1 feta fphi eneTot\n");
223  int ic;
224  for(ic=0;ic<nClust;ic++) {
225  printf("%d %d %.2f %.2f %5g\n",ic+1, clust[ic].k1,clust[ic].feta,clust[ic].fphi,clust[ic].eC);
226  }
227 }
228 
229 //---------------------------------------------------
230 //---------------------------------------------------
231 int EEsoloPi0:: findTowerClust() {
232  assert(seedEnergy>0); // makes no sense to set it lower
233  //..... some histos
234  int k;
235  float totEner=0;
236  for(k=0;k<MxTw;k++) {
237  float ene=soloMip[k].e;
238  if(ene<=0) continue;
239  // printf("irad=%d, e=%f\n",k,soloMip[k].e);
240  hA[0]->Fill(ene);
241  totEner+=ene;
242  }
243  hA[1]->Fill(totEner);
244 
245  //............ search for hight towers
246  while(1) {
247  float maxE=seedEnergy;
248  int k0,k1=-1;
249  for(k0=0;k0<MxTw;k0++) {
250  if(soloMip[k0].e<maxE) continue;
251  if(soloMip[k0].key>0) continue; // droped marked towers
252  k1=k0;
253  maxE=soloMip[k0].e;
254  }
255  if(k1<0) break; // no cluster found
256  // printf("iCl=%d, irad=%d energy=%f\n",nClust,k1,soloMip[k1].e);
257  clust[nClust].k1=k1;
258  clust[nClust].eH=soloMip[k1].e;
259  nClust++;
260  soloMip[k1].id=nClust;
261  tagCluster(k1);
262  }
263  //printf("nClust=%d\n",nClust);
264  //if(nClust<2) return ;
265 
266  //............ sum energy of clusters, find centroid
267  Cluster clustG[MxTw]; // Good cluster storage
268  int nClustG=0;
269  int ic;
270  for(ic=0;ic<nClust;ic++) {
271  sumTwClusterEnergy(ic);
272  float rat=clust[ic].eH/clust[ic].eC;
273  // printf(" sum energy ic=%d eH=%f eC=%f rat=%f\n",ic,clust[ic].eH,clust[ic].eC,rat);
274  if(rat<shapeLimit) continue;
275  hA[2]->Fill(clust[ic].eC);
276  hA[3]->Fill(rat);
277  clustG[nClustG++]=clust[ic];
278  }
279 
280  // printf(" nClustG=%d\n",nClustG);
281 
282  //..... copy only good clusters
283  for(ic=0;ic<nClustG;ic++) {
284  //printf("copyG ic=%d k1=%d, eC=%f feta=%f fphi=%f\n",ic, clustG[ic].k1,clustG[ic].eC,clustG[ic].feta,clustG[ic].fphi);
285  clust[ic]=clustG[ic];
286  }
287  nClust=nClustG;
288 
289  hA[4]->Fill(nClust);
290  //printf("doneE nCl=%d %f %d\n",nClust,clust[0].eC,clust[0].k1);
291  return nClust;
292 }
293 
294 
295 
296 //---------------------------------------------------
297 //---------------------------------------------------
298 void EEsoloPi0::findTowerPi0() {
299  if(nClust<2) return ;
300 
301  //.................. scan pairs of clusters
302  int i,j;
303  for(i=0;i<nClust;i++)
304  for(j=i+1;j<nClust;j++) {
305 
306  Cluster *cl1=&clust[i];
307  Cluster *cl2=&clust[j];
308 
309  totPi0+=findInvM(cl1,cl2,hR);
310 
311 
312  // mix event pair
313  if(rand()%2)
314  cl1=&oldClust;
315  else
316  cl2=&oldClust;
317 
318  //
319  // The pi0 finder cannot identify pi0's when the
320  // seed towers of the two clusters are adjacent.
321  // We therefore require the two mixed clusters
322  // to be separated in eta and/or phi by at least
323  // one 1.4 towers... (JB)
324  //
325 
326  float a=cl1->feta - cl2->feta;
327  float b=cl1->fphi - cl2->fphi;
328  // trick to accomodate cyclic phi
329  // fphi1, fphi2 are in [0,MxTwPhi);
330  // 'b' measures the opening angle in phi
331  if(b<0) b+=MxTwPhi;
332  if(b>MxTwPhi/2.) b=MxTwPhi-b;
333  if(sqrt(a*a+b*b) <sqrt(2.) )continue;
334 
335  totXPi0+=findInvM(cl1,cl2,hM);
336 
337  }
338 
339 
340 }
341 
342 
343 
344 //---------------------------------------------------
345 //---------------------------------------------------
346 void EEsoloPi0:: tagCluster(int k0,int d){
347 
348  int ieta=k0%12;
349  int iphi=k0/12;
350 
351  int i,j;
352  float ener=soloMip[ ieta + MxTwEta*iphi ].e;
353  for(i=ieta-d; i<=ieta+d;i++){
354  // printf("try ieta=%d \n",i);
355  if( i>=MxTwEta || i<0) continue;
356  for(j=iphi-d;j<=iphi+d;j++){
357  int jj=j;
358  if( jj<0 ) jj+=MxTwPhi;
359  if( jj>=MxTwPhi ) jj-=MxTwPhi;
360  assert( jj>=0 && jj<MxTwPhi );
361  soloMip[ i + MxTwEta*jj ].key+=(int)(1000*ener);
362  // printf("tag iphi=%d ieta=%d key=%d\n",j,i, soloMip[ i + MxTwEta*j ].key);
363  }
364  }
365 }
366 
367 //---------------------------------------------------
368 //---------------------------------------------------
369 void EEsoloPi0:: sumTwClusterEnergy(int ic,int d){
370 
371  int k0=clust[ic].k1;
372  int ieta=k0%12;
373  int iphi=k0/12;
374 
375  int i,j;
376  float w0=soloMip[ieta + MxTwEta*iphi].key;
377  double sum=0, sumi=0, sumj=0;
378  for(i=ieta-d; i<=ieta+d;i++){
379  if( i>=MxTwEta || i<0) continue;
380  for(j=iphi-d;j<=iphi+d;j++){
381  int jj=j;
382  if( jj<0 ) jj+=MxTwPhi;
383  if( jj>=MxTwPhi ) jj-=MxTwPhi;
384  assert( jj>=0 && jj<MxTwPhi );
385  int k1=i + MxTwEta*jj;
386  if(soloMip[k1].e<=0) continue;
387 
388  float w=w0/soloMip[ k1 ].key;
389  // printf("add to cl.k0=%d@ ieta=%d,phi=%d ieta=%d iphi=%d w=%f\n",k0,ieta,iphi,i,j,w);
390  // float e=soloMip[k1 ].e/soloMip[ k1 ].key;
391  float e=w*soloMip[k1 ].e;
392 
393  sum+=e;
394  sumi+=e*i;
395  sumj+=e*j;
396  }
397  }
398  assert(sum>0);
399  // printf("k0=%d sum=%f, sumi=%f, sumj=%f ic=%d \n",k0, sum,sumi,sumj,ic);
400  clust[ic].eC=sum;
401  clust[ic].feta=sumi/sum;
402  clust[ic].fphi=sumj/sum;
403  //printf(" feta=%f fphi=%f\n",clust[ic].feta, clust[ic].fphi);
404 
405 }
406 
407 //---------------------------------------------------
408 //---------------------------------------------------
409 float EEsoloPi0::sumPatchEnergy(int k0,int d,EEsoloMipA *soloMipX, float *maxVal){
410 
411  int ieta=k0%12;
412  int iphi=k0/12;
413 
414  int i,j;
415  double sum=0;
416  double max=0;
417  for(i=ieta-d; i<=ieta+d;i++){
418  if( i>=MxTwEta || i<0) continue;
419  for(j=iphi-d;j<=iphi+d;j++){
420  int jj=j;
421  if( jj<0 ) jj+=MxTwPhi;
422  if( jj>=MxTwPhi ) jj-=MxTwPhi;
423  assert( jj>=0 && jj<MxTwPhi );
424  int k1=i + MxTwEta*jj;
425  if(soloMipX[k1].e<=0) continue;
426  sum+=soloMipX[k1 ].e;
427  if(max<soloMipX[k1 ].e) max=soloMipX[k1 ].e;
428  }
429  }
430 
431  if(maxVal) *maxVal=max;
432 
433  printf("sumPatchEnergy(k0=%d, d=%d)=%f ,max=%f\n",k0, d,sum,max);
434  return sum;
435 }
436 
437 
438 //-------------------------------------------------
439 //-------------------------------------------------
440 //-------------------------------------------------
441 int EEsoloPi0::findInvM(Cluster *c1, Cluster *c2, TH1F **h){
442  int isPi0=0;
443  float e1=c1->eC;
444  float e2=c2->eC;
445  // ((TH2F*) h[0])->Fill(e1,e2);
446 
447  TVector3 r1=geom-> getDirection( c1->feta, c1->fphi);
448  TVector3 r2=geom-> getDirection( c2->feta, c2->fphi);
449 
450  TVector3 p1=e1* r1.Unit();
451  TVector3 p2=e2* r2.Unit();
452 
453  float opAngle=p1.Angle(p2);
454  // printf("-->%.1f\n", opAngle/3.1416*180);
455 
456  h[6]->Fill(opAngle);
457 
458  TVector3 p12=p1+p2;
459  float e12=e1+e2;
460  float invm2= e12*e12-p12*p12;
461  float invm=sqrt(invm2);
462  TVector3 r12=r1-r2;
463  float d12=sqrt(r12*r12);
464 
465 #if 0
466  if(invm>0.1 & invm<0.20)
467 {
468  printf("\ninvM=%.3f e1=%.2f e2=%.2f ", invm,e1,e2);
469 
470 #if 0
471  //invm2 = 2.0*e1*e2*(1.0-cos(theta12))
472  float mm2=2.0*e1*e2*(1.0-cos(p1.Angle(p2)));
473  printf("\ninvM=%f e1=%f e2=%f feta1=%f fphi1=%f feta2=%f fphi2=%f\n d12/cm=%f ang01=%f ang02=%f ang12=%f etot=%f m=%f\n",
474  invm,e1,e2,c1->feta, c1->fphi,c2->feta, c2->fphi,d12,p12.Angle(p1),p12.Angle(p2),p1.Angle(p2),e12, sqrt(mm2));
475 
476  printf(" x1,y1,z1=%f %f %f\n",r1.x(),r1.y(),r1.z());
477  printf(" x2,y2,z2=%f %f %f\n",r2.x(),r2.y(),r2.z());
478  printf(" p1,p1,p1=%f %f %f\n",p1.x(),p1.y(),p1.z());
479  printf(" p2,p2,p2=%f %f %f\n",p2.x(),p2.y(),p2.z());
480 #endif
481 }
482 
483 #endif
484 
485  h[1]->Fill(invm);
486  h[25]->Fill(invm,timeSec/60.);
487  // printf("%f %d\n",c1->feta, (int)(c1->feta+1));
488  h[(int) (27+c1->feta)] ->Fill(invm);
489  h[(int) (27+c2->feta)] ->Fill(invm);
490 
491  if(c1->eC < c2->eC) {
492  ((TH2F*) h[4])->Fill(r1.x(),r1.y());
493  ((TH2F*) h[5])->Fill(r2.x(),r2.y());
494  } else {
495  ((TH2F*) h[5])->Fill(r1.x(),r1.y());
496  ((TH2F*) h[4])->Fill(r2.x(),r2.y());
497  }
498 
499  int bin1=1+c1->k1%12;
500  int bin2=1+c2->k1%12;
501  if (bin2>bin1) { int kk=bin1; bin1=bin2; bin2=kk;}
502 
503  ((TH2F*) h[3])->Fill(bin1, bin2);
504 
505  ((TH2F*) h[2])->Fill(e12,d12);
506 
507  // ieta iphi
508  int kk1=(c1->k1%12)*60+ (c1->k1/12);
509  int kk2=(c2->k1%12)*60+ (c2->k1/12);
510  h[13]->Fill(kk1);
511  h[13]->Fill(kk2);
512 
513  if(mLo<invm && invm<mHi){ // accepted pi0
514  isPi0=1;
515  h[7]->Fill(e12);
516  h[8]->Fill(p12.Eta());
517  h[9]->Fill(p12.Phi());
518  h[10]->Fill(p12.Pt());
519  h[14]->Fill(kk1);
520  h[14]->Fill(kk2);
521  ((TH2F*) h[15])->Fill(e12,d12);
522  h[24]->Fill(opAngle);
523 
524  float zE=fabs(c1->eC - c2->eC)/(c1->eC + c2->eC);
525  h[26]->Fill(zE);
526 
527  if(c1->eC < c2->eC) {
528  ((TH2F*) h[11])->Fill(r1.x(),r1.y());
529  ((TH2F*) h[12])->Fill(r2.x(),r2.y());
530  } else {
531  ((TH2F*) h[12])->Fill(r1.x(),r1.y());
532  ((TH2F*) h[11])->Fill(r2.x(),r2.y());
533  }
534  }
535  return isPi0;
536 }
537 
538 
539 /*****************************************************************
540  * $Log: EEsoloPi0.cxx,v $
541  * Revision 1.11 2009/02/04 20:33:21 ogrebeny
542  * Moved the EEMC database functionality from StEEmcDbMaker to StEEmcUtil/database. See ticket http://www.star.bnl.gov/rt2/Ticket/Display.html?id=1388
543  *
544  * Revision 1.10 2007/10/19 23:18:40 balewski
545  * 2008 cleanup, now works only w/ regular muDst
546  *
547  * Revision 1.9 2005/03/01 20:02:15 balewski
548  * hack to access 2005 trigger data
549  *
550  * Revision 1.8 2004/09/29 18:04:44 balewski
551  * now it runs on M-C as well
552  *
553  * Revision 1.7 2004/09/03 04:50:52 balewski
554  * big clenup
555  *
556  * Revision 1.6 2004/08/26 04:39:40 balewski
557  * towards pi0
558  *
559  */
560 
561 
562 
563 
564 
565 #if 0
566  float adc2gev[MaxEtaBins]={ // ideal gain (ch/GeV)
567  18.938, 20.769, 22.650, 24.575,
568  26.539, 28.514, 30.493, 32.473,
569  34.438, 36.387, 38.28, 40.146 };
570 
571  if(strstr(x->name,"01TA05")) continue;
572  if(strstr(x->name,"11TD09")) continue;
573  if(strstr(x->name,"09TB06")) continue;
574 
575 
576 #endif
577 
TObjArray * HList
DB access point.
Definition: EEsoloPi0.h:72
EEMC simple geometry.