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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Fri Mar 13 15:23:20 2009 UTC (15 years, 9 months ago) by pam-fi
Branch: pamela
CVS Tags: beta
Changes since 1.1: +0 -0 lines
CaloElectron beta version

1 #include <CaloElectron.h>
2
3 ////////////////////////////////////////////////////////////
4 /// INITIALIZATIONS & GLOBAL PARAMETERS
5 ////////////////////////////////////////////////////////////
6
7 CaloElectron_parameters * CaloElectron_parameters::_parameters = 0;
8
9 /**
10 * Set external parameters to default values
11 */
12 void CaloElectron_parameters::SetDefault(){
13 cout << "CaloElectron --> SET DEFAULT PARAMETERS" << endl;
14
15 isimu = 0;
16 dolongfit = 1;
17 dolatcorr = 1;
18 calibmode = 0;
19
20 debug = false;
21
22 // dodrawlong = false;
23 // dodrawq0q1 = false;
24 // dodrawlat = false;
25
26 TAUMAX = 5.;
27 RMAX = 40.;//4.; //temporaneo???
28 RMAXsp = 40.;
29
30 // cout << "Shower cuts:"<<endl;
31 // cout << "TAUMAX = "<<TAUMAX<<endl;
32 // cout << "RMAX = "<<RMAX<<" cm"<<endl;
33
34 for(int ip=0; ip<22; ip++)
35 for(int iv=0; iv<2; iv++)
36 maskpl[ip][iv] = false;
37 //
38 h_qtot[0] = NULL;
39 h_qtot[1] = NULL;
40 //
41 h_qfit[0] = NULL;
42 h_qfit[1] = NULL;
43 //
44 cl1 = NULL;
45
46 //
47 for(int i=0; i<NTAUBINMAX; i++){
48 for(int j=0; j<3; j++){
49 h_qtot_tau[i][j] = NULL;
50 h_qtot_tau_wav[i][j] = NULL;
51 for(int ii=0; ii<CALIBNBIN; ii++){
52 summW[i][j][ii] = 0.;
53 summWF[i][j][ii] = 0.;
54 }
55 }
56 }
57
58 SetCalo(0,0);
59 SetPar();
60
61 Dump();
62
63 };
64 /**
65 * Set external parameters to default values
66 */
67 void CaloElectron_parameters::Dump(){
68 cout << "CaloElectron --> DUMP PARAMETERS" << endl;
69 cout << endl;
70 cout << "Shower cuts (for energy determination):"<<endl;
71 cout << " TAUMAX = "<<TAUMAX<<" TAU=t/T"<<endl;
72 cout << " RMAX = "<<RMAX<<" cm"<<endl;
73 // cout << endl;
74 cout << "MASKED PLANES:"<<endl;
75 cout << " X -> ";
76 for(int ip=0; ip<22; ip++)cout << maskpl[ip][0];
77 cout << endl;
78 cout << " Y -> ";
79 for(int ip=0; ip<22; ip++)cout << maskpl[ip][1];
80 cout << endl;
81 cout << " ipmin = "<<ipmin<<endl;
82 cout << " ipmax = "<<ipmax<<endl;
83 // cout << endl;
84 cout << "Flags:"<<endl;
85 cout << " lateral correction ? "<<dolatcorr<<endl;
86 cout << " longitudinal correction ? "<<dolongfit<<endl;
87 cout << " simulation ? "<<isimu<<endl;
88 cout << " calibration mode ? "<<calibmode<<endl;
89 cout << endl;
90
91 };
92 /**
93 * Set calorimeter masks and book histograms.
94 * @icalo Calorimeter configuration (icalo=0 --> all planes included)
95 * @notused Num.of planes exluded (icalo=1 excludes bottom planes, icalo=2 exclude top planes)
96 * NB: plane 19x is always excluded
97 *
98 */
99 void CaloElectron_parameters::SetCalo(int icalo,int notused){
100
101
102 if(icalo==0){
103 maskpl[18][0]=true;
104 ipmin=0;
105 ipmax=22;
106 }
107 if(icalo==1){
108 maskpl[18][0]=true;
109 ipmin=0;
110 ipmax=22-notused;
111 if(18-notused>=0)maskpl[18-notused][0]=true;
112 }
113 if(icalo==2){
114 maskpl[18][0]=true;
115 ipmin=notused;
116 ipmax=22;
117 if(18+notused<22)maskpl[18+notused][0]=true;
118 }
119
120 // cout << "MASKED PLANES:"<<endl;
121 // cout << "X -> ";
122 // for(int ip=0; ip<22; ip++)cout << maskpl[ip][0];
123 // cout << endl;
124 // cout << "Y -> ";
125 // for(int ip=0; ip<22; ip++)cout << maskpl[ip][1];
126 // cout << endl;
127 // cout << "ipmin = "<<ipmin<<endl;
128 // cout << "ipmax = "<<ipmax<<endl;
129
130 // histos for kolmogorov test
131 // if(h_qtot)h_qtot->Delete();
132 // if(h_qfit)h_qfit->Delete();
133 // h_qtot[0] = new TH2F("htot0","Matrix of energy releases (measured)",192,-0.5,191.5,22,-0.5,21.5);
134 // h_qfit[0] = new TH2F("hfit0","Matrix of energy releases (fit)", 192,-0.5,191.5,22,-0.5,21.5);
135 // h_qtot[1] = new TH2F("htot1","Matrix of energy releases (measured)",192,-0.5,191.5,22,-0.5,21.5);
136 // h_qfit[1] = new TH2F("hfit1","Matrix of energy releases (fit)", 192,-0.5,191.5,22,-0.5,21.5);
137
138 // binnaggio in funzione della coordinata, relativo al margine del piano
139 int nbin = 100;
140 double xbin[101];
141 // retrieve the coordinate of the bottom-left corner of the plane
142 xbin[0]=0.;
143 int ibin = 0;
144 for(int ise=0; ise<3; ise++){//sensors
145 ibin++;
146 if(ise==0) xbin[ibin] = xbin[ibin-1] + DEAD;
147 if(ise==1||ise==2) xbin[ibin] = xbin[ibin-1] + DEAD + GLUE + DEAD;
148 for(int is=0; is<32; is++){//strip
149 ibin++;
150 xbin[ibin] = xbin[ibin-1] + PITCH;
151 }
152 }
153 ibin++;
154 xbin[ibin] = xbin[ibin-1] + DEAD;
155
156 if(h_qtot[0])h_qtot[0]->Delete();
157 if(h_qtot[1])h_qtot[1]->Delete();
158 if(h_qfit[0])h_qfit[0]->Delete();
159 if(h_qfit[1])h_qfit[1]->Delete();
160
161 h_qtot[0] = new TH2F("htot0","Matrix of energy releases (measured)",nbin,xbin,22,-0.5,21.5);
162 h_qfit[0] = new TH2F("hfit0","Matrix of energy releases (fit)", nbin,xbin,22,-0.5,21.5);
163 h_qtot[1] = new TH2F("htot1","Matrix of energy releases (measured)",nbin,xbin,22,-0.5,21.5);
164 h_qfit[1] = new TH2F("hfit1","Matrix of energy releases (fit)", nbin,xbin,22,-0.5,21.5);
165
166 }
167 /**
168 * Set external parameters to default values
169 */
170 void CaloElectron_parameters::SetPar(){
171
172 // ---------------
173 // lateral profile (hardcoded parameters )
174 // ---------------
175 TString pathx,pathy,pathyd,pathyp;
176 TString dir = gSystem->Getenv("PAM_CALIB");
177 if(isimu==0){
178 pathx=dir+"/cal-param/parxdati.txt";
179 pathyd=dir+"/cal-param/paryddati.txt";
180 pathyp=dir+"/cal-param/parypdati.txt";
181 }else{
182 pathx=dir+"/cal-param/parxsimu.txt";
183 pathyd=dir+"/cal-param/parydsimu.txt";
184 pathyp=dir+"/cal-param/parypsimu.txt";
185 }
186
187 cout << "Load LATERAL PARAMETERS "<<endl;
188 cout << " X from "<<pathx << endl;
189 cout << " Y-ODD from "<<pathyd << endl;
190 cout << " Y-EVEN from "<<pathyp << endl;
191
192 SetPar(pathx,pathyd,pathyp);
193
194 }
195 /**
196 * Set external parameters from input files
197 */
198 void CaloElectron_parameters::SetPar(TString pathx,TString pathyd,TString pathyp){
199
200 //these parameter are directly the values of rp,rt,p in each taubin
201 //they are obtained from the simulation in different taubin up to tau=3
202 ifstream file;
203 for(int iv=0;iv<2;iv++){
204 if(iv==0){
205 ifstream file(pathx);
206 for(int i=0;i<12;i++)file>>file_tau[i]>>file_p[i][iv]>>file_rt[i][iv]>>file_rc[i][iv];
207 }
208 if(iv==1){
209 ifstream filep(pathyp);
210 for(int i=0;i<12;i++)filep>>file_tau[i]>>file_p[i][iv]>>file_rt[i][iv]>>file_rc[i][iv];
211 ifstream filed(pathyd);
212 for(int i=0;i<12;i++)filed>>file_tau[i]>>file_p[i][iv+1]>>file_rt[i][iv+1]>>file_rc[i][iv+1];
213 }
214 }
215
216 };
217
218 /**
219 * Set calibration tools.
220 * Create histos for lateral profile parameterization
221 */
222 void CaloElectron_parameters::Calibration_SetTools(int ntau, float* taubin){
223
224 if(!calibmode)return;
225
226 cout << "CaloElectron --> Set calibration tools "<<endl;
227 if( ntau > NTAUBINMAX ){
228 ntau = NTAUBINMAX;
229 cout << "(NB: max allowed n.tau-bins = "<<NTAUBINMAX<<")"<<endl;
230 };
231 par_ntau = ntau;
232 for(int i=0; i<=par_ntau; i++)par_taubin[i]=taubin[i];
233 //
234 cout << "Set TAU binning:"<<endl;
235 cout << par_ntau<<" bins, from "<<par_taubin[0]<<" to "<<par_taubin[par_ntau]<<endl;
236 cout << endl;
237 //
238 // create histos
239 //
240 TString htitle,hid;
241 for(int i=0; i<par_ntau; i++){
242 for(int j=0; j<3; j++){
243 //
244 hid.Form("hqtottau_%i_%i",i,j);
245 htitle.Form("Lateral profile - view %i - tau-bin %i",j,i);
246 cout <<hid<<" --> "<< htitle<<" "<<h_qtot_tau[i][j]<<endl;
247 if( h_qtot_tau[i][j] )h_qtot_tau[i][j]->Delete();
248 h_qtot_tau[i][j] = new TH2F(hid.Data(),htitle.Data(),CALIBNBIN,-1*CALIBRANGE,1*CALIBRANGE,5000,0.,10.);
249 //
250 hid.Form("hqtottauwav_%i_%i",i,j);
251 htitle.Form("Lateral profile - view %i - tau-bin %i (weighted average)",j,i);
252 cout <<hid<<" --> "<< htitle<<" "<<h_qtot_tau_wav[i][j]<<endl;
253 if( h_qtot_tau_wav[i][j] )h_qtot_tau_wav[i][j]->Delete();
254 h_qtot_tau_wav[i][j] = new TH1F(hid.Data(),htitle.Data(),CALIBNBIN,-1*CALIBRANGE,1*CALIBRANGE);
255 }
256 }
257
258 return;
259 };
260 /**
261 * Set calibration tools
262 * Create histos for lateral profile parameterization
263 */
264 void CaloElectron_parameters::Calibration_SetTools(){
265
266 if(!calibmode)return;
267
268 int ntau = 12;
269 float fromtau = 0.;
270 float totau = 3.;
271 float dtau = (totau-fromtau)/(float)ntau;
272 vector<float> taubin;
273 float *pt_taubin = taubin.get_allocator().allocate(ntau+1);
274 pt_taubin[0]=fromtau;
275 for(int i=1; i<=ntau; i++)pt_taubin[i]=(pt_taubin[0]+i*dtau);
276 Calibration_SetTools(ntau,pt_taubin);
277 return;
278 };
279 /**
280 * Fit calibration histos
281 */
282 void CaloElectron_parameters::Calibration_Fit(){
283
284 if(!calibmode)return;
285
286 TF1* frad = new TF1("frad",fradpro,-5.,5.,4);
287 //
288 // int nt_tau = CaloElectron_parameters::Get()->par_ntau;
289 int ntau = par_ntau;
290 //
291 for(int itau = 0; itau<ntau; itau++){ //loop over tau-bins
292 for(int j=0; j<3; j++){
293 //
294 // TProfile* hh = 0;
295 // if( !h_qtot_tau[itau][j] )continue;
296 // cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "<<endl;
297 // cout << " fitting profile histo "<<h_qtot_tau[itau][j]->GetName()<<endl;
298 // cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "<<endl;
299
300 // hh = h_qtot_tau[itau][j]->ProfileX("hh");
301 // frad->SetParameter(0,1.5);//rt
302 // frad->SetParameter(1,0.5);//p
303 // frad->SetParameter(2,0.4);//rc
304 // frad->SetParameter(3,.01);//nrom
305 // hh->Fit(frad,"R","",-2,2);
306 // hh->Fit(frad,"R","",-5,5);
307 // hh->Delete();
308 //
309 if( !h_qtot_tau_wav[itau][j] )continue;
310 cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "<<endl;
311 cout << " fitting profile histo "<<h_qtot_tau_wav[itau][j]->GetName()<<endl;
312 cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "<<endl;
313
314 TH1F *hh = h_qtot_tau_wav[itau][j];
315 frad->SetParameter(0,1.5);//rt
316 frad->SetParameter(1,0.5);//p
317 frad->SetParameter(2,0.4);//rc
318 frad->SetParameter(3,.01);//nrom
319 hh->Fit(frad,"R","",-2,2);
320 hh->Fit(frad,"R","",-5,5);
321 hh->Delete();
322
323 };
324 };
325 frad->Delete();
326
327 return;
328 };
329 /**
330 * Write calibration output to file
331 */
332 void CaloElectron_parameters::Calibration_Save(TFile* file){
333
334 if(!calibmode)return;
335
336 if( !file || (file&&file->IsZombie()) )return;
337 file->cd();
338 //
339 // int ntau = CaloElectron_parameters::Get()->par_ntau;
340 int ntau = par_ntau;
341 for(int itau=0; itau<ntau; itau++){
342 for(int j=0; j<3; j++){
343
344 //
345 // fill weighted-average histogram
346 //
347 for(int ibin=0; ibin<CALIBNBIN; ibin++){
348 if(summW[itau][j][ibin]==0.)continue;
349 h_qtot_tau_wav[itau][j]->SetBinContent(ibin+1,summWF[itau][j][ibin]/summW[itau][j][ibin]);
350 h_qtot_tau_wav[itau][j]->SetBinError(ibin+1,1./sqrt(summW[itau][j][ibin]));
351 }
352
353 if(h_qtot_tau[itau][j]) h_qtot_tau[itau][j]->Write();
354 if(h_qtot_tau_wav[itau][j]) h_qtot_tau_wav[itau][j]->Write();
355 }
356 }
357
358 return;
359 };
360 /**
361 * Load calibration output histos from existing file
362 */
363 void CaloElectron_parameters::Calibration_Load(TFile* file){
364
365
366 if( !file || (file&&file->IsZombie()) )return;
367 file->cd();
368 cout <<" File: "<<file->GetName();
369
370 //
371 TString hid;
372 par_ntau=0;
373 for(int i=0; i<100; i++){
374 for(int j=0; j<3; j++){
375 //
376 hid.Form("hqtottau_%i_%i",i,j);
377 TH2F* hh = (TH2F*)file->Get(hid.Data());
378 if(!hh)continue;
379 cout<<"histo --> "<<hid<<endl;
380 h_qtot_tau[i][j]=hh;
381 //
382 hid.Form("hqtottauwav_%i_%i",i,j);
383 TH1F* hhh = (TH1F*)file->Get(hid.Data());
384 if(!hhh)continue;
385 cout<<"histo --> "<<hid<<endl;
386 h_qtot_tau_wav[i][j]=hhh;
387 //
388 par_ntau=i+1;
389 }
390 }
391
392 calibmode = 1;
393
394 return;
395 };
396
397
398
399 ////////////////////////////////////////////////////////////
400 /// CLASS IMPLEMENTATION
401 ////////////////////////////////////////////////////////////
402 /**
403 * Reset event
404 * it has to be called for each event
405 */
406 void CaloElectron::Reset(){
407
408
409 for(int ip=0; ip<22; ip++){
410 for(int iv=0; iv<2; iv++){
411 trkcoordx[ip][iv] = 0.;
412 trkcoordy[ip][iv] = 0.;
413 // trkcoordz[ip][iv] = 0.;
414 trkstrip[ip][iv] = 0.;
415 qplane0[ip][iv] = 0.;
416 qplane1[ip][iv] = 0.;
417 qplanefit[ip][iv] = 0.;
418 tplane[ip][iv] = -100.;
419
420 RMS[ip][iv] = 0.;
421 SKEW[ip][iv] = 0.;
422 KURT[ip][iv] = 0.;
423 TAU[ip][iv] = 0.;
424 }
425 }
426
427 qtot = 0.;
428
429 tg = 0.;
430 tgx = 0.;
431 tgy = 0.;
432
433 corr__l = 1.;
434 err__l = 0;
435 chi2__l = 0.;
436 chi2 = 0.;
437 for(int i=0; i<4; i++)par__l[i]=0.;
438
439 }
440 /**
441 * \brief GetQ
442 * Method to retrieve the total collected charge (within RMAX and TAUMAX).
443 * @param icorr Correction level
444 * 0 = no correction
445 * 1 = lateral correction
446 * 2 = longitudinal correction
447 * 3 = ??
448 */
449 float CaloElectron::GetQ(int icorr){
450
451 float qx,qy,qtotc;
452
453
454 qx = GetQView(icorr,0);
455 qy = GetQView(icorr,1);
456 qtotc = qx+qy;
457
458 // if(qy<0.7*(qtotc/2.)){
459 // cout<<"qx "<<qx<<" qy "<<qy<<" qtotc "<<qtotc<<endl;
460 // cout<<"maybe this is image track???"<<endl;
461 // qtotc=-100.;
462 // }
463
464 return qtotc;
465
466 };
467 /**
468 * \brief GetQview
469 * Method to retrieve the total collected charge in each view
470 * @param icorr Correction level (0= no correction, 1=lateral correction, 2=longitudinal correction)
471 * @param iv (0=xview, 1=yview)
472 */
473 float CaloElectron::GetQView(int icorr,int iv){
474
475
476 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
477 int ipmin = CaloElectron_parameters::Get()->ipmin;
478 int ipmax = CaloElectron_parameters::Get()->ipmax;
479
480 float qqqq=0;
481
482 // if(onlyy && iv==0) return qqqq;
483
484
485 float idmax,ipmaxl;
486 //se faccio così idmax deve essere rispetto al piano da cui inizio davvero
487 idmax = GetShowerMaximum(icorr);
488 // ***BUG??***
489 ipmaxl = idmax*TAUMAX+iv;
490 // ***BUG??***
491 // ipmaxl = idmax*TAUMAX;
492 if( ipmaxl>(ipmax-ipmin) ) ipmaxl=ipmax-ipmin;
493
494 //if(ipmaxl<22) cout<<"GetQView icorr "<<icorr<<" ipmaxl="<<ipmaxl<<endl;
495
496 // ----------------------
497 // total collected charge
498 // ----------------------
499 if(icorr==0){
500 for(int ip=ipmin; ip<ipmin+ipmaxl; ip++){
501 qqqq += qplane0[ip][iv];
502 }
503 }
504 // -------------------------------------
505 // total charge after lateral correction
506 // -------------------------------------
507 else if(icorr==1){
508 for(int ip=ipmin; ip<ipmin+ipmaxl; ip++){
509 qqqq += qplane1[ip][iv];
510 }
511 }
512 // ------------------------------------------
513 // total charge after longitudinal correction
514 // ------------------------------------------
515 else if(icorr==2){
516 for(int ip=ipmin; ip<ipmin+ipmaxl; ip++){
517 qqqq += qplane1[ip][iv];
518 }
519 qqqq=qqqq*corr__l;
520 }
521 // ------------------------------------------
522 // total charge from longitudinal fit
523 // ------------------------------------------
524 else if(icorr==3){
525 for(int ip=ipmin; ip<ipmin+ipmaxl; ip++){
526 qqqq += qplanefit[ip][iv];
527 }
528 }
529 // cout << "**** "<<ipmin << " "<<ipmin+ipmaxl<<" "<<qqqq<<" -- "<<qtot<<endl;
530
531
532 return qqqq;
533 };
534 /**
535 * \brief Evaluate shower maximum
536 * It gives the number of W-layers traversed at shower maximum.
537 * The charge deposited in each layer is evaluated as the averege
538 * between the adjacent x and y planes.
539 * NB: the shower depth is evaluated relative to ipmin.
540 * It goes from 0 to 22 (more generally, from 0 to ipmax-ipmin ).
541 */
542 float CaloElectron::GetShowerMaximum(float qplane[][2]){
543
544 int ipmin = CaloElectron_parameters::Get()->ipmin;
545 int ipmax = CaloElectron_parameters::Get()->ipmax;
546
547 int maxlayer = 0;
548 float maxq = qplane[0][1]; //0Y - first active layer
549 float q;
550 for(int il=1; il<22; il++){
551 q=0.;
552 int nxy=0;
553 float qx = qplane[il-1][0];
554 float qy = qplane[il][1];
555 bool ISHIT = true;
556 bool maskpl_x = CaloElectron_parameters::Get()->maskpl[il-1][0];
557 bool maskpl_y = CaloElectron_parameters::Get()->maskpl[il][1];
558 if( tplane[il-1][0] <0 || tplane[il][1]<0 )ISHIT=false;
559 if(ISHIT){
560 // if( !maskpl[il-1][0] )nxy++;
561 // if( !maskpl[il][1] )nxy++;
562 if( !maskpl_x )nxy++;
563 if( !maskpl_y )nxy++;
564 if(nxy>0)q=(qx+qy)/nxy;
565 if(q>maxq){
566 maxq=q;
567 maxlayer=il;
568 }
569 }
570 }
571 if( tplane[21][0] > 0 ){
572 q = qplane[21][0]; //21X - last active layer
573 if(q>maxq){
574 maxq=q;
575 maxlayer=22;
576 }
577 }
578
579 maxlayer=maxlayer-ipmin;
580 if(maxlayer<0) maxlayer=0;
581 if(maxlayer>ipmax-ipmin) maxlayer=ipmax-ipmin;
582 return (float)maxlayer;
583 }
584
585 /**
586 * \brief Evaluate shower maximum (id of shower maximum plane)
587 */
588 float CaloElectron::GetShowerMaximum(int icorr){
589 // ------------------------------------
590 // shower maximum before any correction
591 // ------------------------------------
592 if(icorr==0) return GetShowerMaximum(qplane0);
593 // ---------------------------------------
594 // shower maximum after lateral correction
595 // ---------------------------------------
596 if(icorr==1) return GetShowerMaximum(qplane1);
597 // ---------------------------------------
598
599 // ---------------------------------------
600 // shower maximum from longitudinal fit
601 // ---------------------------------------
602 if(icorr==2 || icorr==3){
603 if( err__l==0 ){
604 return par__l[2]*cos(atan(tg))/(WTICK/WX0);
605 }else{
606 return GetShowerMaximum(qplane1);
607 }
608 }
609
610 return 0.;
611
612 }
613 /**
614 * \brief Evaluate shower maximum (in X0 unit, considering track inclination angle)
615 */
616 float CaloElectron::GetShowerMaximumX0(int icorr){
617
618 float maxX0=0;
619 if(icorr==0 || icorr==1) maxX0=(GetShowerMaximum(icorr)/cos(atan(tg)))*(WTICK/WX0);
620 if(icorr==2 || icorr==3) maxX0=par__l[2];
621
622 return maxX0;
623
624 }
625
626 float CaloElectron::GetShowerMaximumViewX0(int view,int icorr){
627
628 float maxX0=0;
629 if(icorr==0 || icorr==1) maxX0=(GetShowerMaximumView(view,icorr)/cos(atan(tg)))*(WTICK/WX0);
630 if(icorr==2 || icorr==3) maxX0=par__l[2];
631
632 return maxX0;
633
634 }
635 float CaloElectron::GetShowerMaximumView(int view,float qplane[][2]){
636
637 int ipmin = CaloElectron_parameters::Get()->ipmin;
638 int ipmax = CaloElectron_parameters::Get()->ipmax;
639 int maxlayer = 0;
640 float maxq = qplane[0][view];
641 for(int il=1; il<22; il++){
642 if(qplane[il][view]>maxq){
643 maxq = qplane[il][view];
644 maxlayer = il+1-view;
645 }
646 }
647 maxlayer=maxlayer-ipmin;
648 if(maxlayer<0) maxlayer=0;
649 if(maxlayer>ipmax-ipmin) maxlayer=ipmax-ipmin;
650 return (float)maxlayer;
651
652 }
653 float CaloElectron::GetShowerMaximumView(int view,int icorr){
654 // ------------------------------------
655 // shower maximum before any correction
656 // ------------------------------------
657 if(icorr==0) return GetShowerMaximumView(view,qplane0);
658 // ---------------------------------------
659 // shower maximum after lateral correction
660 // ---------------------------------------
661 if(icorr==1) return GetShowerMaximumView(view,qplane1);
662 // ---------------------------------------
663
664 // ---------------------------------------
665 // shower maximum from longitudinal fit
666 // ---------------------------------------
667 if(icorr==2 || icorr==3){
668 if(err__l==0){
669 return par__l[2]*cos(atan(tg))/(WTICK/WX0);
670 }else{
671 return GetShowerMaximumView(view,qplane1);
672 }
673 }
674
675 return 0.;
676
677 }
678
679
680 /**
681 * \brief Set event
682 */
683 bool CaloElectron::Set(CaloLevel1 *cl1,float trackcoordinate[][2]){
684
685 if(!cl1 || !trackcoordinate ){
686 cout <<" void CaloElectron::Set(CaloLevel1 *cl1, float tracoo[22][2]) -- ERROR -- input == NULL"<<endl;
687 return false;
688 }
689 //
690 CaloElectron_parameters::Get()->cl1 = cl1; //set CaloLevel1 event
691 CaloStrip cstrip;
692
693
694 // -------------------
695 // retrieve parameters
696 // -------------------
697 bool debug = CaloElectron_parameters::Get()->debug;
698 float RMAX = CaloElectron_parameters::Get()->RMAX;
699 int dolatcorr = CaloElectron_parameters::Get()->dolatcorr;
700 int dolongfit = CaloElectron_parameters::Get()->dolongfit;
701 int ipmin = CaloElectron_parameters::Get()->ipmin;
702 int ipmax = CaloElectron_parameters::Get()->ipmax;
703
704 int calibmode = CaloElectron_parameters::Get()->calibmode;
705
706 // gBenchmark->Start("conta");
707
708 // --------------------------
709 // reset energy-deposit plots
710 // --------------------------
711 TH2F* h_qtot[2];
712 for(int iv=0; iv<2; iv++){
713 h_qtot[iv] = CaloElectron_parameters::Get()->h_qtot[iv];
714 if(!h_qtot[iv])return false;
715 h_qtot[iv]->Reset();
716 }
717
718 // cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "<< CaloElectron_parameters::Get() << endl;
719 // cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "<< CaloElectron_parameters::Get()->cl1 << endl;
720 // cout <<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "<< cl1 << endl;
721
722
723 if( cl1->istrip < 5 )return false;
724
725
726 // float trkstrip[22][2]; // strip traversed by the track
727 //
728 for(int ip=0; ip<22; ip++){
729 for(int iv=0; iv<2; iv++){
730 // --------------------------------------
731 // determine strip traversed by the track
732 // --------------------------------------
733 // Float_t coo(0),lad(0),stri(0);
734 // Float_t xcorner,ycorner;
735 // GetCornerCoord(ip,iv,xcorner,ycorner);
736 // if(iv==0) coo = (trackcoordinate[ip][iv]-xcorner)*10.;
737 // if(iv==1) coo = (trackcoordinate[ip][iv]-ycorner)*10.;
738 // if(coo<80.25) lad=1;
739 // if(coo>80.25 && coo<160.75) lad=2;
740 // if(coo>160.75) lad=3;
741 // stri=32*(lad-1)+(coo-(lad-1)*80.5-0.96)/2.44;
742 // Int_t trkstripnew = (Int_t)stri;
743 // if(stri-trkstripnew>0.5) trkstripnew=trkstripnew+1;
744 // trkstrip[ip][iv]=trkstripnew;
745 // if(coo<0. || coo> 241.)trkstrip[ip][iv]=-1.;
746 //
747 // non so perche` ma mi sembra che sia sbagliato...
748 // ci riprovo a modo mio:
749 //
750 trkstrip[ip][iv]=-1.;
751 float xy[2];
752 for(int is=0; is<96; is++){
753 cstrip.Set(iv,ip,is);
754 xy[0] = cstrip.GetX();
755 xy[1] = cstrip.GetY();
756 if(
757 trackcoordinate[ip][iv] >= xy[iv] - 0.5*PITCH &&
758 trackcoordinate[ip][iv] < xy[iv] + 0.5*PITCH &&
759 true){
760 trkstrip[ip][iv] = is;
761 break;
762 }
763 };
764 }
765 }
766
767
768 // cout << " 1 ------------------ init"<<endl;
769 // gBenchmark->Print("conta");
770
771
772 //<><><><><><><><><><><><><><><><><><><><><><><><>
773 // LOOP OVER HIT STRIPS
774 // - to set charge collected in each plane
775 // - to fill energy-deposit plot (if required)
776 //<><><><><><><><><><><><><><><><><><><><><><><><>
777
778 int isimu = CaloElectron_parameters::Get()->isimu;
779 if(isimu==0)cstrip = CaloStrip(cl1,false);//conferma da Emiliano
780 if(isimu==1)cstrip = CaloStrip(cl1,true);
781
782 float xy[2];
783 for(int ih=0;ih<cl1->istrip;ih++){
784 int iv=-1;
785 int ip=-1;
786 int is=-1;
787 cl1->DecodeEstrip(ih,iv,ip,is);
788 cstrip.Set(iv,ip,is);
789 // enestr[is][ip][iv] = cstrip.GetE();
790 xy[0] = cstrip.GetX();
791 xy[1] = cstrip.GetY();
792 if( TMath::Abs(trackcoordinate[ip][iv]-xy[iv]) < RMAX )
793 qplane0[ip][iv] += cstrip.GetE(); //<< QPLANE0
794 bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
795 if(
796 ip>=ipmin &&
797 ip<ipmax &&
798 !maskpl &&
799 true){
800 qtot += cstrip.GetE();//<< QTOT
801 //
802 // h_qtot[iv]->Fill( (float)(is+iv*96), (float)ip, cstrip.GetE());
803 // retrieve the coordinate of the bottom-left corner of the plane
804 float corner[] = {0.,0.};
805 GetCornerCoord(ip,iv,corner[0],corner[1]);
806 h_qtot[iv]->Fill( xy[iv]-corner[iv], (float)ip, cstrip.GetE());
807 }
808 // cout <<(float)(is+iv*96)<<(float)ip<<cstrip.GetE()<<endl;
809 }
810
811 // cout << " 2 ------------------ read charge"<<endl;
812 // gBenchmark->Print("conta");
813
814 // ------------------------------------------------
815 // set track intersection coordinate in each plane
816 // and evaluate shower depth
817 // ------------------------------------------------
818
819 float trkcoordz[22][2]; ///< track coordinates (PAMELA r.s.)
820
821 for(int ip=0; ip<22; ip++){
822 for(int iv=0; iv<2; iv++){
823 cstrip.Set(iv,ip,0);
824 trkcoordz[ip][iv] = cstrip.GetZ();
825 }
826 }
827 tgx = (trackcoordinate[0][0]-trackcoordinate[21][0])/(trkcoordz[0][0]-trkcoordz[21][0]);
828 tgy = (trackcoordinate[0][1]-trackcoordinate[21][1])/(trkcoordz[0][1]-trkcoordz[21][1]);
829 tg = sqrt(pow(trackcoordinate[0][1]-trackcoordinate[21][1],2)+pow(trackcoordinate[0][0]-trackcoordinate[21][0],2))/(trkcoordz[0][1]-trkcoordz[21][1]);
830
831 bool TRACK_OUT = false;
832 for(int ip=0; ip<22; ip++){
833 for(int iv=1; iv>=0; iv--){
834 if(iv==0){
835 trkcoordx[ip][0] = trackcoordinate[ip][0]; //track intersection coordinate
836 trkcoordy[ip][0] = trackcoordinate[ip][1] + (trkcoordz[ip][0]-trkcoordz[ip][1])*tgy; //track intersection coordinate
837 }else{
838 trkcoordx[ip][1] = trackcoordinate[ip][0] + (trkcoordz[ip][1]-trkcoordz[ip][0])*tgx; //track intersection coordinate
839 trkcoordy[ip][1] = trackcoordinate[ip][1]; //track intersection coordinate
840 }
841 // ---------------------------------------------
842 // if the track go out of the calorimeter, break
843 // ---------------------------------------------
844 if( trkstrip[ip][iv] == -1 ){
845 //TRACK_OUT = true;
846 if(debug)cout << "ip="<<ip <<" iv="<<iv<<" --> TRACK OUT";
847 }
848 if( !TRACK_OUT ){
849 // shower depth in units of radiation length (TO BE CHECKED)
850 tplane[ip][iv] = GetNWLayers(ip,iv) * sqrt(tgx*tgx+tgy*tgy+1) * WTICK/WX0;//sqrt(tgx*tgx+tgy*tgy+1)=1/cos(atan(tg)
851 qplane1[ip][iv] = qplane0[ip][iv]; // initialize qplane1
852 }else return false;
853 }
854 }
855
856 // cout << " 3 ------------------ get track coordinates"<<endl;
857 // gBenchmark->Print("conta");
858
859 if(GetQ(0)<1){
860 cout<<"Don't go on ..GetQ(0) "<<GetQ(0)<<endl;
861 return false;
862 }
863 if(GetShowerMaximum(0)<1 || GetShowerMaximum(0)>21){
864 cout<<"Don't go on ..GetShowerMaximum(0) "<<GetShowerMaximum(0)<<endl;
865 return false;
866 }
867
868 // -----------------------------------------
869 // fill calibration histograms (if required)
870 // -----------------------------------------
871
872 if( calibmode )Calibration_Fill();
873
874 // -----------------------------------------
875 // apply lateral correction
876 // -----------------------------------------
877
878 if(dolatcorr==0) return true;
879
880 float maxlayer;
881 int niter;
882 float corr;
883
884 maxlayer = 0.;
885 corr = 0.;
886 niter = 0;
887 do{
888 niter++;
889 maxlayer = GetShowerMaximum(1);
890 corr = ApplyLateralCorrection(maxlayer);
891 }while( maxlayer != GetShowerMaximum(1) && niter < 3);
892
893 if(debug && niter>1)cout<<"WARNING! - lateral correction iterated "<<niter<<" times"<<endl;
894
895 if(debug)cout << "LATERAL CORRECTION FACTOR = "<<corr<<endl;
896
897 // cout << " 4 ------------------ lateral correction"<<endl;
898 // gBenchmark->Print("conta");
899
900 if(GetQ(1)<1){
901 cout<<"Don't go on ..GetQ(1) "<<GetQ(1)<<endl;
902 return false;
903 }
904
905 // -----------------------------------------
906 // apply longitudinal correction
907 //possible dolongfit values are:
908 //-1 don't apply longitudinal correction
909 //0 apply to q0 (charge collected by each plane inside RMAX)
910 //1 apply to q1 (charge collected by each plane with lateral collection inside RMAX )
911 // -----------------------------------------
912
913 if(dolongfit<0) return true;
914
915 int ret = ApplyLongitudinalFit(dolongfit);
916
917 // cout << " 5 ------------------ longitudinal fit"<<endl;
918 // gBenchmark->Print("conta");
919
920 if( ret==0 ){
921 corr = ApplyLateralCorrection( GetShowerMaximum(2) );
922 ret = ApplyLongitudinalFit(dolongfit);
923 corr__l = GetLongitudinalCorrection();
924 chi2 = ProfileTest();
925 }
926 if(debug){
927 cout << "LATERAL CORRECTION FACTOR (iterated) = "<<corr<<endl;
928 cout << "LONGITUDINAL CORRECTION FACTOR = "<<corr__l<<endl;
929 }
930 // cout << " 6 ------------------ iteration"<<endl;
931 // gBenchmark->Print("conta");
932
933 // if(ret==0 || ret==10){
934 // if(debug)cout << ">> Longitudinal correction from level "<<dolongfit<<" corr__l "<<corr__l<<endl;
935 // if(GetLongitudinalFcnout()>600){
936 // cout<< "too big GetLongitudinalFcnout() "<<GetLongitudinalFcnout()<<endl;
937 // //return false;
938 // }
939 // }else{
940 // cout<< ">> problems with Longitudinal correction!"<<endl;
941 // //return false;
942 // }
943
944
945
946 return true;
947
948 }
949 /**
950 * \brief Set event
951 */
952 bool CaloElectron::Set(CaloLevel1 *cl1, CaloTrkVar* ctrk){
953
954 if(!cl1 ||!ctrk){
955 cout <<" void CaloElectron::Set(CaloLevel1 *cl1, CaloTrkVar* ctrk) -- ERROR -- input == NULL"<<endl;
956 return false;
957 }
958
959 float trackcoordinate[22][2];
960
961 for(int ip=0; ip<22; ip++){
962 for(int iv=0; iv<2; iv++){
963 trackcoordinate[ip][iv]=ctrk->tbar[ip][iv];
964 // trkstrip[ip][iv]=ctrk->tibar[ip][iv];
965 }
966 }
967 return Set(cl1,trackcoordinate);
968
969 };
970 /**
971 * \brief Set event
972 */
973 bool CaloElectron::Set(PamLevel2 *l2, int ntr){
974
975 CaloLevel1* cl1 = l2->GetCaloLevel1();
976 CaloTrkVar* ctrk = 0;
977 if( ntr < l2->GetTrkLevel2()->GetNTracks() )ctrk = l2->GetTrack(ntr)->GetCaloTrack();
978 return Set(cl1,ctrk);
979
980 };
981
982
983 /**
984 * \brief Method to apply lateral correction
985 * @param maxl shower maximum, in units of W-layers
986 */
987 float CaloElectron::ApplyLateralCorrection( float maxl ){
988
989 bool debug = CaloElectron_parameters::Get()->debug;
990 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
991 // float RMAX = CaloElectron_parameters::Get()->RMAX;
992 int ipmin = CaloElectron_parameters::Get()->ipmin;
993 int ipmax = CaloElectron_parameters::Get()->ipmax;
994
995 if( debug ) cout << "CaloElectron::ApplyLateralCorrection(maxl="<<maxl<<")"<<endl;
996
997 if( maxl <=0 )return 0.;
998 if( GetQ(0) <=0 )return 0.;
999
1000 for(int ip=ipmin; ip<ipmax; ip++){
1001 for(int iv=1; iv>=0; iv--){
1002
1003 double corr=1.;
1004 // evaluate the shower-depth of the plane
1005 float nlayer = (float)GetNWLayers(ip,iv);
1006 double tau = (double)(nlayer-ipmin)/(double)maxl;
1007 int ibintau = (int)(tau/0.25);
1008 if( ibintau>=12 ) ibintau=11;
1009 // retrieve the coordinate of the bottom-left corner of the plane
1010 float xcorner = 0;
1011 float ycorner = 0;
1012 GetCornerCoord(ip,iv,xcorner,ycorner);
1013 // evaluate track coordinate relative to the plane corner
1014 double xpl = (double)trkcoordx[ip][iv] - (double)xcorner;
1015 double ypl = (double)trkcoordy[ip][iv] - (double)ycorner;
1016 // trkcoordxpl[ip][iv] = xpl;
1017 // trkcoordypl[ip][iv] = ypl;
1018 //cout<<"ip "<<ip<<" iv "<<iv<<" xpl "<<xpl<<" ypl "<<ypl<<" trkcoordx "<<trkcoordx[ip][iv]<<" trkcoordy "<<trkcoordy[ip][iv]<<endl;
1019 // -----------------------------------------------------
1020 // evaluate lateral correction if:
1021 // - the plane is traversed by the track (tplane!=-100)
1022 // - the plane is not the first active layer (tplane =0)
1023 // - the plane correspond to tau lower then TAUMAX
1024 // -----------------------------------------------------
1025 corr=1.;//correction has no effect if tau>TAUMAX
1026 bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
1027 // if( !maskpl[ip][iv] ){
1028 if( !maskpl ){
1029 if( tplane[ip][iv] > 0 && tau<TAUMAX ){
1030 int iiv=0;
1031 if(iv==0) iiv=0;
1032 if(iv==1 && ip%2) iiv=1;
1033 if(iv==1 && !ip%2) iiv=2;
1034 corr = GetLateralCorrection(xpl,ypl,ibintau,iiv);
1035 }
1036 }
1037 qplane1[ip][iv] = qplane0[ip][iv] / corr;
1038 // if(debug && corr<0.5){
1039 // cout <<" qp0 "<<qplane0[ip][iv];
1040 // cout <<" qp1 "<<qplane1[ip][iv];
1041 // cout <<" ip "<<ip<<" iv "<<iv<<" tau "<<tau<<endl;
1042 // }
1043 }
1044 }
1045
1046 return GetQ(1)/GetQ(0);
1047
1048 // corr = GetQ(1)/GetQ(0);
1049
1050 // //questo disegna due grafici con la carica rilasciata nelle viste x e y prima e dopo la correzione
1051 // if(dodrawq0q1){
1052
1053 // Double_t tgx[22],tgy[22],qx[22],qy[22],qx1[22],qy1[22];
1054
1055 // for(int ip=0; ip<22; ip++){
1056 // tgx[ip]=tplane[ip][0];
1057 // tgy[ip]=tplane[ip][1];
1058 // qx[ip]=qplane0[ip][0];
1059 // qy[ip]=qplane0[ip][1];
1060 // qx1[ip]=qplane1[ip][0];
1061 // qy1[ip]=qplane1[ip][1];
1062 // }
1063
1064 // TGraph *gqx= new TGraph(22,tgx,qx);
1065 // TGraph *gqy= new TGraph(22,tgy,qy);
1066 // TGraph *gqx1= new TGraph(22,tgx,qx1);
1067 // TGraph *gqy1= new TGraph(22,tgy,qy1);
1068 // TCanvas a;a.Divide(2,1);a.cd(1);
1069 // a.cd(1);
1070 // gqx1->SetMarkerColor(2);gqx1->SetMarkerStyle(7);gqx1->Draw("AP");
1071 // gqx->SetMarkerColor(1);gqx->SetMarkerStyle(7);gqx->Draw("Psame");
1072 // a.cd(2);
1073 // gqy1->SetMarkerColor(2);gqy1->SetMarkerStyle(7);gqy1->Draw("AP");
1074 // gqy->SetMarkerColor(1);gqy->SetMarkerStyle(7);gqy->Draw("Psame");
1075 // a.Update();
1076 // int salvalo;
1077 // cout<<"save dodrawq0q1 (1 yes, 0 no)??";
1078 // cin>>salvalo;
1079 // if(salvalo>1) a.Print(Form("./gq0q1_%d.root",salvalo));
1080 // else if(salvalo==1) a.Print("electronq0q1.root");
1081
1082 // }// end of if(dodrawq0q1)
1083
1084 // //questo disegna la distribuzione laterale sul un certo piano e vista
1085 // //con la posizione dei gap e la funzione usata per correggere
1086 // if(dodrawq0q1){
1087
1088 // int iv,ip,iiv(0);
1089 // float iwmax,iw;
1090 // cout<<"which plane and view?"<<endl;
1091 // cin>>ip>>iv;
1092 // if(iv==0)iiv=0;
1093 // if(iv==1 && ip%2) iiv=1;
1094 // if(iv==1 && !ip%2) iiv=2;
1095 // iwmax=GetShowerMaximum(0);
1096 // iw=ip+(iv-1);
1097 // int ibintau=(int)((iw/iwmax)/0.25);
1098 // cout<<"plane "<<ip<<" iv "<<iv<<" iiv "<<iiv<<" iwmax "<<iwmax<<" iw "<<iw<<" ibintau "<<(iw/iwmax)/0.25<<" "<<ibintau<<" ..setting parameter "<<endl;
1099 // cout<<file_rt[ibintau][iiv]<<" "<<file_p[ibintau][iiv]<<" "<<file_rc[ibintau][iiv]<<endl;
1100 // if(ibintau>=12) ibintau=11;
1101 // int nparam=5;
1102 // TF1 ff = TF1("fradpro",fradpro,-RMAXsp,RMAXsp,nparam);
1103 // Double_t param[5];
1104 // param[0]=file_rt[ibintau][iiv];
1105 // param[1]=file_p[ibintau][iiv];
1106 // param[2]=file_rc[ibintau][iiv];
1107 // param[3]=qplane0[ip][iv];
1108 // //param[4]=trkcoordx[ip][iv];
1109 // param[4]=0.;
1110 // cout<<"plane "<<ip<<" iv "<<iv<<" ibintau "<<ibintau<<" ..setting parameter "<<endl;
1111 // for(int i=0;i<nparam;i++){
1112 // ff.SetParameter(i,param[i]);
1113 // cout<<" "<<i<<" -> "<<param[i]<<endl;
1114 // }
1115
1116
1117 // CaloStrip st = CaloStrip();
1118 // CaloStrip st1 = CaloStrip();
1119 // CaloStrip st2 = CaloStrip();
1120 // if(isimu==0)st.UseStandardAlig();
1121 // if(isimu==1)st.UseMechanicalAlig();
1122 // TH1F *hgap=new TH1F("hgap","hgap",34,-RMAXsp,RMAXsp);
1123 // float posgap1(0),posgap2(0);
1124 // st1.Set(iv,ip,31);st2.Set(iv,ip,32);
1125 // if (iv==0) posgap1=(st1.GetX()+st2.GetX())/2.-trkcoordx[ip][iv];
1126 // if (iv==1) posgap1=(st1.GetY()+st2.GetY())/2.-trkcoordy[ip][iv];
1127 // st1.Set(iv,ip,63);st2.Set(iv,ip,64);
1128 // if (iv==0) posgap2=(st1.GetX()+st2.GetX())/2.-trkcoordx[ip][iv];
1129 // if (iv==1) posgap2=(st1.GetY()+st2.GetY())/2.-trkcoordy[ip][iv];
1130
1131 // hgap->Fill(posgap1,100.);
1132 // hgap->Fill(posgap2,100.);
1133
1134
1135 // TH1F *h=new TH1F("h","h",34,-RMAXsp,RMAXsp);
1136 // float binsize=8./34.;
1137 // double e(0),d(0),etot(0);
1138 // for(int is=0;is<96;is++){
1139 // e=enestr[is][ip][iv];
1140 // if(e>0.){
1141 // st.Set(iv,ip,is);
1142 // if (iv==0) d=st.GetX()-trkcoordx[ip][iv];
1143 // if (iv==1) d=st.GetY()-trkcoordy[ip][iv];
1144 // if(TMath::Abs(d)<RMAXsp){
1145 // etot=etot+e;
1146 // cout<<"filling is "<<is<<" d "<<d<<" e "<<e<<endl;
1147 // h->Fill(d,e/binsize);
1148 // }
1149 // }
1150 // }
1151 // TCanvas a;a.Divide(2,1);a.cd(1);
1152 // h->Draw();//ff.Draw("same");
1153 // a.cd(2);ff.Draw(); h->Draw("same");hgap->SetFillColor(2);hgap->Draw("same");
1154 // a.Update();
1155 // cout<<"plane "<<ip<<" iv "<<iv<<" corr "<<qplane1[ip][iv]/qplane0[ip][iv]<<endl;
1156 // cout<<" h->Integral(width) "<<h->Integral("width")<<" h->Integral() "<<h->Integral()<<" ff.Integral() "<<ff.Integral(-12.,12.,param,1.e-12)<<" etot "<<etot<<endl;
1157
1158 // int salvalo;
1159 // cout<<"save dodrawlat (1 yes, 0 no)??";
1160 // cin>>salvalo;
1161 // //potrei provare a calcolare il fattore di correzione su ogni piano da questo confronto e
1162 // //confrontarlo con quello che viene dal mio metodo
1163
1164 // }
1165
1166 // return corr;
1167
1168 }
1169 ////////////////////////////////////////////////////////////////////////
1170 /**
1171 * 1-dimension function describing lateral distribution of the
1172 * shower as viewed by calorimeter
1173 * (projection of 3d function in one direction)
1174 *
1175 * xi[0] = x or y coordinate relative to shower axis
1176 * parmin[0] = rt
1177 * parmin[1] = p
1178 * parmin[2] = rc
1179 * parmin[3] = norm
1180 * parmin[4] = x0,y0
1181 *
1182 */
1183 ////////////////////////////////////////////////////////////////////////
1184 double fradpro(Double_t *xi, Double_t *parmin) {
1185
1186 double fradpromin2,p,rt,rc,es,x,pig,norm,c;
1187 x = *xi;
1188 pig = acos(-1.);
1189
1190 rt = parmin[0];
1191 p = parmin[1];
1192 rc = parmin[2];
1193
1194 norm = parmin[3];
1195 c = parmin[4];
1196 x = x-c;
1197 es = 1.5;
1198 fradpromin2 = p*pig*pow(rc,2)/pow((pow(x,2)+pow(rc,2)),es);
1199 fradpromin2 = fradpromin2+(1-p)*pig*pow(rt,2)/pow((pow(x,2)+pow(rt,2)),es);
1200 fradpromin2 = norm*fradpromin2/(2*pig);
1201 //cout<<"x,fradpromin2 "<< x<<" "<<fradpromin2 <<endl;
1202 return fradpromin2;
1203 }
1204 ////////////////////////////////////////////////////////////////////////
1205 /**
1206 * 2-dimension function describing lateral distribution of the shower
1207 *
1208 * xyi[0] = x coordinate relative to shower axis
1209 * xyi[1] = y coordinate relative to shower axis
1210 * parmin[0] = rt
1211 * parmin[1] = p
1212 * parmin[2] = rc
1213 *
1214 */
1215 ////////////////////////////////////////////////////////////////////////
1216 double frad(double *xyi, double *parmin) {
1217
1218 double fradout,p,rt,rc,pig,r2;
1219
1220 r2 = pow(xyi[0],2)+pow(xyi[1],2);
1221 pig = acos(-1.);
1222
1223 rt = parmin[0];
1224 p = parmin[1];
1225 rc = parmin[2];
1226
1227 fradout = p*2*pow(rc,2)/pow((r2+pow(rc,2)),2);
1228 fradout = fradout+(1-p)*2*pow(rt,2)/pow((r2+pow(rt,2)),2);
1229 fradout = fradout/(2*pig);
1230
1231 return fradout;
1232 };
1233 ////////////////////////////////////////////////////////////////////////
1234 /**
1235 * 2-dimension function describing lateral distribution of the shower, with
1236 * the second variable implemented as a parameter
1237 *
1238 * xyi[0] = x or y coordinate relative to shower axis
1239 * parmin[0] = rt
1240 * parmin[1] = p
1241 * parmin[2] = rc
1242 * parmin[3] = other coordinate
1243 *
1244 */
1245 ////////////////////////////////////////////////////////////////////////
1246 double fradx(double *xyi, double *parmin) {
1247
1248 double fradout,p,rt,rc,pig,r2;
1249
1250 r2 = pow(xyi[0],2)+pow(parmin[3],2);
1251 pig = acos(-1.);
1252
1253 rt = parmin[0];
1254 p = parmin[1];
1255 rc = parmin[2];
1256
1257 fradout = p*2*pow(rc,2)/pow((r2+pow(rc,2)),2);
1258 fradout = fradout+(1-p)*2*pow(rt,2)/pow((r2+pow(rt,2)),2);
1259 fradout = fradout/(2*pig);
1260
1261 return fradout;
1262 };
1263
1264
1265 /**
1266 * \brief Evaluate lateral correction factor
1267 */
1268 double CaloElectron::GetLateralCorrection(double xpl, double ypl, int ibintau, int iv){
1269
1270 TF2 ff = TF2("frad",frad,-25.,25.,-25.,25.,3);
1271
1272 int ivqui = iv;
1273
1274 float file_rt = CaloElectron_parameters::Get()->file_rt[ibintau][ivqui];
1275 float file_p = CaloElectron_parameters::Get()->file_p[ibintau][ivqui];
1276 float file_rc = CaloElectron_parameters::Get()->file_rc[ibintau][ivqui];
1277
1278 ff.SetParameter(0,file_rt);
1279 ff.SetParameter(1,file_p);
1280 ff.SetParameter(2,file_rc);
1281
1282 double corr = GetLateralCorrection(xpl,ypl,&ff,iv);
1283 return corr;
1284 };
1285 /**
1286 * \brief Evaluate lateral correction factor
1287 */
1288 double CaloElectron::GetLateralCorrection(double xpl, double ypl, TF2* ff,int iv){
1289
1290 float RMAXsp = CaloElectron_parameters::Get()->RMAXsp;
1291 float RMAX = CaloElectron_parameters::Get()->RMAX;
1292
1293 double x1,x2,x3,x4,x5,x6,ps[3];
1294 x1 = DEAD;
1295 x2 = x1 + PITCH*32;
1296 x3 = x2 + DEAD + GLUE + DEAD;
1297 x4 = x3 + PITCH*32;
1298 x5 = x4 + DEAD + GLUE + DEAD;
1299 x6 = x5 + PITCH*32;
1300 ps[0] = x1;
1301 ps[1] = x3;
1302 ps[2] = x5;
1303 double integgap(0),integgaptmp(0),integnogap(0),correggif(0);
1304 double epsil=0.0001;
1305 for (Int_t ii=0;ii<3;ii++){
1306 for (Int_t jj=0;jj<3;jj++){
1307 double xmi = ps[ii] - xpl;
1308 double xma = xmi + PITCH*32;
1309 double ymi = ps[jj] - ypl;
1310 double yma = ymi + PITCH*32;
1311 int dointeg=1;
1312 if(iv==0){
1313 if(xmi<-RMAXsp && xma>-RMAXsp) xmi=-RMAXsp;
1314 if(xma>RMAXsp && xmi<RMAXsp) xma=RMAXsp;
1315 if(xmi>RMAXsp || xma<-RMAXsp)dointeg=0;
1316 }
1317 if(iv==1 || iv==2){
1318 if(ymi<-RMAXsp && yma>-RMAXsp) ymi=-RMAXsp;
1319 if(yma>RMAXsp && ymi<RMAXsp) yma=RMAXsp;
1320 if(ymi>RMAXsp || yma<-RMAXsp)dointeg=0;
1321 }
1322 if(dointeg==1){
1323 integgaptmp=ff->Integral(xmi,xma,ymi,yma,epsil);
1324 integgap += integgaptmp;
1325 }
1326 }
1327 }
1328
1329 double RPMAX=40.;
1330 double xmin(0),xmax(0),ymin(0),ymax(0);
1331 if(iv==0){
1332 ymin=-RPMAX;
1333 ymax=RPMAX;
1334 xmin=-RMAX;
1335 xmax=RMAX;
1336 }
1337 if(iv==1 || iv==2){
1338 xmin=-RPMAX;
1339 xmax=RPMAX;
1340 ymin=-RMAX;
1341 ymax=RMAX;
1342 }
1343 integnogap=ff->Integral(xmin,xmax,ymin,ymax,epsil);
1344
1345 correggif=integgap/integnogap;
1346
1347 return correggif;
1348
1349 }
1350 // ---------------------------------------------------------------------
1351 // TMinuit does not allow fcn to be a member function, and the function
1352 // arguments are fixed, so the one of the only ways to bring the data
1353 // into fcn is to declare the data as global.
1354 // ---------------------------------------------------------------------
1355 //
1356 Int_t iuse;
1357 Double_t zfit[44],tfit[44],errorzfit[44],errortfit[44];
1358 //Float_t corr,m,q,lp1m,lp2m,sig1,sig2;Float_t parglobali[4];
1359 //______________________________________________________________________________
1360 Double_t func(Double_t *tin,Double_t *par)
1361 {
1362
1363 Double_t gaa,a,tm,et,value,t,t0;
1364 t = *tin;
1365 et = par[0];
1366 a = par[1];
1367 tm = par[2];
1368 t0 = par[3];
1369 gaa = TMath::Gamma(a);
1370
1371 value = et*((a-1)/(tm*gaa))*pow(((a-1)*(t-t0)/tm),(a-1))*exp(-(a-1)*(t-t0)/tm);
1372
1373 return value;
1374 }
1375 //______________________________________________________________________________
1376 // fcn passes back f = chisq the function to be minimized.
1377 void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
1378 {
1379
1380 int iusequi=0;
1381 Double_t chisq = 0.;
1382 for (int i=0;i<iuse; i++) {
1383 if(tfit[i]>=par[3]){
1384 iusequi++;
1385 Double_t fu=func(&tfit[i],par);
1386 Double_t delta = (zfit[i]-fu)/errorzfit[i];
1387 chisq += delta*delta;
1388 }
1389 }
1390
1391 //cout<<"iusequi,par,fcn "<<iusequi<<" "<<par[0]<<" "<<par[1]<<" "<<par[2]<<" "<<chisq<<endl;
1392 f = chisq;
1393
1394 }
1395
1396 /**
1397 * \brief Method to apply longitudinal correction
1398 * @param longto Fit options:
1399 * -1 don't apply longitudinal correction
1400 * 0 apply to q0 (charge collected by each plane inside RMAX)
1401 * 1 apply to q1 (charge collected by each plane with lateral collection inside RMAX )
1402 */
1403 int CaloElectron::ApplyLongitudinalFit(int longto){
1404
1405 cout << "CaloElectron::ApplyLongitudinalFit("<<longto<<") ---> temporarily commented (problems with TMinuit!!)"<<endl;
1406
1407 // bool debug = CaloElectron_parameters::Get()->debug;
1408 // float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
1409 // // float RMAX = CaloElectron_parameters::Get()->RMAX;
1410 // int ipmin = CaloElectron_parameters::Get()->ipmin;
1411 // int ipmax = CaloElectron_parameters::Get()->ipmax;
1412
1413 // if( debug ) cout << "CaloElectron::ApplyLongitudinalFit("<<longto<<")"<<endl;
1414
1415 // float ipmaxl = ipmax-ipmin;
1416
1417 // /// ?????
1418 // if(GetShowerMaximum(longto)*TAUMAX<ipmax-ipmin){
1419 // corr__l = 1;
1420 // err__l = 10;
1421 // if(debug){
1422 // cout<<"GetShowerMaximum(longto) "<<GetShowerMaximum(longto)<<" TAUMAX "<<TAUMAX<<" ipmax-ipmin "<<ipmax-ipmin<<endl;
1423 // }else{
1424 // return err__l;
1425 // }
1426 // }
1427
1428 // // initialize TMinuit with a maximum of 5 params
1429 // TMinuit *minuit = new TMinuit(4);
1430
1431 // // cout << minuit << endl;
1432 // if(!debug) minuit->SetPrintLevel(-1);
1433 // if( debug) minuit->SetPrintLevel(-1);
1434 // minuit->SetFCN(fcn);
1435
1436
1437 // // cout << "<><><><><><><><><><><><><"<<endl;
1438 // // --------------------------------------------
1439 // // Set layers to be used for the fit
1440 // // --------------------------------------------
1441 // Double_t arglist[10];
1442 // Int_t ierflg = 0;
1443 // iuse = 0;//n.layers included in the fit
1444 // for(int ip=ipmin; ip<ipmin+ipmaxl; ip++){
1445 // //for(int iv=0; iv<2; iv++){
1446 // for(int iv=1; iv>=0; iv--){
1447 // bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
1448 // if(!maskpl){
1449 // if(longto==0) zfit[iuse] = qplane0[ip][iv];
1450 // if(longto==1) zfit[iuse] = qplane1[ip][iv];
1451 // tfit[iuse] = (double)tplane[ip][iv]-(double)tplane[ipmin][1];
1452 // errortfit[iuse] = 0.01;
1453 // errorzfit[iuse] = sqrt( zfit[iuse] );
1454 // if(zfit[iuse]<0.0001) errorzfit[iuse] = 1.;
1455 // // if(debug)cout<<"iuse,ip,iv,tplane,t,z "<<iuse<<" "<<ip<<" "<<iv<<" "<<tplane[ip][iv]<<" "<<tfit[iuse]<<" "<<zfit[iuse]<<endl;
1456 // iuse++;
1457 // }
1458 // }
1459 // }
1460 // if(debug)cout << "N.layers inlcuded in the fit: "<<iuse<<endl;
1461
1462 // // --------------------------------------------
1463 // // Set starting values and step sizes for param
1464 // // --------------------------------------------
1465 // Double_t size = (double)tplane[2][1]-(double)tplane[1][1];
1466 // Double_t initpar0 = 0;
1467 // for(int ip=ipmin+1; ip<ipmin+ipmaxl; ip++)
1468 // initpar0 = initpar0 + size*(zfit[ip*2]+zfit[ip*2-1])/2;
1469 // Double_t initpar2 = GetShowerMaximumX0(longto);
1470 // Double_t initpar1 = pow(initpar2,0.9);
1471 // Double_t initpar3 = 0.;
1472
1473 // Double_t vstart[4] = {initpar0, initpar1, initpar2, initpar3};
1474 // Double_t step[4] = {1.,0.1,1.,0.1};
1475 // Double_t limmin[4] = {0,0.,0.,0};
1476 // Double_t limmax[4] = {0,20.,20.,0};
1477 // string parname[4] = {"E","alpha","tm","t0"};
1478
1479 // // --------------------------------------------
1480 // // Now ready for minimization step with limits
1481 // // --------------------------------------------
1482 // if(debug)cout << "--------------------- First step (with limits): "<<endl;
1483 // for (int i=0; i<4; i++)
1484 // minuit->mnparm(i, parname[i].c_str(),vstart[i],step[i],limmin[i],limmax[i],ierflg);
1485 // minuit->FixParameter(3);//fix starting point
1486 // arglist[0] = 500;
1487 // minuit->mnexcm("MIGRAD", arglist ,1,ierflg);
1488 // err__l = ierflg;
1489 // if(ierflg>0){
1490 // if(debug){
1491 // cout<<"ierflg "<<ierflg<<" ma prova ad andare avanti"<<endl;
1492 // }else{
1493 // return err__l;
1494 // }
1495 // }
1496
1497 // Double_t vstart2[4];
1498 // Double_t vend[4],errvend[4];
1499
1500 // for(int i=0; i<4; i++){
1501 // minuit->GetParameter(i,vend[i],errvend[i]);
1502 // if(debug)cout<<setw(7)<<parname[i].c_str()<<" v-start "<<setw(10)<<vstart[i]<<" --> v-end "<<setw(10)<<vend[i]<<" +- "<<errvend[i]<<endl;
1503
1504 // }
1505
1506 // // // ===========================================
1507 // // // NB NB NB !!!!!!!!!!!!!
1508 // // // temporaneamente eseguo il secondo step
1509 // // // solo in modalita` debug
1510 // // // (chiedere spiegazioni a elena)
1511 // // // ===========================================
1512 // // if( debug && err__l ){
1513
1514 // // --------------------------------------------
1515 // // Now ready for minimization step without limits
1516 // // --------------------------------------------
1517 // if(debug)cout << "--------------------- Second step (without limits): "<<endl;
1518 // minuit->mnfree(0); //restore all fixed parameters
1519 // for (int i=0; i<4; i++){
1520 // vstart[i] = vend[i];
1521 // minuit->mnparm(i, parname[i].c_str(),vstart[i],step[i],0.,0.,ierflg);
1522 // }
1523 // minuit->FixParameter(3);//fix starting point
1524 // arglist[0] = 500;
1525 // minuit->mnexcm("MIGRAD", arglist ,1,ierflg);
1526 // err__l = ierflg;
1527 // if(ierflg>0){
1528 // if(debug){
1529 // cout<<"ierflg "<<ierflg<<" ma prova ad andare avanti"<<endl;
1530 // }else{
1531 // return err__l;
1532 // }
1533 // }
1534 // for(int i=0; i<4; i++){
1535 // minuit->GetParameter(i,vend[i],errvend[i]);
1536 // if(debug)cout<<setw(7)<<parname[i].c_str()<<" v-start "<<setw(10)<<vstart[i]<<" --> v-end "<<setw(10)<<vend[i]<<" +- "<<errvend[i]<<endl;
1537 // }
1538
1539 // // }
1540
1541 // // --------------------------------------------
1542 // // retrive parameters
1543 // // --------------------------------------------
1544 // // Double_t tup = TAUMAX*initpar2;
1545 // // TF1 *ffunc = new TF1("ffunc",func,0.,tup,4);
1546 // // ffunc->SetLineWidth(1);
1547 // for(int i=0; i<4; i++){
1548 // par__l[i] = vend[i];
1549 // if(par__l[i]<0 || par__l[2]>22 || par__l[1]>50){
1550 // cout<<" converge a valori assurdi... escluso"<<endl;
1551 // err__l = 5;
1552 // return err__l;
1553 // }
1554 // }
1555
1556 // if(debug)cout << "--------------------- DONE! "<<endl;
1557
1558
1559 // for(int ip=0; ip<22; ip++){
1560 // for(int iv=0; iv<2; iv++){
1561 // bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
1562 // if(!maskpl){
1563 // double tpla = (double)tplane[ip][iv];
1564 // Double_t fu1=func(&tpla,vend);
1565 // qplanefit[ip][iv] = fu1;
1566 // }
1567 // }
1568 // }
1569
1570 // Double_t graddummy[4];
1571 // double outfcn;
1572 // minuit->Eval(4,graddummy,outfcn,vend,1);
1573
1574 // if(iuse>3)chi2__l = (float)outfcn/(float)(iuse-3);
1575 // else chi2__l = 0.;
1576
1577 // delete minuit;
1578
1579 return err__l;
1580
1581 }
1582 /*
1583 * \brief Evaluate longitudinal correction
1584 */
1585 float CaloElectron::GetLongitudinalCorrection(){
1586
1587 bool debug = CaloElectron_parameters::Get()->debug;
1588 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
1589 int ipmin = CaloElectron_parameters::Get()->ipmin;
1590 int ipmax = CaloElectron_parameters::Get()->ipmax;
1591 // --------------------------------------------
1592 // evaluate longitudinal
1593 // --------------------------------------------
1594 Double_t corr = 0.;
1595 Double_t t3,intecalo3,intecalo,tmaxcalo;
1596 if( err__l == 0 ){
1597 t3 = par__l[3] + TAUMAX*par__l[2];
1598 TF1 *ffunc = GetFunc_Longitudinal();
1599 intecalo3 = ffunc->Integral(par__l[3],t3);
1600 // if(debug)cout<<"integro da "<<par__l[3]<<" fino a t3 "<<t3<<" trovo intecalo3 "<<intecalo3<<endl;
1601 tmaxcalo = (double)tplane[ipmax-1][0]-(double)tplane[ipmin][1];
1602 if(t3<tmaxcalo){//if(t3<tplane[21][0]){
1603 intecalo=intecalo3;
1604 // if(debug)cout<<"siccome tmaxcalo "<<tmaxcalo<<" >t3 "<<" intecalo=intecalo3 "<<endl;
1605 }else{
1606 intecalo=ffunc->Integral(par__l[3],tmaxcalo);
1607 // if(debug)cout<<"integro da "<<par__l[3]<<" fino a tmaxcalo "<<tmaxcalo<<" trovo intecalo3 "<<intecalo<<endl;
1608 }
1609 corr = intecalo3/intecalo;
1610 }else{
1611 corr=0;
1612 }
1613
1614 corr__l = (float)corr;
1615
1616 if(debug) cout<<"Longitudinal correction: "<<corr__l<<endl;
1617
1618 return corr__l;
1619
1620 }
1621 /////////////////////////////////////////////////////////////////////
1622 //
1623 //
1624 //
1625 //
1626 /////////////////////////////////////////////////////////////////////
1627 TGraphErrors *CaloElectron::GetGraph_Longitudinal(){
1628 TGraphErrors *graph = new TGraphErrors(iuse ,tfit,zfit,errortfit,errorzfit);
1629 graph->SetMarkerSize(0.8);
1630 graph->SetMarkerStyle(20);
1631 return graph;
1632 }
1633 //
1634 TGraphErrors *CaloElectron::GetGraph_Longitudinal_Fit(){
1635 double zfunc[44];
1636 double errorzfunc[44];
1637 TF1 *fu = new TF1("fu",func,0.,tfit[iuse-1],4);
1638 for(int i=0; i<4; i++)fu->SetParameter(i,par__l[i]);
1639 for(int i=0; i<iuse; i++){
1640 zfunc[i] = fu->Eval(tfit[i]);;
1641 errorzfunc[i] = 0.;
1642 if(zfunc[i]>0.)errorzfunc[i] = sqrt(zfunc[i]);
1643 }
1644 delete fu;
1645 TGraphErrors *graph = new TGraphErrors(iuse,tfit,zfunc,errortfit,errorzfunc);
1646 graph->SetMarkerSize(0.8);
1647 graph->SetMarkerColor(2);
1648 graph->SetMarkerStyle(20);
1649 return graph;
1650 }
1651 //
1652 TGraphErrors *CaloElectron::GetGraph_Longitudinal_Integral(){
1653 double zfitint[44];
1654 double errorzfitint[44];
1655 zfitint[0] = zfit[0];
1656 for(int i=1; i<iuse; i++){
1657 zfitint[i] = zfitint[i-1]+zfit[i];
1658 errorzfitint[i] = sqrt(zfitint[i]);
1659 }
1660 TGraphErrors *graph = new TGraphErrors(iuse,tfit,zfitint,errortfit,errorzfitint);
1661 graph->SetMarkerSize(0.8);
1662 graph->SetMarkerStyle(24);
1663 return graph;
1664 }
1665 //
1666 TGraphErrors *CaloElectron::GetGraph_Longitudinal_Integral_Fit(){
1667 double zfunc[44];
1668 double errorzfunc[44];
1669 TF1 *fu = new TF1("fu",func,0.,tfit[iuse-1],4);
1670 for(int i=0; i<4; i++)fu->SetParameter(i,par__l[i]);
1671 zfunc[0] = fu->Eval(tfit[0]);;
1672 for(int i=1; i<iuse; i++){
1673 zfunc[i] = zfunc[i-1] + fu->Eval(tfit[i]);;
1674 errorzfunc[i] = 0.;
1675 if(zfunc[i]>0.)errorzfunc[i] = sqrt(zfunc[i]);
1676 }
1677 delete fu;
1678 TGraphErrors *graph = new TGraphErrors(iuse,tfit,zfunc,errortfit,errorzfunc);
1679 graph->SetMarkerSize(0.8);
1680 graph->SetMarkerStyle(24);
1681 graph->SetMarkerColor(2);
1682 graph->SetLineColor(2);
1683 return graph;
1684 }
1685 //
1686 TF1 *CaloElectron::GetFunc_Longitudinal(){
1687 TF1 *fu = new TF1("longitudinalprofile",func,0.,tfit[iuse-1],4);
1688 for(int i=0; i<4; i++)fu->SetParameter(i,par__l[i]);
1689 fu->SetLineColor(2);
1690 // fu->Draw();
1691 // if(err__l!=0)fu->SetLineStyle(12);
1692 return fu;
1693 }
1694 //
1695 TGraphErrors *CaloElectron::GetGraph_Lateral(int ipp, int ivv){
1696
1697 cout << "TGraphErrors *CaloElectron::GetGraph_Lateral("<<ipp<<","<<ivv<<") "<<endl;
1698 // cout <<"ooooooooo%%%%%%%%%%%%%%%%%%%%% "<< CaloElectron_parameters::Get() << endl;
1699 // cout <<"ooooooooo%%%%%%%%%%%%%%%%%%%%% "<< CaloElectron_parameters::Get()->cl1 << endl;
1700 CaloLevel1* cl1 = CaloElectron_parameters::Get()->cl1;
1701 if(!cl1)return NULL;
1702
1703 float xx[96];
1704 float qq[96];
1705 float errxx[96];
1706 float errqq[96];
1707 CaloStrip cstrip;
1708 for(int is=0; is<96; is++){
1709 cstrip.Set(ivv,ipp,is);
1710 float xy[2];
1711 xy[0] = cstrip.GetX() - trkcoordx[ipp][ivv];
1712 xy[1] = cstrip.GetY() - trkcoordy[ipp][ivv];
1713 qq[is] = 0.;
1714 xx[is] = xy[ivv];
1715 errqq[is] = 0.;
1716 errxx[is] = 0.5*PITCH;
1717 }
1718 // -----------------------------------
1719 // set charge collected in each plane
1720 // -----------------------------------
1721 int isimu = CaloElectron_parameters::Get()->isimu;
1722 if(isimu==0)cstrip = CaloStrip(cl1,false);
1723 if(isimu==1)cstrip = CaloStrip(cl1,true);
1724 for(int ih=0;ih<cl1->istrip;ih++){
1725 int iv=-1;
1726 int ip=-1;
1727 int is=-1;
1728 cl1->DecodeEstrip(ih,iv,ip,is);
1729 cstrip.Set(iv,ip,is);
1730 float xy[2];
1731 xy[0] = cstrip.GetX() - trkcoordx[ip][iv];
1732 xy[1] = cstrip.GetY() - trkcoordy[ip][iv];
1733 if( ip==ipp && iv==ivv ){
1734 qq[is] = cstrip.GetE();
1735 xx[is] = xy[iv];
1736 if(qq[is]>0)errqq[is] = sqrt( qq[is] );
1737 }
1738 }
1739 TGraphErrors *graph = new TGraphErrors(96,xx,qq,errxx,errqq);
1740 graph->SetMarkerSize(0.8);
1741 graph->SetMarkerStyle(20);
1742 return graph;
1743 }
1744 //
1745 // TF1 *CaloElectron::GetFunc_Lateral(int ip, int iv, int icorr){
1746
1747
1748 // int iiv(0);
1749 // if(iv==0)iiv=0;
1750 // if(iv==1 && ip%2) iiv=1;
1751 // if(iv==1 && !ip%2) iiv=2;
1752
1753 // float iwmax,iw;
1754 // iwmax = GetShowerMaximum(icorr);
1755 // iw = ip+(iv-1);
1756 // int ibintau = (int)((iw/iwmax)/0.25);
1757 // if(ibintau>=12) ibintau=11;
1758
1759
1760 // float file_rt = CaloElectron_parameters::Get()->file_rt[ibintau][iiv];
1761 // float file_p = CaloElectron_parameters::Get()->file_p[ibintau][iiv];
1762 // float file_rc = CaloElectron_parameters::Get()->file_rc[ibintau][iiv];
1763 // float RMAXsp = CaloElectron_parameters::Get()->RMAXsp;
1764
1765 // int nparam=5;
1766 // TF1 *ff = new TF1("fradpro",fradpro,-RMAX,RMAX,nparam);
1767 // Double_t param[5];
1768 // param[0] = file_rt;
1769 // param[1] = file_p;
1770 // param[2] = file_rc;
1771 // param[3] = qplanefit[ip][iv];//qplane0[ip][iv];
1772 // param[4] = 0.;
1773 // for(int i=0;i<nparam;i++){
1774 // ff->SetParameter(i,param[i]);
1775 // // cout<<" "<<i<<" -> "<<param[i]<<endl;
1776 // }
1777 // return ff;
1778
1779 // }
1780 /*
1781 * Return a graph with the integral of the 2-dimentional profile (normalized) over
1782 * each strip (taking into account the gaps).
1783 */
1784 TGraphErrors *CaloElectron::GetFunc_Lateral(int ip, int iv){
1785
1786 cout << "TGraphErrors *CaloElectron::GetFunc_Lateral("<<ip<<","<<iv<<",) "<<endl;
1787
1788 float xx[96];
1789 float qq[96];
1790 float errxx[96];
1791 float errqq[96];
1792 GetProfile(ip,iv,xx,qq,errxx,errqq);
1793
1794
1795 TGraphErrors *graph = new TGraphErrors(96,xx,qq,errxx,errqq);
1796 // graph->SetMarkerSize(0.8);
1797 // graph->SetMarkerStyle(1);
1798 graph->SetLineColor(2);
1799 return graph;
1800
1801 }
1802 /**
1803 * evaluate the expected average profile, by integrating the expected charge distribution
1804 * over each strip
1805 *
1806 */
1807 void CaloElectron::GetProfile(int ip, int iv, float xx[], float qq[],float errxx[], float errqq[] ){
1808
1809 // bool debug = CaloElectron_parameters::Get()->debug;
1810 // float xx[96];
1811 // float qq[96];
1812 // float errxx[96];
1813 // float errqq[96];
1814 CaloLevel1* cl1 = CaloElectron_parameters::Get()->cl1;
1815 if(!cl1)cout << " ERROR -- CaloLevel1* cl1 == NULL"<<endl;
1816 if(!cl1)return;
1817
1818 // x y-even or y-odd
1819 int iiv(0);
1820 if(iv==0) iiv = 0;
1821 if(iv==1 && ip%2) iiv = 1;
1822 if(iv==1 && !ip%2) iiv = 2;
1823
1824 // shower maximum ==> tau-bin
1825 // float iwmax,iw;
1826 // iwmax = GetShowerMaximum(icorr);
1827 // // iw = ip+(iv-1); //!!!!!!!!!!!!! BUG!?!?!
1828 // iw = ip-(iv-1);
1829 // int ibintau = (int)((iw/iwmax)/0.25);
1830 // if(ibintau>=12) ibintau=11;
1831 // cout << " maximum (W)"<<iwmax<<endl;
1832 // cout << " ip (W)"<<iw<<endl;
1833 // cout << " tau "<<iw/iwmax<<" tau-bin "<<ibintau<<endl;
1834 int ipmin = CaloElectron_parameters::Get()->ipmin;
1835 float maxl = GetShowerMaximum(2);
1836 float nlayer = (float)GetNWLayers(ip,iv);
1837 double tau = (double)(nlayer-ipmin)/(double)maxl;
1838 int ibintau = (int)(tau/0.25);
1839 if(ibintau>=12) ibintau=11;
1840 // if(debug){
1841 // cout << " maximum (W)"<<maxl<<endl;
1842 // cout << " ip (W)"<<nlayer<<endl;
1843 // cout << " tau "<<tau<<" tau-bin "<<ibintau<<endl;
1844 // }
1845 // retrieve lateral-profile parameters
1846 float file_rt = CaloElectron_parameters::Get()->file_rt[ibintau][iiv];
1847 float file_p = CaloElectron_parameters::Get()->file_p[ibintau][iiv];
1848 float file_rc = CaloElectron_parameters::Get()->file_rc[ibintau][iiv];
1849 float RMAXsp = CaloElectron_parameters::Get()->RMAXsp;
1850 // if(debug){
1851 // cout << " RT "<<file_rt<<endl;
1852 // cout << " RC "<<file_rc<<endl;
1853 // cout << " p "<<file_p<<endl;
1854 // }
1855 // 2-dimentional function
1856 TF2 ff = TF2("frad",frad,-25.,25.,-25.,25.,3);
1857 ff.SetParameter(0,file_rt);
1858 ff.SetParameter(1,file_p);
1859 ff.SetParameter(2,file_rc);
1860
1861 // 1-dimentional function
1862 TF1 fx = TF1("fradx",fradx,-25.,25.,4);
1863 fx.SetParameter(0,file_rt);
1864 fx.SetParameter(1,file_p);
1865 fx.SetParameter(2,file_rc);
1866
1867 // sensitive area
1868 double x1,x2,x3,x4,x5,x6,ps[3];
1869 x1 = DEAD;
1870 x2 = x1 + PITCH*32;
1871 x3 = x2 + DEAD + GLUE + DEAD;
1872 x4 = x3 + PITCH*32;
1873 x5 = x4 + DEAD + GLUE + DEAD;
1874 x6 = x5 + PITCH*32;
1875 ps[0] = x1;
1876 ps[1] = x3;
1877 ps[2] = x5;
1878
1879 // retrieve the coordinate of the bottom-left corner of the plane
1880 float corner[] = {0.,0.};
1881 GetCornerCoord(ip,iv,corner[0],corner[1]);
1882
1883
1884 // integral over each strip
1885 double integgap;
1886 double epsil = 0.0001;
1887 CaloStrip cstrip;
1888
1889 //
1890 for(int is=0; is<96; is++){ //loop over strips
1891 cstrip.Set(iv,ip,is);
1892 float xy[2];
1893 float trkcoord[2];
1894 trkcoord[0] = trkcoordx[ip][iv]; //track coordinate
1895 trkcoord[1] = trkcoordy[ip][iv];
1896 xy[0] = cstrip.GetX() - trkcoordx[ip][iv];//strip coordinate (relative to track)
1897 xy[1] = cstrip.GetY() - trkcoordy[ip][iv];
1898 //
1899 qq[is] = 0.;
1900 xx[is] = xy[iv];
1901 errqq[is] = 0.;
1902 errxx[is] = 0.5*PITCH;
1903 //
1904 integgap = 0.;
1905 for (Int_t jj=0;jj<3;jj++){ //loop over the 3 sensors
1906 //
1907 double ymi = ps[jj] + (double)corner[iv] - (double)trkcoord[iv];
1908 double yma = ymi + PITCH*32;
1909 double xmi = (double)xx[is]-(double)errxx[is];//strip size
1910 double xma = (double)xx[is]+(double)errxx[is];
1911 //
1912 int dointeg=1;
1913 if(iv==0){
1914 if(xmi<-RMAXsp && xma>-RMAXsp) xmi = -RMAXsp;
1915 if(xma>RMAXsp && xmi<RMAXsp) xma = RMAXsp;
1916 if(xmi>RMAXsp || xma<-RMAXsp) dointeg = 0;
1917 }
1918 if(iv==1 || iv==2){
1919 if(ymi<-RMAXsp && yma>-RMAXsp) ymi = -RMAXsp;
1920 if(yma>RMAXsp && ymi<RMAXsp) yma = RMAXsp;
1921 if(ymi>RMAXsp || yma<-RMAXsp) dointeg = 0;
1922 }
1923 if(dointeg==0) continue;
1924
1925 //
1926 bool DOFAST = false;
1927 if(fabs(xx[is])>2.)DOFAST=true;
1928
1929 double integral = 0.;
1930
1931 if(DOFAST){
1932 //
1933 // integrale veloce
1934 //
1935
1936 double fmi,fma,k,c;
1937 fx.SetParameter(3,xmi);
1938 fmi = fx.Integral(ymi,yma);
1939 fx.SetParameter(3,xma);
1940 fma = fx.Integral(ymi,yma);
1941 k = 0.;
1942 if(fmi>0.&&fma>0.&&(xma-xmi)>0.)k=log(fma/fmi)/(xma-xmi);
1943 c = log(fmi)-k*xmi;
1944 if(fabs(k)>1.e-6)integral += (fma-fmi)/k;
1945
1946 }else{
1947 //
1948 // integrale lento ma piu` preciso
1949 //
1950 integral = ff.Integral(xmi,xma,ymi,yma,epsil);
1951
1952 }
1953
1954 integgap += integral;
1955
1956 // cout << setw(2)<<jj<<setw(15)<<xmi<<setw(15)<<ymi<< setw(15)<<integral << setw(15)<<integgaptmp<<endl;
1957 }
1958
1959 qq[is] = integgap * qplanefit[ip][iv];
1960 // if( qq[is]>0 )errqq[is] = sqrt(qq[is]);
1961 }
1962 }
1963 /**
1964 *
1965 */
1966 float CaloElectron::ProfileTest(){
1967
1968 int ipmin = CaloElectron_parameters::Get()->ipmin;
1969 int ipmax = CaloElectron_parameters::Get()->ipmax;
1970 float RMAX = CaloElectron_parameters::Get()->RMAX;
1971 // float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
1972
1973 TH2F* h_qfit[2];
1974 TH2F* h_qtot[2];
1975 //
1976 // retrieve histrograms of shower lateral profile
1977 //
1978 for(int iv=0; iv<2; iv++){
1979 h_qfit[iv] = CaloElectron_parameters::Get()->h_qfit[iv]; //average
1980 if(!h_qfit[iv])return 0.;
1981 h_qfit[iv]->Reset(); //-->reset
1982
1983 h_qtot[iv] = CaloElectron_parameters::Get()->h_qtot[iv]; //data
1984 if(!h_qtot[iv])return 0.;
1985 }
1986
1987 // float maxl = GetShowerMaximum(2);
1988 //
1989 double chi2tmp = 0.;
1990 int ndof = 0;
1991 // cout << "<><><><><><><><><><><><><><>"<<endl;
1992 // cout << setw(3) << "IP" << setw(3) << "IV" ;
1993 // cout << setw(10) << "TAU";
1994 // cout << setw(10) << "RMS";
1995 // cout << setw(10) << "SKEW";
1996 // cout << setw(10) << "KURT";
1997 // cout << endl;
1998 //
1999 for(int ip=0; ip<22; ip++){ // loop over planes
2000 for(int iv=1; iv>=0; iv--){ // loop over views
2001 bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
2002 float corner[] = {0.,0.};
2003 GetCornerCoord(ip,iv,corner[0],corner[1]);
2004 if(
2005 ip >= ipmin &&
2006 ip < ipmax &&
2007 !maskpl &&
2008 true){
2009 //
2010 float xx[96];
2011 float qq[96];
2012 float errxx[96];
2013 float errqq[96];
2014 //
2015 float trkcoord[2];
2016 trkcoord[0] = trkcoordx[ip][iv];
2017 trkcoord[1] = trkcoordy[ip][iv];
2018 //
2019 GetProfile(ip,iv,xx,qq,errxx,errqq); //<<< average profile
2020 // float nlayer = (float)GetNWLayers(ip,iv);
2021 // double tau = (double)(nlayer-ipmin)/(double)maxl;
2022 for(int is=0; is<96; is++) {
2023 if(
2024 fabs(xx[is]) < RMAX &&
2025 // tau<TAUMAX &&
2026 true){
2027 // h_qfit[iv]->Fill( (float)(is+iv*96), (float)ip, qq[is]);
2028 h_qfit[iv]->Fill( xx[is]+trkcoord[iv]-corner[iv], (float)ip, qq[is]);
2029 float qqq = h_qtot[iv]->GetBinContent((is+iv*96+1),ip+1);
2030 // cout << setw(15)<< qqq<<setw(15)<<qq[is]<<setw(15)<<pow(qq[is]-qqq,2.)<< endl;
2031 if(qq[is]>0) chi2tmp += pow((double)(qq[is]-qqq),2.)/sqrt((double)qq[is]);
2032 ndof++;
2033 }
2034 }
2035 // cout << "<><><><><><><><><><><><><><>"<<endl;
2036 // cout << ip << " - "<<iv << endl;
2037 // TH1D* hfitpro = h_qfit[iv]->ProjectionX("hfitpx",ip+1,ip+2);
2038 TH1D* htotpro = h_qtot[iv]->ProjectionX("htotpx",ip+1,ip+2);
2039 // cout <<"Mean "<< setw(10)<<htotpro->GetMean() << setw(10)<<hfitpro->GetMean() << endl;
2040 // cout <<"RMS "<< setw(10)<<htotpro->GetRMS() << setw(10)<<hfitpro->GetRMS() << endl;
2041 // cout <<"Skew "<< setw(10)<<htotpro->GetSkewness() << setw(10)<<hfitpro->GetSkewness() << endl;
2042 // cout <<"Kurt "<< setw(10)<<htotpro->GetKurtosis() << setw(10)<<hfitpro->GetKurtosis() << endl;
2043 if(GetShowerMaximumX0(2)>0.)
2044 TAU[ip][iv] = tplane[ip][iv]/GetShowerMaximumX0(2);
2045 if(htotpro->GetEntries()>4){
2046 RMS[ip][iv] = htotpro->GetRMS();
2047 SKEW[ip][iv] = htotpro->GetSkewness();
2048 KURT[ip][iv] = htotpro->GetKurtosis();
2049 }
2050 // cout << setw(3) << ip << setw(3) << iv ;
2051 // cout << setw(10) << TAU[ip][iv];
2052 // cout << setw(10) << RMS[ip][iv];
2053 // cout << setw(10) << SKEW[ip][iv];
2054 // cout << setw(10) << KURT[ip][iv];
2055 // cout << endl;
2056 // hfitpro->Delete();
2057 htotpro->Delete();
2058 // cout << "<><><><><><><><><><><><><><>"<<endl;
2059 }
2060 }
2061 }
2062 // cout << "<><><><><><><><><><><><><><>"<<endl;
2063
2064 // double kolp = h_qfit->KolmogorovTest(h_qtot,"ND");
2065 // double kold = h_qfit->KolmogorovTest(h_qtot,"NDM");
2066 // h_qfit->Sumw2();
2067 // h_qtot->Sumw2();
2068 // double kolp = h_qfit->KolmogorovTest(h_qtot,"D");
2069 // double kold = h_qfit->KolmogorovTest(h_qtot,"DM");
2070 // double chi2tmp = h_qfit->Chi2Test(h_qtot,"WWP");
2071 // cout << "KKKKK "<<kolp << endl;
2072 // cout << "KKKKK "<<kold << endl;
2073 // cout << "KKKKK "<<chi2 << " "<<ndof<<" "<<chi2/(double)(ndof)<< endl;
2074 if( ndof>3 )chi2 = (float)(chi2tmp/(double)(ndof-3));
2075 else chi2 = 0.;
2076
2077 return chi2;
2078
2079 }
2080 /**
2081 *
2082 */
2083 float CaloElectron::GetMaxResidual(){
2084 float max = 0;
2085 for(int iv=0; iv<2; iv++){
2086 for(int ip=0; ip<22; ip++){
2087 if(
2088 // qplane1[ip][iv] > 0. &&
2089 // fabs(qplane1[ip][iv]-qplanefit[ip][iv])/sqrt(qplane1[ip][iv]) > fabs(max) &&
2090 fabs(qplane1[ip][iv]-qplanefit[ip][iv]) > fabs(max) &&
2091 true){
2092 max = qplane1[ip][iv]-qplanefit[ip][iv];
2093 }
2094 }
2095 }
2096 return max;
2097 }
2098 int CaloElectron::GetNRun(){
2099 bool POS = true;
2100 bool NEG = true;
2101 int nrun = 0;
2102 for(int ip=0; ip<22; ip++){
2103 for(int iv=1; iv>=0; iv--){
2104 if( qplane1[ip][iv] > qplanefit[ip][iv] && NEG ){
2105 nrun++;
2106 POS = true; NEG = !POS;
2107 }
2108 if( qplane1[ip][iv] <= qplanefit[ip][iv] && POS ){
2109 nrun++;
2110 NEG = true; POS = !NEG;
2111 }
2112 }
2113 }
2114 return nrun;
2115 }
2116 float CaloElectron::GetMaxRun(){
2117 bool POS = true;
2118 bool NEG = true;
2119 int nrun = 0;
2120 float sum[44]; for(int ip=0; ip<44; ip++)sum[ip]=0.;
2121 //
2122 for(int ip=0; ip<22; ip++){
2123 for(int iv=1; iv>=0; iv--){
2124 if( qplane1[ip][iv] > qplanefit[ip][iv] && NEG ){
2125 nrun++;
2126 POS = true; NEG = !POS;
2127 }
2128 if( qplane1[ip][iv] <= qplanefit[ip][iv] && POS ){
2129 nrun++;
2130 NEG = true; POS = !NEG;
2131 }
2132 sum[nrun-1] += qplane1[ip][iv]-qplanefit[ip][iv];
2133 }
2134 }
2135 //
2136 float max=0;
2137 for(int ip=0; ip<44; ip++)
2138 if( fabs(sum[ip]) > fabs(max) )max=sum[ip];
2139
2140 return max;
2141 }
2142 /**
2143 * \brief Method to retrieve the coordinates of the plane bottom-left corner
2144 * (l'angolo è dell'inizio del rivelatore compreso il dead)
2145 */
2146 void CaloElectron::GetCornerCoord(int ip, int iv, float& xorig, float& yorig){
2147
2148 // coordinate meccaniche dei piani in cm
2149
2150 CaloStrip st = CaloStrip();
2151 int isimu = CaloElectron_parameters::Get()->isimu;
2152 if(isimu==0)st.UseStandardAlig();
2153 if(isimu==1)st.UseMechanicalAlig();
2154
2155 yorig = -0.1*st.GetYalig()+0.1;
2156 xorig = -0.1*st.GetXalig();
2157
2158 if(ip%2!=1){
2159 //ip 0,2,4,6,...,20
2160 if(iv==0){
2161 yorig = yorig;
2162 xorig = xorig+0.05;
2163 }else{
2164 yorig = yorig-0.05;
2165 xorig = xorig+0.1;
2166 }
2167 }else{
2168 //ip 1,3,5,..,21
2169 if(iv==0){
2170 yorig = yorig-0.2;
2171 xorig = xorig-0.05;
2172 }else{
2173 yorig = yorig-0.15;
2174 xorig = xorig-0.1;
2175 }
2176 }
2177
2178
2179
2180
2181
2182
2183 }
2184 /**
2185 * \brief Print the event
2186 */
2187 void CaloElectron::Print(){
2188
2189 int ipmin = CaloElectron_parameters::Get()->ipmin;
2190 int ipmax = CaloElectron_parameters::Get()->ipmax;
2191 // cout<<"Print idiev "<<idiev<<endl;
2192 cout << " n. W-layers - qx0 qy0 -------> qx1 qy1 -------> qx(fit) qy(fit)"<<endl;
2193 float qx0,qy0,qx1,qy1,qx2,qy2;
2194 qx0=0.;
2195 qy0=0.;
2196 qx1=0.;
2197 qy1=0.;
2198 qx2=0.;
2199 qy2=0.;
2200 for(int il=ipmin; il<=ipmax; il++){
2201 if(il>ipmin){
2202 qx0 = qplane0[il-1][0];
2203 qy0 = qplane0[il][1];
2204 qx1 = qplane1[il-1][0];
2205 qy1 = qplane1[il][1];
2206 qx2 = qplanefit[il-1][0];
2207 qy2 = qplanefit[il][1];
2208 }
2209 if(il==ipmin){
2210 // qx0 = 0;
2211 qy0 = qplane0[ipmin][1];
2212 // qx1 = 0;
2213 qy1 = qplane1[ipmin][1];
2214 // qx2 = 0;
2215 qy2 = qplanefit[ipmin][1];
2216 }
2217 if(il==ipmax){
2218 qx0 = qplane0[ipmax-1][0];
2219 // qy0 = 0.;
2220 qx1 = qplane1[ipmax-1][0];
2221 // qy1 = 0.;
2222 qx2 = qplanefit[ipmax-1][0];
2223 // qy2 = 0.;
2224 }
2225 cout << " "<<setw(2)<<il<<" - "<<setw(10)<<qx0<<setw(10)<<qy0<<" "<<setw(10)<<qx1<<setw(10)<<qy1<<" "<<setw(10)<<qx2<<setw(10)<<qy2<<endl;
2226 }
2227 cout<<" "<<endl;
2228 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
2229 float RMAX = CaloElectron_parameters::Get()->RMAX;
2230 cout << "Total collectced charge (mip) "<<qtot<<endl;
2231 cout << "Charge outside cylinder ( RMAX="<<RMAX<<" ,TAUMAX="<<TAUMAX<<" )";
2232 cout << qtot - GetQ(0);
2233 if(qtot>0.)cout <<" ( "<< 100.*(qtot-GetQ(0))/qtot<<" % )"<<endl;
2234 for(int icorr=0;icorr<4;icorr++){
2235 cout << " ---------------------------------------------- "<<icorr;
2236 if(icorr==0)cout <<"(no corr.)"<<endl;
2237 if(icorr==1)cout <<"(lateral corr.)"<<endl;
2238 if(icorr==2)cout <<"(lateral+longitudinal corr.)"<<endl;
2239 if(icorr==3)cout <<"(fit)"<<endl;
2240 cout << " - Collected charge (mip) "<<GetQ(icorr)<<endl;
2241 cout << " - Shower maximum (W-layer, X0) "<<GetShowerMaximum(icorr)<<" "<<GetShowerMaximumX0(icorr)<<endl;
2242 cout << " - Energy (GeV) "<<GetEnergy(icorr)<<endl;
2243 }
2244 cout << "Longitudinal parameters:"<<endl;
2245 cout << "- E :"<<par__l[0]<<endl;
2246 cout << "- alpha :"<<par__l[1]<<endl;
2247 cout << "- Tm :"<<par__l[2]<<endl;
2248 cout << "- T0 :"<<par__l[3]<<endl;
2249 cout << "- chi2 :"<<chi2__l<<endl;
2250 cout << "- minuit status :"<<err__l<<endl;
2251 cout << endl ;
2252 cout << "- chi2 (global) :"<<chi2<<endl;
2253 cout << endl ;
2254
2255 // cout<<" rigidity "<<rig<<" qtotlevel2 "<<qtotl2<<endl;
2256
2257 }
2258 //______________________________________________________________________________
2259 Double_t paraloss(Double_t *tin,Double_t *par)
2260 {
2261
2262 Double_t t,p0,p1,p2,p3,t0,value;
2263 t=*tin;
2264 p0=par[0];
2265 p1=par[1];
2266 p2=par[2];
2267 p3=par[3];
2268 t0=1.7;//t0=1.5;
2269 Double_t paralossdit0=1.00659;
2270 if(t<t0) return paralossdit0;
2271 value=p0+p1*t+p2*pow(t,2)+p3*pow(t,3);
2272 return value;
2273 }
2274
2275 /**
2276 * \brief Collect corrected charge to energy
2277 */
2278 float CaloElectron::GetEnergy(int icorr){
2279
2280 float energy = 0;
2281 float collectedq = 0;
2282 float p0 = 0;
2283 float p1 = 0;
2284
2285 if(icorr == 0){
2286 // ---------------------------------------
2287 // before any correction
2288 // ---------------------------------------
2289
2290 //the same as energy 1.. not to be used
2291 p0=24.14;
2292 p1=253.3;
2293
2294 }else if(icorr == 1 || icorr == 3){
2295 // ---------------------------------------
2296 // after lateral correction 4 giugno 2007
2297 // ---------------------------------------
2298
2299 //linear (only with fit of points 5-15gev where longitudinal containment is satisfactory)
2300 //we expect a sistematic error for greater energies that has to be corrected by longitudinal fit
2301
2302 //10-9-07
2303 p0=24.14;
2304 p1=253.3;
2305
2306 }else if(icorr == 2){
2307 // ---------------------------------------
2308 // after longitudinal fit
2309 // ---------------------------------------
2310
2311 //10-9-07
2312 p0=-13.86;
2313 p1=264.4;
2314
2315
2316 }else{
2317
2318 return energy;
2319
2320 }
2321
2322 collectedq=GetQ(icorr);
2323 // if(onlyy)collectedq=collectedq*2;
2324
2325 energy = (collectedq-p0)/p1;
2326
2327 if(GetQ(icorr)<=0) energy=0.;
2328
2329 if(icorr == 3){
2330 TF1 *f4=new TF1("f4",paraloss,0.,3.,4);//f1->FixParameter(2,1.3);
2331 f4->SetParameter(0,-0.8013231);
2332 f4->SetParameter(1,2.276176);
2333 f4->SetParameter(2,-0.8295547);
2334 f4->SetParameter(3,0.06835571);
2335 float lnmax=TMath::Log(par__l[2]);
2336 float lnmax1=TMath::Log(GetShowerMaximumX0(1));
2337 if(lnmax>2.4 || GetIerflg()>0){
2338 cout<<"max "<<GetShowerMaximumX0(1)<<" "<<GetShowerMaximumX0(2)<<" lnmax "<<lnmax<<" ier "<<GetIerflg()<<endl;
2339 lnmax=lnmax1;
2340 }
2341 float corrparaloss=f4->Eval(lnmax);
2342 //cout<<"icorr 3...lnmax "<<lnmax<<" corrparaloss "<<corrparaloss<<endl;
2343 energy=energy/corrparaloss;
2344 }
2345
2346 return energy;
2347
2348 };
2349
2350 /*
2351 defined cuts to have gaussian error from calorimeter reconstruction for alignement purpose
2352 */
2353 bool CaloElectron::IsInsideFiducial(int level){
2354
2355
2356 // float ma=GetShowerMaximum(1);
2357 // if(ma>=20 || ma<=4)return false;
2358 // int ima=(int)ma+ipmin;
2359 // float strima=0;
2360 // for(int iv=0;iv<=1;iv++){
2361 // strima=GetStripW(ima,iv);
2362 // if(strima<11 || strima>86 || strima==33 || strima==32 || strima==65 || strima==64) return false;
2363 // }
2364
2365 // if(level==1) return true;
2366
2367 // if(outfcn>600) return false;
2368 // if(minuitierflg>0) return false;
2369 // float lma1=log(par__l[1]);
2370 // float lma2=log(par__l[2]);
2371 // float lma1expected=0.92*lma2;
2372 // if(lma2<1.3 || lma2>2.3) return false;
2373 // if(TMath::Abs(lma1-lma1expected)>0.5) return false;
2374
2375 return true;
2376
2377 }
2378
2379 //////////////////////////////////////////////////////////////////////////
2380
2381 /**
2382 * Fill calibration histos
2383 */
2384 void CaloElectron::Calibration_Fill(){
2385
2386 bool debug = CaloElectron_parameters::Get()->debug;
2387 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
2388 float RMAX = CaloElectron_parameters::Get()->RMAX;
2389 int ntau = CaloElectron_parameters::Get()->par_ntau;
2390 float *taubin = CaloElectron_parameters::Get()->par_taubin;
2391 CaloLevel1* cl1 = CaloElectron_parameters::Get()->cl1;
2392 //
2393 if(!cl1)cout << "NB --> missing CaloLevel1, needed for calibration !!"<<endl;
2394 if(!cl1)return;
2395 //
2396 int isimu = CaloElectron_parameters::Get()->isimu;
2397
2398 // /////////////////////////////////////
2399 // some parameters to select good shower
2400 // /////////////////////////////////////
2401 float stoll_g = 5;//maximum n.strips from gaps
2402 float stoll_b = 10;//maximum n.strips from borders
2403 float toll = stoll_b*PITCH;//3.;//(cm) distance of shower axis from border on the last silicon plane
2404 float qmin = 10;//(mip)minimum energy deposit per plane
2405 //
2406
2407 // ---------------
2408 // lateral profile
2409 // ---------------
2410 CaloStrip cstrip;
2411 if(isimu==0)cstrip = CaloStrip(cl1,false);
2412 if(isimu==1)cstrip = CaloStrip(cl1,true);
2413 if(debug)cout << "====== n.strip "<<cl1->istrip<<endl;
2414 if(debug)cout << "====== s.max (X0) "<<GetShowerMaximumX0(0);
2415 float showermax = GetShowerMaximumX0(0);
2416
2417 // -------------------------------
2418 // containment conditions (global)
2419 // -------------------------------
2420 // shower axis must be contained within 3 cm (on the last plane)
2421 // (otherwise the shower maximum could be not properly evaluated)
2422 bool CONTAINED = false;
2423 //
2424 // last silicon plane
2425 //
2426 int ip = 21;
2427 int iv = 0;//x
2428 cstrip.Set(iv,ip,0);
2429 float xcorner_l = cstrip.GetX();
2430 float ycorner_l = cstrip.GetY();
2431 cstrip.Set(iv,ip,95);
2432 float xcorner_r = cstrip.GetX();
2433 float ycorner_r = cstrip.GetY();
2434 //
2435 if(
2436 trkcoordx[ip][iv] > xcorner_l + toll &&
2437 trkcoordx[ip][iv] < xcorner_r - toll &&
2438 trkcoordy[ip][iv] > ycorner_l + toll &&
2439 trkcoordy[ip][iv] < ycorner_r - toll &&
2440 true)CONTAINED = true;
2441 //
2442 // if(!CONTAINED)return; // discard event if shower is not contained
2443
2444 // -----------------------------------------------
2445 // first loop over planes to determine the tau-bin
2446 // and verify some general conditions:
2447 // - shower axis in each plane far from gaps
2448 // - minimal energy deposit
2449 // -----------------------------------------------
2450 int ibintau[22][2];
2451 //
2452 for(int ip=0; ip<22; ip++){
2453 for(int iv=0; iv<2; iv++){
2454 //
2455 ibintau[ip][iv]=-1;
2456 // ------------
2457 // shower depth
2458 // ------------
2459 float tau = tplane[ip][iv]/showermax;
2460 if(debug)cout <<" --> plane "<<ip<<" view "<<iv<<" tau "<<tau<<endl;
2461 //
2462 if(tau>TAUMAX)continue; // discard plane if tau exceed TAUMAX
2463 //
2464 // ---------------------------------------
2465 // containment conditions (plane by plane)
2466 // ---------------------------------------
2467 // shower axis should be far from gaps
2468 //
2469 if(qplane0[ip][iv]<qmin)continue;//discard plane if energy deposit is low
2470 //
2471 bool CONTAINED = false;
2472 //
2473 if(
2474 ( trkstrip[ip][iv] >= stoll_b && trkstrip[ip][iv] < 32 - stoll_g )||
2475 ( trkstrip[ip][iv] >= 32 + stoll_g && trkstrip[ip][iv] < 64 - stoll_g )||
2476 ( trkstrip[ip][iv] >= 64 + stoll_g && trkstrip[ip][iv] < 96 - stoll_b )||
2477 false)CONTAINED = true;
2478 //
2479 if(!CONTAINED)continue; // discard plane if shower traverses gaps
2480 //
2481 for(int itau = 0; itau<ntau; itau++){
2482 if(taubin[0]>tau)break;
2483 if(taubin[itau+1]>=tau){
2484 ibintau[ip][iv]=itau;
2485 break;
2486 }
2487 }
2488 if(debug)cout << " --> tau-bin "<<ibintau<<endl;
2489 //
2490 }
2491 }
2492 // ----------------------------------------------------
2493 // then loop over hit strips to fill profile histograms
2494 // ----------------------------------------------------
2495 // for(int ih=0;ih<cl1->istrip;ih++){//loop over hit strips
2496 // int iv=-1;
2497 // int ip=-1;
2498 // int is=-1;
2499 // cl1->DecodeEstrip(ih,iv,ip,is);
2500 //
2501 // NBNB --> credo di dover riempire con TUTTE le strisce
2502 //
2503 for(int ip=0; ip<22; ip++){
2504 for(int iv=0; iv<2; iv++){
2505
2506 int ivv=iv; //x (0) and yeven (1)
2507 if(ip%2)ivv=2; //yodd (2)
2508 //
2509 if(ibintau[ip][iv]==-1)continue; //outside tau range or plane discarded
2510 //
2511 for(int is=0; is<96; is++){
2512
2513 cl1->GetEstrip(iv,ip,is);
2514 cstrip.Set(iv,ip,is);
2515 //
2516 float xy[2];
2517 xy[0] = cstrip.GetX() - trkcoordx[ip][iv];
2518 xy[1] = cstrip.GetY() - trkcoordy[ip][iv];
2519 //
2520 if( TMath::Abs(xy[iv]) >= RMAX )continue;// discard strip if exceed TAUMAX
2521 //
2522 // FRACTION OF CHARGE COLLECTED BY THE STRIP
2523 //
2524 float pitch = 1.;//PITCH;
2525 float F = cstrip.GetE();
2526 F = F / qplane0[ip][iv]; // normalized to total charge
2527 F = F / pitch; // per unit length
2528 //
2529 // weigths
2530 //
2531 double calo_noise = 0.2; //MIP
2532 // if(F==0.)calo_noise = 0.7; //MIP (threshold)
2533 double DF2 = 0.;
2534 DF2 += pow(calo_noise/cstrip.GetE(),2.)*pow((double)F,2.);
2535 // DF2 += pow((double)F,2.)/(double)qplane0[ip][iv];//sbagliato
2536 double W = 1./DF2;
2537 // -----------
2538 // fill histos
2539 // -----------
2540 TH2F* h_qtot_tau = CaloElectron_parameters::Get()->h_qtot_tau[ibintau[ip][iv]][ivv];
2541 if( !h_qtot_tau )
2542 CaloElectron_parameters::Get()->Calibration_SetTools();
2543 //
2544 if( !h_qtot_tau )return;;
2545 h_qtot_tau->Fill(xy[iv],F);
2546 // -------------------------
2547 // evaluate weighted average
2548 // -------------------------
2549 int ibin;
2550 for(ibin=-1; ibin<CALIBNBIN; ibin++){
2551 if( -1*CALIBRANGE + (ibin+1)*2*CALIBRANGE/CALIBNBIN >= xy[iv] )break;
2552 }
2553 if(ibin==-1)continue;//strip out of range
2554 //
2555 // problema: quando il segnale e` 0. in realta` e` <0.7
2556 // quindi si introduce un bias... che spero pero` sia piccolo
2557 //
2558 //
2559 CaloElectron_parameters::Get()->summW[ibintau[ip][iv]][ivv][ibin]
2560 += W;
2561 CaloElectron_parameters::Get()->summWF[ibintau[ip][iv]][ivv][ibin]
2562 += W*(double)F;
2563
2564 }
2565 }
2566 }
2567
2568
2569 return;
2570 };
2571
2572 ClassImp(CaloElectron);
2573 ClassImp(CaloElectron_parameters);
2574
2575

  ViewVC Help
Powered by ViewVC 1.1.23