ROOT logo
/*

This macro creates a gain map for the TPC based on the results of the Krypton calibration.
The main steps are the following:

1. Define outlier-pads where the krypton calibration was not succesful
2. A parabolic fit for the whole chamber is performed
3. replace outliers with fitted values
4. normalize separately IROCs and OROCs

For more details see below.



example usage:
==============

TFile f("calibKr.root")
AliTPCCalPad * kryptonRaw = new AliTPCCalPad(*fitMean)
AliTPCCalPad * kryptonMean = new AliTPCCalPad(*spectrMean)
AliTPCCalPad * kryptonChi2 = new AliTPCCalPad(*fitNormChi2)
AliTPCCalPad * kryptonRMS = new AliTPCCalPad(*fitRMS)

.L CreateGainMap.C
AliTPCCalPad * final = CreateGainMap(kryptonRaw, kryptonRMS)

TFile *h = new TFile("GainMap.root", "RECREATE")
final.Write()

*/


AliTPCCalPad * CreateGainMap(AliTPCCalPad *krypFitMean, AliTPCCalPad *krypFitRMS, AliTPCCalPad *noiseMap = 0, AliTPCCalPad *krypSpectrMean = 0, 
			     AliTPCCalPad *krypChi2 = 0, AliTPCCalPad *pulser = 0, AliTPCCalPad *electrode = 0) {

  
  // Draw input map
  TCanvas *test3 = new TCanvas("ASIDE3", "Aoriginal");
  krypFitMean->MakeHisto2D()->Draw("colz");
  TCanvas *test4 = new TCanvas("CSIDE4", "Coriginal");
  krypFitMean->MakeHisto2D(1)->Draw("colz");
  TH1F * hDEBUG = new TH1F("bla", "fitRMS/fitMean",100,0,0.3);

  const Double_t kryptonMean = 0.05012;
  const Double_t kryptonSigma = 0.00386;

  TObjArray arrayRocFinal(72);

  //
  // Loop over all sectors
  //
  for(Int_t isector=0; isector < 72; isector++){

    AliTPCCalROC *rocKrypFitMean = krypFitMean->GetCalROC(isector);
    AliTPCCalROC *rocKrypFitRMS  = krypFitRMS->GetCalROC(isector);

    AliTPCCalROC *rocOutlier = new AliTPCCalROC(*rocKrypFitMean);

    // 1. define map of outliers: the 41keV peak is fitted and krypFitMean represents the peak position and krypFitRMS its sigma.
    //    In order to control the fit qualtiy krypFitRMS/krypFitMean is computed and plotted; it is roughly gaussian distributed
    //    with the mean resolution kryptonMean = 0.05012 and sigma kryptonSigma = 0.00386. If the deviation is larger than 4sigma
    //    the fit to the 41keV peak is considered as failed.

    Int_t nPointsFit = 0;
    for(Int_t iChannel=0; iChannel < rocOutlier->GetNchannels(); iChannel++){
      Double_t fitMean = rocKrypFitMean->GetValue(iChannel);
      Double_t fitRMS = rocKrypFitRMS->GetValue(iChannel);
      if (fitRMS < 0.001 || fitMean < 0.001) continue;
       hDEBUG->Fill(fitRMS/fitMean);
      if (TMath::Abs(fitRMS/fitMean - kryptonMean) < 4*kryptonSigma || fitRMS < 0.001 || fitMean < 0.001) {
	rocOutlier->SetValue(iChannel,0);
	nPointsFit++;
      }
    }
    //TCanvas *DEBUG = new TCanvas();
    //rocOutlier->MakeHisto2D()->Draw("colz");
    
    Double_t rocMedian = rocKrypFitMean->GetMedian(rocOutlier);
    

    // 2. make a parabolic fit for the whole chamber with excluded outliers
    
    TVectorD params;
    TMatrixD cov;
    Float_t chi2;
    rocKrypFitMean->GlobalFit(rocOutlier,0,params,cov,chi2);
    AliTPCCalROC *rocParabolicFit=AliTPCCalROC::CreateGlobalFitCalROC(params,isector);

    if (nPointsFit != 0) cout << "sector: "<< isector << " chi2: " << chi2/nPointsFit <<" median: "<< rocMedian <<" n: " << nPointsFit << endl;
    if (nPointsFit == 0) {
      AliTPCCalROC *rocFinal = new AliTPCCalROC(*rocParabolicFit); // What to do with sectors being switched off??
      arrayRocFinal.AddAt(rocFinal,isector);
      continue;
    }

    //
    // VERY IMPORTANT **** VERY IMPORTANT  **** VERY IMPORTANT  **** VERY IMPORTANT  **** VERY IMPORTANT  **** VERY IMPORTANT 
    //
    // if the fit is considered as failed, the mean value is taken for the whole chamber (TO AVOID THIS, RELEASE THIS CUT)
    // if cosmic data can be used for gain calibration, this cut should be strong (e.g. 5) !!!!!!!!!!

    if (chi2/nPointsFit > 5) {
      AliTPCCalROC *rocFinal = new AliTPCCalROC(*rocParabolicFit);
      if (rocMedian == 0 && isector == 51) rocMedian = 1075; // manual patch to be removed for sector 51!
      for(Int_t iChannel=0; iChannel < rocFinal->GetNchannels(); iChannel++) rocFinal->SetValue(iChannel,rocMedian);
      arrayRocFinal.AddAt(rocFinal,isector);
      continue;
    }

    // 3. replace outliers with fitted values

    AliTPCCalROC *rocFinal = new AliTPCCalROC(*rocParabolicFit);
    for(Int_t iChannel=0; iChannel < rocFinal->GetNchannels(); iChannel++){
      Double_t fitMean = rocKrypFitMean->GetValue(iChannel);
      Double_t fitRMS = rocKrypFitRMS->GetValue(iChannel);   
      if (fitRMS < 0.001 || fitMean < 0.001 || TMath::Abs(rocParabolicFit->GetValue(iChannel)/fitMean - 1) > 0.35) {
	rocFinal->SetValue(iChannel,rocParabolicFit->GetValue(iChannel));
	continue;
      }
      if (TMath::Abs(fitRMS/fitMean - kryptonMean) < 4*kryptonSigma) {
	rocFinal->SetValue(iChannel,rocKrypFitMean->GetValue(iChannel));
      }
    }
    

    // 4. Postprocessing: Set dead channels and very noisy channels (time dependent) to 0
    
    const Double_t noiseMin = 0.01;
    const Double_t noiseMax = 2;

    if (noiseMap) {
      AliTPCCalROC *rocNoise = noiseMap->GetCalROC(isector);
      for(Int_t iChannel=0; iChannel < rocFinal->GetNchannels(); iChannel++){
	Double_t noise = rocNoise->GetValue(iChannel);
	if (noise < noiseMin || noise > noiseMax) rocFinal->SetValue(iChannel, 0);
      }
    }
    // Fill an array of ROCs

    arrayRocFinal.AddAt(rocFinal,isector);

  }

  AliTPCCalPad *final = new AliTPCCalPad(&arrayRocFinal);
  
  // 4. normalize separately IROCs and OROCs to the mean of their medians

  Double_t meanMedianIROC;
  Double_t meanMedianOROC;
  Int_t n = 0;

  for(Int_t isector=0; isector < 36; isector++){ // IROCs
    AliTPCCalROC *rocFinal = final->GetCalROC(isector);
    if (rocFinal->GetMedian() != 0) {
      meanMedianIROC += rocFinal->GetMedian();
      n++;
    }
  }
  meanMedianIROC = meanMedianIROC/n;

  n = 0;
  for(Int_t isector=36; isector < 72; isector++){ // OROCs
    AliTPCCalROC *rocFinal = final->GetCalROC(isector);
    if (rocFinal->GetMedian() != 0) {
      meanMedianOROC += rocFinal->GetMedian();
      n++;
    }
  }
  meanMedianOROC = meanMedianOROC/n;

  for(Int_t isector=0; isector < 72; isector++){ // OROCs
    AliTPCCalROC *rocFinal = final->GetCalROC(isector);
    if (isector<36) rocFinal->Multiply(1./meanMedianIROC);
    if (isector>35) rocFinal->Multiply(1./meanMedianOROC);
  }

  // Draw results
  TCanvas *test = new TCanvas("ASIDE", "A");
  final->MakeHisto2D()->Draw("colz");
  TCanvas *test2 = new TCanvas("CSIDE", "C");
  final->MakeHisto2D(1)->Draw("colz");
  TCanvas *cDEBUG = new TCanvas();
  hDEBUG->Draw();

  //return results
  final->SetName("GainMap");
  return final;

}



