StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
mipcalib.C
1 // File: mipcalib.C
2 // Author: Piotr A. Zolnierczuk, IUCF
3 // Date: June 15-21, 2003
4 // Update: Jan 7, 2004
5 // Purpose: generate EEMC Tower PMT calibration
6 // Usage:
7 // root './mipcalib.C(sector,rootfile)'
8 // sector is a sector number 5,6,7 or 8 (0 stands for all four)
9 // rootfile 'ntuple' tree root file (wildcards allowed)
10 // Output:
11 // stderr - fitting log file
12 // sectorXX.cal - eemc dbase input files(s)
13 // mip$$T#EE.eps - an eps plot for each tower
14 // mipcalib.ps - a single ps of the above
15 // mipcalib.hist.root - a root histo file
16 //
17 // Notes(s):
18 // 1. cuts are nicely hidden :) in miptower()
19 // 2. best to run it under bash where one can redirect
20 // stdout and stderr separately e.g.
21 // root './mipcalib.C(0,"root/R*.root")' 2> mipcalib.log
22 //
23 
24 #ifndef __CINT__
25 #include <iostream>
26 #include <cstdio>
27 #include <cstdlib>
28 #include <cstring>
29 #include <cctype>
30 
31 #include <getopt.h>
32 #include <signal.h>
33 
34 #include <TROOT.h>
35 #include <TSystem.h>
36 #include <TError.h>
37 #include <TStyle.h>
38 #include <TApplication.h>
39 #include <TRint.h>
40 #include <TList.h>
41 #include <TCanvas.h>
42 #include <TBox.h>
43 #include <TLine.h>
44 #include <TPave.h>
45 #include <TLegend.h>
46 #include <TPaveLabel.h>
47 #include <TPolyLine.h>
48 #include <TGraph.h>
49 
50 #include <TString.h>
51 #include <TH1.h>
52 #include <TH2.h>
53 #include <TF1.h>
54 
55 #include <TTree.h>
56 #include <TFile.h>
57 #include <TChain.h>
58 #include <TBranch.h>
59 
60 using namespace std;
61 
62 #endif
63 
64 const float etaBinTable[] = {
65  2.0000,1.9008,1.8065,1.7168,1.6317,1.5507,1.4738,
66  1.4007,1.3312,1.2651,1.2023,1.1427,1.0860,-1.0 };
67 
68 const float SamplingFraction = 0.05; // 5%
69 const float EnergyLossMip = 0.0018*9.6; // 0.020 GeV at eta=1.3
70 const short AdcRange = 4076; // 4096 - 20(pedestals)
71 const float EnergyTransverseMax = 60.0; // 60 GeV
72 
73 const int MaxSec = 12;
74 const int MaxSSec = 5;
75 const int MaxEta = 12;
76 
77 const int FirstSec= 0;
78 const int LastSec =11;
79 const int MinEta = 4;
80 
81 //const float MaxCTB = 1000;
82 float MaxCTB = 1000.0;
83 const float MinPt = 0.500;
84 const float MaxDEta = 0.035; //0.020;
85 const float MaxDPhi = 0.028; //0.026;
86 
87 
88 // PHIHW 0.0873/2.0
89 // ETAHW 12: 0.0992/2.0
90 // 10: 0.0897/2.0
91 // 8: 0.0810/2.0
92 // 6: 0.0731/2.0
93 // 4: 0.0661/2.0
94 // 1: 0.0567/2.0
95 
96 
97 
98 void mystat(TH1 *h, Double_t x1, Double_t x2,
99  Double_t& xmean, Double_t& emean, Double_t& dint,
100  Double_t& xmax , Double_t& xlo , Double_t& xhi);
101 int miptower( TH1 **hadc,
102  const int MinEta,
103  const int MaxEta,
104  const char *dname= "eta",
105  const char *func = "landau",
106  const float xmin = 10.0,
107  const float xmax = 80.0,
108  FILE *outfd = stderr);
109 
110 
111 // ===========================================================================
112 // the main routine
113 // ===========================================================================
114 // WHAT A MESS!!!
115 void
116 mipcalib(
117  const int secNum = 0, // counting from 1!! (0==all)
118  const char *fName = "", // if fName=="", use root global file list
119  const char *histName= "calib.root",// histogram file name
120  const char *fitFunc = "landau" ,// function to fit (gaus or landau)
121  const float xMin = 10.0, // lower limit of the fit
122  const float xMax = 80.0, // upper limit of the fit
123  const int trig = 0, // select trigger, 0==all
124  const bool doSort = false // a flag that decides whether we sort or plot the data
125  )
126 {
127  gROOT->Reset();
128  gErrorIgnoreLevel=1000;
129 
130  const int MaxHist = MaxEta*MaxSec*MaxSSec;
131  const int MaxTracks = 1024;
132  const int MaxTrigger = 32;
133 
134  // track info
135  int numtracks;
136  int sector[MaxTracks];
137  int subsec[MaxTracks];
138  int etabin[MaxTracks];
139  float adcval[MaxTracks];
140  int ntrack[MaxTracks];
141  //
142  float pt [MaxTracks];
143  float ptot [MaxTracks];
144  //float length[MaxTracks];
145  //float dedx [MaxTracks];
146  //int nhits [MaxTracks];
147  float etatrk[MaxTracks];
148  //
149  float detasmd [MaxTracks];
150  float dphismd [MaxTracks];
151  float detapres[MaxTracks];
152  float dphipres[MaxTracks];
153  float detapost[MaxTracks];
154  float dphipost[MaxTracks];
155 
156  // trigger Info
157  int numtrig;
158  int trigid[MaxTrigger];
159  int daqbits;
160  int ctbsum;
161 
162  // histogram list
163  TH1* hadc[MaxHist]; for(int i=0; i<MaxHist; i++) hadc[i]=NULL;
164  TH1* heta[MaxEta]; for(int i=0; i<MaxEta ; i++) heta[i]=NULL;
165 
166  int nentries= 0;
167  long ntracks = 0;
168  TChain *chain = NULL;
169 
170  if(doSort) {
171 
172  chain = new TChain("track");
173  if( fName!="" ) {
174  chain->Add(fName);
175  } else {
176  TFile *f = NULL;
177  TSeqCollection *seq = gROOT->GetListOfFiles();
178  TIter next(seq);
179  while ( ( f = (TFile *)next() ) != NULL ) chain->Add(f->GetName());
180  fName = "attached files";
181  }
182  cout << "sorting " << fName << " (trigger=" << trig << ") to " << histName << endl;
183  cout << "MaxCTB: " << MaxCTB << endl;
184  nentries = (int)chain->GetEntries();
185 
186  chain->SetBranchAddress("ntracks" ,&numtracks);
187 
188  chain->SetBranchAddress("sec" , sector );
189  chain->SetBranchAddress("ssec" , subsec );
190  chain->SetBranchAddress("eta" , etabin );
191  chain->SetBranchAddress("adc" , adcval );
192  chain->SetBranchAddress("track" , ntrack );
193 
194  chain->SetBranchAddress("pt" , pt );
195  chain->SetBranchAddress("ptot" , ptot );
196  //chain->SetBranchAddress("nhits" , nhits );
197  //chain->SetBranchAddress("length" , length );
198  //chain->SetBranchAddress("dedx" , dedx );
199  //chain->SetBranchAddress("etatrk" , etatrk );
200 
201  chain->SetBranchAddress("detasmd" , detasmd );
202  chain->SetBranchAddress("dphismd" , dphismd );
203 
204  chain->SetBranchAddress("detapres", detapres );
205  chain->SetBranchAddress("dphipres", dphipres );
206 
207  chain->SetBranchAddress("detapost", detapost );
208  chain->SetBranchAddress("dphipost", dphipost );
209 
210  chain->SetBranchAddress("ntrig" ,&numtrig );
211  chain->SetBranchAddress("trigid" , trigid );
212  chain->SetBranchAddress("daqbits" ,&daqbits );
213  chain->SetBranchAddress("ctbsum" ,&ctbsum );
214  } else {
215  cout << histName << " fitting " << fitFunc << endl;
216  }
217 
218  int sec1=(secNum>0) ? secNum-1 : FirstSec;
219  int sec2=(secNum>0) ? secNum-1 : LastSec;
220 
221  TFile *histfile = new TFile(histName,doSort ? "RECREATE" : "READ");
222  TString outName = TString(histName).ReplaceAll(".root","");
223 
224  // histograms
225  // individual towers
226  char dir[256];
227  char name[256],titl[256];
228  for(int sec=sec1;sec<=sec2 ;sec++) {
229  for( int ssec=0; ssec<MaxSSec; ssec++) {
230  sprintf(dir,"%02dT%1c",sec+1,ssec+'A');
231  if(doSort) histfile->mkdir(dir);
232  histfile->cd(dir);
233  for( int eta=0; eta<MaxEta; eta++ ) {
234  sprintf(titl,"ADC(%02dT%1c%02d)",sec+1,ssec+'A',eta+1);
235  sprintf(name,"%02dT%1c%02d" ,sec+1,ssec+'A',eta+1);
236  int hidx=(sec*MaxSSec+ssec)*MaxEta+eta;
237  if(hidx<0 || MaxHist<=hidx) continue;
238  if(doSort) hadc[hidx] = new TH1F(name,titl,40,0.0,120.0);
239  else hadc[hidx] = (TH1F *)gDirectory->Get(name);
240 
241  }
242  }
243  }
244  // summed over eta
245  {
246  sprintf(dir,"eta");
247  if(doSort) histfile->mkdir(dir);
248  histfile->cd(dir);
249  for( int eta=0; eta<MaxEta; eta++ ) {
250  sprintf(titl,"ADC(ETA%02d)",eta+1);
251  sprintf(name,"ETA%02d" ,eta+1);
252  if(doSort) heta[eta] = new TH1F(name,titl,60,0.0,120.0);
253  else heta[eta] = (TH1F *)gDirectory->Get(name);
254  }
255  }
256 
257  if(doSort) { // sort data
258  int ie=0;
259  for(ie=0;ie<nentries;ie++) {
260  ntracks += numtracks;
261  chain->GetEntry(ie);
262  if(ie%100==0)fprintf(stdout ,"Entry %d/%d (%.2f%%)\r",ie,nentries,(ie*100.0)/nentries);
263  if(ctbsum>MaxCTB) continue;
264  if(trig>0) {
265  int it=0;
266  int *trigword=trigid;
267  while(it<numtrig && *trigword>0 && *trigword!=trig ) { it++; trigword++; };
268  if(*trigword!=trig) continue;
269  }
270 
271  for(int t=0;t<numtracks; t++) {
272  // select the tracks
273  if(ntrack[t] > 1 ) continue; // reject multiple tracks
274  if(pt[t] < MinPt ) continue;
275  if(fabs(detapres[t]) > MaxDEta ) continue;
276  if(fabs(dphipres[t]) > MaxDPhi ) continue;
277  if(fabs(detasmd[t]) > MaxDEta ) continue;
278  if(fabs(dphismd[t]) > MaxDPhi ) continue;
279  if(fabs(detapost[t]) > MaxDEta ) continue;
280  if(fabs(dphipost[t]) > MaxDPhi ) continue;
281 
282  int sec = sector[t];
283  int ssec = subsec[t];
284  int eta = etabin[t];
285  int hidx=(sec*MaxSSec+ssec)*MaxEta+eta;
286  if(hidx<0 || MaxHist<=hidx) continue;
287  if(hadc[hidx]!=NULL) hadc[hidx]->Fill(adcval[t]);
288  if(heta[eta ]!=NULL) heta[eta ]->Fill(adcval[t]);
289  }
290  }
291  fprintf(stdout ,"Entry %d/%d (%.2f%%)\n",ie,nentries,(ie*100.0)/nentries);
292  fprintf(stdout ,"Totals tracks %ld\n",ntracks);
293  histfile->Write();
294  } else { // plot
295  int nFitOK=0;
296  TCanvas *c1 = new TCanvas(outName,"MIP CALIB",800,0,1024,1024);
297  c1->Print(outName+".ps[");
298  bool go_on = true;
299  for(int sec=sec1;sec<=sec2 && go_on;sec++) {
300  char outfn[256];
301  sprintf(outfn,"sector%02d.cal",sec+1);
302  FILE *outfd = fopen(outfn,"w");
303  for(int ssec=0;ssec<MaxSSec && go_on;ssec++) {
304  sprintf(dir,"%02dT%1c",sec+1,ssec+'A');
305  c1->Clear();
306  nFitOK += miptower(hadc+(sec*MaxSSec+ssec)*MaxEta,MinEta,MaxEta,dir,fitFunc,xMin,xMax,outfd);
307  c1->Update();
308  c1->Print(outName+".ps");
309  //c1->Print(epsfn,"eps");
310 
311  // a lousy loop break for interactive session
312  if(!gROOT->IsBatch()) {
313  while(true) {
314  char cmd[256];
315  char c;
316  int k=0;
317  cmd[k]=0x00;
318  cout << "fit> ";
319  do {
320  c=getchar();
321  if(c==0x0A) { cmd[k++]=0x00; break; }
322  cmd[k++]=c;
323  } while(k<255);
324  if(cmd[0]==0x0A) { break;
325  } else if(strncasecmp(cmd,".cont" ,2)==0 ||
326  strncasecmp(cmd, "cont" ,1)==0) { break;
327  } else if(strncasecmp(cmd,".quit" ,2)==0 ||
328  strncasecmp(cmd, "quit" ,1)==0) { go_on=false; break;
329  } else if(strncasecmp(cmd,".help" ,2)==0 ||
330  strncasecmp(cmd, "help" ,1)==0) {
331  cerr << "commands (may be abbreviated):\n";
332  cerr << " .c cont - to continue with fitting\n" ;
333  cerr << " .q quit - to quit fitting loop \n" ;
334  cerr << " .h help - this help \n" << endl;
335  } else {
336  cerr << "unkown command:" << cmd << " type help for command list" << endl;
337  }
338  }
339  }
340  }
341  fclose(outfd);
342  }
343  cout << "TOTAL FIT OK " << nFitOK << endl;
344  c1->Clear();
345  (void) miptower(heta,MinEta,MaxEta,"ETA",fitFunc,xMin,xMax);
346  c1->Update();
347  c1->Print(outName+".ps");
348  c1->Print(outName+".ps]");
349  }
350 }
351 
352 
353 // ===========================================================================
354 // fit/plot/get calib for one tower (sec,ssec,eta=4..11)
355 // WARNING: here we count from 0
356 // ===========================================================================
357 int
358 miptower( TH1 **hadc,
359  const int MinEta,
360  const int MaxEta,
361  const char *dir,
362  const char *func ,
363  const float xMin ,
364  const float xMax ,
365  FILE *outfd)
366 {
367  const Double_t MinCounts = 30.0; // King's constants or the cuts
368  const Double_t MinPeakV = 8.0;
369  const Double_t MaxPeakV = 30.0;
370  const Double_t MaxPeakE = 6.0 ;
371  const Double_t MinChi2 = 0.0 ;
372  const Double_t MaxChi2 =10.0 ;
373  //
374  const int MaxPad = MaxEta-MinEta;
375 
376  int nFitOK=0;
377 
378  // root mumbo-jumbo
379  TString gltit("EEMC TOWERS ");
380  TString pz ("Piotr A. Zolnierczuk (IU) ");
381  TPaveLabel *tlab = new TPaveLabel(0.005,0.955,0.990,0.985,gltit+dir);
382  TDatime *now = new TDatime;
383  TPaveLabel *date = new TPaveLabel(0.555,0.005,0.995,0.045,pz+now->AsString());
384  TPad *gpad = new TPad("Graphs","Graphs",0.005,0.05,0.995,0.95);
385 
386  gStyle->SetOptStat(101111);
387  gStyle->SetOptFit(1);
388  tlab->Draw();
389  date->Draw();
390  gpad->Draw();
391  gpad->Divide(2,MaxPad/2);
392  gpad->cd(1);
393  gpad->Update();
394 
395  if(gROOT->IsBatch()) cout << "TOWERS " << dir << " " << flush;
396 
397  //TFile *f = gDirectory->GetFile();
398  //f->mkdir(dir);
399  //f->cd(dir);
400 
401 
402  for(int eta=0,pad=0; pad<MaxPad && eta<MaxEta; eta++) {
403  Double_t xint;
404  Double_t xmean , xmnerr;
405  Double_t xpeak , xpkerr;
406  Double_t xgain , xgnerr;
407  Double_t par[20];
408  Double_t chi2;
409  Int_t ndf;
410  char name[256];
411  sprintf(name,"%s%02d",dir,eta+1);
412 
413  if(hadc[eta]==NULL) continue;
414 
415  double xlim1, xlim2;
416  mystat(hadc[eta],xMin,xMax,xmean,xmnerr,xint,xpeak,xlim1,xlim2);
417 
418  // set initial parameter values
419  par[0] = hadc[eta]->GetMaximum();
420  par[1] = xpeak;
421  par[2] = xmnerr;
422  //
423 
424  TF1 *fit1 = new TF1("fit1" ,func ,0.0,120.0); //xmin+0.0,xmax);
425  fit1->SetParameters(par);
426  fit1->SetLineWidth(2);
427  fit1->SetLineColor(kRed);
428 
429  // FIXME hack
430  if(strncmp(func,"gaus",4)==0) {
431  //cerr << xpeak << " (" << xlim1 << "," << xlim2 << ")" << endl;
432  hadc[eta]->Fit("fit1","Q0","",xlim1,xlim2);
433  } else {
434  hadc[eta]->Fit("fit1","Q0","",xMin,xMax);
435  }
436 
437 
438 
439 
440  xpeak = fit1->GetParameter(1);
441  xpkerr = fit1->GetParError(1);
442  chi2 = fit1->GetChisquare();
443  ndf = fit1->GetNDF();
444  chi2 = (ndf>=1) ? chi2/ndf : -1.0;
445  xpkerr *= (chi2>0.0) ? sqrt(chi2) : 1.0 ;
446 
447  // calculate gain and gain error
448  Double_t xeta = 0.5*(etaBinTable[eta-1]+etaBinTable[eta]);
449  Double_t xscale = SamplingFraction/EnergyLossMip*TMath::TanH(xeta);
450  xgain = xpeak * xscale;
451  xgnerr = xpkerr * xscale;
452 
453  // print all the stuff
454  fprintf(outfd,"%6s %8.3f %8.3f 0.0 # %8.3f %6.0f",
455  name,xgain,xgnerr,chi2,xint);
456 
457  // now get the error message
458  char *errmsg = NULL;
459  if (xint<MinCounts ) errmsg = "not enough statistics";
460  else if(xpeak<MinPeakV || MaxPeakV<xpeak ) errmsg = "bad fit value";
461  else if( MaxPeakE < xpkerr ) errmsg = "fit error too large";
462  else if(chi2<MinChi2 || MaxChi2<chi2 ) errmsg = "chi2 too large";
463 
464  if(errmsg==NULL) fprintf(outfd," fit %s ok \n",func);
465  else fprintf(outfd," *** %s ***\n",errmsg);
466  if(eta<MinEta) continue;
467 
468  // plot
469  gpad->cd(++pad);
470  Double_t hmax = hadc[eta]->GetMaximum();
471  hadc[eta]->SetMaximum( (hmax>10.0) ? 1.2*hmax : 12.0 );
472  hadc[eta]->GetXaxis()->SetTitle("ADC");
473  hadc[eta]->Draw("E");
474  fit1->Draw("SAME");
475 
476  if(errmsg!=NULL) {
477  hmax = hadc[eta]->GetMaximum();
478  TPaveLabel* badfitlabel = new TPaveLabel(70,0.25*hmax,118,0.40*hmax,errmsg);
479  badfitlabel->SetFillColor(kRed );
480  badfitlabel->SetTextColor(kYellow );
481  badfitlabel->Draw();
482  } else {
483  nFitOK++;
484  }
485  gpad->Update();
486  }
487  fprintf(outfd,"\n");
488  if(gROOT->IsBatch()) cout << " (" << nFitOK << ") DONE " << endl;
489  return nFitOK;
490 }
491 
492 
493 
494 // ===========================================================================
495 // get some statistics for a H1F
496 // returns mean, its error and the integral between x1 and x2
497 // ===========================================================================
498 void
499 mystat(TH1 *h,
500  Double_t x1 , Double_t x2,
501  Double_t& xmean, Double_t& emean, Double_t& dint,
502  Double_t& xmax , Double_t& xlo , Double_t& xhi)
503 {
504  TAxis* xax = h->GetXaxis();
505  Int_t i1 = xax->FindBin(x1);
506  Int_t i2 = xax->FindBin(x2);
507 
508  Float_t sw=0.0,sw2=0.0,swx=0.0,swx2=0.0,wmax=0.0;
509  Int_t n=0;
510  Int_t imax=0;
511  xmean=emean=xmax=0.0;
512  for(Int_t i=i1;i<=i2;i++) {
513  Double_t x = h->GetBinCenter(i);
514  Double_t w = h->GetBinContent(i);
515  if(w>wmax) { xmax=x; wmax=w; imax=i; }
516  sw += w;
517  sw2 += w*w;
518  swx += w*x;
519  swx2+= w*x*x;
520  n++;
521  }
522 
523  xlo = h->GetBinCenter(i1);
524  xhi = h->GetBinCenter(i2);
525 
526  //cerr << "MAX " << imax << " (" << i1 << "," << i2 << ") " << wmax << endl;
527  //cerr << "LO" << endl;
528  wmax *= 0.4;
529  for(Int_t i=imax;i>=i1;i--) {
530  Double_t w = h->GetBinContent(i);
531  //cerr << i << "," << w << endl;
532  if(w<wmax) {
533  xlo = h->GetBinCenter(i);
534  break;
535  }
536  }
537  //cerr << "HI" << endl;
538  for(Int_t i=imax;i<=i2;i++) {
539  Double_t w = h->GetBinContent(i);
540  //cerr << i << "," << w << endl;
541  if(w<wmax) {
542  xhi = h->GetBinCenter(i);
543  break;
544  }
545  }
546 
547  dint = sw;
548  xmean = (sw>0.0) ? swx/sw : 0.0 ;
549  emean = (sw>0.0) ? (swx2/sw - xmean*xmean ) : 0.0 ;
550  emean = (emean>0.0) ? sqrt(emean/n) : 0.0;
551 }
552 
553 
554 #ifndef __CINT__
555 int sector = 0;
556 char *outname = "mipcalib.hist.root";
557 char *fitfunc = "landau";
558 
559 int trig = 0;
560 float xmin = 9.0;
561 float xmax = 100.0;
562 
563 void
564 usage(char *name)
565 {
566  cerr << "usage: " << name << " [options] rootfile(s) \n";
567  cerr << " -s <sector> - (0 == all) \n";
568  cerr << " -t <trigger_id> - (0 == any) \n";
569  cerr << " -o <histogram file> - .hist.root file \n";
570  cerr << " -L - fit Landau/Gauss distributions\n";
571  cerr << " -G - fit Landau/Gauss distributions\n";
572  cerr << " -x <xmin> - fit lower bound\n";
573  cerr << " -X <xmax> - fit upper bound\n";
574  cerr << " -b - run in batch mode without graphics \n";
575  cerr << " -h - this help\n";
576  cerr << endl;
577 }
578 
579 
580 int
581 main(int argc, char **argv)
582 {
583  extern char *optarg;
584  extern int optind;
585  char optchar;
586  cerr << "#===============================================\n";
587  cerr << "# ******* WARNING ******* \n";
588  cerr << "# A LOUSY PROGRAM THAT GREW OUT OF A ROOT MACRO \n";
589  cerr << "# needs to be rewritten \n";
590  cerr << "#===============================================\n" << endl;
591 
592 
593  while((optchar = getopt(argc, argv, "s:t:o:LGx:X:c:bqnlh")) != EOF) {
594  switch(optchar) {
595  case 's': sector = atoi(optarg); break;
596  case 'o': outname = optarg ; break;
597  case 't': trig = atoi(optarg); break;
598  case 'L': fitfunc = "landau"; break;
599  case 'G': fitfunc = "gaus" ; break;
600  case 'x': xmin = atof(optarg); break;
601  case 'X': xmax = atof(optarg); break;
602  case 'c': MaxCTB = atof(optarg); break;
603  case 'b': gROOT->SetBatch(kTRUE); // fall down
604  case 'q': // pass
605  case 'n': // pass
606  case 'l': break; // targv[targc++]=optarg; break;
607  case 'h': usage(argv[0]); exit(0); break;
608  case '?':
609  default: usage(argv[0]); exit(-1);break;
610  }
611  }
612 
613 
614  // attach root files from the in the list
615  for(int k=optind;k<argc; k++) new TFile(argv[k],"");
616  argc=optind;
617 
618 
619  TApplication *myApp;
620  if(gROOT->IsBatch())
621  myApp = new TApplication("mipcalib",&argc,argv);
622  else
623  myApp = new TRint ("mipcalib",&argc,argv);
624 
625  mipcalib(sector,"",outname,fitfunc,xmin,xmax,trig,true ); // sort
626  mipcalib(sector,"",outname,fitfunc,xmin,xmax,trig,false); // fit and plot
627 
628  if(!gROOT->IsBatch() ) myApp->Run(); // "Exit ROOT" will quit the application
629 
630  return 0;
631 }
632 #endif