/[PAMELA software]/calo/flight/CaloAxis/src/CaloAxis.cpp
ViewVC logotype

Annotation of /calo/flight/CaloAxis/src/CaloAxis.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Mon Mar 2 09:26:19 2009 UTC (15 years, 9 months ago) by mocchiut
Branch point for: CaloAxis, MAIN
Initial revision

1 mocchiut 1.1 /**
2     * \file CaloAxis.cpp
3     * \author Elena Vannuccini
4     */
5     #if !defined(__CINT__) || defined(__MAKECINT__)
6    
7     #include <CaloAxis.h>
8    
9     #endif
10     //===============================================================================
11     //
12     //
13     //
14     //
15     //===============================================================================
16     /**
17     * Add a calorimeter hit
18     * @param iis strip 0-95
19     * @param iip plane 0-21
20     * @param fq signal
21     * @param fz z-coordinate
22     * @param fxy x or y-coordinate
23     */
24     void CaloEvent::Add(int iis, int iip, float fq, float fz, float fxy){
25     // cout << " CaloEvent::Add()"<<endl;
26     ids.push_back(iis);
27     idp.push_back(iip);
28     q.push_back(fq);
29     zcoord.push_back(fz);
30     xycoord.push_back(fxy);
31     };
32     /**
33     * Reset
34     */
35     void CaloEvent::Reset(){
36     // cout << " CaloEvent::Reset()"<<endl;
37     ids.clear();
38     idp.clear();
39     q.clear();
40     zcoord.clear();
41     xycoord.clear();
42     };
43     /**
44     * Set a CaloEvent from CaloLevel1 object
45     */
46     void CaloEvent::Set(CaloLevel1* calo, int view, Bool_t usemechanicalalignement){
47    
48     Reset();
49     // cout << " CaloEvent::Set()"<<endl;
50     CaloStrip cstrip;
51     cstrip = CaloStrip(calo,usemechanicalalignement);
52    
53     for(int ih=0;ih<calo->istrip;ih++){
54     int iv=-1;
55     int ip=-1;
56     int is=-1;
57     calo->DecodeEstrip(ih,iv,ip,is);
58     if(iv==view){
59     cstrip.Set(view,ip,is);
60     float fxy = 0.;
61     if( !view ) fxy = cstrip.GetX();
62     else fxy = cstrip.GetY();
63     float fz = cstrip.GetZ();
64     float fq = cstrip.GetE();
65     if(fq>0)Add(is,ip,fq,fz,fxy);
66     }
67     }
68    
69     };
70     //===============================================================================
71     //
72     //
73     //
74     //
75     //===============================================================================
76     /**
77     * Initialization
78     */
79     void CaloAxis::Init(){
80     for(Int_t i=0; i<2;i++){
81     par[i]=0;
82     for(Int_t j=0; j<2;j++)covpar[i][j]=0;
83     };
84     sel = 0;
85     axis = 0;
86     for(Int_t i=0; i<22; i++){
87     cog[i]=0;
88     qpl[i]=0;
89     }
90     }
91    
92     /**
93     * Reset
94     */
95     void CaloAxis::Reset(){
96     x.clear();
97     y.clear();
98     w.clear();
99     q.clear();
100     if(sel)sel->Delete();
101     if(axis)axis->Delete();
102     Init();
103     }
104     /**
105     *
106     */
107     void CaloAxis::Add(float xin, float yin){
108     x.push_back(xin);
109     y.push_back(yin);
110     w.push_back(1.);
111     q.push_back(0.);
112     };
113     void CaloAxis::Add(float xin, float yin, float qin){
114     x.push_back(xin);
115     y.push_back(yin);
116     q.push_back(qin);
117     w.push_back(1.);
118     };
119     void CaloAxis::Add(float xin, float yin, float qin, float win){
120     x.push_back(xin);
121     y.push_back(yin);
122     w.push_back(win);
123     q.push_back(qin);
124     };
125     /**
126     * Fit a straight line thtrough the stored hits
127     */
128     int CaloAxis::Fit(){
129    
130     Float_t SSS = 0;
131     Float_t SSX = 0;
132     Float_t SXX = 0;
133    
134     Float_t SSY = 0;
135     Float_t SXY = 0;
136    
137     Int_t np=0;
138     for(Int_t i=0; i<(int)(x.size()); i++){
139     SSS += w[i]*w[i];
140     SSX += x[i]*w[i]*w[i];
141     SXX += x[i]*x[i]*w[i]*w[i];
142     SSY += y[i]*w[i]*w[i];
143     SXY += x[i]*y[i]*w[i]*w[i];
144     if(w[i])np++;
145     }
146     Float_t det = SSS*SXX-SSX*SSX;
147     if(det==0)return 0;
148     if(np<3)return 0;
149     par[0] = (SSY*SXX-SXY*SSX)/det;
150     par[1] = (SXY*SSS-SSY*SSX)/det;
151     return 1;
152     };
153    
154     /**
155     * Print select hits
156     */
157     void CaloAxis::Print(){
158     for(Int_t i=0; i<(int)(x.size()); i++)
159     if(w[i])cout << x[i] << " - "<<y[i]<<endl;
160     }
161    
162    
163     float* CaloAxis::GetX(){
164     float *xout = new float[(int)(x.size())];
165     for(Int_t i=0; i<(int)(x.size()); i++)xout[i]=x[i];
166     return xout;
167     }
168    
169     float* CaloAxis::GetY(){
170     float *yout = new float[(int)(y.size())];
171     for(Int_t i=0; i<(int)(y.size()); i++) yout[i]=y[i];
172     return yout;
173     }
174    
175     float* CaloAxis::GetQ(){
176     float *qout = new float[(int)(q.size())];
177     for(int i=0; i<(int)(q.size()); i++) qout[i]=q[i];
178     return qout;
179     }
180    
181     float CaloAxis::GetChi2(){
182     float chi2=0;
183     int nchi=0;
184     for(Int_t i=0; i<(int)(y.size()); i++){
185     chi2 += w[i]*w[i]*(y[i]-par[0]-par[1]*x[i])*(y[i]-par[0]-par[1]*x[i]);
186     nchi += (int)w[i];
187     };
188     if(nchi<3)return -999;
189     chi2=chi2/(nchi-2);
190     return chi2;
191     }
192    
193     /**
194     * Return the total signal of the hits included to evaluate the axis
195     */
196     float CaloAxis::GetQaxis(){
197     float qaxis=0;
198     for(Int_t i=0; i<(int)(q.size()); i++) qaxis +=q[i];
199     return qaxis;
200     }
201     /**
202     * Signal of the hits included to evaluate the axis,
203     * within a distance toll from the axis
204     */
205     float CaloAxis::GetQaxis(float toll){
206     float qaxis=0;
207     for(int ih=0;ih<cevent->GetN(); ih++){
208     float x = cevent->xycoord[ih];
209     float z = cevent->zcoord[ih];
210     float q = cevent->q[ih];
211     // int ip = cevent->idp[ih];
212     float d = fabs(x-par[0]-par[1]*z)/sqrt(par[1]*par[1]+1);
213     if( d < toll )qaxis+=q;
214     }
215     return qaxis;
216     }
217    
218     /**
219     * Average signal per strip
220     */
221     float CaloAxis::GetQstrip(){
222    
223     float qaxis=0;
224     for(Int_t i=0; i<(int)(q.size()); i++) qaxis +=q[i];
225     if(q.size()==0) return 0.;
226     return qaxis/q.size();
227     }
228     /**
229     * Coordinate of the last hit included in the axis
230     */
231     float CaloAxis::GetXmin(){
232     float zmin=9999;
233     for(Int_t i=0; i<(int)(x.size()); i++) if(x[i]<zmin) zmin = x[i];
234     return zmin;
235     }
236     /**
237     * Coordinate of the first hit included in the axis
238     */
239     float CaloAxis::GetXmax(){
240     float zmax=-9999;
241     for(Int_t i=0; i<(int)(x.size()); i++) if(x[i]>zmax) zmax = x[i];
242     return zmax;
243    
244     }
245    
246     /**
247     * Draw the axis (in PAMELA reference plane)
248     */
249    
250     void CaloAxis::Draw(int col){
251    
252     // cout << " CaloAxis::Draw()"<<endl;
253     if(GetN()<3)return;
254    
255     sel = new TPolyMarker(GetN(),GetY(),GetX());
256     sel->SetMarkerSize(0.4);
257     sel->SetMarkerColor(col);
258    
259     axis = new TLine( par[0]+GetXmin()*par[1], GetXmin(), par[0]+GetXmax()*par[1], GetXmax() );
260     axis->SetLineWidth(1);
261     axis->SetLineColor(col);
262    
263     // cout << sel << endl;
264     // cout << axis << endl;
265    
266     sel->Draw();
267     axis->Draw();
268     };
269    
270     /**
271     * Fit an axis through the calorimeter pattern.
272     * NB!! This method is optimized for non-interacting particles.
273     */
274     int CaloAxis::FitAxis( CaloLevel1* calo , Int_t view , Float_t toll , Bool_t usemechanicalalignement ){
275    
276     // cout << "CaloAxis::FitAxis(...)"<<endl;
277    
278     Set(calo,view,usemechanicalalignement);
279    
280     // ------------------------------
281     // first : all hits included, w=1
282     // ------------------------------
283     for(int ih=0;ih<cevent->GetN(); ih++){
284     float x = cevent->xycoord[ih];
285     float z = cevent->zcoord[ih];
286     float q = cevent->q[ih];
287     Add(z,x,q);
288     }
289    
290     if(GetN()<3)return 0;
291     Fit();
292     // cout << " n. hits :"<<GetN()<<endl;
293     // cout << " P0 P1 :"<<par[0]<< " "<<par[1]<<endl;
294     // cout << " Chi2 :"<<GetChi2()<<endl;
295     // cout << " Q axis :"<<GetQaxis()<<endl;
296     // cout << " Q strip :"<<GetQstrip()<<endl;
297    
298     float P0;
299     float P1;
300     int dof;
301    
302     // ---------------------------
303     // second : iteration
304     // ---------------------------
305     int niter=0; // number of iterations
306     int pok[22];
307    
308     // prova
309     // pesi lineari
310     float W22=1.;
311     float W1=10.;
312     float b=(W22-W1)/(22.-1.);// (w22 - w1)/(22-1)
313     float a=W1-b;
314    
315     for(int i=0; i<22; i++)pok[i]=0;
316     do{
317     niter++;
318     float ttoll = toll; //tolerance (cm)
319     if(niter==1)ttoll = 10.*toll;
320     dof = GetN(); //previous fit
321     P0 = par[0];
322     P1 = par[1];
323     Reset(); //fit reset
324     for(int ih=0;ih<cevent->GetN(); ih++){
325     float x = cevent->xycoord[ih];
326     float z = cevent->zcoord[ih];
327     float q = cevent->q[ih];
328     int ip = cevent->idp[ih];
329     float d = fabs(x-P0-P1*z)/sqrt(P1*P1+1);
330     // cout<<d<<endl;
331     if( d < ttoll && (niter==1 || (niter>1 && pok[ip]==1)) ){
332     // if( d < ttoll ){
333     float W=a+b*(ip+1);
334     // cout << ip << " "<<W<<endl;
335     Add(z,x,q,W);
336     pok[ip]=1;
337     }
338     }
339     // break the track if more than 3 planes are missing
340     int nmissing = 0;
341     for(int ip=0; ip<22; ip++){
342     if(pok[ip]==0){
343     nmissing++;
344     }else{
345     nmissing = 0;
346     }
347     if(nmissing==3){
348     for(int ipp=ip+1; ipp<22; ipp++)pok[ipp]=0;
349     break;
350     }
351     }
352    
353    
354     if(niter==100)break;
355     if(GetN()<3)break;
356     Fit();
357     }while(niter==1 || GetN() != dof);
358     // cout << " >>> "<<GetN()<<endl;
359     if(GetN()<3)return 0;
360     Fit();
361     // cout << " n. hits :"<<GetN()<<endl;
362     // cout << " P0 P1 :"<<par[0]<< " "<<par[1]<<endl;
363     // cout << " Chi2 :"<<GetChi2()<<endl;
364     // cout << " Q axis :"<<GetQaxis()<<endl;
365     // cout << " Q strip :"<<GetQstrip()<<endl;
366    
367     // ---------------------------------------------
368     // third : selecting only closest strip-clusters
369     // and fit baricenters
370     // ---------------------------------------------
371     P0 = par[0];
372     P1 = par[1];
373     Reset();
374    
375     float dmin[22];
376     int closest[22];
377     for(int ip=0; ip<22; ip++){
378     dmin[ip]=999;
379     closest[ip]=-1;
380     }
381     for(int ih=0;ih<cevent->GetN(); ih++){
382     float x = cevent->xycoord[ih];
383     float z = cevent->zcoord[ih];
384     // float q = cevent->q[ih];
385     int ip = cevent->idp[ih];
386     // int is = cevent->ids[ih];
387     float d = fabs(x-P0-P1*z)/sqrt(P1*P1+1);
388     if( d < toll && d<dmin[ip] && pok[ip]==1 ){
389     // Add(z,x,q,q);
390     closest[ip]=ih;
391     // cog[ip] += x*q;
392     // qpl[ip] += q;
393     }
394     }
395     for(Int_t ip=0; ip<22; ip++){
396     if(closest[ip]!=-1){
397     float x = cevent->xycoord[closest[ip]];
398     float z = cevent->zcoord[closest[ip]];
399     float q = cevent->q[closest[ip]];
400     // int is = cevent->ids[closest[ip]];
401     Add(z,x,q,q);
402     cog[ip] += x*q;
403     qpl[ip] += q;
404     // cout << ip << " -o- "<<is<<endl;
405     }
406     }
407     // add +/- one strip
408     for(int ih=0;ih<cevent->GetN(); ih++){
409     float x = cevent->xycoord[ih];
410     float z = cevent->zcoord[ih];
411     float q = cevent->q[ih];
412     int ip = cevent->idp[ih];
413     int is = cevent->ids[ih];
414     if( closest[ip]!=-1 ){
415     int isc = cevent->ids[closest[ip]];
416     if( is == isc+1 || is == isc-1 ){
417     Add(z,x,q,q);
418     cog[ip] += x*q;
419     qpl[ip] += q;
420     // cout << ip << " -+- "<<is<<endl;
421     }
422     }
423     }
424     Fit();
425    
426     if(GetN()<3)return 0;
427     for(int ip=0; ip<22; ip++){
428     if(qpl[ip]!=0){
429     cog[ip]=cog[ip]/qpl[ip];
430     // Add(z,cog[ip],cog[ip],0.7);
431     }
432     }
433    
434     // cout << " n. hits :"<<GetN()<<endl;
435     // cout << " P0 P1 :"<<par[0]<< " "<<par[1]<<endl;
436     // cout << " Chi2 :"<<GetChi2()<<endl;
437     // cout << " Q axis :"<<GetQaxis()<<endl;
438     // cout << " Q strip :"<<GetQstrip()<<endl;
439     // cout << " ---------------------------"<<endl;
440     return 1;
441     };
442    
443     /**
444     * Fit an axis through the calorimeter pattern.
445     * NB!! This method is optimized for non-interacting particles.
446     */
447    
448     int CaloAxis::FitShower( CaloLevel1* calo , Int_t view , Float_t toll , Bool_t usemechanicalalignement ){
449    
450     // cout << "CaloAxis::FitAxis(...)"<<endl;
451    
452     Set(calo,view,usemechanicalalignement);
453    
454     // ------------------------------
455     // first :
456     // ------------------------------
457     for(int ih=0;ih<cevent->GetN(); ih++){
458     float x = cevent->xycoord[ih];
459     // float z = cevent->zcoord[ih];
460     float q = cevent->q[ih];
461     int ip = cevent->idp[ih];
462     cog[ip] += x*q;
463     qpl[ip] += q;
464     // Add(z,x,q);
465     }
466     for(int ip=0; ip<22; ip++){
467     if(qpl[ip]!=0)cog[ip]=cog[ip]/qpl[ip];
468     // cout << ip << " > "<<qpl[ip]<<" "<<cog[ip]<<endl;
469     }
470     // ----------------
471     // plane of maximum
472     // ----------------
473     float qplmax=1;
474     int ipmax = -1;
475     float dmin[22];
476     int closest[22];
477     for(int ip=0; ip<22; ip++)if(qpl[ip]>qplmax){
478     ipmax=ip;
479     qplmax=qpl[ip];
480     dmin[ip]=1000.;//init
481     closest[ip]=-1;//init
482     }
483     for(int ih=0;ih<cevent->GetN(); ih++){
484     float x = cevent->xycoord[ih];
485     float z = cevent->zcoord[ih];
486     float q = cevent->q[ih];
487     int ip = cevent->idp[ih];
488     // if( (ipmax>3 && ip<=ipmax) || ipmax<=3 )Add(z,x,q);
489     if( ip<=ipmax || ip<=3 ){
490     Add(z,x,q);
491     }
492     }
493     if(GetN()<3)return 0;
494     Fit();
495     // cout << " n. hits :"<<GetN()<<endl;
496     // cout << " P0 P1 :"<<par[0]<< " "<<par[1]<<endl;
497     // cout << " Chi2 :"<<GetChi2()<<endl;
498     // cout << " Q axis :"<<GetQaxis()<<endl;
499     // cout << " Q strip :"<<GetQstrip()<<endl;
500    
501     float P0;
502     float P1;
503     int dof;
504    
505     // ---------------------------
506     // second : iteration
507     // ---------------------------
508     int niter=0; // number of iterations
509     int pok[22];
510     // prova
511     // pesi lineari
512     float W22=1.;
513     float W1=10.;
514     float b=(W22-W1)/(22.-1.);// (w22 - w1)/(22-1)
515     float a=W1-b;
516    
517     for(int i=0; i<22; i++){
518     pok[i]=0;
519     cog[i]=0;
520     qpl[i]=0;
521     }
522     do{
523     niter++;
524     float ttoll = toll; //tolerance (cm)
525     if(niter==1)ttoll = 10.*toll;
526     dof = GetN(); //previous fit
527     P0 = par[0];
528     P1 = par[1];
529     Reset(); //fit reset
530     for(int i=0; i<22; i++){
531     cog[i]=0;
532     qpl[i]=0;
533     }
534     for(int ih=0;ih<cevent->GetN(); ih++){
535     float x = cevent->xycoord[ih];
536     float z = cevent->zcoord[ih];
537     float q = cevent->q[ih];
538     int ip = cevent->idp[ih];
539     float d = fabs(x-P0-P1*z)/sqrt(P1*P1+1);
540     // cout<<d<<endl;
541     if(
542     (niter==1 || (niter>1 && pok[ip]==1)) &&
543     // (ip<=ipmax || ip<=3) &&
544     (ip<ipmax || ip<=3) &&
545     // ((ipmax>3 && ip<=ipmax) || ipmax<=3) &&
546     true){
547    
548     if(niter==1 && d<dmin[ip]){
549     dmin[ip]=d;
550     closest[ip]=ih;
551     }
552    
553     float W=a+b*(ip+1);
554     // cout << ip << " "<<W<<endl;
555     if( d < ttoll || ( niter==2 && ih==closest[ip] )){
556     /* if(ip==ipmax && ipmax>1)Add(z,x,q,W*q); */
557     /* else Add(z,x,q,W); */
558     cog[ip] += x*q;
559     qpl[ip] += q;
560     Add(z,x,q,W);
561     pok[ip]=1;
562     }
563     }
564     }
565     // break the track if more than 3 planes are missing
566     int nmissing = 0;
567     for(int ip=0; ip<22; ip++){
568     if(pok[ip]==0){
569     nmissing++;
570     }else{
571     nmissing = 0;
572     }
573     if(nmissing==6){
574     for(int ipp=ip+1; ipp<22; ipp++)pok[ipp]=0;
575     break;
576     }
577     }
578    
579     for(int ip=0; ip<22; ip++)if(qpl[ip]!=0)cog[ip]=cog[ip]/qpl[ip];
580    
581     if(niter==100)break;
582     if(GetN()<3)break;
583    
584     Fit();
585    
586     }while(niter==1 || GetN() != dof);
587     // cout << " >>> "<<GetN()<<endl;
588     if(GetN()<3)return 0;
589     Fit();
590    
591     // cout << " n. hits :"<<GetN()<<endl;
592     // cout << " P0 P1 :"<<par[0]<< " "<<par[1]<<endl;
593     // cout << " Chi2 :"<<GetChi2()<<endl;
594     // cout << " Q axis :"<<GetQaxis()<<endl;
595     // cout << " Q strip :"<<GetQstrip()<<endl;
596     // cout << " ---------------------------"<<endl;
597     return 1;
598     };
599    
600     ClassImp(CaloEvent);
601     ClassImp(CaloAxis);

  ViewVC Help
Powered by ViewVC 1.1.23