void MakeCalibTree(char * inputKr="calibKr.root", char * inputCE ="fitCE.root", char * inputPulser=0){
  //
  //
  //
   AliTPCPreprocessorOnline * preprocesor = new AliTPCPreprocessorOnline;
   TFile f(inputKr);
   TFile fce(inputCE);
   AliTPCCalPad * kryptonMean     = (AliTPCCalPad*)f.Get("spectrMean");
   AliTPCCalPad * kryptonRMS      = (AliTPCCalPad*)f.Get("spectrRMS");
   AliTPCCalPad * kryptonMeanG    = (AliTPCCalPad*)f.Get("fitMean");
   AliTPCCalPad * kryptonRMSG     = (AliTPCCalPad*)f.Get("fitRMS");
   AliTPCCalPad * kryptonNormChi2 = (AliTPCCalPad*)f.Get("fitNormChi2");
   AliTPCCalPad * kryptonEntries  = (AliTPCCalPad*)f.Get("entries");
   AliTPCCalPad * ceqIn           = (AliTPCCalPad*)fce.Get("qIn");
   AliTPCCalPad * ceqF1             = (AliTPCCalPad*)fce.Get("qF1");
   AliTPCCalPad * ceqF2             = (AliTPCCalPad*)fce.Get("qF2");



   preprocesor->AddComponent(kryptonMean->Clone());
   preprocesor->AddComponent(kryptonRMS->Clone());
   preprocesor->AddComponent(kryptonMeanG->Clone());
   preprocesor->AddComponent(kryptonRMSG->Clone());
   preprocesor->AddComponent(kryptonNormChi2->Clone());
   preprocesor->AddComponent(kryptonEntries->Clone());
   //
   preprocesor->AddComponent(ceqIn->Clone());
   preprocesor->AddComponent(ceqF1->Clone());
   preprocesor->AddComponent(ceqF2->Clone());

   preprocesor->DumpToFile("gainTree.root");
   //
}

