00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __CINT__
00025 #include <iostream>
00026 #include <cstdio>
00027 #include <cstdlib>
00028 #include <cstring>
00029 #include <cctype>
00030
00031 #include <getopt.h>
00032 #include <signal.h>
00033
00034 #include <TROOT.h>
00035 #include <TSystem.h>
00036 #include <TError.h>
00037 #include <TStyle.h>
00038 #include <TApplication.h>
00039 #include <TRint.h>
00040 #include <TList.h>
00041 #include <TCanvas.h>
00042 #include <TBox.h>
00043 #include <TLine.h>
00044 #include <TPave.h>
00045 #include <TLegend.h>
00046 #include <TPaveLabel.h>
00047 #include <TPolyLine.h>
00048 #include <TGraph.h>
00049
00050 #include <TString.h>
00051 #include <TH1.h>
00052 #include <TH2.h>
00053 #include <TF1.h>
00054
00055 #include <TTree.h>
00056 #include <TFile.h>
00057 #include <TChain.h>
00058 #include <TBranch.h>
00059
00060 using namespace std;
00061
00062 #endif
00063
00064 const float etaBinTable[] = {
00065 2.0000,1.9008,1.8065,1.7168,1.6317,1.5507,1.4738,
00066 1.4007,1.3312,1.2651,1.2023,1.1427,1.0860,-1.0 };
00067
00068 const float SamplingFraction = 0.05;
00069 const float EnergyLossMip = 0.0018*9.6;
00070 const short AdcRange = 4076;
00071 const float EnergyTransverseMax = 60.0;
00072
00073 const int MaxSec = 12;
00074 const int MaxSSec = 5;
00075 const int MaxEta = 12;
00076
00077 const int FirstSec= 0;
00078 const int LastSec =11;
00079 const int MinEta = 4;
00080
00081
00082 float MaxCTB = 1000.0;
00083 const float MinPt = 0.500;
00084 const float MaxDEta = 0.035;
00085 const float MaxDPhi = 0.028;
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 void mystat(TH1 *h, Double_t x1, Double_t x2,
00099 Double_t& xmean, Double_t& emean, Double_t& dint,
00100 Double_t& xmax , Double_t& xlo , Double_t& xhi);
00101 int miptower( TH1 **hadc,
00102 const int MinEta,
00103 const int MaxEta,
00104 const char *dname= "eta",
00105 const char *func = "landau",
00106 const float xmin = 10.0,
00107 const float xmax = 80.0,
00108 FILE *outfd = stderr);
00109
00110
00111
00112
00113
00114
00115 void
00116 mipcalib(
00117 const int secNum = 0,
00118 const char *fName = "",
00119 const char *histName= "calib.root",
00120 const char *fitFunc = "landau" ,
00121 const float xMin = 10.0,
00122 const float xMax = 80.0,
00123 const int trig = 0,
00124 const bool doSort = false
00125 )
00126 {
00127 gROOT->Reset();
00128 gErrorIgnoreLevel=1000;
00129
00130 const int MaxHist = MaxEta*MaxSec*MaxSSec;
00131 const int MaxTracks = 1024;
00132 const int MaxTrigger = 32;
00133
00134
00135 int numtracks;
00136 int sector[MaxTracks];
00137 int subsec[MaxTracks];
00138 int etabin[MaxTracks];
00139 float adcval[MaxTracks];
00140 int ntrack[MaxTracks];
00141
00142 float pt [MaxTracks];
00143 float ptot [MaxTracks];
00144
00145
00146
00147 float etatrk[MaxTracks];
00148
00149 float detasmd [MaxTracks];
00150 float dphismd [MaxTracks];
00151 float detapres[MaxTracks];
00152 float dphipres[MaxTracks];
00153 float detapost[MaxTracks];
00154 float dphipost[MaxTracks];
00155
00156
00157 int numtrig;
00158 int trigid[MaxTrigger];
00159 int daqbits;
00160 int ctbsum;
00161
00162
00163 TH1* hadc[MaxHist]; for(int i=0; i<MaxHist; i++) hadc[i]=NULL;
00164 TH1* heta[MaxEta]; for(int i=0; i<MaxEta ; i++) heta[i]=NULL;
00165
00166 int nentries= 0;
00167 long ntracks = 0;
00168 TChain *chain = NULL;
00169
00170 if(doSort) {
00171
00172 chain = new TChain("track");
00173 if( fName!="" ) {
00174 chain->Add(fName);
00175 } else {
00176 TFile *f = NULL;
00177 TSeqCollection *seq = gROOT->GetListOfFiles();
00178 TIter next(seq);
00179 while ( ( f = (TFile *)next() ) != NULL ) chain->Add(f->GetName());
00180 fName = "attached files";
00181 }
00182 cout << "sorting " << fName << " (trigger=" << trig << ") to " << histName << endl;
00183 cout << "MaxCTB: " << MaxCTB << endl;
00184 nentries = (int)chain->GetEntries();
00185
00186 chain->SetBranchAddress("ntracks" ,&numtracks);
00187
00188 chain->SetBranchAddress("sec" , sector );
00189 chain->SetBranchAddress("ssec" , subsec );
00190 chain->SetBranchAddress("eta" , etabin );
00191 chain->SetBranchAddress("adc" , adcval );
00192 chain->SetBranchAddress("track" , ntrack );
00193
00194 chain->SetBranchAddress("pt" , pt );
00195 chain->SetBranchAddress("ptot" , ptot );
00196
00197
00198
00199
00200
00201 chain->SetBranchAddress("detasmd" , detasmd );
00202 chain->SetBranchAddress("dphismd" , dphismd );
00203
00204 chain->SetBranchAddress("detapres", detapres );
00205 chain->SetBranchAddress("dphipres", dphipres );
00206
00207 chain->SetBranchAddress("detapost", detapost );
00208 chain->SetBranchAddress("dphipost", dphipost );
00209
00210 chain->SetBranchAddress("ntrig" ,&numtrig );
00211 chain->SetBranchAddress("trigid" , trigid );
00212 chain->SetBranchAddress("daqbits" ,&daqbits );
00213 chain->SetBranchAddress("ctbsum" ,&ctbsum );
00214 } else {
00215 cout << histName << " fitting " << fitFunc << endl;
00216 }
00217
00218 int sec1=(secNum>0) ? secNum-1 : FirstSec;
00219 int sec2=(secNum>0) ? secNum-1 : LastSec;
00220
00221 TFile *histfile = new TFile(histName,doSort ? "RECREATE" : "READ");
00222 TString outName = TString(histName).ReplaceAll(".root","");
00223
00224
00225
00226 char dir[256];
00227 char name[256],titl[256];
00228 for(int sec=sec1;sec<=sec2 ;sec++) {
00229 for( int ssec=0; ssec<MaxSSec; ssec++) {
00230 sprintf(dir,"%02dT%1c",sec+1,ssec+'A');
00231 if(doSort) histfile->mkdir(dir);
00232 histfile->cd(dir);
00233 for( int eta=0; eta<MaxEta; eta++ ) {
00234 sprintf(titl,"ADC(%02dT%1c%02d)",sec+1,ssec+'A',eta+1);
00235 sprintf(name,"%02dT%1c%02d" ,sec+1,ssec+'A',eta+1);
00236 int hidx=(sec*MaxSSec+ssec)*MaxEta+eta;
00237 if(hidx<0 || MaxHist<=hidx) continue;
00238 if(doSort) hadc[hidx] = new TH1F(name,titl,40,0.0,120.0);
00239 else hadc[hidx] = (TH1F *)gDirectory->Get(name);
00240
00241 }
00242 }
00243 }
00244
00245 {
00246 sprintf(dir,"eta");
00247 if(doSort) histfile->mkdir(dir);
00248 histfile->cd(dir);
00249 for( int eta=0; eta<MaxEta; eta++ ) {
00250 sprintf(titl,"ADC(ETA%02d)",eta+1);
00251 sprintf(name,"ETA%02d" ,eta+1);
00252 if(doSort) heta[eta] = new TH1F(name,titl,60,0.0,120.0);
00253 else heta[eta] = (TH1F *)gDirectory->Get(name);
00254 }
00255 }
00256
00257 if(doSort) {
00258 int ie=0;
00259 for(ie=0;ie<nentries;ie++) {
00260 ntracks += numtracks;
00261 chain->GetEntry(ie);
00262 if(ie%100==0)fprintf(stdout ,"Entry %d/%d (%.2f%%)\r",ie,nentries,(ie*100.0)/nentries);
00263 if(ctbsum>MaxCTB) continue;
00264 if(trig>0) {
00265 int it=0;
00266 int *trigword=trigid;
00267 while(it<numtrig && *trigword>0 && *trigword!=trig ) { it++; trigword++; };
00268 if(*trigword!=trig) continue;
00269 }
00270
00271 for(int t=0;t<numtracks; t++) {
00272
00273 if(ntrack[t] > 1 ) continue;
00274 if(pt[t] < MinPt ) continue;
00275 if(fabs(detapres[t]) > MaxDEta ) continue;
00276 if(fabs(dphipres[t]) > MaxDPhi ) continue;
00277 if(fabs(detasmd[t]) > MaxDEta ) continue;
00278 if(fabs(dphismd[t]) > MaxDPhi ) continue;
00279 if(fabs(detapost[t]) > MaxDEta ) continue;
00280 if(fabs(dphipost[t]) > MaxDPhi ) continue;
00281
00282 int sec = sector[t];
00283 int ssec = subsec[t];
00284 int eta = etabin[t];
00285 int hidx=(sec*MaxSSec+ssec)*MaxEta+eta;
00286 if(hidx<0 || MaxHist<=hidx) continue;
00287 if(hadc[hidx]!=NULL) hadc[hidx]->Fill(adcval[t]);
00288 if(heta[eta ]!=NULL) heta[eta ]->Fill(adcval[t]);
00289 }
00290 }
00291 fprintf(stdout ,"Entry %d/%d (%.2f%%)\n",ie,nentries,(ie*100.0)/nentries);
00292 fprintf(stdout ,"Totals tracks %ld\n",ntracks);
00293 histfile->Write();
00294 } else {
00295 int nFitOK=0;
00296 TCanvas *c1 = new TCanvas(outName,"MIP CALIB",800,0,1024,1024);
00297 c1->Print(outName+".ps[");
00298 bool go_on = true;
00299 for(int sec=sec1;sec<=sec2 && go_on;sec++) {
00300 char outfn[256];
00301 sprintf(outfn,"sector%02d.cal",sec+1);
00302 FILE *outfd = fopen(outfn,"w");
00303 for(int ssec=0;ssec<MaxSSec && go_on;ssec++) {
00304 sprintf(dir,"%02dT%1c",sec+1,ssec+'A');
00305 c1->Clear();
00306 nFitOK += miptower(hadc+(sec*MaxSSec+ssec)*MaxEta,MinEta,MaxEta,dir,fitFunc,xMin,xMax,outfd);
00307 c1->Update();
00308 c1->Print(outName+".ps");
00309
00310
00311
00312 if(!gROOT->IsBatch()) {
00313 while(true) {
00314 char cmd[256];
00315 char c;
00316 int k=0;
00317 cmd[k]=0x00;
00318 cout << "fit> ";
00319 do {
00320 c=getchar();
00321 if(c==0x0A) { cmd[k++]=0x00; break; }
00322 cmd[k++]=c;
00323 } while(k<255);
00324 if(cmd[0]==0x0A) { break;
00325 } else if(strncasecmp(cmd,".cont" ,2)==0 ||
00326 strncasecmp(cmd, "cont" ,1)==0) { break;
00327 } else if(strncasecmp(cmd,".quit" ,2)==0 ||
00328 strncasecmp(cmd, "quit" ,1)==0) { go_on=false; break;
00329 } else if(strncasecmp(cmd,".help" ,2)==0 ||
00330 strncasecmp(cmd, "help" ,1)==0) {
00331 cerr << "commands (may be abbreviated):\n";
00332 cerr << " .c cont - to continue with fitting\n" ;
00333 cerr << " .q quit - to quit fitting loop \n" ;
00334 cerr << " .h help - this help \n" << endl;
00335 } else {
00336 cerr << "unkown command:" << cmd << " type help for command list" << endl;
00337 }
00338 }
00339 }
00340 }
00341 fclose(outfd);
00342 }
00343 cout << "TOTAL FIT OK " << nFitOK << endl;
00344 c1->Clear();
00345 (void) miptower(heta,MinEta,MaxEta,"ETA",fitFunc,xMin,xMax);
00346 c1->Update();
00347 c1->Print(outName+".ps");
00348 c1->Print(outName+".ps]");
00349 }
00350 }
00351
00352
00353
00354
00355
00356
00357 int
00358 miptower( TH1 **hadc,
00359 const int MinEta,
00360 const int MaxEta,
00361 const char *dir,
00362 const char *func ,
00363 const float xMin ,
00364 const float xMax ,
00365 FILE *outfd)
00366 {
00367 const Double_t MinCounts = 30.0;
00368 const Double_t MinPeakV = 8.0;
00369 const Double_t MaxPeakV = 30.0;
00370 const Double_t MaxPeakE = 6.0 ;
00371 const Double_t MinChi2 = 0.0 ;
00372 const Double_t MaxChi2 =10.0 ;
00373
00374 const int MaxPad = MaxEta-MinEta;
00375
00376 int nFitOK=0;
00377
00378
00379 TString gltit("EEMC TOWERS ");
00380 TString pz ("Piotr A. Zolnierczuk (IU) ");
00381 TPaveLabel *tlab = new TPaveLabel(0.005,0.955,0.990,0.985,gltit+dir);
00382 TDatime *now = new TDatime;
00383 TPaveLabel *date = new TPaveLabel(0.555,0.005,0.995,0.045,pz+now->AsString());
00384 TPad *gpad = new TPad("Graphs","Graphs",0.005,0.05,0.995,0.95);
00385
00386 gStyle->SetOptStat(101111);
00387 gStyle->SetOptFit(1);
00388 tlab->Draw();
00389 date->Draw();
00390 gpad->Draw();
00391 gpad->Divide(2,MaxPad/2);
00392 gpad->cd(1);
00393 gpad->Update();
00394
00395 if(gROOT->IsBatch()) cout << "TOWERS " << dir << " " << flush;
00396
00397
00398
00399
00400
00401
00402 for(int eta=0,pad=0; pad<MaxPad && eta<MaxEta; eta++) {
00403 Double_t xint;
00404 Double_t xmean , xmnerr;
00405 Double_t xpeak , xpkerr;
00406 Double_t xgain , xgnerr;
00407 Double_t par[20];
00408 Double_t chi2;
00409 Int_t ndf;
00410 char name[256];
00411 sprintf(name,"%s%02d",dir,eta+1);
00412
00413 if(hadc[eta]==NULL) continue;
00414
00415 double xlim1, xlim2;
00416 mystat(hadc[eta],xMin,xMax,xmean,xmnerr,xint,xpeak,xlim1,xlim2);
00417
00418
00419 par[0] = hadc[eta]->GetMaximum();
00420 par[1] = xpeak;
00421 par[2] = xmnerr;
00422
00423
00424 TF1 *fit1 = new TF1("fit1" ,func ,0.0,120.0);
00425 fit1->SetParameters(par);
00426 fit1->SetLineWidth(2);
00427 fit1->SetLineColor(kRed);
00428
00429
00430 if(strncmp(func,"gaus",4)==0) {
00431
00432 hadc[eta]->Fit("fit1","Q0","",xlim1,xlim2);
00433 } else {
00434 hadc[eta]->Fit("fit1","Q0","",xMin,xMax);
00435 }
00436
00437
00438
00439
00440 xpeak = fit1->GetParameter(1);
00441 xpkerr = fit1->GetParError(1);
00442 chi2 = fit1->GetChisquare();
00443 ndf = fit1->GetNDF();
00444 chi2 = (ndf>=1) ? chi2/ndf : -1.0;
00445 xpkerr *= (chi2>0.0) ? sqrt(chi2) : 1.0 ;
00446
00447
00448 Double_t xeta = 0.5*(etaBinTable[eta-1]+etaBinTable[eta]);
00449 Double_t xscale = SamplingFraction/EnergyLossMip*TMath::TanH(xeta);
00450 xgain = xpeak * xscale;
00451 xgnerr = xpkerr * xscale;
00452
00453
00454 fprintf(outfd,"%6s %8.3f %8.3f 0.0 # %8.3f %6.0f",
00455 name,xgain,xgnerr,chi2,xint);
00456
00457
00458 char *errmsg = NULL;
00459 if (xint<MinCounts ) errmsg = "not enough statistics";
00460 else if(xpeak<MinPeakV || MaxPeakV<xpeak ) errmsg = "bad fit value";
00461 else if( MaxPeakE < xpkerr ) errmsg = "fit error too large";
00462 else if(chi2<MinChi2 || MaxChi2<chi2 ) errmsg = "chi2 too large";
00463
00464 if(errmsg==NULL) fprintf(outfd," fit %s ok \n",func);
00465 else fprintf(outfd," *** %s ***\n",errmsg);
00466 if(eta<MinEta) continue;
00467
00468
00469 gpad->cd(++pad);
00470 Double_t hmax = hadc[eta]->GetMaximum();
00471 hadc[eta]->SetMaximum( (hmax>10.0) ? 1.2*hmax : 12.0 );
00472 hadc[eta]->GetXaxis()->SetTitle("ADC");
00473 hadc[eta]->Draw("E");
00474 fit1->Draw("SAME");
00475
00476 if(errmsg!=NULL) {
00477 hmax = hadc[eta]->GetMaximum();
00478 TPaveLabel* badfitlabel = new TPaveLabel(70,0.25*hmax,118,0.40*hmax,errmsg);
00479 badfitlabel->SetFillColor(kRed );
00480 badfitlabel->SetTextColor(kYellow );
00481 badfitlabel->Draw();
00482 } else {
00483 nFitOK++;
00484 }
00485 gpad->Update();
00486 }
00487 fprintf(outfd,"\n");
00488 if(gROOT->IsBatch()) cout << " (" << nFitOK << ") DONE " << endl;
00489 return nFitOK;
00490 }
00491
00492
00493
00494
00495
00496
00497
00498 void
00499 mystat(TH1 *h,
00500 Double_t x1 , Double_t x2,
00501 Double_t& xmean, Double_t& emean, Double_t& dint,
00502 Double_t& xmax , Double_t& xlo , Double_t& xhi)
00503 {
00504 TAxis* xax = h->GetXaxis();
00505 Int_t i1 = xax->FindBin(x1);
00506 Int_t i2 = xax->FindBin(x2);
00507
00508 Float_t sw=0.0,sw2=0.0,swx=0.0,swx2=0.0,wmax=0.0;
00509 Int_t n=0;
00510 Int_t imax=0;
00511 xmean=emean=xmax=0.0;
00512 for(Int_t i=i1;i<=i2;i++) {
00513 Double_t x = h->GetBinCenter(i);
00514 Double_t w = h->GetBinContent(i);
00515 if(w>wmax) { xmax=x; wmax=w; imax=i; }
00516 sw += w;
00517 sw2 += w*w;
00518 swx += w*x;
00519 swx2+= w*x*x;
00520 n++;
00521 }
00522
00523 xlo = h->GetBinCenter(i1);
00524 xhi = h->GetBinCenter(i2);
00525
00526
00527
00528 wmax *= 0.4;
00529 for(Int_t i=imax;i>=i1;i--) {
00530 Double_t w = h->GetBinContent(i);
00531
00532 if(w<wmax) {
00533 xlo = h->GetBinCenter(i);
00534 break;
00535 }
00536 }
00537
00538 for(Int_t i=imax;i<=i2;i++) {
00539 Double_t w = h->GetBinContent(i);
00540
00541 if(w<wmax) {
00542 xhi = h->GetBinCenter(i);
00543 break;
00544 }
00545 }
00546
00547 dint = sw;
00548 xmean = (sw>0.0) ? swx/sw : 0.0 ;
00549 emean = (sw>0.0) ? (swx2/sw - xmean*xmean ) : 0.0 ;
00550 emean = (emean>0.0) ? sqrt(emean/n) : 0.0;
00551 }
00552
00553
00554 #ifndef __CINT__
00555 int sector = 0;
00556 char *outname = "mipcalib.hist.root";
00557 char *fitfunc = "landau";
00558
00559 int trig = 0;
00560 float xmin = 9.0;
00561 float xmax = 100.0;
00562
00563 void
00564 usage(char *name)
00565 {
00566 cerr << "usage: " << name << " [options] rootfile(s) \n";
00567 cerr << " -s <sector> - (0 == all) \n";
00568 cerr << " -t <trigger_id> - (0 == any) \n";
00569 cerr << " -o <histogram file> - .hist.root file \n";
00570 cerr << " -L - fit Landau/Gauss distributions\n";
00571 cerr << " -G - fit Landau/Gauss distributions\n";
00572 cerr << " -x <xmin> - fit lower bound\n";
00573 cerr << " -X <xmax> - fit upper bound\n";
00574 cerr << " -b - run in batch mode without graphics \n";
00575 cerr << " -h - this help\n";
00576 cerr << endl;
00577 }
00578
00579
00580 int
00581 main(int argc, char **argv)
00582 {
00583 extern char *optarg;
00584 extern int optind;
00585 char optchar;
00586 cerr << "#===============================================\n";
00587 cerr << "# ******* WARNING ******* \n";
00588 cerr << "# A LOUSY PROGRAM THAT GREW OUT OF A ROOT MACRO \n";
00589 cerr << "# needs to be rewritten \n";
00590 cerr << "#===============================================\n" << endl;
00591
00592
00593 while((optchar = getopt(argc, argv, "s:t:o:LGx:X:c:bqnlh")) != EOF) {
00594 switch(optchar) {
00595 case 's': sector = atoi(optarg); break;
00596 case 'o': outname = optarg ; break;
00597 case 't': trig = atoi(optarg); break;
00598 case 'L': fitfunc = "landau"; break;
00599 case 'G': fitfunc = "gaus" ; break;
00600 case 'x': xmin = atof(optarg); break;
00601 case 'X': xmax = atof(optarg); break;
00602 case 'c': MaxCTB = atof(optarg); break;
00603 case 'b': gROOT->SetBatch(kTRUE);
00604 case 'q':
00605 case 'n':
00606 case 'l': break;
00607 case 'h': usage(argv[0]); exit(0); break;
00608 case '?':
00609 default: usage(argv[0]); exit(-1);break;
00610 }
00611 }
00612
00613
00614
00615 for(int k=optind;k<argc; k++) new TFile(argv[k],"");
00616 argc=optind;
00617
00618
00619 TApplication *myApp;
00620 if(gROOT->IsBatch())
00621 myApp = new TApplication("mipcalib",&argc,argv);
00622 else
00623 myApp = new TRint ("mipcalib",&argc,argv);
00624
00625 mipcalib(sector,"",outname,fitfunc,xmin,xmax,trig,true );
00626 mipcalib(sector,"",outname,fitfunc,xmin,xmax,trig,false);
00627
00628 if(!gROOT->IsBatch() ) myApp->Run();
00629
00630 return 0;
00631 }
00632 #endif