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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Mon Mar 2 09:26:19 2009 UTC (15 years, 9 months ago) by mocchiut
Branch: CaloAxis, MAIN
CVS Tags: start, v1r00, HEAD
Changes since 1.1: +0 -0 lines
Elena's source

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