AliTPCCalibViewerGUI*viewer =0;
TTree * tree =0;

void LoadViewer(){
  //
  // Load calib Viewer
  //
  TObjArray * array = AliTPCCalibViewerGUI::ShowGUI("gainTree.root");
  AliTPCCalibViewerGUI* viewer = (AliTPCCalibViewerGUI*)array->At(0);
  makePad = viewer->GetViewer();
  tree = viewer->GetViewer()->GetTree();

  tree->SetAlias("krAccept0","abs(fitRMS.fElements/fitMean.fElements-0.06)<0.04");
  tree->SetAlias("krAccept1","abs(fitRMS.fElements)>30");
  tree->SetAlias("yedge","tan(10*pi/180.)*lx.fElements");
  tree->SetAlias("ceAccept1","abs(qIn.fElements/qIn_Median.fElements-1.5)<1.4&&qIn.fElements>3&&qIn_Median.fElements>3");

}

void Fit(){
  TF1 f1("f1","[0]*exp(-[1]*x)+[2]");
  f1.SetParameters(1,1,0.2);
  tree->Draw("1-qIn.fElements/qF1.fElements:yedge-abs(ly.fElements)>>his(50,1.5,5,100,-0.5,1.5)","ceAccept1&&sector>36"); 
  his->FitSlicesY();
  his_1->Fit(&f1);


}
 CreateGainMap.C:1
 CreateGainMap.C:2
 CreateGainMap.C:3
 CreateGainMap.C:4
 CreateGainMap.C:5
 CreateGainMap.C:6
 CreateGainMap.C:7
 CreateGainMap.C:8
 CreateGainMap.C:9
 CreateGainMap.C:10
 CreateGainMap.C:11
 CreateGainMap.C:12
 CreateGainMap.C:13
 CreateGainMap.C:14
 CreateGainMap.C:15
 CreateGainMap.C:16
 CreateGainMap.C:17
 CreateGainMap.C:18
 CreateGainMap.C:19
 CreateGainMap.C:20
 CreateGainMap.C:21
 CreateGainMap.C:22
 CreateGainMap.C:23
 CreateGainMap.C:24
 CreateGainMap.C:25
 CreateGainMap.C:26
 CreateGainMap.C:27
 CreateGainMap.C:28
 CreateGainMap.C:29
 CreateGainMap.C:30
 CreateGainMap.C:31
 CreateGainMap.C:32
 CreateGainMap.C:33
 CreateGainMap.C:34
 CreateGainMap.C:35
 CreateGainMap.C:36
 CreateGainMap.C:37
 CreateGainMap.C:38
 CreateGainMap.C:39
 CreateGainMap.C:40
 CreateGainMap.C:41
 CreateGainMap.C:42
 CreateGainMap.C:43
 CreateGainMap.C:44
 CreateGainMap.C:45
 CreateGainMap.C:46
 CreateGainMap.C:47
 CreateGainMap.C:48
 CreateGainMap.C:49
 CreateGainMap.C:50
 CreateGainMap.C:51
 CreateGainMap.C:52
 CreateGainMap.C:53
 CreateGainMap.C:54
 CreateGainMap.C:55
 CreateGainMap.C:56
 CreateGainMap.C:57
 CreateGainMap.C:58
 CreateGainMap.C:59
 CreateGainMap.C:60
 CreateGainMap.C:61
 CreateGainMap.C:62
 CreateGainMap.C:63
 CreateGainMap.C:64
 CreateGainMap.C:65
 CreateGainMap.C:66
 CreateGainMap.C:67
 CreateGainMap.C:68
 CreateGainMap.C:69
 CreateGainMap.C:70
 CreateGainMap.C:71
 CreateGainMap.C:72
 CreateGainMap.C:73
 CreateGainMap.C:74
 CreateGainMap.C:75
 CreateGainMap.C:76
 CreateGainMap.C:77
 CreateGainMap.C:78
 CreateGainMap.C:79
 CreateGainMap.C:80
 CreateGainMap.C:81
 CreateGainMap.C:82
 CreateGainMap.C:83
 CreateGainMap.C:84
 CreateGainMap.C:85
 CreateGainMap.C:86
 CreateGainMap.C:87
 CreateGainMap.C:88
 CreateGainMap.C:89
 CreateGainMap.C:90
 CreateGainMap.C:91
 CreateGainMap.C:92
 CreateGainMap.C:93
 CreateGainMap.C:94
 CreateGainMap.C:95
 CreateGainMap.C:96
 CreateGainMap.C:97
 CreateGainMap.C:98
 CreateGainMap.C:99
 CreateGainMap.C:100
 CreateGainMap.C:101
 CreateGainMap.C:102
 CreateGainMap.C:103
 CreateGainMap.C:104
 CreateGainMap.C:105
 CreateGainMap.C:106
 CreateGainMap.C:107
 CreateGainMap.C:108
 CreateGainMap.C:109
 CreateGainMap.C:110
 CreateGainMap.C:111
 CreateGainMap.C:112
 CreateGainMap.C:113
 CreateGainMap.C:114
 CreateGainMap.C:115
 CreateGainMap.C:116
 CreateGainMap.C:117
 CreateGainMap.C:118
 CreateGainMap.C:119
 CreateGainMap.C:120
 CreateGainMap.C:121
 CreateGainMap.C:122
 CreateGainMap.C:123
 CreateGainMap.C:124
 CreateGainMap.C:125
 CreateGainMap.C:126
 CreateGainMap.C:127
 CreateGainMap.C:128
 CreateGainMap.C:129
 CreateGainMap.C:130
 CreateGainMap.C:131
 CreateGainMap.C:132
 CreateGainMap.C:133
 CreateGainMap.C:134
 CreateGainMap.C:135
 CreateGainMap.C:136
 CreateGainMap.C:137
 CreateGainMap.C:138
 CreateGainMap.C:139
 CreateGainMap.C:140
 CreateGainMap.C:141
 CreateGainMap.C:142
 CreateGainMap.C:143
 CreateGainMap.C:144
 CreateGainMap.C:145
 CreateGainMap.C:146
 CreateGainMap.C:147
 CreateGainMap.C:148
 CreateGainMap.C:149
 CreateGainMap.C:150
 CreateGainMap.C:151
 CreateGainMap.C:152
 CreateGainMap.C:153
 CreateGainMap.C:154
 CreateGainMap.C:155
 CreateGainMap.C:156
 CreateGainMap.C:157
 CreateGainMap.C:158
 CreateGainMap.C:159
 CreateGainMap.C:160
 CreateGainMap.C:161
 CreateGainMap.C:162
 CreateGainMap.C:163
 CreateGainMap.C:164
 CreateGainMap.C:165
 CreateGainMap.C:166
 CreateGainMap.C:167
 CreateGainMap.C:168
 CreateGainMap.C:169
 CreateGainMap.C:170
 CreateGainMap.C:171
 CreateGainMap.C:172
 CreateGainMap.C:173
 CreateGainMap.C:174
 CreateGainMap.C:175
 CreateGainMap.C:176
 CreateGainMap.C:177
 CreateGainMap.C:178
 CreateGainMap.C:179
 CreateGainMap.C:180
 CreateGainMap.C:181
 CreateGainMap.C:182
 CreateGainMap.C:183
 CreateGainMap.C:184
 CreateGainMap.C:185
 CreateGainMap.C:186
 CreateGainMap.C:187
 CreateGainMap.C:188
 CreateGainMap.C:189
 CreateGainMap.C:190
 CreateGainMap.C:191
 CreateGainMap.C:192
 CreateGainMap.C:193
 CreateGainMap.C:194
 CreateGainMap.C:195
 CreateGainMap.C:196
 CreateGainMap.C:197
 CreateGainMap.C:198
 CreateGainMap.C:199
 CreateGainMap.C:200
 CreateGainMap.C:201
 CreateGainMap.C:202
 CreateGainMap.C:203
 CreateGainMap.C:204
 CreateGainMap.C:205
 CreateGainMap.C:206
 CreateGainMap.C:207
 CreateGainMap.C:208
 CreateGainMap.C:209
 CreateGainMap.C:210
 CreateGainMap.C:211
 CreateGainMap.C:212
 CreateGainMap.C:213
 CreateGainMap.C:214
 CreateGainMap.C:215
 CreateGainMap.C:216
 CreateGainMap.C:217
 CreateGainMap.C:218
 CreateGainMap.C:219
 CreateGainMap.C:220
 CreateGainMap.C:221
 CreateGainMap.C:222
 CreateGainMap.C:223
 CreateGainMap.C:224
 CreateGainMap.C:225
 CreateGainMap.C:226
 CreateGainMap.C:227
 CreateGainMap.C:228
 CreateGainMap.C:229
 CreateGainMap.C:230
 CreateGainMap.C:231
 CreateGainMap.C:232
 CreateGainMap.C:233
 CreateGainMap.C:234
 CreateGainMap.C:235
 CreateGainMap.C:236
 CreateGainMap.C:237
 CreateGainMap.C:238
 CreateGainMap.C:239
 CreateGainMap.C:240
 CreateGainMap.C:241
 CreateGainMap.C:242
 CreateGainMap.C:243
 CreateGainMap.C:244
 CreateGainMap.C:245
 CreateGainMap.C:246
 CreateGainMap.C:247
 CreateGainMap.C:248
 CreateGainMap.C:249
 CreateGainMap.C:250
 CreateGainMap.C:251
 CreateGainMap.C:252
 CreateGainMap.C:253
 CreateGainMap.C:254
 CreateGainMap.C:255