#include <TH1.h>
#include <TF1.h>
#include <TH1I.h>
+#include <TH2F.h>
#include <TIterator.h>
#include <TKey.h>
#include <TFile.h>
#include <TLine.h>
+#include <TText.h>
#include <TPaveText.h>
#include <TMath.h>
#include "AliQAv1.h"
#include "AliQAChecker.h"
#include "AliEMCALQAChecker.h"
-#include "AliEMCALQADataMakerRec.h"
ClassImp(AliEMCALQAChecker)
//__________________________________________________________________
AliEMCALQAChecker::AliEMCALQAChecker() :
AliQACheckerBase("EMCAL","EMCAL Quality Assurance Data Maker"),
-fLine(new TLine*[fknSM]),
-fHref(new TLine*[fknSM]),
-fText(NULL)
+fTextSM(new TText*[fknSM]),
+fLineCol(new TLine(48.0,0.,48.0,47.0)),
+fLineRow(new TLine(0.,24.,96.,24.)),
+fText(new TPaveText(0.2,0.7,0.8,0.9,"NDC"))
{
- /// ctor
- for (Int_t sm = 0 ; sm < fknSM ; sm++){
- fLine[sm] = NULL ;
- fHref[sm] = NULL ;
- }
+ // ctor
+ fLineCol->SetLineColor(1);
+ fLineCol->SetLineWidth(2);
+ fLineRow->SetLineColor(1);
+ fLineRow->SetLineWidth(2);
+
+ fTextSM[0]= new TText(20, 12, "SM A0");
+ fTextSM[1]= new TText(20, 38, "SM A1");
+ fTextSM[2]= new TText(64, 12, "SM C0");
+ fTextSM[3]= new TText(64, 38, "SM C1");
}
//__________________________________________________________________
AliEMCALQAChecker::~AliEMCALQAChecker()
{
/// dtor
- delete [] fLine ;
- delete [] fHref ;
- if (fText)
- delete fText ;
+ delete [] fTextSM ;
+ delete fLineCol ;
+ delete fLineRow ;
+ delete fText ;
}
//__________________________________________________________________
AliEMCALQAChecker::AliEMCALQAChecker(const AliEMCALQAChecker& qac) :
AliQACheckerBase(qac.GetName(), qac.GetTitle()),
-fLine(new TLine*[fknSM]),
-fHref(new TLine*[fknSM]),
-fText(qac.fText)
+fTextSM(new TText*[fknSM]) ,
+fLineCol(static_cast<TLine*>(qac.fLineCol->Clone())) ,
+fLineRow(static_cast<TLine*>(qac.fLineRow->Clone())) ,
+fText(new TPaveText(0.2,0.7,0.8,0.9,"NDC"))
{
- /// copy ctor
+ // copy ctor
for (Int_t sm = 0 ; sm < fknSM ; sm++){
- fLine[sm] = qac.fLine[sm] ;
- fHref[sm] = qac.fHref[sm] ;
+ fTextSM[sm] = static_cast<TText *>(qac.fTextSM[sm]->Clone()) ;
}
+
}
//__________________________________________________________________
-AliEMCALQAChecker& AliEMCALQAChecker::operator = (const AliEMCALQAChecker &qac)
+AliEMCALQAChecker& AliEMCALQAChecker::operator = (const AliEMCALQAChecker &qac)
{
- fText = qac.fText;
-
+ fTextSM = new TText*[fknSM] ;
+ fLineCol = static_cast<TLine*>(qac.fLineCol->Clone()) ;
+ fLineRow = static_cast<TLine*>(qac.fLineRow->Clone()) ;
+ fText = new TPaveText(0.2,0.7,0.8,0.9,"NDC") ;
for (Int_t sm = 0 ; sm < fknSM ; sm++){
- fLine[sm] = qac.fLine[sm] ;
- fHref[sm] = qac.fHref[sm] ;
+ fTextSM[sm] = static_cast<TText *>(qac.fTextSM[sm]->Clone()) ;
}
return *this ;
}
//______________________________________________________________________________
-Double_t *
-AliEMCALQAChecker::Check(AliQAv1::ALITASK_t index, TObjArray ** list, AliDetectorRecoParam * /*recoParam*/)
+void AliEMCALQAChecker::Check(Double_t * test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
{
/// Check objects in list
if ( index == AliQAv1::kRAW )
{
- return CheckRaws(list);
+ CheckRaws(test, list);
printf ("checkers for task %d \n", index) ;
}
if ( index == AliQAv1::kREC)
{
- return CheckRecPoints(list);
+ CheckRecPoints(test, list);
}
if ( index == AliQAv1::kESD )
{
- return CheckESD(list);
+ CheckESD(test, list);
}
AliWarning(Form("Checker for task %d not implement for the moment",index));
- return NULL;
}
//______________________________________________________________________________
//______________________________________________________________________________
-Double_t *
-AliEMCALQAChecker::CheckRaws(TObjArray ** list)
+void AliEMCALQAChecker::CheckRaws(Double_t * test, TObjArray ** list)
{
-// Check RAW QA histograms
-// We count the times of the response for each tower, the propability for all towers should be the same (average is given value).
-// We skip the first few cycles since the statistics is not enough, the average should be always larger than 1 at least.
-// By calculating the difference between the counts for each tower and the average, we decide whether we should recalculate
-// the average depending the the gaus fitting on the divation distribution.
-// During the recalutation of the average, we count how many towers are used for the calculation.
-// From the fraction of towers used, we decide whether each SM works fine or not
-// From the divation of average, we set the QA flag for the full detetcor as INFO, WARNING, ERROR or FATAL.
-
-// -- Yaxian Mao, CCNU/CERN/LPSC
-
- Float_t kThreshold = 80. ;
+ // Check RAW QA histograms
+ // -- Yaxian Mao, CCNU/CERN/LPSC
+ //adding new checking method: 25/04/2010, Yaxian Mao
+ //Comparing the amplitude from current run to the reference run, if the ratio in the range [0.8, .12], count as a good tower.
+ //If more than 90% towers are good, EMCAL works fine, otherwise experts should be contacted.
- Double_t * test = new Double_t[AliRecoParam::kNSpecies] ;
+
+ //Float_t kThreshold = 80. ;
+ Int_t nTowersPerSM = 24*48; // number of towers in a SuperModule; 24x48
+ Double_t nTot = fknSM * nTowersPerSM ;
for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
- test[specie] = 1.0 ;
+ test[specie] = 0.0 ;
if ( !AliQAv1::Instance()->IsEventSpecieSet(specie))
continue ;
if (list[specie]->GetEntries() == 0)
test[specie] = 0. ; // nothing to check
else {
- TH1 * hdata = (TH1*)list[specie]->At(kTowerHG) ;
- if(hdata->GetEntries()==0)
- continue;
- Int_t nbin = hdata->GetNbinsX() ;
- Int_t nTower = nbin/4 ; // ! number of channels for each SM
- if(fText) {
- fText->DeleteText() ;
- fText->Clear() ;
+ TH2F * hdata = (TH2F*)list[specie]->At(k2DRatioAmp) ;
+ TH1F * ratio = (TH1F*)list[specie]->At(kRatioDist) ;
+ if(hdata->GetEntries()==0 || ratio->GetEntries()==0)
+ continue;
+ //adding the lines to distinguish different SMs
+ if ( hdata->GetListOfFunctions()->GetEntries() == 0 ){
+ hdata->GetListOfFunctions()->Add(fLineCol);
+ hdata->GetListOfFunctions()->Add(fLineRow);
+ //Now adding the text to for each SM
+ for(Int_t iSM = 0 ; iSM < fknSM ; iSM++){ //number of SMs loop start
+ hdata->GetListOfFunctions()->Add(fTextSM[iSM]);
+ }
+ }
+ if ( ratio->GetListOfFunctions()->GetEntries() == 0 ){ //adding the object at the beginning
+ ratio->GetListOfFunctions()->Add(fText) ;
}
- else {
- fText = new TPaveText(0.3,0.6,0.7,0.9,"NDC") ;
+
+ //now check the ratio histogram
+ Double_t binContent = 0. ;
+ Int_t NGoodTower = 0 ;
+ Double_t rv = 0. ;
+ for(Int_t ix = 1; ix <= hdata->GetNbinsX(); ix++) {
+ for(Int_t iy = 1; iy <= hdata->GetNbinsY(); iy++) {
+ binContent = hdata->GetBinContent(ix, iy) ;
+ if (binContent < 1.2 && binContent > 0.8)
+ NGoodTower++ ;
+ }
}
- fText->AddText(Form("OK if more than %2.2f %% inside aver-sigma < HG counts < aver+sigma", kThreshold));
- //TPaveText * fText[fknSM] = {0};
- Double_t rv = 0. ; //value to define the flag for the full detector
- for(Int_t iSM = 0 ; iSM < fknSM ; iSM++){ //number of SMs loop start
- TString projname = Form("proj_%d",iSM);
- Double_t aver = 0. ; //average calculated by the input histogram
- Double_t recal = 0 ; // recalculate the average if the divation is large
- Double_t init = 0. ; // value to decide whether we should recalculate the average
- Double_t mean = 0. ; //the divation from the average, from the gaus fitting peak
- Double_t width = 0. ; // the sigma of the devation, from the gaus fitting
- Int_t flag = 0 ; //counts for channels used for recalculation of average
- Double_t ratio = 0. ; //value to decide whether each SM works
- TH1F * proj = NULL ; //a temp histogram store the difference from the average for the fitting procedure
-
- for(Int_t iTower = iSM*nTower ; iTower<(iSM+1)*nTower ; iTower++) //channel loop to calculate the average
- aver += hdata->GetBinContent(iTower);
+ rv = NGoodTower/nTot ;
+ printf("%2.2f %% towers out of range [0.8, 1.2]\n", (1-rv)*100);
+ if(fText){
+ fText->Clear() ;
- aver /=nTower;
- AliInfo(Form("SM: %d has average = %f\n",iSM, aver));
- Double_t ymin = hdata->GetBinContent(hdata->GetMinimumBin());
- Double_t ymax = hdata->GetBinContent(hdata->GetMaximumBin());
- proj = new TH1F(projname,projname,nbin,-aver,aver);
- fLine[iSM] = dynamic_cast<TLine*>(hdata->GetListOfFunctions()->FindObject(fLine[iSM]));
- //initialize the lines separate different SM
- if (!fLine[iSM]) {
- fLine[iSM] = new TLine((iSM+1)*nTower,ymin,(iSM+1)*nTower,ymax);
- fLine[iSM]->SetLineColor(1);
- fLine[iSM]->SetLineWidth(2);
- hdata->GetListOfFunctions()->Add(fLine[iSM]);
- list[specie]->AddAt(hdata, kTowerHG) ;
- }
- else {
- fLine[iSM]->SetX1((iSM+1)*nTower) ;
- fLine[iSM]->SetY1(ymin) ;
- fLine[iSM]->SetX2((iSM+1)*nTower) ;
- fLine[iSM]->SetY2(ymax) ;
+ fText->AddText(Form("%2.2f %% towers out of range [0.8, 1.2]", (1-rv)*100));
+ if (rv < 0.9) {
+ test[specie] = 0.9 ;
+ // 2 lines text info for quality
+ fText->SetFillColor(2) ;
+ fText->AddText(Form("EMCAL = NOK, CALL EXPERTS!!!"));
}
- //filling the histogram with the difference and fitting with gaus function to obtain mean and sigma
- for(Int_t iTower = iSM*nTower ; iTower<(iSM+1)*nTower ; iTower++){
- proj->Fill(hdata->GetBinContent(iTower)-aver);
- }
- proj->Fit("gaus","","QNO");
- mean=proj->GetFunction("gaus")->GetParameter(1); // ! mean should be peaked at 0 in principal
- width=proj->GetFunction("gaus")->GetParameter(2);
- AliInfo(Form("aver = %f, mean = %f, sigma =%f\n",aver,mean, width));
-
- if(aver) init=TMath::Abs(mean/aver); //calculate the divation from the average
-
- //if mean or sigma is too huge or the sigma is too small, the fitting failed
- if((aver+mean) < 1. || width/aver >2. || width < 1.e-3)
- flag = -1 ;
- else { //recalculate the average if the fitting didn't give the initial average
- aver+=mean; //average corrected after fitting is fitting works
- //if(aver <= 1. ) break ;
- // if divation is too large, we conside to recalate the average by excluding channels too far from the average
- while(init>0.01 && aver >= 1.){
- if(flag) flag = 0 ; //for each time recalculation, reset flag
- for(Int_t iTower = iSM*nTower ; iTower < (iSM+1)*nTower ; iTower++){
- if(hdata->GetBinContent(iTower)>(aver-width) && hdata->GetBinContent(iTower)<(aver+width)){
- flag++ ;
- recal += hdata->GetBinContent(iTower);
- }
- } //end of channels loop
-
- if(flag == 0 || recal < 1.) {
- flag = -1 ;
- break ;
- }
- else {
- recal/=flag ;
- init=(aver-recal)/(aver+recal) ; //difference between the new average and the pervious one
- aver =(aver+recal)/2 ; //recalculate the average by the last two values
- }
- } //out of while condition
-
- ratio=100.0*flag/nTower ; //counting how many towers used for average recalculation
- AliInfo(Form("SM %d has %2.2f %% chanhel works \n", iSM, ratio));
- } // end of recalculation
-
- rv+=init ; //define the deviation from the final average
-
- //define the average line on each SM
- fHref[iSM] = dynamic_cast<TLine*>(hdata->GetListOfFunctions()->FindObject(fHref[iSM]));
- if(!fHref[iSM]) {
- fHref[iSM] = new TLine(iSM*nTower,aver,(iSM+1)*nTower,aver);
- hdata->GetListOfFunctions()->Add(fHref[iSM]);
- list[specie]->AddAt(hdata, kTowerHG) ;
- }
- else {
- fHref[iSM]->Clear() ;
- fHref[iSM]->SetX1(iSM*nTower) ;
- fHref[iSM]->SetY1(aver) ;
- fHref[iSM]->SetX2((iSM+1)*nTower) ;
- fHref[iSM]->SetY2(aver) ;
- }
-
- hdata->Paint() ;
-
- // if channels used for average recalculation smaller than the threshold,
- // then too much noise channels or channels didn't work
- if(ratio<= kThreshold && flag >0){
- //fText->SetFillColor(2);
- fHref[iSM]->SetLineColor(2);
- fHref[iSM]->SetLineWidth(2);
- fText->SetFillColor(2);
- fText->AddText(Form("SM %d: NOK = %2.0f %% channels OK!!!",iSM,ratio));
- //fText[iSM]->AddText(Form("SM %d NOT OK, only %5.2f %% works!!!",iSM,flag/nTower));
- }
- else if (flag == -1 || flag == 0 ) { //fitting failed or recalculation didn't call
- fText->SetFillColor(2);
- fHref[iSM]->SetLineColor(2);
- fHref[iSM]->SetLineWidth(2);
- fText->SetFillColor(2);
- fText->AddText(Form("SM %d: NOK Fitting failed",iSM,ratio));
- //fText[iSM]->AddText(Form("SM %d has %5.2f %% towers wok normally",iSM,flag/nTower));
- }
else {
- fText->SetFillColor(3);
- fHref[iSM]->SetLineColor(3);
- fHref[iSM]->SetLineWidth(2);
- fText->AddText(Form("SM %d: OK = %2.0f %% channels OK",iSM,ratio));
- //fText[iSM]->AddText(Form("SM %d has %5.2f %% towers wok normally",iSM,flag/nTower));
+ test[specie] = 0.1 ;
+ fText->SetFillColor(3) ;
+ fText->AddText(Form("EMCAL = OK, ENJOY..."));
}
- hdata->Paint() ;
- //hdata->GetListOfFunctions()->Add(fText[iSM]);
- delete proj ;
- } // end of SM loop
- rv/=fknSM;
- hdata->GetListOfFunctions()->Add(fText);
- hdata->Paint() ;
- if ( rv <=0.1 ) {
- AliInfo(Form("The deviation rv = %2.2f is small compared to average, detector works fine",rv));
- test[specie] = 0.05;
- }
-
- if ( rv <=0.5 && rv >0.1 ) {
- AliWarning(Form("The deviation rv = %2.2f is acceptable from average, the detector works not perfect!",rv));
- test[specie] = 0.3;
- }
-
- if ( rv <=0.8 && rv >0.5 ) {
- AliError(Form("Got a large deviation of %2.2f from average, some error on the detector!!!",rv));
- test[specie] = 0.7;
- }
-
- if ( rv >0.8 ) {
- AliError(Form("Got too large deviation of %2.2f from average, detector out of control???!!!",rv));
- test[specie] = 0.9;
- }
-
- } //end of checking raw
-
- } //species loop
- return test ;
+ //hdata->Reset("ICE");
+ //ratio->Reset("ICE");
+ }//fText
+ }
+ } //finish the checking
}
//______________________________________________________________________________