/[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.2 - (show annotations) (download)
Thu Jan 23 11:23:47 2014 UTC (10 years, 10 months ago) by mocchiut
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +22 -19 lines
Error occurred while calculating annotation data.
Compilation warnings using GCC4.7 fixed

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,ps[3];
1294 // double x1,x2,x3,x4,x5,x6,ps[3];
1295 x1 = DEAD;
1296 x2 = x1 + PITCH*32;
1297 x3 = x2 + DEAD + GLUE + DEAD;
1298 x4 = x3 + PITCH*32;
1299 x5 = x4 + DEAD + GLUE + DEAD;
1300 // x6 = x5 + PITCH*32;
1301 ps[0] = x1;
1302 ps[1] = x3;
1303 ps[2] = x5;
1304 double integgap(0),integgaptmp(0),integnogap(0),correggif(0);
1305 double epsil=0.0001;
1306 for (Int_t ii=0;ii<3;ii++){
1307 for (Int_t jj=0;jj<3;jj++){
1308 double xmi = ps[ii] - xpl;
1309 double xma = xmi + PITCH*32;
1310 double ymi = ps[jj] - ypl;
1311 double yma = ymi + PITCH*32;
1312 int dointeg=1;
1313 if(iv==0){
1314 if(xmi<-RMAXsp && xma>-RMAXsp) xmi=-RMAXsp;
1315 if(xma>RMAXsp && xmi<RMAXsp) xma=RMAXsp;
1316 if(xmi>RMAXsp || xma<-RMAXsp)dointeg=0;
1317 }
1318 if(iv==1 || iv==2){
1319 if(ymi<-RMAXsp && yma>-RMAXsp) ymi=-RMAXsp;
1320 if(yma>RMAXsp && ymi<RMAXsp) yma=RMAXsp;
1321 if(ymi>RMAXsp || yma<-RMAXsp)dointeg=0;
1322 }
1323 if(dointeg==1){
1324 integgaptmp=ff->Integral(xmi,xma,ymi,yma,epsil);
1325 integgap += integgaptmp;
1326 }
1327 }
1328 }
1329
1330 double RPMAX=40.;
1331 double xmin(0),xmax(0),ymin(0),ymax(0);
1332 if(iv==0){
1333 ymin=-RPMAX;
1334 ymax=RPMAX;
1335 xmin=-RMAX;
1336 xmax=RMAX;
1337 }
1338 if(iv==1 || iv==2){
1339 xmin=-RPMAX;
1340 xmax=RPMAX;
1341 ymin=-RMAX;
1342 ymax=RMAX;
1343 }
1344 integnogap=ff->Integral(xmin,xmax,ymin,ymax,epsil);
1345
1346 correggif=integgap/integnogap;
1347
1348 return correggif;
1349
1350 }
1351 // ---------------------------------------------------------------------
1352 // TMinuit does not allow fcn to be a member function, and the function
1353 // arguments are fixed, so the one of the only ways to bring the data
1354 // into fcn is to declare the data as global.
1355 // ---------------------------------------------------------------------
1356 //
1357 Int_t iuse;
1358 Double_t zfit[44],tfit[44],errorzfit[44],errortfit[44];
1359 //Float_t corr,m,q,lp1m,lp2m,sig1,sig2;Float_t parglobali[4];
1360 //______________________________________________________________________________
1361 Double_t func(Double_t *tin,Double_t *par)
1362 {
1363
1364 Double_t gaa,a,tm,et,value,t,t0;
1365 t = *tin;
1366 et = par[0];
1367 a = par[1];
1368 tm = par[2];
1369 t0 = par[3];
1370 gaa = TMath::Gamma(a);
1371
1372 value = et*((a-1)/(tm*gaa))*pow(((a-1)*(t-t0)/tm),(a-1))*exp(-(a-1)*(t-t0)/tm);
1373
1374 return value;
1375 }
1376 //______________________________________________________________________________
1377 // fcn passes back f = chisq the function to be minimized.
1378 void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
1379 {
1380
1381 int iusequi=0;
1382 Double_t chisq = 0.;
1383 for (int i=0;i<iuse; i++) {
1384 if(tfit[i]>=par[3]){
1385 iusequi++;
1386 Double_t fu=func(&tfit[i],par);
1387 Double_t delta = (zfit[i]-fu)/errorzfit[i];
1388 chisq += delta*delta;
1389 }
1390 }
1391
1392 //cout<<"iusequi,par,fcn "<<iusequi<<" "<<par[0]<<" "<<par[1]<<" "<<par[2]<<" "<<chisq<<endl;
1393 f = chisq;
1394
1395 }
1396
1397 /**
1398 * \brief Method to apply longitudinal correction
1399 * @param longto Fit options:
1400 * -1 don't apply longitudinal correction
1401 * 0 apply to q0 (charge collected by each plane inside RMAX)
1402 * 1 apply to q1 (charge collected by each plane with lateral collection inside RMAX )
1403 */
1404 int CaloElectron::ApplyLongitudinalFit(int longto){
1405
1406 cout << "CaloElectron::ApplyLongitudinalFit("<<longto<<") ---> temporarily commented (problems with TMinuit!!)"<<endl;
1407
1408 // bool debug = CaloElectron_parameters::Get()->debug;
1409 // float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
1410 // // float RMAX = CaloElectron_parameters::Get()->RMAX;
1411 // int ipmin = CaloElectron_parameters::Get()->ipmin;
1412 // int ipmax = CaloElectron_parameters::Get()->ipmax;
1413
1414 // if( debug ) cout << "CaloElectron::ApplyLongitudinalFit("<<longto<<")"<<endl;
1415
1416 // float ipmaxl = ipmax-ipmin;
1417
1418 // /// ?????
1419 // if(GetShowerMaximum(longto)*TAUMAX<ipmax-ipmin){
1420 // corr__l = 1;
1421 // err__l = 10;
1422 // if(debug){
1423 // cout<<"GetShowerMaximum(longto) "<<GetShowerMaximum(longto)<<" TAUMAX "<<TAUMAX<<" ipmax-ipmin "<<ipmax-ipmin<<endl;
1424 // }else{
1425 // return err__l;
1426 // }
1427 // }
1428
1429 // // initialize TMinuit with a maximum of 5 params
1430 // TMinuit *minuit = new TMinuit(4);
1431
1432 // // cout << minuit << endl;
1433 // if(!debug) minuit->SetPrintLevel(-1);
1434 // if( debug) minuit->SetPrintLevel(-1);
1435 // minuit->SetFCN(fcn);
1436
1437
1438 // // cout << "<><><><><><><><><><><><><"<<endl;
1439 // // --------------------------------------------
1440 // // Set layers to be used for the fit
1441 // // --------------------------------------------
1442 // Double_t arglist[10];
1443 // Int_t ierflg = 0;
1444 // iuse = 0;//n.layers included in the fit
1445 // for(int ip=ipmin; ip<ipmin+ipmaxl; ip++){
1446 // //for(int iv=0; iv<2; iv++){
1447 // for(int iv=1; iv>=0; iv--){
1448 // bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
1449 // if(!maskpl){
1450 // if(longto==0) zfit[iuse] = qplane0[ip][iv];
1451 // if(longto==1) zfit[iuse] = qplane1[ip][iv];
1452 // tfit[iuse] = (double)tplane[ip][iv]-(double)tplane[ipmin][1];
1453 // errortfit[iuse] = 0.01;
1454 // errorzfit[iuse] = sqrt( zfit[iuse] );
1455 // if(zfit[iuse]<0.0001) errorzfit[iuse] = 1.;
1456 // // if(debug)cout<<"iuse,ip,iv,tplane,t,z "<<iuse<<" "<<ip<<" "<<iv<<" "<<tplane[ip][iv]<<" "<<tfit[iuse]<<" "<<zfit[iuse]<<endl;
1457 // iuse++;
1458 // }
1459 // }
1460 // }
1461 // if(debug)cout << "N.layers inlcuded in the fit: "<<iuse<<endl;
1462
1463 // // --------------------------------------------
1464 // // Set starting values and step sizes for param
1465 // // --------------------------------------------
1466 // Double_t size = (double)tplane[2][1]-(double)tplane[1][1];
1467 // Double_t initpar0 = 0;
1468 // for(int ip=ipmin+1; ip<ipmin+ipmaxl; ip++)
1469 // initpar0 = initpar0 + size*(zfit[ip*2]+zfit[ip*2-1])/2;
1470 // Double_t initpar2 = GetShowerMaximumX0(longto);
1471 // Double_t initpar1 = pow(initpar2,0.9);
1472 // Double_t initpar3 = 0.;
1473
1474 // Double_t vstart[4] = {initpar0, initpar1, initpar2, initpar3};
1475 // Double_t step[4] = {1.,0.1,1.,0.1};
1476 // Double_t limmin[4] = {0,0.,0.,0};
1477 // Double_t limmax[4] = {0,20.,20.,0};
1478 // string parname[4] = {"E","alpha","tm","t0"};
1479
1480 // // --------------------------------------------
1481 // // Now ready for minimization step with limits
1482 // // --------------------------------------------
1483 // if(debug)cout << "--------------------- First step (with limits): "<<endl;
1484 // for (int i=0; i<4; i++)
1485 // minuit->mnparm(i, parname[i].c_str(),vstart[i],step[i],limmin[i],limmax[i],ierflg);
1486 // minuit->FixParameter(3);//fix starting point
1487 // arglist[0] = 500;
1488 // minuit->mnexcm("MIGRAD", arglist ,1,ierflg);
1489 // err__l = ierflg;
1490 // if(ierflg>0){
1491 // if(debug){
1492 // cout<<"ierflg "<<ierflg<<" ma prova ad andare avanti"<<endl;
1493 // }else{
1494 // return err__l;
1495 // }
1496 // }
1497
1498 // Double_t vstart2[4];
1499 // Double_t vend[4],errvend[4];
1500
1501 // for(int i=0; i<4; i++){
1502 // minuit->GetParameter(i,vend[i],errvend[i]);
1503 // if(debug)cout<<setw(7)<<parname[i].c_str()<<" v-start "<<setw(10)<<vstart[i]<<" --> v-end "<<setw(10)<<vend[i]<<" +- "<<errvend[i]<<endl;
1504
1505 // }
1506
1507 // // // ===========================================
1508 // // // NB NB NB !!!!!!!!!!!!!
1509 // // // temporaneamente eseguo il secondo step
1510 // // // solo in modalita` debug
1511 // // // (chiedere spiegazioni a elena)
1512 // // // ===========================================
1513 // // if( debug && err__l ){
1514
1515 // // --------------------------------------------
1516 // // Now ready for minimization step without limits
1517 // // --------------------------------------------
1518 // if(debug)cout << "--------------------- Second step (without limits): "<<endl;
1519 // minuit->mnfree(0); //restore all fixed parameters
1520 // for (int i=0; i<4; i++){
1521 // vstart[i] = vend[i];
1522 // minuit->mnparm(i, parname[i].c_str(),vstart[i],step[i],0.,0.,ierflg);
1523 // }
1524 // minuit->FixParameter(3);//fix starting point
1525 // arglist[0] = 500;
1526 // minuit->mnexcm("MIGRAD", arglist ,1,ierflg);
1527 // err__l = ierflg;
1528 // if(ierflg>0){
1529 // if(debug){
1530 // cout<<"ierflg "<<ierflg<<" ma prova ad andare avanti"<<endl;
1531 // }else{
1532 // return err__l;
1533 // }
1534 // }
1535 // for(int i=0; i<4; i++){
1536 // minuit->GetParameter(i,vend[i],errvend[i]);
1537 // if(debug)cout<<setw(7)<<parname[i].c_str()<<" v-start "<<setw(10)<<vstart[i]<<" --> v-end "<<setw(10)<<vend[i]<<" +- "<<errvend[i]<<endl;
1538 // }
1539
1540 // // }
1541
1542 // // --------------------------------------------
1543 // // retrive parameters
1544 // // --------------------------------------------
1545 // // Double_t tup = TAUMAX*initpar2;
1546 // // TF1 *ffunc = new TF1("ffunc",func,0.,tup,4);
1547 // // ffunc->SetLineWidth(1);
1548 // for(int i=0; i<4; i++){
1549 // par__l[i] = vend[i];
1550 // if(par__l[i]<0 || par__l[2]>22 || par__l[1]>50){
1551 // cout<<" converge a valori assurdi... escluso"<<endl;
1552 // err__l = 5;
1553 // return err__l;
1554 // }
1555 // }
1556
1557 // if(debug)cout << "--------------------- DONE! "<<endl;
1558
1559
1560 // for(int ip=0; ip<22; ip++){
1561 // for(int iv=0; iv<2; iv++){
1562 // bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
1563 // if(!maskpl){
1564 // double tpla = (double)tplane[ip][iv];
1565 // Double_t fu1=func(&tpla,vend);
1566 // qplanefit[ip][iv] = fu1;
1567 // }
1568 // }
1569 // }
1570
1571 // Double_t graddummy[4];
1572 // double outfcn;
1573 // minuit->Eval(4,graddummy,outfcn,vend,1);
1574
1575 // if(iuse>3)chi2__l = (float)outfcn/(float)(iuse-3);
1576 // else chi2__l = 0.;
1577
1578 // delete minuit;
1579
1580 return err__l;
1581
1582 }
1583 /*
1584 * \brief Evaluate longitudinal correction
1585 */
1586 float CaloElectron::GetLongitudinalCorrection(){
1587
1588 bool debug = CaloElectron_parameters::Get()->debug;
1589 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
1590 int ipmin = CaloElectron_parameters::Get()->ipmin;
1591 int ipmax = CaloElectron_parameters::Get()->ipmax;
1592 // --------------------------------------------
1593 // evaluate longitudinal
1594 // --------------------------------------------
1595 Double_t corr = 0.;
1596 Double_t t3,intecalo3,intecalo,tmaxcalo;
1597 if( err__l == 0 ){
1598 t3 = par__l[3] + TAUMAX*par__l[2];
1599 TF1 *ffunc = GetFunc_Longitudinal();
1600 intecalo3 = ffunc->Integral(par__l[3],t3);
1601 // if(debug)cout<<"integro da "<<par__l[3]<<" fino a t3 "<<t3<<" trovo intecalo3 "<<intecalo3<<endl;
1602 tmaxcalo = (double)tplane[ipmax-1][0]-(double)tplane[ipmin][1];
1603 if(t3<tmaxcalo){//if(t3<tplane[21][0]){
1604 intecalo=intecalo3;
1605 // if(debug)cout<<"siccome tmaxcalo "<<tmaxcalo<<" >t3 "<<" intecalo=intecalo3 "<<endl;
1606 }else{
1607 intecalo=ffunc->Integral(par__l[3],tmaxcalo);
1608 // if(debug)cout<<"integro da "<<par__l[3]<<" fino a tmaxcalo "<<tmaxcalo<<" trovo intecalo3 "<<intecalo<<endl;
1609 }
1610 corr = intecalo3/intecalo;
1611 }else{
1612 corr=0;
1613 }
1614
1615 corr__l = (float)corr;
1616
1617 if(debug) cout<<"Longitudinal correction: "<<corr__l<<endl;
1618
1619 return corr__l;
1620
1621 }
1622 /////////////////////////////////////////////////////////////////////
1623 //
1624 //
1625 //
1626 //
1627 /////////////////////////////////////////////////////////////////////
1628 TGraphErrors *CaloElectron::GetGraph_Longitudinal(){
1629 TGraphErrors *graph = new TGraphErrors(iuse ,tfit,zfit,errortfit,errorzfit);
1630 graph->SetMarkerSize(0.8);
1631 graph->SetMarkerStyle(20);
1632 return graph;
1633 }
1634 //
1635 TGraphErrors *CaloElectron::GetGraph_Longitudinal_Fit(){
1636 double zfunc[44];
1637 double errorzfunc[44];
1638 TF1 *fu = new TF1("fu",func,0.,tfit[iuse-1],4);
1639 for(int i=0; i<4; i++)fu->SetParameter(i,par__l[i]);
1640 for(int i=0; i<iuse; i++){
1641 zfunc[i] = fu->Eval(tfit[i]);;
1642 errorzfunc[i] = 0.;
1643 if(zfunc[i]>0.)errorzfunc[i] = sqrt(zfunc[i]);
1644 }
1645 delete fu;
1646 TGraphErrors *graph = new TGraphErrors(iuse,tfit,zfunc,errortfit,errorzfunc);
1647 graph->SetMarkerSize(0.8);
1648 graph->SetMarkerColor(2);
1649 graph->SetMarkerStyle(20);
1650 return graph;
1651 }
1652 //
1653 TGraphErrors *CaloElectron::GetGraph_Longitudinal_Integral(){
1654 double zfitint[44];
1655 double errorzfitint[44];
1656 zfitint[0] = zfit[0];
1657 for(int i=1; i<iuse; i++){
1658 zfitint[i] = zfitint[i-1]+zfit[i];
1659 errorzfitint[i] = sqrt(zfitint[i]);
1660 }
1661 TGraphErrors *graph = new TGraphErrors(iuse,tfit,zfitint,errortfit,errorzfitint);
1662 graph->SetMarkerSize(0.8);
1663 graph->SetMarkerStyle(24);
1664 return graph;
1665 }
1666 //
1667 TGraphErrors *CaloElectron::GetGraph_Longitudinal_Integral_Fit(){
1668 double zfunc[44];
1669 double errorzfunc[44];
1670 TF1 *fu = new TF1("fu",func,0.,tfit[iuse-1],4);
1671 for(int i=0; i<4; i++)fu->SetParameter(i,par__l[i]);
1672 zfunc[0] = fu->Eval(tfit[0]);;
1673 for(int i=1; i<iuse; i++){
1674 zfunc[i] = zfunc[i-1] + fu->Eval(tfit[i]);;
1675 errorzfunc[i] = 0.;
1676 if(zfunc[i]>0.)errorzfunc[i] = sqrt(zfunc[i]);
1677 }
1678 delete fu;
1679 TGraphErrors *graph = new TGraphErrors(iuse,tfit,zfunc,errortfit,errorzfunc);
1680 graph->SetMarkerSize(0.8);
1681 graph->SetMarkerStyle(24);
1682 graph->SetMarkerColor(2);
1683 graph->SetLineColor(2);
1684 return graph;
1685 }
1686 //
1687 TF1 *CaloElectron::GetFunc_Longitudinal(){
1688 TF1 *fu = new TF1("longitudinalprofile",func,0.,tfit[iuse-1],4);
1689 for(int i=0; i<4; i++)fu->SetParameter(i,par__l[i]);
1690 fu->SetLineColor(2);
1691 // fu->Draw();
1692 // if(err__l!=0)fu->SetLineStyle(12);
1693 return fu;
1694 }
1695 //
1696 TGraphErrors *CaloElectron::GetGraph_Lateral(int ipp, int ivv){
1697
1698 cout << "TGraphErrors *CaloElectron::GetGraph_Lateral("<<ipp<<","<<ivv<<") "<<endl;
1699 // cout <<"ooooooooo%%%%%%%%%%%%%%%%%%%%% "<< CaloElectron_parameters::Get() << endl;
1700 // cout <<"ooooooooo%%%%%%%%%%%%%%%%%%%%% "<< CaloElectron_parameters::Get()->cl1 << endl;
1701 CaloLevel1* cl1 = CaloElectron_parameters::Get()->cl1;
1702 if(!cl1)return NULL;
1703
1704 float xx[96];
1705 float qq[96];
1706 float errxx[96];
1707 float errqq[96];
1708 CaloStrip cstrip;
1709 for(int is=0; is<96; is++){
1710 cstrip.Set(ivv,ipp,is);
1711 float xy[2];
1712 xy[0] = cstrip.GetX() - trkcoordx[ipp][ivv];
1713 xy[1] = cstrip.GetY() - trkcoordy[ipp][ivv];
1714 qq[is] = 0.;
1715 xx[is] = xy[ivv];
1716 errqq[is] = 0.;
1717 errxx[is] = 0.5*PITCH;
1718 }
1719 // -----------------------------------
1720 // set charge collected in each plane
1721 // -----------------------------------
1722 int isimu = CaloElectron_parameters::Get()->isimu;
1723 if(isimu==0)cstrip = CaloStrip(cl1,false);
1724 if(isimu==1)cstrip = CaloStrip(cl1,true);
1725 for(int ih=0;ih<cl1->istrip;ih++){
1726 int iv=-1;
1727 int ip=-1;
1728 int is=-1;
1729 cl1->DecodeEstrip(ih,iv,ip,is);
1730 cstrip.Set(iv,ip,is);
1731 float xy[2];
1732 xy[0] = cstrip.GetX() - trkcoordx[ip][iv];
1733 xy[1] = cstrip.GetY() - trkcoordy[ip][iv];
1734 if( ip==ipp && iv==ivv ){
1735 qq[is] = cstrip.GetE();
1736 xx[is] = xy[iv];
1737 if(qq[is]>0)errqq[is] = sqrt( qq[is] );
1738 }
1739 }
1740 TGraphErrors *graph = new TGraphErrors(96,xx,qq,errxx,errqq);
1741 graph->SetMarkerSize(0.8);
1742 graph->SetMarkerStyle(20);
1743 return graph;
1744 }
1745 //
1746 // TF1 *CaloElectron::GetFunc_Lateral(int ip, int iv, int icorr){
1747
1748
1749 // int iiv(0);
1750 // if(iv==0)iiv=0;
1751 // if(iv==1 && ip%2) iiv=1;
1752 // if(iv==1 && !ip%2) iiv=2;
1753
1754 // float iwmax,iw;
1755 // iwmax = GetShowerMaximum(icorr);
1756 // iw = ip+(iv-1);
1757 // int ibintau = (int)((iw/iwmax)/0.25);
1758 // if(ibintau>=12) ibintau=11;
1759
1760
1761 // float file_rt = CaloElectron_parameters::Get()->file_rt[ibintau][iiv];
1762 // float file_p = CaloElectron_parameters::Get()->file_p[ibintau][iiv];
1763 // float file_rc = CaloElectron_parameters::Get()->file_rc[ibintau][iiv];
1764 // float RMAXsp = CaloElectron_parameters::Get()->RMAXsp;
1765
1766 // int nparam=5;
1767 // TF1 *ff = new TF1("fradpro",fradpro,-RMAX,RMAX,nparam);
1768 // Double_t param[5];
1769 // param[0] = file_rt;
1770 // param[1] = file_p;
1771 // param[2] = file_rc;
1772 // param[3] = qplanefit[ip][iv];//qplane0[ip][iv];
1773 // param[4] = 0.;
1774 // for(int i=0;i<nparam;i++){
1775 // ff->SetParameter(i,param[i]);
1776 // // cout<<" "<<i<<" -> "<<param[i]<<endl;
1777 // }
1778 // return ff;
1779
1780 // }
1781 /*
1782 * Return a graph with the integral of the 2-dimentional profile (normalized) over
1783 * each strip (taking into account the gaps).
1784 */
1785 TGraphErrors *CaloElectron::GetFunc_Lateral(int ip, int iv){
1786
1787 cout << "TGraphErrors *CaloElectron::GetFunc_Lateral("<<ip<<","<<iv<<",) "<<endl;
1788
1789 float xx[96];
1790 float qq[96];
1791 float errxx[96];
1792 float errqq[96];
1793 GetProfile(ip,iv,xx,qq,errxx,errqq);
1794
1795
1796 TGraphErrors *graph = new TGraphErrors(96,xx,qq,errxx,errqq);
1797 // graph->SetMarkerSize(0.8);
1798 // graph->SetMarkerStyle(1);
1799 graph->SetLineColor(2);
1800 return graph;
1801
1802 }
1803 /**
1804 * evaluate the expected average profile, by integrating the expected charge distribution
1805 * over each strip
1806 *
1807 */
1808 void CaloElectron::GetProfile(int ip, int iv, float xx[], float qq[],float errxx[], float errqq[] ){
1809
1810 // bool debug = CaloElectron_parameters::Get()->debug;
1811 // float xx[96];
1812 // float qq[96];
1813 // float errxx[96];
1814 // float errqq[96];
1815 CaloLevel1* cl1 = CaloElectron_parameters::Get()->cl1;
1816 if(!cl1)cout << " ERROR -- CaloLevel1* cl1 == NULL"<<endl;
1817 if(!cl1)return;
1818
1819 // x y-even or y-odd
1820 int iiv(0);
1821 if(iv==0) iiv = 0;
1822 if(iv==1 && ip%2) iiv = 1;
1823 if(iv==1 && !ip%2) iiv = 2;
1824
1825 // shower maximum ==> tau-bin
1826 // float iwmax,iw;
1827 // iwmax = GetShowerMaximum(icorr);
1828 // // iw = ip+(iv-1); //!!!!!!!!!!!!! BUG!?!?!
1829 // iw = ip-(iv-1);
1830 // int ibintau = (int)((iw/iwmax)/0.25);
1831 // if(ibintau>=12) ibintau=11;
1832 // cout << " maximum (W)"<<iwmax<<endl;
1833 // cout << " ip (W)"<<iw<<endl;
1834 // cout << " tau "<<iw/iwmax<<" tau-bin "<<ibintau<<endl;
1835 int ipmin = CaloElectron_parameters::Get()->ipmin;
1836 float maxl = GetShowerMaximum(2);
1837 float nlayer = (float)GetNWLayers(ip,iv);
1838 double tau = (double)(nlayer-ipmin)/(double)maxl;
1839 int ibintau = (int)(tau/0.25);
1840 if(ibintau>=12) ibintau=11;
1841 // if(debug){
1842 // cout << " maximum (W)"<<maxl<<endl;
1843 // cout << " ip (W)"<<nlayer<<endl;
1844 // cout << " tau "<<tau<<" tau-bin "<<ibintau<<endl;
1845 // }
1846 // retrieve lateral-profile parameters
1847 float file_rt = CaloElectron_parameters::Get()->file_rt[ibintau][iiv];
1848 float file_p = CaloElectron_parameters::Get()->file_p[ibintau][iiv];
1849 float file_rc = CaloElectron_parameters::Get()->file_rc[ibintau][iiv];
1850 float RMAXsp = CaloElectron_parameters::Get()->RMAXsp;
1851 // if(debug){
1852 // cout << " RT "<<file_rt<<endl;
1853 // cout << " RC "<<file_rc<<endl;
1854 // cout << " p "<<file_p<<endl;
1855 // }
1856 // 2-dimentional function
1857 TF2 ff = TF2("frad",frad,-25.,25.,-25.,25.,3);
1858 ff.SetParameter(0,file_rt);
1859 ff.SetParameter(1,file_p);
1860 ff.SetParameter(2,file_rc);
1861
1862 // 1-dimentional function
1863 TF1 fx = TF1("fradx",fradx,-25.,25.,4);
1864 fx.SetParameter(0,file_rt);
1865 fx.SetParameter(1,file_p);
1866 fx.SetParameter(2,file_rc);
1867
1868 // sensitive area
1869 // double x1,x2,x3,x4,x5,x6,ps[3];
1870 double x1,x2,x3,x4,x5,ps[3];
1871 x1 = DEAD;
1872 x2 = x1 + PITCH*32;
1873 x3 = x2 + DEAD + GLUE + DEAD;
1874 x4 = x3 + PITCH*32;
1875 x5 = x4 + DEAD + GLUE + DEAD;
1876 // x6 = x5 + PITCH*32;
1877 ps[0] = x1;
1878 ps[1] = x3;
1879 ps[2] = x5;
1880
1881 // retrieve the coordinate of the bottom-left corner of the plane
1882 float corner[] = {0.,0.};
1883 GetCornerCoord(ip,iv,corner[0],corner[1]);
1884
1885
1886 // integral over each strip
1887 double integgap;
1888 double epsil = 0.0001;
1889 CaloStrip cstrip;
1890
1891 //
1892 for(int is=0; is<96; is++){ //loop over strips
1893 cstrip.Set(iv,ip,is);
1894 float xy[2];
1895 float trkcoord[2];
1896 trkcoord[0] = trkcoordx[ip][iv]; //track coordinate
1897 trkcoord[1] = trkcoordy[ip][iv];
1898 xy[0] = cstrip.GetX() - trkcoordx[ip][iv];//strip coordinate (relative to track)
1899 xy[1] = cstrip.GetY() - trkcoordy[ip][iv];
1900 //
1901 qq[is] = 0.;
1902 xx[is] = xy[iv];
1903 errqq[is] = 0.;
1904 errxx[is] = 0.5*PITCH;
1905 //
1906 integgap = 0.;
1907 for (Int_t jj=0;jj<3;jj++){ //loop over the 3 sensors
1908 //
1909 double ymi = ps[jj] + (double)corner[iv] - (double)trkcoord[iv];
1910 double yma = ymi + PITCH*32;
1911 double xmi = (double)xx[is]-(double)errxx[is];//strip size
1912 double xma = (double)xx[is]+(double)errxx[is];
1913 //
1914 int dointeg=1;
1915 if(iv==0){
1916 if(xmi<-RMAXsp && xma>-RMAXsp) xmi = -RMAXsp;
1917 if(xma>RMAXsp && xmi<RMAXsp) xma = RMAXsp;
1918 if(xmi>RMAXsp || xma<-RMAXsp) dointeg = 0;
1919 }
1920 if(iv==1 || iv==2){
1921 if(ymi<-RMAXsp && yma>-RMAXsp) ymi = -RMAXsp;
1922 if(yma>RMAXsp && ymi<RMAXsp) yma = RMAXsp;
1923 if(ymi>RMAXsp || yma<-RMAXsp) dointeg = 0;
1924 }
1925 if(dointeg==0) continue;
1926
1927 //
1928 bool DOFAST = false;
1929 if(fabs(xx[is])>2.)DOFAST=true;
1930
1931 double integral = 0.;
1932
1933 if(DOFAST){
1934 //
1935 // integrale veloce
1936 //
1937
1938 // double fmi,fma,k,c;
1939 double fmi,fma,k;
1940 fx.SetParameter(3,xmi);
1941 fmi = fx.Integral(ymi,yma);
1942 fx.SetParameter(3,xma);
1943 fma = fx.Integral(ymi,yma);
1944 k = 0.;
1945 if(fmi>0.&&fma>0.&&(xma-xmi)>0.)k=log(fma/fmi)/(xma-xmi);
1946 //c = log(fmi)-k*xmi;
1947 if(fabs(k)>1.e-6)integral += (fma-fmi)/k;
1948
1949 }else{
1950 //
1951 // integrale lento ma piu` preciso
1952 //
1953 integral = ff.Integral(xmi,xma,ymi,yma,epsil);
1954
1955 }
1956
1957 integgap += integral;
1958
1959 // cout << setw(2)<<jj<<setw(15)<<xmi<<setw(15)<<ymi<< setw(15)<<integral << setw(15)<<integgaptmp<<endl;
1960 }
1961
1962 qq[is] = integgap * qplanefit[ip][iv];
1963 // if( qq[is]>0 )errqq[is] = sqrt(qq[is]);
1964 }
1965 }
1966 /**
1967 *
1968 */
1969 float CaloElectron::ProfileTest(){
1970
1971 int ipmin = CaloElectron_parameters::Get()->ipmin;
1972 int ipmax = CaloElectron_parameters::Get()->ipmax;
1973 float RMAX = CaloElectron_parameters::Get()->RMAX;
1974 // float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
1975
1976 TH2F* h_qfit[2];
1977 TH2F* h_qtot[2];
1978 //
1979 // retrieve histrograms of shower lateral profile
1980 //
1981 for(int iv=0; iv<2; iv++){
1982 h_qfit[iv] = CaloElectron_parameters::Get()->h_qfit[iv]; //average
1983 if(!h_qfit[iv])return 0.;
1984 h_qfit[iv]->Reset(); //-->reset
1985
1986 h_qtot[iv] = CaloElectron_parameters::Get()->h_qtot[iv]; //data
1987 if(!h_qtot[iv])return 0.;
1988 }
1989
1990 // float maxl = GetShowerMaximum(2);
1991 //
1992 double chi2tmp = 0.;
1993 int ndof = 0;
1994 // cout << "<><><><><><><><><><><><><><>"<<endl;
1995 // cout << setw(3) << "IP" << setw(3) << "IV" ;
1996 // cout << setw(10) << "TAU";
1997 // cout << setw(10) << "RMS";
1998 // cout << setw(10) << "SKEW";
1999 // cout << setw(10) << "KURT";
2000 // cout << endl;
2001 //
2002 for(int ip=0; ip<22; ip++){ // loop over planes
2003 for(int iv=1; iv>=0; iv--){ // loop over views
2004 bool maskpl = CaloElectron_parameters::Get()->maskpl[ip][iv];
2005 float corner[] = {0.,0.};
2006 GetCornerCoord(ip,iv,corner[0],corner[1]);
2007 if(
2008 ip >= ipmin &&
2009 ip < ipmax &&
2010 !maskpl &&
2011 true){
2012 //
2013 float xx[96];
2014 float qq[96];
2015 float errxx[96];
2016 float errqq[96];
2017 //
2018 float trkcoord[2];
2019 trkcoord[0] = trkcoordx[ip][iv];
2020 trkcoord[1] = trkcoordy[ip][iv];
2021 //
2022 GetProfile(ip,iv,xx,qq,errxx,errqq); //<<< average profile
2023 // float nlayer = (float)GetNWLayers(ip,iv);
2024 // double tau = (double)(nlayer-ipmin)/(double)maxl;
2025 for(int is=0; is<96; is++) {
2026 if(
2027 fabs(xx[is]) < RMAX &&
2028 // tau<TAUMAX &&
2029 true){
2030 // h_qfit[iv]->Fill( (float)(is+iv*96), (float)ip, qq[is]);
2031 h_qfit[iv]->Fill( xx[is]+trkcoord[iv]-corner[iv], (float)ip, qq[is]);
2032 float qqq = h_qtot[iv]->GetBinContent((is+iv*96+1),ip+1);
2033 // cout << setw(15)<< qqq<<setw(15)<<qq[is]<<setw(15)<<pow(qq[is]-qqq,2.)<< endl;
2034 if(qq[is]>0) chi2tmp += pow((double)(qq[is]-qqq),2.)/sqrt((double)qq[is]);
2035 ndof++;
2036 }
2037 }
2038 // cout << "<><><><><><><><><><><><><><>"<<endl;
2039 // cout << ip << " - "<<iv << endl;
2040 // TH1D* hfitpro = h_qfit[iv]->ProjectionX("hfitpx",ip+1,ip+2);
2041 TH1D* htotpro = h_qtot[iv]->ProjectionX("htotpx",ip+1,ip+2);
2042 // cout <<"Mean "<< setw(10)<<htotpro->GetMean() << setw(10)<<hfitpro->GetMean() << endl;
2043 // cout <<"RMS "<< setw(10)<<htotpro->GetRMS() << setw(10)<<hfitpro->GetRMS() << endl;
2044 // cout <<"Skew "<< setw(10)<<htotpro->GetSkewness() << setw(10)<<hfitpro->GetSkewness() << endl;
2045 // cout <<"Kurt "<< setw(10)<<htotpro->GetKurtosis() << setw(10)<<hfitpro->GetKurtosis() << endl;
2046 if(GetShowerMaximumX0(2)>0.)
2047 TAU[ip][iv] = tplane[ip][iv]/GetShowerMaximumX0(2);
2048 if(htotpro->GetEntries()>4){
2049 RMS[ip][iv] = htotpro->GetRMS();
2050 SKEW[ip][iv] = htotpro->GetSkewness();
2051 KURT[ip][iv] = htotpro->GetKurtosis();
2052 }
2053 // cout << setw(3) << ip << setw(3) << iv ;
2054 // cout << setw(10) << TAU[ip][iv];
2055 // cout << setw(10) << RMS[ip][iv];
2056 // cout << setw(10) << SKEW[ip][iv];
2057 // cout << setw(10) << KURT[ip][iv];
2058 // cout << endl;
2059 // hfitpro->Delete();
2060 htotpro->Delete();
2061 // cout << "<><><><><><><><><><><><><><>"<<endl;
2062 }
2063 }
2064 }
2065 // cout << "<><><><><><><><><><><><><><>"<<endl;
2066
2067 // double kolp = h_qfit->KolmogorovTest(h_qtot,"ND");
2068 // double kold = h_qfit->KolmogorovTest(h_qtot,"NDM");
2069 // h_qfit->Sumw2();
2070 // h_qtot->Sumw2();
2071 // double kolp = h_qfit->KolmogorovTest(h_qtot,"D");
2072 // double kold = h_qfit->KolmogorovTest(h_qtot,"DM");
2073 // double chi2tmp = h_qfit->Chi2Test(h_qtot,"WWP");
2074 // cout << "KKKKK "<<kolp << endl;
2075 // cout << "KKKKK "<<kold << endl;
2076 // cout << "KKKKK "<<chi2 << " "<<ndof<<" "<<chi2/(double)(ndof)<< endl;
2077 if( ndof>3 )chi2 = (float)(chi2tmp/(double)(ndof-3));
2078 else chi2 = 0.;
2079
2080 return chi2;
2081
2082 }
2083 /**
2084 *
2085 */
2086 float CaloElectron::GetMaxResidual(){
2087 float max = 0;
2088 for(int iv=0; iv<2; iv++){
2089 for(int ip=0; ip<22; ip++){
2090 if(
2091 // qplane1[ip][iv] > 0. &&
2092 // fabs(qplane1[ip][iv]-qplanefit[ip][iv])/sqrt(qplane1[ip][iv]) > fabs(max) &&
2093 fabs(qplane1[ip][iv]-qplanefit[ip][iv]) > fabs(max) &&
2094 true){
2095 max = qplane1[ip][iv]-qplanefit[ip][iv];
2096 }
2097 }
2098 }
2099 return max;
2100 }
2101 int CaloElectron::GetNRun(){
2102 bool POS = true;
2103 bool NEG = true;
2104 int nrun = 0;
2105 for(int ip=0; ip<22; ip++){
2106 for(int iv=1; iv>=0; iv--){
2107 if( qplane1[ip][iv] > qplanefit[ip][iv] && NEG ){
2108 nrun++;
2109 POS = true; NEG = !POS;
2110 }
2111 if( qplane1[ip][iv] <= qplanefit[ip][iv] && POS ){
2112 nrun++;
2113 NEG = true; POS = !NEG;
2114 }
2115 }
2116 }
2117 return nrun;
2118 }
2119 float CaloElectron::GetMaxRun(){
2120 bool POS = true;
2121 bool NEG = true;
2122 int nrun = 0;
2123 float sum[44]; for(int ip=0; ip<44; ip++)sum[ip]=0.;
2124 //
2125 for(int ip=0; ip<22; ip++){
2126 for(int iv=1; iv>=0; iv--){
2127 if( qplane1[ip][iv] > qplanefit[ip][iv] && NEG ){
2128 nrun++;
2129 POS = true; NEG = !POS;
2130 }
2131 if( qplane1[ip][iv] <= qplanefit[ip][iv] && POS ){
2132 nrun++;
2133 NEG = true; POS = !NEG;
2134 }
2135 sum[nrun-1] += qplane1[ip][iv]-qplanefit[ip][iv];
2136 }
2137 }
2138 //
2139 float max=0;
2140 for(int ip=0; ip<44; ip++)
2141 if( fabs(sum[ip]) > fabs(max) )max=sum[ip];
2142
2143 return max;
2144 }
2145 /**
2146 * \brief Method to retrieve the coordinates of the plane bottom-left corner
2147 * (l'angolo è dell'inizio del rivelatore compreso il dead)
2148 */
2149 void CaloElectron::GetCornerCoord(int ip, int iv, float& xorig, float& yorig){
2150
2151 // coordinate meccaniche dei piani in cm
2152
2153 CaloStrip st = CaloStrip();
2154 int isimu = CaloElectron_parameters::Get()->isimu;
2155 if(isimu==0)st.UseStandardAlig();
2156 if(isimu==1)st.UseMechanicalAlig();
2157
2158 yorig = -0.1*st.GetYalig()+0.1;
2159 xorig = -0.1*st.GetXalig();
2160
2161 if(ip%2!=1){
2162 //ip 0,2,4,6,...,20
2163 if(iv==0){
2164 yorig = yorig;
2165 xorig = xorig+0.05;
2166 }else{
2167 yorig = yorig-0.05;
2168 xorig = xorig+0.1;
2169 }
2170 }else{
2171 //ip 1,3,5,..,21
2172 if(iv==0){
2173 yorig = yorig-0.2;
2174 xorig = xorig-0.05;
2175 }else{
2176 yorig = yorig-0.15;
2177 xorig = xorig-0.1;
2178 }
2179 }
2180
2181
2182
2183
2184
2185
2186 }
2187 /**
2188 * \brief Print the event
2189 */
2190 void CaloElectron::Print(){
2191
2192 int ipmin = CaloElectron_parameters::Get()->ipmin;
2193 int ipmax = CaloElectron_parameters::Get()->ipmax;
2194 // cout<<"Print idiev "<<idiev<<endl;
2195 cout << " n. W-layers - qx0 qy0 -------> qx1 qy1 -------> qx(fit) qy(fit)"<<endl;
2196 float qx0,qy0,qx1,qy1,qx2,qy2;
2197 qx0=0.;
2198 qy0=0.;
2199 qx1=0.;
2200 qy1=0.;
2201 qx2=0.;
2202 qy2=0.;
2203 for(int il=ipmin; il<=ipmax; il++){
2204 if(il>ipmin){
2205 qx0 = qplane0[il-1][0];
2206 qy0 = qplane0[il][1];
2207 qx1 = qplane1[il-1][0];
2208 qy1 = qplane1[il][1];
2209 qx2 = qplanefit[il-1][0];
2210 qy2 = qplanefit[il][1];
2211 }
2212 if(il==ipmin){
2213 // qx0 = 0;
2214 qy0 = qplane0[ipmin][1];
2215 // qx1 = 0;
2216 qy1 = qplane1[ipmin][1];
2217 // qx2 = 0;
2218 qy2 = qplanefit[ipmin][1];
2219 }
2220 if(il==ipmax){
2221 qx0 = qplane0[ipmax-1][0];
2222 // qy0 = 0.;
2223 qx1 = qplane1[ipmax-1][0];
2224 // qy1 = 0.;
2225 qx2 = qplanefit[ipmax-1][0];
2226 // qy2 = 0.;
2227 }
2228 cout << " "<<setw(2)<<il<<" - "<<setw(10)<<qx0<<setw(10)<<qy0<<" "<<setw(10)<<qx1<<setw(10)<<qy1<<" "<<setw(10)<<qx2<<setw(10)<<qy2<<endl;
2229 }
2230 cout<<" "<<endl;
2231 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
2232 float RMAX = CaloElectron_parameters::Get()->RMAX;
2233 cout << "Total collectced charge (mip) "<<qtot<<endl;
2234 cout << "Charge outside cylinder ( RMAX="<<RMAX<<" ,TAUMAX="<<TAUMAX<<" )";
2235 cout << qtot - GetQ(0);
2236 if(qtot>0.)cout <<" ( "<< 100.*(qtot-GetQ(0))/qtot<<" % )"<<endl;
2237 for(int icorr=0;icorr<4;icorr++){
2238 cout << " ---------------------------------------------- "<<icorr;
2239 if(icorr==0)cout <<"(no corr.)"<<endl;
2240 if(icorr==1)cout <<"(lateral corr.)"<<endl;
2241 if(icorr==2)cout <<"(lateral+longitudinal corr.)"<<endl;
2242 if(icorr==3)cout <<"(fit)"<<endl;
2243 cout << " - Collected charge (mip) "<<GetQ(icorr)<<endl;
2244 cout << " - Shower maximum (W-layer, X0) "<<GetShowerMaximum(icorr)<<" "<<GetShowerMaximumX0(icorr)<<endl;
2245 cout << " - Energy (GeV) "<<GetEnergy(icorr)<<endl;
2246 }
2247 cout << "Longitudinal parameters:"<<endl;
2248 cout << "- E :"<<par__l[0]<<endl;
2249 cout << "- alpha :"<<par__l[1]<<endl;
2250 cout << "- Tm :"<<par__l[2]<<endl;
2251 cout << "- T0 :"<<par__l[3]<<endl;
2252 cout << "- chi2 :"<<chi2__l<<endl;
2253 cout << "- minuit status :"<<err__l<<endl;
2254 cout << endl ;
2255 cout << "- chi2 (global) :"<<chi2<<endl;
2256 cout << endl ;
2257
2258 // cout<<" rigidity "<<rig<<" qtotlevel2 "<<qtotl2<<endl;
2259
2260 }
2261 //______________________________________________________________________________
2262 Double_t paraloss(Double_t *tin,Double_t *par)
2263 {
2264
2265 Double_t t,p0,p1,p2,p3,t0,value;
2266 t=*tin;
2267 p0=par[0];
2268 p1=par[1];
2269 p2=par[2];
2270 p3=par[3];
2271 t0=1.7;//t0=1.5;
2272 Double_t paralossdit0=1.00659;
2273 if(t<t0) return paralossdit0;
2274 value=p0+p1*t+p2*pow(t,2)+p3*pow(t,3);
2275 return value;
2276 }
2277
2278 /**
2279 * \brief Collect corrected charge to energy
2280 */
2281 float CaloElectron::GetEnergy(int icorr){
2282
2283 float energy = 0;
2284 float collectedq = 0;
2285 float p0 = 0;
2286 float p1 = 0;
2287
2288 if(icorr == 0){
2289 // ---------------------------------------
2290 // before any correction
2291 // ---------------------------------------
2292
2293 //the same as energy 1.. not to be used
2294 p0=24.14;
2295 p1=253.3;
2296
2297 }else if(icorr == 1 || icorr == 3){
2298 // ---------------------------------------
2299 // after lateral correction 4 giugno 2007
2300 // ---------------------------------------
2301
2302 //linear (only with fit of points 5-15gev where longitudinal containment is satisfactory)
2303 //we expect a sistematic error for greater energies that has to be corrected by longitudinal fit
2304
2305 //10-9-07
2306 p0=24.14;
2307 p1=253.3;
2308
2309 }else if(icorr == 2){
2310 // ---------------------------------------
2311 // after longitudinal fit
2312 // ---------------------------------------
2313
2314 //10-9-07
2315 p0=-13.86;
2316 p1=264.4;
2317
2318
2319 }else{
2320
2321 return energy;
2322
2323 }
2324
2325 collectedq=GetQ(icorr);
2326 // if(onlyy)collectedq=collectedq*2;
2327
2328 energy = (collectedq-p0)/p1;
2329
2330 if(GetQ(icorr)<=0) energy=0.;
2331
2332 if(icorr == 3){
2333 TF1 *f4=new TF1("f4",paraloss,0.,3.,4);//f1->FixParameter(2,1.3);
2334 f4->SetParameter(0,-0.8013231);
2335 f4->SetParameter(1,2.276176);
2336 f4->SetParameter(2,-0.8295547);
2337 f4->SetParameter(3,0.06835571);
2338 float lnmax=TMath::Log(par__l[2]);
2339 float lnmax1=TMath::Log(GetShowerMaximumX0(1));
2340 if(lnmax>2.4 || GetIerflg()>0){
2341 cout<<"max "<<GetShowerMaximumX0(1)<<" "<<GetShowerMaximumX0(2)<<" lnmax "<<lnmax<<" ier "<<GetIerflg()<<endl;
2342 lnmax=lnmax1;
2343 }
2344 float corrparaloss=f4->Eval(lnmax);
2345 //cout<<"icorr 3...lnmax "<<lnmax<<" corrparaloss "<<corrparaloss<<endl;
2346 energy=energy/corrparaloss;
2347 }
2348
2349 return energy;
2350
2351 };
2352
2353 /*
2354 defined cuts to have gaussian error from calorimeter reconstruction for alignement purpose
2355 */
2356 bool CaloElectron::IsInsideFiducial(int level){
2357
2358
2359 // float ma=GetShowerMaximum(1);
2360 // if(ma>=20 || ma<=4)return false;
2361 // int ima=(int)ma+ipmin;
2362 // float strima=0;
2363 // for(int iv=0;iv<=1;iv++){
2364 // strima=GetStripW(ima,iv);
2365 // if(strima<11 || strima>86 || strima==33 || strima==32 || strima==65 || strima==64) return false;
2366 // }
2367
2368 // if(level==1) return true;
2369
2370 // if(outfcn>600) return false;
2371 // if(minuitierflg>0) return false;
2372 // float lma1=log(par__l[1]);
2373 // float lma2=log(par__l[2]);
2374 // float lma1expected=0.92*lma2;
2375 // if(lma2<1.3 || lma2>2.3) return false;
2376 // if(TMath::Abs(lma1-lma1expected)>0.5) return false;
2377
2378 return true;
2379
2380 }
2381
2382 //////////////////////////////////////////////////////////////////////////
2383
2384 /**
2385 * Fill calibration histos
2386 */
2387 void CaloElectron::Calibration_Fill(){
2388
2389 bool debug = CaloElectron_parameters::Get()->debug;
2390 float TAUMAX = CaloElectron_parameters::Get()->TAUMAX;
2391 float RMAX = CaloElectron_parameters::Get()->RMAX;
2392 int ntau = CaloElectron_parameters::Get()->par_ntau;
2393 float *taubin = CaloElectron_parameters::Get()->par_taubin;
2394 CaloLevel1* cl1 = CaloElectron_parameters::Get()->cl1;
2395 //
2396 if(!cl1)cout << "NB --> missing CaloLevel1, needed for calibration !!"<<endl;
2397 if(!cl1)return;
2398 //
2399 int isimu = CaloElectron_parameters::Get()->isimu;
2400
2401 // /////////////////////////////////////
2402 // some parameters to select good shower
2403 // /////////////////////////////////////
2404 float stoll_g = 5;//maximum n.strips from gaps
2405 float stoll_b = 10;//maximum n.strips from borders
2406 // float toll = stoll_b*PITCH;//3.;//(cm) distance of shower axis from border on the last silicon plane
2407 float qmin = 10;//(mip)minimum energy deposit per plane
2408 //
2409
2410 // ---------------
2411 // lateral profile
2412 // ---------------
2413 CaloStrip cstrip;
2414 if(isimu==0)cstrip = CaloStrip(cl1,false);
2415 if(isimu==1)cstrip = CaloStrip(cl1,true);
2416 if(debug)cout << "====== n.strip "<<cl1->istrip<<endl;
2417 if(debug)cout << "====== s.max (X0) "<<GetShowerMaximumX0(0);
2418 float showermax = GetShowerMaximumX0(0);
2419
2420 // -------------------------------
2421 // containment conditions (global)
2422 // -------------------------------
2423 // shower axis must be contained within 3 cm (on the last plane)
2424 // (otherwise the shower maximum could be not properly evaluated)
2425 // bool CONTAINED = false;
2426 //
2427 // last silicon plane
2428 //
2429 int ip = 21;
2430 int iv = 0;//x
2431 // cstrip.Set(iv,ip,0);
2432 // float xcorner_l = cstrip.GetX();
2433 // float ycorner_l = cstrip.GetY();
2434 cstrip.Set(iv,ip,95);
2435 // float xcorner_r = cstrip.GetX();
2436 // float ycorner_r = cstrip.GetY();
2437 //
2438 // if(
2439 // trkcoordx[ip][iv] > xcorner_l + toll &&
2440 // trkcoordx[ip][iv] < xcorner_r - toll &&
2441 // trkcoordy[ip][iv] > ycorner_l + toll &&
2442 // trkcoordy[ip][iv] < ycorner_r - toll &&
2443 // true)CONTAINED = true;
2444 //
2445 // if(!CONTAINED)return; // discard event if shower is not contained
2446
2447 // -----------------------------------------------
2448 // first loop over planes to determine the tau-bin
2449 // and verify some general conditions:
2450 // - shower axis in each plane far from gaps
2451 // - minimal energy deposit
2452 // -----------------------------------------------
2453 int ibintau[22][2];
2454 //
2455 for(int ip=0; ip<22; ip++){
2456 for(int iv=0; iv<2; iv++){
2457 //
2458 ibintau[ip][iv]=-1;
2459 // ------------
2460 // shower depth
2461 // ------------
2462 float tau = tplane[ip][iv]/showermax;
2463 if(debug)cout <<" --> plane "<<ip<<" view "<<iv<<" tau "<<tau<<endl;
2464 //
2465 if(tau>TAUMAX)continue; // discard plane if tau exceed TAUMAX
2466 //
2467 // ---------------------------------------
2468 // containment conditions (plane by plane)
2469 // ---------------------------------------
2470 // shower axis should be far from gaps
2471 //
2472 if(qplane0[ip][iv]<qmin)continue;//discard plane if energy deposit is low
2473 //
2474 bool CONTAINED = false;
2475 //
2476 if(
2477 ( trkstrip[ip][iv] >= stoll_b && trkstrip[ip][iv] < 32 - stoll_g )||
2478 ( trkstrip[ip][iv] >= 32 + stoll_g && trkstrip[ip][iv] < 64 - stoll_g )||
2479 ( trkstrip[ip][iv] >= 64 + stoll_g && trkstrip[ip][iv] < 96 - stoll_b )||
2480 false)CONTAINED = true;
2481 //
2482 if(!CONTAINED)continue; // discard plane if shower traverses gaps
2483 //
2484 for(int itau = 0; itau<ntau; itau++){
2485 if(taubin[0]>tau)break;
2486 if(taubin[itau+1]>=tau){
2487 ibintau[ip][iv]=itau;
2488 break;
2489 }
2490 }
2491 if(debug)cout << " --> tau-bin "<<ibintau<<endl;
2492 //
2493 }
2494 }
2495 // ----------------------------------------------------
2496 // then loop over hit strips to fill profile histograms
2497 // ----------------------------------------------------
2498 // for(int ih=0;ih<cl1->istrip;ih++){//loop over hit strips
2499 // int iv=-1;
2500 // int ip=-1;
2501 // int is=-1;
2502 // cl1->DecodeEstrip(ih,iv,ip,is);
2503 //
2504 // NBNB --> credo di dover riempire con TUTTE le strisce
2505 //
2506 for(int ip=0; ip<22; ip++){
2507 for(int iv=0; iv<2; iv++){
2508
2509 int ivv=iv; //x (0) and yeven (1)
2510 if(ip%2)ivv=2; //yodd (2)
2511 //
2512 if(ibintau[ip][iv]==-1)continue; //outside tau range or plane discarded
2513 //
2514 for(int is=0; is<96; is++){
2515
2516 cl1->GetEstrip(iv,ip,is);
2517 cstrip.Set(iv,ip,is);
2518 //
2519 float xy[2];
2520 xy[0] = cstrip.GetX() - trkcoordx[ip][iv];
2521 xy[1] = cstrip.GetY() - trkcoordy[ip][iv];
2522 //
2523 if( TMath::Abs(xy[iv]) >= RMAX )continue;// discard strip if exceed TAUMAX
2524 //
2525 // FRACTION OF CHARGE COLLECTED BY THE STRIP
2526 //
2527 float pitch = 1.;//PITCH;
2528 float F = cstrip.GetE();
2529 F = F / qplane0[ip][iv]; // normalized to total charge
2530 F = F / pitch; // per unit length
2531 //
2532 // weigths
2533 //
2534 double calo_noise = 0.2; //MIP
2535 // if(F==0.)calo_noise = 0.7; //MIP (threshold)
2536 double DF2 = 0.;
2537 DF2 += pow(calo_noise/cstrip.GetE(),2.)*pow((double)F,2.);
2538 // DF2 += pow((double)F,2.)/(double)qplane0[ip][iv];//sbagliato
2539 double W = 1./DF2;
2540 // -----------
2541 // fill histos
2542 // -----------
2543 TH2F* h_qtot_tau = CaloElectron_parameters::Get()->h_qtot_tau[ibintau[ip][iv]][ivv];
2544 if( !h_qtot_tau )
2545 CaloElectron_parameters::Get()->Calibration_SetTools();
2546 //
2547 if( !h_qtot_tau )return;;
2548 h_qtot_tau->Fill(xy[iv],F);
2549 // -------------------------
2550 // evaluate weighted average
2551 // -------------------------
2552 int ibin;
2553 for(ibin=-1; ibin<CALIBNBIN; ibin++){
2554 if( -1*CALIBRANGE + (ibin+1)*2*CALIBRANGE/CALIBNBIN >= xy[iv] )break;
2555 }
2556 if(ibin==-1)continue;//strip out of range
2557 //
2558 // problema: quando il segnale e` 0. in realta` e` <0.7
2559 // quindi si introduce un bias... che spero pero` sia piccolo
2560 //
2561 //
2562 CaloElectron_parameters::Get()->summW[ibintau[ip][iv]][ivv][ibin]
2563 += W;
2564 CaloElectron_parameters::Get()->summWF[ibintau[ip][iv]][ivv][ibin]
2565 += W*(double)F;
2566
2567 }
2568 }
2569 }
2570
2571
2572 return;
2573 };
2574
2575 ClassImp(CaloElectron);
2576 ClassImp(CaloElectron_parameters);
2577
2578

  ViewVC Help
Powered by ViewVC 1.1.23