X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=STAT%2FTStatToolkit.cxx;h=da7f695973b75f67c13a749e10e4d288eeeb4ded;hb=034aa4b3440dc1a247db625e716c570cb5d49069;hp=4a5fc4480fee4ad34e86aaa6da7e14010e90e28c;hpb=28dfdfed135bc96645162377b1e37591568f890d;p=u%2Fmrichter%2FAliRoot.git diff --git a/STAT/TStatToolkit.cxx b/STAT/TStatToolkit.cxx index 4a5fc4480fe..da7f695973b 100644 --- a/STAT/TStatToolkit.cxx +++ b/STAT/TStatToolkit.cxx @@ -381,7 +381,7 @@ Bool_t TStatToolkit::LTMHisto(TH1 *his1D, TVectorD ¶ms , Float_t fraction){ // substract fractions of bin0 and bin1 to keep sum0=fration*sumCont // Double_t diff = sum0-fraction*sumCont; - Double_t mean = sum1/sum0; + Double_t mean = (sum0>0) ? sum1/sum0:0; // Double_t x0=his1D->GetBinCenter(ibin0); Double_t x1=his1D->GetBinCenter(ibin1); @@ -970,7 +970,7 @@ TString* TStatToolkit::FitPlane(TTree *tree, const char* drawCommand, const char Int_t entries = tree->Draw(drawStr.Data(), cutStr.Data(), "goff", stop-start, start); if (entries == -1) { delete formulaTokens; - return new TString("An ERROR has occured during fitting!"); + return new TString(TString::Format("ERROR expr: %s\t%s\tEntries==0",drawStr.Data(),cutStr.Data())); } Double_t **values = new Double_t*[dim+1] ; for (Int_t i=0; iGetV1(), entries*sizeof(Double_t)); @@ -992,7 +992,7 @@ TString* TStatToolkit::FitPlane(TTree *tree, const char* drawCommand, const char if (entries != centries) { delete []errors; delete []values; - return new TString("An ERROR has occured during fitting!"); + return new TString(TString::Format("ERROR: %s\t%s\tEntries==%d\tEntries2=%d\n",drawStr.Data(),cutStr.Data(),entries,centries)); } values[i] = new Double_t[entries]; memcpy(values[i], tree->GetV1(), entries*sizeof(Double_t)); @@ -1523,8 +1523,8 @@ TGraph * TStatToolkit::MakeGraphSparse(TTree * tree, const char * expr, const ch graphNew->GetHistogram()->SetTitle(""); graphNew->SetMarkerStyle(mstyle); - graphNew->SetMarkerColor(mcolor); - if (msize>0) graphNew->SetMarkerSize(msize); + graphNew->SetMarkerColor(mcolor); graphNew->SetLineColor(mcolor); + if (msize>0) { graphNew->SetMarkerSize(msize); graphNew->SetLineWidth(msize); } delete [] unsortedX; delete [] runNumber; delete [] index; @@ -1577,7 +1577,10 @@ Int_t TStatToolkit::MakeStatAlias(TTree * tree, const char * expr, const char * } // TObjArray* oaAlias = TString(alias).Tokenize(":"); - if (oaAlias->GetEntries()<2) return 0; + if (oaAlias->GetEntries()<2) { + printf("Alias must have 2 arguments:\t%s\n", alias); + return 0; + } Float_t entryFraction = atof( oaAlias->At(1)->GetName() ); // Double_t median = TMath::Median(entries,tree->GetV1()); @@ -1631,10 +1634,17 @@ Int_t TStatToolkit::SetStatusAlias(TTree * tree, const char * expr, const char TObjArray* oaVar = TString(expr).Tokenize(":"); char varname[50]; snprintf(varname,50,"%s", oaVar->At(0)->GetName()); + Float_t entryFraction = 0.8; // TObjArray* oaAlias = TString(alias).Tokenize(":"); - if (oaAlias->GetEntries()<3) return 0; - Float_t entryFraction = atof( oaAlias->At(2)->GetName() ); + if (oaAlias->GetEntries()<2) { + printf("Alias must have at least 2 arguments:\t%s\n", alias); + return 0; + } + else if (oaAlias->GetEntries()<3) { + //printf("Using default entryFraction if needed:\t%f\n", entryFraction); + } + else entryFraction = atof( oaAlias->At(2)->GetName() ); // Double_t median = TMath::Median(entries,tree->GetV1()); Double_t mean = TMath::Mean(entries,tree->GetV1()); @@ -1671,15 +1681,40 @@ TMultiGraph* TStatToolkit::MakeStatusMultGr(TTree * tree, const char * expr, co // Compute a trending multigraph that shows for which runs a variable has outliers. // (by MI, Patrick Reichelt) // - // format of expr : varname:xaxis (e.g. meanTPCncl:run) + // format of expr : varname:xaxis (e.g. meanTPCncl:run, but 'varname' can be any string that you need for seach-and-replace) // format of cut : char like in TCut - // format of alias: (1):(varname_Out==0):(varname_Out)[:(varname_Warning):...] + // format of alias: (1):(statisticOK):(varname_Warning):(varname_Out)[:(varname_PhysAcc):(varname_Extra)] + // + // function MakeGraphSparse() is called for each alias argument, which will be used as tree expression. + // each alias argument is supposed to be a Boolean statement which can be evaluated as tree expression. + // the order of these criteria should be kept, as the marker styles and colors are chosen to be meaningful this way! + // 'statisticOK' could e.g. be an alias for '(meanTPCncl>0)'. + // if you dont need e.g. a 'warning' condition, then just replace it by (0). // in the alias, 'varname' will be replaced by its content (e.g. varname_Out -> meanTPCncl_Out) // note: the aliases 'varname_Out' etc have to be defined by function TStatToolkit::SetStatusAlias(...) // counter igr is used to shift the multigraph in y when filling a TObjArray. // + // + // To create the Status Bar, the following is done in principle. + // ( example current usage in $ALICE_ROOT/PWGPP/TPC/macros/drawPerformanceTPCQAMatchTrends.C and ./qaConfig.C. ) + // + // TStatToolkit::SetStatusAlias(tree, "meanTPCncl", "", "varname_Out:(abs(varname-MeanEF)>6.*RMSEF):0.8"); + // TStatToolkit::SetStatusAlias(tree, "tpcItsMatchA", "", "varname_Out:(abs(varname-MeanEF)>6.*RMSEF):0.8"); + // TStatToolkit::SetStatusAlias(tree, "meanTPCncl", "", "varname_Warning:(abs(varname-MeanEF)>3.*RMSEF):0.8"); + // TStatToolkit::SetStatusAlias(tree, "tpcItsMatchA", "", "varname_Warning:(abs(varname-MeanEF)>3.*RMSEF):0.8"); + // TObjArray* oaMultGr = new TObjArray(); int igr=0; + // oaMultGr->Add( TStatToolkit::MakeStatusMultGr(tree, "tpcItsMatchA:run", "", "(1):(meanTPCncl>0):(varname_Warning):(varname_Outlier):", igr) ); igr++; + // oaMultGr->Add( TStatToolkit::MakeStatusMultGr(tree, "meanTPCncl:run", "", "(1):(meanTPCncl>0):(varname_Warning):(varname_Outlier):", igr) ); igr++; + // TCanvas *c1 = new TCanvas("c1","c1"); + // TStatToolkit::AddStatusPad(c1, 0.30, 0.40); + // TStatToolkit::DrawStatusGraphs(oaMultGr); + + TObjArray* oaVar = TString(expr).Tokenize(":"); - if (oaVar->GetEntries()<2) return 0; + if (oaVar->GetEntries()<2) { + printf("Expression has to be of type 'varname:xaxis':\t%s\n", expr); + return 0; + } char varname[50]; char var_x[50]; snprintf(varname,50,"%s", oaVar->At(0)->GetName()); @@ -1688,24 +1723,24 @@ TMultiGraph* TStatToolkit::MakeStatusMultGr(TTree * tree, const char * expr, co TString sAlias(alias); sAlias.ReplaceAll("varname",varname); TObjArray* oaAlias = TString(sAlias.Data()).Tokenize(":"); - if (oaAlias->GetEntries()<3) return 0; - // + if (oaAlias->GetEntries()<2) { + printf("Alias must have 2-6 arguments:\t%s\n", alias); + return 0; + } char query[200]; TMultiGraph* multGr = new TMultiGraph(); - Int_t marArr[6] = {24+igr%2, 20+igr%2, 20+igr%2, 20+igr%2, 22, 23}; - Int_t colArr[6] = {kBlack, kBlack, kRed, kOrange, kMagenta, kViolet}; - Double_t sizArr[6] = {1.2, 1.1, 1.0, 1.0, 1, 1}; + Int_t marArr[6] = {24+igr%2, 20+igr%2, 20+igr%2, 20+igr%2, 20+igr%2, 20+igr%2}; + Int_t colArr[6] = {kBlack, kBlack, kOrange, kRed, kGreen+1, kBlue}; + Double_t sizeArr[6] = {1.4, 1.1, 1.5, 1.1, 1.4, 0.8}; + Double_t shiftArr[6] = {0., 0., 0.25, 0.25, -0.25, -0.25}; const Int_t ngr = oaAlias->GetEntriesFast(); for (Int_t i=0; iAt(i)->GetName(), var_x); - multGr->Add( (TGraphErrors*) TStatToolkit::MakeGraphSparse(tree,query,cut,marArr[i],colArr[i],sizArr[i]) ); + multGr->Add( (TGraphErrors*) TStatToolkit::MakeGraphSparse(tree,query,cut,marArr[i],colArr[i],sizeArr[i],shiftArr[i]) ); } - snprintf(query,200, "%f*(%s-0.5):%s", 1.+igr, oaAlias->At(2)->GetName(), var_x); - multGr->Add( (TGraphErrors*) TStatToolkit::MakeGraphSparse(tree,query,cut,marArr[2],colArr[2],sizArr[2]) ); // multGr->SetName(varname); - multGr->SetTitle(varname); // used for y-axis labels. // details to be included! + multGr->SetTitle(varname); // used for y-axis labels of status bar, can be modified by calling function. delete oaVar; delete oaAlias; return multGr; @@ -1752,10 +1787,11 @@ void TStatToolkit::DrawStatusGraphs(TObjArray* oaMultGr) const Int_t nvars = oaMultGr->GetEntriesFast(); TGraph* grAxis = (TGraph*) ((TMultiGraph*) oaMultGr->At(0))->GetListOfGraphs()->At(0); grAxis->SetMaximum(0.5*nvars+0.5); - grAxis->SetMinimum(0); + grAxis->SetMinimum(0); grAxis->GetYaxis()->SetLabelSize(0); + grAxis->GetYaxis()->SetTitle(""); + grAxis->SetTitle(""); Int_t entries = grAxis->GetN(); - printf("entries (via GetN()) = %d\n",entries); grAxis->GetXaxis()->SetLabelSize(5.7*TMath::Min(TMath::Max(5./entries,0.01),0.03)); grAxis->GetXaxis()->LabelsOption("v"); grAxis->Draw("ap"); @@ -1771,6 +1807,253 @@ void TStatToolkit::DrawStatusGraphs(TObjArray* oaMultGr) } +TTree* TStatToolkit::WriteStatusToTree(TObject* oStatusGr) +{ + // + // Create Tree with Integers for each status variable flag (warning, outlier, physacc). + // (by Patrick Reichelt) + // + // input: either a TMultiGraph with status of single variable, which + // was computed by TStatToolkit::MakeStatusMultGr(), + // or a TObjArray which contains up to 10 of such variables. + // example: TTree* statusTree = WriteStatusToTree( TStatToolkit::MakeStatusMultGr(tree, "tpcItsMatch:run", "", sCriteria.Data(), 0) ); + // or : TTree* statusTree = TStatToolkit::WriteStatusToTree(oaMultGr); + // + // output tree: 1=flag is true, 0=flag is false, -1=flag was not computed. + // To be rewritten to the pcstream + + TObjArray* oaMultGr = NULL; + Bool_t needDeletion=kFALSE; + if (oStatusGr->IsA() == TObjArray::Class()) { + oaMultGr = (TObjArray*) oStatusGr; + } + else if (oStatusGr->IsA() == TMultiGraph::Class()) { + oaMultGr = new TObjArray(); needDeletion=kTRUE; + oaMultGr->Add((TMultiGraph*) oStatusGr); + } + else { + Printf("WriteStatusToTree(): Error! 'oStatusGr' must be a TMultiGraph or a TObjArray of them!"); + return 0; + } + // variables for output tree + const int nvarsMax=10; + const int ncritMax=5; + Int_t currentRun; + Int_t treevars[nvarsMax*ncritMax]; + TString varnames[nvarsMax*ncritMax]; + for (int i=0; iGetEntriesFast()) { + varnames[vari*ncritMax+0] = Form("%s_statisticOK", ((TMultiGraph*) oaMultGr->At(vari))->GetName()); + varnames[vari*ncritMax+1] = Form("%s_Warning", ((TMultiGraph*) oaMultGr->At(vari))->GetName()); + varnames[vari*ncritMax+2] = Form("%s_Outlier", ((TMultiGraph*) oaMultGr->At(vari))->GetName()); + varnames[vari*ncritMax+3] = Form("%s_PhysAcc", ((TMultiGraph*) oaMultGr->At(vari))->GetName()); + varnames[vari*ncritMax+4] = Form("%s_Extra", ((TMultiGraph*) oaMultGr->At(vari))->GetName()); + } + else { + varnames[vari*ncritMax+0] = Form("dummy"); + varnames[vari*ncritMax+1] = Form("dummy"); + varnames[vari*ncritMax+2] = Form("dummy"); + varnames[vari*ncritMax+3] = Form("dummy"); + varnames[vari*ncritMax+4] = Form("dummy"); + } + cout << " " << varnames[vari*ncritMax+0].Data() << " " << varnames[vari*ncritMax+1].Data() << " " << varnames[vari*ncritMax+2].Data() << " " << varnames[vari*ncritMax+3].Data() << " " << varnames[vari*ncritMax+4].Data() << endl; + } + + TTree* statusTree = new TTree("statusTree","statusTree"); + statusTree->Branch("run", ¤tRun ); + statusTree->Branch(varnames[ 0].Data(), &treevars[ 0]); + statusTree->Branch(varnames[ 1].Data(), &treevars[ 1]); + statusTree->Branch(varnames[ 2].Data(), &treevars[ 2]); + statusTree->Branch(varnames[ 3].Data(), &treevars[ 3]); + statusTree->Branch(varnames[ 4].Data(), &treevars[ 4]); + statusTree->Branch(varnames[ 5].Data(), &treevars[ 5]); + statusTree->Branch(varnames[ 6].Data(), &treevars[ 6]); + statusTree->Branch(varnames[ 7].Data(), &treevars[ 7]); + statusTree->Branch(varnames[ 8].Data(), &treevars[ 8]); + statusTree->Branch(varnames[ 9].Data(), &treevars[ 9]); + statusTree->Branch(varnames[10].Data(), &treevars[10]); + statusTree->Branch(varnames[11].Data(), &treevars[11]); + statusTree->Branch(varnames[12].Data(), &treevars[12]); + statusTree->Branch(varnames[13].Data(), &treevars[13]); + statusTree->Branch(varnames[14].Data(), &treevars[14]); + statusTree->Branch(varnames[15].Data(), &treevars[15]); + statusTree->Branch(varnames[16].Data(), &treevars[16]); + statusTree->Branch(varnames[17].Data(), &treevars[17]); + statusTree->Branch(varnames[18].Data(), &treevars[18]); + statusTree->Branch(varnames[19].Data(), &treevars[19]); + statusTree->Branch(varnames[20].Data(), &treevars[20]); + statusTree->Branch(varnames[21].Data(), &treevars[21]); + statusTree->Branch(varnames[22].Data(), &treevars[22]); + statusTree->Branch(varnames[23].Data(), &treevars[23]); + statusTree->Branch(varnames[24].Data(), &treevars[24]); + statusTree->Branch(varnames[25].Data(), &treevars[25]); + statusTree->Branch(varnames[26].Data(), &treevars[26]); + statusTree->Branch(varnames[27].Data(), &treevars[27]); + statusTree->Branch(varnames[28].Data(), &treevars[28]); + statusTree->Branch(varnames[29].Data(), &treevars[29]); + statusTree->Branch(varnames[30].Data(), &treevars[30]); + statusTree->Branch(varnames[31].Data(), &treevars[31]); + statusTree->Branch(varnames[32].Data(), &treevars[32]); + statusTree->Branch(varnames[33].Data(), &treevars[33]); + statusTree->Branch(varnames[34].Data(), &treevars[34]); + statusTree->Branch(varnames[35].Data(), &treevars[35]); + statusTree->Branch(varnames[36].Data(), &treevars[36]); + statusTree->Branch(varnames[37].Data(), &treevars[37]); + statusTree->Branch(varnames[38].Data(), &treevars[38]); + statusTree->Branch(varnames[39].Data(), &treevars[39]); + statusTree->Branch(varnames[40].Data(), &treevars[40]); + statusTree->Branch(varnames[41].Data(), &treevars[41]); + statusTree->Branch(varnames[42].Data(), &treevars[42]); + statusTree->Branch(varnames[43].Data(), &treevars[43]); + statusTree->Branch(varnames[44].Data(), &treevars[44]); + statusTree->Branch(varnames[45].Data(), &treevars[45]); + statusTree->Branch(varnames[46].Data(), &treevars[46]); + statusTree->Branch(varnames[47].Data(), &treevars[47]); + statusTree->Branch(varnames[48].Data(), &treevars[48]); + statusTree->Branch(varnames[49].Data(), &treevars[49]); + + // run loop + Double_t graphX; // x-position of marker (0.5, 1.5, ...) + Double_t graphY; // if >0 -> warning/outlier/physacc! if =-0.5 -> no warning/outlier/physacc + TList* arrRuns = (TList*) ((TGraph*) ((TMultiGraph*) oaMultGr->At(0))->GetListOfGraphs()->At(0))->GetXaxis()->GetLabels(); + //'TAxis->GetLabels()' returns THashList of TObjString, but using THashList gives compilation error "... incomplete type 'struct THashList' " + for (Int_t runi=0; runiGetSize(); runi++) + { + currentRun = atoi( arrRuns->At(runi)->GetName() ); + //Printf(" runi=%2i, name: %s \t run number: %i", runi, arrRuns->At(runi)->GetName(), currentRun); + + // status variable loop + for (Int_t vari=0; variGetEntriesFast(); vari++) + { + TMultiGraph* multGr = (TMultiGraph*) oaMultGr->At(vari); + + // criteria loop + // the order is given by TStatToolkit::MakeStatusMultGr(). + // criterion #1 is 'statisticOK' and mandatory, the rest is optional. (#0 is always True, thus skipped) + for (Int_t criti=1; critiGetListOfGraphs()->GetEntries(); criti++) + { + TGraph* grCriterion = (TGraph*) multGr->GetListOfGraphs()->At(criti); + graphX = -1, graphY = -1; + grCriterion->GetPoint(runi, graphX, graphY); + treevars[(vari)*ncritMax+(criti-1)] = (graphY>0)?1:0; + } + } + statusTree->Fill(); + } + + if (needDeletion) delete oaMultGr; + + return statusTree; +} + + +void TStatToolkit::MakeSummaryTree(TTree* treeIn, TTreeSRedirector *pcstream, TObjString & sumID, TCut &selection){ + // + // Make a summary tree for the input tree + // For the moment statistic works only for the primitive branches (Float/Double/Int) + // Extension recursive version planned for graphs a and histograms + // + // Following statistics are exctracted: + // - Standard: mean, meadian, rms + // - LTM robust statistic: mean60, rms60, mean90, rms90 + // Parameters: + // treeIn - input tree + // pctream - Output redirector + // sumID - ID as will be used in output tree + // selection - selection criteria define the set of entries used to evaluat statistic + // + TObjArray * brArray = treeIn->GetListOfBranches(); + Int_t tEntries= treeIn->GetEntries(); + Int_t nBranches=brArray->GetEntries(); + TString treeName = treeIn->GetName(); + treeName+="Summary"; + + (*pcstream)<GetEntries()<2) { + printf("Expression has to be of type 'varname:xaxis':\t%s\n", expr); + return 0; + } + char varname[50]; + char var_x[50]; + snprintf(varname,50,"%s", oaVar->At(0)->GetName()); + snprintf(var_x ,50,"%s", oaVar->At(1)->GetName()); + // + TString sAlias(alias); + if (sAlias.IsNull()) { // alias for default usage set here: + sAlias = "varname_OutlierMin:varname_OutlierMax:varname_WarningMin:varname_WarningMax:varname_PhysAccMin:varname_PhysAccMax:varname_RobustMean"; + } + sAlias.ReplaceAll("varname",varname); + TObjArray* oaAlias = TString(sAlias.Data()).Tokenize(":"); + if (oaAlias->GetEntries()<2) { + printf("Alias must have 2-7 arguments:\t%s\n", alias); + return 0; + } + char query[200]; + TMultiGraph* multGr = new TMultiGraph(); + Int_t colArr[7] = {kRed, kRed, kOrange, kOrange, kGreen+1, kGreen+1, kGray+2}; + const Int_t ngr = oaAlias->GetEntriesFast(); + for (Int_t i=0; iAt(i)->GetName(), var_x); + multGr->Add( (TGraphErrors*) TStatToolkit::MakeGraphSparse(tree,query,cut,29,colArr[i],1.5) ); + } + // + multGr->SetName(varname); + multGr->SetTitle(varname); + delete oaVar; + delete oaAlias; + return multGr; +} + + TH1* TStatToolkit::DrawHistogram(TTree * tree, const char* drawCommand, const char* cuts, const char* histoname, const char* histotitle, Int_t nsigma, Float_t fraction ) { // @@ -1817,7 +2100,7 @@ TH1* TStatToolkit::DrawHistogram(TTree * tree, const char* drawCommand, const ch TStatToolkit::EvaluateUni(entries, tree->GetV1(),meanY,rmsY, fraction*entries); TStatToolkit::EvaluateUni(entries, tree->GetV2(),meanX,rmsX, fraction*entries); } - TH1* hOut; + TH1* hOut=NULL; if(dim==1){ hOut = new TH1F(histoname, histotitle, 200, meanX-nsigma*rmsX, meanX+nsigma*rmsX); for (Int_t i=0; iFill(tree->GetV1()[i]); @@ -1833,3 +2116,22 @@ TH1* TStatToolkit::DrawHistogram(TTree * tree, const char* drawCommand, const ch } return hOut; } + +void TStatToolkit::CheckTreeAliases(TTree * tree, Int_t ncheck){ + // + // Check consistency of tree aliases + // + Int_t nCheck=100; + TList * aliases = (TList*)tree->GetListOfAliases(); + Int_t entries = aliases->GetEntries(); + for (Int_t i=0; iAt(i); + if (!object) continue; + Int_t ndraw=tree->Draw(aliases->At(i)->GetName(),"1","goff",nCheck); + if (ndraw==0){ + ::Error("Alias:\tProblem",aliases->At(i)->GetName()); + }else{ + ::Info("Alias:\tOK",aliases->At(i)->GetName()); + } + } +}