00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00047
00048 #ifndef __CINT__
00049 #include "TCanvas.h"
00050 #include "TChain.h"
00051 #include "TGraphErrors.h"
00052 #include "TF1.h"
00053 #include "TProfile.h"
00054 #include "TArrayD.h"
00055 #include "TCut.h"
00056 #include "TPolyMarker.h"
00057 #include "TVirtualFitter.h"
00058 #include "TMath.h"
00059 #include <Stiostream.h>
00060 #endif
00061
00062
00063
00064 void Calib_SC_GL(const char* input, const char* cuts=0, int scaler=-1, int debug=0);
00065
00066
00067 int FitLine(TTree* SC, const char* v0, const char* v1, double window,
00068 double& p0, double& p1, double& e0, double& e1, int debug=0);
00069 int Waiting();
00070 double Differ(double s0, double s1, double* co);
00071 void FindMinMax(TH1* h, double& min, double& max);
00072 int SetDivb(TH1I& hh, TArrayD& divb);
00073
00074
00075
00076 const int nfip=128;
00077 const int nsca=32;
00078 const int npos=nfip*nsca;
00079 TCanvas* c1 = 0;
00080 TChain* SCi[nfip];
00081 TGraphErrors* gr_lk=0;
00082 TGraphErrors* gr_sc=0;
00083 TGraphErrors* gr_so=0;
00084 TGraphErrors* gr_s2=0;
00085 TGraphErrors* gr_go=0;
00086 TGraphErrors* gr_temp=0;
00087 TF1* scgl_fit=0;
00088 TCut cut;
00089
00090
00091
00092
00093
00094 double MAX_SC = 0.0010;
00095
00096 double MAX_GAPF = 0.035;
00097
00098
00100
00101
00102
00103 void Calib_SC_GL(const char* input, const char* cuts, int scaler, int debug) {
00104
00105
00106
00107 TString dets[nsca];
00108 dets[0] = "bbce+bbcw-4*(bbcyb+bbcbb)";
00109 dets[1] = "bbcx" ;
00110 dets[2] = "zdcx" ;
00111 dets[3] = "zdce+zdcw";
00112 dets[4] = "bbce+bbcw";
00113
00114 int dets_used[nsca];
00115 memset(dets_used,0,nsca*sizeof(int));
00116 int minsca = 0;
00117 int maxsca = nsca;
00118 if (scaler>=0) { minsca = scaler; maxsca = scaler+1; }
00119
00120 int i,j,indx,uindx,jmin,nfi,result;
00121 TString fis[nfip];
00122 int det[nfip];
00123 double usc[nfip];
00124 double ugl[nfip];
00125 double uso[nfip];
00126 double sca[nfip];
00127
00128 char fname[128];
00129 Bool_t allZeros = kTRUE;
00130
00131
00132 ifstream dats(input);
00133 nfi = nfip;
00134 for (i=0;i<nfi;i++) {
00135 dats >> fname;
00136 if (dats.eof()) { nfi=i; continue; }
00137 fis[i] = fname;
00138 dats >> det[i] >> usc[i] >> ugl[i];
00139 if (usc[i]) allZeros = kFALSE;
00140
00141 if (fis[i].Contains("!")) {
00142 dats >> uso[i];
00143 fis[i].Remove(fis[i].First('!'),1);
00144 } else {
00145 uso[i] = 0;
00146 }
00147 dets_used[det[i]] = 1;
00148
00149 if (fname[0]=='#') i--;
00150 }
00151 printf("Found %d dataset specifications.\n",nfi);
00152
00153 cut = ((cuts) ? cuts : "");
00154
00155 if (c1==0) c1 = new TCanvas("c1","Calib SC and GL");
00156
00157
00158 double rms[npos];
00159 double lum[npos];
00160 double off[npos];
00161 double glk[npos];
00162 double glo[npos];
00163 double go[npos];
00164 double lumE[npos];
00165 double offE[npos];
00166 double glkE[npos];
00167 double gloE[npos];
00168
00169
00170 double rmin=1;
00171 jmin=-1;
00172 SCi[nfip-1] = new TChain("SC","ChainAll");
00173 for (i=0;i<nfi;i++) {
00174
00175
00176 SCi[i] = new TChain("SC",Form("Chain%d : %s",i,fis[i].Data()));
00177 int added_files=0;
00178 if ((added_files = SCi[i]->Add(fis[i].Data())) < 1)
00179 printf("Warning: no files added from %s\n",fis[i].Data());
00180 else {
00181 printf("%d files added from %s\n",added_files,fis[i].Data());
00182 SCi[nfip-1]->Add(fis[i].Data());
00183 }
00184 SCi[i]->SetMarkerStyle(7);
00185 SCi[i]->SetMarkerColor(2);
00186
00187
00188 for (j=minsca;j<maxsca;j++) {
00189 if (scaler>=0 && !(dets_used[j] || j==scaler)) continue;
00190 if (dets[j].Length()<1) continue;
00191 indx = i + j*nfi;
00192 double pr,pg,pl,po,pgE,plE,poE,pgo,pgoE;
00193 const char* dt = dets[j].Data();
00194
00195
00196 result = FitLine(SCi[i],"gapf",dt,MAX_GAPF,pgo,pg,pgoE,pgE,debug);
00197 if (result<0) return;
00198
00199
00200 result = FitLine(SCi[i],"sc",dt,MAX_SC,po,pl,poE,plE,debug);
00201 if (result<0) return;
00202
00203 TString plot = Form("sc-(%6.4g+(%6.4g)*(%s))",po,pl,dt);
00204 SCi[i]->Draw(plot.Data(),cut);
00205 pr = SCi[i]->GetHistogram()->GetRMS();
00206 if (debug>0) printf("RMS = %6.4g for %s\n",pr,dt);
00207
00208 rms[indx] = pr;
00209 glk[indx] = pg;
00210 lum[indx] = pl;
00211 off[indx] = po;
00212 glo[indx] = pgo;
00213 glkE[indx] = pgE;
00214 lumE[indx] = plE;
00215 offE[indx] = poE;
00216 gloE[indx] = pgoE;
00217 go[indx] = pgo + pg*uso[i];
00218
00219
00220 if (pr < rmin) { rmin=pr; jmin=j; }
00221 }
00222 }
00223 if (jmin<0) { printf("ERROR - no good scaler found\n"); return; }
00224 const char* detbest = dets[jmin].Data();
00225 if (scaler<0) {
00226 printf("*** Best scaler = %s [ID = %d]\n\n",detbest,jmin);
00227 }
00228
00229
00230
00231 gr_lk = new TGraphErrors(nfi);
00232 gr_sc = new TGraphErrors(nfi);
00233 gr_so = new TGraphErrors(nfi);
00234 gr_s2 = new TGraphErrors(nfi);
00235 gr_go = new TGraphErrors(nfi);
00236 gr_lk->SetTitle("Leak vs. SC*GL");
00237 gr_sc->SetTitle("SC vs. GL");
00238 gr_so->SetTitle("SO vs. GL");
00239 gr_s2->SetTitle("SO vs. SC");
00240 gr_go->SetTitle("Leak @uso vs. uso");
00241 gr_lk->SetMarkerStyle(27);
00242 gr_sc->SetMarkerStyle(27);
00243 gr_so->SetMarkerStyle(27);
00244 gr_s2->SetMarkerStyle(27);
00245 gr_go->SetMarkerStyle(27);
00246 gr_lk->SetMarkerColor(1);
00247 gr_sc->SetMarkerColor(4);
00248 gr_so->SetMarkerColor(4);
00249 gr_s2->SetMarkerColor(4);
00250 gr_go->SetMarkerColor(1);
00251 TPolyMarker mark;
00252 mark.SetMarkerColor(2);
00253 mark.SetMarkerStyle(28);
00254 double zero=0;
00255
00256 for (i=0; i<nfi; i++) {
00257 indx = i + jmin*nfi;
00258 if (det[i] != jmin) {
00259 for (j=0; j<i; j++) {
00260 if (det[i] == det[j]) { sca[i] = sca[j]; break; }
00261 }
00262 if (j==i) {
00263
00264 double temp1,temp2,temp3;
00265 result = FitLine(SCi[nfip-1],dets[det[i]],dets[jmin],0,temp1,sca[i],temp2,temp3,debug);
00266 if (result<0) return;
00267 }
00268 uindx = i + det[i]*nfi;
00269 } else {
00270 sca[i] = 1.0;
00271 uindx = indx;
00272 }
00273 if (debug>2) printf("RMS=%6.4g Lum=%6.4g Glk=%6.4g\n",
00274 rms[indx],lum[indx],glk[indx]);
00275
00276
00277 gr_lk->SetPoint(i,usc[i]*sca[i]*ugl[i],glk[indx]);
00278 gr_sc->SetPoint(i,ugl[i],lum[indx]);
00279 gr_so->SetPoint(i,ugl[i],off[indx]);
00280 gr_s2->SetPoint(i,lum[indx],off[indx]);
00281 gr_go->SetPoint(i,usc[i]*ugl[i],glo[indx]);
00282 gr_lk->SetPointError(i,0,glkE[indx]);
00283 gr_sc->SetPointError(i,0,lumE[indx]);
00284 gr_so->SetPointError(i,0,offE[indx]);
00285 gr_s2->SetPointError(i,lumE[indx],offE[indx]);
00286 gr_go->SetPointError(i,0,gloE[indx]);
00287
00288 }
00289
00290 c1->Clear();
00291 c1->Divide(2,2,0.01,0.025);
00292
00293 double p0,p1,p2,p3,ep0,ep1;
00294
00295 gr_go->Fit("pol1","0Q");
00296 TF1* go_fit = gr_go->GetFunction("pol1");
00297 go_fit->SetLineColor(4);
00298 p0 = go_fit->GetParameter(0);
00299 p1 = go_fit->GetParError(0);
00300 p2 = go_fit->GetParameter(1);
00301 p3 = go_fit->GetParError(1);
00302
00303
00304
00306
00307
00308
00309 if (allZeros) {
00310 printf("\n*** Try the following calibration values: ***\n");
00311 for (i=0; i<nfi; i++) {
00312 indx = i + jmin*nfi;
00313 double sop = -off[indx]/lum[indx];
00314 printf("SC = %6.4g * ((%s) - (%6.4g))",lum[indx],detbest,sop);
00315 printf(" with GL = %4.1f\n\n",ugl[i]);
00316 }
00317 c1->cd(1);
00318 gr_sc->Draw("AP");
00319 c1->cd(2);
00320 gr_so->Draw("AP");
00321 return;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00332
00333
00334
00335
00336
00337
00338
00339 c1->cd(1);
00340 gr_lk->Fit("pol1","Q");
00341 double* cov = TVirtualFitter::GetFitter()->GetCovarianceMatrix();
00342 TF1* lk_fit = gr_lk->GetFunction("pol1");
00343 lk_fit->SetLineColor(4);
00344 gr_lk->Draw("AP");
00345 p0 = lk_fit->GetParameter(0);
00346 p1 = lk_fit->GetParameter(1);
00347 ep0 = lk_fit->GetParError(0);
00348 ep1 = lk_fit->GetParError(1);
00349 double scXgl = -p0/p1;
00350 double escXgl = scXgl*TMath::Sqrt(cov[0]/(p0*p0)+cov[3]/(p1*p1)+2.*cov[1]/(-p0*p1));
00351 printf("* Constraint on SC x GL = %6.4g +/- %6.4g\n",scXgl,escXgl);
00352
00353 if (!scgl_fit) scgl_fit = new TF1("scgl_fit","[0]/x",-5.,100.);
00354 scgl_fit->SetParameter(0,scXgl);
00355 scgl_fit->SetLineColor(4);
00356 scgl_fit->SetLineWidth(1);
00357 mark.DrawPolyMarker(1,&scXgl,&zero);
00358
00359
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 double scp,glp,scp1,glp1,scp2,glp2;
00398 double s0,s1,s2,diff0,diff1,diff2;
00399 Bool_t one_sol;
00400
00401
00402 c1->cd(2);
00403 gr_sc->Fit("pol1","Q");
00404 gr_sc->Draw("AP");
00405 TF1* sc_fit = gr_sc->GetFunction("pol1");
00406 p0 = sc_fit->GetParameter(0);
00407 p1 = sc_fit->GetParameter(1);
00408 scp = p0*p0+4*p1*scXgl;
00409 if (scp>=0) scp = (p0 + TMath::Sqrt(scp))*0.5;
00410 else {
00411 scp = TMath::Sqrt(-p1*scXgl);
00412 printf("Using closest approach on first guess...\n");
00413 }
00414 glp = scXgl/scp;
00415
00416
00417 gr_sc->Fit("pol2","Q");
00418 gr_sc->Draw("AP");
00419 scgl_fit->DrawCopy("same");
00420 scgl_fit->SetLineStyle(7);
00421 scgl_fit->SetParameter(0,scXgl+escXgl);
00422 scgl_fit->DrawCopy("same");
00423 scgl_fit->SetParameter(0,scXgl-escXgl);
00424 scgl_fit->DrawCopy("same");
00425 TF1* sc_fi2 = gr_sc->GetFunction("pol2");
00426 p0 = sc_fi2->GetParameter(0);
00427 p1 = sc_fi2->GetParameter(1);
00428 p2 = sc_fi2->GetParameter(2);
00429 double coefs[4];
00430 coefs[3] = -1.0;
00431 coefs[2] = p0;
00432 coefs[1] = p1*scXgl;
00433 coefs[0] = p2*scXgl*scXgl;
00434 one_sol = TMath::RootsCubic(coefs,s0,s1,s2);
00435 if (one_sol) {
00436 printf("* Guesses on SC = %6.4g , %6.4g\n",scp,s0);
00437 scp1 = s0;
00438 } else {
00439 printf("* Guesses on SC = %6.4g , %6.4g , %6.4g , %6.4g\n",scp,s0,s1,s2);
00440 diff0 = Differ(scp,s0,coefs);
00441 diff1 = Differ(scp,s1,coefs);
00442 diff2 = Differ(scp,s2,coefs);
00443 scp1 = (diff0 < diff1 ? s0 : s1);
00444 scp1 = (diff2 < TMath::Min(diff0,diff1) ? s2 : scp1);
00445 }
00446 glp1 = scXgl/scp1;
00447
00448
00449 coefs[3] = p2;
00450 coefs[2] = p1;
00451 coefs[1] = p0;
00452 coefs[0] = -scXgl;
00453 one_sol = TMath::RootsCubic(coefs,s0,s1,s2);
00454 if (one_sol) {
00455 printf("* Guesses on GL = %6.4g , %6.4g\n",glp,s0);
00456 glp2 = s0;
00457 } else {
00458 printf("* Guesses on GL = %6.4g , %6.4g , %6.4g , %6.4g\n",glp,s0,s1,s2);
00459 diff0 = Differ(glp,s0,coefs);
00460 diff1 = Differ(glp,s1,coefs);
00461 diff2 = Differ(glp,s2,coefs);
00462 glp2 = (diff0 < diff1 ? s0 : s1);
00463 glp2 = (diff2 < TMath::Min(diff0,diff1) ? s2 : glp2);
00464 }
00465 scp2 = scXgl/glp2;
00466
00467
00468 diff1 = TMath::Sqrt(pow((scp1/scp)-1,2)+pow((glp1/glp)-1,2));
00469 diff2 = TMath::Sqrt(pow((scp2/scp)-1,2)+pow((glp2/glp)-1,2));
00470 if (diff1 < diff2) {
00471 scp = scp1; glp = glp1;
00472 } else {
00473 scp = scp2; glp = glp2;
00474 }
00475 mark.DrawPolyMarker(1,&glp,&scp);
00476
00477
00479
00480
00481
00482
00483
00484
00485
00486 c1->cd(4);
00487 gr_so->Fit("pol2","Q");
00488 gr_so->Draw("AP");
00489 TF1* so_fit = gr_so->GetFunction("pol2");
00490 double sop = -(so_fit->Eval(glp))/scp;
00491
00492 c1->cd(3);
00493 gr_s2->Fit("pol2","Q");
00494 gr_s2->Draw("AP");
00495 TF1* s2_fit = gr_s2->GetFunction("pol2");
00496 double s2p = -(s2_fit->Eval(scp))/scp;
00497 printf("* Guesses on SO = %6.4g , %6.4g\n",sop,s2p);
00498 sop = 0.5*(sop+s2p);
00499
00500 double som = -scp*sop;
00501 mark.DrawPolyMarker(1,&scp,&som);
00502 c1->cd(4);
00503 mark.DrawPolyMarker(1,&glp,&som);
00504
00505
00507
00508 printf("\n*** FINAL CALIBRATION VALUES: ***\n");
00509 printf("SC = %6.4g * ((%s) - (%6.4g))",scp,detbest,sop);
00510 printf(" with GL = %5.2f\n\n",glp);
00511
00512
00513 c1->Update(); c1->Draw();
00514
00515
00516 for (i=0;i<nfi;i++) {
00517 int color = 60 + (int) (40.0*((float) i)/((float) (nfi-1)));
00518 SCi[i]->SetMarkerColor(color);
00519 SCi[i]->SetLineColor(color);
00520 SCi[i]->SetMarkerStyle(22+i);
00521 }
00522
00523 }
00524
00525
00526
00528
00529 int FitLine(TTree* SC, const char* v0, const char* v1, double window,
00530 double& p0, double& p1, double& e0, double& e1, int debug) {
00531
00532
00533 double mindif = 0.01;
00534 double dif = 1.0;
00535 TF1 fline("fline","[0]+[1]*x");
00536 fline.SetParameters(0,0);
00537 p0 = 0; p1 = 0;
00538 int i,j,nbinsc = 8;
00539 if (gr_temp) delete gr_temp;
00540 gr_temp = new TGraphErrors(nbinsc);
00541 gr_temp->SetMarkerStyle(25);
00542 gr_temp->SetMarkerColor(4);
00543
00544 TCut cut2 = "";
00545 TString plot = Form("%s:%s",v0,v1);
00546
00547
00548 TString plotb = Form("%s>>hscab",v1);
00549 if (debug>2) printf("FitLine for \"%s\" from \"%s\"\n",plot.Data(),SC->GetTitle());
00550 SC->Draw(v1,cut);
00551 TH1* HSC = SC->GetHistogram();
00552 if (!HSC) printf("Problem creating hist of \"%s\" from \"%s\"\n",v1,SC->GetTitle());
00553 double hmin,hmax;
00554 FindMinMax(HSC,hmin,hmax);
00555
00556
00557 TH1I hscab("hscab","hschistb",nbinsc*100,hmin,hmax);
00558 TArrayD divb(nbinsc+1);
00559 divb[0] = hmin;
00560 divb[nbinsc] = hmax;
00561
00562 int count=0;
00563 double oldp1[256];
00564 while (dif>mindif && count<256) {
00565 if (count>0)
00566 cut2 = Form("abs(%s-(%6.4g+(%6.4g)*(%s)))<%6.4g",v0,p0,p1,v1,window);
00567 SC->Draw(plotb.Data(),cut&&cut2);
00568 int divbs = SetDivb(hscab,divb);
00569 if (divbs<3) return -5;
00570 if (divbs<=nbinsc) divb[divbs] = hmax;
00571 i = 0;
00572 double xi,yi,xf,yf;
00573 for (j=1; j<=divbs; j++) {
00574 TCut cut3 = cut && cut2 &&
00575 Form("((%s)>(%6.4g)&&(%s)<(%6.4g))",v1,divb[j-1],v1,divb[j]);
00576 SC->Draw(v0,cut3);
00577 HSC = SC->GetHistogram();
00578 if (!HSC) {
00579 printf("Problem creating hist of \"%s\" from \"%s\"\n",v0,SC->GetTitle());
00580 continue;
00581 }
00582 double yj = HSC->GetMean();
00583
00584
00585 double eyj = TMath::Sqrt(HSC->GetRMS()*HSC->GetRMS()
00586 + HSC->GetMeanError()*HSC->GetMeanError());
00587 SC->Draw(v1,cut3);
00588 HSC = SC->GetHistogram();
00589 if (!HSC) {
00590 printf("Problem creating hist of \"%s\" from \"%s\"\n",v1,SC->GetTitle());
00591 continue;
00592 }
00593 double xj = HSC->GetMean();
00594
00595 double exj = HSC->GetMeanError();
00596 gr_temp->SetPoint(i,xj,yj);
00597 gr_temp->SetPointError(i,exj,eyj);
00598 if (!count) {
00599 if (i>0) {
00600 xf = xj; yf = yj;
00601 } else {
00602 xi = xj; yi = yj;
00603 }
00604 }
00605 i++;
00606 }
00607 if (i<2) {
00608 printf("Problem with fit! Too few points remain!\n");
00609 break;
00610 }
00611 if (!count) fline.SetParameter(1,(yf-yi)/(xf-xi));
00612 gr_temp->Set(i);
00613 gr_temp->Fit(&fline,"QC");
00614 if (debug>4) {
00615 c1->Clear();
00616 gr_temp->Draw("AP");
00617
00618 SC->Draw(plot.Data(),cut&&cut2,"same");
00619 c1->Update(); c1->Draw();
00620 if (debug>5 && Waiting()<0) return -1;
00621 }
00622 p0 = fline.GetParameter(0); p1 = fline.GetParameter(1);
00623
00624 fline.FixParameter(0,p0);
00625 gr_temp->Fit(&fline,"QC");
00626 e1 = fline.GetParError(1);
00627 fline.ReleaseParameter(0);
00628 fline.FixParameter(1,p1);
00629 gr_temp->Fit(&fline,"QC");
00630 e0 = fline.GetParError(0);
00631 fline.ReleaseParameter(1);
00632 if (window>1e-19) {
00633 dif = 1.0;
00634 for (int cmp=0; cmp<count; cmp++) {
00635 double olddif = 1e10;
00636 if (oldp1[cmp]!=0) olddif = TMath::Abs(1.0-(p1/oldp1[cmp]));
00637 dif = TMath::Min(dif,olddif);
00638 }
00639 } else dif = 0;
00640 oldp1[count]=p1;
00641 if (debug>3) printf("Finishing iteration %d\n",count);
00642 count++;
00643 }
00644 if (debug>1) printf("Linear fit within %s\n",cut2.GetTitle());
00645 return count;
00646 }
00647
00648 int Waiting() {
00649 int tempi;
00650 printf("Waiting...\n");
00651 cin >> tempi;
00652 return tempi;
00653 }
00654
00655 double Differ(double s0, double s1, double* co) {
00656
00657 if (s1*s0 < 0) return 1e15;
00658 double eval = co[0]+s1*co[1]+s1*s1*co[2]+s1*s1*s1*co[3];
00659
00660 if (TMath::Abs(eval) > 0.01*TMath::Abs(co[0])) return 2e15;
00661 return TMath::Abs(1.0-(s1/s0));
00662 }
00663
00664 void FindMinMax(TH1* h, double& min, double& max) {
00665
00666 min = h->GetXaxis()->GetXmin();
00667 max = h->GetXaxis()->GetXmax();
00668
00669
00670 double margin = 0.075*(max-min);
00671 min -= margin;
00672 max += margin;
00673 }
00674
00675 int SetDivb(TH1I& hh, TArrayD& divb) {
00676
00677 double* integrals = hh.GetIntegral();
00678 int nbins = divb.GetSize()-1;
00679 double frac = 1.0/((float) nbins);
00680 int bin=1; int step=1; int count=0;
00681 while (step<nbins && bin<=hh.GetNbinsX()) {
00682
00683 count += (int) hh.GetBinContent(bin);
00684 if (integrals[bin] >= step*frac && count>1) {
00685 divb.AddAt(hh.GetXaxis()->GetBinCenter(bin),step);
00686 step++; count=0;
00687 }
00688 bin++;
00689 }
00690 return step;
00691 }
00692
00693
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717