--- /dev/null
+/*
+ * MuonGenerator.C
+ * aliroot_dev
+ *
+ * Created by philippe pillot on 05/03/13.
+ * Copyright 2013 SUBATECH. All rights reserved.
+ *
+ */
+
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include <Riostream.h>
+#include "TRandom.h"
+#include "AliGenerator.h"
+#include "AliGenParam.h"
+#endif
+
+
+static Int_t IpMuon( TRandom *ran);
+static Double_t PtMuon( const Double_t *px, const Double_t */*dummy*/ );
+static Double_t YMuon( const Double_t *py, const Double_t */*dummy*/ );
+static Double_t V2Muon( const Double_t *pv, const Double_t */*dummy*/ );
+
+
+//-------------------------------------------------------------------------
+AliGenerator* GenParamCustomSingle()
+{
+ AliGenParam *singleMu = new AliGenParam(1,-1,PtMuon,YMuon,V2Muon,IpMuon);
+ singleMu->SetMomentumRange(0,1e6);
+ singleMu->SetPtRange(VAR_GENPARAMCUSTOMSINGLE_PTMIN,999.);
+ singleMu->SetYRange(-4.2, -2.3);
+ singleMu->SetPhiRange(0., 360.);
+ singleMu->SetForceDecay(kNoDecay);
+ singleMu->SetTrackingFlag(1);
+ return singleMu;
+}
+
+//-------------------------------------------------------------------------
+Int_t IpMuon(TRandom *ran)
+{
+ // muon composition
+
+ if (ran->Rndm() < 0.5 )
+ {
+ return 13;
+ }
+ else
+ {
+ return -13;
+ }
+}
+
+//-------------------------------------------------------------------------
+Double_t PtMuon( const Double_t *px, const Double_t */*dummy*/ )
+{
+ // muon pT
+
+ Double_t x=*px;
+ Float_t p0,p1,p2,p3;
+ p0 = VAR_GENPARAMCUSTOMSINGLE_PT_P0; //4.05962;
+ p1 = VAR_GENPARAMCUSTOMSINGLE_PT_P1; //1;
+ p2 = VAR_GENPARAMCUSTOMSINGLE_PT_P2; //2.46187;
+ p3 = VAR_GENPARAMCUSTOMSINGLE_PT_P3; //2.08644;
+ return p0 / TMath::Power( p1 + TMath::Power(x,p2), p3 );
+}
+
+//-------------------------------------------------------------------------
+Double_t YMuon( const Double_t *py, const Double_t */*dummy*/ )
+{
+ // muon y
+
+ Double_t y = *py;
+ //pol4 only valid in y= -4;-2.5
+ Float_t p0,p1,p2,p3;
+ p0 = VAR_GENPARAMCUSTOMSINGLE_Y_P0; //0.729545;
+ p1 = VAR_GENPARAMCUSTOMSINGLE_Y_P1; //0.53837;
+ p2 = VAR_GENPARAMCUSTOMSINGLE_Y_P2; //0.141776;
+ p3 = VAR_GENPARAMCUSTOMSINGLE_Y_P3; //0.0130173;
+ return p0 * (1. + p1*y + p2*y*y + p3*y*y*y);
+}
+
+//-------------------------------------------------------------------------
+Double_t V2Muon( const Double_t */*dummy*/, const Double_t */*dummy*/ )
+{
+ //muon v2
+ return 0.;
+}
+
// MUON Tracker Residual Alignment
reco.SetSpecificStorage("MUON/Align/Data","alien://folder=/alice/simulation/2008/v4-15-Release/Residual");
-
+reco.SetSpecificStorage("MUON/Calib/RejectList","alien://folder=/alice/cern.ch/user/l/laphecet/OCDB");
+
reco.Run();
}
#include "AliAnalysisMuMu.h"
#include "AliAnalysisMuMuBinning.h"
-#include "AliAnalysisMuMuResult.h"
+#include "AliAnalysisMuMuFnorm.h"
+#include "AliAnalysisMuMuGraphUtil.h"
+#include "AliAnalysisMuMuJpsiResult.h"
#include "AliAnalysisMuMuSpectra.h"
#include "AliAnalysisTriggerScalers.h"
#include "AliCounterCollection.h"
#include "TGrid.h"
#include "TH1.h"
#include "TH2.h"
+#include "THashList.h"
#include "TKey.h"
#include "TLegend.h"
#include "TLegendEntry.h"
GetCollections(fFilename,fMergeableCollection,fCounterCollection,fBinning,fRunNumbers);
- if (IsSimulation())
+ if ( fCounterCollection )
{
- SetEventSelectionList("ALL");
- SetDimuonTriggerList("CMULLO-B-NOPF-MUON");
- SetFitTypeList("PSI1:1,COUNTJPSI:1");
- }
+ if (IsSimulation())
+ {
+ SetEventSelectionList("ALL");
+ SetDimuonTriggerList("CMULLO-B-NOPF-MUON");
+ SetFitTypeList("COUNTJPSI:1");
+// SetFitTypeList("PSI1:1,COUNTJPSI:1");
+ }
- if ( strlen(associatedSimFileName) )
- {
- fAssociatedSimulation = new AliAnalysisMuMu(associatedSimFileName);
+ if ( strlen(associatedSimFileName) )
+ {
+ fAssociatedSimulation = new AliAnalysisMuMu(associatedSimFileName);
+ }
}
}
AliAnalysisMuMu::~AliAnalysisMuMu()
{
// dtor
+
+ if ( fAssociatedSimulation )
+ {
+ fAssociatedSimulation->Update();
+ }
+
+ Update();
+
delete fCounterCollection;
delete fBinning;
delete fMergeableCollection;
Update();
}
-//_____________________________________________________________________________
-void AliAnalysisMuMu::Compact(TGraph& g)
-{
- /// Compact (i.e. get the equivalent of 1 bin = 1 run number for an histogram)
- /// the graph.
- /// Only works if the x content of this graph represents run numbers. Otherwise
- /// result is unpredictable ;-)
-
- if ( !g.GetN() ) return;
-
- TGraph* newgraph = static_cast<TGraph*>(g.Clone());
- Double_t x,xerr,y,yerr;
- TGraphErrors* ge = dynamic_cast<TGraphErrors*>(newgraph);
-
- TAxis* axis = g.GetXaxis();
-
- for ( Int_t i = 0; i < newgraph->GetN(); ++i )
- {
- g.GetPoint(i,x,y);
- if (ge)
- {
- xerr = ge->GetErrorX(i);
- yerr = ge->GetErrorY(i);
- }
-
- g.SetPoint(i,i+0.5,y);
- if (ge)
- {
- static_cast<TGraphErrors&>(g).SetPointError(i,0.5,yerr);
- }
-
- axis->SetBinLabel(i,Form("%d",TMath::Nint(x)));
- }
-
-
-}
-
//_____________________________________________________________________________
TObjArray* AliAnalysisMuMu::CompareJpsiPerCMUUWithBackground(const char* jpsiresults,
int& aodtrain,
int& runnumber)
{
+ // tries to extract period and pass numbers from a file name.
+
esdpass=aodtrain=runnumber=-1;
period="";
if (!sfile.BeginsWith("LHC") && !sfile.BeginsWith("SIM") )
{
+ // does not look nice but let's try at least to get the period
+
+ TObjArray* tmp = sfile.Tokenize(".");
+
+ for ( Int_t j = 0; j < tmp->GetEntries(); ++j )
+ {
+ TString s = static_cast<TObjString*>(tmp->At(j))->String();
+ s.ToLower();
+ if ( s.BeginsWith("lhc") )
+ {
+ period = s;
+ period.ReplaceAll("lhc","LHC");
+ break;
+ }
+ }
+
+ delete tmp;
+
+ if ( period.Length() )
+ {
+ return kTRUE;
+ }
+
std::cerr << Form("filename %s does not start with LHC or SIM",filename) << std::endl;
return kFALSE;
}
TString stype(type);
stype.ToUpper();
- TString spectraName(Form("/%s/%s/%s/%s/%s-%s-%s",eventType,trigger,centrality,pairCut,particle,stype.Data(),flavour));
+ TString spectraName(Form("/%s/%s/%s/%s/%s-%s",eventType,trigger,centrality,pairCut,particle,stype.Data()));
+
+ if ( strlen(flavour))
+ {
+ spectraName += "-";
+ spectraName += flavour;
+ }
AliAnalysisMuMuSpectra* spectra = static_cast<AliAnalysisMuMuSpectra*>(MC()->GetObject(spectraName.Data()));
TObjArray* spectraBins(0x0);
if ( spectra )
{
- spectraBins = spectra->Bins();
+ spectraBins = spectra->BinContentArray();
}
TCanvas* c = new TCanvas;
AliDebug(1,name.Data());
- AliAnalysisMuMuResult* spectraBin(0x0);
+ AliAnalysisMuMuJpsiResult* spectraBin(0x0);
if ( spectraBins )
{
AliAnalysisMuMuResult* sr = static_cast<AliAnalysisMuMuResult*>(spectraBins->At(ci));
- spectraBin = sr->SubResult(subresultname);
+ spectraBin = static_cast<AliAnalysisMuMuJpsiResult*>(sr->SubResult(subresultname));
AliDebug(1,Form("spectraBin(%s)=%p",subresultname,spectraBin));
}
return file;
}
+//_____________________________________________________________________________
+void AliAnalysisMuMu::TwikiOutputFnorm(const char* series) const
+{
+ // make a twiki-compatible output of the Fnorm factor(s)
+ TObjArray* what = TString(series).Tokenize(",");
+ TObjString* s;
+ TObjArray graphs;
+ TIter next(what);
+
+ std::cout << "| *Run* |";
+ while ( ( s = static_cast<TObjString*>(next())) )
+ {
+ TGraph* g = static_cast<TGraph*>(MC()->GetObject(Form("/FNORM/GRAPHS/%s",s->String().Data())));
+ if (!g)
+ {
+ AliError(Form("Could not find graph for %s",s->String().Data()));
+ continue;
+ }
+ std::cout << " *" << s->String().Data();
+ if ( s->String().BeginsWith("RelDif") ) std::cout << " %";
+ std::cout << "*|";
+ graphs.Add(g);
+ }
+
+ std::cout << endl;
+
+ TGraphErrors* g0 = static_cast<TGraphErrors*>(graphs.First());
+ if (!g0) return;
+
+ for ( Int_t i = 0; i < g0->GetN(); ++i )
+ {
+ TString msg;
+
+ msg.Form("|%6d|",TMath::Nint(g0->GetX()[i]));
+
+ for ( Int_t j = 0; j < graphs.GetEntries(); ++j )
+ {
+ TGraphErrors* g = static_cast<TGraphErrors*>(graphs.At(j));
+
+ msg += TString::Format(" %6.2f +- %6.2f |",g->GetY()[i],g->GetEY()[i]);
+ }
+
+ std::cout << msg.Data() << std::endl;
+ }
+
+ next.Reset();
+
+ std::cout << "|*Weigthed mean (*)*|";
+
+ AliAnalysisMuMuResult* r = static_cast<AliAnalysisMuMuResult*>(MC()->GetObject("/FNORM/RESULTS/Fnorm"));
+
+ if (!r)
+ {
+ AliError("Could not find Fnorm result !");
+ return;
+ }
+
+
+ while ( ( s = static_cast<TObjString*>(next())) )
+ {
+ TString var("Fnorm");
+ TString unit;
+
+ if ( s->String().BeginsWith("Fnorm") )
+ {
+ r = static_cast<AliAnalysisMuMuResult*>(MC()->GetObject("/FNORM/RESULTS/Fnorm"));
+ }
+ else if ( s->String().BeginsWith("RelDif") )
+ {
+ r = static_cast<AliAnalysisMuMuResult*>(MC()->GetObject("/FNORM/RESULTS/RelDif"));
+ unit = "%";
+ }
+
+ r->Exclude("*");
+ r->Include(s->String().Data());
+
+ std::cout << Form(" * %5.2f +- %5.2f %s * |",
+ r->GetValue(var.Data()),
+ r->GetErrorStat(var.Data()),
+ unit.Data());
+ }
+
+ next.Reset();
+
+ std::cout << std::endl;
+
+ std::cout << "|*RMS*|";
+
+ while ( ( s = static_cast<TObjString*>(next())) )
+ {
+ TString var("Fnorm");
+
+ if ( s->String().BeginsWith("Fnorm") )
+ {
+ r = static_cast<AliAnalysisMuMuResult*>(MC()->GetObject("/FNORM/RESULTS/Fnorm"));
+ }
+ else if ( s->String().BeginsWith("RelDif") )
+ {
+ r = static_cast<AliAnalysisMuMuResult*>(MC()->GetObject("/FNORM/RESULTS/RelDif"));
+ }
+
+ r->Exclude("*");
+ r->Include(s->String().Data());
+
+ Double_t d = 100.0*r->GetRMS(var.Data())/r->GetValue(var.Data());
+
+ std::cout << Form(" * %5.2f (%5.2f %%) * |",
+ r->GetRMS(var.Data()),d);
+ }
+
+ std::cout << std::endl;
+ std::cout << "(*) weight is the number of CMUL7-B-NOPF-MUON triggers (physics-selected and pile-up corrected) in each run" << std::endl;
+
+ delete what;
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMu::FigureOutputFnorm(const char* filelist)
+{
+ /// Make some figure of the Fnorm factors for files in filelist
+
+ TObjArray* periods = ReadFileList(filelist);
+
+ if (!periods || periods->IsEmpty() ) return;
+
+ TIter next(periods);
+
+ TObjArray fnormoffline1;
+ TObjArray fnormoffline2;
+ TObjArray reldif;
+ TObjArray correctionPSMUL;
+ TObjArray correctionPSMB;
+ TObjArray correctionPUPS;
+ TObjArray correctionPSRatio;
+
+ fnormoffline1.SetOwner(kTRUE);
+ fnormoffline2.SetOwner(kTRUE);
+ reldif.SetOwner(kTRUE);
+ correctionPUPS.SetOwner(kTRUE);
+ correctionPSMUL.SetOwner(kTRUE);
+ correctionPSMB.SetOwner(kTRUE);
+ correctionPSRatio.SetOwner(kTRUE);
+
+ for ( Int_t i = 0; i <= periods->GetLast(); ++i )
+ {
+ TString period("unknown");
+
+ TString filename(static_cast<TObjString*>(periods->At(i))->String());
+
+ Int_t dummy(0);
+
+ if (!DecodeFileName(filename,period,dummy,dummy,dummy))
+ {
+ continue;
+ }
+
+ if ( gSystem->AccessPathName(filename) )
+ {
+ AliErrorClass(Form("Could not find file %s. Skipping it.",filename.Data()));
+ continue;
+
+ }
+
+ AliAnalysisMuMu m(filename.Data());
+
+ fnormoffline1.Add(m.MC()->GetObject("/FNORM/GRAPHS/FnormOffline1PUPS")->Clone());
+ fnormoffline2.Add(m.MC()->GetObject("/FNORM/GRAPHS/FnormOffline2PUPS")->Clone());
+
+
+ correctionPSMUL.Add(m.MC()->GetObject("/FNORM/GRAPHS/CorrectionPSMUL")->Clone());
+ correctionPSMB.Add(m.MC()->GetObject("/FNORM/GRAPHS/CorrectionPSMB")->Clone());
+ correctionPUPS.Add(m.MC()->GetObject("/FNORM/GRAPHS/CorrectionPUPSMB")->Clone());
+
+ correctionPSRatio.Add(m.MC()->GetObject("/FNORM/GRAPHS/CorrectionPSRatio")->Clone());
+
+
+ reldif.Add(m.MC()->GetObject("/FNORM/GRAPHS/RelDifFnormScalersPUPSvsFnormOffline2PUPS")->Clone());
+
+ }
+
+ AliAnalysisMuMuGraphUtil gu(fgOCDBPath);
+
+ gu.ShouldDrawPeriods(kTRUE);
+
+ TObjArray a;
+
+ a.Add(gu.Combine(fnormoffline1,fgIsCompactGraphs));
+ a.Add(gu.Combine(fnormoffline2,fgIsCompactGraphs));
+
+ Double_t ymin(0.0);
+ Double_t ymax(3000.0);
+
+ new TCanvas("fnormoffline","fnormoffline");
+
+ gu.PlotSameWithLegend(a,ymin,ymax);
+
+ new TCanvas("corrections","corrections");
+
+ a.Clear();
+
+ a.Add(gu.Combine(correctionPSMB,fgIsCompactGraphs));
+ a.Add(gu.Combine(correctionPSMUL,fgIsCompactGraphs));
+ a.Add(gu.Combine(correctionPUPS,fgIsCompactGraphs));
+
+ gu.PlotSameWithLegend(a,0.8,1.2);
+
+ new TCanvas("psratio","psratio");
+
+ a.Clear();
+
+ a.Add(gu.Combine(correctionPSRatio,fgIsCompactGraphs));
+
+ gu.PlotSameWithLegend(a,0.8,1.2);
+
+ new TCanvas("offlinevsscalers","fig:offlinevsscalers");
+
+ a.Clear();
+
+ a.Add(gu.Combine(reldif,fgIsCompactGraphs));
+
+ gu.PlotSameWithLegend(a,-15,15);
+}
+
//_____________________________________________________________________________
TFile*
AliAnalysisMuMu::FileOpen(const char* file)
delete bins;
return 0x0;
}
-
+
+ TObjArray* runs = fCounterCollection->GetKeyWords("run").Tokenize(",");
+ Int_t nruns = runs->GetEntries();
+ delete runs;
+
+
// binning.Print();
AliAnalysisMuMuSpectra* spectra(0x0);
hminv = static_cast<TH1*>(hminv->Clone(Form("minv%d",n++)));
- AliAnalysisMuMuResult* r = new AliAnalysisMuMuResult(*hminv,
- trigger,
- eventType,
- pairCut,
- centrality,
- *bin);
+ AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(*hminv,
+ trigger,
+ eventType,
+ pairCut,
+ centrality,
+ *bin);
r->SetNofTriggers(ntrigger);
+ r->SetNofRuns(nruns);
nextFitType.Reset();
if ( r )
{
- AliAnalysisMuMuResult* r1 = r->SubResult("JPSI:1");
+ AliAnalysisMuMuJpsiResult* r1 = dynamic_cast<AliAnalysisMuMuJpsiResult*>(r->SubResult("JPSI:1"));
if (r1)
{
TF1* func = static_cast<TF1*>(r1->Minv()->GetListOfFunctions()->FindObject("fitTotal"));
sflavour.ToUpper();
TString spectraName(Form("/PSALL/%s/PP/%s/PSI-%s",
- First(fgDefaultDimuonTriggers).Data(),
- First(fgDefaultPairSelectionList).Data(),
+ First(fDimuonTriggers).Data(),
+ First(fPairSelectionList).Data(),
swhat.Data()));
if (sflavour.Length()>0)
{
// whether or not we have MC information
+ if (!fMergeableCollection) return kFALSE;
+
return ( fMergeableCollection->Histo(Form("/INPUT/%s/MinvUS",fgDefaultEventSelectionForSimulations.Data())) != 0x0 );
}
binning->AddBin("psi",swhat->String().Data());
}
- std::cout << "++++++++++++ swhat=" << swhat->String().Data() << std::endl;
+ StdoutToAliDebug(1,std::cout << "++++++++++++ swhat=" << swhat->String().Data() << std::endl;);
if (!binning)
{
AliError("oups. binning is NULL");
continue;
}
- binning->Print();
+
+ StdoutToAliDebug(1,binning->Print(););
nextTrigger.Reset();
fMergeableCollection->Adopt(id.Data(),spectra);
- spectra->Print();
+ StdoutToAliDebug(1,spectra->Print(););
}
}
}
delete eventTypeArray;
delete pairCutArray;
- timer.Print();
+ StdoutToAliDebug(1,timer.Print(););
if (nfits)
{
}
+//_____________________________________________________________________________
+void AliAnalysisMuMu::LatexOutputFnorm(const char* filelist, const char* subresultnames, Bool_t rms)
+{
+ /// Make a LaTeX output of the Fnorm factors for each file in filelist
+
+ TObjArray* periods = ReadFileList(filelist);
+
+ if (!periods || periods->IsEmpty() ) return;
+
+ TIter next(periods);
+
+ TObjArray* subresults = TString(subresultnames).Tokenize(",");
+ TIter nextSub(subresults);
+
+ Int_t ic(0);
+ Int_t iclast = subresults->GetLast();
+
+
+ std::cout << "\\begin{tabular}{l|r|r|r|r}" << std::endl;
+
+ std::cout << "Period & ";
+
+ TObjString* rname;
+
+
+ while ( ( rname = static_cast<TObjString*>(nextSub())) )
+ {
+ std::cout << rname->String().Data();
+
+ if ( ic != iclast )
+ {
+ std::cout << " & ";
+ }
+ ++ic;
+ }
+
+ std::cout << "\\\\" << std::endl << "\\hline" << std::endl;
+
+ for ( Int_t i = 0; i <= periods->GetLast(); ++i )
+ {
+ TString period("unknown");
+
+ TString filename(static_cast<TObjString*>(periods->At(i))->String());
+
+ Int_t dummy(0);
+
+ if (!DecodeFileName(filename,period,dummy,dummy,dummy))
+ {
+ continue;
+ }
+
+ if ( gSystem->AccessPathName(filename) )
+ {
+ AliErrorClass(Form("Could not find file %s. Skipping it.",filename.Data()));
+ continue;
+
+ }
+
+ AliAnalysisMuMu m(filename.Data());
+
+ AliMergeableCollection* norm = m.MC()->Project("/FNORM/RESULTS/");
+
+ AliAnalysisMuMuResult* r = static_cast<AliAnalysisMuMuResult*>(norm->GetObject("Fnorm")->Clone());
+
+ nextSub.Reset();
+
+ if (!r)
+ {
+ AliErrorClass(Form("Could not get result for file %s.",filename.Data()));
+ continue;
+ }
+
+ std::cout << period << " & ";
+
+ next.Reset();
+
+ ic = 0;
+
+ while ( ( rname = static_cast<TObjString*>(nextSub())) )
+ {
+ TString name(rname->String());
+ TString var("Fnorm");
+
+ if ( name.BeginsWith("RelDif"))
+ {
+ r = static_cast<AliAnalysisMuMuResult*>(norm->GetObject("RelDif"));
+
+ }
+ else if ( name.BeginsWith("Correction"))
+ {
+ r = static_cast<AliAnalysisMuMuResult*>(norm->GetObject("Correction"));
+ }
+ else
+ {
+ r = static_cast<AliAnalysisMuMuResult*>(norm->GetObject("Fnorm"));
+ }
+ r->Exclude("*");
+ r->Include(name.Data());
+
+ if ( rms )
+ {
+ std::cout << Form(" $%7.2f (%5.2f \%%)$ ",
+ r->GetRMS(var.Data()),
+ 100.0*r->GetRMS(var.Data())/r->GetValue(var.Data()));
+
+ }
+ else
+ {
+ std::cout << Form(" $%7.2f \\pm %5.3f$ ",r->GetValue(var.Data()),
+ r->GetErrorStat(var.Data()));
+ }
+
+ if ( ic != iclast )
+ {
+ std::cout << "&";
+ }
+
+ ++ic;
+ }
+
+ if ( i != periods->GetLast() )
+ {
+ std::cout << "\\\\";
+ }
+
+ std::cout << std::endl;
+
+ delete norm;
+ }
+
+
+ std::cout << "\\end{tabular}" << std::endl;
+
+
+
+ delete periods;
+}
+
//_____________________________________________________________________________
void AliAnalysisMuMu::PlotBackgroundEvolution(const char* gfile, const char* triggerList, Double_t ymax, Bool_t fillBoundaries)
{
{
TObjArray* a = static_cast<TObjArray*>(m->GetValue(str->String().Data()));
if (!a) continue;
- AliAnalysisMuMuResult* r = static_cast<AliAnalysisMuMuResult*>(a->FindObject(triggerClass.Data()));
+ AliAnalysisMuMuJpsiResult* r = static_cast<AliAnalysisMuMuJpsiResult*>(a->FindObject(triggerClass.Data()));
if (!r) continue;
TString period;
if ( CompactGraphs() )
{
- Compact(*g);
+ AliAnalysisMuMuGraphUtil::Compact(*g);
}
g->Draw("P");
AliAnalysisMuMu::ReadFileList(const char* filelist)
{
//
- // read the filelist and try to order it by runnumber
+ // read the filelist and try to order it by runnumber (or periods)
//
// filelist can either be a real filelist (i.e. a text file containing
// root filenames) or a root file itself.
return files;
}
- std::set<int> runnumbers;
- std::map<int,std::string> filemap;
+ std::set<std::string> sorting;
+ std::map<std::string,std::string> filemap;
std::ifstream in(sfilelist.Data());
while ( in.getline(line,1022,'\n') )
{
+ TString sline(line);
+ if (sline.BeginsWith("#")) continue;
+
DecodeFileName(line,period,esdpass,aodtrain,runnumber);
AliDebugClass(1,Form("line %s => period %s esdpass %d aodtrain %d runnumber %09d",
line,period.Data(),esdpass,aodtrain,runnumber));
- filemap.insert(std::make_pair<int,std::string>(runnumber,line));
- runnumbers.insert(runnumber);
+ TString key(Form("%d",runnumber));
+
+ if ( runnumber <= 0 )
+ {
+ key = period;
+ }
+ sorting.insert(key.Data());
+ filemap.insert(std::make_pair<std::string,std::string>(key.Data(),line));
}
in.close();
- std::set<int>::const_iterator it;
-
- for ( it = runnumbers.begin(); it != runnumbers.end(); ++it )
+ std::set<std::string>::const_iterator it;
+
+ for ( it = sorting.begin(); it != sorting.end(); ++it )
{
files->Add(new TObjString(filemap[*it].c_str()));
}
-
return files;
}
}
//_____________________________________________________________________________
-void AliAnalysisMuMu::SetNofInputParticles(AliAnalysisMuMuResult& r)
+void AliAnalysisMuMu::SetNofInputParticles(AliAnalysisMuMuJpsiResult& r)
{
/// Set the "NofInput" variable(s) of one result
{
/// update the current file with memory
+ if (!CC() || !MC()) return;
+
ReOpen(fFilename,"UPDATE");
- MC()->Write("MC",TObject::kSingleKey);
+ if (MC())
+ {
+ MC()->Write("MC",TObject::kSingleKey|TObject::kOverwrite);
+ }
ReOpen(fFilename,"READ");
+
+ GetCollections(fFilename,fMergeableCollection,fCounterCollection,fBinning,fRunNumbers);
}
//_____________________________________________________________________________
return kTRUE;
}
+//_____________________________________________________________________________
+void AliAnalysisMuMu::ComputeFnorm()
+{
+ /// Compute the CMUL to CINT ratio(s)
+
+ if (!CC()) return;
+
+ MC()->Prune("/FNORM");
+
+ AliAnalysisMuMuFnorm computer(*(CC()),AliAnalysisMuMuFnorm::kMUL,fgOCDBPath.Data(),fgIsCompactGraphs);
+
+ computer.ComputeFnorm();
+
+ AliMergeableCollection* fnorm = computer.DetachMC();
+
+ MC()->Attach(fnorm,"/FNORM/");
+
+ Update();
+}
+
//_____________________________________________________________________________
AliAnalysisMuMuSpectra* AliAnalysisMuMu::CorrectSpectra(const char* type, const char* flavour)
{
TIter nextBin(bins);
AliAnalysisMuMuBinning::Range* bin;
Int_t i(0);
- AliAnalysisMuMuResult* r;
+ AliAnalysisMuMuJpsiResult* r;
while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(nextBin()) ) )
{
- r = static_cast<AliAnalysisMuMuResult*>(realSpectra->Bins()->At(i));
+ r = static_cast<AliAnalysisMuMuJpsiResult*>(realSpectra->BinContentArray()->At(i));
StdoutToAliDebug(1,std::cout << "bin=";r->Print(););
- AliAnalysisMuMuResult* rsim = static_cast<AliAnalysisMuMuResult*>(simSpectra->Bins()->At(i));
+ AliAnalysisMuMuJpsiResult* rsim = static_cast<AliAnalysisMuMuJpsiResult*>(simSpectra->BinContentArray()->At(i));
Double_t mbeq = nofCINT7w0MUL / ( nofCINT7 * nofCMUL7);
Double_t mbeqError = mbeq * AliAnalysisMuMuResult::ErrorABC( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
nofCINT7,TMath::Sqrt(nofCINT7),
nofCMUL7,TMath::Sqrt(nofCMUL7));
- r->Set("MBR",nofCINT7/nofCINT7w0MUL,(nofCINT7/nofCINT7w0MUL)*AliAnalysisMuMuResult::ErrorAB( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
+ r->Set("Fnorm",nofCINT7/nofCINT7w0MUL,(nofCINT7/nofCINT7w0MUL)*AliAnalysisMuMuResult::ErrorAB( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
nofCINT7,TMath::Sqrt(nofCINT7)));
Double_t yield = r->GetValue("CorrNofJpsi") * mbeq;
return realSpectra;
}
-////_____________________________________________________________________________
-//AliAnalysisMuMuSpectra* AliAnalysisMuMu::ComputeYield(const char* realFile, const char* simFile,
-// const char* type)
-//{
-// const char* accEffSubResultName="COUNTJPSI-1";
-//
-// AliAnalysisMuMu real(realFile);
-// AliAnalysisMuMu sim(simFile);
-//
-//
-// AliAnalysisMuMuSpectra* realSpectra = static_cast<AliAnalysisMuMuSpectra*>(real.MC()->GetObject(Form("/PSALL/CMUL7-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-%s",type)));
-// AliAnalysisMuMuSpectra* simSpectra = static_cast<AliAnalysisMuMuSpectra*>(sim.MC()->GetObject(Form("/ALL/CMULLO-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-%s",type)));
-//
-// if ( !realSpectra )
-// {
-// AliErrorClass("could not get real spectra");
-// return 0x0;
-// }
-//
-// if ( !simSpectra)
-// {
-// AliErrorClass("could not get sim spectra");
-// return 0x0;
-// }
-//
-// AliAnalysisMuMuSpectra* corrSpectra = static_cast<AliAnalysisMuMuSpectra*>(realSpectra->Clone());
-// corrSpectra->Correct(*simSpectra,"Jpsi",accEffSubResultName);
-//
-// Double_t nofCMUL7 = real.CC()->GetSum(Form("trigger:CMUL7-B-NOPF-MUON/event:PSALL"));
-// Double_t nofCINT7 = real.CC()->GetSum(Form("trigger:CINT7-B-NOPF-ALLNOTRD/event:PSALL"));
-// Double_t nofCINT7w0MUL = real.CC()->GetSum(Form("trigger:CINT7-B-NOPF-ALLNOTRD&0MUL/event:PSALL"));
-//
-// AliAnalysisMuMuBinning* binning = corrSpectra->Binning();
-// TObjArray* bins = binning->CreateBinObjArray();
-// TIter nextBin(bins);
-// AliAnalysisMuMuBinning::Range* bin;
-// Int_t i(0);
-// AliAnalysisMuMuResult* r;
-//
-// while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(nextBin()) ) )
-// {
-// r = static_cast<AliAnalysisMuMuResult*>(corrSpectra->Bins()->At(i));
-//
-// AliAnalysisMuMuResult* rsim = static_cast<AliAnalysisMuMuResult*>(simSpectra->Bins()->At(i));
-//
-// Double_t mbeq = nofCINT7w0MUL / ( nofCINT7 * nofCMUL7);
-// Double_t mbeqError = mbeq * AliAnalysisMuMuResult::ErrorABC( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
-// nofCINT7,TMath::Sqrt(nofCINT7),
-// nofCMUL7,TMath::Sqrt(nofCMUL7));
-//
-// r->Set("MBR",nofCINT7/nofCINT7w0MUL,(nofCINT7/nofCINT7w0MUL)*AliAnalysisMuMuResult::ErrorAB( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
-// nofCINT7,TMath::Sqrt(nofCINT7)));
-//
-// Double_t yield = r->GetValue("CorrNofJpsi") * mbeq;
-//
-// Double_t yieldError = yield * AliAnalysisMuMuResult::ErrorAB( r->GetValue("CorrNofJpsi"), r->GetErrorStat("CorrNofJpsi"),
-// mbeq,mbeqError);
-//
-// r->Set("YJpsi",yield,yieldError);
-//
-// r->Set("NofInputJpsi",rsim->GetValue("NofInputJpsi",accEffSubResultName),rsim->GetErrorStat("NofInputJpsi",accEffSubResultName));
-// r->Set("AccEffJpsi",rsim->GetValue("AccEffJpsi",accEffSubResultName),rsim->GetErrorStat("AccEffJpsi",accEffSubResultName));
-//
-// ++i;
-// }
-//
-// delete bins;
-//
-// return corrSpectra;
-//}
-
//_____________________________________________________________________________
AliAnalysisMuMuSpectra* AliAnalysisMuMu::RABy(const char* realFile, const char* simFile, const char* type,
const char* direction)
TIter nextBin(bins);
AliAnalysisMuMuBinning::Range* bin;
Int_t i(0);
- AliAnalysisMuMuResult* r;
+ AliAnalysisMuMuJpsiResult* r;
Int_t n = bins->GetLast();
AliInfoClass(Form("y range : LAB %f ; %f CMS %f ; %f -> ynorm : %f ; %f -> BR x sigmapp = %f",
ylowlab,yhighlab,ylowcms,yhighcms,ylownorm,yhighnorm,brsigmapp));
- r = static_cast<AliAnalysisMuMuResult*>(corrSpectra->Bins()->At(i)->Clone());
+ r = static_cast<AliAnalysisMuMuJpsiResult*>(corrSpectra->BinContentArray()->At(i)->Clone());
- AliAnalysisMuMuResult* rsim = static_cast<AliAnalysisMuMuResult*>(simSpectra->Bins()->At(i));
+ AliAnalysisMuMuJpsiResult* rsim = static_cast<AliAnalysisMuMuJpsiResult*>(simSpectra->BinContentArray()->At(i));
Double_t mbeq = nofCINT7w0MUL / ( nofCINT7 * nofCMUL7);
Double_t mbeqError = mbeq * AliAnalysisMuMuResult::ErrorABC( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
nofCINT7,TMath::Sqrt(nofCINT7),
nofCMUL7,TMath::Sqrt(nofCMUL7));
- r->Set("MBR",nofCINT7/nofCINT7w0MUL,(nofCINT7/nofCINT7w0MUL)*AliAnalysisMuMuResult::ErrorAB( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
+ r->Set("Fnorm",nofCINT7/nofCINT7w0MUL,(nofCINT7/nofCINT7w0MUL)*AliAnalysisMuMuResult::ErrorAB( nofCINT7w0MUL, TMath::Sqrt(nofCINT7w0MUL),
nofCINT7,TMath::Sqrt(nofCINT7)));
Double_t yield = r->GetValue("CorrNofJpsi") * mbeq;
j = n-i;
}
- r = static_cast<AliAnalysisMuMuResult*>(finalResults.At(j));
+ r = static_cast<AliAnalysisMuMuJpsiResult*>(finalResults.At(j));
bin = static_cast<AliAnalysisMuMuBinning::Range*>(finalBins.At(j));
}
//_____________________________________________________________________________
-TGraph* AliAnalysisMuMu::ResultEvolution(const char* runlist, const char* period, const char* what, Bool_t forceRecomputation)
+void AliAnalysisMuMu::ComputeJpsi(const char* runlist, const char* prefix, const char* what, const char* binningFlavour)
+{
+ /// Call the Jpsi method for each file
+
+ std::vector<int> runs;
+ AliAnalysisTriggerScalers::ReadIntegers(runlist,runs);
+
+ for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i )
+ {
+ Int_t runNumber = runs[i];
+
+ TString filename(Form("RUNBYRUN/%s_%09d.saf.root",prefix,runNumber));
+
+ if ( gSystem->AccessPathName(filename.Data())==kTRUE ) continue;
+
+ AliAnalysisMuMu m(filename.Data());
+ m.Jpsi(what,binningFlavour);
+ }
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuSpectra*
+AliAnalysisMuMu::CombineSpectra(const char* runlist,
+ const char* realPrefix,
+ const char* simPrefix,
+ const char* quantity,
+ const char* variable,
+ const char* binningFlavour)
+{
+ std::vector<int> runs;
+ AliAnalysisTriggerScalers::ReadIntegers(runlist,runs);
+
+ std::vector<double> vw;
+ std::vector<AliAnalysisMuMuSpectra*> vspectra;
+
+ for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i )
+ {
+ Int_t runNumber = runs[i];
+
+ TString filename(Form("RUNBYRUN/%s_%09d.saf.root",realPrefix,runNumber));
+
+ AliAnalysisMuMu mreal(filename.Data());
+
+ std::cout << filename.Data() << std::flush << std::endl;
+
+ if ( !mreal.CC() || !mreal.MC() )
+ {
+ AliErrorClass(Form("Have to skip %s CC=%p MC=%p",filename.Data(),mreal.CC(),mreal.MC()));
+ continue;
+ }
+
+ TGraph* g = static_cast<TGraph*>(mreal.MC()->GetObject("/FNORM/GRAPHS/NMBeqBest2"));
+
+ if (!g)
+ {
+ mreal.ComputeFnorm();
+ g = static_cast<TGraph*>(mreal.MC()->GetObject("/FNORM/GRAPHS/NMBeqBest2"));
+ }
+
+ if (!g) continue;
+
+ if ( TMath::Nint(g->GetX()[0]) != runNumber )
+ {
+ AliErrorClass("Wrong run number in NMBeqBest2 graph !");
+ continue;
+ }
+
+ filename.Form("RUNBYRUN/%s_%09d.saf.root",simPrefix,runNumber);
+
+ AliAnalysisMuMu msim(filename.Data());
+
+ TString spectraName(Form("/ALL/CMULLO-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-%s",variable));
+ if (strlen(binningFlavour))
+ {
+ spectraName += "-";
+ spectraName += binningFlavour;
+ }
+
+ AliAnalysisMuMuSpectra* s = static_cast<AliAnalysisMuMuSpectra*>(msim.MC()->GetObject(spectraName.Data()));
+
+ if (!s)
+ {
+ msim.Jpsi(quantity,binningFlavour);
+
+ s = static_cast<AliAnalysisMuMuSpectra*>(msim.MC()->GetObject(spectraName.Data()));
+ }
+
+ if (!s)
+ {
+ AliErrorClass(Form("Could not find spectra for sim %s",filename.Data()));
+ continue;
+ }
+
+ vw.push_back(g->GetY()[0]);
+ vspectra.push_back(static_cast<AliAnalysisMuMuSpectra*>(s->Clone()));
+ }
+
+ Double_t sumw(0.0);
+
+ for ( std::vector<int>::size_type i = 0; i < vw.size(); ++i )
+ {
+ sumw += vw[i];
+ vspectra[i]->Print();
+ }
+
+ // normalize the weights
+ TList list;
+ list.SetOwner(kTRUE);
+
+ for ( std::vector<int>::size_type i = 0; i < vw.size(); ++i )
+ {
+ vw[i] /= sumw;
+
+ vspectra[i]->SetWeight(vw[i]);
+
+ if ( i > 0 ) list.Add(vspectra[i]);
+ }
+
+ std::cout << "before merging" << std::endl;
+ for ( std::vector<int>::size_type i = 0; i < vw.size(); ++i )
+ {
+ std::cout << " ---------------- " << i << std::endl;
+
+ vspectra[i]->Print();
+ }
+
+ vspectra[0]->Merge(&list);
+
+
+ return vspectra[0];
+}
+
+
+//_____________________________________________________________________________
+TGraph* AliAnalysisMuMu::ResultEvolution(const char* runlist, const char* realPrefix, const char* simPrefix, const char* what, Bool_t forceRecomputation)
{
std::vector<int> runs;
AliAnalysisTriggerScalers::ReadIntegers(runlist,runs);
TGraphErrors* g = new TGraphErrors(runs.size());
TString direction("Pbp");
+ TString check(realPrefix);
+ check.ToUpper();
- if (TString(period) == "LHC13b" ||
- TString(period) == "LHC13c" ||
- TString(period) == "LHC13d" ||
- TString(period) == "LHC13e"
+ if (check.Contains("LHC13B") ||
+ check.Contains("LHC13C") ||
+ check.Contains("LHC13D") ||
+ check.Contains("LHC13E")
)
{
direction = "pPb";
}
- AliInfoClass(Form("period %s direction %s",period,direction.Data()));
+ AliInfoClass(Form("direction %s",direction.Data()));
- Double_t weightedMean(0.0);
- Double_t sumOfWeights(0.0);
-
Double_t mean(0.0);
+ Double_t v1(0.0);
+
TString subResultName("");
+
TString swhat(what);
-
+
+ TObjArray* parts = swhat.Tokenize(":");
+
+ if ( parts->GetEntries() > 1 )
+ {
+ subResultName = static_cast<TObjString*>(parts->At(1))->String();
+ }
+
+ delete parts;
+
for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i )
{
Int_t runNumber = runs[i];
- AliInfoClass(Form("RUN %09d",runNumber));
+ AliDebugClass(1,Form("RUN %09d",runNumber));
- TString realFile(Form("RUNBYRUN/%s_muon_calo_AODMUON000_%09d.saf.root",period,runNumber));
+ TString realFile(Form("RUNBYRUN/%s_%09d.saf.root",realPrefix,runNumber));
- TString simFileName(Form("RUNBYRUN/SIM_JPSI_%s_pp503_newalign_%09d.saf.root",period,runNumber));
- if ( direction == "pPb" )
- {
- simFileName = Form("RUNBYRUN/SIM_JPSI_%s_pp503_%09d.saf.root",period,runNumber);
- }
-
+ TString simFileName(Form("RUNBYRUN/%s_%09d.saf.root",simPrefix,runNumber));
+
TString simFile(simFileName);
TString resultName(Form("%s%sJpsi",what,direction.Data()));
- if ( swhat == "MBR")
+ if ( swhat == "Fnorm")
{
- resultName = "MBR";
+ resultName = "Fnorm";
}
else if ( swhat.Contains("Acc") )
{
resultName.ReplaceAll(direction,"");
}
- AliAnalysisMuMu mreal(realFile);
+ AliAnalysisMuMu* mreal(0x0);
- AliAnalysisMuMuSpectra* real = static_cast<AliAnalysisMuMuSpectra*>(mreal.MC()->GetObject("/PSALL/CMUL7-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-"));
-
- if (!real || forceRecomputation)
+ if ( !swhat.Contains("Acc"))
+ {
+ mreal = new AliAnalysisMuMu(realFile);
+ }
+
+ AliAnalysisMuMuSpectra* real(0x0);
+
+ if ( mreal )
{
- mreal.Jpsi();
- real = static_cast<AliAnalysisMuMuSpectra*>(mreal.MC()->GetObject("/PSALL/CMUL7-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-"));
- if (!real)
+ real = static_cast<AliAnalysisMuMuSpectra*>(mreal->MC()->GetObject("/PSALL/CMUL7-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-INTEGRATED"));
+
+ if (!real || forceRecomputation)
{
- AliErrorClass(Form("Could not get real spectra for run %d",runNumber));
- return 0x0;
+ mreal->Jpsi();
+ real = static_cast<AliAnalysisMuMuSpectra*>(mreal->MC()->GetObject("/PSALL/CMUL7-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-INTEGRATED"));
+ if (!real)
+ {
+ AliErrorClass(Form("Could not get real spectra for run %d",runNumber));
+ delete mreal;
+ return 0x0;
+ }
}
}
AliAnalysisMuMu msim(simFile);
- AliAnalysisMuMuSpectra* sim = static_cast<AliAnalysisMuMuSpectra*>(msim.MC()->GetObject("/ALL/CMULLO-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-"));
+ AliAnalysisMuMuSpectra* sim = static_cast<AliAnalysisMuMuSpectra*>(msim.MC()->GetObject("/ALL/CMULLO-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-INTEGRATED"));
if (!sim || forceRecomputation)
{
msim.SetEventSelectionList("ALL");
msim.Jpsi();
- sim = static_cast<AliAnalysisMuMuSpectra*>(msim.MC()->GetObject("/ALL/CMULLO-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-"));
+ sim = static_cast<AliAnalysisMuMuSpectra*>(msim.MC()->GetObject("/ALL/CMULLO-B-NOPF-MUON/PP/pMATCHLOWRABSBOTH/PSI-INTEGRATED"));
if (!sim)
{
AliErrorClass(Form("Could not get sim spectra for run %d",runNumber));
+ delete mreal;
return 0x0;
}
}
- AliAnalysisMuMuSpectra* corrected = AliAnalysisMuMu::RABy(realFile.Data(),simFile.Data(),"",direction.Data());
+ AliAnalysisMuMuSpectra* corrected = 0x0;
+
+ if ( real )
+ {
+ corrected = AliAnalysisMuMu::RABy(realFile.Data(),simFile.Data(),"",direction.Data());
+ }
+ else
+ {
+ corrected = sim;
+ }
- AliAnalysisMuMuResult* result = static_cast<AliAnalysisMuMuResult*>(corrected->Bins()->First());
+ AliAnalysisMuMuResult* result = static_cast<AliAnalysisMuMuResult*>(corrected->BinContentArray()->First());
- result->Print();
+// result->Print();
- Double_t value = result->GetValue(resultName.Data());
- Double_t error = result->GetErrorStat(resultName.Data());
+ Double_t value = result->GetValue(resultName.Data(),subResultName.Data());
+ Double_t error = result->GetErrorStat(resultName.Data(),subResultName.Data());
g->SetPoint(i,runNumber,value);
g->SetPointError(i,1,error);
- Double_t n = mreal.CC()->GetSum(Form("trigger:CMUL7-B-NOPF-MUON/event:PSALL/run:%d",runNumber));
+ Double_t n = 1.0;
- weightedMean += n*result->GetValue(resultName.Data());
- sumOfWeights += n;
+ if ( mreal )
+ {
+ n = mreal->CC()->GetSum(Form("trigger:CMUL7-B-NOPF-MUON/event:PSALL/run:%d",runNumber));
+ }
+
+ Double_t w(0.0);
+ if ( error > 0 ) w = 1.0/error/error;
- mean += result->GetValue(resultName.Data());
+ mean += value*w;
+ v1 += w;
// std::cout << result->SubResults() << " " << result->GetError(resultName.Data()) << std::endl;
+ delete mreal;
}
gStyle->SetOptFit(1);
{
g->GetYaxis()->SetTitle("Acc#timesEff_{J/#psi}");
}
- else if ( TString(what).Contains("MBR") )
+ else if ( TString(what).Contains("Fnorm") )
{
g->GetYaxis()->SetTitle("CINT7 / CINT7&0MUL");
}
if (CompactGraphs())
{
- Compact(*g);
+ AliAnalysisMuMuGraphUtil::Compact(*g);
}
- mean /= runs.size();
- weightedMean /= sumOfWeights;
-
- AliInfoClass(Form("Mean %e Weighted Mean %e",mean,weightedMean));
-
- return g;
-}
-
-//______________________________________________________________________________
-void AliAnalysisMuMu::GetMBR(Int_t runNumber, const char* eventSelection, Double_t& value, Double_t& error) const
-{
- // Get the scaling factor to go from CMUL to CINT7 for a given event selection
- value = 0.0;
- error = 0.0;
- if ( strlen(eventSelection) > 0 )
- {
- ULong64_t a = TMath::Nint(fCounterCollection->GetSum(Form("trigger:CINT7-B-NOPF-ALLNOTRD/event:%s/run:%d",
- eventSelection,runNumber)));
-
- ULong64_t b = TMath::Nint(fCounterCollection->GetSum(Form("trigger:CINT7-B-NOPF-ALLNOTRD&0MUL/event:%s/run:%d",
- eventSelection,runNumber)));
-
- value = b > 0 ? a/b : 0;
- error = value*AliAnalysisMuMuResult::ErrorAB(a,TMath::Sqrt(a),b,TMath::Sqrt(b));
- }
-}
-
-//______________________________________________________________________________
-TGraph* AliAnalysisMuMu::MBREvolution(const char* eventSelection1, const char* eventSelection2) const
-{
- if (!fCounterCollection) return 0x0;
-
- TObjArray* runs = fCounterCollection->GetKeyWords("run").Tokenize(",");
- runs->Sort();
- TIter nextRun(runs);
- TObjString* srun;
-
- std::set<int> runnumbers;
-
- TGraphErrors* g = new TGraphErrors(runs->GetEntries());
- Int_t i(0);
-
- while ( ( srun = static_cast<TObjString*>(nextRun()) ) )
- {
- Int_t runNumber = srun->String().Atoi();
-
- runnumbers.insert(runNumber);
-
- Double_t mbr1,mbrError1;
- Double_t mbr2,mbrError2;
-
- GetMBR(runNumber,eventSelection1,mbr1,mbrError1);
-
- GetMBR(runNumber,eventSelection2,mbr2,mbrError2);
-
- Double_t mbr = mbr1;
-
- if ( mbr2 > 0 ) mbr /= mbr2;
-
- Double_t mbrError = mbr*AliAnalysisMuMuResult::ErrorAB(mbr1,mbrError1,mbr2,mbrError2);
-
- g->SetPoint(i,runNumber,mbr);
- g->SetPointError(i,0.5,mbrError);
-
- ++i;
- }
+ mean /= v1;
- g->GetXaxis()->SetNoExponent();
+ AliInfoClass(Form("Weighted Mean %e",mean));
- AliAnalysisTriggerScalers ts(RunNumbers(),fgOCDBPath.Data());
- ts.DrawFills(0,1000);
-
return g;
}
-
-
-
#include "RQ_OBJECT.h"
class AliAnalysisMuMuResult;
+class AliAnalysisMuMuJpsiResult;
class AliAnalysisMuMuSpectra;
class AliCounterCollection;
class AliMergeableCollection;
class TF1;
class TFile;
class TGraph;
+class TGraphErrors;
class TH1;
class TMap;
AliAnalysisMuMuSpectra* CorrectSpectra(const char* type, const char* flavour="");
- AliAnalysisMuMuSpectra* ComputeYield(const char* type, const char* flavour="");
+ void ComputeFnorm();
+
+ void TwikiOutputFnorm(const char* series="FnormOffline2PUPS,FnormScalersPUPS,FnormBest2,RelDifFnormScalersPUPSvsFnormOffline2PUPS") const;
+
+ static void FigureOutputFnorm(const char* filelist);
+ static void LatexOutputFnorm(const char* filelist, const char* subresultnames="FnormOffline2PUPS,FnormScalersPUPS,FnormBest2,RelDifFnormScalersPUPSvsFnormOffline2PUPS", Bool_t rms=kFALSE);
+
+ AliAnalysisMuMuSpectra* ComputeYield(const char* type, const char* flavour="");
+
void CleanAllSpectra();
///------
static AliAnalysisMuMuSpectra* RABy(const char* realFile="ds.list.saf.root", const char* simFile="ds.sim.list.saf.root", const char* type="", const char* direction="pPb");
- static TGraph* ResultEvolution(const char* runlist, const char* period="LHC13f", const char* what="Y",
+ static TGraph* ResultEvolution(const char* runlist,
+ const char* realPrefix="LHC13f_muon_calo_AODMUON127",
+ const char* simPrefix="SIM_JPSI_LHC13f_CynthiaTuneWithRejectList",
+ const char* what="Y",
Bool_t forceRecomputation=kFALSE);
+ static void ComputeJpsi(const char* runlist, const char* prefix="SIM_JPSI_LHC13f_CynthiaTuneWithRejectList", const char* what="integrated", const char* binningFlavour="");
+
+ static AliAnalysisMuMuSpectra* CombineSpectra(const char* runlist,
+ const char* realPrefix="LHC13f_muon_calo_AODMUON127",
+ const char* simPrefix="SIM_JPSI_LHC13f_CynthiaTuneWithRejectList",
+ const char* quantity="AccEff",
+ const char* variable="INTEGRATED",
+ const char* binningFlavour="");
///-------
TGraph* PlotEventSelectionEvolution(const char* trigger1="CINT7-B-NOPF-MUON", const char* event1="PSALL",
static Bool_t CompactGraphs() { return fgIsCompactGraphs; }
- static void Compact(TGraph& g);
-
void Print(Option_t* opt="") const;
- void GetMBR(Int_t runNumber, const char* eventSelection, Double_t& value, Double_t& error) const;
-
- TGraph* MBREvolution(const char* eventSelection1="PSALLNOTZEROPILEUP", const char* eventSelection2="PSALL") const;
-
const std::set<int>& RunNumbers() const { return fRunNumbers; }
void DrawMinv(const char* type,
private:
- void SetNofInputParticles(AliAnalysisMuMuResult& r);
+ void SetNofInputParticles(AliAnalysisMuMuJpsiResult& r);
static TString ExpandPathName(const char* file);
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+///
+/// AliAnalysisMuMuFnorm : class to encapsulate computation(s)
+/// of the normalisation factor used to get the equivalent
+/// number of MB events from the number of CMUL triggers
+///
+/// The computed objects are stored within a AliMergeableCollection
+/// with 3 subdirectories, dependinf on their type
+///
+/// /GRAPHS/
+/// /RESULTS/
+/// /HISTOS/
+///
+/// author: Laurent Aphecetche (Subatech)
+
+#include "AliAnalysisMuMuFnorm.h"
+
+#include "AliAnalysisMuMuGraphUtil.h"
+#include "AliAnalysisMuMuResult.h"
+#include "AliAnalysisTriggerScalers.h"
+#include "AliCounterCollection.h"
+#include "AliLog.h"
+#include "AliMergeableCollection.h"
+#include "Riostream.h"
+#include "TAxis.h"
+#include "TCanvas.h"
+#include "TGraphErrors.h"
+#include "TH1F.h"
+#include "TList.h"
+#include "TMap.h"
+#include "TMath.h"
+#include "TObjArray.h"
+#include "TObjString.h"
+#include "TPaveText.h"
+#include "TStyle.h"
+#include <cassert>
+#include <numeric>
+
+ClassImp(AliAnalysisMuMuFnorm)
+
+//_____________________________________________________________________________
+AliAnalysisMuMuFnorm::AliAnalysisMuMuFnorm(AliCounterCollection& cc,
+ AliAnalysisMuMuFnorm::ETriggerType refTriggerType,
+ const char* ocdbpath,
+ Bool_t compactGraphs) :
+TObject(),
+fCounterCollection(cc),
+fMergeableCollection(0x0),
+fIsOwner(kTRUE),
+fOCDBPath(ocdbpath),
+fIsCompactGraphs(compactGraphs),
+fReferenceTriggerType(refTriggerType)
+{
+ // ctor
+
+
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuFnorm::~AliAnalysisMuMuFnorm()
+{
+ // dtor
+ if ( fIsOwner )
+ {
+ delete fMergeableCollection;
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeFnorm()
+{
+ /// Compute the CMUL to CINT ratio(s)
+ ///
+ /// Using offline method
+ /// - in one go CINT/CMUL
+ /// - in two steps CINT/CMSL and CMSL/CMUL
+ ///
+ /// Using scaler method
+ /// - bare scaler values
+ /// - scaler values corrected for pile-up
+ /// - scaler values corrected for pile-up and physics selection
+
+ const ETriggerType triggerTypes[] = { kMB, kMUL, kMSL, kMSH };
+ const Bool_t trueFalse[] = { kTRUE, kFALSE };
+
+ for ( Int_t i = 0; i < 4; ++i )
+ {
+ for ( Int_t pileup = 0; pileup < 2; ++pileup )
+ {
+ for ( Int_t ps = 0; ps < 2; ++ps )
+ {
+ ComputeNofEvents(triggerTypes[i],trueFalse[pileup],ps);
+ }
+ }
+ }
+
+ ComputeFnormOffline(1,kFALSE,0);
+ ComputeFnormOffline(1,kFALSE,1);
+ ComputeFnormOffline(1,kTRUE,1);
+
+ ComputeFnormOffline(2,kFALSE,0);
+ ComputeFnormOffline(2,kFALSE,1);
+ ComputeFnormOffline(2,kTRUE,1);
+
+// ComputeFnormOffline(2,kFALSE,2);
+// ComputeFnormOffline(2,kTRUE,2);
+
+ ComputeFnormScalers(kFALSE,0);
+ ComputeFnormScalers(kTRUE,0);
+ ComputeFnormScalers(kTRUE,1);
+// ComputeFnormScalers(kTRUE,2);
+
+ WeightedMeanGraphs("Offline");
+ WeightedMeanGraphs("Scalers");
+ WeightedMeanGraphs("FnormOffline2PUPS,FnormOffline1PUPS","FnormOffline12PUPS");
+
+ WeightedMeanGraphs("FnormOffline2PUPS,FnormScalersPUPS","FnormBest2");
+
+ ComputeGraphRelDif("FnormOffline2PUPS","FnormScalersPUPS");
+
+ ComputeGraphRelDif("FnormOffline2PUPS","FnormOffline2");
+ ComputeGraphRelDif("FnormOffline2PUPS","FnormOffline2PS");
+
+ ComputeGraphRelDif("CorrectionPSMB","CorrectionPSMUL");
+
+// for ( Int_t i = 0; i < 4; ++i )
+/// {
+ TString triggerEvents;
+
+// triggerEvents.Form("NofEvent%sPUPS",GetTriggerTypeName(triggerTypes[i]).Data());
+ triggerEvents.Form("NofEvent%sPUPS",GetTriggerTypeName(fReferenceTriggerType).Data());
+
+ MultiplyGraphs(triggerEvents.Data(),"FnormBest2","NMBeqBest2");
+
+ MultiplyGraphs(triggerEvents.Data(),"FnormOffline2PUPS","NMBeqOffline2PUPS");
+ MultiplyGraphs(triggerEvents.Data(),"FnormScalersPUPS","NMBeqScalersPUPS");
+// }
+
+// MultiplyGraphs(Form("NofEvent%sPUTS",GetTriggerTypeName(fReferenceTriggerType).Data()),"FnormOffline2PUTS","NMBeqOffline2PUTS");
+// MultiplyGraphs(Form("NofEvent%sPUTS",GetTriggerTypeName(fReferenceTriggerType).Data()),"FnormOffline2TS","NMBeqOffline2TS");
+
+ ComputeResultsFromGraphs();
+
+ AliAnalysisMuMuResult* result = GetResult("Fnorm");
+ if (result)
+ {
+ result->Exclude("*");
+ result->Include("FnormBest2");
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeCorrectionFactors(Int_t eventSelectionCorrected)
+{
+ /// Compute individual graphs for the correction factors (PS_CMUL, PS_CINT,
+ /// F_pile-up,PS_CINT/PS_CMUL) used in the computation of (some) Fnorm factors
+ ///
+
+ TString graphName(Form("CorrectionGlobal%s",GetEventSelectionName(eventSelectionCorrected).Data()));;
+
+ if ( GetGraph(graphName) )
+ {
+ // insure we compute it only once
+ return;
+ }
+
+ AliDebug(2,"");
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ std::vector<double> vyGlobal;
+ std::vector<double> vyGlobalErr;
+
+ const ETriggerType triggerTypes[] = { kMB, kMUL, kMSL, kMSH };
+
+ for ( Int_t i = 0; i < 4; ++i )
+ {
+ ComputeEventSelectionGraph(triggerTypes[i],eventSelectionCorrected);
+ ComputePileUpGraph(triggerTypes[i],eventSelectionCorrected);
+ }
+
+ TGraphErrors* gPSCINT = GetGraph(Form("Correction%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(AliAnalysisMuMuFnorm::kMB).Data()));
+
+ TGraphErrors* gPSCMUL = GetGraph(Form("Correction%s%s", GetEventSelectionName(eventSelectionCorrected).Data(), GetTriggerTypeName(AliAnalysisMuMuFnorm::kMUL).Data()));
+
+ TGraphErrors* gPU = GetGraph(Form("CorrectionPU%s%s",GetEventSelectionName(eventSelectionCorrected).Data(), GetTriggerTypeName(AliAnalysisMuMuFnorm::kMB).Data()));
+
+ if ( !gPSCINT || !gPSCMUL || !gPU )
+ {
+ AliError("Did not get the relevant graphs. Cannot work");
+ return;
+ }
+
+ for ( Int_t i = 0; i < gPSCINT->GetN(); ++i )
+ {
+ Double_t x,y,yerr,yGlobal,yGlobalErr;
+
+ gPSCINT->GetPoint(i,x,y);
+
+ if ( fIsCompactGraphs )
+ {
+ x = TString(gPSCINT->GetXaxis()->GetBinLabel(i)).Atoi();
+ }
+
+ yGlobal = gPSCINT->GetY()[i] * gPU->GetY()[i] / gPSCMUL->GetY()[i];
+
+ yGlobalErr = yGlobal*AliAnalysisMuMuResult::ErrorABC(gPSCINT->GetY()[i],gPSCINT->GetEY()[i],
+ gPSCMUL->GetY()[i],gPSCMUL->GetEY()[i],
+ gPU->GetY()[i],gPU->GetEY()[i]);
+
+ y = gPSCINT->GetY()[i] / gPSCMUL->GetY()[i];
+ yerr = y * AliAnalysisMuMuResult::ErrorAB(gPSCINT->GetY()[i],gPSCINT->GetEY()[i],
+ gPSCMUL->GetY()[i],gPSCMUL->GetEY()[i]);
+
+ vx.push_back(x);
+ vxerr.push_back(gPSCINT->GetEX()[i]);
+
+ vyGlobal.push_back(yGlobal);
+ vyGlobalErr.push_back(yGlobalErr);
+
+ vy.push_back(y);
+ vyerr.push_back(yerr);
+ }
+
+ TString name(Form("Correction%sRatio",GetEventSelectionName(eventSelectionCorrected).Data()));
+ TString title(Form("%s_MB/%s_%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(fReferenceTriggerType).Data(),
+ GetEventSelectionName(eventSelectionCorrected).Data()));
+
+ CreateAndAddGraph(name,title,vx,vxerr,vy,vyerr);
+
+ title = TString::Format("%s_MB x Fpile-up / %s_%s ",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(fReferenceTriggerType).Data(),GetEventSelectionName(eventSelectionCorrected).Data());
+
+ CreateAndAddGraph(graphName,title,vx,vxerr,vyGlobal,vyGlobalErr);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeFnormOffline(Int_t nstep, Bool_t pileUpCorrected, Int_t eventSelectionCorrected)
+{
+ /// Compute MB to CMUL ratio using offline method, either in 1 or 2 steps
+
+ TString name("FnormOffline");
+ TString title("Computed using offline information");
+
+ if (nstep==1)
+ {
+ name += "1";
+ title += " in one step (CINT/CINT&0MUL)";
+ }
+ else
+ {
+ name += "2";
+ title += " in two steps (CMSL/CMSL&0MUL x CINT/CINT&MSL)";
+ }
+
+ if (pileUpCorrected)
+ {
+ name += "PU";
+ title += " with pile-up correction";
+ }
+ if (eventSelectionCorrected==1)
+ {
+ name += "PS";
+ title += " with (ps) purity corrections";
+ }
+ else if ( eventSelectionCorrected==2 )
+ {
+ name += "TS";
+ title += " with (ts) purity corrections";
+ }
+
+ if ( GetGraph(name) )
+ {
+ // insure we're computing it only once
+ return;
+ }
+
+ AliDebug(2,name);
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ const std::set<int>& runs = RunNumbers();
+
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ TString mbTrigger = GetTriggerClassName(kMB,runNumber);
+ TString muonTrigger = GetTriggerClassName(kMSL,runNumber);
+ TString dimuonTrigger = GetTriggerClassName(kMUL,runNumber);
+
+ if (!mbTrigger.Length())
+ {
+ AliError(Form("Cannot get MB trigger for run %d",runNumber));
+ continue;
+ }
+
+ Double_t nofMB = GetSum(mbTrigger.Data(),runNumber,eventSelectionCorrected);
+ Double_t nofMSL(0.0);
+ Double_t nofMSLw0MUL(0.0);
+
+ if ( nstep==2 )
+ {
+ nofMSL = GetSum(muonTrigger.Data(),runNumber,eventSelectionCorrected);
+ nofMSLw0MUL = GetSum(Form("%s&0MUL",muonTrigger.Data()),runNumber,eventSelectionCorrected);
+ }
+
+ Double_t nofMBw0MUL = GetSum(Form("%s&0MUL",mbTrigger.Data()),runNumber,eventSelectionCorrected);
+ Double_t nofMBw0MSL = GetSum(Form("%s&0MSL",mbTrigger.Data()),runNumber,eventSelectionCorrected);
+
+ if ( !nofMBw0MUL ) continue;
+ if ( !nofMBw0MSL && nstep == 2 ) continue;
+
+ Double_t purityMB(1.0);
+ Double_t purityMBerror(0.0);
+
+ if ( eventSelectionCorrected > 0 )
+ {
+ ComputeEventSelectionGraph(kMB,eventSelectionCorrected);
+
+ TGraphErrors* gps = GetGraph(Form("Correction%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(kMB).Data()));
+
+ GetValueAndErrorFromGraph(gps,runNumber,purityMB,purityMBerror);
+ }
+
+ Double_t pileUpFactor(1.0);
+ Double_t pileUpFactorError(0.0);
+
+ if (pileUpCorrected)
+ {
+ ComputePileUpGraph(kMB,eventSelectionCorrected);
+
+ TGraphErrors* gpu = GetGraph(Form("CorrectionPU%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(kMB).Data()));
+
+ GetValueAndErrorFromGraph(gpu,runNumber,pileUpFactor,pileUpFactorError);
+
+ nofMB *= pileUpFactor;
+ }
+
+ double value = nofMBw0MUL > 0.0 ? nofMB/nofMBw0MUL : 0.0;
+ double error = value*AliAnalysisMuMuResult::ErrorABC(nofMB,TMath::Sqrt(nofMB),
+ nofMBw0MUL,TMath::Sqrt(nofMBw0MUL),
+ pileUpFactor,pileUpFactorError);
+
+ if ( nstep == 2 )
+ {
+ value = (nofMB/nofMSLw0MUL)*(nofMSL/nofMBw0MSL);
+
+ if ( runNumber == 196310 )
+ {
+ AliDebug(1,Form("RUN %09d %d-%d-%d value=%e nofMB %e nofMSLw0MUL %e nofMSL %e nofMBw0MSL %e",
+ runNumber,nstep,pileUpCorrected,eventSelectionCorrected,
+ value,nofMB,nofMSLw0MUL,nofMSL,nofMBw0MSL));
+ }
+
+ error = value*AliAnalysisMuMuResult::ErrorABCD(nofMB,TMath::Sqrt(nofMB),
+ nofMSLw0MUL,TMath::Sqrt(nofMSLw0MUL),
+ nofMSL,TMath::Sqrt(nofMSL),
+ nofMBw0MSL,TMath::Sqrt(nofMBw0MSL));
+ }
+
+ if ( value > 0.0 )
+ {
+ vx.push_back(1.0*runNumber);
+ vxerr.push_back(0.5);
+ vy.push_back(value);
+ vyerr.push_back(error);
+ }
+ }
+
+
+ CreateAndAddGraph(name,title,vx,vxerr,vy,vyerr);
+}
+
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeFnormScalers(Bool_t pileUpCorrected,
+ Int_t eventSelectionCorrected)
+{
+ /// Compute the MB to CMUL ratio using the scalers method (from OCDB)
+ ///
+ /// i.e. Fnorm = L0B(MB) x PS(MB) x Fpile-up / ( L0B(REF) x PS(REF) )
+ ///
+ /// where MB is the minbias trigger
+ /// REF is the fReferenceTrigger
+ /// and PS is the fraction of events selected by the physics selection
+ ///
+ /// The correction factor (the two PS and one Fpile-up) are
+ /// taken from graphs computed in other methods
+ ///
+
+ TString name("FnormScalers");
+ TString title("Computed using OCDB scalers");
+
+ if (pileUpCorrected)
+ {
+ name += "PU";
+ title += " with pile-up correction";
+ }
+ if (eventSelectionCorrected==1)
+ {
+ name += "PS";
+ title += " with (ps) purity corrections";
+ }
+ if (eventSelectionCorrected==2)
+ {
+ name += "TS";
+ title += " with (ts) purity corrections";
+ }
+
+ if ( GetGraph(name) )
+ {
+ // insure we're computing it only once
+ return;
+ }
+
+ AliDebug(2,name);
+
+ // insure we have all the graphs we need to work
+ ComputeTriggerL0B(kMB);
+ ComputeTriggerL0B(fReferenceTriggerType);
+
+ const std::set<int>& runs = RunNumbers();
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ Double_t purityREF(1.0);
+ Double_t purityMB(1.0);
+ Double_t purityREFerror(00);
+ Double_t purityMBerror(0.0);
+
+ // compute the per run values
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ TString mbTrigger = GetTriggerClassName(kMB,runNumber);
+ TString refTrigger = GetTriggerClassName(fReferenceTriggerType,runNumber);
+
+ purityMB=purityREF=1.0;
+ purityMBerror=purityREFerror=0.0;
+
+ if (eventSelectionCorrected>0)
+ {
+ ComputeEventSelectionGraph(kMB,eventSelectionCorrected);
+ ComputeEventSelectionGraph(fReferenceTriggerType,eventSelectionCorrected);
+
+ TGraphErrors* gpsMB = GetGraph(Form("Correction%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(kMB).Data()));
+ TGraphErrors* gpsREF = GetGraph(Form("Correction%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(fReferenceTriggerType).Data()));
+
+ GetValueAndErrorFromGraph(gpsMB,runNumber,purityMB,purityMBerror);
+ GetValueAndErrorFromGraph(gpsREF,runNumber,purityREF,purityREFerror);
+ }
+
+ if (purityMB<=0.0)
+ {
+ AliError(Form("Got purity=%e for MB for run %9d",purityMB,runNumber));
+ continue;
+ }
+
+ TGraphErrors* gl0bMB = GetGraph(Form("L0B%s",GetTriggerTypeName(kMB).Data()));
+ TGraphErrors* gl0bREF = GetGraph(Form("L0B%s",GetTriggerTypeName(fReferenceTriggerType).Data()));
+
+ Double_t L0bMB,L0bMBError;
+ Double_t L0bREF,L0bREFError;
+
+ GetValueAndErrorFromGraph(gl0bMB,runNumber,L0bMB,L0bMBError);
+ GetValueAndErrorFromGraph(gl0bREF,runNumber,L0bREF,L0bREFError);
+
+ Double_t pileUpFactor(1.0);
+ Double_t pileUpFactorError(0.0);
+
+ if (pileUpCorrected)
+ {
+ TGraphErrors* gpu = GetGraph((Form("CorrectionPU%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(kMB).Data())));
+
+ GetValueAndErrorFromGraph(gpu,runNumber,pileUpFactor,pileUpFactorError);
+ }
+
+ Double_t value;
+ Double_t error;
+
+ ScalerFnorm(value,error,
+ L0bREF,purityREF,purityREFerror,
+ L0bMB,purityMB,purityMBerror,
+ pileUpFactor,pileUpFactorError);
+
+ if ( value > 0.0 )
+ {
+ vx.push_back(1.0*runNumber);
+ vxerr.push_back(0.5);
+ vy.push_back(value);
+ vyerr.push_back(error);
+ }
+ }
+
+ CreateAndAddGraph(name,title,vx,vxerr,vy,vyerr);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeGraphRelDif(const char* a, const char* b) const
+{
+ // compute dispersion of b versus a
+ //
+ // computed differences graphs are put into the GRAPHS/ directory
+ // computed differences results are put into the HISTOS/ directory
+
+ TString name(Form("RelDif%svs%s",b,a));
+
+ if ( GetGraph(name) )
+ {
+ // insure we compute it only once
+ return;
+ }
+
+ AliDebug(2,name);
+
+ TGraphErrors* ga = static_cast<TGraphErrors*>(MC()->GetObject(Form("/GRAPHS/%s",a)));
+ TGraphErrors* gb = static_cast<TGraphErrors*>(MC()->GetObject(Form("/GRAPHS/%s",b)));
+
+ if (!ga)
+ {
+ AliError(Form("Cannot get graph for %s",a));
+ return;
+ }
+
+ if (!gb)
+ {
+ AliError(Form("Cannot get graph for %s",b));
+ return;
+ }
+
+ if ( ga->GetN() != gb->GetN() )
+ {
+ AliError(Form("Cannot work with different number of points in the graphs : %d vs %d",
+ ga->GetN(),gb->GetN()));
+ return;
+ }
+
+ TString title(Form("%s-%s (RelDif,%%)",b,a));
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ for ( Int_t i = 0; i < ga->GetN(); ++i )
+ {
+ Double_t xa,xb,ya,yb;
+
+ ga->GetPoint(i,xa,ya);
+ gb->GetPoint(i,xb,yb);
+
+ if ( xa != xb )
+ {
+ AliError(Form("Incompatible graphs : got xa=%e and xb=%e",xa,xb));
+ return;
+ }
+
+ Double_t newvalue = 0.0;
+
+ if ( TMath::Abs(xa) > 1E-12 )
+ {
+ newvalue = 100.0*( yb - ya ) / ya;
+ }
+
+ Double_t yerr = newvalue*AliAnalysisMuMuResult::ErrorAB(ya,ga->GetEY()[i],
+ yb,gb->GetEY()[i]);
+
+ if ( fIsCompactGraphs )
+ {
+ xa = TString(ga->GetXaxis()->GetBinLabel(i+1)).Atoi()*1.0;
+ }
+
+ vx.push_back(xa);
+ vxerr.push_back(0.5);
+ vy.push_back(newvalue);
+ vyerr.push_back(yerr);
+
+ }
+
+ CreateAndAddGraph(name,title,vx,vxerr,vy,vyerr);
+
+ // FIXME : fill here an histogram from the graph to get the
+ // weight of 1/e2 ?
+ // h->Fill(newvalue,1.0/(yerr*yerr));
+ // MC()->Adopt("/HISTOS/",h);
+
+ // AliAnalysisMuMuResult* r = GetRunIntegratedResult(*g,"FnormDispersion");
+ // if (r)
+ // {
+ // if (!dispersion)
+ // {
+ // dispersion = new AliAnalysisMuMuResult("FnormDispersion");
+ // }
+ // dispersion->AdoptSubResult(r);
+ // if ( !TString(g->GetName()).BeginsWith("Fnorm") )
+ // {
+ // dispersion->Exclude(r->Alias());
+ // }
+ // }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputePileUpGraph(ETriggerType tt, Int_t eventSelectionCorrected)
+{
+ /// Compute the per-run graph of pile-up factor
+
+ TString graphName(Form("CorrectionPU%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(tt).Data()));
+
+ if ( GetGraph(graphName) )
+ {
+ // insure we're computing it only once
+ return;
+ }
+
+ AliDebug(2,graphName);
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ const std::set<int>& runs = RunNumbers();
+
+ AliAnalysisTriggerScalers ts(runs,OCDBPath().Data());
+
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ Double_t pileUpFactor(1.0);
+ Double_t pileUpFactorError(0.0);
+ Double_t purity(1.0);
+ Double_t purityError(0.0);
+
+ TString triggerClassName = GetTriggerClassName(tt,runNumber);
+
+ if ( triggerClassName.Length()==0 )
+ {
+ AliError(Form("Unknown trigger type %d",tt));
+ return;
+ }
+
+ if (eventSelectionCorrected)
+ {
+ GetPurity(triggerClassName.Data(),runNumber,purity,purityError,eventSelectionCorrected);
+ }
+ ts.GetPileUpFactor(runNumber,triggerClassName.Data(),purity,pileUpFactor,pileUpFactorError);
+
+ vx.push_back(runNumber);
+ vxerr.push_back(0.5);
+ vy.push_back(pileUpFactor);
+ vyerr.push_back(pileUpFactorError);
+ }
+
+ TString title(Form("Pile-up correction factor for trigger %s",GetTriggerTypeName(tt).Data()));
+
+ if (eventSelectionCorrected)
+ {
+ title += "( L0BRate corrected by event selection";
+ title += GetEventSelectionName(eventSelectionCorrected);
+ title += " accept fraction)";
+ }
+
+ CreateAndAddGraph(graphName,title,vx,vxerr,vy,vyerr);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeEventSelectionGraph(ETriggerType tt, Int_t eventSelectionCorrected)
+{
+ /// Compute the per-run graph of physics selection accept fraction
+ /// for the given trigger
+
+ TString graphName(Form("Correction%s%s",GetEventSelectionName(eventSelectionCorrected).Data(), GetTriggerTypeName(tt).Data()));
+
+ if (GetGraph(graphName))
+ {
+ // insure we're computing it only once
+ return;
+ }
+
+ AliDebug(2,graphName);
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ const std::set<int>& runs = RunNumbers();
+
+ AliAnalysisTriggerScalers ts(runs,OCDBPath().Data());
+
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ Double_t purity, purityError;
+
+ TString triggerClassName = GetTriggerClassName(tt,runNumber);
+
+ if ( triggerClassName.Length()==0 )
+ {
+ AliError(Form("Unknown trigger type %d",tt));
+ return;
+ }
+
+ GetPurity(triggerClassName.Data(),runNumber,purity,purityError,eventSelectionCorrected);
+
+ vx.push_back(runNumber);
+ vxerr.push_back(0.5);
+ vy.push_back(purity);
+ vyerr.push_back(purityError);
+ }
+
+ TString title(Form("Fraction of events accepted by the event selection %s for trigger %s",GetTriggerTypeName(tt).Data(),
+ GetEventSelectionName(eventSelectionCorrected).Data()));
+
+ CreateAndAddGraph(graphName,title,vx,vxerr,vy,vyerr);
+}
+
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeResultsFromGraphs()
+{
+ // Compute one single value for each graph, by weighting by the fraction
+ // of events in each run
+ // do this for certain groups of graphs
+
+ TObjArray groups;
+ groups.SetOwner(kTRUE);
+
+ groups.Add(new TObjString("Fnorm"));
+ groups.Add(new TObjString("NMBeq"));
+ groups.Add(new TObjString("Correction"));
+ groups.Add(new TObjString("RelDif"));
+
+ TList* objectList = MC()->CreateListOfObjectNames("/GRAPHS/");
+
+ TIter nextGroup(&groups);
+ TObjString* grp;
+
+ TIter next(objectList);
+ TObjString* str(0x0);
+
+ while ( ( grp = static_cast<TObjString*>(nextGroup()) ) )
+ {
+ TString oname(Form("/RESULTS/%s",grp->String().Data()));
+
+ if ( MC()->GetObject(oname) )
+ {
+ // delete if we have it already so we can replace it
+ MC()->Remove(oname);
+ }
+
+ AliAnalysisMuMuResult* result = new AliAnalysisMuMuResult(grp->String());
+
+ MC()->Adopt("/RESULTS/",result);
+
+ next.Reset();
+
+ while ( ( str = static_cast<TObjString*>(next()) ) )
+ {
+ if ( ! ( str->String().BeginsWith(grp->String() ) ) ) continue;
+
+ TGraphErrors* g = GetGraph(str->String());
+
+ if (!g) continue;
+
+ AliAnalysisMuMuResult* sub = GetRunIntegratedResult(*g);
+
+ if ( !sub )
+ {
+ AliError(Form("Could not get result for graph %s",g->GetName()));
+ }
+ if ( sub )
+ {
+ result->AdoptSubResult(sub);
+ }
+ }
+ }
+
+ delete objectList;
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeNofEvents(ETriggerType triggerType,
+ Bool_t pileUpCorrected,
+ Int_t eventSelectionCorrected)
+{
+ /// Compute trigger fractions
+
+ TString graphName(Form("NofEvent%s%s%s",GetTriggerTypeName(triggerType).Data(),
+ pileUpCorrected ? "PU" : "",
+ GetEventSelectionName(eventSelectionCorrected).Data()));
+
+ if ( GetGraph(graphName) )
+ {
+ // compute it only once
+ return;
+ }
+
+ ComputeCorrectionFactors(eventSelectionCorrected);
+
+ TString gpsname(Form("Correction%s%s",GetEventSelectionName(eventSelectionCorrected).Data(),GetTriggerTypeName(triggerType).Data()));
+ TString gpuname(Form("CorrectionPU%s%s",GetEventSelectionName(eventSelectionCorrected).Data(), GetTriggerTypeName(triggerType).Data()));
+
+ TGraphErrors* gPS = GetGraph(gpsname);
+
+ if (!gPS)
+ {
+ AliError(Form("Could not find %s",gpsname.Data()));
+ return;
+ }
+
+ TGraphErrors* gPU = GetGraph(gpuname);
+
+ if (!gPU)
+ {
+ AliError(Form("Could not find %s",gpuname.Data()));
+ return;
+ }
+
+ AliDebug(2,graphName);
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ const std::set<int>& runs = RunNumbers();
+
+ Int_t i(0);
+
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ TString triggerClassName = GetTriggerClassName(triggerType,runNumber);
+
+ if ( triggerClassName.Length() )
+ {
+ Double_t n = GetSum(triggerClassName,runNumber,0);
+
+ vx.push_back(runNumber);
+ vxerr.push_back(0.5);
+
+ assert(runNumber==TMath::Nint(gPU->GetX()[i]));
+
+ Double_t y(n);
+ Double_t y1(1.0);
+ Double_t y2(1.0);
+ Double_t e1(0);
+ Double_t e2(0);
+
+ if ( pileUpCorrected )
+ {
+ y1 = gPU->GetY()[i];
+ e1 = gPU->GetEY()[i];
+ }
+
+ if ( eventSelectionCorrected > 0 )
+ {
+ y2 = gPS->GetY()[i];
+ e2 = gPS->GetEY()[i];
+ }
+
+ y *= y1*y2;
+
+ AliDebug(2,Form("RUN %09d n %e y1 %e y2 %e y% e",runNumber,n,y1,y2,y));
+
+ Double_t yerr = y*AliAnalysisMuMuResult::ErrorABC( n, TMath::Sqrt(n),
+ y1, e1,
+ y2, e2);
+
+ vy.push_back(y);
+ vyerr.push_back(yerr);
+
+ ++i;
+ }
+ }
+
+ TString title(Form("Number of event of trigger %s",GetTriggerTypeName(triggerType).Data()));
+
+ CreateAndAddGraph(graphName,title,vx,vxerr,vy,vyerr);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeTriggerFractions(ETriggerType triggerType,
+ Bool_t physicsSelectionCorrected)
+{
+ /// Compute trigger fractions
+
+ TString graphName(Form("Fractions%s%s",GetTriggerTypeName(triggerType).Data(),physicsSelectionCorrected ? "PS" : ""));
+
+ if ( GetGraph(graphName) )
+ {
+ // compute it only once
+ return;
+ }
+
+ AliDebug(2,graphName);
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ const std::set<int>& runs = RunNumbers();
+
+ Double_t n(0.0);
+
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ TString triggerClassName = GetTriggerClassName(triggerType,runNumber);
+
+ if ( triggerClassName.Length() )
+ {
+ n += GetSum(triggerClassName,runNumber,physicsSelectionCorrected);
+ }
+ }
+
+ if ( n <= 0.0 )
+ {
+ AliWarning(Form("Got zero trigger for %s",GetTriggerTypeName(triggerType).Data()));
+ return;
+ }
+
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ TString triggerClassName = GetTriggerClassName(triggerType,runNumber);
+
+ vx.push_back(runNumber);
+ vxerr.push_back(0.5);
+ Double_t y = GetSum(triggerClassName,runNumber,physicsSelectionCorrected);
+ vy.push_back(y/n);
+ vyerr.push_back( (y/n) * AliAnalysisMuMuResult::ErrorAB( y,TMath::Sqrt(y),
+ n, TMath::Sqrt(n)));
+ }
+
+
+ TString title(Form("Fraction of event of trigger %s",GetTriggerTypeName(triggerType).Data()));
+
+ CreateAndAddGraph(graphName,title,vx,vxerr,vy,vyerr);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ComputeTriggerL0B(ETriggerType triggerType)
+{
+ /// Compute trigger L0B
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ TString graphName(Form("L0B%s",GetTriggerTypeName(triggerType).Data()));
+
+ if ( GetGraph(graphName) )
+ {
+ // insure we're computing it only once
+ return;
+ }
+
+ AliDebug(2,graphName);
+
+ const std::set<int>& runs = RunNumbers();
+
+ AliAnalysisTriggerScalers ts(runs,OCDBPath().Data());
+
+ for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+ {
+ Int_t runNumber = *it;
+
+ TString triggerClassName = GetTriggerClassName(triggerType,runNumber);
+
+ AliAnalysisTriggerScalerItem* item = ts.GetTriggerScaler(runNumber,"L0B",triggerClassName);
+ if (!item) continue;
+
+ vx.push_back(runNumber);
+ vxerr.push_back(0.5);
+
+ Double_t y = item->Value();
+
+ vy.push_back(y);
+
+ vyerr.push_back( TMath::Sqrt(y) );
+ }
+
+ TString title(Form("L0B of trigger %s",GetTriggerTypeName(triggerType).Data()));
+
+ CreateAndAddGraph(graphName,title,vx,vxerr,vy,vyerr);
+}
+
+////_____________________________________________________________________________
+//void AliAnalysisMuMuFnorm::ComputeTSGraph(ETriggerType tt)
+//{
+// /// Compute the per-run graph of physics selection accept fraction x track
+// /// accept fraction for the given trigger
+//
+// TString graphName(Form("CorrectionTS%s",GetTriggerTypeName(tt).Data()));
+//
+// if (GetGraph(graphName))
+// {
+// // insure we're computing it only once
+// return;
+// }
+//
+// AliDebug(1,graphName);
+//
+// std::vector<double> vx;
+// std::vector<double> vxerr;
+// std::vector<double> vy;
+// std::vector<double> vyerr;
+//
+// const std::set<int>& runs = RunNumbers();
+//
+// AliAnalysisTriggerScalers ts(runs,OCDBPath().Data());
+//
+// for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it )
+// {
+// Int_t runNumber = *it;
+//
+// Double_t purity, purityError;
+//
+// TString triggerClassName = GetTriggerClassName(tt,runNumber);
+//
+// if ( triggerClassName.Length()==0 )
+// {
+// AliError(Form("Unknown trigger type %d",tt));
+// return;
+// }
+//
+// GetPurity(triggerClassName.Data(),runNumber,purity,purityError,"OFFLINE1");
+//
+// vx.push_back(runNumber);
+// vxerr.push_back(0.5);
+// vy.push_back(purity);
+// vyerr.push_back(purityError);
+// }
+//
+// TString title(Form("Fraction of events accepted by the physics selection x track selection for trigger %s",GetTriggerTypeName(tt).Data()));
+//
+// CreateAndAddGraph(graphName,title,vx,vxerr,vy,vyerr);
+//}
+//
+
+//_____________________________________________________________________________
+TGraphErrors* AliAnalysisMuMuFnorm::CreateAndAddGraph(const TString& name,
+ const TString& title,
+ const std::vector<double>& vx,
+ const std::vector<double>& vxerr,
+ const std::vector<double>& vy,
+ const std::vector<double>& vyerr) const
+{
+ /// Creates a graph and adds it to our mergeable collection
+
+ TGraphErrors* g = new TGraphErrors(vx.size(),&vx[0],&vy[0],&vxerr[0],&vyerr[0]);
+ g->SetName(name.Data());
+ g->SetTitle(title.Data());
+
+ if (fIsCompactGraphs)
+ {
+ AliAnalysisMuMuGraphUtil::Compact(*g);
+ }
+
+ g->GetXaxis()->SetNoExponent();
+// g->GetXaxis()->SetTitle("Run number");
+
+ TPaveText* text = new TPaveText(0.70,0.70,0.89,0.89,"NDC");
+ text->SetBorderSize(0);
+ text->SetFillColor(0);
+ text->AddText(Form("Mean %e",g->GetMean(2)));
+ text->AddText(Form("RMS %e",g->GetRMS(2)));
+ g->GetListOfFunctions()->Add(text);
+
+ MC()->Adopt("/GRAPHS/",g);
+ return g;
+}
+
+//_____________________________________________________________________________
+AliMergeableCollection* AliAnalysisMuMuFnorm::DetachMC()
+{
+ // let go the ownership of our mergeable collection
+ fIsOwner = kFALSE;
+ return fMergeableCollection;
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::DrawWith2Scales(const char* graphName1, const char* graphName2)
+{
+ TGraphErrors* g1 = static_cast<TGraphErrors*>(GetGraph(graphName1)->Clone());
+ TGraphErrors* g2 = static_cast<TGraphErrors*>(GetGraph(graphName2)->Clone());
+
+ if ( g1 && g2 )
+ {
+ gStyle->SetOptTitle(0);
+
+ AliAnalysisMuMuGraphUtil gu;
+
+ TCanvas* c = gu.DrawWith2Scales(*g1,*g2);
+ c->Draw();
+
+ for ( Int_t i = 0; i < 2; ++i )
+ {
+ c->cd(i);
+ gPad->SetLeftMargin(0.15);
+ gPad->SetRightMargin(0.15);
+ }
+
+ c->Update();
+
+ // TGraphErrors* g = new TGraphErrors(g1->GetN());
+ //
+ // Double_t check(0.0);
+ //
+ // for ( Int_t i = 0; i < g->GetN(); ++i )
+ // {
+ // Double_t y = g1->GetY()[i]*g2->GetY()[i];
+ //
+ // check += g2->GetY()[i];
+ //
+ // g->SetPoint(i,g2->GetX()[i],y);
+ // g->SetPointError(i,g2->GetEX()[i],
+ // y*AliAnalysisMuMuResult::ErrorAB(g1->GetY()[i],g1->GetEY()[i],
+ // g2->GetY()[i],g2->GetEY()[i]));
+ // }
+ //
+ // new TCanvas;
+ //
+ // g->Draw("ap");
+ //
+ // AliInfo(Form("check: %e g mean %e rms %e",check,g->GetMean(2),g->GetRMS(2)));
+
+ /*
+
+ // g1 vs g2
+
+ TGraphErrors* g = new TGraphErrors(g1->GetN());
+
+ for ( Int_t i = 0; i < g->GetN(); ++i )
+ {
+ g->SetPoint(i,g2->GetY()[i],g1->GetY()[i]);
+ g->SetPointError(i,g2->GetEY()[i],g1->GetEY()[i]);
+ }
+
+ new TCanvas;
+
+ g->Draw("ap");
+
+ AliInfo(Form("g mean %e rms %e",g->GetMean(2),g->GetRMS(2)));
+
+ */
+
+ }
+
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuFnorm::GetEventSelectionName(Int_t eventSelectionCorrected) const
+{
+ if ( eventSelectionCorrected == 1 )
+ {
+ return "PS";
+ }
+ else if ( eventSelectionCorrected == 2 )
+ {
+ return "TS";
+ }
+ return "";
+}
+
+//_____________________________________________________________________________
+TGraphErrors* AliAnalysisMuMuFnorm::GetGraph(const char* name) const
+{
+ // shortcut method to give access to one graph
+
+ TObject* o = MC()->GetObject(Form("/GRAPHS/%s",name));
+
+ if (!o) return 0x0;
+
+ if ( o->IsA() != TGraphErrors::Class() )
+ {
+ AliError(Form("Object %s is not of the expected type",o->GetName()));
+ return 0x0;
+ }
+
+ return static_cast<TGraphErrors*>(o);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::GetPurity(const char* triggerClassName, Int_t runNumber,
+ Double_t& value, Double_t& error, Int_t eventSelectionCorrected) const
+{
+ /// Get the physics selection accept fraction for a given trigger
+
+ value=error=0.0;
+
+ TString runCondition;
+
+ if (runNumber>0)
+ {
+ runCondition.Form("/run:%d",runNumber);
+ }
+
+ Double_t nall = fCounterCollection.GetSum(Form("trigger:%s/event:ALL%s",triggerClassName,runCondition.Data()));
+
+ TString ename;
+
+ if ( eventSelectionCorrected == 1 )
+ {
+ ename = "PSALL";
+ }
+ else if ( eventSelectionCorrected == 2 )
+ {
+ ename = "OFFLINE1";
+ }
+ else
+ {
+ value = 1.0;
+ return;
+
+ }
+ Double_t nps = fCounterCollection.GetSum(Form("trigger:%s/event:%s%s",
+ triggerClassName,ename.Data(),runCondition.Data()));
+
+ if ( nall <= 0.0 ) return;
+
+ value = nps/nall;
+
+ error = AliAnalysisMuMuResult::ErrorAB(nall,TMath::Sqrt(nall),nps,TMath::Sqrt(nps));
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuResult* AliAnalysisMuMuFnorm::GetResult(const char* name) const
+{
+ // shortcut method to give access to one result
+
+ TObject* o = MC()->GetObject(Form("/RESULTS/%s",name));
+
+ if (!o) return 0x0;
+
+ if ( o->IsA() != AliAnalysisMuMuResult::Class() )
+ {
+ AliError(Form("Object %s is not of the expected type",o->GetName()));
+ return 0x0;
+ }
+
+ return static_cast<AliAnalysisMuMuResult*>(o);
+}
+
+//______________________________________________________________________________
+AliAnalysisMuMuResult* AliAnalysisMuMuFnorm::GetRunIntegratedResult(const TGraphErrors& g, const char* basename)
+{
+ /// get one value +- error for this graph (weighting the run-by-run values
+ /// by the fraction of the number of triggers in that run)
+ /// also the rms is computed.
+
+ Bool_t physicsSelectionCorrected(kFALSE);
+
+ if ( TString(g.GetName()).Contains("PS") )
+ {
+ physicsSelectionCorrected=kTRUE;
+ }
+
+ ComputeTriggerFractions(fReferenceTriggerType,physicsSelectionCorrected);
+
+ TString fname(Form("Fractions%s%s",GetTriggerTypeName(fReferenceTriggerType).Data(),physicsSelectionCorrected ? "PS" : ""));
+
+ TGraphErrors* gTriggerFractions = GetGraph(fname);
+
+ StdoutToAliDebug(2,std::cout << g.GetName() << std::endl; g.Print(););
+
+ if (!gTriggerFractions)
+ {
+ AliError(Form("Did not find graph for %s",fname.Data()));
+ return 0x0;
+ }
+
+ Double_t mean = g.GetY()[0];
+ Int_t n = g.GetN();
+
+ Double_t errorOnMean = g.GetEY()[0];
+ Double_t rms = 0.0;
+
+ if ( n > 1 )
+ {
+ mean = errorOnMean = 0.0;
+ Double_t d(0.0);
+ Double_t v1(0.0);
+ Double_t v2(0.0);
+
+ for ( Int_t i = 0; i < n; ++i )
+ {
+ Double_t y = g.GetY()[i];
+
+ Double_t weight = gTriggerFractions->GetY()[i]; // sum of weight should be 1.0
+
+ AliDebug(2,Form("%s i %3d y %e weight %e",g.GetName(),i,y,weight));
+
+ mean += y * weight;
+
+ v1 += weight;
+ v2 += weight*weight;
+ }
+
+ mean /= v1;
+
+ for ( Int_t i = 0; i < n; ++i )
+ {
+ Double_t weight = gTriggerFractions->GetY()[i]; // sum of weight should be 1.0
+ Double_t y = g.GetY()[i];
+
+ d += (y-mean)*(y-mean)*weight;
+ }
+
+ AliDebug(2,Form("v1=%e v2=%e d=%e",v1,v2,d));
+
+ if ( v1 <= 0) return 0x0;
+
+ errorOnMean = TMath::Sqrt((1.0/v1)*(1.0/(n-1))*d);
+
+ rms = TMath::Sqrt( (v1/(v1*v1-v2))*d );
+ }
+
+ AliAnalysisMuMuResult* result = new AliAnalysisMuMuResult(g.GetName(),g.GetTitle());
+
+ result->Set(basename,mean,errorOnMean,rms);
+
+ if ( TString(g.GetName()) == "FnormScalersPUPS" )
+ {
+ AliDebug(1,Form("mean %e errorOnMean %e rms %e",mean,errorOnMean,rms));
+ StdoutToAliDebug(1,result->Print("full"));
+ }
+
+ return result;
+}
+
+//_____________________________________________________________________________
+Double_t AliAnalysisMuMuFnorm::GetSum(const char* triggerClassName,
+ Int_t runNumber,
+ Int_t eventSelectionCorrected) const
+{
+ TString condition(Form("trigger:%s/run:%d",triggerClassName,runNumber));
+
+ if (eventSelectionCorrected==1)
+ {
+ condition += "/event:PSALL";
+ }
+ else if ( eventSelectionCorrected == 2 )
+ {
+ condition += "/event:OFFLINE1";
+ }
+ else
+ {
+ condition += "/event:ALL";
+ }
+
+ Double_t n = fCounterCollection.GetSum(condition.Data());
+
+ if (n<=0)
+ {
+ AliError(Form("Got no count for %s for run %d (physicsSelected:%d)",triggerClassName,runNumber,eventSelectionCorrected));
+ return 0;
+ }
+
+ return n;
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuFnorm::GetTriggerClassName(ETriggerType tt, Int_t runNumber) const
+{
+ // get the triggerclass to for a given trigger type and run number
+
+ if ( tt == kMB )
+ {
+ return MBTriggerClassName(runNumber);
+ }
+ else if ( tt == kMUL )
+ {
+ return MULTriggerClassName(runNumber);
+ }
+ else if ( tt == kMSL)
+ {
+ return MSLTriggerClassName(runNumber);
+ }
+ else if ( tt == kMSH)
+ {
+ return MSHTriggerClassName(runNumber);
+ }
+ return "";
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuFnorm::GetTriggerTypeName(ETriggerType tt) const
+{
+ // get the name of the trigger type
+ if ( tt == kMB )
+ {
+ return "MB";
+ }
+ else if ( tt == kMUL )
+ {
+ return "MUL";
+ }
+ else if ( tt == kMSL)
+ {
+ return "MSL";
+ }
+ else if ( tt == kMSH)
+ {
+ return "MSH";
+ }
+ return "";
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::GetValueAndErrorFromGraph(TGraphErrors* graph,
+ Int_t runNumber,
+ Double_t& value,
+ Double_t& error) const
+{
+ /// get (value,error) corresponding to run=runNumber.
+ /// Works both for compact and non-compact graphs
+
+ value = TMath::Limits<Double_t>::Max();
+ error = 0.0;
+
+ if (!graph) return;
+
+ TAxis* axis = graph->GetXaxis();
+
+ for ( Int_t i = 0; i < graph->GetN(); ++i )
+ {
+ Int_t rbin = TMath::Nint(graph->GetX()[i]);
+ Int_t rlabel = TString(axis->GetBinLabel(i+1)).Atoi();
+ if ( rbin == runNumber || rlabel == runNumber )
+ {
+ value = graph->GetY()[i];
+ error = graph->GetEY()[i];
+ }
+ }
+}
+
+//_____________________________________________________________________________
+AliMergeableCollection* AliAnalysisMuMuFnorm::MC() const
+{
+ // get our mergeable collection
+ if (!fMergeableCollection)
+ {
+ fMergeableCollection = new AliMergeableCollection("Fnorm",Form("MB to %s trigger normalization results",GetTriggerTypeName(fReferenceTriggerType).Data()));
+ }
+ return fMergeableCollection;
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuFnorm::MBTriggerClassName(Int_t runNumber) const
+{
+ /// FIXME : find a better way ?
+
+ if ( TriggerClassnameTest("CINT7-B-NOPF-ALLNOTRD",runNumber) )
+ {
+ return "CINT7-B-NOPF-ALLNOTRD";
+ }
+ return "";
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuFnorm::MSHTriggerClassName(Int_t runNumber) const
+{
+ /// FIXME : find a better way ?
+
+ if ( TriggerClassnameTest("CMSH7-B-NOPF-ALLNOTRD",runNumber) )
+ {
+ return "CMSH7-B-NOPF-ALLNOTRD";
+ }
+ else if ( TriggerClassnameTest("CMSH7-B-NOPF-MUON",runNumber) )
+ {
+ return "CMSH7-B-NOPF-MUON";
+ }
+ return "";
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuFnorm::MSLTriggerClassName(Int_t runNumber) const
+{
+ /// FIXME : find a better way ?
+
+ if ( TriggerClassnameTest("CMSL7-B-NOPF-MUON",runNumber) )
+ {
+ return "CMSL7-B-NOPF-MUON";
+ }
+// else
+// if ( TriggerClassnameTest("CMSL7-B-NOPF-ALLNOTRD",runNumber) )
+// {
+// return "CMSL7-B-NOPF-ALLNOTRD";
+// }
+ return "";
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::MultiplyGraphs(const char* g1name, const char* g2name, const char* name)
+{
+ /// Make a new graph = g1*g2
+ std::vector<double> vx;
+ std::vector<double> vy;
+ std::vector<double> vxerr;
+ std::vector<double> vyerr;
+
+ TGraphErrors* g1 = GetGraph(g1name);
+ TGraphErrors* g2 = GetGraph(g2name);
+
+ if (!g1)
+ {
+ AliError(Form("Could not get graph %s",g1name));
+ return;
+ }
+
+ if (!g2)
+ {
+ AliError(Form("Could not get graph %s",g2name));
+ return;
+ }
+
+ if ( g1->GetN() != g2->GetN() )
+ {
+ AliError(Form("Could not multiply incompatible graphs %d pts vs %d pts",g1->GetN(),g2->GetN()));
+ return;
+ }
+
+ for ( Int_t i = 0; i < g1->GetN(); ++i )
+ {
+ if ( g1->GetX()[i] != g2->GetX()[i] )
+ {
+ AliError(Form("Incompatible bin %d : %e vs %e",i,g1->GetX()[i],g2->GetX()[i]));
+ return;
+ }
+
+ vx.push_back(g1->GetX()[i]);
+ vxerr.push_back(g1->GetEX()[i]);
+
+ Double_t y = g1->GetY()[i]*g2->GetY()[i];
+ Double_t yerr = y*AliAnalysisMuMuResult::ErrorAB( g1->GetY()[i], g1->GetEY()[i],
+ g2->GetY()[i], g2->GetEY()[i]);
+
+ vy.push_back(y);
+ vyerr.push_back(yerr);
+ }
+
+ TString gname(name);
+
+ if ( gname.Length() == 0 )
+ {
+ gname = g1->GetName();
+ gname += "x";
+ gname += g2->GetName();
+ }
+
+ TString title(Form("Product of %s by %s",g1->GetName(),g2->GetName()));
+
+ CreateAndAddGraph(gname,title,vx,vxerr,vy,vyerr);
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuFnorm::MULTriggerClassName(Int_t runNumber) const
+{
+ /// FIXME : find a better way ?
+
+ if ( TriggerClassnameTest("CMUL7-B-NOPF-ALLNOTRD",runNumber) )
+ {
+ return "CMUL7-B-NOPF-ALLNOTRD";
+ }
+ else if ( TriggerClassnameTest("CMUL7-B-NOPF-MUON",runNumber) )
+ {
+ return "CMUL7-B-NOPF-MUON";
+ }
+ return "";
+
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::Print(Option_t* opt) const
+{
+ if ( fMergeableCollection )
+ {
+ fMergeableCollection->Print(opt);
+ }
+}
+
+//_____________________________________________________________________________
+std::set<int> AliAnalysisMuMuFnorm::RunNumbers() const
+{
+ // Extract the run numbers from our counter collection
+
+ std::set<int> runset;
+
+ TString sruns = fCounterCollection.GetKeyWords("run");
+ TObjArray* runs = sruns.Tokenize(",");
+
+ TIter next(runs);
+ TObjString* s;
+
+ while ( ( s = static_cast<TObjString*>(next())) )
+ {
+ runset.insert(s->String().Atoi());
+ }
+ delete runs;
+
+ return runset;
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ScalerFnorm(Double_t& value, Double_t& error,
+ Double_t L0bREF, Double_t purityREF, Double_t purityREFerror,
+ Double_t L0bMB, Double_t purityMB, double_t purityMBerror,
+ Double_t pileUpFactor, Double_t pileUpFactorError)
+{
+ /// Compute the MB to CMUL ratio and its associated error
+
+ value = error = 0.0;
+
+ value = L0bREF*purityREF;
+
+ if (!value) return;
+
+ value = L0bMB*purityMB*pileUpFactor/value;
+
+ error = value*AliAnalysisMuMuResult::ErrorABCDE(L0bREF,TMath::Sqrt(L0bREF),
+ purityREF,purityREFerror,
+ L0bMB,TMath::Sqrt(L0bMB),
+ purityMB,purityMBerror,
+ pileUpFactor,pileUpFactorError);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuFnorm::ShowFnorm(const TObjArray& a) const
+{
+ /// Print and plot Fnorm values
+ TIter next(&a);
+ TGraphErrors* g;
+
+ while ( ( g = static_cast<TGraphErrors*>(next()) ) )
+ {
+ g->SetTitle(Form("Fnorm %s",g->GetTitle()));
+
+ new TCanvas(Form("c%s",g->GetName()));
+
+ if (fIsCompactGraphs)
+ {
+ AliAnalysisMuMuGraphUtil::Compact(*g);
+ }
+ else
+ {
+ g->GetXaxis()->SetNoExponent();
+ }
+ g->Draw("lpa");
+
+ Double_t y(0.0);
+ Double_t yerr(0.0);
+
+ for ( Int_t i = 0; i < g->GetN(); ++i )
+ {
+ y += g->GetY()[i];
+ Double_t e = ( y != 0.0 ? g->GetEY()[i]/y : 0.0);
+
+ yerr += e*e;
+ }
+
+ y /= (g->GetN());
+ yerr = TMath::Sqrt(yerr)*y;
+
+ AliInfo(Form("%30s graph %e +- %e (%5.2f %%) RMS %e",g->GetName(),
+ y,yerr,yerr*100/y,g->GetRMS(2)));
+
+ }
+}
+
+//_____________________________________________________________________________
+Bool_t AliAnalysisMuMuFnorm::TriggerClassnameTest(const char* triggerClassName, Int_t runNumber) const
+{
+ /// Check if we have counts for that trigger,run combination
+
+ TString runs = fCounterCollection.GetKeyWords("run");
+
+ if ( !runs.Contains(Form("%d",runNumber)) ) return kFALSE;
+
+ TString triggers = fCounterCollection.GetKeyWords("trigger");
+
+ if (!triggers.Contains(triggerClassName)) return kFALSE;
+
+ Double_t n = fCounterCollection.GetSum(Form("trigger:%s/run:%d",triggerClassName,runNumber));
+
+ return ( n > 0.0 );
+}
+
+//_____________________________________________________________________________
+void
+AliAnalysisMuMuFnorm::WeightedMeanGraphs(const char* patternOrList, const char* graphName)
+{
+ /// Sum the graphs which name matches pattern
+ /// Sum is made using a weighted mean (each element is weighted by the inverse
+ /// of its error squared)
+
+ TString spattern(patternOrList);
+ TObjArray* slist(0x0);
+
+ if ( spattern.CountChar(',') )
+ {
+ // it's not a pattern but a list...
+ slist = spattern.Tokenize(",");
+ spattern = "";
+ }
+
+ TList* objectList = MC()->CreateListOfObjectNames("/GRAPHS/");
+ TIter next(objectList);
+ TObjString* str(0x0);
+ TObjArray selected;
+ selected.SetOwner(kFALSE);
+
+ while ( ( str = static_cast<TObjString*>(next()) ) )
+ {
+ TGraphErrors* g = GetGraph(str->String());
+
+ if (!g) continue;
+
+ TString name(g->GetName());
+
+ if ( spattern.Length() >0 && !name.Contains(spattern.Data()) ) continue;
+
+ if ( slist && !slist->FindObject(name)) continue;
+
+ AliDebug(2,Form("Selected for sum : %s",name.Data()));
+
+ selected.Add(g);
+ }
+
+ delete slist;
+ delete objectList;
+
+ if (selected.GetLast()<0) return;
+
+ std::vector<double> vx;
+ std::vector<double> vy;
+ std::vector<double> vxerr;
+ std::vector<double> vyerr;
+
+ Int_t npts = static_cast<TGraphErrors*>(selected.First())->GetN();
+
+ for ( Int_t ipoint = 0; ipoint < npts; ++ipoint )
+ {
+ Double_t x,xref,xerr;
+ Double_t sum(0.0);
+ Double_t sume2(0.0);
+
+ for ( Int_t igraph = 0; igraph <= selected.GetLast(); ++igraph )
+ {
+ TGraphErrors* g = static_cast<TGraphErrors*>(selected.At(igraph));
+
+ if ( g->GetN() != npts )
+ {
+ AliError(Form("Graph %s does not have the expected %d points",g->GetName(),npts));
+ continue;
+ }
+ Double_t runNumber;
+
+ if ( fIsCompactGraphs )
+ {
+ runNumber = TString(g->GetXaxis()->GetBinLabel(ipoint+1)).Atoi()*1.0;
+ }
+ else
+ {
+ runNumber = g->GetX()[ipoint];
+ }
+
+ if ( igraph == 0 )
+ {
+ xref = g->GetX()[ipoint];
+ x = runNumber;
+ xerr = g->GetEX()[ipoint];
+ }
+ else
+ {
+ if ( xref != g->GetX()[ipoint] )
+ {
+ AliError(Form("Cannot sum graphs with different axis : get %e and expected %e : %s vs %s",xref,x,selected.At(0)->GetName(),g->GetName()));
+ return;
+ }
+ }
+
+ Double_t e2 = g->GetEY()[ipoint]*g->GetEY()[ipoint];
+
+ if ( e2 != 0.0 )
+ {
+ sum += g->GetY()[ipoint]/e2;
+ sume2 += 1.0/e2;
+ }
+ }
+
+ if (sume2 != 0.0)
+ {
+ vx.push_back(x);
+ vxerr.push_back(xerr);
+ vy.push_back(sum/sume2);
+ vyerr.push_back(TMath::Sqrt(1/sume2));
+ }
+ }
+
+ Int_t n = selected.GetEntries();
+
+ TString name(graphName);
+ TString title(Form("Weighted mean from %d individual graphs",n));
+
+ if ( strlen(graphName) == 0)
+ {
+ name = TString::Format("WeightMeanFnorm%s",patternOrList);
+ name.ReplaceAll(",","_");
+ title = TString::Format("WeightMeanFnorm%s from %d individual graphs",patternOrList,n);
+ }
+
+ CreateAndAddGraph(name,title,vx,vxerr,vy,vyerr);
+}
+
+
--- /dev/null
+#ifndef ALIANALYSISMUMUFNORM_H
+#define ALIANALYSISMUMUFNORM_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+#ifndef ROOT_TObject
+# include "TObject.h"
+#endif
+
+#ifndef ROOT_TString
+# include "TString.h"
+#endif
+
+#include <set>
+#include <vector>
+
+class TObjArray;
+class TGraphErrors;
+class TGraph;
+class AliAnalysisMuMuResult;
+class AliCounterCollection;
+class AliMergeableCollection;
+
+class AliAnalysisMuMuFnorm : public TObject
+{
+
+public:
+
+ enum ETriggerType
+ {
+ kMB=1,
+ kMUL=2,
+ kMSL=3,
+ kMSH=4
+ };
+
+ AliAnalysisMuMuFnorm(AliCounterCollection& cc,
+ AliAnalysisMuMuFnorm::ETriggerType triggerType=AliAnalysisMuMuFnorm::kMUL,
+ const char* ocdbpath="raw://",
+ Bool_t compactGraphs=kFALSE);
+
+ virtual ~AliAnalysisMuMuFnorm();
+
+ void ComputeFnorm();
+
+ void ComputeCorrectionFactors(Int_t eventSelectionCorrected);
+
+ void ComputeFnormOffline(Int_t nstep, Bool_t pileUpCorrected, Int_t eventSelectionCorrected);
+
+
+ void ComputeFnormScalers(Bool_t pileUpCorrected, Int_t eventSelectionCorrected);
+
+ void ComputeGraphRelDif(const char* a, const char* b) const;
+
+ void ComputeNofEvents(ETriggerType triggerType, Bool_t pileUpCorrected, Int_t eventSelectionCorrected);
+
+ void ComputePileUpGraph(ETriggerType tt, Int_t eventSelectionCorrected=0);
+
+ void ComputeEventSelectionGraph(ETriggerType tt, Int_t eventSelectionCorrected);
+
+ void ComputeResultsFromGraphs();
+
+ void ComputeTriggerFractions(ETriggerType triggerType, Bool_t physicsSelectionCorrected);
+
+ void ComputeTriggerL0B(ETriggerType tt);
+
+ void ComputeTSGraph(ETriggerType tt);
+
+ AliMergeableCollection* DetachMC();
+
+ void DrawWith2Scales(const char* graphName1, const char* graphName2);
+
+ TString GetEventSelectionName(Int_t eventSelectionCorrected) const;
+
+ void GetFnorm(Int_t runNumber, const char* eventSelection, Double_t& value, Double_t& error) const;
+
+ TGraphErrors* GetGraph(const char* name) const;
+
+ void GetPurity(const char* triggerClassName, Int_t runNumber, Double_t& value, Double_t& error, Int_t eventSelectionCorrected) const;
+
+ void GetValueAndErrorFromGraph(TGraphErrors* graph,
+ Int_t runNumber,
+ Double_t& value,
+ Double_t& error) const;
+
+ AliAnalysisMuMuResult* GetResult(const char* name) const;
+
+ AliAnalysisMuMuResult* GetRunIntegratedResult(const TGraphErrors& g, const char* basename="Fnorm");
+
+ AliMergeableCollection* MC() const;
+
+ void MultiplyGraphs(const char* g1, const char* g2, const char* name="");
+
+ TString OCDBPath() const { return fOCDBPath; }
+
+ void Print(Option_t* opt="") const;
+
+ void ScalerFnorm(Double_t& value, Double_t& error,
+ Double_t L0bCMUL7, Double_t purityCMUL7, Double_t purityCMUL7error,
+ Double_t L0bCINT7, Double_t purityCINT7, Double_t purityCINT7error,
+ Double_t pileUpFactor, Double_t pileUpFactorError);
+
+ void ShowFnorm(const TObjArray& a) const;
+
+ Bool_t TriggerClassnameTest(const char* triggerClassName, Int_t runNumber) const;
+
+ void WeightedMeanGraphs(const char* pattern, const char* name="");
+
+private:
+
+ AliAnalysisMuMuFnorm(const AliAnalysisMuMuFnorm& rhs); // not implemented on purpose
+ AliAnalysisMuMuFnorm& operator=(const AliAnalysisMuMuFnorm& rhs); // not implemented on purpose
+
+ TGraphErrors* CreateAndAddGraph(const TString& name,
+ const TString& title,
+ const std::vector<double>& vx,
+ const std::vector<double>& vxerr,
+ const std::vector<double>& vy,
+ const std::vector<double>& vyerr) const;
+
+ Double_t GetSum(const char* triggerClassName, Int_t runNumber, Int_t eventSelectionCorrected) const;
+
+ TString GetTriggerClassName(ETriggerType tt, Int_t runNumber) const;
+
+ TString GetTriggerTypeName(ETriggerType tt) const;
+
+ std::set<int> RunNumbers() const;
+
+ TString MBTriggerClassName(Int_t runNumber) const;
+ TString MSLTriggerClassName(Int_t runNumber) const;
+ TString MULTriggerClassName(Int_t runNumber) const;
+ TString MSHTriggerClassName(Int_t runNumber) const;
+
+private:
+
+ /*const*/ AliCounterCollection& fCounterCollection; // collection of trigger counters (not owner)
+ mutable AliMergeableCollection* fMergeableCollection; // collection of results, histograms, graphs (ownership is in fIsOwner)
+ Bool_t fIsOwner; // whether we are the owner of the mergeable collection
+ TString fOCDBPath; // OCDB to be used (raw:// by default)
+ mutable AliAnalysisMuMuResult* fResult; // combined result of the various computations
+ Bool_t fIsCompactGraphs; // whether the graph produced should be compact
+ ETriggerType fReferenceTriggerType; // reference trigger to get the weighting factors
+
+ ClassDef(AliAnalysisMuMuFnorm,0) // class to compute MB to MUON trigger normalization factor
+};
+
+#endif
--- /dev/null
+#include "AliAnalysisMuMuGraphUtil.h"
+
+#include "TAxis.h"
+#include "TCanvas.h"
+#include "TPad.h"
+#include "TGraphErrors.h"
+#include "TString.h"
+#include <vector>
+#include <map>
+#include "TMath.h"
+#include "TObjArray.h"
+#include "AliLog.h"
+#include "TLegend.h"
+#include "TH2F.h"
+#include "TStyle.h"
+#include "AliAnalysisTriggerScalers.h"
+#include <set>
+#include "AliAnalysisMuMuResult.h"
+
+ClassImp(AliAnalysisMuMuGraphUtil)
+
+//____________________________________________________________________________
+AliAnalysisMuMuGraphUtil::AliAnalysisMuMuGraphUtil(const char* ocdbpath) : TObject(),
+fOCDBPath(ocdbpath),
+fAttLine(),
+fAttMarker(),
+fAttFill(),
+fAttXaxis(),
+fAttYaxis(),
+fDrawOptions(),
+fShouldDrawPeriods(kFALSE)
+{
+ // default ctor
+ DefaultStyle();
+}
+
+//____________________________________________________________________________
+TGraphErrors* AliAnalysisMuMuGraphUtil::Combine(TObjArray& graphs, Bool_t compact)
+{
+ // make one graph out of several
+ // x axis is supposed to be run numbers and will end up ordered in the
+ // returned graph
+
+ std::map<int, std::vector<double> > values;
+ std::map<int, std::vector<double> >::const_iterator it;
+
+ TIter next(&graphs);
+ TGraph* g;
+
+ while ( ( g = static_cast<TGraph*>(next())) )
+ {
+ TGraphErrors* ge = dynamic_cast<TGraphErrors*>(g);
+
+ for ( Int_t i = 0; i < g->GetN(); ++i )
+ {
+ Int_t runNumber = GetRunNumber(*g,i); // by doing this we "de-compact" the graph
+
+ it = values.find(runNumber);
+ if ( it != values.end() )
+ {
+ AliErrorClass(Form("Already got values for run %d !",runNumber));
+ StdoutToAliErrorClass(graphs.Print(););
+ return 0x0;
+ }
+
+ std::vector<double> quartet;
+
+ quartet.push_back(runNumber);
+ quartet.push_back(g->GetY()[i]);
+
+ if ( ge )
+ {
+ quartet.push_back(ge->GetEX()[i]);
+ quartet.push_back(ge->GetEY()[i]);
+ }
+ else
+ {
+ quartet.push_back(0.0);
+ quartet.push_back(0.0);
+ }
+
+ values.insert( std::make_pair<int, std::vector<double> >(runNumber,quartet));
+ }
+ }
+
+ TGraphErrors* rv(0x0);
+
+ if ( values.size() )
+ {
+ std::vector<double> vx;
+ std::vector<double> vy;
+ std::vector<double> vxerr;
+ std::vector<double> vyerr;
+
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ const std::vector<double>& q = it->second;
+
+ vx.push_back(q[0]);
+ vy.push_back(q[1]);
+ vxerr.push_back(q[2]);
+ vyerr.push_back(q[3]);
+ }
+
+ rv = new TGraphErrors(values.size(),&vx[0],&vy[0],&vxerr[0],&vyerr[0]);
+ rv->GetXaxis()->SetNoExponent();
+
+ g = static_cast<TGraph*>(graphs.At(0));
+
+ rv->SetName(g->GetName());
+ rv->SetTitle(g->GetTitle());
+
+ if ( compact || IsCompact(*g) )
+ {
+ Compact(*rv);
+ }
+ }
+
+ return rv;
+}
+
+//____________________________________________________________________________
+void AliAnalysisMuMuGraphUtil::DefaultStyle()
+{
+ // Define default color/styles to be used, for at least 2 graphs
+ // (here 5)
+
+ Int_t colors[] = { 1, kGray+1, 4, 2, 6 };
+
+ for ( Int_t i = 0; i < 5; ++i )
+ {
+ Int_t color = colors[i];
+
+ fAttLine.push_back(TAttLine(color,1,1));
+ fAttFill.push_back(TAttFill(color,1001));
+ fAttMarker.push_back(TAttMarker(color,20+i,1));
+ fAttXaxis.push_back(TAttAxis());
+
+ TAttAxis a;
+
+ a.ResetAttAxis();
+
+ a.SetLabelColor(color);
+ a.SetTitleColor(color);
+
+ fAttYaxis.push_back(a);
+
+ fDrawOptions.push_back("LP");
+ }
+}
+
+//____________________________________________________________________________
+TCanvas* AliAnalysisMuMuGraphUtil::DrawWith2Scales(TGraph& g1, TGraph& g2, const char* canvasName)
+{
+ TCanvas* c1 = new TCanvas(canvasName,canvasName);
+ c1->Draw();
+
+ TPad* pad1 = new TPad("pad1","",0,0,1,1);
+ TPad* pad2 = new TPad("pad2","",0,0,1,1);
+
+ g2.GetYaxis()->SetTitle(g2.GetTitle());
+ g1.GetYaxis()->SetTitle(g1.GetTitle());
+
+ pad1->SetFillStyle(4000);
+ pad1->SetFrameFillStyle(0); // transparent pad
+
+ pad2->Draw();
+ pad2->cd();
+
+ StyleGraph(g2,1);
+
+ g2.Draw("abxy+");
+
+ pad1->Draw();
+ pad1->cd();
+
+ StyleGraph(g1,0);
+
+ g1.Draw("alp");
+
+ return c1;
+}
+
+//____________________________________________________________________________
+void AliAnalysisMuMuGraphUtil::Compact(TGraph& g)
+{
+ /// Compact (i.e. get the equivalent of 1 bin = 1 run number for an histogram)
+ /// the graph.
+ /// Only works if the x content of this graph represents run numbers. Otherwise
+ /// result is unpredictable ;-)
+
+ if ( !g.GetN() ) return;
+
+ Double_t x,y;
+
+ std::vector<int> runs;
+ std::vector<double> bins;
+
+ Int_t i(0);
+
+ for ( i = 0; i < g.GetN(); ++i )
+ {
+ g.GetPoint(i,x,y);
+ runs.push_back(TMath::Nint(x));
+ bins.push_back(i);
+ g.SetPoint(i,i+0.5,y);
+ }
+
+ bins.push_back(i);
+
+ TAxis* axis = g.GetXaxis();
+
+ axis->Set(g.GetN(),&bins[0]);
+
+ for ( std::vector<int>::size_type j = 0; j < runs.size(); ++j )
+ {
+ axis->SetBinLabel(j+1,TString::Format("%d",runs[j]).Data());
+ }
+
+ axis->LabelsOption("v");
+}
+
+//_____________________________________________________________________________
+Int_t AliAnalysisMuMuGraphUtil::GetRunNumber(const TGraph& g, Int_t i)
+{
+ // get the run number associated with bin i+1
+ // if graph is not compacted then run number = x-value
+ // otherwise we get it from the axis label
+
+ Int_t runNumber = TMath::Nint(g.GetX()[i]);
+
+ TString runLabel = g.GetXaxis()->GetBinLabel(i+1);
+
+ if ( runLabel.Length() )
+ {
+ runNumber = runLabel.Atoi();
+ }
+
+ return runNumber;
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuGraphUtil::GetRuns(std::set<int>& runs, TGraph& graph) const
+{
+ // extract the list of runs in graph's x-axis
+
+ for ( Int_t i = 0; i < graph.GetN(); ++i )
+ {
+ runs.insert(GetRunNumber(graph,i));
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuGraphUtil::GetYMinAndMax(TGraph& graph, Double_t& ymin, Double_t& ymax)
+{
+ // find graph y-range
+ // note that ymin and ymax *must* be initialized correctly outside
+ // (this is done this way so that this method can be used easily
+ // to get the range of a set of graphs)
+
+ Double_t x,y;
+
+ for ( Int_t i = 0; i < graph.GetN(); ++i )
+ {
+ graph.GetPoint(i,x,y);
+ ymin = TMath::Min(ymin,y);
+ ymax = TMath::Max(ymax,y);
+ }
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliAnalysisMuMuGraphUtil::IsCompact(TGraph& g)
+{
+ // whether the graph is compact or not
+ Double_t delta(0.0);
+
+ for ( Int_t i = 1; i < g.GetN(); ++i )
+ {
+ delta = TMath::Max(delta,g.GetX()[i] - g.GetX()[i-1]);
+ }
+
+ Bool_t hasLabels(kFALSE);
+
+ for ( Int_t i = 1; ( i <= g.GetN() ) && ( !hasLabels ); ++i )
+ {
+ TString label(g.GetXaxis()->GetBinLabel(i));
+ if ( label.Length() ) hasLabels = kTRUE;
+ }
+
+ return hasLabels && delta == 1.0;
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuGraphUtil::PlotSameWithLegend(TObjArray& a,
+ Double_t ymin, Double_t ymax) const
+{
+ // plot on same canvas
+ if (!gPad) new TCanvas;
+
+ Double_t xmin = TMath::Limits<Double_t>::Max();
+ Double_t xmax = TMath::Limits<Double_t>::Min();
+
+ TIter next(&a);
+ TGraph* g;
+
+ while ( ( g = static_cast<TGraph*>(next())))
+ {
+ xmin = TMath::Min(xmin,g->GetX()[0]);
+
+ xmax = TMath::Max(xmax,g->GetX()[g->GetN()-1]);
+
+ }
+
+ TH2* hframe = new TH2F("hframe","hframe",100,xmin,xmax,100,ymin,ymax);
+
+ gStyle->SetOptTitle(0);
+ gStyle->SetOptStat(0);
+
+ hframe->GetXaxis()->SetNoExponent();
+
+// if ( IsCompact(g1) )
+// {
+// (*(hframe->GetXaxis()))=(*(g1.GetXaxis()));
+// }
+
+ hframe->Draw();
+
+ if ( fShouldDrawPeriods )
+ {
+ std::set<int> runs;
+
+ next.Reset();
+
+ while ( ( g = static_cast<TGraph*>(next())))
+ {
+ GetRuns(runs,*g);
+ }
+
+ AliAnalysisTriggerScalers ts(runs,fOCDBPath);
+
+ ts.DrawPeriods(ymin,ymax,kGray);
+
+ hframe->Draw("axissame");
+ }
+
+ next.Reset();
+
+ Int_t i(0);
+ TLegend* l = new TLegend(0.5,0.7,0.9,0.9); // fixme: how to get the legend position/size ?
+ l->SetFillColor(0);
+
+ while ( ( g = static_cast<TGraph*>(next())))
+ {
+ StyleGraph(*g,i);
+ g->Draw(fDrawOptions[i].c_str());
+ ++i;
+ l->AddEntry(g,g->GetName(),fDrawOptions[0].c_str());
+ }
+
+ l->Draw();
+
+}
+
+//_____________________________________________________________________________
+TGraph* AliAnalysisMuMuGraphUtil::RelDif(TGraph& ga, TGraph& gb)
+{
+ // compute the relative difference between two graphs
+
+ std::vector<double> vx;
+ std::vector<double> vxerr;
+ std::vector<double> vy;
+ std::vector<double> vyerr;
+
+ for ( Int_t i = 0; i < ga.GetN(); ++i )
+ {
+ Double_t xa,xb,ya,yb;
+
+ ga.GetPoint(i,xa,ya);
+ gb.GetPoint(i,xb,yb);
+
+ if ( xa != xb )
+ {
+ AliErrorClass(Form("Incompatible graphs : got xa=%e and xb=%e",xa,xb));
+ return 0x0;
+ }
+
+ Double_t newvalue = 0.0;
+
+ if ( TMath::Abs(xa) > 1E-12 )
+ {
+ newvalue = 100.0*( yb - ya ) / ya;
+ }
+
+ Double_t yerr = 0.0;
+
+ if ( dynamic_cast<TGraphErrors*>(&ga) && dynamic_cast<TGraphErrors*>(&gb) )
+ {
+ yerr = newvalue*AliAnalysisMuMuResult::ErrorAB(ya,ga.GetEY()[i],
+ yb,gb.GetEY()[i]);
+ }
+
+ vx.push_back(xa);
+ vxerr.push_back(0.5);
+ vy.push_back(newvalue);
+ vyerr.push_back(yerr);
+ }
+
+
+ return new TGraphErrors(vx.size(),&vx[0],&vy[0],&vxerr[0],&vyerr[0]);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuGraphUtil::StyleGraph(TGraph& g, UInt_t index) const
+{
+ if ( index >= fAttFill.size() ) index = 0;
+
+ static_cast<TAttFill&>(g) = fAttFill[index];
+ static_cast<TAttLine&>(g) = fAttLine[index];
+ static_cast<TAttMarker&>(g) = fAttMarker[index];
+
+ g.GetYaxis()->SetLabelColor(fAttYaxis[index].GetLabelColor());
+ g.GetYaxis()->SetTitleColor(fAttYaxis[index].GetTitleColor());
+
+ //static_cast<TAttAxis&>((*g.GetYaxis())) = fAttYaxis[index];
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuGraphUtil::UnCompact(TGraph& g)
+{
+ /// Reverse operation of the Compact method
+ /// Only works if the labels of this graph represents run numbers. Otherwise
+ /// result is unpredictable ;-)
+
+ if ( !g.GetN() ) return;
+
+ // Int_t run1 = TString(g.GetXaxis()->GetBinLabel(1)).Atoi();
+ // Int_t run2 = TString(g.GetXaxis()->GetBinLabel(g.GetN())).Atoi();
+
+ std::vector<double> runs;
+ Int_t runNumber;
+
+ for ( Int_t i = 0; i < g.GetN(); ++i )
+ {
+ runNumber = TString(g.GetXaxis()->GetBinLabel(i+1)).Atoi();
+ runs.push_back(runNumber*1.0);
+ }
+
+ runs.push_back(runNumber+1);
+
+ g.GetXaxis()->Set(g.GetN(),&runs[0]);
+
+ for ( Int_t i = 0; i < g.GetN(); ++i )
+ {
+ g.SetPoint(i,runs[i],g.GetY()[i]);
+ }
+
+ g.GetXaxis()->SetNoExponent();
+
+}
+
+
--- /dev/null
+#ifndef ALIANALYSISMUMUGRAPHUTIL_H
+#define ALIANALYSISMUMUGRAPHUTIL_H
+
+#ifndef ROOT_TObject
+# include "TObject.h"
+#endif
+
+#include <vector>
+#include <string>
+#include <set>
+
+class TGraph;
+class TGraphErrors;
+class TCanvas;
+class TObjArray;
+
+#include "TAttFill.h"
+#include "TAttMarker.h"
+#include "TAttLine.h"
+#include "TAttAxis.h"
+#include "TString.h"
+
+class AliAnalysisMuMuGraphUtil : public TObject
+{
+public:
+
+ AliAnalysisMuMuGraphUtil(const char* ocdbpath="raw://");
+ virtual ~AliAnalysisMuMuGraphUtil() {}
+
+ static TGraphErrors* Combine(TObjArray& graph, Bool_t compact);
+
+ static void Compact(TGraph& g);
+
+ void DefaultStyle();
+
+ TCanvas* DrawWith2Scales(TGraph& g1, TGraph& g2, const char* canvasName="c1");
+
+ static Int_t GetRunNumber(const TGraph& g, Int_t i);
+
+ void GetRuns(std::set<int>& runs, TGraph& graph) const;
+
+ static Bool_t IsCompact(TGraph& g);
+
+ void PlotSameWithLegend(TObjArray& a, Double_t ymin, Double_t ymax) const;
+
+ void ShouldDrawPeriods(Bool_t value) { fShouldDrawPeriods = value; }
+
+ void StyleGraph(TGraph& graph, UInt_t index) const;
+
+ static void UnCompact(TGraph& g);
+
+ static void GetYMinAndMax(TGraph& g, Double_t& ymin, Double_t& ymax);
+
+ static TGraph* RelDif(TGraph& ga, TGraph& gb);
+
+
+private:
+ AliAnalysisMuMuGraphUtil(const AliAnalysisMuMuGraphUtil& rhs); // not implemented
+ AliAnalysisMuMuGraphUtil& operator=(const AliAnalysisMuMuGraphUtil& rhs); // not implemented
+
+ TString fOCDBPath; // OCDB path
+
+ std::vector<TAttLine> fAttLine; // line attributes
+ std::vector<TAttMarker> fAttMarker; // marker attributes
+ std::vector<TAttFill> fAttFill; // fill attributes
+ std::vector<TAttAxis> fAttXaxis; // x-axis attributes
+ std::vector<TAttAxis> fAttYaxis; // y-axis attributes
+ std::vector<std::string> fDrawOptions; // draw options
+
+ Bool_t fShouldDrawPeriods; // draw period names on top of graphs
+
+ ClassDef(AliAnalysisMuMuGraphUtil,0) // utility class to modify/plot graphs
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+///
+/// Class to hold results about J/psi
+/// like number of of J/psi (before and after Acc x Eff correction),
+/// Acc x Eff correction, Yield, RAB, etc...
+///
+/// author: Laurent Aphecetche (Subatech)
+///
+
+#include "AliAnalysisMuMuJpsiResult.h"
+
+ClassImp(AliAnalysisMuMuJpsiResult)
+
+#include "TF1.h"
+#include "TFitResult.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "THashList.h"
+#include "TLine.h"
+#include "TList.h"
+#include "TMap.h"
+#include "TMath.h"
+#include "TObjArray.h"
+#include "TParameter.h"
+#include "AliAnalysisMuMuBinning.h"
+#include "AliLog.h"
+#include <map>
+
+namespace {
+
+ const std::map<std::string,Double_t>& MassMap()
+ {
+ /// a simple map of masses...
+ static std::map<std::string,Double_t> massMap;
+ // not super elegant, but that way we do not depend on TDatabasePDG and thus
+ // can decide on our particle naming
+ if (massMap.empty())
+ {
+ massMap["Jpsi"] = 3.096916e+00;
+ massMap["PsiPrime"] = 3.68609e+00;
+ massMap["Upsilon"] = 9.46030e+00;
+ massMap["UpsilonPrime"] = 1.00233e+01;
+ }
+ return massMap;
+ }
+
+
+ Double_t funcCB(Double_t* xx, Double_t* par)
+ {
+ /// Crystal ball
+
+ Double_t norm = par[0];
+ Double_t alpha = par[1];
+ Double_t n = par[2];
+ Double_t mean = par[3];
+ Double_t sigma = par[4];
+
+ Double_t x = xx[0];
+
+ Double_t a = TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-0.5*alpha*alpha);
+ Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
+
+ Double_t y = ( TMath::Abs(sigma) > 1E-12 ? (x-mean)/sigma : 0 );
+
+ if ( y > alpha*-1.0 )
+ {
+ return norm*TMath::Exp(-0.5*y*y);
+ }
+ else
+ {
+ return norm*a*TMath::Power(b-y,-n);
+ }
+ }
+
+ Double_t funcJpsiGCBE(Double_t* xx, Double_t* par)
+ {
+ /// crystal ball + expo + gaussian
+ Double_t x = xx[0];
+
+ Double_t g = par[0]*TMath::Gaus(x,par[1],par[2]);
+
+ Double_t jpsi = funcCB(xx,par+3);
+
+ Double_t expo = par[8]*TMath::Exp(par[9]*x);
+
+ return g+expo+jpsi;
+ }
+
+ Double_t funcCB2(Double_t* xx, Double_t* par)
+ {
+ /// CB2 = extended crystal ball
+
+ Double_t norm = par[0];
+ Double_t alpha = par[1];
+ Double_t n = par[2];
+ Double_t mean = par[3];
+ Double_t sigma = par[4];
+ Double_t alphaprime = par[5];
+ Double_t nprime = par[6];
+
+ Double_t x = xx[0];
+
+ Double_t a = TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-0.5*alpha*alpha);
+ Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
+ Double_t c = TMath::Power(nprime/TMath::Abs(alphaprime),nprime)*TMath::Exp(-0.5*alphaprime*alphaprime);
+ Double_t d = nprime/TMath::Abs(alphaprime) - TMath::Abs(alphaprime);
+
+ Double_t y = ( TMath::Abs(sigma) > 1E-12 ? (x-mean)/sigma : 0 );
+
+ if ( y > alphaprime )
+ {
+ return norm*c*TMath::Power(d+y,-nprime);
+ }
+ else if ( y > alpha*-1.0 )
+ {
+ return norm*TMath::Exp(-0.5*y*y);
+ }
+ else
+ {
+ return norm*a*TMath::Power(b-y,-n);
+ }
+ }
+
+
+ Double_t funcJpsiNA48(Double_t*x, Double_t* par)
+ {
+ /// Fit function from e.q. 4.8 of Ruben's PhD.
+ Double_t c1 = par[0];
+ Double_t c2 = par[1];
+ Double_t d1 = par[2];
+ Double_t d2 = par[3];
+ Double_t g1 = par[4];
+ Double_t g2 = par[5];
+ Double_t m0 = par[6];
+ Double_t sigma1 = par[7];
+ Double_t sigma2 = par[8];
+ Double_t b1 = par[9];
+ Double_t b2 = par[10];
+ Double_t norm = par[11];
+
+ Double_t m = x[0];
+
+ Double_t rv(0);
+
+ if ( m <= c1*m0 )
+ {
+ Double_t e = d1-g1*TMath::Sqrt(c1*m0-m);
+ rv = TMath::Power(b1*(c1*m0-m),e);
+ rv += sigma1;
+ }
+ else if( m >= c1*m0 && m <= m0 )
+ {
+ rv = sigma1;
+ }
+ else if ( m >= m0 && m < c2*m0 )
+ {
+ rv = sigma2;
+ }
+ else if( m >= c2*m0 )
+ {
+ Double_t e = d2-g2*TMath::Sqrt(m-c2*m0);
+ rv = TMath::Power(b2*(m-c2*m0),e);
+ rv += sigma2;
+ }
+
+ return norm*TMath::Exp(-(m-m0)*(m-m0)/(2.0*rv*rv));
+ }
+
+ //------------------------------------------------------------------------------
+ Double_t BackgroundVWG(Double_t *x, Double_t *par)
+ {
+ // gaussian variable width
+ Double_t sigma = par[2]+par[3]*((x[0]-par[1])/par[1]);
+ return par[0]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/(2.*sigma*sigma));
+
+ }
+
+ //------------------------------------------------------------------------------
+ Double_t CrystalBallExtended(Double_t *x,Double_t *par)
+ {
+ //par[0] = Normalization
+ //par[1] = mean
+ //par[2] = sigma
+ //par[3] = alpha
+ //par[4] = n
+ //par[5] = alpha'
+ //par[6] = n'
+
+ Double_t t = (x[0]-par[1])/par[2];
+ if (par[3] < 0) t = -t;
+
+ Double_t absAlpha = fabs((Double_t)par[3]);
+ Double_t absAlpha2 = fabs((Double_t)par[5]);
+
+ if (t >= -absAlpha && t < absAlpha2) // gaussian core
+ {
+ return par[0]*(exp(-0.5*t*t));
+ }
+
+ if (t < -absAlpha) //left tail
+ {
+ Double_t a = TMath::Power(par[4]/absAlpha,par[4])*exp(-0.5*absAlpha*absAlpha);
+ Double_t b = par[4]/absAlpha - absAlpha;
+ return par[0]*(a/TMath::Power(b - t, par[4]));
+ }
+
+ if (t >= absAlpha2) //right tail
+ {
+
+ Double_t c = TMath::Power(par[6]/absAlpha2,par[6])*exp(-0.5*absAlpha2*absAlpha2);
+ Double_t d = par[6]/absAlpha2 - absAlpha2;
+ return par[0]*(c/TMath::Power(d + t, par[6]));
+ }
+
+ return 0. ;
+ }
+
+
+ //---------------------------------------------------------------------------
+// Double_t fitFunctionVWG(Double_t *x, Double_t *par)
+// {
+// if (x[0] > 2.9 && x[0] < 3.3) TF1::RejectPoint();
+// return BackgroundVWG(x, par);
+// }
+
+ //---------------------------------------------------------------------------
+ Double_t fitFunctionCB2VWG(Double_t *x, Double_t *par)
+ {
+ return BackgroundVWG(x, par) + CrystalBallExtended(x, &par[4]);
+ }
+
+ //---------------------------------------------------------------------------
+ Double_t func2CB2VWG(Double_t *x, Double_t *par)
+ {
+ /// 2 extended crystal balls + variable width gaussian
+ /// width of the second CB related to the first (free) one.
+
+ Double_t par2[7] = {
+ par[11],
+ 3.68609+(par[5]-3.096916)/3.096916*3.68609,
+ par[6]/3.096916*3.68609,
+ par[7],
+ par[8],
+ par[9],
+ par[10]
+ };
+ return BackgroundVWG(x, par) + CrystalBallExtended(x, &par[4]) + CrystalBallExtended(x, par2);
+ }
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(TRootIOCtor* /*io*/) :
+AliAnalysisMuMuResult("",""),
+fNofRuns(),
+fNofTriggers(-1),
+fMinv(0x0),
+fBin(),
+fRebin(0),
+fTriggerClass(),
+fEventSelection(),
+fPairSelection(),
+fCentralitySelection()
+{
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const TH1& hminv) :
+AliAnalysisMuMuResult("",""),
+fNofRuns(1),
+fNofTriggers(-1),
+fMinv(0x0),
+fBin(),
+fRebin(0),
+fTriggerClass(),
+fEventSelection(),
+fPairSelection(),
+fCentralitySelection()
+{
+ SetMinv(hminv);
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const TH1& hminv,
+ const char* fitType,
+ Int_t nrebin)
+:
+AliAnalysisMuMuResult(Form("%s:%d",fitType,nrebin),""),
+fNofRuns(1),
+fNofTriggers(-1),
+fMinv(0x0),
+fBin(),
+fRebin(nrebin),
+fTriggerClass(),
+fEventSelection(),
+fPairSelection(),
+fCentralitySelection()
+{
+ SetMinv(hminv);
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const TH1& hminv,
+ const char* triggerName,
+ const char* eventSelection,
+ const char* pairSelection,
+ const char* centSelection,
+ const AliAnalysisMuMuBinning::Range& bin)
+:
+AliAnalysisMuMuResult(Form("%s-%s-%s-%s",triggerName,eventSelection,pairSelection,centSelection),""),
+fNofRuns(1),
+fNofTriggers(-1),
+fMinv(0x0),
+fBin(bin),
+fRebin(1),
+fTriggerClass(triggerName),
+fEventSelection(eventSelection),
+fPairSelection(pairSelection),
+fCentralitySelection(centSelection)
+{
+ SetMinv(hminv);
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult::AliAnalysisMuMuJpsiResult(const AliAnalysisMuMuJpsiResult& rhs)
+:
+AliAnalysisMuMuResult(rhs),
+fNofRuns(rhs.NofRuns()),
+fNofTriggers(rhs.NofTriggers()),
+fMinv(0x0),
+fBin(rhs.Bin()),
+fRebin(rhs.fRebin),
+fTriggerClass(rhs.fTriggerClass),
+fEventSelection(rhs.fEventSelection),
+fPairSelection(rhs.fPairSelection),
+fCentralitySelection(rhs.fCentralitySelection)
+{
+ /// copy ctor
+ /// Note that the mother is lost
+ /// fKeys remains 0x0 so it will be recomputed if need be
+
+ if ( rhs.fMinv )
+ {
+ fMinv = static_cast<TH1*>(rhs.fMinv->Clone());
+ }
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult& AliAnalysisMuMuJpsiResult::operator=(const AliAnalysisMuMuJpsiResult& rhs)
+{
+ /// Assignment operator
+
+ if (this!=&rhs)
+ {
+ static_cast<AliAnalysisMuMuResult&>(*this) = static_cast<const AliAnalysisMuMuResult&>(rhs);
+ delete fMinv;
+
+ if ( rhs.fMinv )
+ {
+ fMinv = static_cast<TH1*>(rhs.fMinv->Clone());
+ }
+
+ fNofRuns = rhs.NofRuns();
+ fNofTriggers = rhs.NofTriggers();
+ fBin = rhs.Bin();
+ fRebin = rhs.fRebin;
+ }
+
+ return *this;
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult::~AliAnalysisMuMuJpsiResult()
+{
+ // dtor
+ delete fMinv;
+}
+
+//_____________________________________________________________________________
+const AliAnalysisMuMuBinning::Range& AliAnalysisMuMuJpsiResult::Bin() const
+{
+ /// Get the bin of this result
+ if ( !Mother() ) return fBin;
+ else return Mother()->Bin();
+}
+
+//_____________________________________________________________________________
+TObject* AliAnalysisMuMuJpsiResult::Clone(const char* /*newname*/) const
+{
+ /// Clone this result
+ return new AliAnalysisMuMuJpsiResult(*this);
+}
+
+//_____________________________________________________________________________
+Bool_t AliAnalysisMuMuJpsiResult::Correct(const AliAnalysisMuMuJpsiResult& other, const char* particle, const char* subResultName)
+{
+ /// Assuming other has an AccxEff entry, correct this value by AccxEff of other
+
+ if ( HasValue(Form("Nof%s",particle)) )
+ {
+ if (!other.HasValue(Form("AccEff%s",particle),subResultName))
+ {
+ AliError(Form("Cannot correct as I do not find the AccEff%s value (subResultName=%s)!",particle,subResultName));
+ return kFALSE;
+ }
+
+ Double_t acc = other.GetValue(Form("AccEff%s",particle),subResultName);
+ Double_t value = 0.0;
+
+ if ( acc > 0 ) value = GetValue(Form("Nof%s",particle)) / acc;
+
+ Double_t error = ErrorAB( GetValue(Form("Nof%s",particle)),
+ GetErrorStat(Form("Nof%s",particle)),
+ other.GetValue(Form("AccEff%s",particle),subResultName),
+ other.GetErrorStat(Form("AccEff%s",particle),subResultName) );
+
+ Set(Form("CorrNof%s",particle),value,error*value);
+
+ return kTRUE;
+ }
+ else
+ {
+ AliError(Form("Result does not have Nof%s : cannot correct it !",particle));
+ }
+ return kFALSE;
+}
+
+//_____________________________________________________________________________
+Double_t AliAnalysisMuMuJpsiResult::CountParticle(const TH1& hminv, const char* particle, Double_t sigma)
+{
+ /// Count the number of entries in an invariant mass range
+
+ const std::map<std::string,Double_t>& m = MassMap();
+
+ std::map<std::string,Double_t>::const_iterator it = m.find(particle);
+
+ if ( it == m.end() )
+ {
+ AliErrorClass(Form("Don't know the mass of particle %s",particle));
+ return 0.0;
+ }
+
+ Double_t mass = it->second;
+
+ if ( sigma < 0 )
+ {
+ AliDebugClass(1,Form("Oups. Got a sigma of %e for particle %s !",sigma,particle));
+ return hminv.Integral();
+ }
+
+ TAxis* x = hminv.GetXaxis();
+
+ Int_t b1 = x->FindBin(mass-sigma);
+ Int_t b2 = x->FindBin(mass+sigma);
+
+ AliDebugClass(1,Form("hminv getentries %e integral %e",hminv.GetEntries(),hminv.Integral(b1,b2)));
+
+ return hminv.Integral(b1,b2);
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsiGCBE(TH1& h)
+{
+ /// Fit Jpsi spectra with crystal ball + gaussian + exponential
+
+ std::cout << "Fit with jpsi alone (gaus + CB + expo)" << std::endl;
+
+ Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
+
+ AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSIGCBE",nrebin);
+
+ TH1* hfit = r->Minv();
+
+ const Double_t xmin(1.0);
+ const Double_t xmax(8.0);
+
+ TF1* fitTotal = new TF1("fitTotal",funcJpsiGCBE,xmin,xmax,10);
+ fitTotal->SetParNames("cste","x0","sigma0","N","alpha","n","mean","sigma","expocste","exposlope");
+
+ fitTotal->SetParLimits(3,0,h.GetMaximum()*2); // N
+
+ const Double_t cbalpha(0.98);
+ const Double_t cbn(5.2);
+
+ fitTotal->FixParameter(4,cbalpha);
+ fitTotal->FixParameter(5,cbn);
+
+ fitTotal->SetParLimits(6,2.8,3.2); // mean
+ fitTotal->SetParLimits(7,0.02,0.3); // sigma
+
+ TF1* fg = new TF1("fg","gaus",xmin,xmax);
+
+ hfit->Fit(fg,"","",0.75,3.0);
+
+ fitTotal->SetParameter(0,fg->GetParameter(0));
+ fitTotal->SetParameter(1,fg->GetParameter(1));
+ fitTotal->SetParameter(2,fg->GetParameter(2));
+
+ TF1* fexpo = new TF1("expo","expo",xmin,xmax);
+
+ hfit->Fit(fexpo,"","",3.5,5);
+
+ fitTotal->SetParameter(8,fexpo->GetParameter(0));
+ fitTotal->SetParameter(9,fexpo->GetParameter(1));
+
+ fitTotal->SetParameter(3,h.GetMaximum()),
+ fitTotal->SetParameter(4,cbalpha);
+ fitTotal->SetParameter(5,cbn);
+ fitTotal->SetParameter(6,3.15);
+ fitTotal->SetParameter(7,0.1);
+
+ const char* fitOption = "QSI+";
+
+ TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"",2,5);
+
+ r->Set("MeanJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
+ r->Set("SigmaJpsi",fitTotal->GetParameter(7),fitTotal->GetParError(7));
+
+ double m = r->GetValue("MeanJpsi");
+ double s = r->GetValue("SigmaJpsi");
+ double n = 3.0;
+
+ TF1* fcb = new TF1("fcb",funcCB,xmin,xmax,5);
+ fcb->SetParameters(fitTotal->GetParameter(3),
+ fitTotal->GetParameter(4),
+ fitTotal->GetParameter(5),
+ fitTotal->GetParameter(6),
+ fitTotal->GetParameter(7));
+
+ fcb->SetLineColor(6);
+ fcb->SetNpx(100);
+ TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(3));
+ TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(3));
+ l1->SetLineColor(6);
+ l2->SetLineColor(6);
+ h.GetListOfFunctions()->Add(fcb);
+ h.GetListOfFunctions()->Add(l1);
+ h.GetListOfFunctions()->Add(l2);
+
+
+ Double_t cbParameters[5];
+ Double_t covarianceMatrix[5][5];
+
+ cbParameters[0] = fitTotal->GetParameter(3);
+ cbParameters[1] = fitTotal->GetParameter(4);
+ cbParameters[2] = fitTotal->GetParameter(5);
+ cbParameters[3] = fitTotal->GetParameter(6);
+ cbParameters[4] = fitTotal->GetParameter(7);
+
+ for ( int iy = 0; iy < 5; ++iy )
+ {
+ for ( int ix = 0; ix < 5; ++ix )
+ {
+ covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+3,iy+3);
+ }
+ }
+
+ double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
+
+ double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
+
+ r->Set("NofJpsi",njpsi,nerr);
+
+ return r;
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsi(TH1& h)
+{
+ /// Fit Jpsi spectra using extended crystall ball (CB2) with free tails
+
+ StdoutToAliDebug(1,std::cout << "Fit with jpsi alone" << std::endl;);
+
+ Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
+
+ AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSI",nrebin);
+
+ TH1* hfit = r->Minv();
+
+ const Double_t xmin(1.5);
+ const Double_t xmax(8.0);
+
+ TF1* fitTotal = new TF1("fitTotal",funcCB2,xmin,xmax,7);
+ fitTotal->SetParNames("N","alphaLow","nLow","mean","sigma","alphaUp","nUp");
+ fitTotal->SetParameters(h.GetMaximum(),1,5,3.1,0.07,1.5,3);
+ fitTotal->SetParLimits(0,0,h.GetMaximum()*2); // N
+ fitTotal->SetParLimits(1,0,10); // alpha
+ fitTotal->SetParLimits(2,0.1,10); // n
+ fitTotal->SetParLimits(3,3,3.15); // mean
+ fitTotal->SetParLimits(4,0.01,1); // sigma
+ fitTotal->SetParLimits(5,0,10); // alpha
+ fitTotal->SetParLimits(6,0.1,10); // n
+
+ hfit->Fit(fitTotal,"QSER+","",2,5);
+
+
+ r->Set("MeanJpsi",fitTotal->GetParameter(3),fitTotal->GetParError(3));
+ r->Set("SigmaJpsi",fitTotal->GetParameter(4),fitTotal->GetParError(4));
+
+ double m = r->GetValue("MeanJpsi");
+ double s = r->GetValue("SigmaJpsi");
+ double n = 10.0;
+
+ r->Set("NofJpsi",fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1),fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1));
+
+ return r;
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsiCB2VWG(const TH1& h)
+{
+ /// Fit Jpsi spectra using extended crystal ball (CB2) + variable width gaussian (VWG)
+
+ StdoutToAliDebug(1,std::cout << "Fit with jpsi VWG" << std::endl;);
+
+ Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
+
+ AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSICB2VWG",nrebin);
+
+
+ TH1* hfit = r->Minv();
+
+ const Double_t xmin(2.0);
+ const Double_t xmax(5.0);
+
+// // gaussian variable width
+// Double_t sigma = par[2]+par[3]*((x[0]-par[1])/par[1]);
+// return par[0]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/(2.*sigma*sigma));
+// Double_t CrystalBallExtended(Double_t *x,Double_t *par)
+// //par[0] = Normalization
+// //par[1] = mean
+// //par[2] = sigma
+// //par[3] = alpha
+// //par[4] = n
+// //par[5] = alpha'
+// //par[6] = n'
+
+ TF1* fitTotal = new TF1("fitTotal",fitFunctionCB2VWG,xmin,xmax,11);
+ fitTotal->SetParNames("kVWG","mVWG","sVWG1","sVWG2","norm","mean","sigma","alpha","n","alpha'","n'");
+
+ fitTotal->SetParameter(0, 10000.); // kVWG
+ fitTotal->SetParameter(1, 1.9); // mVWG
+
+ fitTotal->SetParameter(2, 0.5); // sVWG1
+ fitTotal->SetParLimits(2, 0., 100.);
+
+ fitTotal->SetParameter(3, 0.3); // sVWG2
+ fitTotal->SetParLimits(3, 0., 100.);
+
+ fitTotal->SetParameter(4, h.GetMaximum()); // norm
+
+ fitTotal->SetParameter(5, 3.1); // mean
+ fitTotal->SetParLimits(5, 3.0, 3.2);
+
+ fitTotal->SetParameter(6, 0.08); // sigma
+ fitTotal->SetParLimits(6, 0.04, 0.20);
+
+ fitTotal->SetParameter(7,1.0); // alpha
+ fitTotal->SetParameter(8,5); // n
+ fitTotal->SetParameter(9,2.0); // alpha'
+ fitTotal->SetParameter(10,4); // n'
+
+// fitTotal->FixParameter(7, 0.93);
+// fitTotal->FixParameter(8, 5.59);
+// fitTotal->FixParameter(9, 2.32);
+// fitTotal->FixParameter(10, 3.39);
+// fitTotal->SetParameter(11, 10.);
+
+ const char* fitOption = "QSIER"; //+";
+
+ TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
+
+ r->Set("MeanJpsi",fitTotal->GetParameter(5),fitTotal->GetParError(5));
+ r->Set("SigmaJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
+
+ double m = r->GetValue("MeanJpsi");
+ double s = r->GetValue("SigmaJpsi");
+ double n = 3.0;
+
+ TF1* fcb = new TF1("fcb",CrystalBallExtended,xmin,xmax,7);
+ fcb->SetParameters(fitTotal->GetParameter(4),
+ fitTotal->GetParameter(5),
+ fitTotal->GetParameter(6),
+ fitTotal->GetParameter(7),
+ fitTotal->GetParameter(8),
+ fitTotal->GetParameter(9),
+ fitTotal->GetParameter(10));
+
+
+ fcb->SetLineColor(1);
+ fcb->SetNpx(1000);
+ TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(4));
+ TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(4));
+ l1->SetLineColor(6);
+ l2->SetLineColor(6);
+ hfit->GetListOfFunctions()->Add(fcb);
+ hfit->GetListOfFunctions()->Add(l1);
+ hfit->GetListOfFunctions()->Add(l2);
+
+ Double_t cbParameters[7];
+ Double_t covarianceMatrix[7][7];
+
+ for ( int ix = 0; ix < 7; ++ix )
+ {
+ cbParameters[ix] = fitTotal->GetParameter(ix+4);
+ }
+
+ for ( int iy = 0; iy < 5; ++iy )
+ {
+ for ( int ix = 0; ix < 5; ++ix )
+ {
+ covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+4,iy+4);
+ }
+ }
+
+ double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
+ double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
+
+ r->Set("NofJpsi",njpsi,nerr);
+
+ return r;
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsi2CB2VWG(const TH1& h,
+ Double_t alphaLow,
+ Double_t nLow,
+ Double_t alphaUp,
+ Double_t nUp)
+{
+ /// Fit using extended crystal ball + variable width gaussian
+
+ StdoutToAliDebug(1,std::cout << Form("Fit with jpsi + psiprime VWG alphaLow=%5.2f nLow=%5.2f alphaUp=%5.2f nUp=%5.2f",
+ alphaLow,nLow,alphaUp,nUp) << std::endl;);
+
+ Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
+
+ TString resultName("JPSI2CB2VWG");
+ if ( alphaLow > 0 )
+ {
+ resultName += TString::Format("alphaLow=%5.2f",alphaLow);
+ }
+ if ( nLow > 0 )
+ {
+ resultName += TString::Format("nLow=%5.2f",nLow);
+ }
+ if ( alphaUp > 0 )
+ {
+ resultName += TString::Format("alphaUp=%5.2f",alphaUp);
+ }
+ if ( nUp > 0 )
+ {
+ resultName += TString::Format("nUp=%5.2f",nUp);
+ }
+ resultName.ReplaceAll(" ","");
+
+ AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,resultName.Data(),nrebin);
+
+ TH1* hfit = r->Minv();
+
+ const Double_t xmin(2.2);
+ const Double_t xmax(5.0);
+
+ TF1* fitTotal = new TF1("fitTotal",func2CB2VWG,xmin,xmax,12);
+ fitTotal->SetParNames("kVWG","mVWG","sVWG1","sVWG2","kPsi","mPsi","sPsi","alPsi","nlPsi","auPsi","nuPsi");
+ fitTotal->SetParName(11, "kPsi'");
+
+ fitTotal->SetParameter(0, 10000.);
+ fitTotal->SetParameter(1, 1.9);
+ fitTotal->SetParameter(2, 0.5);
+ fitTotal->SetParLimits(2, 0., 100.);
+ fitTotal->SetParameter(3, 0.3);
+ fitTotal->SetParLimits(3, 0., 100.);
+ fitTotal->SetParameter(4, 100.);
+ fitTotal->SetParameter(5, 3.1);
+ fitTotal->SetParLimits(5, 3.08, 3.2);
+ fitTotal->SetParameter(6, 0.08);
+ fitTotal->SetParLimits(6, 0.05, 0.15);
+
+// r = FitJpsi2CB2VWG(*hminv,0.93,5.59,2.32,3.39);
+
+ if ( alphaLow > 0 )
+ {
+ fitTotal->FixParameter(7, alphaLow);
+ }
+ else
+ {
+ fitTotal->SetParameter(7,0.9);
+ fitTotal->SetParLimits(7,0.1,10.0);
+ }
+
+ if ( nLow > 0 )
+ {
+ fitTotal->FixParameter(8, nLow);
+ }
+ else
+ {
+ fitTotal->SetParameter(8,5.0);
+ fitTotal->SetParLimits(8,0.0,10.0);
+ }
+
+ if ( alphaUp > 0 )
+ {
+ fitTotal->FixParameter(9, alphaUp);
+ }
+ else
+ {
+ fitTotal->SetParameter(9, 2.0);
+ fitTotal->SetParLimits(9,0.1,10.0);
+ }
+
+ if ( nUp > 0 )
+ {
+ fitTotal->FixParameter(10, nUp);
+ }
+ else
+ {
+ fitTotal->SetParameter(10,3.0);
+ fitTotal->SetParLimits(10,0.0,10.0);
+ }
+
+ fitTotal->SetParameter(11, 10.);
+
+ const char* fitOption = "QSER"; //+";
+
+ TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
+
+ r->Set("MeanJpsi",fitTotal->GetParameter(5),fitTotal->GetParError(5));
+ r->Set("SigmaJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
+
+ double m = r->GetValue("MeanJpsi");
+ double s = r->GetValue("SigmaJpsi");
+ double n = 3.0;
+
+ TF1* fcb = new TF1("fcb",CrystalBallExtended,xmin,xmax,7);
+ fcb->SetParameters(fitTotal->GetParameter(4),
+ fitTotal->GetParameter(5),
+ fitTotal->GetParameter(6),
+ fitTotal->GetParameter(7),
+ fitTotal->GetParameter(8),
+ fitTotal->GetParameter(9),
+ fitTotal->GetParameter(10));
+
+
+ fcb->SetLineColor(1);
+ fcb->SetNpx(1000);
+ TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(4));
+ TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(4));
+ l1->SetLineColor(6);
+ l2->SetLineColor(6);
+ hfit->GetListOfFunctions()->Add(fcb);
+ hfit->GetListOfFunctions()->Add(l1);
+ hfit->GetListOfFunctions()->Add(l2);
+
+ Double_t cbParameters[7];
+ Double_t covarianceMatrix[7][7];
+
+ for ( int ix = 0; ix < 7; ++ix )
+ {
+ cbParameters[ix] = fitTotal->GetParameter(ix+4);
+ }
+
+ for ( int iy = 0; iy < 5; ++iy )
+ {
+ for ( int ix = 0; ix < 5; ++ix )
+ {
+ covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+4,iy+4);
+ }
+ }
+
+ double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
+ double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
+
+ r->Set("NofJpsi",njpsi,nerr);
+
+ return r;
+}
+
+//_____________________________________________________________________________
+AliAnalysisMuMuJpsiResult* AliAnalysisMuMuJpsiResult::FitJpsiNA48(const TH1& h)
+{
+ /// fit using functional form from Ruben Shahoyan's thesis (2001) (eq. 4.8.)
+
+ StdoutToAliDebug(1,std::cout << "Fit with jpsi NA50 Ruben eq. 4.8" << std::endl;);
+
+ Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
+
+ AliAnalysisMuMuJpsiResult* r = new AliAnalysisMuMuJpsiResult(h,"JPSINA",nrebin);
+
+ TH1* hfit = r->Minv();
+
+ const Double_t xmin(2.0);
+ const Double_t xmax(5.0);
+
+ TF1* fitTotal = new TF1("fitTotal",funcJpsiNA48,xmin,xmax,12);
+
+ fitTotal->SetParName( 0, "c1");
+ fitTotal->FixParameter(0,0.97);
+
+ fitTotal->SetParName( 1, "c2");
+ fitTotal->FixParameter(1,1.05);
+
+ fitTotal->SetParName( 2, "d1");
+ fitTotal->SetParameter(2,0.0);
+ fitTotal->SetParLimits(2,0,1);
+
+ fitTotal->SetParName( 3, "d2");
+ fitTotal->SetParameter(3,0.0);
+ fitTotal->SetParLimits(3,0,1);
+
+ fitTotal->SetParName( 4, "g1");
+ fitTotal->SetParameter(4,0.0);
+ fitTotal->SetParLimits(4,0.0,1);
+
+ fitTotal->SetParName( 5, "g2");
+ fitTotal->SetParameter(5,0.0);
+ fitTotal->SetParLimits(5,0.0,1);
+
+ fitTotal->SetParName( 6, "m0");
+ fitTotal->SetParameter(6,3.1);
+ fitTotal->SetParLimits(6,2.8,3.4);
+
+ fitTotal->SetParName( 7, "sigma1");
+ fitTotal->SetParameter(7,0.05);
+ fitTotal->SetParLimits(7,0.01,0.2);
+
+ fitTotal->SetParName( 8, "sigma2");
+ fitTotal->SetParameter(8,0.05);
+ fitTotal->SetParLimits(8,0.01,0.2);
+
+ fitTotal->SetParName( 9, "b1");
+ fitTotal->SetParameter(9,1.0);
+ fitTotal->SetParLimits(9,0,1);
+
+ fitTotal->SetParName(10, "b2");
+ fitTotal->SetParameter(10,1.0);
+ fitTotal->SetParLimits(10,0,1);
+
+ fitTotal->SetParName(11, "norm");
+ fitTotal->SetParameter(11,h.GetMaximum());
+
+ const char* fitOption = "QSIER"; //+";
+
+ TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
+
+ r->Set("MeanJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
+ r->Set("SigmaJpsi",
+ fitTotal->GetParameter(7)+fitTotal->GetParameter(8),
+ 0.0);
+
+ double m = r->GetValue("MeanJpsi");
+ double s = r->GetValue("SigmaJpsi");
+ double n = 3.0;
+
+ TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(11));
+ TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(11));
+ l1->SetLineColor(6);
+ l2->SetLineColor(6);
+ hfit->GetListOfFunctions()->Add(l1);
+ hfit->GetListOfFunctions()->Add(l2);
+
+ double njpsi = fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
+ double nerr = fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1);
+
+ r->Set("NofJpsi",njpsi,nerr);
+
+ return r;
+}
+
+//_____________________________________________________________________________
+Bool_t AliAnalysisMuMuJpsiResult::AddFit(const char* fitType, Int_t npar, Double_t* par)
+{
+ // Add a fit to this result
+
+ TString msg(Form("fitType=%s npar=%d par[]=",fitType,npar));
+
+ for ( Int_t i = 0; i < npar; ++i )
+ {
+ msg += TString::Format("%e,",par[i]);
+ }
+
+ msg += TString::Format(" minv=%p %d",fMinv,fMinv?TMath::Nint(fMinv->GetEntries()):0);
+
+ if ( !fMinv ) return kFALSE;
+
+ TString sFitType(fitType);
+ sFitType.ToUpper();
+ Int_t nrebin(1);
+
+ if (sFitType.CountChar(':'))
+ {
+ Int_t index = sFitType.Index(":");
+ nrebin = TString(sFitType(index+1,sFitType.Length()-index-1)).Atoi();
+ sFitType = sFitType(0,index);
+ }
+
+ msg += TString::Format(" nrebin=%d",nrebin);
+
+ AliDebug(1,msg.Data());
+
+
+ if ( fMinv->GetEntries()<100 && !sFitType.Contains("COUNT")) return kFALSE;
+
+ TH1* hminv = static_cast<TH1*>(fMinv->Clone());
+
+ hminv->Rebin(nrebin);
+ hminv->SetDirectory(0);
+
+ AliAnalysisMuMuJpsiResult* r(0x0);
+
+ if ( sFitType=="PSI1")
+ {
+ r = FitJpsi(*hminv);
+ }
+ else if ( sFitType == "PSILOW")
+ {
+ r = FitJpsi2CB2VWG(*hminv,-1,-1,-1,-1); // free tails
+ }
+ else if ( sFitType == "PSILOWMCTAILS" )
+ {
+ if ( npar!= 4 )
+ {
+ AliError("Cannot use PSILOWMCTAILS without being given the MC tails !");
+ delete hminv;
+ return kFALSE;
+ }
+ r = FitJpsi2CB2VWG(*hminv,par[0],par[1],par[2],par[3]);
+ if (r)
+ {
+ r->SetAlias("MCTAILS");
+ }
+ }
+ else if ( sFitType.BeginsWith("PSILOWALPHA") )
+ {
+ Float_t lpar[] = { 0.0, 0.0, 0.0, 0.0 };
+
+ AliDebug(1,Form("sFitType=%s",sFitType.Data()));
+
+ sscanf(sFitType.Data(),"PSILOWALPHALOW%fNLOW%fALPHAUP%fNUP%f",
+ &lpar[0],&lpar[1],&lpar[2],&lpar[3]);
+
+ AliDebug(1,Form("PSILOW ALPHALOW=%f NLOW=%f ALPHAUP=%f NUP=%f",lpar[0],lpar[1],lpar[2],lpar[3]));
+
+ if ( lpar[0] == 0.0 && lpar[1] == 0.0 && lpar[0] == 0.0 && lpar[1] == 0.0 )
+ {
+ AliError("Cannot work with zero tails !");
+ }
+ else
+ {
+ r = FitJpsi2CB2VWG(*hminv,lpar[0],lpar[1],lpar[2],lpar[3]);
+ }
+ }
+ else if ( sFitType == "COUNTJPSI" )
+ {
+ r = new AliAnalysisMuMuJpsiResult(*hminv,"COUNTJPSI",1);
+ Double_t n = CountParticle(*hminv,"Jpsi");
+ r->Set("NofJpsi",n,TMath::Sqrt(n));
+ }
+
+
+ if ( r )
+ {
+ StdoutToAliDebug(1,r->Print(););
+ r->SetBin(Bin());
+ r->SetNofTriggers(NofTriggers());
+ r->SetNofRuns(NofRuns());
+
+ AdoptSubResult(r);
+ }
+
+ delete hminv;
+
+ return (r!=0x0);
+}
+
+//_____________________________________________________________________________
+Long64_t AliAnalysisMuMuJpsiResult::Merge(TCollection* list)
+{
+ /// Merge method
+ ///
+ /// Merge a list of AliAnalysisMuMuJpsiResult objects with this
+ /// Returns the number of merged objects (including this).
+ ///
+ /// Note that the merging is to be understood here as an weighted mean operation
+ ///
+ /// FIXME ! (compared to base class Merge, should only Minv merging ?)
+
+ AliError("Implement me !");
+ if (!list) return 0;
+
+ if (list->IsEmpty()) return 1;
+
+ return 0;
+
+}
+
+//_____________________________________________________________________________
+Int_t AliAnalysisMuMuJpsiResult::NofRuns() const
+{
+ /// Get the number of runs
+ if ( !Mother() ) return fNofRuns;
+ else return Mother()->NofRuns();
+}
+
+//_____________________________________________________________________________
+Int_t AliAnalysisMuMuJpsiResult::NofTriggers() const
+{
+ /// Get the number of triggers
+
+ if ( !Mother() ) return fNofTriggers;
+ else return Mother()->NofTriggers();
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::Print(Option_t* opt) const
+{
+ /// printout
+
+ std::cout << Form("NRUNS %d - NTRIGGER %10d - %s",
+ NofRuns(),
+ NofTriggers(),
+ fBin.AsString().Data());
+
+ AliAnalysisMuMuResult::Print(opt);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::PrintValue(const char* key, const char* opt, Double_t value, Double_t errorStat,
+ Double_t rms) const
+{
+ /// exclude the particles with zero stat
+
+ const std::map<std::string,Double_t>& m = MassMap();
+
+ for( std::map<std::string,Double_t>::const_iterator it = m.begin(); it != m.end(); ++it )
+ {
+ TString particle(it->first.c_str());
+
+ if (TString(key).Contains(particle.Data()))
+ {
+ if ( GetValue("Nof%s",particle.Data()) <= 0.0 ) return;
+ }
+ }
+
+ AliAnalysisMuMuResult::PrintValue(key,opt,value,errorStat,rms);
+
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::PrintParticle(const char* particle, const char* opt) const
+{
+ /// Print all information about one particule type
+
+ Double_t npart = GetValue(Form("Nof%s",particle));
+ if (npart<=0) return;
+
+
+ std::cout << opt << Form("\t%s",particle) << std::endl;
+
+ // Double_t npartError = GetErrorStat(Form("Nof%s",particle));
+// std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f","Count",npart,npartError) << std::endl;
+
+ TIter next(Keys());
+ TObjString* key;
+
+ while ( ( key = static_cast<TObjString*>(next()) ) )
+ {
+ if ( !key->String().Contains(particle) ) continue;
+
+ PrintValue(key->String(),opt,GetValue(key->String()),GetErrorStat(key->String()),GetRMS(key->String()));
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::SetBin(const AliAnalysisMuMuBinning::Range& bin)
+{
+ /// Set the bin
+
+ if (!Mother()) fBin = bin;
+ else Mother()->SetBin(bin);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::SetNofInputParticles(const TH1& hminv)
+{
+ /// Set the number of input particle from the invariant mass spectra
+
+ static const char* particleNames[] = { "Jpsi" , "PsiPrime", "Upsilon","UpsilonPrime" };
+
+ const std::map<std::string,Double_t>& m = MassMap();
+
+ for ( Int_t i = 0; i < 4; ++i )
+ {
+ std::map<std::string,Double_t>::const_iterator it = m.find(particleNames[i]);
+
+ Double_t sigma(-1.0);
+
+ if (it != m.end() )
+ {
+ sigma = it->second*0.1;
+ }
+
+ Double_t n = CountParticle(hminv,particleNames[i],sigma);
+
+ AliDebug(1,Form("i=%d particle %s n %e",i,particleNames[i],n));
+
+ if ( n > 0 )
+ {
+ SetNofInputParticles(particleNames[i],TMath::Nint(n));
+ }
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::SetNofInputParticles(const char* particle, int n)
+{
+ /// Set the number of input particles (so it is a MC result)
+ /// and (re)compute the AccxEff values
+
+ Set(Form("NofInput%s",particle),n,TMath::Sqrt(n));
+
+ if (n<=0)
+ {
+ Set(Form("AccEff%s",particle),0,0);
+ return;
+ }
+
+ Double_t npart = GetValue(Form("Nof%s",particle));
+ Double_t npartErr = GetErrorStat(Form("Nof%s",particle));
+ Double_t ninput = GetValue(Form("NofInput%s",particle));
+ Double_t ninputErr = GetErrorStat(Form("NofInput%s",particle));
+
+ Set(Form("AccEff%s",particle),
+ npart/ninput,
+ (npart/ninput)*ErrorAB(npart,npartErr,ninput,ninputErr));
+
+ TIter next(SubResults());
+ AliAnalysisMuMuJpsiResult* r;
+
+ while ( ( r = static_cast<AliAnalysisMuMuJpsiResult*>(next())) )
+ {
+ r->Set(Form("NofInput%s",particle),n,TMath::Sqrt(n));
+
+ npart = r->GetValue(Form("Nof%s",particle));
+ npartErr = r->GetErrorStat(Form("Nof%s",particle));
+
+ r->Set(Form("AccEff%s",particle),
+ npart/ninput,
+ (npart/ninput)*ErrorAB(npart,npartErr,ninput,ninputErr));
+
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::SetNofRuns(Int_t n)
+{
+ if ( !Mother() ) fNofRuns=n;
+ else Mother()->SetNofRuns(n);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::SetNofTriggers(Int_t n)
+{
+ if ( !Mother() ) fNofTriggers=n;
+ else Mother()->SetNofTriggers(n);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuJpsiResult::SetMinv(const TH1& hminv)
+{
+ /// Set the inv. mass spectrum to be fitted.
+ static UInt_t n(0);
+
+ delete fMinv;
+ fMinv = static_cast<TH1*>(hminv.Clone(Form("Minv%u",n++)));
+ fMinv->SetDirectory(0);
+}
--- /dev/null
+#ifndef ALIANALYSISMUMUJPSIRESULT_H
+#define ALIANALYSISMUMUJPSIRESULT_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+///
+/// AliAnalysisMuMuJpsiResult : helper class to store Jpsi results from
+/// AliAnalysisTaskMuMu
+///
+/// author : Laurent Aphecetche (Subatech)
+
+#include "TNamed.h"
+#include <TString.h>
+#include "AliAnalysisMuMuResult.h"
+#include "AliAnalysisMuMuBinning.h"
+
+class TH1;
+class THashList;
+class TF1;
+class TMap;
+
+class AliAnalysisMuMuJpsiResult : public AliAnalysisMuMuResult
+{
+
+public:
+
+ AliAnalysisMuMuJpsiResult(TRootIOCtor* io);
+
+ AliAnalysisMuMuJpsiResult(const TH1& hminv);
+
+ AliAnalysisMuMuJpsiResult(const TH1& hminv,
+ const char* fitType,
+ Int_t nrebin);
+
+ AliAnalysisMuMuJpsiResult(const TH1& hminv,
+ const char* triggerClass,
+ const char* eventSelection,
+ const char* pairSelection,
+ const char* centSelection,
+ const AliAnalysisMuMuBinning::Range& bin);
+
+ AliAnalysisMuMuJpsiResult(const AliAnalysisMuMuJpsiResult& rhs);
+ AliAnalysisMuMuJpsiResult& operator=(const AliAnalysisMuMuJpsiResult& rhs);
+
+ virtual ~AliAnalysisMuMuJpsiResult();
+
+ virtual TObject* Clone(const char* newname = "") const;
+
+ Bool_t Correct(const AliAnalysisMuMuJpsiResult& other, const char* particle, const char* subResultName="");
+
+ TH1* Minv() const { return fMinv; }
+
+ Int_t NofTriggers() const;
+
+ void SetNofTriggers(Int_t n);
+
+ void Print(Option_t* opt="") const;
+
+ Bool_t AddFit(const char* fitType, Int_t npar=0, Double_t* par=0x0);
+
+ AliAnalysisMuMuJpsiResult* CountJpsi(TH1& h);
+
+ AliAnalysisMuMuJpsiResult* FitJpsi(TH1& h);
+
+ AliAnalysisMuMuJpsiResult* FitJpsiNA48(const TH1& h);
+ AliAnalysisMuMuJpsiResult* FitJpsiCB2VWG(const TH1& h);
+ AliAnalysisMuMuJpsiResult* FitJpsi2CB2VWG(const TH1& h, Double_t alphaLow=-1.0, Double_t nLow=-1.0, Double_t alphaUp=-1.0, Double_t nUp=-1.0);
+
+ AliAnalysisMuMuJpsiResult* FitJpsiGCBE(TH1& h);
+
+ Int_t NofRuns() const;
+
+ void SetNofRuns(int n);
+
+ const AliAnalysisMuMuBinning::Range& Bin() const;
+
+ void SetBin(const AliAnalysisMuMuBinning::Range& bin);
+
+ void SetNofInputParticles(const char* particle, int n);
+
+ void SetNofInputParticles(const TH1& hminv);
+
+ void SetMinv(const TH1& hminv);
+
+ Long64_t Merge(TCollection* list);
+
+ static Double_t CountParticle(const TH1& hminv, const char* particle, Double_t sigma=-1.0);
+
+ virtual AliAnalysisMuMuJpsiResult* Mother() const { return static_cast<AliAnalysisMuMuJpsiResult*>(AliAnalysisMuMuResult::Mother()); }
+
+ void PrintValue(const char* key, const char* opt, Double_t value, Double_t errorStat, Double_t rms=0.0) const;
+
+private:
+
+ enum EIndex
+ {
+ kValue=0,
+ kErrorStat=1
+ };
+
+ void PrintParticle(const char* particle, const char* opt) const;
+
+private:
+ Int_t fNofRuns; // number of runs used to get this result
+ Int_t fNofTriggers; // number of trigger analyzed
+ TH1* fMinv; // invariant mass spectrum
+ AliAnalysisMuMuBinning::Range fBin; // bin range
+ Int_t fRebin; // rebin level of minv spectra
+
+ TString fTriggerClass; // trigger class for this result
+ TString fEventSelection; // event selection for this result
+ TString fPairSelection; // pair selection for this result
+ TString fCentralitySelection; // centrality selection for this result
+
+ ClassDef(AliAnalysisMuMuJpsiResult,1) // a class to hold invariant mass analysis results (counts, yields, AccxEff, R_AB, etc...)
+};
+
+#endif
* provided "as is" without express or implied warranty. *
**************************************************************************/
-
-// $Id$
+///
+/// Base class to hold a set of results for the same quantity,
+/// computed using various methods, each with their errors
+///
+/// author: Laurent Aphecetche (Subatech)
+///
#include "AliAnalysisMuMuResult.h"
ClassImp(AliAnalysisMuMuResult)
-#include "TF1.h"
-#include "TFitResult.h"
-#include "TH1.h"
-#include "TH2.h"
#include "THashList.h"
#include "TLine.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TParameter.h"
-#include "AliAnalysisMuMuBinning.h"
-#include "AliHistogramCollection.h"
#include "AliLog.h"
#include <map>
-const std::map<std::string,Double_t>& MassMap()
-{
- /// a simple map of masses...
- static std::map<std::string,Double_t> massMap;
- // not super elegant, but that way we do not depend on TDatabasePDG and thus
- // can decide on our particle naming
- if (massMap.empty())
- {
- massMap["Jpsi"] = 3.096916e+00;
- massMap["PsiPrime"] = 3.68609e+00;
- massMap["Upsilon"] = 9.46030e+00;
- massMap["UpsilonPrime"] = 1.00233e+01;
- }
- return massMap;
-}
-
-
-Double_t funcCB(Double_t* xx, Double_t* par)
-{
- /// Crystal ball
-
- Double_t norm = par[0];
- Double_t alpha = par[1];
- Double_t n = par[2];
- Double_t mean = par[3];
- Double_t sigma = par[4];
-
- Double_t x = xx[0];
-
- Double_t a = TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-0.5*alpha*alpha);
- Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
-
- Double_t y = ( TMath::Abs(sigma) > 1E-12 ? (x-mean)/sigma : 0 );
-
- if ( y > alpha*-1.0 )
- {
- return norm*TMath::Exp(-0.5*y*y);
- }
- else
- {
- return norm*a*TMath::Power(b-y,-n);
- }
-}
-
-Double_t funcJpsiGCBE(Double_t* xx, Double_t* par)
-{
- /// crystal ball + expo + gaussian
- Double_t x = xx[0];
-
- Double_t g = par[0]*TMath::Gaus(x,par[1],par[2]);
-
- Double_t jpsi = funcCB(xx,par+3);
-
- Double_t expo = par[8]*TMath::Exp(par[9]*x);
-
- return g+expo+jpsi;
-}
-
-Double_t funcJpsiPsiPrimeCustom(Double_t* xx, Double_t* par)
-{
- // custom fit for jpsi + psi prime
-
- Double_t norm = par[0];
- Double_t alpha = par[1];
- Double_t n = par[2];
- Double_t mean = par[3];
- Double_t sigma = par[4];
- Double_t alphaprime = par[5];
- Double_t nprime = par[6];
-
- Double_t x = xx[0];
-
- Double_t a = TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-0.5*alpha*alpha);
- Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
- Double_t c = TMath::Power(nprime/TMath::Abs(alphaprime),nprime)*TMath::Exp(-0.5*alphaprime*alphaprime);
- Double_t d = nprime/TMath::Abs(alphaprime) - TMath::Abs(alphaprime);
-
- Double_t y = ( TMath::Abs(sigma) > 1E-12 ? (x-mean)/sigma : 0 );
-
- Double_t cb(0);
-
- if ( y > alphaprime )
- {
- cb = norm*c*TMath::Power(d+y,-nprime);
- }
- else if ( y > alpha*-1.0 )
- {
- cb = norm*TMath::Exp(-0.5*y*y);
- }
- else
- {
- cb = norm*a*TMath::Power(b-y,-n);
- }
-
- if ( x < mean )
- {
- return cb + par[7] + par[8]*x; // gaus + pol1
- }
- else
- {
- Double_t yprime = (x-par[10])/par[11];
- return cb + par[9]*TMath::Exp(-0.5*yprime*yprime)+par[12]*TMath::Exp(-par[13]*x);
- // gaus (j/psi) + gaus (psi') + expo
- }
-}
-
-
-Double_t funcCB2(Double_t* xx, Double_t* par)
-{
- /// CB2 = extended crystal ball
-
- Double_t norm = par[0];
- Double_t alpha = par[1];
- Double_t n = par[2];
- Double_t mean = par[3];
- Double_t sigma = par[4];
- Double_t alphaprime = par[5];
- Double_t nprime = par[6];
-
- Double_t x = xx[0];
-
- Double_t a = TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-0.5*alpha*alpha);
- Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
- Double_t c = TMath::Power(nprime/TMath::Abs(alphaprime),nprime)*TMath::Exp(-0.5*alphaprime*alphaprime);
- Double_t d = nprime/TMath::Abs(alphaprime) - TMath::Abs(alphaprime);
-
- Double_t y = ( TMath::Abs(sigma) > 1E-12 ? (x-mean)/sigma : 0 );
-
- if ( y > alphaprime )
- {
- return norm*c*TMath::Power(d+y,-nprime);
- }
- else if ( y > alpha*-1.0 )
- {
- return norm*TMath::Exp(-0.5*y*y);
- }
- else
- {
- return norm*a*TMath::Power(b-y,-n);
- }
-}
-
-Double_t funcJpsiPsiPrime(Double_t* xx, Double_t* par)
-{
- /// CB + CB2
-
- Double_t jpsi = funcCB(xx,par);
- Double_t psiprime = funcCB2(xx,par+5);
-
- int n = 10;
- Double_t x = xx[0];
-
- Double_t e1 = par[n]*TMath::Exp(par[n+1]*x);
- Double_t e2 = par[n+2]*TMath::Exp(par[n+3]*x);
-
- Double_t e = e1;
-
- if ( x > par[3] ) e=e2;
-
- return jpsi+psiprime+e;
-}
-
-Double_t funcJpsiCBE(Double_t* xx, Double_t* par)
-{
- // CB + expo
-
- Double_t jpsi = funcCB(xx,par);
-
- Double_t x = xx[0];
-
- Double_t e1 = par[5]*TMath::Exp(par[6]*x);
-
- return jpsi+e1;
-}
-
-
-Double_t funcJpsiPCBE(Double_t* xx, Double_t* par)
-{
- // CB + expo + pol2
-
- Double_t x = xx[0];
-
- Double_t pol2 = par[0] + par[1]*x + par[2]*x*x;
-
- Double_t jpsi = funcCB(xx,par+3);
-
- Double_t expo = par[8]*TMath::Exp(par[9]*x);
-
- return pol2+jpsi+expo;
-}
-
-Double_t funcJpsiECBE(Double_t* xx, Double_t* par)
-{
- // CB + expo
-
- Double_t jpsi = funcCB(xx,par+2);
-
- Double_t x = xx[0];
-
- Double_t e1 = par[0]*TMath::Exp(par[1]*x);
-
- Double_t e2 = par[7]*TMath::Exp(par[8]*x);
-
- return e1+e2+jpsi;
-}
-
-Double_t funcJpsiNA48(Double_t*x, Double_t* par)
-{
- /// Fit function from e.q. 4.8 of Ruben's PhD.
- Double_t c1 = par[0];
- Double_t c2 = par[1];
- Double_t d1 = par[2];
- Double_t d2 = par[3];
- Double_t g1 = par[4];
- Double_t g2 = par[5];
- Double_t m0 = par[6];
- Double_t sigma1 = par[7];
- Double_t sigma2 = par[8];
- Double_t b1 = par[9];
- Double_t b2 = par[10];
- Double_t norm = par[11];
-
- Double_t m = x[0];
-
- Double_t rv(0);
-
- if ( m <= c1*m0 )
- {
- Double_t e = d1-g1*TMath::Sqrt(c1*m0-m);
- rv = TMath::Power(b1*(c1*m0-m),e);
- rv += sigma1;
- }
- else if( m >= c1*m0 && m <= m0 )
- {
- rv = sigma1;
- }
- else if ( m >= m0 && m < c2*m0 )
- {
- rv = sigma2;
- }
- else if( m >= c2*m0 )
- {
- Double_t e = d2-g2*TMath::Sqrt(m-c2*m0);
- rv = TMath::Power(b2*(m-c2*m0),e);
- rv += sigma2;
- }
-
- return norm*TMath::Exp(-(m-m0)*(m-m0)/(2.0*rv*rv));
-}
-
-const char* NormalizeName(const char* name, const char* suffix)
-{
- /// Remove - and / from the name, and adds _suffix
-
- TString str(Form("%s_%s",name,suffix));
-
- str.ReplaceAll("-","_");
- str.ReplaceAll("/","%");
-
- return str.Data();
-}
-
-//------------------------------------------------------------------------------
-Double_t BackgroundVWG(Double_t *x, Double_t *par)
-{
- // gaussian variable width
- Double_t sigma = par[2]+par[3]*((x[0]-par[1])/par[1]);
- return par[0]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/(2.*sigma*sigma));
-
-}
-
-//------------------------------------------------------------------------------
-Double_t CrystalBallExtended(Double_t *x,Double_t *par)
-{
- //par[0] = Normalization
- //par[1] = mean
- //par[2] = sigma
- //par[3] = alpha
- //par[4] = n
- //par[5] = alpha'
- //par[6] = n'
-
- Double_t t = (x[0]-par[1])/par[2];
- if (par[3] < 0) t = -t;
-
- Double_t absAlpha = fabs((Double_t)par[3]);
- Double_t absAlpha2 = fabs((Double_t)par[5]);
-
- if (t >= -absAlpha && t < absAlpha2) // gaussian core
- {
- return par[0]*(exp(-0.5*t*t));
- }
-
- if (t < -absAlpha) //left tail
- {
- Double_t a = TMath::Power(par[4]/absAlpha,par[4])*exp(-0.5*absAlpha*absAlpha);
- Double_t b = par[4]/absAlpha - absAlpha;
- return par[0]*(a/TMath::Power(b - t, par[4]));
- }
-
- if (t >= absAlpha2) //right tail
- {
-
- Double_t c = TMath::Power(par[6]/absAlpha2,par[6])*exp(-0.5*absAlpha2*absAlpha2);
- Double_t d = par[6]/absAlpha2 - absAlpha2;
- return par[0]*(c/TMath::Power(d + t, par[6]));
- }
-
- return 0. ;
-}
-
-//------------------------------------------------------------------------------
-Double_t Gaus(Double_t *x, Double_t *par)
-{
- // gaussian
- return par[0]/TMath::Sqrt(2.*TMath::Pi())/par[2]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/(2.*par[2]*par[2]));
-
-}
-
-//------------------------------------------------------------------------------
-Double_t Exp(Double_t *x, Double_t *par)
-{
- // exponential
- return par[0]*TMath::Exp(par[1]*x[0]);
-
-}
-
-//------------------------------------------------------------------------------
-Double_t Pow(Double_t *x, Double_t *par)
-{
- // power law
- return par[0]*TMath::Power(x[0],par[1]);
-
-}
-
-//------------------------------------------------------------------------------
-Double_t fitFunctionVWG(Double_t *x, Double_t *par)
-{
- if (x[0] > 2.9 && x[0] < 3.3) TF1::RejectPoint();
- return BackgroundVWG(x, par);
-}
-
-//------------------------------------------------------------------------------
-Double_t fitFunctionCB2VWG(Double_t *x, Double_t *par)
-{
- return BackgroundVWG(x, par) + CrystalBallExtended(x, &par[4]);
-}
-
-//------------------------------------------------------------------------------
-Double_t func2CB2VWG(Double_t *x, Double_t *par)
-{
- /// 2 extended crystal balls + variable width gaussian
- /// width of the second CB related to the first (free) one.
-
- Double_t par2[7] = {
- par[11],
- 3.68609+(par[5]-3.096916)/3.096916*3.68609,
- par[6]/3.096916*3.68609,
- par[7],
- par[8],
- par[9],
- par[10]
- };
- return BackgroundVWG(x, par) + CrystalBallExtended(x, &par[4]) + CrystalBallExtended(x, par2);
-}
-
-//_____________________________________________________________________________
-//_____________________________________________________________________________
-//_____________________________________________________________________________
-//_____________________________________________________________________________
-//_____________________________________________________________________________
-
//_____________________________________________________________________________
-AliAnalysisMuMuResult::AliAnalysisMuMuResult(TRootIOCtor* /*io*/) :
-TNamed("",""),
-fNofRuns(),
-fNofTriggers(-1),
-fMinv(0x0),
-fBin(),
+AliAnalysisMuMuResult::AliAnalysisMuMuResult(const char* name, const char* title) :
+TNamed(name,title),
fSubResults(0x0),
fMap(0x0),
fMother(0x0),
fKeys(0x0),
fWeight(0.0),
-fRebin(0),
-fTriggerClass(),
-fEventSelection(),
-fPairSelection(),
-fCentralitySelection(),
-fAlias()
+fAlias(),
+fSubResultsToBeIncluded(0x0)
{
-}
-
-//_____________________________________________________________________________
-AliAnalysisMuMuResult::AliAnalysisMuMuResult(const TH1& hminv)
-:
- TNamed("",""),
- fNofRuns(1),
- fNofTriggers(-1),
- fMinv(0x0),
- fBin(),
- fSubResults(0x0),
- fMap(0x0),
- fMother(0x0),
-fKeys(0x0),
-fWeight(0.0),
-fRebin(0),
-fTriggerClass(),
-fEventSelection(),
-fPairSelection(),
-fCentralitySelection(),
-fAlias()
-{
- SetMinv(hminv);
-}
-
-//_____________________________________________________________________________
-AliAnalysisMuMuResult::AliAnalysisMuMuResult(const TH1& hminv,
- const char* fitType,
- Int_t nrebin)
-:
-TNamed(Form("%s:%d",fitType,nrebin),""),
-fNofRuns(1),
-fNofTriggers(-1),
-fMinv(0x0),
-fBin(),
-fSubResults(0x0),
-fMap(0x0),
-fMother(0x0),
-fKeys(0x0),
-fWeight(0.0),
-fRebin(nrebin),
-fTriggerClass(),
-fEventSelection(),
-fPairSelection(),
-fCentralitySelection(),
-fAlias()
-{
- SetMinv(hminv);
-}
-
-//_____________________________________________________________________________
-AliAnalysisMuMuResult::AliAnalysisMuMuResult(const TH1& hminv,
- const char* triggerName,
- const char* eventSelection,
- const char* pairSelection,
- const char* centSelection,
- const AliAnalysisMuMuBinning::Range& bin)
-:
-TNamed(Form("%s-%s-%s-%s",triggerName,eventSelection,pairSelection,centSelection),""),
-fNofRuns(1),
-fNofTriggers(-1),
-fMinv(0x0),
-fBin(bin),
-fSubResults(0x0),
-fMap(0x0),
-fMother(0x0),
-fKeys(0x0),
-fWeight(0.0),
-fRebin(1),
-fTriggerClass(triggerName),
-fEventSelection(eventSelection),
-fPairSelection(pairSelection),
-fCentralitySelection(centSelection),
-fAlias()
-{
- SetMinv(hminv);
+ /// default ctor
}
//_____________________________________________________________________________
AliAnalysisMuMuResult::AliAnalysisMuMuResult(const AliAnalysisMuMuResult& rhs)
:
TNamed(rhs),
-fNofRuns(rhs.NofRuns()),
-fNofTriggers(rhs.NofTriggers()),
-fMinv(0x0),
-fBin(rhs.Bin()),
fSubResults(0x0),
fMap(0x0),
fMother(0x0),
fKeys(0x0),
fWeight(rhs.fWeight),
-fRebin(rhs.fRebin),
-fTriggerClass(rhs.fTriggerClass),
-fEventSelection(rhs.fEventSelection),
-fPairSelection(rhs.fPairSelection),
-fCentralitySelection(rhs.fCentralitySelection),
-fAlias()
+fAlias(),
+fSubResultsToBeIncluded(0x0)
{
/// copy ctor
/// Note that the mother is lost
/// fKeys remains 0x0 so it will be recomputed if need be
- if ( rhs.fMinv )
- {
- fMinv = static_cast<TH1*>(rhs.fMinv->Clone());
- }
-
if (rhs.fSubResults)
{
fSubResults = static_cast<TObjArray*>(rhs.fSubResults->Clone());
{
fAlias = rhs.fAlias;
}
+
+ if ( rhs.fSubResultsToBeIncluded )
+ {
+ fSubResultsToBeIncluded = static_cast<TList*>(rhs.fSubResultsToBeIncluded->Clone());
+ }
+
}
//_____________________________________________________________________________
if (this!=&rhs)
{
- delete fMinv;
delete fMap;
delete fSubResults;
+ delete fSubResultsToBeIncluded;
- fMinv = 0x0;
fMap = 0x0;
fSubResults = 0x0;
fKeys = 0x0;
-
- if ( rhs.fMinv )
- {
- fMinv = static_cast<TH1*>(rhs.fMinv->Clone());
- }
+ fSubResultsToBeIncluded = 0x0;
if (rhs.fSubResults)
{
fMap = static_cast<TMap*>(rhs.fMap->Clone());
}
+ if ( rhs.fSubResultsToBeIncluded )
+ {
+ fSubResultsToBeIncluded = static_cast<TList*>(rhs.fSubResultsToBeIncluded->Clone());
+ }
+
static_cast<TNamed&>(*this)=rhs;
-
- fNofRuns = rhs.NofRuns();
- fNofTriggers = rhs.NofTriggers();
- fBin = rhs.Bin();
+
fWeight = rhs.fWeight;
- fRebin = rhs.fRebin;
-
fAlias="";
if ( rhs.fAlias.Length() > 0 )
{
// dtor
delete fMap;
- delete fMinv;
delete fSubResults;
delete fKeys;
+ delete fSubResultsToBeIncluded;
}
//_____________________________________________________________________________
-const AliAnalysisMuMuBinning::Range& AliAnalysisMuMuResult::Bin() const
+void AliAnalysisMuMuResult::AdoptSubResult(AliAnalysisMuMuResult* r)
{
- /// Get the bin of this result
- if ( !Mother() ) return fBin;
- else return Mother()->Bin();
+ /// Adopt (i.e. becomes owner) of a subresult
+ if (!fSubResults)
+ {
+ fSubResults = new TObjArray;
+ fSubResults->SetOwner(kTRUE);
+ }
+
+ fSubResults->Add(r);
+
+ SubResultsToBeIncluded()->Add(new TObjString(r->Alias()));
}
//_____________________________________________________________________________
return new AliAnalysisMuMuResult(*this);
}
+
//_____________________________________________________________________________
-Bool_t AliAnalysisMuMuResult::Correct(const AliAnalysisMuMuResult& other, const char* particle, const char* subResultName)
+Double_t AliAnalysisMuMuResult::ErrorAB(Double_t a, Double_t aerr, Double_t b, Double_t berr)
{
- /// Assuming other has an AccxEff entry, correct this value by AccxEff of other
+ /// Compute the quadratic sum of 2 errors
+
+ Double_t e(0.0);
- if ( HasValue(Form("Nof%s",particle)) )
+ if ( TMath::Abs(a) > 1E-12 )
{
- if (!other.HasValue(Form("AccEff%s",particle),subResultName))
- {
- AliError(Form("Cannot correct as I do not find the AccEff%s value (subResultName=%s)!",particle,subResultName));
- return kFALSE;
- }
-
- Double_t acc = other.GetValue(Form("AccEff%s",particle),subResultName);
- Double_t value = 0.0;
-
- if ( acc > 0 ) value = GetValue(Form("Nof%s",particle)) / acc;
-
- Double_t error = ErrorAB( GetValue(Form("Nof%s",particle)),
- GetErrorStat(Form("Nof%s",particle)),
- other.GetValue(Form("AccEff%s",particle),subResultName),
- other.GetErrorStat(Form("AccEff%s",particle),subResultName) );
-
- Set(Form("CorrNof%s",particle),value,error*value);
-
- return kTRUE;
+ e += (aerr*aerr)/(a*a);
}
- else
+
+ if ( TMath::Abs(b) > 1E-12 )
{
- AliError(Form("Result does not have Nof%s : cannot correct it !",particle));
+ e += (berr*berr)/(b*b);
}
- return kFALSE;
+
+ return TMath::Sqrt(e);
}
//_____________________________________________________________________________
-Double_t AliAnalysisMuMuResult::CountParticle(const TH1& hminv, const char* particle, Double_t sigma)
+Double_t AliAnalysisMuMuResult::ErrorABC(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror)
{
- /// Count the number of entries in an invariant mass range
-
- const std::map<std::string,Double_t>& m = MassMap();
+ /// Compute the quadratic sum of 3 errors
- std::map<std::string,Double_t>::const_iterator it = m.find(particle);
+ Double_t e(0.0);
- if ( it == m.end() )
+ if ( TMath::Abs(a) > 1E-12 )
{
- AliErrorClass(Form("Don't know the mass of particle %s",particle));
- return 0.0;
+ e += (aerr*aerr)/(a*a);
}
- Double_t mass = it->second;
-
- if ( sigma < 0 )
+ if ( TMath::Abs(b) > 1E-12 )
{
- AliDebugClass(1,Form("Oups. Got a sigma of %e for particle %s !",sigma,particle));
- return hminv.Integral();
+ e += (berr*berr)/(b*b);
}
- TAxis* x = hminv.GetXaxis();
-
- Int_t b1 = x->FindBin(mass-sigma);
- Int_t b2 = x->FindBin(mass+sigma);
-
- AliDebugClass(1,Form("hminv getentries %e integral %e",hminv.GetEntries(),hminv.Integral(b1,b2)));
+ if ( TMath::Abs(c) > 1E-12 )
+ {
+ e += (cerror*cerror)/(c*c);
+ }
- return hminv.Integral(b1,b2);
+ return TMath::Sqrt(e);
}
-/*
//_____________________________________________________________________________
-void AliAnalysisMuMuResult::FitJpsiPsiPrimeCustom(TH1& h)
+Double_t AliAnalysisMuMuResult::ErrorABCD(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror, Double_t d, Double_t derror)
{
- std::cout << "Fit with jpsi + psiprime (custom)" << std::endl;
-
- const Double_t xmin(1.5);
- const Double_t xmax(8.0);
-
- fitTotal = new TF1("fitTotal",funcJpsiPsiPrimeCustom,xmin,xmax,14);
- fitTotal->SetLineColor(4);
-
- fitTotal->SetParName(0,"cstecb");
- fitTotal->SetParName(1,"alpha");
- fitTotal->SetParName(2,"n");
- fitTotal->SetParName(3,"meanjpsi");
- fitTotal->SetParName(4,"sigmajpsi");
- fitTotal->SetParName(5,"alphaprime");
- fitTotal->SetParName(6,"nprime");
- fitTotal->SetParName(7,"cstepol1");
- fitTotal->SetParName(8,"slopepol1");
- fitTotal->SetParName(9,"cstegaus");
- fitTotal->SetParName(10,"meanpsiprime");
- fitTotal->SetParName(11,"sigmapsiprime");
- fitTotal->SetParName(12,"csteexpo");
- fitTotal->SetParName(13,"slopeexpo");
-
- fitTotal->SetParameter( 0,1);
-
- const char* fitOption = "SQBR+";
- const Double_t alphaMC = 0.936;
- const Double_t nMC = 4.44;
- const Double_t alphaprimeMC = 1.60;
- const Double_t nprimeMC = 3.23;
-
- TF1* fcb = new TF1("cb",funcCB2,2.9,3.3,7);
- fcb->SetParameters(1,1.0,4.0,3.1,0.1,1.5,3);
-
- fcb->SetParLimits(3,3,4);
- fcb->SetParLimits(4,0,1);
-
- fcb->FixParameter(1,alphaMC);
- fcb->FixParameter(2,nMC);
- fcb->FixParameter(5,alphaprimeMC);
- fcb->FixParameter(6,nprimeMC);
+ /// Compute the quadratic sum of 4 errors
- TFitResultPtr rcb = h.Fit(fcb,fitOption,"",2.9,3.3);
-
- if (!rcb.Get())
+ Double_t e(0.0);
+
+ if ( TMath::Abs(a) > 1E-12 )
{
- return;
+ e += (aerr*aerr)/(a*a);
}
- fitTotal->SetParameter(0,rcb->Parameter(0));
- fitTotal->SetParameter(1,rcb->Parameter(1)); fitTotal->SetParLimits(1,0,10); // alpha
- fitTotal->SetParameter(2,rcb->Parameter(2)); fitTotal->SetParLimits(2,1,10); // n
- fitTotal->SetParameter(3,rcb->Parameter(3)); fitTotal->SetParLimits(3,3.0,3.5); // mean
- fitTotal->SetParameter(4,rcb->Parameter(4)); fitTotal->SetParLimits(4,0,1); // sigma
- fitTotal->SetParameter(5,rcb->Parameter(5)); fitTotal->SetParLimits(1,0,10); // alphaprime
- fitTotal->SetParameter(6,rcb->Parameter(6)); fitTotal->SetParLimits(2,1,10); // nprime
-
- fitTotal->FixParameter(1,alphaMC);
- fitTotal->FixParameter(2,nMC);
- fitTotal->FixParameter(5,alphaprimeMC);
- fitTotal->FixParameter(6,nprimeMC);
-
- TF1* fge = new TF1("fge","gaus(0)+expo(3)",3.5,4.4);
- fge->SetParameters(1,3.6,0.25,1,1);
- TFitResultPtr rpsiprime = h.Fit(fge,fitOption,"",3.5,4.4);
-
- if (static_cast<int>(rpsiprime))
- {
- AliInfo("Will fix psiprime parameters");
- fitTotal->FixParameter(9,0);
- fitTotal->FixParameter(10,3.7);
- fitTotal->FixParameter(11,0.1);
- }
- else
- {
- fitTotal->SetParameter(10,rpsiprime->Parameter(1)); fitTotal->SetParLimits(10,3.5,3.8); // mean'
- fitTotal->SetParameter(11,rpsiprime->Parameter(2)); fitTotal->SetParLimits(11,0.05,0.7); // sigma'
- }
-
- TFitResultPtr rpol1 = h.Fit("pol1",fitOption,"",1.5,2.5);
- fitTotal->SetParameter( 7,rpol1->Parameter(0));
- fitTotal->SetParameter( 8,rpol1->Parameter(1));
-
- TFitResultPtr rexpo = h.Fit("expo",fitOption,"",4.5,7.0);
- fitTotal->SetParameter(12,rexpo->Parameter(0));
- fitTotal->SetParameter(13,rexpo->Parameter(1));
-
-
- TFitResultPtr r = h.Fit(fitTotal,fitOption,"",1.5,7);
-
- TF1* signal = new TF1("signal","gaus",2,6);
- signal->SetParameters(fitTotal->GetParameter(0),
- fitTotal->GetParameter(3),
- fitTotal->GetParameter(4));
-
- TF1* signalPrime = new TF1("signalPrime","gaus",2,6);
- signalPrime->SetParameters(fitTotal->GetParameter(9),
- fitTotal->GetParameter(10),
- fitTotal->GetParameter(11));
-
- Double_t gausParameters[3];
- Double_t covarianceMatrix[3][3];
- Double_t gausParametersPrime[3];
- Double_t covarianceMatrixPrime[3][3];
-
- covarianceMatrix[0][0] = (r->GetCovarianceMatrix())(0,0);
- covarianceMatrix[1][0] = (r->GetCovarianceMatrix())(3,0);
- covarianceMatrix[2][0] = (r->GetCovarianceMatrix())(4,0);
- covarianceMatrix[0][1] = (r->GetCovarianceMatrix())(0,3);
- covarianceMatrix[0][2] = (r->GetCovarianceMatrix())(0,4);
-
- for ( int iy = 1; iy < 3; ++iy )
- {
- for ( int ix = 1; ix < 3; ++ix )
- {
- covarianceMatrix[ix][iy] = (r->GetCovarianceMatrix())(ix+2,iy+2);
- }
- }
-
- gausParameters[0] = fitTotal->GetParameter(0);
- gausParameters[1] = fitTotal->GetParameter(3);
- gausParameters[2] = fitTotal->GetParameter(4);
-
- gausParametersPrime[0] = fitTotal->GetParameter(9);
- gausParametersPrime[1] = fitTotal->GetParameter(10);
- gausParametersPrime[2] = fitTotal->GetParameter(11);
-
- covarianceMatrixPrime[0][0] = (r->GetCovarianceMatrix())(9,9);
- covarianceMatrixPrime[1][0] = (r->GetCovarianceMatrix())(10,9);
- covarianceMatrixPrime[2][0] = (r->GetCovarianceMatrix())(11,9);
- covarianceMatrixPrime[0][1] = (r->GetCovarianceMatrix())(9,10);
- covarianceMatrixPrime[0][2] = (r->GetCovarianceMatrix())(9,11);
-
- for ( int iy = 1; iy < 3; ++iy )
+ if ( TMath::Abs(b) > 1E-12 )
{
- for ( int ix = 1; ix < 3; ++ix )
- {
- covarianceMatrixPrime[ix][iy] = (r->GetCovarianceMatrix())(ix+2,iy+2);
- }
+ e += (berr*berr)/(b*b);
}
- double n = signal->Integral(2,6)/h.GetBinWidth(10);
- double nerr = signal->IntegralError(2,6,&gausParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(10);
- Set("NofJpsi",n,nerr);
- Set("MeanJpsi",fitTotal->GetParameter(3),fitTotal->GetParError(3));
- Set("SigmaJpsi",fitTotal->GetParameter(4),fitTotal->GetParError(4));
-
- double nprime = signalPrime->Integral(2,6)/h.GetBinWidth(10);
- double nerrprime = signalPrime->IntegralError(2,6,&gausParametersPrime[0],&covarianceMatrixPrime[0][0])/h.GetBinWidth(10);
- Set("NofPsiPrime",nprime,nerrprime);
- Set("MeanPsiPrime",fitTotal->GetParameter(10),fitTotal->GetParError(10));
- Set("SigmaPsiPrime",fitTotal->GetParameter(11),fitTotal->GetParError(11));
-}
-*/
-
-/*
-//_____________________________________________________________________________
-AliAnalysisMuMuResult::SubResult AliAnalysisMuMuResult::FitJpsiPsiPrimeCB(TH1& h)
-{
- std::cout << "Fit with jpsi + psiprime (CB) " << std::endl;
-
- const Double_t xmin(1.5);
- const Double_t xmax(8.0);
-
- fitTotal = new TF1("fitTotal",funcJpsiPsiPrime,xmin,xmax,14);
-
-// Double_t N = par[0];
-// Double_t alpha = par[1];
-// Double_t n = par[2];
-// Double_t mean = par[3];
-// Double_t sigma = par[4];
-
- fitTotal->SetParameter( 0,1); // N
- fitTotal->FixParameter( 1,0.936); // alpha
- fitTotal->FixParameter( 2,4.44); // n
- fitTotal->SetParameter( 3,3.1); fitTotal->SetParLimits(3,3.0,3.2); // mean
- fitTotal->SetParameter( 4,0.07); fitTotal->SetParLimits(4,0.02,1); // sigma
-
- fitTotal->SetParameter( 5,0.01); // N'
- fitTotal->FixParameter( 6,0.936); // alpha'
- fitTotal->FixParameter( 7,4.44); // n'
- fitTotal->SetParameter( 8,3.7); fitTotal->SetParLimits(8,3.5,3.8); // mean'
- fitTotal->SetParameter( 9,0.1); fitTotal->SetParLimits(9,0.02,1.0); // sigma'
-
- fitTotal->SetParameter(10,h.GetMaximum());
- fitTotal->SetParameter(11,-1);
-
- fitTotal->SetParameter(12,h.GetMaximum()/100);
- fitTotal->SetParameter(13,-1);
-
- TFitResultPtr r = h.Fit(fitTotal,"SQBI","",1.5,6);
-
-// for ( int ix = 0; ix < fitTotal->GetNpar(); ++ix )
-// {
-// for ( int iy = 0; iy < fitTotal->GetNpar(); ++iy )
-// {
-// std::cout << Form("COV(%d,%d)=%e ",ix,iy,r->GetCovarianceMatrix()(ix,iy));
-// }
-// std::cout << std::endl;
-// }
-
-
- TF1* signal = new TF1("signal","gaus",2,8);
-
- signal->SetParameters(fitTotal->GetParameter(0),
- fitTotal->GetParameter(3),
- fitTotal->GetParameter(4));
-
- TF1* signalPrime = new TF1("signalPrime","gaus",2,8);
-
- signalPrime->SetParameters(fitTotal->GetParameter(0),
- fitTotal->GetParameter(8),
- fitTotal->GetParameter(9));
-
- Double_t gausParameters[3];
- Double_t gausParametersPrime[3];
- Double_t covarianceMatrix[3][3];
- Double_t covarianceMatrixPrime[3][3];
-
- gausParameters[0] = fitTotal->GetParameter(0);
- gausParameters[1] = fitTotal->GetParameter(3);
- gausParameters[2] = fitTotal->GetParameter(4);
-
- covarianceMatrix[0][0] = (r->GetCovarianceMatrix())(0,0);
- covarianceMatrix[1][0] = (r->GetCovarianceMatrix())(3,0);
- covarianceMatrix[2][0] = (r->GetCovarianceMatrix())(4,0);
- covarianceMatrix[0][1] = (r->GetCovarianceMatrix())(0,3);
- covarianceMatrix[0][2] = (r->GetCovarianceMatrix())(0,4);
-
- for ( int iy = 1; iy < 3; ++iy )
+ if ( TMath::Abs(c) > 1E-12 )
{
- for ( int ix = 1; ix < 3; ++ix )
- {
- covarianceMatrix[ix][iy] = (r->GetCovarianceMatrix())(ix+2,iy+2);
- }
- }
-
- gausParametersPrime[0] = fitTotal->GetParameter(0);
- gausParametersPrime[1] = fitTotal->GetParameter(8);
- gausParametersPrime[2] = fitTotal->GetParameter(9);
-
- covarianceMatrixPrime[0][0] = (r->GetCovarianceMatrix())(0,0);
- covarianceMatrixPrime[1][0] = (r->GetCovarianceMatrix())(8,0);
- covarianceMatrixPrime[2][0] = (r->GetCovarianceMatrix())(9,0);
- covarianceMatrixPrime[0][1] = (r->GetCovarianceMatrix())(0,8);
- covarianceMatrixPrime[0][2] = (r->GetCovarianceMatrix())(0,9);
-
- for ( int iy = 1; iy < 3; ++iy )
- {
- for ( int ix = 1; ix < 3; ++ix )
- {
- covarianceMatrixPrime[ix][iy] = (r->GetCovarianceMatrix())(ix+2,iy+2);
- }
+ e += (cerror*cerror)/(c*c);
}
-
- double n = signal->Integral(2,6)/h.GetBinWidth(10);
- double nerr = signal->IntegralError(2,6,&gausParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(10);
-
- Set("NofJpsi",n,nerr);
- Set("MeanJpsi",fitTotal->GetParameter(3),fitTotal->GetParError(3));
- Set("SigmaJpsi",fitTotal->GetParameter(4),fitTotal->GetParError(4));
- double nprime = signalPrime->Integral(2,6)/h.GetBinWidth(10);
- double nerrprime = signalPrime->IntegralError(2,6,&gausParametersPrime[0],&covarianceMatrixPrime[0][0])/h.GetBinWidth(10);
-
- Set("NofPsiPrime",nprime,nerrprime);
- Set("MeanPsiPrime",fitTotal->GetParameter(8),fitTotal->GetParError(8));
- Set("SigmaPsiPrime",fitTotal->GetParameter(9),fitTotal->GetParError(9));
-
-}
- */
-
-//_____________________________________________________________________________
-AliAnalysisMuMuResult* AliAnalysisMuMuResult::FitJpsiGCBE(TH1& h)
-{
- /// Fit Jpsi spectra with crystal ball + gaussian + exponential
-
- std::cout << "Fit with jpsi alone (gaus + CB + expo)" << std::endl;
-
- Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
-
- AliAnalysisMuMuResult* r = new AliAnalysisMuMuResult(h,"JPSIGCBE",nrebin);
-
- TH1* hfit = r->Minv();
-
- const Double_t xmin(1.0);
- const Double_t xmax(8.0);
-
- TF1* fitTotal = new TF1("fitTotal",funcJpsiGCBE,xmin,xmax,10);
- fitTotal->SetParNames("cste","x0","sigma0","N","alpha","n","mean","sigma","expocste","exposlope");
-
- fitTotal->SetParLimits(3,0,h.GetMaximum()*2); // N
-
- const Double_t cbalpha(0.98);
- const Double_t cbn(5.2);
-
- fitTotal->FixParameter(4,cbalpha);
- fitTotal->FixParameter(5,cbn);
-
- fitTotal->SetParLimits(6,2.8,3.2); // mean
- fitTotal->SetParLimits(7,0.02,0.3); // sigma
-
- TF1* fg = new TF1("fg","gaus",xmin,xmax);
-
- hfit->Fit(fg,"","",0.75,3.0);
-
- fitTotal->SetParameter(0,fg->GetParameter(0));
- fitTotal->SetParameter(1,fg->GetParameter(1));
- fitTotal->SetParameter(2,fg->GetParameter(2));
-
- TF1* fexpo = new TF1("expo","expo",xmin,xmax);
-
- hfit->Fit(fexpo,"","",3.5,5);
-
- fitTotal->SetParameter(8,fexpo->GetParameter(0));
- fitTotal->SetParameter(9,fexpo->GetParameter(1));
-
- fitTotal->SetParameter(3,h.GetMaximum()),
- fitTotal->SetParameter(4,cbalpha);
- fitTotal->SetParameter(5,cbn);
- fitTotal->SetParameter(6,3.15);
- fitTotal->SetParameter(7,0.1);
-
- const char* fitOption = "SI+";
-
- TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"",2,5);
-
- r->Set("MeanJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
- r->Set("SigmaJpsi",fitTotal->GetParameter(7),fitTotal->GetParError(7));
-
- double m = r->GetValue("MeanJpsi");
- double s = r->GetValue("SigmaJpsi");
- double n = 3.0;
-
- TF1* fcb = new TF1("fcb",funcCB,xmin,xmax,5);
- fcb->SetParameters(fitTotal->GetParameter(3),
- fitTotal->GetParameter(4),
- fitTotal->GetParameter(5),
- fitTotal->GetParameter(6),
- fitTotal->GetParameter(7));
-
- fcb->SetLineColor(6);
- fcb->SetNpx(100);
- TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(3));
- TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(3));
- l1->SetLineColor(6);
- l2->SetLineColor(6);
- h.GetListOfFunctions()->Add(fcb);
- h.GetListOfFunctions()->Add(l1);
- h.GetListOfFunctions()->Add(l2);
-
-
- Double_t cbParameters[5];
- Double_t covarianceMatrix[5][5];
-
- cbParameters[0] = fitTotal->GetParameter(3);
- cbParameters[1] = fitTotal->GetParameter(4);
- cbParameters[2] = fitTotal->GetParameter(5);
- cbParameters[3] = fitTotal->GetParameter(6);
- cbParameters[4] = fitTotal->GetParameter(7);
-
- for ( int iy = 0; iy < 5; ++iy )
+ if ( TMath::Abs(d) > 1E-12 )
{
- for ( int ix = 0; ix < 5; ++ix )
- {
- covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+3,iy+3);
- }
+ e += (derror*derror)/(d*d);
}
-
- double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
-
- double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
-
- r->Set("NofJpsi",njpsi,nerr);
-
- return r;
-}
-
-/*
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::FitJpsiPCBE(TH1& h)
-{
- std::cout << "Fit with jpsi alone (pol2 + CB + expo)" << std::endl;
-
- const Double_t xmin(2.0);
- const Double_t xmax(5.0);
-
- fitTotal = new TF1("fitTotal",funcJpsiPCBE,xmin,xmax,10);
- fitTotal->SetParNames("p0","p1","p2","N","alpha","n","mean","sigma","expocste","exposlope");
-
- fitTotal->SetParLimits(3,0,h.GetMaximum()*2); // N
-
- const Double_t cbalpha(0.98);
- const Double_t cbn(5.2);
-
- fitTotal->FixParameter(4,cbalpha);
- fitTotal->FixParameter(5,cbn);
-
- fitTotal->SetParLimits(6,2,4); // mean
- fitTotal->SetParLimits(7,0.05,0.2); // sigma
-
- TF1* fpol2 = new TF1("pol2","pol2",xmin,xmax);
-
- h.Fit(fpol2,"+","",2,2.8);
-
- fitTotal->SetParameter(0,fpol2->GetParameter(0));
- fitTotal->SetParameter(1,fpol2->GetParameter(1));
- fitTotal->SetParameter(2,fpol2->GetParameter(2));
-
- TF1* fexpo = new TF1("expo","expo",xmin,xmax);
-
- h.Fit(fexpo,"+","",3.5,4.5);
-
- fitTotal->SetParameter(8,fexpo->GetParameter(0));
- fitTotal->SetParameter(9,fexpo->GetParameter(1));
-
- fitTotal->SetParameter(3,h.GetMaximum()),
- fitTotal->SetParameter(4,cbalpha);
- fitTotal->SetParameter(5,cbn);
- fitTotal->SetParameter(6,3.15);
- fitTotal->SetParameter(7,0.1);
-
- h.Fit(fitTotal,"+","",2.5,5);
-
- Set("MeanJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
- Set("SigmaJpsi",fitTotal->GetParameter(7),fitTotal->GetParError(7));
-
- double m = GetValue("MeanJpsi");
- double s = GetValue("SigmaJpsi");
- double n = 2.0;
-
- TF1* fcb = new TF1("fcb",funcCB,xmin,xmax,5);
- fcb->SetParameters(fitTotal->GetParameter(3),
- fitTotal->GetParameter(4),
- fitTotal->GetParameter(5),
- fitTotal->GetParameter(6),
- fitTotal->GetParameter(7));
-
- fcb->SetLineColor(6);
- fcb->SetNpx(100);
- TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(3));
- TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(3));
- l1->SetLineColor(6);
- l2->SetLineColor(6);
- h.GetListOfFunctions()->Add(fcb);
- h.GetListOfFunctions()->Add(l1);
- h.GetListOfFunctions()->Add(l2);
-
-
- Set("NofJpsi",fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1),fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1));
-
- // Set("NofJpsi",fitTotal->Integral(0,10)/h.GetBinWidth(1),fitTotal->IntegralError(0,10)/h.GetBinWidth(1));
-
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::FitJpsiCBE(TH1& h)
-{
- std::cout << "Fit with jpsi alone" << std::endl;
-
- const Double_t xmin(1.5);
- const Double_t xmax(8.0);
-
- fitTotal = new TF1("fitTotal",funcJpsiCBE,xmin,xmax,7);
- fitTotal->SetParNames("N","alpha","n","mean","sigma","expocste","exposlope");
-
-// fitTotal->SetParameters(h.GetMaximum(),1,5,3.0,0.07,1.5,3,1,0);
- fitTotal->SetParameters(1,1.15,3.6,3.0,0.07,1,-1);
-
- fitTotal->SetParLimits(0,0,h.GetMaximum()); // N
-// fitTotal->SetParLimits(1,0.1,2); // alpha
- fitTotal->FixParameter(1,0.98);
-// fitTotal->SetParLimits(2,0.01,5); // n
- fitTotal->FixParameter(2,5.2);
- fitTotal->SetParLimits(3,2.8,3.5); // mean
- fitTotal->SetParLimits(4,0.05,0.2); // sigma
-
- TF1* fexpo = new TF1("expo","expo",xmin,xmax);
-
- h.Fit(fexpo,"+","",2,3);
-
- fitTotal->SetParameter(5,fexpo->GetParameter(0));
- fitTotal->SetParameter(6,fexpo->GetParameter(1));
-
- h.Fit(fitTotal,"+","",2,5);
-
-
- Set("MeanJpsi",fitTotal->GetParameter(3),fitTotal->GetParError(3));
- Set("SigmaJpsi",fitTotal->GetParameter(4),fitTotal->GetParError(4));
-
- double m = GetValue("MeanJpsi");
- double s = GetValue("SigmaJpsi");
- double n = 3.0;
-
- TF1* fcb = new TF1("fcb",funcCB,xmin,xmax,5);
- fcb->SetParameters(fitTotal->GetParameter(0),
- fitTotal->GetParameter(1),
- fitTotal->GetParameter(2),
- fitTotal->GetParameter(3),
- fitTotal->GetParameter(4));
-
- fcb->SetLineColor(6);
- fcb->SetNpx(1000);
- TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(0));
- TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(0));
- l1->SetLineColor(6);
- l2->SetLineColor(6);
- h.GetListOfFunctions()->Add(fcb);
- h.GetListOfFunctions()->Add(l1);
- h.GetListOfFunctions()->Add(l2);
-
-
- Set("NofJpsi",fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1),fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1));
-
- // Set("NofJpsi",fitTotal->Integral(0,10)/h.GetBinWidth(1),fitTotal->IntegralError(0,10)/h.GetBinWidth(1));
-
+ return TMath::Sqrt(e);
}
//_____________________________________________________________________________
-void AliAnalysisMuMuResult::FitJpsiECBE(TH1& h)
+Double_t AliAnalysisMuMuResult::ErrorABCDE(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror, Double_t d, Double_t derror, Double_t ee, Double_t eeerror)
{
- std::cout << "Fit with jpsi alone (expo + CB + expo)" << std::endl;
-
- const Double_t xmin(1.5);
- const Double_t xmax(8.0);
-
- fitTotal = new TF1("fitTotal",funcJpsiECBE,xmin,xmax,9);
- fitTotal->SetParNames("e0","s0","N","alpha","n","mean","sigma","e1","s1");
-
- fitTotal->SetParameters(1,-1,1,1.15,3.6,3.2,0.06,-1);
-
- fitTotal->SetParLimits(0,0,h.GetMaximum()*2);
-
- fitTotal->FixParameter(3,0.98); // alpha
- fitTotal->FixParameter(4,5.2); // n
- fitTotal->SetParLimits(5,2.8,3.5); // mean
- fitTotal->SetParLimits(6,0.05,0.2); // sigma
-
- TF1* fexpo1 = new TF1("expo1","expo",xmin,xmax);
- TF1* fexpo2 = new TF1("expo2","expo",xmin,xmax);
+ /// Compute the quadratic sum of 4 errors
- h.Fit(fexpo1,"","",1.5,3);
-
- fitTotal->SetParameter(0,fexpo1->GetParameter(0));
- fitTotal->SetParameter(1,fexpo1->GetParameter(1));
-
- h.Fit(fexpo2,"","",3.5,5.0);
-
- fitTotal->SetParameter(7,fexpo2->GetParameter(0));
- fitTotal->SetParameter(8,fexpo2->GetParameter(1));
-
- const char* fitOption = "SI+";
-
- TFitResultPtr r = h.Fit(fitTotal,fitOption,"",2,5);
-
- Set("MeanJpsi",fitTotal->GetParameter(5),fitTotal->GetParError(5));
- Set("SigmaJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
-
- double m = GetValue("MeanJpsi");
- double s = GetValue("SigmaJpsi");
- double n = 3.0;
+ Double_t e(0.0);
- TF1* fcb = new TF1("fcb",funcCB,xmin,xmax,5);
- fcb->SetParameters(fitTotal->GetParameter(2),
- fitTotal->GetParameter(3),
- fitTotal->GetParameter(4),
- fitTotal->GetParameter(5),
- fitTotal->GetParameter(6));
-
- fcb->SetParError(0,fitTotal->GetParError(2));
- fcb->SetParError(1,fitTotal->GetParError(3));
- fcb->SetParError(2,fitTotal->GetParError(4));
- fcb->SetParError(3,fitTotal->GetParError(5));
- fcb->SetParError(4,fitTotal->GetParError(6));
-
- fcb->SetLineColor(6);
- fcb->SetNpx(1000);
- TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(2));
- TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(2));
- l1->SetLineColor(6);
- l2->SetLineColor(6);
- h.GetListOfFunctions()->Add(fcb);
- h.GetListOfFunctions()->Add(l1);
- h.GetListOfFunctions()->Add(l2);
-
-
- Double_t cbParameters[5];
- Double_t covarianceMatrix[5][5];
-
- cbParameters[0] = fitTotal->GetParameter(2);
- cbParameters[1] = fitTotal->GetParameter(3);
- cbParameters[2] = fitTotal->GetParameter(4);
- cbParameters[3] = fitTotal->GetParameter(5);
- cbParameters[4] = fitTotal->GetParameter(6);
-
- for ( int iy = 0; iy < 5; ++iy )
+ if ( TMath::Abs(a) > 1E-12 )
{
- for ( int ix = 0; ix < 5; ++ix )
- {
- covarianceMatrix[ix][iy] = (r->GetCovarianceMatrix())(ix+2,iy+2);
- }
+ e += (aerr*aerr)/(a*a);
}
-
- double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
-
- double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
-
-
- Set("NofJpsi",njpsi,nerr);
-}
-
- */
-
-//_____________________________________________________________________________
-AliAnalysisMuMuResult* AliAnalysisMuMuResult::FitJpsi(TH1& h)
-{
- /// Fit Jpsi spectra using extended crystall ball (CB2) with free tails
-
- std::cout << "Fit with jpsi alone" << std::endl;
-
- Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
-
- AliAnalysisMuMuResult* r = new AliAnalysisMuMuResult(h,"JPSI",nrebin);
-
- TH1* hfit = r->Minv();
-
- const Double_t xmin(1.5);
- const Double_t xmax(8.0);
-
- TF1* fitTotal = new TF1("fitTotal",funcCB2,xmin,xmax,7);
- fitTotal->SetParNames("N","alphaLow","nLow","mean","sigma","alphaUp","nUp");
- fitTotal->SetParameters(h.GetMaximum(),1,5,3.1,0.07,1.5,3);
- fitTotal->SetParLimits(0,0,h.GetMaximum()*2); // N
- fitTotal->SetParLimits(1,0,10); // alpha
- fitTotal->SetParLimits(2,0.1,10); // n
- fitTotal->SetParLimits(3,3,3.1); // mean
- fitTotal->SetParLimits(4,0.01,1); // sigma
- fitTotal->SetParLimits(5,0,10); // alpha
- fitTotal->SetParLimits(6,0.1,10); // n
-
- hfit->Fit(fitTotal,"+","",2,5);
-
-
- r->Set("MeanJpsi",fitTotal->GetParameter(3),fitTotal->GetParError(3));
- r->Set("SigmaJpsi",fitTotal->GetParameter(4),fitTotal->GetParError(4));
-
- double m = r->GetValue("MeanJpsi");
- double s = r->GetValue("SigmaJpsi");
- double n = 10.0;
-
- r->Set("NofJpsi",fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1),fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1));
-
- return r;
-}
-
-//_____________________________________________________________________________
-AliAnalysisMuMuResult* AliAnalysisMuMuResult::FitJpsiCB2VWG(const TH1& h)
-{
- /// Fit Jpsi spectra using extended crystal ball (CB2) + variable width gaussian (VWG)
-
- std::cout << "Fit with jpsi VWG" << std::endl;
-
- Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
-
- AliAnalysisMuMuResult* r = new AliAnalysisMuMuResult(h,"JPSICB2VWG",nrebin);
-
-
- TH1* hfit = r->Minv();
-
- const Double_t xmin(2.0);
- const Double_t xmax(5.0);
-
-// // gaussian variable width
-// Double_t sigma = par[2]+par[3]*((x[0]-par[1])/par[1]);
-// return par[0]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/(2.*sigma*sigma));
-// Double_t CrystalBallExtended(Double_t *x,Double_t *par)
-// //par[0] = Normalization
-// //par[1] = mean
-// //par[2] = sigma
-// //par[3] = alpha
-// //par[4] = n
-// //par[5] = alpha'
-// //par[6] = n'
-
- TF1* fitTotal = new TF1("fitTotal",fitFunctionCB2VWG,xmin,xmax,11);
- fitTotal->SetParNames("kVWG","mVWG","sVWG1","sVWG2","norm","mean","sigma","alpha","n","alpha'","n'");
-
- fitTotal->SetParameter(0, 10000.); // kVWG
- fitTotal->SetParameter(1, 1.9); // mVWG
-
- fitTotal->SetParameter(2, 0.5); // sVWG1
- fitTotal->SetParLimits(2, 0., 100.);
-
- fitTotal->SetParameter(3, 0.3); // sVWG2
- fitTotal->SetParLimits(3, 0., 100.);
-
- fitTotal->SetParameter(4, h.GetMaximum()); // norm
-
- fitTotal->SetParameter(5, 3.1); // mean
- fitTotal->SetParLimits(5, 3.0, 3.2);
-
- fitTotal->SetParameter(6, 0.08); // sigma
- fitTotal->SetParLimits(6, 0.04, 0.20);
-
- fitTotal->SetParameter(7,1.0); // alpha
- fitTotal->SetParameter(8,5); // n
- fitTotal->SetParameter(9,2.0); // alpha'
- fitTotal->SetParameter(10,4); // n'
-
-// fitTotal->FixParameter(7, 0.93);
-// fitTotal->FixParameter(8, 5.59);
-// fitTotal->FixParameter(9, 2.32);
-// fitTotal->FixParameter(10, 3.39);
-// fitTotal->SetParameter(11, 10.);
-
- const char* fitOption = "SIER"; //+";
-
- TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
-
- r->Set("MeanJpsi",fitTotal->GetParameter(5),fitTotal->GetParError(5));
- r->Set("SigmaJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
-
- double m = r->GetValue("MeanJpsi");
- double s = r->GetValue("SigmaJpsi");
- double n = 3.0;
-
- TF1* fcb = new TF1("fcb",CrystalBallExtended,xmin,xmax,7);
- fcb->SetParameters(fitTotal->GetParameter(4),
- fitTotal->GetParameter(5),
- fitTotal->GetParameter(6),
- fitTotal->GetParameter(7),
- fitTotal->GetParameter(8),
- fitTotal->GetParameter(9),
- fitTotal->GetParameter(10));
-
-
- fcb->SetLineColor(1);
- fcb->SetNpx(1000);
- TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(4));
- TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(4));
- l1->SetLineColor(6);
- l2->SetLineColor(6);
- hfit->GetListOfFunctions()->Add(fcb);
- hfit->GetListOfFunctions()->Add(l1);
- hfit->GetListOfFunctions()->Add(l2);
-
- Double_t cbParameters[7];
- Double_t covarianceMatrix[7][7];
-
- for ( int ix = 0; ix < 7; ++ix )
+ if ( TMath::Abs(b) > 1E-12 )
{
- cbParameters[ix] = fitTotal->GetParameter(ix+4);
+ e += (berr*berr)/(b*b);
}
- for ( int iy = 0; iy < 5; ++iy )
+ if ( TMath::Abs(c) > 1E-12 )
{
- for ( int ix = 0; ix < 5; ++ix )
- {
- covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+4,iy+4);
- }
+ e += (cerror*cerror)/(c*c);
}
- double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
- double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
-
- r->Set("NofJpsi",njpsi,nerr);
-
- return r;
-}
-
-//_____________________________________________________________________________
-AliAnalysisMuMuResult* AliAnalysisMuMuResult::FitJpsi2CB2VWG(const TH1& h,
- Double_t alphaLow,
- Double_t nLow,
- Double_t alphaUp,
- Double_t nUp)
-{
- /// Fit using extended crystal ball + variable width gaussian
-
- std::cout << Form("Fit with jpsi + psiprime VWG alphaLow=%5.2f nLow=%5.2f alphaUp=%5.2f nUp=%5.2f",
- alphaLow,nLow,alphaUp,nUp) << std::endl;
-
- Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
-
- TString resultName("JPSI2CB2VWG");
- if ( alphaLow > 0 )
+ if ( TMath::Abs(d) > 1E-12 )
{
- resultName += TString::Format("alphaLow=%5.2f",alphaLow);
+ e += (derror*derror)/(d*d);
}
- if ( nLow > 0 )
- {
- resultName += TString::Format("nLow=%5.2f",nLow);
- }
- if ( alphaUp > 0 )
- {
- resultName += TString::Format("alphaUp=%5.2f",alphaUp);
- }
- if ( nUp > 0 )
- {
- resultName += TString::Format("nUp=%5.2f",nUp);
- }
- resultName.ReplaceAll(" ","");
-
- AliAnalysisMuMuResult* r = new AliAnalysisMuMuResult(h,resultName.Data(),nrebin);
-
- TH1* hfit = r->Minv();
-
- const Double_t xmin(2.2);
- const Double_t xmax(5.0);
-
- TF1* fitTotal = new TF1("fitTotal",func2CB2VWG,xmin,xmax,12);
- fitTotal->SetParNames("kVWG","mVWG","sVWG1","sVWG2","kPsi","mPsi","sPsi","alPsi","nlPsi","auPsi","nuPsi");
- fitTotal->SetParName(11, "kPsi'");
- fitTotal->SetParameter(0, 10000.);
- fitTotal->SetParameter(1, 1.9);
- fitTotal->SetParameter(2, 0.5);
- fitTotal->SetParLimits(2, 0., 100.);
- fitTotal->SetParameter(3, 0.3);
- fitTotal->SetParLimits(3, 0., 100.);
- fitTotal->SetParameter(4, 100.);
- fitTotal->SetParameter(5, 3.1);
- fitTotal->SetParLimits(5, 3.08, 3.2);
- fitTotal->SetParameter(6, 0.08);
- fitTotal->SetParLimits(6, 0.05, 0.15);
-
-// r = FitJpsi2CB2VWG(*hminv,0.93,5.59,2.32,3.39);
-
- if ( alphaLow > 0 )
+ if ( TMath::Abs(e) > 1E-12 )
{
- fitTotal->FixParameter(7, alphaLow);
+ e += (eeerror*eeerror)/(ee*ee);
}
- else
- {
- fitTotal->SetParameter(7,0.9);
- fitTotal->SetParLimits(7,0.1,10.0);
- }
-
- if ( nLow > 0 )
- {
- fitTotal->FixParameter(8, nLow);
- }
- else
- {
- fitTotal->SetParameter(8,5.0);
- fitTotal->SetParLimits(8,0.0,10.0);
- }
-
- if ( alphaUp > 0 )
- {
- fitTotal->FixParameter(9, alphaUp);
- }
- else
- {
- fitTotal->SetParameter(9, 2.0);
- fitTotal->SetParLimits(9,0.1,10.0);
- }
-
- if ( nUp > 0 )
- {
- fitTotal->FixParameter(10, nUp);
- }
- else
- {
- fitTotal->SetParameter(10,3.0);
- fitTotal->SetParLimits(10,0.0,10.0);
- }
-
- fitTotal->SetParameter(11, 10.);
- const char* fitOption = "SER"; //+";
-
- TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
-
- r->Set("MeanJpsi",fitTotal->GetParameter(5),fitTotal->GetParError(5));
- r->Set("SigmaJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
-
- double m = r->GetValue("MeanJpsi");
- double s = r->GetValue("SigmaJpsi");
- double n = 3.0;
-
- TF1* fcb = new TF1("fcb",CrystalBallExtended,xmin,xmax,7);
- fcb->SetParameters(fitTotal->GetParameter(4),
- fitTotal->GetParameter(5),
- fitTotal->GetParameter(6),
- fitTotal->GetParameter(7),
- fitTotal->GetParameter(8),
- fitTotal->GetParameter(9),
- fitTotal->GetParameter(10));
-
-
- fcb->SetLineColor(1);
- fcb->SetNpx(1000);
- TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(4));
- TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(4));
- l1->SetLineColor(6);
- l2->SetLineColor(6);
- hfit->GetListOfFunctions()->Add(fcb);
- hfit->GetListOfFunctions()->Add(l1);
- hfit->GetListOfFunctions()->Add(l2);
-
- Double_t cbParameters[7];
- Double_t covarianceMatrix[7][7];
-
- for ( int ix = 0; ix < 7; ++ix )
- {
- cbParameters[ix] = fitTotal->GetParameter(ix+4);
- }
-
- for ( int iy = 0; iy < 5; ++iy )
- {
- for ( int ix = 0; ix < 5; ++ix )
- {
- covarianceMatrix[ix][iy] = (fitResult->GetCovarianceMatrix())(ix+4,iy+4);
- }
- }
-
- double njpsi = fcb->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
- double nerr = fcb->IntegralError(m-n*s,m+n*s,&cbParameters[0],&covarianceMatrix[0][0])/h.GetBinWidth(1);
-
- r->Set("NofJpsi",njpsi,nerr);
-
- return r;
+ return TMath::Sqrt(e);
}
-//_____________________________________________________________________________
-AliAnalysisMuMuResult* AliAnalysisMuMuResult::FitJpsiNA48(const TH1& h)
-{
- /// fit using functional form from Ruben Shahoyan's thesis (2001) (eq. 4.8.)
-
- std::cout << "Fit with jpsi NA50 Ruben eq. 4.8" << std::endl;
-
- Int_t nrebin = fMinv->GetXaxis()->GetNbins() / h.GetXaxis()->GetNbins();
-
- AliAnalysisMuMuResult* r = new AliAnalysisMuMuResult(h,"JPSINA",nrebin);
-
- TH1* hfit = r->Minv();
-
- const Double_t xmin(2.0);
- const Double_t xmax(5.0);
-
- TF1* fitTotal = new TF1("fitTotal",funcJpsiNA48,xmin,xmax,12);
-
- fitTotal->SetParName( 0, "c1");
- fitTotal->FixParameter(0,0.97);
-
- fitTotal->SetParName( 1, "c2");
- fitTotal->FixParameter(1,1.05);
-
- fitTotal->SetParName( 2, "d1");
- fitTotal->SetParameter(2,0.0);
- fitTotal->SetParLimits(2,0,1);
-
- fitTotal->SetParName( 3, "d2");
- fitTotal->SetParameter(3,0.0);
- fitTotal->SetParLimits(3,0,1);
-
- fitTotal->SetParName( 4, "g1");
- fitTotal->SetParameter(4,0.0);
- fitTotal->SetParLimits(4,0.0,1);
-
- fitTotal->SetParName( 5, "g2");
- fitTotal->SetParameter(5,0.0);
- fitTotal->SetParLimits(5,0.0,1);
-
- fitTotal->SetParName( 6, "m0");
- fitTotal->SetParameter(6,3.1);
- fitTotal->SetParLimits(6,2.8,3.4);
-
- fitTotal->SetParName( 7, "sigma1");
- fitTotal->SetParameter(7,0.05);
- fitTotal->SetParLimits(7,0.01,0.2);
-
- fitTotal->SetParName( 8, "sigma2");
- fitTotal->SetParameter(8,0.05);
- fitTotal->SetParLimits(8,0.01,0.2);
-
- fitTotal->SetParName( 9, "b1");
- fitTotal->SetParameter(9,1.0);
- fitTotal->SetParLimits(9,0,1);
-
- fitTotal->SetParName(10, "b2");
- fitTotal->SetParameter(10,1.0);
- fitTotal->SetParLimits(10,0,1);
-
- fitTotal->SetParName(11, "norm");
- fitTotal->SetParameter(11,h.GetMaximum());
-
- const char* fitOption = "SIER"; //+";
-
- TFitResultPtr fitResult = hfit->Fit(fitTotal,fitOption,"");
-
- r->Set("MeanJpsi",fitTotal->GetParameter(6),fitTotal->GetParError(6));
- r->Set("SigmaJpsi",
- fitTotal->GetParameter(7)+fitTotal->GetParameter(8),
- 0.0);
-
- double m = r->GetValue("MeanJpsi");
- double s = r->GetValue("SigmaJpsi");
- double n = 3.0;
-
- TLine* l1 = new TLine(m-n*s,0,m-n*s,fitTotal->GetParameter(11));
- TLine* l2 = new TLine(m+n*s,0,m+n*s,fitTotal->GetParameter(11));
- l1->SetLineColor(6);
- l2->SetLineColor(6);
- hfit->GetListOfFunctions()->Add(l1);
- hfit->GetListOfFunctions()->Add(l2);
-
- double njpsi = fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1);
- double nerr = fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1);
-
- r->Set("NofJpsi",njpsi,nerr);
-
- return r;
-}
-/*
//_____________________________________________________________________________
-void AliAnalysisMuMuResult::FitUpsilon(TH1& h)
+void AliAnalysisMuMuResult::Exclude(const char* subResultList)
{
- std::cout << "Fit with upsilon alone" << std::endl;
-
- const Double_t xmin(6.0);
- const Double_t xmax(12.0);
-
- fitTotal = new TF1("fitTotal",funcCB2,xmin,xmax,7);
- fitTotal->SetParNames("N","alpha","n","mean","sigma","alphaprime","nprime");
- fitTotal->SetParameters(h.GetMaximum(),1,5,9.46,0.2,1.5,3);
- fitTotal->SetParLimits(0,0,h.GetMaximum()*2); // N
- fitTotal->SetParLimits(1,0,10); // alpha
- fitTotal->SetParLimits(2,1,10); // n
- fitTotal->SetParLimits(3,8,12); // mean
- fitTotal->SetParLimits(4,0.01,1); // sigma
- fitTotal->SetParLimits(5,0,10); // alpha
- fitTotal->SetParLimits(6,1,10); // n
-
- h.Fit(fitTotal,"+","",6,12);
-
+ // exclude some subresult names from the list of subresult
+ // to be used when computing the mean
- Set("MeanUpsilon",fitTotal->GetParameter(3),fitTotal->GetParError(3));
- Set("SigmaUpsilon",fitTotal->GetParameter(4),fitTotal->GetParError(4));
+ TString slist(subResultList);
- double m = GetValue("MeanUpsilon");
- double s = GetValue("SigmaUpsilon");
- double n = 3.0;
+ TString tobeincluded = GetSubResultNameList();
- Set("NofUpsilon",fitTotal->Integral(m-n*s,m+n*s)/h.GetBinWidth(1),fitTotal->IntegralError(m-n*s,m+n*s)/h.GetBinWidth(1));
-}
-*/
-
-//_____________________________________________________________________________
-Double_t AliAnalysisMuMuResult::ErrorAB(Double_t a, Double_t aerr, Double_t b, Double_t berr)
-{
- /// Compute the quadratic sum of 2 errors
-
- Double_t e(0.0);
-
- if ( TMath::Abs(a) > 1E-12 )
+ if ( slist == "*" )
{
- e += (aerr*aerr)/(a*a);
+ Exclude(tobeincluded);
+ return;
}
- if ( TMath::Abs(b) > 1E-12 )
+ if ( fSubResultsToBeIncluded )
{
- e += (berr*berr)/(b*b);
- }
-
- return TMath::Sqrt(e);
-}
+ TObjArray* a = slist.Tokenize(",");
+ TIter nextA(a);
+ TObjString* s;
-//_____________________________________________________________________________
-Double_t AliAnalysisMuMuResult::ErrorABC(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror)
-{
- /// Compute the quadratic sum of 3 errors
-
- Double_t e(0.0);
-
- if ( TMath::Abs(a) > 1E-12 )
- {
- e += (aerr*aerr)/(a*a);
- }
-
- if ( TMath::Abs(b) > 1E-12 )
- {
- e += (berr*berr)/(b*b);
- }
-
- if ( TMath::Abs(b) > 1E-12 )
- {
- e += (cerror*cerror)/(c*c);
+ while ( ( s = static_cast<TObjString*>(nextA())) )
+ {
+ TObject* o = fSubResultsToBeIncluded->FindObject(s->String());
+ fSubResultsToBeIncluded->Remove(o);
+ }
+
+ delete a;
}
-
- return TMath::Sqrt(e);
}
-
//_____________________________________________________________________________
-Bool_t AliAnalysisMuMuResult::AddFit(const char* fitType, Int_t npar, Double_t* par)
+Double_t AliAnalysisMuMuResult::GetErrorStat(const char* name, const char* subResultName) const
{
- // Add a fit to this result
-
- TString msg(Form("fitType=%s npar=%d par[]=",fitType,npar));
-
- for ( Int_t i = 0; i < npar; ++i )
- {
- msg += TString::Format("%e,",par[i]);
- }
-
- msg += TString::Format(" minv=%p %d",fMinv,fMinv?TMath::Nint(fMinv->GetEntries()):0);
-
- if ( !fMinv ) return kFALSE;
-
- TString sFitType(fitType);
- sFitType.ToUpper();
- Int_t nrebin(1);
-
- if (sFitType.CountChar(':'))
- {
- Int_t index = sFitType.Index(":");
- nrebin = TString(sFitType(index+1,sFitType.Length()-index-1)).Atoi();
- sFitType = sFitType(0,index);
- }
-
- msg += TString::Format(" nrebin=%d",nrebin);
+ // compute the mean value from all subresults that are included
- AliDebug(1,msg.Data());
-
-
- if ( fMinv->GetEntries()<100 && !sFitType.Contains("COUNT")) return kFALSE;
-
- TH1* hminv = static_cast<TH1*>(fMinv->Clone());
-
- hminv->Rebin(nrebin);
- hminv->SetDirectory(0);
-
- AliAnalysisMuMuResult* r(0x0);
-
- if ( sFitType=="PSI1")
- {
- r = FitJpsi(*hminv);
- }
- else if ( sFitType == "PSILOW")
- {
- r = FitJpsi2CB2VWG(*hminv,-1,-1,-1,-1); // free tails
- }
- else if ( sFitType == "PSILOWMCTAILS" )
+ if ( strlen(subResultName) > 0 )
{
- if ( npar!= 4 )
+ if ( !fSubResults)
{
- AliError("Cannot use PSILOWMCTAILS without being given the MC tails !");
- delete hminv;
- return kFALSE;
+ AliError(Form("No subresult from which I could get the %s one...",subResultName));
+ return TMath::Limits<Double_t>::Max();
}
- r = FitJpsi2CB2VWG(*hminv,par[0],par[1],par[2],par[3]);
- if (r)
+ AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
+ if (!sub)
{
- r->SetAlias("MCTAILS");
+ AliError(Form("Could not get subresult named %s",subResultName));
+ return TMath::Limits<Double_t>::Max();
}
+ return sub->GetErrorStat(name);
}
- else if ( sFitType.BeginsWith("PSILOWALPHA") )
+
+ if ( fMap )
{
- Float_t lpar[] = { 0.0, 0.0, 0.0, 0.0 };
-
- AliDebug(1,Form("sFitType=%s",sFitType.Data()));
-
- sscanf(sFitType.Data(),"PSILOWALPHALOW%fNLOW%fALPHAUP%fNUP%f",
- &lpar[0],&lpar[1],&lpar[2],&lpar[3]);
-
- AliDebug(1,Form("PSILOW ALPHALOW=%f NLOW=%f ALPHAUP=%f NUP=%f",lpar[0],lpar[1],lpar[2],lpar[3]));
-
- if ( lpar[0] == 0.0 && lpar[1] == 0.0 && lpar[0] == 0.0 && lpar[1] == 0.0 )
+ TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
+ if (p)
{
- AliError("Cannot work with zero tails !");
+ TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kErrorStat));
+ return val->GetVal();
}
- else
+ }
+
+ TIter next(fSubResults);
+ AliAnalysisMuMuResult* r;
+ Int_t n(0);
+ Double_t v1(0);
+ Double_t v2(0);
+ Double_t d(0);
+
+ Double_t mean = GetValue(name);
+
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
+ {
+ if ( IsIncluded(r->Alias()) && r->HasValue(name) )
{
- r = FitJpsi2CB2VWG(*hminv,lpar[0],lpar[1],lpar[2],lpar[3]);
+ Double_t error = r->GetErrorStat(name);
+ if (error)
+ {
+ v1 += 1.0/(error*error);
+ v2 += 1.0/(error*error*error*error);
+
+ d += ( (r->GetValue(name) - mean)*(r->GetValue(name)-mean) / (error*error));
+ }
+ ++n;
}
}
- else if ( sFitType == "COUNTJPSI" )
- {
- r = new AliAnalysisMuMuResult(*hminv,"COUNTJPSI",1);
- Double_t n = CountParticle(*hminv,"Jpsi");
- r->Set("NofJpsi",n,TMath::Sqrt(n));
- }
+ if ( n<1 ) return 0.0;
- if ( r )
+ if ( n == 1 )
{
- r->Print();
- r->SetBin(Bin());
- r->SetNofTriggers(NofTriggers());
- r->SetNofRuns(NofRuns());
-
- if (!fSubResults)
+ next.Reset();
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
{
- fSubResults = new TObjArray;
- fSubResults->SetOwner(kTRUE);
+ if ( IsIncluded(r->Alias()) && r->HasValue(name) )
+ {
+ return r->GetErrorStat(name);
+ }
}
-
- fSubResults->Add(r);
}
- delete hminv;
+ Double_t variance= (1.0/v1)*(1.0/(n-1))*d;
+ // variance corrected by over/under-estimation of errors
+ // i.e. scaled by chisquare per ndf
- return (r!=0x0);
+ return TMath::Sqrt(variance);
}
//_____________________________________________________________________________
-Double_t AliAnalysisMuMuResult::GetErrorStat(const char* name, const char* subResultName) const
+Double_t AliAnalysisMuMuResult::GetRMS(const char* name, const char* subResultName) const
{
- // compute the mean value from all subresults
-
+ // compute the rms of the subresults
+ // returns zero if no subresults
+
if ( strlen(subResultName) > 0 )
{
if ( !fSubResults)
AliError(Form("Could not get subresult named %s",subResultName));
return TMath::Limits<Double_t>::Max();
}
- return sub->GetErrorStat(name);
+ return sub->GetRMS(name);
}
if ( fMap )
TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
if (p)
{
- TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kErrorStat));
- return val->GetVal();
+ TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kRMS));
+ return val ? val->GetVal() : 0.0; // val can be null for old results which did not have the rms set
}
}
TIter next(fSubResults);
AliAnalysisMuMuResult* r;
+ Double_t v1(0);
+ Double_t v2(0);
+ Double_t sum(0);
Int_t n(0);
- Double_t mean(0);
+
+ Double_t xmean = GetValue(name);
while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
{
- if ( r->HasValue(name) )
+ if ( IsIncluded(r->Alias()) && r->HasValue(name) )
{
- mean += r->GetErrorStat(name);
- ++n;
+ if ( r->GetErrorStat(name) > 0 )
+ {
+ Double_t ei = r->GetErrorStat(name);
+ Double_t wi = 1.0/(ei*ei);
+ v1 += wi;
+ v2 += wi*wi;
+ Double_t diff = r->GetValue(name) - xmean;
+ sum += wi*diff*diff;
+ ++n;
+ }
+ }
+ }
+
+ if ( n < 1 ) return 0.0;
+
+ if ( n == 1 )
+ {
+ next.Reset();
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
+ {
+ if ( IsIncluded(r->Alias()) && r->HasValue(name) )
+ {
+ return r->GetRMS(name);
+ }
}
}
- return ( n ? mean/n : 0.0 );
+
+ Double_t unbiased = TMath::Sqrt( (v1/(v1*v1-v2)) * sum);
+
+ Double_t biased = TMath::Sqrt( sum/v1 );
+
+ AliDebug(1,Form("v1 %e v1*v1 %e v2 %e -> biased %e unbiased %e (ratio %e)",v1,v1*v1,v2,biased,unbiased,unbiased/biased));
+
+ return unbiased;
+}
+
+//_____________________________________________________________________________
+TString AliAnalysisMuMuResult::GetSubResultNameList() const
+{
+ // get a comma separated list of our subresult aliases
+ TString tobeincluded;
+ TIter next(fSubResults);
+ AliAnalysisMuMuResult* r;
+
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
+ {
+ if (tobeincluded.Length()>0) tobeincluded+=",";
+ tobeincluded += r->Alias();
+ }
+ return tobeincluded;
}
//_____________________________________________________________________________
// compute the mean value from all subresults
TIter next(fSubResults);
AliAnalysisMuMuResult* r;
- Int_t n(0);
Double_t mean(0);
+ Double_t errorSum(0.0);
while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
{
- if ( r->HasValue(name) )
+ if ( IsIncluded(r->Alias()) && r->HasValue(name) )
{
- mean += r->GetValue(name);
- ++n;
+ Double_t e = r->GetErrorStat(name);
+ Double_t e2 = e*e;
+ if ( e != 0.0 )
+ {
+ mean += r->GetValue(name)/e2;
+ errorSum += 1.0/e2;
+ }
}
}
- return ( n ? mean/n : 0.0 );
+ if ( errorSum != 0.0 )
+ {
+ return mean/errorSum;
+ }
+ else
+ {
+ return TMath::Limits<Double_t>::Max();
+ }
}
//_____________________________________________________________________________
return kFALSE;
}
+//_____________________________________________________________________________
+void AliAnalysisMuMuResult::Include(const char* subResultList)
+{
+ // (re)include some subresult names
+
+ TString slist(subResultList);
+
+ if ( slist.Length()==0 )
+ {
+ Exclude("*");
+ return;
+ }
+
+ if ( slist == "*" )
+ {
+ slist = GetSubResultNameList();
+ }
+
+ TObjArray* a = slist.Tokenize(",");
+ a->SetOwner(kFALSE);
+ TIter next(a);
+ TObjString* s;
+
+ while ( ( s = static_cast<TObjString*>(next()) ) )
+ {
+ if (!fSubResultsToBeIncluded )
+ {
+ fSubResultsToBeIncluded = new TList;
+ fSubResultsToBeIncluded->SetOwner(kTRUE);
+ }
+ if (!IsIncluded(s->String()))
+ {
+ fSubResultsToBeIncluded->Add(s);
+ }
+ }
+
+ delete a;
+}
+
+//_____________________________________________________________________________
+Bool_t AliAnalysisMuMuResult::IsIncluded(const TString& alias) const
+{
+ // whether that subresult alias should be included when computing means, etc...
+
+ if (!fSubResultsToBeIncluded) return kTRUE;
+
+ return ( fSubResultsToBeIncluded->FindObject(alias) != 0x0 );
+}
+
//_____________________________________________________________________________
THashList* AliAnalysisMuMuResult::Keys() const
{
/// Merge a list of AliAnalysisMuMuResult objects with this
/// Returns the number of merged objects (including this).
///
- /// Note that the merging is to be understood here as an average operation
+ /// Note that the merging is to be understood here as a weighed mean operation
- AliInfo(Form("this=%p",this));
if (!list) return 0;
if (list->IsEmpty()) return 1;
TIter next(list);
TObject* currObj;
- TList hminvList;
- hminvList.SetOwner(kTRUE);
-
- Double_t thisWeight = Weight();
- Double_t sumOfWeights = thisWeight;
- Double_t nofTriggers = fNofTriggers*thisWeight;
- Double_t nofRuns = fNofRuns*thisWeight;
-
- fNofRuns = TMath::Nint(fNofRuns*thisWeight);
+ Double_t sumw(Weight()); // sum of weights
while ( ( currObj = next() ) )
{
continue;
}
- Double_t w = result->Weight();
-
- nofRuns += result->NofRuns()*w;
- nofTriggers += result->NofTriggers()*w;
- fWeight += result->fWeight;
- sumOfWeights += w;
+ sumw += result->Weight();
}
- thisWeight/= sumOfWeights;
- fNofRuns = TMath::Nint(nofRuns/sumOfWeights);
- fNofTriggers = TMath::Nint(nofTriggers/sumOfWeights);
- fWeight /= sumOfWeights;
-
- AliInfo(Form("thisWeight=%e sumOfWeight=%8.2f noftriggers=%e weight=%e",thisWeight,sumOfWeights,1.0*fNofTriggers,fWeight));
-
- TIter nextKey(fMap);
+ TIter nextKey(Keys());
TObjString* key;
while ( ( key = static_cast<TObjString*>(nextKey())) )
{
- AliInfo(key->String().Data());
-
- Double_t value = GetValue(key->String())*thisWeight;
- Double_t estat = GetErrorStat(key->String())*GetErrorStat(key->String())*thisWeight*thisWeight;
-
- Double_t test(thisWeight);
+ Double_t value = GetValue(key->String())*Weight()/sumw;
+ Double_t e = GetErrorStat(key->String());
+ Double_t e2 = e*e*Weight()*Weight()/sumw/sumw;
next.Reset();
// can only merge under the condition we have the same bin
- if ( fBin != result->Bin() )
- {
- AliError("Cannot merge results of different bin");
- continue;
- }
-
- Double_t w = result->Weight()/sumOfWeights;
+ Double_t w = result->Weight()/sumw;
Double_t w2 = w*w;
- test += w;
-
value += result->GetValue(key->String())*w;
- estat += result->GetErrorStat(key->String())*result->GetErrorStat(key->String())*w2;
+ e2 += result->GetErrorStat(key->String())*result->GetErrorStat(key->String())*w2;
}
Set(key->String(),
value,
- TMath::Sqrt(estat));
-
- AliInfo(Form("test=%e",test));
- }
-
- if ( fMinv )
- {
- fMinv->Scale(thisWeight);
- }
-
- next.Reset();
-
- while ( ( currObj = next() ) )
- {
- AliAnalysisMuMuResult* result = dynamic_cast<AliAnalysisMuMuResult*>(currObj);
-
- if ( result->Minv() )
- {
- TH1* h = static_cast<TH1*>(result->Minv()->Clone());
- AliInfo(Form("Nbins %d xmin %e xmax %e",h->GetXaxis()->GetNbins(),h->GetXaxis()->GetXmin(),
- h->GetXaxis()->GetXmax()));
- h->Scale(result->Weight());
- hminvList.Add(h);
- }
- }
-
- if ( fMinv )
- {
- fMinv->Merge(&hminvList);
- fMinv->Scale(1.0/sumOfWeights);
+ TMath::Sqrt(e2));
}
TIter nextSubresult(fSubResults);
r->Merge(&sublist);
}
+ fWeight = sumw;
+
return list->GetEntries()+1;
}
//_____________________________________________________________________________
-Int_t AliAnalysisMuMuResult::NofRuns() const
-{
- /// Get the number of runs
- if ( !Mother() ) return fNofRuns;
- else return Mother()->NofRuns();
-}
-
-//_____________________________________________________________________________
-Int_t AliAnalysisMuMuResult::NofTriggers() const
+Int_t AliAnalysisMuMuResult::NofIncludedSubResults(const char* name) const
{
- /// Get the number of triggers
+ // Return the number of subresults which have key name and are included
- if ( !Mother() ) return fNofTriggers;
- else return Mother()->NofTriggers();
+ TIter next(fSubResults);
+ AliAnalysisMuMuResult* r;
+ Int_t n(0);
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
+ {
+ if ( IsIncluded(r->Alias()) && r->HasValue(name) )
+ {
+ ++n;
+ }
+ }
+ return n;
}
//_____________________________________________________________________________
std::cout << pot.Data();
- if ( fAlias.Length() > 0 )
- {
- std::cout << Form("%s - ",fAlias.Data());
- }
-
- std::cout << Form("%50s - NRUNS %d - NTRIGGER %10d - %s%s",
- GetName(),
- NofRuns(),
- NofTriggers(),
- fWeight > 0.0 ? Form(" WEIGHT %e -",fWeight) : "",
- fBin.AsString().Data());
-
- if ( fSubResults && fSubResults->GetEntries()>1 )
+ if ( fAlias.Length() > 0 )
{
- std::cout << " (" << fSubResults->GetEntries()-1 << " subresults)";
+ std::cout << Form("%s - ",fAlias.Data());
}
- if (!fSubResults )
- {
- std::cout << Form(" - REBIN %d",fRebin) << std::endl;
- }
+ std::cout << Form("%s %s %s",
+ GetName(),GetTitle(),fWeight > 0.0 ? Form(" WEIGHT %e",fWeight) : "");
- std::cout << std::endl;
-
- if ( sopt.Contains("DUMP") )
- {
- TIter next(fMap);
- TObjString* str;
- while ( ( str = static_cast<TObjString*>(next()) ) )
- {
- TObjArray* a = static_cast<TObjArray*>(fMap->GetValue(str->String()));
-
- std::cout << Form("%s %e %e",
- str->String().Data(),
- static_cast<TParameter<Double_t>*> (a->At(kValue))->GetVal(),
- static_cast<TParameter<Double_t>*> (a->At(kErrorStat))->GetVal()) << std::endl;
- }
- }
- else
+ if ( fSubResults && fSubResults->GetEntries()>1 )
{
-
- PrintParticle("Jpsi",pot.Data());
- PrintParticle("PsiPrime",pot.Data());
- PrintParticle("Upsilon",pot.Data());
+ std::cout << " (" << fSubResults->GetEntries() << " subresults)";
}
+
+ std::cout << std::endl;
+
+ TIter next(Keys());
+ TObjString* key;
- if ( HasValue("MBR"))
+ while ( ( key = static_cast<TObjString*>(next())) )
{
- std::cout << Form("\t\tMBR %e +- %e",GetValue("MBR"),GetErrorStat("MBR")) << std::endl;
+ PrintValue(key->String().Data(),pot.Data(),
+ GetValue(key->String()),
+ GetErrorStat(key->String()),
+ GetRMS(key->String()));
}
-
+
if ( fSubResults /* && fSubResults->GetEntries() > 1 */ && ( sopt.Contains("ALL") || sopt.Contains("FULL") ) )
{
std::cout << pot.Data() << "\t===== sub results ===== " << std::endl;
sopt += "\t\t";
- TIter next(fSubResults);
+ TIter nextSubresult(fSubResults);
AliAnalysisMuMuResult* r;
- while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextSubresult()) ) )
{
+ if ( !IsIncluded(r->Alias()) )
+ {
+ std::cout << " [EXCLUDED]";
+ }
r->Print(sopt.Data());
}
}
}
//_____________________________________________________________________________
-void AliAnalysisMuMuResult::PrintParticle(const char* particle, const char* opt) const
-{
- /// Print all information about one particule type
-
- Double_t npart = GetValue(Form("Nof%s",particle));
- if (npart<=0) return;
-
-
- std::cout << opt << Form("\t%s",particle) << std::endl;
-
- // Double_t npartError = GetErrorStat(Form("Nof%s",particle));
-// std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f","Count",npart,npartError) << std::endl;
-
- TIter next(Keys());
- TObjString* key;
-
- while ( ( key = static_cast<TObjString*>(next()) ) )
- {
- if ( !key->String().Contains(particle) ) continue;
-
- PrintValue(key->String(),opt,GetValue(key->String()),GetErrorStat(key->String()));
- }
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::PrintValue(const char* key, const char* opt, Double_t value, Double_t errorStat)
+void AliAnalysisMuMuResult::PrintValue(const char* key, const char* opt,
+ Double_t value, Double_t errorStat, Double_t rms) const
{
// print one value and its associated error
if ( TString(key).Contains("AccEff") )
{
- std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f %%",key,value*100,errorStat*100) << std::endl;
+ std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f %% (%5.2f %%)",key,value*100,errorStat*100,
+ value != 0.0 ? errorStat*100.0/value : 0.0 );
+
+ if ( rms )
+ {
+ std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
+ }
+
+ std::cout << std::endl;
}
else if ( TString(key).BeginsWith("Sigma") || TString(key).BeginsWith("Mean") )
{
- std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f MeV/c^2",key,value*1E3,1E3*errorStat) << std::endl;
+ std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%) MeV/c^2",key,value*1E3,1E3*errorStat,
+ value != 0.0 ? errorStat*100.0/value : 0.0);
+
+ if ( rms )
+ {
+ std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
+ }
+
+ std::cout << std::endl;
}
- else if ( TString(key).Contains("Nof") )
+ else if ( TString(key).Contains("Nof") || ( TString(key).Contains("Fnorm") && !TString(key).Contains("persion") ) )
{
- std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f",key,value,errorStat) << std::endl;
+ std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%)",key,value,errorStat,
+ value != 0.0 ? errorStat*100.0/value : 0.0);
+
+ if ( rms )
+ {
+ std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
+ }
+ std::cout << std::endl;
}
else if ( value > 1E-3 && value < 1E3 )
{
- std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f",key,value,errorStat) << std::endl;
+ std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%)",key,value,errorStat,
+ value != 0.0 ? errorStat*100.0/value : 0.0);
+ if ( rms )
+ {
+ std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
+ }
+ std::cout << std::endl;
}
else
{
- std::cout << opt << Form("\t\t%20s %9.2e +- %9.2e",key,value,errorStat) << std::endl;
+ std::cout << opt << Form("\t\t%20s %9.2e +- %9.2e (%5.2f %%)",key,value,errorStat,
+ value != 0.0 ? errorStat*100.0/value : 0.0);
+ if ( rms )
+ {
+ std::cout << Form(" RMS %9.2e (%5.2f %%)",rms,100.0*rms/value);
+ }
+ std::cout << std::endl;
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisMuMuResult::Scale(Double_t w)
+{
+ /// Scale all our internal values by value
+
+ TIter next(Keys());
+ TObjString* key;
+
+ while ( ( key = static_cast<TObjString*>(next())) )
+ {
+ Double_t value = GetValue(key->String());
+ Double_t error = GetErrorStat(key->String());
+ Double_t rms = GetRMS(key->String());
+
+ Set(key->String(),value*w,error*w,rms*w);
}
+
}
//_____________________________________________________________________________
-void AliAnalysisMuMuResult::Set(const char* name, Double_t value, Double_t errorStat)
+void AliAnalysisMuMuResult::Set(const char* name, Double_t value, Double_t errorStat, Double_t rms)
{
/// Set a (value,error) pair with a given name
p->AddAt(new TParameter<Double_t>(name,value),kValue);
p->AddAt(new TParameter<Double_t>(name,errorStat),kErrorStat);
+ p->AddAt(new TParameter<Double_t>(name,rms),kRMS);
fMap->Add(new TObjString(name),p);
}
{
static_cast<TParameter<double>*>(p->At(kValue))->SetVal(value);
static_cast<TParameter<double>*>(p->At(kErrorStat))->SetVal(errorStat);
+ static_cast<TParameter<double>*>(p->At(kRMS))->SetVal(rms);
}
-
- if ( TString(name)=="NofJpsi" )
- {
- if ( NofTriggers() > 0 )
- {
- Double_t rate = value/NofTriggers();
- Double_t rateError = rate*ErrorAB(value,errorStat,NofTriggers(),TMath::Sqrt(NofTriggers()));
- Set("RateJpsi",rate,rateError);
- }
- }
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::SetBin(const AliAnalysisMuMuBinning::Range& bin)
-{
- /// Set the bin
-
- if (!Mother()) fBin = bin;
- else Mother()->SetBin(bin);
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::SetNofInputParticles(const TH1& hminv)
-{
- /// Set the number of input particle from the invariant mass spectra
-
- static const char* particleNames[] = { "Jpsi" , "PsiPrime", "Upsilon","UpsilonPrime" };
-
- for ( Int_t i = 0; i < 4; ++i )
- {
- Double_t n = CountParticle(hminv,particleNames[i]);
-
- AliDebug(1,Form("i=%d particle %s n %e",i,particleNames[i],n));
-
- if ( n > 0 )
- {
- SetNofInputParticles(particleNames[i],TMath::Nint(n));
- }
- }
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::SetNofInputParticles(const char* particle, int n)
-{
- /// Set the number of input particles (so it is a MC result)
- /// and (re)compute the AccxEff values
-
- Set(Form("NofInput%s",particle),n,TMath::Sqrt(n));
-
- if (n<=0)
- {
- Set(Form("AccEff%s",particle),0,0);
- return;
- }
-
- Double_t npart = GetValue(Form("Nof%s",particle));
- Double_t npartErr = GetErrorStat(Form("Nof%s",particle));
- Double_t ninput = GetValue(Form("NofInput%s",particle));
- Double_t ninputErr = GetErrorStat(Form("NofInput%s",particle));
-
- Set(Form("AccEff%s",particle),
- npart/ninput,
- (npart/ninput)*ErrorAB(npart,npartErr,ninput,ninputErr));
-
- TIter next(fSubResults);
- AliAnalysisMuMuResult* r;
-
- while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
- {
- r->Set(Form("NofInput%s",particle),n,TMath::Sqrt(n));
-
- npart = r->GetValue(Form("Nof%s",particle));
- npartErr = r->GetErrorStat(Form("Nof%s",particle));
-
- r->Set(Form("AccEff%s",particle),
- npart/ninput,
- (npart/ninput)*ErrorAB(npart,npartErr,ninput,ninputErr));
-
- }
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::SetNofRuns(Int_t n)
-{
- if ( !Mother() ) fNofRuns=n;
- else Mother()->SetNofRuns(n);
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::SetNofTriggers(Int_t n)
-{
- if ( !Mother() ) fNofTriggers=n;
- else Mother()->SetNofTriggers(n);
-}
-
-//_____________________________________________________________________________
-void AliAnalysisMuMuResult::SetMinv(const TH1& hminv)
-{
- /// Set the inv. mass spectrum to be fitted.
- static UInt_t n(0);
-
- delete fMinv;
- fMinv = static_cast<TH1*>(hminv.Clone(Form("Minv%u",n++)));
- fMinv->SetDirectory(0);
}
//_____________________________________________________________________________
return 0x0;
}
+//_____________________________________________________________________________
+TList* AliAnalysisMuMuResult::SubResultsToBeIncluded() const
+{
+ if (!fSubResultsToBeIncluded)
+ {
+ fSubResultsToBeIncluded = new TList;
+ fSubResultsToBeIncluded->SetOwner(kTRUE);
+ }
+ return fSubResultsToBeIncluded;
+}
+
#include "TNamed.h"
#include <TString.h>
-#include "AliAnalysisMuMuBinning.h"
class TH1;
class THashList;
-class TF1;
class TMap;
class AliAnalysisMuMuResult : public TNamed
public:
- AliAnalysisMuMuResult(TRootIOCtor* io);
-
- AliAnalysisMuMuResult(const TH1& hminv);
-
- AliAnalysisMuMuResult(const TH1& hminv,
- const char* fitType,
- Int_t nrebin);
-
- AliAnalysisMuMuResult(const TH1& hminv,
- const char* triggerClass,
- const char* eventSelection,
- const char* pairSelection,
- const char* centSelection,
- const AliAnalysisMuMuBinning::Range& bin);
-
+ AliAnalysisMuMuResult(const char* name="", const char* title="");
AliAnalysisMuMuResult(const AliAnalysisMuMuResult& rhs);
AliAnalysisMuMuResult& operator=(const AliAnalysisMuMuResult& rhs);
virtual ~AliAnalysisMuMuResult();
+ void AdoptSubResult(AliAnalysisMuMuResult* r);
+
virtual TObject* Clone(const char* newname = "") const;
- Bool_t Correct(const AliAnalysisMuMuResult& other, const char* particle, const char* subResultName="");
-
- TH1* Minv() const { return fMinv; }
-
- void Set(const char* name, Double_t value, Double_t errorStat);
+ void Set(const char* name, Double_t value, Double_t errorStat, Double_t rms=0.0);
Bool_t HasValue(const char* name, const char* subResultName="") const;
Double_t GetErrorStat(const char* name, const char* subResultName="") const;
- Int_t NofTriggers() const;
-
- void SetNofTriggers(Int_t n);
+ Double_t GetRMS(const char* name, const char* subResultName="") const;
void Print(Option_t* opt="") const;
- Bool_t AddFit(const char* fitType, Int_t npar=0, Double_t* par=0x0);
-
- AliAnalysisMuMuResult* CountJpsi(TH1& h);
-
- AliAnalysisMuMuResult* FitJpsi(TH1& h);
-
- AliAnalysisMuMuResult* FitJpsiNA48(const TH1& h);
- AliAnalysisMuMuResult* FitJpsiCB2VWG(const TH1& h);
- AliAnalysisMuMuResult* FitJpsi2CB2VWG(const TH1& h, Double_t alphaLow=-1.0, Double_t nLow=-1.0, Double_t alphaUp=-1.0, Double_t nUp=-1.0);
-
- AliAnalysisMuMuResult* FitJpsiGCBE(TH1& h);
-
- Int_t NofRuns() const;
-
- void SetNofRuns(int n);
-
- const AliAnalysisMuMuBinning::Range& Bin() const;
-
- void SetBin(const AliAnalysisMuMuBinning::Range& bin);
-
- void SetNofInputParticles(const char* particle, int n);
-
- void SetNofInputParticles(const TH1& hminv);
-
- void SetMinv(const TH1& hminv);
-
AliAnalysisMuMuResult* SubResult(const char* subResultName) const;
TObjArray* SubResults() const { return fSubResults; }
THashList* Keys() const;
- Double_t Weight() const { return fWeight > 0 ? fWeight : fNofTriggers; }
+ Double_t Weight() const { return fWeight; }
void SetWeight(Double_t w) { fWeight=w; }
- static Double_t CountParticle(const TH1& hminv, const char* particle, Double_t sigma=-1.0);
-
static Double_t ErrorAB(Double_t a, Double_t aerr, Double_t b, Double_t berr);
static Double_t ErrorABC(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror);
- static void PrintValue(const char* key, const char* opt, Double_t value, Double_t errorStat);
+ static Double_t ErrorABCD(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror,
+ Double_t d, Double_t derror);
+
+ static Double_t ErrorABCDE(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror,
+ Double_t d, Double_t derror, Double_t e, Double_t eerror);
+
+ void PrintValue(const char* key, const char* opt, Double_t value, Double_t errorStat, Double_t rms=0.0) const;
void SetAlias(const char* alias) { fAlias = alias; }
TString Alias() const { if ( fAlias.Length()>0) return fAlias; else return GetName(); }
+ void Include(const char* subResultsList);
+
+ void Exclude(const char* subResultsList);
+
+ Bool_t IsIncluded(const TString& alias) const;
+
+ void Scale(Double_t value);
+
private:
enum EIndex
{
kValue=0,
- kErrorStat=1
+ kErrorStat=1,
+ kRMS=2
};
void PrintParticle(const char* particle, const char* opt) const;
+ TList* SubResultsToBeIncluded() const;
+
+ TString GetSubResultNameList() const;
+
+ Int_t NofIncludedSubResults(const char* name) const;
+
private:
- Int_t fNofRuns; // number of runs used to get this result
- Int_t fNofTriggers; // number of trigger analyzed
- TH1* fMinv; // invariant mass spectrum
- AliAnalysisMuMuBinning::Range fBin; // bin range
TObjArray* fSubResults; // TObjArray of AliAnalysisMuMuResult*
TMap* fMap; // internal parameter map
AliAnalysisMuMuResult* fMother; // mother result
mutable THashList* fKeys; //! keys we have in our internal map (or the one of our subresults)
Double_t fWeight; // weight of this result (default 1.0)
- Int_t fRebin; // rebin level of minv spectra
-
- TString fTriggerClass; // trigger class for this result
- TString fEventSelection; // event selection for this result
- TString fPairSelection; // pair selection for this result
- TString fCentralitySelection; // centrality selection for this result
-
TString fAlias; // alias name
+ mutable TList* fSubResultsToBeIncluded; // inclusion list
- ClassDef(AliAnalysisMuMuResult,8) // a class to hold invariant mass analysis results (counts, yields, AccxEff, R_AB, etc...)
+ ClassDef(AliAnalysisMuMuResult,11) // a class to some results (counts, yields, AccxEff, R_AB, etc...)
};
#endif
#include "AliLog.h"
#include "AliAnalysisMuMuBinning.h"
-#include "AliAnalysisMuMuResult.h"
+#include "AliAnalysisMuMuJpsiResult.h"
#include "Riostream.h"
#include "TH1.h"
#include "TList.h"
AliAnalysisMuMuSpectra::AliAnalysisMuMuSpectra(const char* name, const char* title) :
TNamed(name,title),
fBinning(0x0),
-fBins(0x0)
+fBins(0x0),
+fWeight(1.0)
{
// default ctor
}
AliAnalysisMuMuSpectra::AliAnalysisMuMuSpectra(const AliAnalysisMuMuSpectra& rhs)
: TNamed(rhs.GetName(),rhs.GetTitle()),
fBinning(0x0),
-fBins(0x0)
+fBins(0x0),
+fWeight(rhs.Weight())
{
// copy ctor
}
TIter next(rhs.fBins);
- AliAnalysisMuMuBinning::Range* bin;
+ AliAnalysisMuMuResult* bin;
- while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
+ while ( ( bin = static_cast<AliAnalysisMuMuResult*>(next()) ) )
{
if (!fBins)
{
}
fBins->Add(bin);
}
+
+
}
//______________________________________________________________________________
}
TIter next(rhs.fBins);
- AliAnalysisMuMuBinning::Range* bin;
+ AliAnalysisMuMuResult* bin;
- while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
+ while ( ( bin = static_cast<AliAnalysisMuMuResult*>(next()) ) )
{
if (!fBins)
{
fBins->Add(bin);
}
+ fWeight = rhs.Weight();
+
return *this;
}
return kFALSE;
}
- TObjArray* bins = accEff.Bins();
+ TObjArray* bins = accEff.BinContentArray();
for ( Int_t i = 0; i < bins->GetEntries(); ++i )
{
- AliAnalysisMuMuResult* thisResult = static_cast<AliAnalysisMuMuResult*>(fBins->At(i));
- AliAnalysisMuMuResult* accResult = static_cast<AliAnalysisMuMuResult*>(bins->At(i));
+ AliAnalysisMuMuJpsiResult* thisResult = static_cast<AliAnalysisMuMuJpsiResult*>(fBins->At(i));
+ AliAnalysisMuMuJpsiResult* accResult = static_cast<AliAnalysisMuMuJpsiResult*>(bins->At(i));
// AliInfoClass(Form("i=%d",i ));
// StdoutToAliInfoClass(thisResult->Print("full");
// std::cout << "----" << std::endl;
TList binningList;
- for ( Int_t i = 0; i <= fBins->GetLast(); ++i )
+ // for each bin must do a list of results, and merge that list
+
+ TObjArray* bins = fBinning->CreateBinObjArray();
+ TIter nextBin(bins);
+ AliAnalysisMuMuBinning::Range* bin;
+
+ Int_t i(0);
+
+ while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(nextBin()) ) )
{
next.Reset();
while ( ( currObj = next() ) )
{
- AliAnalysisMuMuSpectra* spectra = dynamic_cast<AliAnalysisMuMuSpectra*>(currObj);
- if (!spectra)
- {
- AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuSpectra!", currObj->GetName(), currObj->ClassName()));
- continue;
- }
-
+ AliAnalysisMuMuSpectra* spectra = static_cast<AliAnalysisMuMuSpectra*>(currObj);
+
if (i==0)
{
binningList.Add(spectra->Binning());
- if ( !fBinning->IsEqual(spectra->Binning()) || spectra->Bins()->GetLast() != Bins()->GetLast() )
+ if ( !fBinning->IsEqual(spectra->Binning()) || spectra->BinContentArray()->GetLast() != BinContentArray()->GetLast() )
{
AliError("Cannot merge spectra with different binning");
continue;
}
-
++count;
}
- binList.Add(fBins->At(i));
+ binList.Add(spectra->GetResultForBin(*bin));
}
- AliAnalysisMuMuResult* r = static_cast<AliAnalysisMuMuResult*>(fBins->At(i));
+ ++i;
+
+ AliAnalysisMuMuResult* r = static_cast<AliAnalysisMuMuResult*>(GetResultForBin(*bin));
r->Merge(&binList);
}
-
- fBinning->Merge(&binningList);
+
+ delete bins;
return count+1;
}
for ( Int_t j = 0; j < TMath::Min(binArray->GetEntries(),fBins->GetEntries()); ++j )
{
- AliAnalysisMuMuResult* r = static_cast<AliAnalysisMuMuResult*>(fBins->At(j));
+ AliAnalysisMuMuJpsiResult* r = static_cast<AliAnalysisMuMuJpsiResult*>(fBins->At(j));
if ( strlen(subresult) > 0 && r->SubResults() )
{
TString sub(subresult);
sub.ToUpper();
- r = r->SubResult(sub.Data());
+ r = static_cast<AliAnalysisMuMuJpsiResult*>(r->SubResult(sub.Data()));
if (!r) continue;
}
yerr /= (b.WidthX());
}
+ if (!TMath::Finite(y)) y = 0.0;
+ if (!TMath::Finite(yerr)) yerr = 0.0;
+
std::cout << b.AsString();
- AliAnalysisMuMuResult::PrintValue(swhat.Data(),"",y,yerr);
+ r->PrintValue(swhat.Data(),"",y,yerr);
h->SetBinContent(j+1,y);
h->SetBinError(j+1,yerr);
}
}
}
+
+//______________________________________________________________________________
+void AliAnalysisMuMuSpectra::Scale(Double_t value)
+{
+ // scale all bins by value
+
+ TIter next(fBins);
+ AliAnalysisMuMuResult* r;
+
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
+ {
+ r->Scale(value);
+ }
+}
+
+//______________________________________________________________________________
+void AliAnalysisMuMuSpectra::SetWeight(Double_t w)
+{
+ // Set the weight of this spectra
+ fWeight = w;
+ TIter next(fBins);
+ AliAnalysisMuMuResult* r;
+
+ while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
+ {
+ r->SetWeight(Weight());
+ }
+}
void Print(Option_t* opt="") const;
- TObjArray* Bins() const { return fBins; }
+ TObjArray* BinContentArray() const { return fBins; }
AliAnalysisMuMuBinning* Binning() const { return fBinning; }
Bool_t HasValue(const char* what="NofJpsi") const;
+ void Scale(Double_t value);
+
+ void SetWeight(Double_t w);
+
+ Double_t Weight() const { return fWeight; }
+
private:
AliAnalysisMuMuBinning* fBinning; // internal binning
TObjArray* fBins; // the results (bin by bin)
+ Double_t fWeight; // weight of this spectra (assumed to be a normalized weight)
- ClassDef(AliAnalysisMuMuSpectra,1) // class to hold spectra (with its associated binning and errors)
+ ClassDef(AliAnalysisMuMuSpectra,2) // class to hold spectra (with its associated binning and errors)
};
#endif
return 0;
}
-
- //______________________________________________________________________________
- Double_t Mu(Double_t L0B, Double_t Nb)
- {
- /// L0B = trigger rate before any veto
- /// Nb = number of crossing bunches
-
- Double_t p0 = 1-L0B/(Nb*11245.0); // proba to get *no* collision per bunch crossing
-
- return -TMath::Log(p0);
- }
-
//______________________________________________________________________________
TCanvas* NewCanvas(const char* name)
{
//______________________________________________________________________________
-void AliAnalysisTriggerScalers::DrawFill(Int_t run1, Int_t run2, double ymin, double ymax, const char* label)
+void AliAnalysisTriggerScalers::DrawFill(Int_t run1, Int_t run2, double ymin, double ymax, const char* label, Int_t color)
{
// Draw a yellow box to indicate a run range
AliDebugClass(1,Form("RUN1 %09d RUN2 %09d YMIN %e YMAX %e %s",
run1,run2,ymin,ymax,label));
TBox* b = new TBox(run1*1.0,ymin,run2*1.0,ymax);
- b->SetFillColor(5);
+ b->SetFillColor(color);
b->Draw();
TText* text = new TText((run1+run2)/2.0,ymin + (ymax-ymin)*0.85,label);
text->SetTextSize(0.025);
}
//_____________________________________________________________________________
-void AliAnalysisTriggerScalers::DrawFills(Double_t ymin, Double_t ymax)
+void AliAnalysisTriggerScalers::DrawFills(Double_t ymin, Double_t ymax, Int_t color)
{
/// Draw the fill ranges corresponding to the list of runs
/// Note that this method will scan the OCDB to get the run -> fill number relationship,
const std::pair<int,int>& p = it->second;
TString fillnumber;
fillnumber.Form("%d",it->first);
- DrawFill(p.first,p.second,ymin,ymax,fillnumber.Data());
+ DrawFill(p.first,p.second,ymin,ymax,fillnumber.Data(),color);
+ }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisTriggerScalers::DrawPeriods(Double_t ymin, Double_t ymax, Int_t color)
+{
+ /// Draw the period ranges corresponding to the list of runs
+ /// Note that this method will scan the OCDB to get the run -> fill number relationship,
+ /// so it's better in this case to use a local copy of the OCDB if you have one. Otherwise
+ /// it will be long.
+
+ std::map<std::string, std::pair<int,int> > periods;
+
+ GetLHCPeriodBoundaries(periods);
+
+ for ( std::map<std::string, std::pair<int,int> >::const_iterator it = periods.begin(); it != periods.end(); ++it )
+ {
+ const std::pair<int,int>& p = it->second;
+ DrawFill(p.first,p.second,ymin,ymax,it->first.c_str(),color);
}
+
}
//_____________________________________________________________________________
if ( !AliCDBManager::Instance()->IsDefaultStorageSet() )
{
+ AliInfo(Form("Setting OCDB default storage to %s",fOCDBPath.Data()));
AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data());
}
return total > 0 ? nopac*1.0/total : 0.0;
}
+//______________________________________________________________________________
+void AliAnalysisTriggerScalers::GetPileUpFactor(Int_t runNumber, const char* triggerClassName,
+ Double_t purity,
+ Double_t& value, Double_t& error)
+{
+ /// Get the mean pile-up correction factor for the given run
+
+ value = error = 0.0;
+
+ if (purity<=0.0)
+ {
+ AliError(Form("Cannot work with purity=%f for trigger %s in run %d. Should be strictly positive",purity,triggerClassName,runNumber));
+ return;
+ }
+
+ AliTriggerRunScalers* trs = static_cast<AliTriggerRunScalers*>(GetOCDBObject("GRP/CTP/Scalers",runNumber));
+ const TObjArray* scalers = trs->GetScalersRecords();
+ const AliTriggerScalersRecord* begin = (AliTriggerScalersRecord*)(scalers->First());
+ const AliTriggerScalersRecord* end = (AliTriggerScalersRecord*)(scalers->Last());
+
+ time_t duration = TMath::Nint((end->GetTimeStamp()->GetBunchCross() - begin->GetTimeStamp()->GetBunchCross())*AliTimeStamp::fNanosecPerBC*1E-9);
+
+ if (!duration)
+ {
+ AliError(Form("Got zero duration for run %d",runNumber));
+ return;
+ }
+
+ AliAnalysisTriggerScalerItem* item = GetTriggerScaler(runNumber,"L0B",triggerClassName);
+ if (!item)
+ {
+ AliError(Form("Could not get L0B for trigger %s in run %d",triggerClassName,runNumber));
+ return;
+ }
+
+ AliLHCData* lhc = static_cast<AliLHCData*>(GetOCDBObject("GRP/GRP/LHCData",runNumber));
+
+ Int_t nbcx = NumberOfInteractingBunches(*lhc,runNumber);
+
+ if ( nbcx<=0.0 )
+ {
+ AliError(Form("Cannot work with nbcx=%d for trigger %s in run %d. Should be strictly positive",nbcx,triggerClassName,runNumber));
+ return;
+ }
+
+ Double_t itemValue = purity*item->Value();
+
+ if (itemValue<=0.0)
+ {
+ AliError(Form("Cannot work with value=%f for trigger %s in run %d. Should be strictly positive",itemValue,triggerClassName,runNumber));
+ return;
+ }
+
+ Double_t mu = Mu(itemValue/duration,nbcx);
+
+ value = mu/(1.0-TMath::Exp(-mu));
+
+ error = 0.0; // FIXME
+}
+
//______________________________________________________________________________
AliAnalysisTriggerScalerItem*
AliAnalysisTriggerScalers::GetTriggerScaler(Int_t runNumber, const char* level, const char* triggerClassName)
return 0x0;
}
- Int_t nbcx = NumberOfInteractingBunches(*lhc);
+ Int_t nbcx = NumberOfInteractingBunches(*lhc,runNumber);
if (nbcx <= 0 && ShouldCorrectForPileUp())
{
}
//______________________________________________________________________________
-Int_t AliAnalysisTriggerScalers::NumberOfInteractingBunches(const AliLHCData& lhc) const
+Double_t AliAnalysisTriggerScalers::Mu(Double_t L0B, Double_t Nb)
+{
+ /// L0B = trigger rate before any veto
+ /// Nb = number of crossing bunches
+
+ Double_t p0 = 1-L0B/(Nb*11245.0); // proba to get *no* collision per bunch crossing
+
+ return -TMath::Log(p0);
+}
+
+//______________________________________________________________________________
+Int_t AliAnalysisTriggerScalers::NumberOfInteractingBunches(const AliLHCData& lhc, Int_t runNumber) const
{
/// Extract the number of colliding bunches from the LHC data
if ( valm->GetValue(i) <= 0 ) ++nIBM2;
}
+ if (!numberOfInteractingBunches)
+ {
+ return 0;
+ }
+
if ( numberOfInteractingBunches != numberOfInteractingBunchesMeasured ||
numberOfInteractingBunches != nIBM2 )
{
- AliWarning(Form("Got some different number of interacting bunches here ! NumberOfInteractingBunches=%3d NumberOfInteractingBunchesMeasured=%3d NIBM2=%3d",
- numberOfInteractingBunches,numberOfInteractingBunchesMeasured,nIBM2));
+ Int_t delta = TMath::Max(numberOfInteractingBunches - numberOfInteractingBunchesMeasured,numberOfInteractingBunches-nIBM2);
+
+ if ( 1.0*TMath::Abs(delta)/numberOfInteractingBunches > 0.05 ) // more than 5% difference
+ {
+ AliWarning(Form("Got some different number of interacting bunches for fill %d run %d ! NumberOfInteractingBunches=%3d NumberOfInteractingBunchesMeasured=%3d NIBM2=%3d. Will use %d",
+ lhc.GetFillNumber(),runNumber,
+ numberOfInteractingBunches,numberOfInteractingBunchesMeasured,nIBM2,numberOfInteractingBunches));
+ }
+ else
+ {
+ AliDebug(1,Form("Got some different number of interacting bunches for fill %d run %d ! NumberOfInteractingBunches=%3d NumberOfInteractingBunchesMeasured=%3d NIBM2=%3d. Will use %d",
+ lhc.GetFillNumber(),runNumber,
+ numberOfInteractingBunches,numberOfInteractingBunchesMeasured,nIBM2,numberOfInteractingBunches));
+
+ }
}
return numberOfInteractingBunches;
GetCTPObjects(runNumber,tc,trs,lhc);
- Int_t numberOfInteractingBunches = NumberOfInteractingBunches(*lhc);
+ Int_t numberOfInteractingBunches = NumberOfInteractingBunches(*lhc,runNumber);
const TObjArray* scalers = trs->GetScalersRecords();
}
else if ( swhat.Contains("MU") )
{
+ if (timelapse==0) continue;
value = Mu(l0b/timelapse,numberOfInteractingBunches);
error = 0.0; // FIXME
}
{
/// Read integers from filename, where integers are either
/// separated by "," or by return carriage
- std::ifstream in(gSystem->ExpandPathName(filename));
+
+ if ( gSystem->AccessPathName(filename)==kTRUE )
+ {
+ return;
+ }
+ std::ifstream in(gSystem->ExpandPathName(filename));
int i;
std::set<int> runset;
else
{
ReadIntegers(runlist,fRunList);
+ if (fRunList.empty())
+ {
+ if ( TString(runlist).IsDigit() )
+ {
+ SetRunList(TString(runlist).Atoi());
+ }
+ else
+ {
+ AliError("Could not set run list !");
+ }
+ }
}
}
void CrossSectionUnit(const char* unit="ub") { fCrossSectionUnit=unit; fCrossSectionUnit.ToUpper(); }
TString CrossSectionUnit() const { return fCrossSectionUnit; }
- void DrawFills(Double_t ymin, Double_t ymax);
- void DrawFill(Int_t run1, Int_t run2, double ymin, double ymax, const char* label);
+ void DrawFills(Double_t ymin, Double_t ymax, Int_t color=5);
+ void DrawFill(Int_t run1, Int_t run2, double ymin, double ymax, const char* label,Int_t color=5);
+
+ void DrawPeriods(Double_t ymin, Double_t ymax, Int_t color=5);
void GetCTPObjects(Int_t runNumber, AliTriggerConfiguration*& tc, AliTriggerRunScalers*& trs, AliLHCData*& lhc) const;
Float_t GetPauseAndConfigCorrection(Int_t runNumber, const char* triggerClassName);
+ void GetPileUpFactor(Int_t runNumber, const char* triggerClassName, Double_t purity, Double_t& value, Double_t& error);
+
const std::vector<int>& GetRunList() const { return fRunList; }
Int_t GetTriggerInput(Int_t runNumber, const char* inputname);
TGraph* MakeGraph(const std::vector<int>& vx, const std::vector<int>& vex,
const std::vector<double>& vy, const std::vector<double>& vey);
- Int_t NumberOfInteractingBunches(const AliLHCData& lhc) const;
+ static Double_t Mu(Double_t L0B, Double_t Nb);
+
+ Int_t NumberOfInteractingBunches(const AliLHCData& lhc, Int_t runNumber) const;
TGraph* PlotTrigger(const char* triggerClassName, const char* what);
Int_t splitLevel=10;
}
+ClassImp(AliMuonAccEffSubmitter)
+
//______________________________________________________________________________
AliMuonAccEffSubmitter::AliMuonAccEffSubmitter(const char* generator)
-: TObject(),
-fScalers(0x0),
-fRemoteDir(""),
-fReferenceTrigger(""),
-fRatio(1.0),
+: AliMuonGridSubmitter(AliMuonGridSubmitter::kAccEff),
+fRatio(-1.0),
fFixedNofEvents(10000),
fMaxEventsPerChunk(5000),
-fLocalDir(gSystem->pwd()),
-fOCDBPath("raw://"),
-fTemplateDir(gSystem->ExpandPathName("$ALICE_ROOT/PWG/muondep/AccEffTemplates")),
-fPackageAliroot(),
-fPackageGeant3(),
-fPackageRoot(),
-fPackageApi(),
-fMergedDir(Form("%s/AODs",fRemoteDir.Data())),
fSplitMaxInputFileNumber(20),
fCompactMode(1),
-fShouldOverwriteFiles(kFALSE),
-fVars(0x0),
fExternalConfig(""),
-fUseOCDBSnapshots(kTRUE),
-fIsValid(kFALSE),
-fTemplateFileList(0x0),
-fLocalFileList(0x0),
-fSnapshotDir(fLocalDir),
+fUseOCDBSnapshots(kFALSE),
fUseAODMerging(kFALSE)
{
// ctor
- if (!TGrid::Connect("alien://"))
- {
- AliError("cannot connect to grid");
- fIsValid = kFALSE;
- }
-
- SetPackages("VO_ALICE@AliRoot::v5-03-Rev-18","VO_ALICE@GEANT3::v1-14-8","VO_ALICE@ROOT::v5-34-05-1");
+ SetOCDBPath("raw://");
+
+ SetLocalDirectory("Snapshot",LocalDir());
SetVar("VAR_OCDB_PATH","\"raw://\"");
SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P2","0.141776");
SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P3","0.0130173");
- UseOCDBSnapshots(kTRUE);
+ UseOCDBSnapshots(fUseOCDBSnapshots);
SetGenerator(generator);
-}
-
-//______________________________________________________________________________
-AliMuonAccEffSubmitter::~AliMuonAccEffSubmitter()
-{
- // dtor
- delete fScalers;
- delete fTemplateFileList;
- delete fLocalFileList;
- delete fVars;
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::CheckCompilation(const char* file) const
-{
- /// Check whether file can be compiled or not
- /// FIXME: use gSystem->TempFileName for tmpfile !
-
- Bool_t rv(kTRUE);
-
- TString sfile(gSystem->BaseName(file));
- TString tmpfile(Form("tmpfile_%s",sfile.Data()));
-
- gSystem->Exec(Form("cp %s %s",file,tmpfile.Data()));
- ReplaceVars(tmpfile.Data());
+ MakeNofEventsPropToTriggerCount();
- gSystem->AddIncludePath("-I$ALICE_ROOT/include");
- gSystem->AddIncludePath("-I$ALICE_ROOT/EVGEN");
-
- if (gROOT->LoadMacro(Form("%s++",tmpfile.Data())))
- {
- AliError(Form("macro %s can not be compiled. Please check.",file));
- rv = kFALSE;
- }
+ AddToTemplateFileList("CheckESD.C");
+ AddToTemplateFileList("CheckAOD.C");
+ AddToTemplateFileList("AODtrain.C");
+ AddToTemplateFileList("validation.sh");
- gSystem->Exec(Form("rm %s",tmpfile.Data()));
+ AddToTemplateFileList("Config.C");
+ AddToTemplateFileList("rec.C");
+ AddToTemplateFileList("sim.C");
+ AddToTemplateFileList("simrun.C");
+ AddToTemplateFileList(RunJDLName().Data());
- return rv;
+ UseExternalConfig(fExternalConfig);
}
-
//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::CheckLocal() const
-{
- /// Check whether all required local files are there
- TIter next(LocalFileList());
- TObjString* file;
-
- while ( ( file = static_cast<TObjString*>(next())) )
- {
- if ( gSystem->AccessPathName(file->String().Data()) )
- {
- return kFALSE;
- }
- }
-
- return kTRUE;
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::CheckRemote() const
-{
- /// Check whether all required remote files are there
- AliWarning("implement me");
- return kFALSE;
-}
-
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::CleanLocal(Bool_t cleanSnapshots) const
-{
- /// Clean (remove) local generated files
- /// As OCDB snapshot creation is a long process, cleanSnapshots
- /// is kFALSE by default in order not to delete those.
-
- TIter next(LocalFileList());
- TObjString* file;
-
- while ( ( file = static_cast<TObjString*>(next())) )
- {
- if ( !cleanSnapshots && file->String().Contains("OCDB_") ) continue;
- gSystem->Unlink(file->String().Data());
- }
-}
-
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::CleanRemote() const
+AliMuonAccEffSubmitter::~AliMuonAccEffSubmitter()
{
- /// Clean (remove) remote files
- AliWarning("implement me");
+ // dtor
}
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::CopyFile(const char* localFile)
+///______________________________________________________________________________
+Bool_t AliMuonAccEffSubmitter::Generate(const char* jdlname) const
{
- /// copy a local file to remote destination
- TString local;
-
- if ( gSystem->IsAbsoluteFileName(localFile) )
- {
- local = localFile;
- }
- else
- {
- local = Form("%s/%s",fLocalDir.Data(),gSystem->ExpandPathName(localFile));
- }
-
- if (gSystem->AccessPathName(local.Data()))
- {
- AliError(Form("Local file %s does not exist",local.Data()));
- return kFALSE;
- }
-
- TString remote;
-
- remote += fRemoteDir;
- remote += "/";
-
- if ( gSystem->IsAbsoluteFileName(localFile) )
- {
- TString tmp(localFile);
- tmp.ReplaceAll(fSnapshotDir.Data(),"");
- remote += tmp;
- }
- else
- {
- remote += localFile;
- }
-
- TString dirName = gSystem->DirName(remote.Data());
-
- Bool_t ok(kTRUE);
-
- if (!RemoteDirectoryExists(dirName.Data()))
- {
- ok = gGrid->Mkdir(dirName.Data(),"-p");
- }
-
- if ( ok )
+ if ( TString(jdlname).Contains("merge",TString::kIgnoreCase) )
{
- AliDebug(1,Form("cp %s alien://%s",local.Data(),remote.Data()));
- return TFile::Cp(local.Data(),Form("alien://%s",remote.Data()));
+ return GenerateMergeJDL(jdlname);
}
else
{
- return kFALSE;
- }
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::CheckRemoteDir() const
-{
- /// Check we have a grid connection and that the remote dir exists
-
- if (fRemoteDir.IsNull())
- {
- AliError("you must provide the grid location where to copy the files");
- return kFALSE;
- }
-
- // connect to alien
- if (!gGrid)
- {
- if (!TGrid::Connect("alien://"))
- {
- AliError("Cannot connect to grid");
- return kFALSE;
- }
- }
-
- if (!RemoteDirectoryExists(fRemoteDir))
- {
- AliError(Form("directory %s does not exist", fRemoteDir.Data()));
- return kFALSE;
- }
-
- return kTRUE;
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::CopyLocalFilesToRemote()
-{
- /// copy all files necessary to run the simulation into remote directory
-
- if (!IsValid()) return kFALSE;
-
- AliDebug(1,"");
-
- if ( CheckRemoteDir() )
- {
- TString sdir(gSystem->ExpandPathName(LocalDir()));
-
- TIter next(LocalFileList());
- TObjString* ftc;
-
- Bool_t allok(kTRUE);
-
- while ( ( ftc = static_cast<TObjString*>(next())) )
- {
- allok = allok && CopyFile(ftc->String());
- }
- return allok;
+ return GenerateRunJDL(jdlname);
}
-
- return kFALSE;
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::CopyTemplateFilesToLocal()
-{
- // copy (or generate) local files from the template ones
-
- if (!IsValid()) return kFALSE;
-
- AliDebug(1,"");
-
- TIter next(TemplateFileList());
- TObjString* file;
-
- Int_t err(0);
- Bool_t potentialProblem(kFALSE);
-
- while ( ( file = static_cast<TObjString*>(next())) )
- {
- if ( file->String().Contains("OCDB") )
- {
- /// OCDB snapshots are not in template
- continue;
- }
-
- if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(file->String().Data()) )
- {
- AliError(Form("Local file %s already exists. Remove it first if you want to update overwrite it",file->String().Data()));
- potentialProblem = kTRUE;
- }
- else
- {
- TString stemplate(Form("%s/%s",fTemplateDir.Data(),file->String().Data()));
- TString slocal(Form("%s/%s",fLocalDir.Data(),file->String().Data()));
-
- Int_t c = gSystem->CopyFile(stemplate.Data(),slocal.Data(),ShouldOverwriteFiles());
- if ( c )
- {
- Bool_t ok(kFALSE);
- if ( stemplate.Contains(".jdl",TString::kIgnoreCase) )
- {
- if ( stemplate.Contains("merge",TString::kIgnoreCase) )
- {
- ok = GenerateMergeJDL(file->String().Data());
- }
- else
- {
- ok = GenerateRunJDL(file->String().Data());
- }
- }
- if (!ok)
- {
- AliError(Form("Error %d copying file %s",c,stemplate.Data()));
- }
- else
- {
- c=0;
- }
- }
- else
- {
- if ( HasVars(slocal.Data()) )
- {
- if (!ReplaceVars(slocal.Data()))
- {
- AliError("pb in ReplaceVars");
- c=1;
- }
- }
- }
- err += c;
- }
- }
-
- if ( potentialProblem )
- {
- AliWarning("At least one local file could not be overwritten. Cross-check that the local files are OK before we try to upload them to the Grid !");
- return kFALSE;
- }
- return (err==0);
-}
-
-//______________________________________________________________________________
-std::ostream* AliMuonAccEffSubmitter::CreateJDLFile(const char* name) const
-{
- /// Create a JDL file
- AliDebug(1,"");
-
- TString jdl(Form("%s/%s",fLocalDir.Data(),name));
-
- if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(jdl.Data()) )
- {
- AliError(Form("File %s already exists. Remove it if you want to overwrite it",jdl.Data()));
- return 0x0;
- }
-
- std::ofstream* os = new std::ofstream(gSystem->ExpandPathName(jdl.Data()));
-
- if (os->bad())
- {
- AliError(Form("Cannot create file %s",jdl.Data()));
- delete os;
- os=0x0;
- }
-
- return os;
}
///______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::GenerateMergeJDL(const char* name)
+Bool_t AliMuonAccEffSubmitter::GenerateMergeJDL(const char* name) const
{
/// Create the JDL for merging jobs
/// FIXME: not checked !
<< "# $2 = merging stage" << std::endl
<< "# Stage_<n>.xml made via: find <OutputDir> *Stage<n-1>/*root_archive.zip" << std::endl;
- Output(*os,"Packages",fPackageAliroot.Data(),fPackageGeant3.Data(),
- fPackageRoot.Data(),fPackageApi.Data());
+ OutputToJDL(*os,"Packages",
+ GetMapValue("AliRoot"),
+ GetMapValue("Geant3"),
+ GetMapValue("Root"),
+ GetMapValue("API"));
- Output(*os,"Executable","AOD_merge.sh");
+ OutputToJDL(*os,"Executable","AOD_merge.sh");
- Output(*os,"Price","1");
+ OutputToJDL(*os,"Price","1");
if ( final )
{
- Output(*os,"Jobtag","comment: AliMuonAccEffSubmitter final merging");
+ OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter final merging");
}
else
{
- Output(*os,"Jobtag","comment: AliMuonAccEffSubmitter merging stage $2");
+ OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter merging stage $2");
}
- Output(*os,"Workdirectorysize","5000MB");
+ OutputToJDL(*os,"Workdirectorysize","5000MB");
- Output(*os,"Validationcommand",Form("%s/validation_merge.sh",fRemoteDir.Data()));
+ OutputToJDL(*os,"Validationcommand",Form("%s/validation_merge.sh",RemoteDir().Data()));
- Output(*os,"TTL","7200");
+ OutputToJDL(*os,"TTL","7200");
- Output(*os,"OutputArchive",
+ OutputToJDL(*os,"OutputArchive",
"log_archive.zip:stderr,stdout@disk=1",
"root_archive.zip:AliAOD.root,AliAOD.Muons.root,AnalysisResults.root@disk=3"
);
- Output(*os,"Arguments",(final ? "2":"1")); // for AOD_merge.sh, 1 means intermediate merging stage, 2 means final merging
+ OutputToJDL(*os,"Arguments",(final ? "2":"1")); // for AOD_merge.sh, 1 means intermediate merging stage, 2 means final merging
if ( !final )
{
- Output(*os,"InputFile",Form("LF:%s/AODtrain.C",fRemoteDir.Data()));
- Output(*os,"OutputDir",Form("%s/$1/Stage_$2/#alien_counter_03i#",fRemoteDir.Data()));
- Output(*os,"InputDataCollection",Form("%s/$1/Stage_$2.xml,nodownload",fRemoteDir.Data()));
- Output(*os,"split","se");
- Output(*os,"SplitMaxInputFileNumber",GetSplitMaxInputFileNumber());
- Output(*os,"InputDataListFormat","xml-single");
- Output(*os,"InputDataList","wn.xml");
+ OutputToJDL(*os,"InputFile",Form("LF:%s/AODtrain.C",RemoteDir().Data()));
+ OutputToJDL(*os,"OutputDir",Form("%s/$1/Stage_$2/#alien_counter_03i#",RemoteDir().Data()));
+ OutputToJDL(*os,"InputDataCollection",Form("%s/$1/Stage_$2.xml,nodownload",RemoteDir().Data()));
+ OutputToJDL(*os,"split","se");
+ OutputToJDL(*os,"SplitMaxInputFileNumber",GetSplitMaxInputFileNumber());
+ OutputToJDL(*os,"InputDataListFormat","xml-single");
+ OutputToJDL(*os,"InputDataList","wn.xml");
}
else
{
- Output(*os,"InputFile",Form("LF:%s/AODtrain.C",fRemoteDir.Data()),
- Form("LF:%s/$1/wn.xml",fRemoteDir.Data()));
- Output(*os,"OutputDir",Form("%s/$1",fRemoteDir.Data()));
+ OutputToJDL(*os,"InputFile",Form("LF:%s/AODtrain.C",RemoteDir().Data()),
+ Form("LF:%s/$1/wn.xml",RemoteDir().Data()));
+ OutputToJDL(*os,"OutputDir",Form("%s/$1",RemoteDir().Data()));
}
return kTRUE;
}
//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::GenerateRunJDL(const char* name)
+Bool_t AliMuonAccEffSubmitter::GenerateRunJDL(const char* name) const
{
/// Generate (locally) the JDL to perform the simulation+reco+aod filtering
/// (to be then copied to the grid and finally submitted)
return kFALSE;
}
- Output(*os,"Packages",fPackageAliroot.Data(),fPackageGeant3.Data(),
- fPackageRoot.Data(),fPackageApi.Data());
-
- Output(*os,"Jobtag","comment: AliMuonAccEffSubmitter RUN $1");
+ OutputToJDL(*os,"Packages",
+ GetMapValue("AliRoot"),
+ GetMapValue("Geant3"),
+ GetMapValue("Root"),
+ GetMapValue("API"));
+
+ OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter RUN $1");
- Output(*os,"split","production:1-$2");
+ OutputToJDL(*os,"split","production:1-$2");
- Output(*os,"Price","1");
+ OutputToJDL(*os,"Price","1");
- Output(*os,"OutputDir",Form("%s/$1/#alien_counter_03i#",fRemoteDir.Data()));
+ OutputToJDL(*os,"OutputDir",Form("%s/$1/#alien_counter_03i#",RemoteDir().Data()));
- Output(*os,"Executable","/alice/bin/aliroot_new");
+ OutputToJDL(*os,"Executable","/alice/bin/aliroot_new");
TObjArray files;
files.SetOwner(kTRUE);
if ( !file->String().Contains(".jdl",TString::kIgnoreCase) ||
!file->String().Contains("OCDB_") )
{
- files.Add(new TObjString(Form("LF:%s/%s",fRemoteDir.Data(),file->String().Data())));
+ files.Add(new TObjString(Form("LF:%s/%s",RemoteDir().Data(),file->String().Data())));
}
}
if ( fUseOCDBSnapshots )
{
- files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_sim.root",fRemoteDir.Data())));
- files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_rec.root",fRemoteDir.Data())));
+ files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_sim.root",RemoteDir().Data())));
+ files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_rec.root",RemoteDir().Data())));
}
- Output(*os,"InputFile",files);
+ OutputToJDL(*os,"InputFile",files);
if ( CompactMode() == 0 )
{
// store everything
- Output(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1",
+ OutputToJDL(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1",
"root_archive.zip:galice*.root,Kinematics*.root,TrackRefs*.root,AliESDs.root,AliAOD.root,AliAOD.Muons.root,Merged.QA.Data.root,Run*.root@disk=2");
}
else if ( CompactMode() == 1 )
{
- // keep only muon AODs
- Output(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1",
- "root_archive.zip:galice*.root,AliAOD.Muons.root@disk=2");
+ // keep only muon AODs and QA
+ OutputToJDL(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1",
+ "root_archive.zip:galice*.root,AliAOD.Muons.root,Merged.QA.Data.root@disk=2");
}
else
{
return kFALSE;
}
- Output(*os,"splitarguments","simrun.C --run $1 --chunk #alien_counter# --event $3");
+ OutputToJDL(*os,"splitarguments","simrun.C --run $1 --chunk #alien_counter# --event $3");
- Output(*os,"Workdirectorysize","5000MB");
+ OutputToJDL(*os,"Workdirectorysize","5000MB");
- Output(*os,"JDLVariables","Packages","OutputDir");
+ OutputToJDL(*os,"JDLVariables","Packages","OutputDir");
- Output(*os,"Validationcommand",Form("%s/validation.sh",fRemoteDir.Data()));
+ OutputToJDL(*os,"Validationcommand",Form("%s/validation.sh",RemoteDir().Data()));
- Output(*os,"TTL","72000");
+ OutputToJDL(*os,"TTL","72000");
return kTRUE;
}
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::GetLastStage(const char* remoteDir) const
-{
- /// Get the last staging phase already performed
- /// FIXME : not checked !
-
- Int_t n = 0, lastStage = 0;
- gSystem->Exec(Form("alien_ls -F %s | grep Stage_.*/ > __stage__", remoteDir));
- ifstream f("__stage__");
- std::string dummy;
- while (std::getline(f, dummy)) n++;
- f.close();
- while (n > 0) if (gSystem->Exec(Form("grep Stage_%d/ __stage__ 2>&1 >/dev/null", ++lastStage)) == 0) n--;
- gSystem->Exec("rm -f __stage__");
- return lastStage;
-}
-
-//______________________________________________________________________________
-TObjArray* AliMuonAccEffSubmitter::GetVariables(const char* file) const
-{
- /// Find the variables in the file
-
- std::ifstream in(file);
- char line[1024];
- TObjArray* variables(0x0);
-
- while ( in.getline(line,1023,'\n') )
- {
- TString sline(line);
- while (sline.Contains("VAR_") && !sline.BeginsWith("//") )
- {
- Int_t i1 = sline.Index("VAR_");
- Int_t i2(i1);
-
- while ( ( i2 < sline.Length() ) && ( isalnum(sline[i2]) || sline[i2]=='_' ) ) ++i2;
-
- if (!variables)
- {
- variables = new TObjArray;
- variables->SetOwner(kTRUE);
- }
-
- TString var = sline(i1,i2-i1);
- if ( !variables->FindObject(var) )
- {
- variables->Add(new TObjString(var));
- }
- sline.ReplaceAll(var,"");
- }
- }
-
- in.close();
-
- return variables;
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::HasVars(const char* file) const
-{
- /// Whether or not the file contains variables that have to
- /// be substituted
-
- std::ifstream in(file);
- char line[1024];
- while ( in.getline(line,1023,'\n') )
- {
- TString sline(line);
- if (sline.Contains("VAR_") && !sline.BeginsWith("//") )
- {
- return kTRUE;
- }
- }
- return kFALSE;
-}
-
-//______________________________________________________________________________
-TObjArray* AliMuonAccEffSubmitter::LocalFileList() const
-{
- /// Return (after createing and filling it if needed)
- /// the internal file list with paths from the local directory
-
- if (!fLocalFileList)
- {
- fLocalFileList = static_cast<TObjArray*>(TemplateFileList()->Clone());
- }
-
- return fLocalFileList;
-}
-
//______________________________________________________________________________
Bool_t AliMuonAccEffSubmitter::MakeOCDBSnapshots()
{
if (!fUseOCDBSnapshots) return kTRUE;
- if (!fScalers) return kFALSE;
+ if (!NofRuns()) return kFALSE;
AliDebug(1,"");
- const std::vector<int>& runs = fScalers->GetRunList();
-
Bool_t ok(kTRUE);
+ const std::vector<int>& runs = RunList();
+
for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i )
{
Int_t runNumber = runs[i];
/// - stage=0 --> final merging / stage>0 --> intermediate merging i
///
- if (!RemoteDirectoryExists(fMergedDir.Data())) {
- AliError(Form("directory %s does not exist", fMergedDir.Data()));
+ if (!RemoteDirectoryExists(MergedDir().Data())) {
+ AliError(Form("directory %s does not exist", MergedDir().Data()));
return kFALSE;
}
- gGrid->Cd(fMergedDir.Data());
+ gGrid->Cd(MergedDir().Data());
TString jdl = MergeJDLName(stage==0);
if (!RemoteFileExists(jdl.Data()))
{
- AliError(Form("file %s does not exist in %s\n", jdl.Data(), fRemoteDir.Data()));
+ AliError(Form("file %s does not exist in %s\n", jdl.Data(), RemoteDir().Data()));
return kFALSE;
}
- const std::vector<int>& runs = fScalers->GetRunList();
+ const std::vector<int>& runs = RunList();
if (runs.empty())
{
Int_t run = runs[i];
AliInfo(Form("\n --- processing run %d ---\n", run));
- TString runDir = Form("%s/%d", fMergedDir.Data(), run);
+ TString runDir = Form("%s/%d", MergedDir().Data(), run);
if (!RemoteDirectoryExists(runDir.Data()))
{
TString wn = (stage > 0) ? Form("Stage_%d.xml", stage) : "wn.xml";
TString find = (lastStage == 0) ?
- Form("alien_find -x %s %s/%d *root_archive.zip", wn.Data(), fRemoteDir.Data(), run) :
- Form("alien_find -x %s %s/%d/Stage_%d *root_archive.zip", wn.Data(), fRemoteDir.Data(), run, lastStage);
+ Form("alien_find -x %s %s/%d *root_archive.zip", wn.Data(), RemoteDir().Data(), run) :
+ Form("alien_find -x %s %s/%d/Stage_%d *root_archive.zip", wn.Data(), RemoteDir().Data(), run, lastStage);
gSystem->Exec(Form("%s 1> %s 2>/dev/null", find.Data(), wn.Data()));
gSystem->Exec(Form("grep -c /event %s > __nfiles__", wn.Data()));
ifstream f2("__nfiles__");
}
//______________________________________________________________________________
-UInt_t AliMuonAccEffSubmitter::NofRuns() const
-{
- // number of runs we're dealing with
- if (!fScalers) return 0;
-
- return fScalers->GetRunList().size();
-}
-
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::Output(std::ostream& out, const char* key,
- const TObjArray& values) const
-{
- /// output to ostream of key,{values} pair
-
- out << key << " = ";
-
- Int_t n = values.GetEntries();
-
- if ( n > 1 )
- {
- out << "{" << std::endl;
- TIter next(&values);
- TObjString* v;
-
- while ( ( v = static_cast<TObjString*>(next())) )
- {
- --n;
- out << "\t\"" << v->String().Data() << "\"";
- if ( n ) out << ",";
- out << std::endl;
- }
- out << "}";
- }
- else
- {
- TString& v1 = static_cast<TObjString*>(values.At(0))->String();
-
- if ( v1.IsDigit() )
- {
- out << v1.Atoi();
- }
- else
- {
- out << "\"" << v1.Data() << "\"";
- }
- }
- out << ";" << std::endl;
-}
-
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::Output(std::ostream& out, const char* key, const char* v1,
- const char* v2, const char* v3, const char* v4,
- const char* v5, const char* v6, const char* v7,
- const char* v8, const char* v9) const
-{
- /// output to ostream
-
- TObjArray values;
- values.SetOwner(kTRUE);
-
- values.Add(new TObjString(v1));
- if ( strlen(v2) > 0 ) values.Add(new TObjString(v2));
- if ( strlen(v3) > 0 ) values.Add(new TObjString(v3));
- if ( strlen(v4) > 0 ) values.Add(new TObjString(v4));
- if ( strlen(v5) > 0 ) values.Add(new TObjString(v5));
- if ( strlen(v6) > 0 ) values.Add(new TObjString(v6));
- if ( strlen(v7) > 0 ) values.Add(new TObjString(v7));
- if ( strlen(v8) > 0 ) values.Add(new TObjString(v8));
- if ( strlen(v9) > 0 ) values.Add(new TObjString(v9));
-
- Output(out,key,values);
-}
-
-
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::Print(Option_t* /*opt*/) const
+void AliMuonAccEffSubmitter::Print(Option_t* opt) const
{
/// Printout
- if (!IsValid())
- {
- std::cout << std::string(80,'*') << std::endl;
- std::cout << "INVALID OBJECT. CHECK BELOW THE CONFIGURATION." << std::endl;
- std::cout << std::string(80,'*') << std::endl;
- }
-
- std::cout << "Template directory = " << fTemplateDir.Data() << std::endl;
- std::cout << "Local directory = " << fLocalDir.Data() << std::endl;
- std::cout << "Remote directory = " << fRemoteDir.Data() << std::endl;
-
- if ( fSnapshotDir != fLocalDir )
- {
- std::cout << "Snapshots directory = " << fSnapshotDir.Data() << std::endl;
- }
-
- std::cout << "OCDB path = " << fOCDBPath.Data() << std::endl;
-
+ AliMuonGridSubmitter::Print(opt);
+
if ( fRatio > 0 )
{
std::cout << Form("For each run, will generate %5.2f times the number of real events for trigger %s",
- fRatio,fReferenceTrigger.Data()) << std::endl;
+ fRatio,ReferenceTrigger().Data()) << std::endl;
}
else
{
std::cout << "MaxEventsPerChunk = " << fMaxEventsPerChunk << std::endl;
- if ( NofRuns() )
- {
- std::cout << NofRuns() << " run";
- if ( NofRuns() > 1 ) std::cout << "s";
- std::cout << " = ";
- fScalers->Print();
- }
-
- if ( fVars )
- {
- TIter next(fVars);
- TObjString* key;
- while ( ( key = static_cast<TObjString*>(next())) )
- {
- TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String()));
- std::cout << "Variable " << key->String() << " will be replaced by " << value->String() << std::endl;
- }
- }
-
- std::cout << "Files to be uploaded:" << std::endl;
- TIter nextFile(LocalFileList());
- TObjString* sfile;
- while ( ( sfile = static_cast<TObjString*>(nextFile())) )
- {
- std::cout << sfile->String().Data() << std::endl;
- }
-}
-
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::RemoteDirectoryExists(const char *dirname) const
-{
- // Returns true if directory exists. Can be also a path.
- if (!gGrid) return kFALSE;
- // Check if dirname is a path
- TString dirstripped = dirname;
- dirstripped = dirstripped.Strip();
- dirstripped = dirstripped.Strip(TString::kTrailing, '/');
- TString dir = gSystem->BaseName(dirstripped);
- dir += "/";
- TString path = gSystem->DirName(dirstripped);
- TGridResult *res = gGrid->Ls(path, "-F");
- if (!res) return kFALSE;
- TIter next(res);
- TMap *map;
- TObject *obj;
- while ((map=dynamic_cast<TMap*>(next()))) {
- obj = map->GetValue("name");
- if (!obj) break;
- if (dir == obj->GetName()) {
- delete res;
- return kTRUE;
- }
- }
- delete res;
- return kFALSE;
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::RemoteFileExists(const char *lfn) const
-{
- // Returns true if file exists.
- if (!gGrid) return kFALSE;
- TGridResult *res = gGrid->Ls(lfn);
- if (!res) return kFALSE;
- TMap *map = dynamic_cast<TMap*>(res->At(0));
- if (!map) {
- delete res;
- return kFALSE;
- }
- TObjString *objs = dynamic_cast<TObjString*>(map->GetValue("name"));
- if (!objs || !objs->GetString().Length()) {
- delete res;
- return kFALSE;
- }
- delete res;
- return kTRUE;
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::ReplaceVars(const char* file) const
-{
- /// Replace the variables (i.e. things starting by VAR_) found in file
-
- std::ifstream in(file);
- char line[1024];
- TObjArray lines;
- lines.SetOwner(kTRUE);
- Int_t nvars(0);
- Int_t nreplaced(0);
-
- TIter next(fVars);
-
- while ( in.getline(line,1023,'\n') )
- {
- TString sline(line);
- while (sline.Contains("VAR_") && !sline.BeginsWith("//") )
- {
- ++nvars;
- TObjString* key;
- next.Reset();
- while ( ( key = static_cast<TObjString*>(next())) )
- {
- if ( sline.Contains(key->String()) )
- {
- ++nreplaced;
- TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String()));
- sline.ReplaceAll(key->String(),value->String());
- break;
- }
- }
- }
-
- lines.Add(new TObjString(sline));
- }
-
- in.close();
-
- if ( nvars > 0 )
- {
- if ( nreplaced != nvars )
- {
- AliError(Form("nvars=%d nreplaced=%d",nvars,nreplaced));
- return kFALSE;
- }
- std::ofstream out(file);
- TIter nextLine(&lines);
- TObjString* s;
- while ( ( s = static_cast<TObjString*>(nextLine()) ) )
- {
- out << s->String().Data() << std::endl;
- }
- out.close();
- }
-
- return kTRUE;
+ std::cout << "Will" << (fUseOCDBSnapshots ? "" : " NOT") << " use OCDB snaphosts" << std::endl;
}
//______________________________________________________________________________
return kFALSE;
}
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::SetPackages(const char* aliroot,
- const char* root,
- const char* geant3,
- const char* api)
-{
- /// Set the packages to be used by the jobs
- /// Must be a valid combination, see http://alimonitor.cern.ch/packages/
- ///
- fPackageAliroot = aliroot;
- fPackageRoot = root;
- fPackageGeant3 = geant3;
- fPackageApi = api;
-}
-
-//______________________________________________________________________________
-TString AliMuonAccEffSubmitter::GetRemoteDir(const char* dir, Bool_t create)
-{
- /// Set the target remote directory (on the grid)
-
- if (!RemoteDirectoryExists(dir))
- {
- if (!create)
- {
- AliError(Form("Remote directory %s does not exist", dir));
- return "";
- }
- else
- {
- AliInfo(Form("Remote directory %s does not exist. Trying to create it...",dir));
- if ( !gGrid->Mkdir(dir,"-p") )
- {
- AliError(Form("Could not create remote dir. Sorry."));
- return "";
- }
- }
- }
- return dir;
-}
-
//______________________________________________________________________________
Bool_t AliMuonAccEffSubmitter::SetGenerator(const char* generator)
{
// set the variable to select the generator macro in Config.C
gSystem->Load("libEVGEN");
-
- fIsValid = kFALSE;
- TString generatorFile(Form("%s/%s.C",fTemplateDir.Data(),generator));
+ Invalidate();
+
+ TString generatorFile(Form("%s/%s.C",TemplateDir().Data(),generator));
Int_t nofMissingVariables(0);
while ( ( var = static_cast<TObjString*>(next())) )
{
- if ( !fVars->GetValue(var->String()) )
+ if ( !Vars()->GetValue(var->String()) )
{
++nofMissingVariables;
AliError(Form("file %s expect the variable %s to be defined, but we've not defined it !",generatorFile.Data(),var->String().Data()));
{
if (CheckCompilation(generatorFile.Data()))
{
- fIsValid = kTRUE;
+ Validate();
SetVar("VAR_GENERATOR",Form("%s",generator));
- TemplateFileList()->Add(new TObjString(Form("%s.C",generator)));
+ AddToTemplateFileList(Form("%s.C",generator));
return kTRUE;
}
}
return kFALSE;
}
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::SetMergedDir(const char* dir, Bool_t create)
-{
- // Set the merged directory to be used
- fMergedDir = GetRemoteDir(dir,create);
- return (fMergedDir.Length()>0);
-}
-
-//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::SetRemoteDir(const char* dir, Bool_t create)
-{
- // Set the remote directory to be used
- fRemoteDir = GetRemoteDir(dir,create);
- return (fIsValid = (fRemoteDir.Length()>0));
-}
-
-
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::SetRunList(const char* runList)
-{
- // set the runlist from a text file
- if (!fScalers)
- {
- fScalers = new AliAnalysisTriggerScalers(runList,fOCDBPath.Data());
- }
- else
- {
- fScalers->SetRunList(runList);
- }
- UpdateLocalFileList(kTRUE);
-}
-
-//______________________________________________________________________________
-void AliMuonAccEffSubmitter::SetRunList(int runNumber)
-{
- // set the runlist from a text file
- if (!fScalers)
- {
- fScalers = new AliAnalysisTriggerScalers(runNumber,fOCDBPath.Data());
- }
- else
- {
- fScalers->SetRunList(runNumber);
- }
- UpdateLocalFileList(kTRUE);
-}
-
//______________________________________________________________________________
void AliMuonAccEffSubmitter::SetOCDBPath(const char* ocdbPath)
{
/// Sets the OCDB path to be used
- fOCDBPath = ocdbPath;
-
- if (fScalers)
- {
- // redefine trigger scalers to use the new ocdb path
- AliAnalysisTriggerScalers* ts = new AliAnalysisTriggerScalers(fScalers->GetRunList(),
- fOCDBPath.Data());
-
- delete fScalers;
- fScalers = ts;
- }
+ SetMapKeyValue("OCDBPath",ocdbPath);
}
}
else
{
- fSnapshotDir = dir;
+ SetMapKeyValue("OCDBSnapshot",dir);
}
}
//______________________________________________________________________________
-Bool_t AliMuonAccEffSubmitter::SetVar(const char* varname, const char* value)
+void AliMuonAccEffSubmitter::MakeNofEventsPropToTriggerCount(const char* trigger, Float_t ratio)
{
- /// Set a variable
-
- TString s(varname);
- s.ToUpper();
- if (!s.BeginsWith("VAR_"))
- {
- AliError("Variable name should start with VAR_");
- return kFALSE;
- }
- if (!fVars)
- {
- fVars = new TMap;
- fVars->SetOwnerKeyValue(kTRUE,kTRUE);
- }
-
- TObject* o = new TObjString(s);
- fVars->Remove(o);
-
- fVars->Add(o,new TObjString(value));
-
- return kTRUE;
+ SetMapKeyValue("ReferenceTrigger",trigger);
+ fRatio = ratio;
+}
+
+//______________________________________________________________________________
+void AliMuonAccEffSubmitter::MakeNofEventsFixed(Int_t nevents)
+{
+ fFixedNofEvents = nevents;
+ fRatio=0.0;
+ SetMapKeyValue("ReferenceTrigger","");
}
+
//______________________________________________________________________________
Int_t AliMuonAccEffSubmitter::Submit(Bool_t dryRun)
{
return 0;
}
- if ( !fScalers )
+ if ( !NofRuns() )
{
AliError("No run list set. Use SetRunList");
return 0;
}
- const std::vector<int>& runs = fScalers->GetRunList();
+ const std::vector<int>& runs = RunList();
if (runs.empty())
{
Int_t nJobs(0);
Int_t nEvts(0);
+ AliAnalysisTriggerScalers* ts(0x0);
+
for (std::vector<int>::size_type i=0; i < runs.size(); ++i)
{
Int_t runNumber = runs[i];
if ( fRatio > 0 )
{
- AliAnalysisTriggerScalerItem* trigger = fScalers->GetTriggerScaler(runNumber, "L2A", ReferenceTrigger().Data());
+ if (!ts)
+ {
+ AliInfo(Form("Creating AliAnalysisTriggerScalers from OCDB=%s",OCDBPath().Data()));
+ ts = new AliAnalysisTriggerScalers(runs,OCDBPath().Data());
+ }
+
+ AliAnalysisTriggerScalerItem* trigger = ts->GetTriggerScaler(runNumber, "L2A", ReferenceTrigger().Data());
if (!trigger)
{
<< "total number of generated events = " << nEvts << std::endl
<< std::endl;
- return nJobs;
-}
-
-//______________________________________________________________________________
-TObjArray* AliMuonAccEffSubmitter::TemplateFileList() const
-{
- /// Return (after createing and filling it if needed)
- /// the internal file list with paths from the template directory
-
- if (!fTemplateFileList)
- {
- fTemplateFileList = new TObjArray;
- fTemplateFileList->SetOwner(kTRUE);
-
- fTemplateFileList->Add(new TObjString("CheckESD.C"));
- fTemplateFileList->Add(new TObjString("CheckAOD.C"));
- fTemplateFileList->Add(new TObjString("AODtrain.C"));
- fTemplateFileList->Add(new TObjString("validation.sh"));
- if ( fExternalConfig.Length() > 0 )
- {
- fTemplateFileList->Add(new TObjString(fExternalConfig));
- }
- else
- {
- fTemplateFileList->Add(new TObjString("Config.C"));
- }
- fTemplateFileList->Add(new TObjString("rec.C"));
- fTemplateFileList->Add(new TObjString("sim.C"));
- fTemplateFileList->Add(new TObjString("simrun.C"));
- fTemplateFileList->Add(new TObjString(RunJDLName().Data()));
- if ( fUseAODMerging )
- {
- fTemplateFileList->Add(new TObjString(MergeJDLName(kFALSE).Data()));
- fTemplateFileList->Add(new TObjString(MergeJDLName(kTRUE).Data()));
- fTemplateFileList->Add(new TObjString("AOD_merge.sh"));
- fTemplateFileList->Add(new TObjString("validation_merge.sh"));
- }
- }
+ delete ts;
- return fTemplateFileList;
+ return nJobs;
}
//______________________________________________________________________________
{
/// Update the list of local files
- if (!fScalers) return;
+ AliMuonGridSubmitter::UpdateLocalFileList();
+
+ if (!NofRuns()) return;
if ( clearSnapshots )
{
LocalFileList()->Compress();
}
- const std::vector<int>& runs = fScalers->GetRunList();
-
const char* type[] = { "sim","rec" };
+ const std::vector<int>& runs = RunList();
+
for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i )
{
Int_t runNumber = runs[i];
/// whether or not we should generate JDL for merging AODs
fUseAODMerging = flag;
- // FIXME: here should update the TemplateFileList() (and LocalFileList as well ?)
+
+ AddToTemplateFileList(MergeJDLName(kFALSE).Data());
+ AddToTemplateFileList(MergeJDLName(kTRUE).Data());
+ AddToTemplateFileList("AOD_merge.sh");
+ AddToTemplateFileList("validation_merge.sh");
+}
+
+//______________________________________________________________________________
+void AliMuonAccEffSubmitter::UseExternalConfig(const char* externalConfigFullFilePath)
+{
+ // use an external config (or the default Config.C if externalConfigFullFilePath="")
+
+ fExternalConfig = externalConfigFullFilePath;
+ if ( fExternalConfig.Length() > 0 )
+ {
+ AddToTemplateFileList(fExternalConfig);
+ }
+ else
+ {
+ AddToTemplateFileList("Config.C");
+ }
}
// author: Laurent Aphecetche (Subatech)
//
-#include "TObject.h"
-#include "TString.h"
-#include "Riostream.h"
+#include "AliMuonGridSubmitter.h"
-class AliAnalysisTriggerScalers;
-class TMap;
-
-class AliMuonAccEffSubmitter : public TObject
+class AliMuonAccEffSubmitter : public AliMuonGridSubmitter
{
public:
AliMuonAccEffSubmitter(const char* generator="GenParamCustom");
- virtual ~AliMuonAccEffSubmitter();
-
- Bool_t SetRemoteDir(const char* dir, Bool_t create = kTRUE);
- void SetLocalDir(const char* localdir) { fLocalDir = localdir; }
- Bool_t SetMergedDir(const char* dir, Bool_t create = kTRUE);
-
- void UseOCDBSnapshots(Bool_t flag);
-
- void UseExternalConfig(const char* externalConfigFullFilePath) { fExternalConfig = externalConfigFullFilePath; }
-
- void UseAODMerging(Bool_t flag);
-
- Bool_t CheckLocal() const;
- Bool_t CheckRemote() const;
-
- void CleanLocal(Bool_t cleanSnapshots=kFALSE) const;
- void CleanRemote() const;
-
- TString MergedDir() const { return fMergedDir; }
- TString RemoteDir() const { return fRemoteDir; }
- TString LocalDir() const { return fLocalDir; }
-
- TString FilePath(const char* what) const;
+ virtual Bool_t Generate(const char* jdlname) const;
+ virtual Bool_t Run(const char* mode);
- Int_t MaxEventsPerChunk() const { return fMaxEventsPerChunk; }
- void SetMaxEventsPerChunk(Int_t n) { fMaxEventsPerChunk = n; }
+ virtual ~AliMuonAccEffSubmitter();
- UInt_t NofRuns() const;
-
- void SetRatio(Float_t ratio) { fRatio = ratio; }
- void SetOCDBPath(const char* ocdbPath);
+ void MakeNofEventsPropToTriggerCount(const char* trigger="CMUL7-B-NOPF-MUON", Float_t ratio=1.0);
- void MakeNofEventsPropToTriggerCount(const char* trigger="CMUL8-S-NOPF-MUON", Float_t ratio=1.0) { fReferenceTrigger = trigger; fRatio = ratio; }
- void MakeNofEventsFixed(Int_t nevents) { fFixedNofEvents = nevents; fReferenceTrigger=""; fRatio=0.0; }
+ void MakeNofEventsFixed(Int_t nevents);
- void SetRunList(const char* runlist);
- void SetRunList(int runNumber);
+ void UseOCDBSnapshots(Bool_t flag);
- TString ReferenceTrigger() const { return fReferenceTrigger; }
+ void UseExternalConfig(const char* externalConfigFullFilePath);
- Bool_t Run(const char* mode);
+ void UseAODMerging(Bool_t flag);
Bool_t Merge(Int_t stage, Bool_t dryRun=kTRUE);
virtual void Print(Option_t* opt="") const;
- Bool_t CopyLocalFilesToRemote();
-
- Bool_t CopyTemplateFilesToLocal();
-
- Bool_t GenerateRunJDL(const char* name);
-
- Bool_t GenerateMergeJDL(const char* name);
-
- void SetPackages(const char* aliroot, const char* root, const char* geant3,
- const char* api="VO_ALICE@APISCONFIG::V1.1x");
-
void SetSplitMaxInputFileNumber(Int_t n) { fSplitMaxInputFileNumber = n; }
Int_t GetSplitMaxInputFileNumber() const { return fSplitMaxInputFileNumber; }
void SetCompactMode(Int_t mode) { fCompactMode=mode; }
- Bool_t ShouldOverwriteFiles() const { return fShouldOverwriteFiles; }
-
- void ShouldOverwriteFiles(Bool_t flag) { fShouldOverwriteFiles = flag; }
-
- Bool_t SetVar(const char* varname, const char* value);
-
Bool_t MakeOCDBSnapshots();
+ void SetOCDBPath(const char* ocdbPath);
+
void SetOCDBSnapshotDir(const char* dir);
Bool_t SetGenerator(const char* generator);
-
- TObjArray* GetVariables(const char* file) const;
-
- Bool_t IsValid() const { return fIsValid; }
-
-private:
- TString SnapshotDir() const { return fSnapshotDir; }
+ void CleanLocal(const char* excludeList="OCDB_") const;
- TString GetRemoteDir(const char* dir, Bool_t create);
-
- std::ostream* CreateJDLFile(const char* name) const;
-
- Bool_t CheckRemoteDir() const;
+ Int_t MaxEventsPerChunk() const { return fMaxEventsPerChunk; }
+ void SetMaxEventsPerChunk(Int_t n) { fMaxEventsPerChunk = n; }
- Bool_t CopyFile(const char* localFile);
+ TString OCDBPath() const { return GetMapValue("OCDBPath"); }
- Bool_t GetLastStage(const char* remoteDir) const;
-
- Bool_t RemoteDirectoryExists(const char *dirname) const;
- Bool_t RemoteFileExists(const char *lfn) const;
+ TString SnapshotDir() const { return GetMapValue("OCDBsnapshot"); }
- void Output(std::ostream& out, const char* key, const char* v1,
- const char* v2="", const char* v3="", const char* v4="", const char* v5="",
- const char* v6="", const char* v7="", const char* v8="", const char* v9="") const;
+private:
- void Output(std::ostream& out, const char* key, const TObjArray& values) const;
-
- Bool_t ReplaceVars(const char* file) const;
-
- TObjArray* TemplateFileList() const;
-
- TObjArray* LocalFileList() const;
+ Bool_t GenerateRunJDL(const char* name) const;
- Bool_t HasVars(const char* localFile) const;
-
- void UpdateLocalFileList(Bool_t clearSnapshot=kFALSE);
+ Bool_t GenerateMergeJDL(const char* name) const;
- Bool_t CheckCompilation(const char* file) const;
+ TString ReferenceTrigger() const { return GetMapValue("ReferenceTrigger"); }
+ void UpdateLocalFileList(Bool_t clearSnapshots=kFALSE);
+
private:
AliMuonAccEffSubmitter(const AliMuonAccEffSubmitter& rhs);
AliMuonAccEffSubmitter& operator=(const AliMuonAccEffSubmitter& rhs);
private:
- AliAnalysisTriggerScalers* fScalers; // helper class used to handle the runlist and the scalers
- TString fRemoteDir; // remote directory to used in alien
- TString fReferenceTrigger; // reference trigger (if any) to be used to get the number of events to be used per run
Float_t fRatio; // ratio simulated events vs real events
Int_t fFixedNofEvents; // fixed number of events to be used per run
Int_t fMaxEventsPerChunk; // max events to generate per subjob
- TString fLocalDir; // local directory
TString fOCDBPath; // OCDB path
- TString fTemplateDir; // template directory
- TString fPackageAliroot; // which aliroot package to use
- TString fPackageGeant3; // which geant3 package to use
- TString fPackageRoot; // which root package to use (for valid root,geant3,aliroot combinations see http://alimonitor.cern.ch/packages/)
- TString fPackageApi; // which API package to use
- TString fMergedDir; // merge directory
Int_t fSplitMaxInputFileNumber; // used for merging jdl
Int_t fCompactMode; // controls which outputs are kept (0=everything, 1=only aods)
- Bool_t fShouldOverwriteFiles; // whether any copy (of template to local) is allowed to overwrite existing files
- TMap* fVars; // map of the variables we can replace in template files
TString fExternalConfig; // path to an (optional) external config file
Bool_t fUseOCDBSnapshots; // whether to use OCDB snapshots or not
- Bool_t fIsValid; // whether this object is valid (i.e. properly configured)
- mutable TObjArray* fTemplateFileList; // list of template files
- mutable TObjArray* fLocalFileList; // list of local files
TString fSnapshotDir; // directory for OCDB snapshots
Bool_t fUseAODMerging; // whether or not to perform (aod) merging
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+//
+// AliMuonGridSubmitter : a class to help submit jobs for several runs
+//
+// This class is dealing with 3 different directories :
+//
+// - template directory ($ALICE_ROOT/PWG/muondep/XXXTemplates) containing the
+// basic template files to be used for a particular job type (XXX). A template can contain
+// some variables that will be replaced during during the copy from template
+// to local dir
+//
+// - local directory, where the files from the template directory, are copied
+// once the class has been configured properly (i.e. using the various Set, Use,
+// etc... methods). Some other files (e.g. JDL ones) are generated from
+// scratch and also copied into this directory.
+// At this point one could(should) check the files, as they are the ones
+// to be copied to the remote directory for the production
+//
+// - remote directory, the alien directory where the files will be copied
+// (from the local directory) before the actual submission
+//
+// author: Laurent Aphecetche (Subatech
+//
+
+#include "AliMuonGridSubmitter.h"
+
+#include "AliLog.h"
+#include "TFile.h"
+#include "TGrid.h"
+#include "TGridResult.h"
+#include "TMap.h"
+#include "TMath.h"
+#include "TObjString.h"
+#include "TROOT.h"
+#include "TString.h"
+#include "TSystem.h"
+#include <vector>
+#include "AliAnalysisTriggerScalers.h"
+#include "Riostream.h"
+
+//______________________________________________________________________________
+AliMuonGridSubmitter::AliMuonGridSubmitter(AliMuonGridSubmitter::EJobType jobType)
+: TObject(),
+fInternalMap(0x0),
+fVars(0x0),
+fIsValid(kFALSE),
+fShouldOverwriteFiles(kFALSE),
+fTemplateFileList(0x0),
+fLocalFileList(0x0)
+{
+ // ctor
+
+ if (!gGrid)
+ {
+ TGrid::Connect("alien://");
+ if ( !gGrid )
+ {
+ AliError("cannot connect to grid");
+ }
+ }
+
+ SetPackages("VO_ALICE@AliRoot::v5-04-46-AN","VO_ALICE@GEANT3::v1-15","VO_ALICE@ROOT::v5-34-05");
+
+ TString basedir = gSystem->ExpandPathName("$ALICE_ROOT/PWG/muondep");
+
+ TString dir;
+ dir.Form("%s/%sTemplates",basedir.Data(),JobTypeName(jobType).Data());
+
+ if (!SetTemplateDir(dir.Data()))
+ {
+ AliError(Form("Could not find %s directory. Please check.",dir.Data()));
+ }
+
+ SetLocalDir(gSystem->pwd());
+}
+
+//______________________________________________________________________________
+AliMuonGridSubmitter::~AliMuonGridSubmitter()
+{
+ // dtor
+ delete fTemplateFileList;
+ delete fLocalFileList;
+ delete fInternalMap;
+ delete fVars;
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::AddToTemplateFileList(const char* filename)
+{
+ // add a file to the list of templates
+ // and update the local file list if needed
+
+ TObjArray* a = TemplateFileList();
+
+ if ( !a->FindObject(filename) )
+ {
+ a->Add(new TObjString(filename));
+ UpdateLocalFileList();
+ }
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::CheckCompilation(const char* file) const
+{
+ /// Check whether file can be compiled or not
+ /// FIXME: use gSystem->TempFileName for tmpfile !
+
+ Bool_t rv(kTRUE);
+
+ TString sfile(gSystem->BaseName(file));
+ TString tmpfile(Form("tmpfile_%s",sfile.Data()));
+
+ gSystem->Exec(Form("cp %s %s",file,tmpfile.Data()));
+
+ ReplaceVars(tmpfile.Data());
+
+ gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+ gSystem->AddIncludePath("-I$ALICE_ROOT/EVGEN");
+
+ if (gROOT->LoadMacro(Form("%s++",tmpfile.Data())))
+ {
+ AliError(Form("macro %s can not be compiled. Please check.",file));
+ rv = kFALSE;
+ }
+
+ gSystem->Exec(Form("rm %s",tmpfile.Data()));
+
+ return rv;
+}
+
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::CheckLocal() const
+{
+ /// Check whether all required local files are there
+ TIter next(LocalFileList());
+ TObjString* file;
+
+ while ( ( file = static_cast<TObjString*>(next())) )
+ {
+ if ( gSystem->AccessPathName(file->String().Data()) )
+ {
+ return kFALSE;
+ }
+ }
+
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::CheckRemote() const
+{
+ /// Check whether all required remote files are there
+ AliWarning("implement me");
+ return kFALSE;
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::CleanLocal(const char* excludeList) const
+{
+ /// Clean (remove) local generated files
+ /// exclude contains a list of comma separated pattern of files
+ /// to be avoided
+
+ TIter next(LocalFileList());
+ TObjString* file;
+ TObjArray* excludeArray = TString(excludeList).Tokenize(",");
+
+ while ( ( file = static_cast<TObjString*>(next())) )
+ {
+ Bool_t shouldExclude(kFALSE);
+
+ TIter nextExclude(excludeArray);
+ TObjString* s;
+
+ while ( ( s = static_cast<TObjString*>(nextExclude())) && !shouldExclude )
+ {
+ if ( file->String().Contains(s->String()) ) shouldExclude=kTRUE;
+ }
+
+ if (!shouldExclude)
+ {
+ gSystem->Unlink(file->String().Data());
+ }
+ }
+
+ delete excludeArray;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::CopyFile(const char* localFile)
+{
+ /// copy a local file to remote destination
+ TString local;
+
+ if ( gSystem->IsAbsoluteFileName(localFile) )
+ {
+ local = localFile;
+ }
+ else
+ {
+ local = Form("%s/%s",LocalDir().Data(),gSystem->ExpandPathName(localFile));
+ }
+
+ if (gSystem->AccessPathName(local.Data()))
+ {
+ AliErrorClass(Form("Local file %s does not exist",local.Data()));
+ return kFALSE;
+ }
+
+ TString remote;
+
+ remote += RemoteDir().Data();
+ remote += "/";
+
+ if ( gSystem->IsAbsoluteFileName(localFile) )
+ {
+ TString tmp(localFile);
+ tmp.ReplaceAll(GetMapValue("Snapshot"),"");
+ tmp.ReplaceAll(GetMapValue("Local"),"");
+ remote += tmp;
+ }
+ else
+ {
+ remote += localFile;
+ }
+
+ TString dirName = gSystem->DirName(remote.Data());
+
+ Bool_t ok(kTRUE);
+
+ if (!RemoteDirectoryExists(dirName.Data()))
+ {
+ ok = gGrid->Mkdir(dirName.Data(),"-p");
+ }
+
+ if ( ok )
+ {
+ AliDebugClass(1,Form("cp %s alien://%s",local.Data(),remote.Data()));
+ return TFile::Cp(local.Data(),Form("alien://%s",remote.Data()));
+ }
+ else
+ {
+ return kFALSE;
+ }
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::CheckRemoteDir() const
+{
+ /// Check we have a grid connection and that the remote dir exists
+
+ if (RemoteDir().IsNull())
+ {
+ AliError("you must provide the grid location where to copy the files");
+ return kFALSE;
+ }
+
+ if (!RemoteDirectoryExists(RemoteDir()))
+ {
+ AliError(Form("directory %s does not exist", RemoteDir().Data()));
+ return kFALSE;
+ }
+
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::CopyLocalFilesToRemote()
+{
+ /// copy all files necessary to run the simulation into remote directory
+
+ TIter next(LocalFileList());
+ TObjString* ftc;
+
+ Bool_t allok(kTRUE);
+
+ while ( ( ftc = static_cast<TObjString*>(next())) )
+ {
+ allok = allok && CopyFile(ftc->String());
+ }
+ return allok;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::CopyTemplateFilesToLocal()
+{
+ // copy (or generate) local files from the template ones
+
+ if (!IsValid()) return kFALSE;
+
+ AliDebug(1,"");
+
+ TIter next(TemplateFileList());
+ TObjString* file;
+
+ Int_t err(0);
+ Bool_t potentialProblem(kFALSE);
+
+ while ( ( file = static_cast<TObjString*>(next())) )
+ {
+ if ( file->String().Contains("OCDB") )
+ {
+ /// OCDB snapshots are not in template
+ continue;
+ }
+
+ if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(file->String().Data()) )
+ {
+ AliError(Form("Local file %s already exists. Remove it first if you want to update overwrite it",file->String().Data()));
+ potentialProblem = kTRUE;
+ }
+ else
+ {
+ TString stemplate(Form("%s/%s",TemplateDir().Data(),file->String().Data()));
+ TString slocal(Form("%s/%s",LocalDir().Data(),file->String().Data()));
+
+ Int_t c = gSystem->CopyFile(stemplate.Data(),slocal.Data(),ShouldOverwriteFiles());
+ if ( c )
+ {
+ Bool_t ok(kFALSE);
+ if ( stemplate.Contains(".jdl",TString::kIgnoreCase) )
+ {
+ ok = Generate(file->String().Data());
+ }
+ if (!ok)
+ {
+ AliError(Form("Error %d copying file %s",c,stemplate.Data()));
+ }
+ else
+ {
+ c=0;
+ }
+ }
+ else
+ {
+ if ( HasVars(slocal.Data()) )
+ {
+ if (!ReplaceVars(slocal.Data()))
+ {
+ AliError("pb in ReplaceVars");
+ c=1;
+ }
+ }
+ }
+ err += c;
+ }
+ }
+
+ if ( potentialProblem )
+ {
+ AliWarning("At least one local file could not be overwritten. Cross-check that the local files are OK before we try to upload them to the Grid !");
+ return kFALSE;
+ }
+ return (err==0);
+}
+
+//______________________________________________________________________________
+std::ostream* AliMuonGridSubmitter::CreateJDLFile(const char* name) const
+{
+ /// Create a (local and empty) JDL file
+
+ AliDebugClass(1,"");
+
+ TString jdl(Form("%s/%s",LocalDir().Data(),name));
+
+ if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(jdl.Data()) )
+ {
+ AliErrorClass(Form("File %s already exists. Remove it if you want to overwrite it",jdl.Data()));
+ return 0x0;
+ }
+
+ std::ofstream* os = new std::ofstream(gSystem->ExpandPathName(jdl.Data()));
+
+ if (os->bad())
+ {
+ AliErrorClass(Form("Cannot create file %s",jdl.Data()));
+ delete os;
+ os=0x0;
+ }
+
+ return os;
+}
+
+//______________________________________________________________________________
+Int_t AliMuonGridSubmitter::GetLastStage(const char* remoteDir)
+{
+ /// Get the last staging phase already performed
+
+ TGridResult* r = gGrid->Ls(remoteDir);
+ Int_t i(0);
+ Int_t lastStage(0);
+ Int_t offset = TString("Stage_").Length();
+
+ while ( r->GetFileName(i) )
+ {
+ TString file(r->GetFileName(i));
+ if (file.BeginsWith("Stage_") && !file.Contains("xml") )
+ {
+ Int_t n = TString(file(offset,file.Length()-offset)).Atoi();
+ lastStage = TMath::Max(lastStage,n);
+ }
+ ++i;
+ }
+ delete r;
+ return lastStage;
+}
+
+//______________________________________________________________________________
+TString AliMuonGridSubmitter::GetMapValue(const char* key) const
+{
+ // convenience method to access internal map of TObjStrings
+ if (!fInternalMap) return "";
+
+ TObject* o = fInternalMap->GetValue(key);
+
+ if (o)
+ {
+ return static_cast<TObjString*>(o)->String();
+ }
+
+ return "";
+}
+
+//______________________________________________________________________________
+TObjArray* AliMuonGridSubmitter::GetVariables(const char* file) const
+{
+ /// Find the variables in the file
+
+ std::ifstream in(file);
+ char line[1024];
+ TObjArray* variables(0x0);
+
+ while ( in.getline(line,1023,'\n') )
+ {
+ TString sline(line);
+ while (sline.Contains("VAR_") && !sline.BeginsWith("//") )
+ {
+ Int_t i1 = sline.Index("VAR_");
+ Int_t i2(i1);
+
+ while ( ( i2 < sline.Length() ) && ( isalnum(sline[i2]) || sline[i2]=='_' ) ) ++i2;
+
+ if (!variables)
+ {
+ variables = new TObjArray;
+ variables->SetOwner(kTRUE);
+ }
+
+ TString var = sline(i1,i2-i1);
+ if ( !variables->FindObject(var) )
+ {
+ variables->Add(new TObjString(var));
+ }
+ sline.ReplaceAll(var,"");
+ }
+ }
+
+ in.close();
+
+ return variables;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::HasVars(const char* file) const
+{
+ /// Whether or not the file contains variables that have to
+ /// be substituted
+
+ std::ifstream in(file);
+ char line[1024];
+ while ( in.getline(line,1023,'\n') )
+ {
+ TString sline(line);
+ if (sline.Contains("VAR_") && !sline.BeginsWith("//") )
+ {
+ return kTRUE;
+ }
+ }
+ return kFALSE;
+}
+
+//______________________________________________________________________________
+TMap* AliMuonGridSubmitter::InternalMap() const
+{
+ if (!fInternalMap)
+ {
+ fInternalMap = new TMap;
+ fInternalMap->SetOwnerKeyValue(kTRUE,kTRUE);
+ }
+ return fInternalMap;
+}
+
+//______________________________________________________________________________
+TString AliMuonGridSubmitter::JobTypeName(AliMuonGridSubmitter::EJobType jobType) const
+{
+ if ( jobType == kAccEff )
+ {
+ return "AccEff";
+ }
+ else if ( jobType == kQAMerge)
+ {
+ return "QAMerge";
+ }
+ return "unknown";
+}
+
+//______________________________________________________________________________
+TObjArray* AliMuonGridSubmitter::LocalFileList() const
+{
+ /// Return (after createing and filling it if needed)
+ /// the internal file list with paths from the local directory
+
+ if (!fLocalFileList)
+ {
+ fLocalFileList = static_cast<TObjArray*>(TemplateFileList()->Clone());
+ }
+
+ return fLocalFileList;
+}
+
+//______________________________________________________________________________
+UInt_t AliMuonGridSubmitter::NofRuns() const
+{
+ // number of runs we're dealing with
+ return fRunList.size();
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::OutputToJDL(std::ostream& out, const char* key,
+ const TObjArray& values) const
+{
+ /// output to ostream of key,{values} pair
+
+ out << key << " = ";
+
+ Int_t n = values.GetEntries();
+
+ if ( n > 1 )
+ {
+ out << "{" << std::endl;
+ TIter next(&values);
+ TObjString* v;
+
+ while ( ( v = static_cast<TObjString*>(next())) )
+ {
+ --n;
+ out << "\t\"" << v->String().Data() << "\"";
+ if ( n ) out << ",";
+ out << std::endl;
+ }
+ out << "}";
+ }
+ else
+ {
+ TString& v1 = static_cast<TObjString*>(values.At(0))->String();
+
+ if ( v1.IsDigit() && !(TString(key).Contains("SplitMax")) && !(TString(key).Contains("TTL")) )
+ {
+ out << v1.Atoi();
+ }
+ else
+ {
+ out << "\"" << v1.Data() << "\"";
+ }
+ }
+ out << ";" << std::endl;
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::OutputToJDL(std::ostream& out, const char* key, const char* v1,
+ const char* v2, const char* v3, const char* v4,
+ const char* v5, const char* v6, const char* v7,
+ const char* v8, const char* v9) const
+{
+ /// output to ostream
+
+ TObjArray values;
+ values.SetOwner(kTRUE);
+
+ values.Add(new TObjString(v1));
+ if ( strlen(v2) > 0 ) values.Add(new TObjString(v2));
+ if ( strlen(v3) > 0 ) values.Add(new TObjString(v3));
+ if ( strlen(v4) > 0 ) values.Add(new TObjString(v4));
+ if ( strlen(v5) > 0 ) values.Add(new TObjString(v5));
+ if ( strlen(v6) > 0 ) values.Add(new TObjString(v6));
+ if ( strlen(v7) > 0 ) values.Add(new TObjString(v7));
+ if ( strlen(v8) > 0 ) values.Add(new TObjString(v8));
+ if ( strlen(v9) > 0 ) values.Add(new TObjString(v9));
+
+ OutputToJDL(out,key,values);
+}
+
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::Print(Option_t* /*opt*/) const
+{
+ /// Printout
+
+ if (!IsValid())
+ {
+ std::cout << std::string(80,'*') << std::endl;
+ std::cout << "INVALID OBJECT. CHECK BELOW THE CONFIGURATION." << std::endl;
+ std::cout << std::string(80,'*') << std::endl;
+ }
+
+ TIter next(fInternalMap);
+ TObjString* key;
+
+ while ( ( key = static_cast<TObjString*>(next()) ) )
+ {
+ TString value = static_cast<TObjString*>(fInternalMap->GetValue(key->String()))->String();
+
+ std::cout << key->String() << " : " << value.Data() << std::endl;
+ }
+
+ if ( NofRuns() )
+ {
+ std::cout << NofRuns() << " run";
+ if ( NofRuns() > 1 ) std::cout << "s";
+ std::cout << " = ";
+ for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i )
+ {
+ std::cout << fRunList[i] << " ";
+ }
+ }
+
+ TIter nextVar(fVars);
+ while ( ( key = static_cast<TObjString*>(nextVar())) )
+ {
+ TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String()));
+ std::cout << "Variable " << key->String() << " will be replaced by " << value->String() << std::endl;
+ }
+
+ std::cout << "Files to be uploaded:" << std::endl;
+ TIter nextFile(LocalFileList());
+ TObjString* sfile;
+ while ( ( sfile = static_cast<TObjString*>(nextFile())) )
+ {
+ std::cout << sfile->String().Data() << std::endl;
+ }
+}
+
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::RemoteDirectoryExists(const char *dirname) const
+{
+ // Returns true if directory exists. Can be also a path.
+ if (!gGrid) return kFALSE;
+ // Check if dirname is a path
+ TString dirstripped = dirname;
+ dirstripped = dirstripped.Strip();
+ dirstripped = dirstripped.Strip(TString::kTrailing, '/');
+ TString dir = gSystem->BaseName(dirstripped);
+ dir += "/";
+ TString path = gSystem->DirName(dirstripped);
+ TGridResult *res = gGrid->Ls(path, "-F");
+ if (!res) return kFALSE;
+ TIter next(res);
+ TMap *map;
+ TObject *obj;
+ while ((map=dynamic_cast<TMap*>(next()))) {
+ obj = map->GetValue("name");
+ if (!obj) break;
+ if (dir == obj->GetName()) {
+ delete res;
+ return kTRUE;
+ }
+ }
+ delete res;
+ return kFALSE;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::RemoteFileExists(const char *lfn)
+{
+ // Returns true if file exists.
+ if (!gGrid) return kFALSE;
+ TGridResult *res = gGrid->Ls(lfn);
+ if (!res) return kFALSE;
+ TMap *map = dynamic_cast<TMap*>(res->At(0));
+ if (!map) {
+ delete res;
+ return kFALSE;
+ }
+ TObjString *objs = dynamic_cast<TObjString*>(map->GetValue("name"));
+ if (!objs || !objs->GetString().Length()) {
+ delete res;
+ return kFALSE;
+ }
+ delete res;
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::ReplaceVars(const char* file) const
+{
+ /// Replace the variables (i.e. things starting by VAR_) found in file
+
+ std::ifstream in(file);
+ char line[1024];
+ TObjArray lines;
+ lines.SetOwner(kTRUE);
+ Int_t nvars(0);
+ Int_t nreplaced(0);
+
+ TIter next(fVars);
+
+ while ( in.getline(line,1023,'\n') )
+ {
+ TString sline(line);
+ while (sline.Contains("VAR_") && !sline.BeginsWith("//") )
+ {
+ ++nvars;
+ TObjString* key;
+ next.Reset();
+ while ( ( key = static_cast<TObjString*>(next())) )
+ {
+ if ( sline.Contains(key->String()) )
+ {
+ ++nreplaced;
+ TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String()));
+ sline.ReplaceAll(key->String(),value->String());
+ break;
+ }
+ }
+ }
+
+ lines.Add(new TObjString(sline));
+ }
+
+ in.close();
+
+ if ( nvars > 0 )
+ {
+ if ( nreplaced != nvars )
+ {
+ AliError(Form("nvars=%d nreplaced=%d",nvars,nreplaced));
+ return kFALSE;
+ }
+ std::ofstream out(file);
+ TIter nextLine(&lines);
+ TObjString* s;
+ while ( ( s = static_cast<TObjString*>(nextLine()) ) )
+ {
+ out << s->String().Data() << std::endl;
+ }
+ out.close();
+ }
+
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+const std::vector<int>& AliMuonGridSubmitter::RunList() const
+{
+ /// Return a reference to our runlist
+ return fRunList;
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::SetPackages(const char* aliroot,
+ const char* root,
+ const char* geant3,
+ const char* api)
+{
+ /// Set the packages to be used by the jobs
+ /// Must be a valid combination, see http://alimonitor.cern.ch/packages/
+ ///
+
+ SetMapKeyValue("AliRoot",aliroot);
+ SetMapKeyValue("Root",root);
+ SetMapKeyValue("Geant3",geant3);
+ SetMapKeyValue("API",api);
+}
+
+//______________________________________________________________________________
+TString AliMuonGridSubmitter::GetRemoteDir(const char* dir, Bool_t create)
+{
+ /// Set the target remote directory (on the grid)
+
+ if (!RemoteDirectoryExists(dir))
+ {
+ if (!create)
+ {
+ AliErrorClass(Form("Remote directory %s does not exist", dir));
+ return "";
+ }
+ else
+ {
+ AliInfoClass(Form("Remote directory %s does not exist. Trying to create it...",dir));
+ if (!gGrid)
+ {
+ AliErrorClass("cannot connect to grid");
+ return "";
+ }
+ if ( !gGrid->Mkdir(dir,"-p") )
+ {
+ AliErrorClass(Form("Could not create remote dir. Sorry."));
+ return "";
+ }
+ }
+ }
+ return dir;
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::SetLocalDirectory(const char* type, const char* path)
+{
+ if (gSystem->AccessPathName(path)==kFALSE)
+ {
+ SetMapKeyValue(type,path);
+ return kTRUE;
+ }
+ return kFALSE;
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::SetMapKeyValue(const char* key, const char* value)
+{
+ TObjString skey(key);
+ InternalMap()->Remove(&skey);
+ InternalMap()->Add(new TObjString(key),new TObjString(value));
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::SetRemoteDirectory(const char* type, const char* path)
+{
+ // Set the merged directory to be used
+ TString v = GetRemoteDir(path,kTRUE);
+ SetMapKeyValue(type,v);
+ return (v.Length()>0);
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::SetRunList(const char* runlist)
+{
+ // set the runlist from a text file
+ AliAnalysisTriggerScalers ts(runlist);
+ fRunList = ts.GetRunList();
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::SetRunList(int runNumber)
+{
+ // set the runlist from a text file
+ fRunList.clear();
+ fRunList.push_back(runNumber);
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonGridSubmitter::SetVar(const char* varname, const char* value)
+{
+ /// Set a variable
+
+ TString s(varname);
+ s.ToUpper();
+ if (!s.BeginsWith("VAR_"))
+ {
+ AliError("Variable name should start with VAR_");
+ return kFALSE;
+ }
+ if (!fVars)
+ {
+ fVars = new TMap;
+ fVars->SetOwnerKeyValue(kTRUE,kTRUE);
+ }
+
+ TObject* o = new TObjString(s);
+ fVars->Remove(o);
+
+ fVars->Add(o,new TObjString(value));
+
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+TObjArray* AliMuonGridSubmitter::TemplateFileList() const
+{
+ /// Return (after createing if needed)
+
+ if (!fTemplateFileList)
+ {
+ fTemplateFileList = new TObjArray;
+ fTemplateFileList->SetOwner(kTRUE);
+ }
+ return fTemplateFileList;
+}
+
+//______________________________________________________________________________
+void AliMuonGridSubmitter::UpdateLocalFileList()
+{
+ // insure that local file list contains at least all of the template files
+ TIter next(TemplateFileList());
+ TObjString* s;
+
+ while ( ( s = static_cast<TObjString*>(next())) )
+ {
+ TObjArray* local = LocalFileList();
+ if ( !local->FindObject(s->String()))
+ {
+ local->Add(new TObjString(*s));
+ }
+ }
+}
+
+//______________________________________________________________________________
+TMap* AliMuonGridSubmitter::Vars() const
+{
+ if (!fVars)
+ {
+ fVars = new TMap;
+ fVars->SetOwnerKeyValue(kTRUE,kTRUE);
+ }
+ return fVars;
+}
+
--- /dev/null
+#ifndef ALIMUONGRIDSUBMITTER_H
+#define ALIMUONGRIDSUBMITTER_H
+
+//
+// AliMuonGridSubmitter : a base class to help submit some
+// mini-productions for muon studies (e.g. Acc x Eff, qa merging, etc...)
+//
+// author: Laurent Aphecetche (Subatech)
+//
+
+#include "TObject.h"
+#include "TString.h"
+#include "Riostream.h"
+#include <vector>
+
+class TMap;
+
+class AliMuonGridSubmitter : public TObject
+{
+public:
+
+ enum EJobType
+ {
+ kAccEff=0,
+ kQAMerge=1
+ };
+
+ AliMuonGridSubmitter(AliMuonGridSubmitter::EJobType jobType);
+ virtual ~AliMuonGridSubmitter();
+
+ virtual Bool_t Generate(const char* jdlname) const = 0;
+ virtual Bool_t Run(const char* mode) = 0;
+
+ TString JobTypeName(AliMuonGridSubmitter::EJobType jobType) const;
+
+ Bool_t SetLocalDir(const char* localdir) { return SetLocalDirectory("Local",localdir); }
+ Bool_t SetMergedDir(const char* dir) { return SetRemoteDirectory("Merged",dir); }
+ Bool_t SetRemoteDir(const char* dir) { return SetRemoteDirectory("Remote",dir); }
+ Bool_t SetTemplateDir(const char* templatedir) { return SetLocalDirectory("Template",templatedir); }
+
+ Bool_t CheckLocal() const;
+ Bool_t CheckRemote() const;
+
+ void CleanLocal(const char* excludeList="") const;
+
+ void Invalidate() { fIsValid = kFALSE; }
+
+ void Validate() { fIsValid = kTRUE; }
+
+ TString MergedDir() const { return GetMapValue("Merged"); }
+ TString RemoteDir() const { return GetMapValue("Remote"); }
+ TString LocalDir() const { return GetMapValue("Local"); }
+ TString TemplateDir() const { return GetMapValue("Template"); }
+
+ TString FilePath(const char* what) const;
+
+ UInt_t NofRuns() const;
+
+ const std::vector<Int_t>& RunList() const;
+
+ void SetRunList(const char* runlist);
+ void SetRunList(int runNumber);
+
+ virtual void Print(Option_t* opt="") const;
+
+ Bool_t CopyLocalFilesToRemote();
+
+ Bool_t CopyTemplateFilesToLocal();
+
+ void SetPackages(const char* aliroot, const char* root, const char* geant3,
+ const char* api="VO_ALICE@APISCONFIG::V1.1x");
+
+ Bool_t ShouldOverwriteFiles() const { return fShouldOverwriteFiles; }
+
+ void ShouldOverwriteFiles(Bool_t flag) { fShouldOverwriteFiles = flag; }
+
+ Bool_t IsValid() const { return fIsValid; }
+
+ void OutputToJDL(std::ostream& out, const char* key, const char* v1,
+ const char* v2="", const char* v3="", const char* v4="", const char* v5="",
+ const char* v6="", const char* v7="", const char* v8="", const char* v9="") const;
+
+ void OutputToJDL(std::ostream& out, const char* key, const TObjArray& values) const;
+
+ TString GetRemoteDir(const char* dir, Bool_t create=kTRUE);
+
+ Bool_t RemoteDirectoryExists(const char *dirname) const;
+ Bool_t RemoteFileExists(const char *lfn);
+
+ Bool_t CopyLocalFilesToRemote(const TObjArray& localFiles);
+
+ Bool_t CopyFile(const char* localFile);
+
+ Int_t GetLastStage(const char* remoteDir);
+
+ std::ostream* CreateJDLFile(const char* name) const;
+
+ Bool_t CheckRemoteDir() const;
+
+ Bool_t ReplaceVars(const char* file) const;
+
+ Bool_t HasVars(const char* localFile) const;
+
+ Bool_t SetVar(const char* varname, const char* value);
+
+ TObjArray* GetVariables(const char* file) const;
+
+ Bool_t CheckCompilation(const char* file) const;
+
+ TObjArray* LocalFileList() const;
+
+ TObjArray* TemplateFileList() const;
+
+protected:
+
+ std::ostream* CreateJDLFile(const char* name);
+
+ TString GetMapValue(const char* key) const;
+
+ TMap* InternalMap() const;
+ TMap* Vars() const;
+
+ void SetMapKeyValue(const char* key, const char* value);
+
+ Bool_t SetLocalDirectory(const char* type, const char* path);
+
+ Bool_t SetRemoteDirectory(const char* type, const char* path);
+
+ void UpdateLocalFileList();
+
+ void AddToTemplateFileList(const char* filename);
+
+private:
+ AliMuonGridSubmitter(const AliMuonGridSubmitter& rhs);
+ AliMuonGridSubmitter& operator=(const AliMuonGridSubmitter& rhs);
+
+private:
+ mutable TMap* fInternalMap; // map of directory paths and packages versions
+ mutable TMap* fVars; // map of the variables we can replace in template files
+ Bool_t fIsValid; // whether this object is valid (i.e. properly configured)
+ Bool_t fShouldOverwriteFiles; // whether or not to overwrite the local files each time we run
+ mutable TObjArray* fTemplateFileList; // list of template files
+ mutable TObjArray* fLocalFileList; // list of local files
+ std::vector<Int_t> fRunList; // run list to process
+
+ ClassDef(AliMuonGridSubmitter,0) // Helper class to submit some muon jobs
+};
+
+#endif
+
--- /dev/null
+#include "AliMuonQAMergeSubmitter.h"
+
+#include "AliMuonAccEffSubmitter.h"
+#include "AliAnalysisTriggerScalers.h"
+#include "AliLog.h"
+#include "TSystem.h"
+#include "Riostream.h"
+#include "TGrid.h"
+#include "TGridResult.h"
+
+namespace {
+ const Int_t kFinal(999);
+}
+
+ClassImp(AliMuonQAMergeSubmitter)
+
+//_____________________________________________________________________________
+AliMuonQAMergeSubmitter::AliMuonQAMergeSubmitter(const char* period, const char* pass) :
+AliMuonGridSubmitter(AliMuonGridSubmitter::kQAMerge),
+fPeriod(period),
+fPass(pass),
+fWhatToMerge("Merged.QA.Data.root"),
+fSplitMaxInputFileNumber(50)
+{
+ if (!fPeriod.BeginsWith("LHC"))
+ {
+ AliError("Period not starting with LHC !");
+ }
+
+ AddToTemplateFileList("QAMerge.C");
+ AddToTemplateFileList("QAMerge.sh");
+ AddToTemplateFileList("validation.sh");
+ AddToTemplateFileList(MergeJDLName(kFALSE).Data());
+ AddToTemplateFileList(MergeJDLName(kTRUE).Data());
+
+ SetVar("VAR_MERGED_OUTPUT_NAME",Form("%s",fWhatToMerge.Data()));
+
+ ShouldOverwriteFiles(kTRUE);
+
+ TString speriod(period);
+
+ Int_t year = 2000 + TString(speriod(3,3)).Atoi();
+
+ SetMapKeyValue("DataDirFormat",Form("/alice/data/%d/%s/%%09d/ESDs/%s",year,period,pass));
+}
+
+//_____________________________________________________________________________
+AliMuonQAMergeSubmitter::~AliMuonQAMergeSubmitter()
+{
+}
+
+//______________________________________________________________________________
+Bool_t AliMuonQAMergeSubmitter::Generate(const char* jdlname) const
+{
+ /// Create the JDL for merging jobs
+
+ AliDebug(1,"");
+
+ std::ostream* os = CreateJDLFile(jdlname);
+
+ if (!os)
+ {
+ return kFALSE;
+ }
+
+ Bool_t final = TString(jdlname).Contains("final",TString::kIgnoreCase);
+
+ (*os) << "# Generated merging jdl (production mode)" << std::endl
+ << "# $1 = run number" << std::endl
+ << "# $2 = merging stage" << std::endl
+ << "# Stage_<n>.xml made via: find <OutputDir> *Stage<n-1>/*" << fWhatToMerge.Data() << std::endl;
+
+ OutputToJDL(*os,"Packages",
+ GetMapValue("AliRoot").Data(),
+ GetMapValue("Geant3").Data(),
+ GetMapValue("Root").Data(),
+ GetMapValue("API").Data());
+
+ OutputToJDL(*os,"Executable","QAMerge.sh");
+
+ OutputToJDL(*os,"Price","1");
+
+ if ( final )
+ {
+ OutputToJDL(*os,"Jobtag","comment: AliMuonQAMergeSubmitter final merging RUN $1");
+ }
+ else
+ {
+ OutputToJDL(*os,"Jobtag","comment: AliMuonQAMergeSubmitter merging RUN $1 stage $2");
+ }
+
+ OutputToJDL(*os,"Workdirectorysize","5000MB");
+
+ OutputToJDL(*os,"Validationcommand",Form("%s/validation.sh",RemoteDir().Data()));
+
+ OutputToJDL(*os,"TTL","14400");
+
+ OutputToJDL(*os,"OutputArchive",
+ "log_archive.zip:stderr,stdout@disk=1",
+ Form("root_archive.zip:%s@disk=3",fWhatToMerge.Data())
+ );
+
+// OutputToJDL(*os,"Arguments",(final ? "2":"1")); // for QAmerge.sh, 1 means intermediate merging stage, 2 means final merging
+
+ if ( !final )
+ {
+ OutputToJDL(*os,"Arguments","wn.xml");
+ OutputToJDL(*os,"InputFile",Form("LF:%s/QAMerge.C",RemoteDir().Data()));
+ OutputToJDL(*os,"OutputDir",Form("%s/$1/Stage_$2/#alien_counter_03i#",RemoteDir().Data()));
+ OutputToJDL(*os,"Split","se");
+ OutputToJDL(*os,"InputDataCollection",Form("LF:%s/$1/Stage_$2.xml,nodownload",RemoteDir().Data()));
+ OutputToJDL(*os,"SplitMaxInputFileNumber",Form("%d",GetSplitMaxInputFileNumber()));
+ OutputToJDL(*os,"InputDataListFormat","xml-single");
+ OutputToJDL(*os,"InputDataList","wn.xml");
+ }
+ else
+ {
+ OutputToJDL(*os,"InputFile",Form("LF:%s/QAMerge.C",RemoteDir().Data()),
+ Form("LF:%s/$1/Stage_$2.xml",RemoteDir().Data()));
+ OutputToJDL(*os,"Arguments","Stage_$2.xml $1");
+ OutputToJDL(*os,"OutputDir",Form("%s/$1",RemoteDir().Data()));
+ }
+
+ return kTRUE;
+}
+
+//_____________________________________________________________________________
+UInt_t AliMuonQAMergeSubmitter::MakeXMLCollectionForRun(Int_t runNumber, Int_t stage)
+{
+ /// Create a collection named Stage_[stage].xml
+ /// with the files from stage-1 (or all the files if stage=0)
+ /// Return the total number of files to be merged
+
+ if ( stage < 0 )
+ {
+ AliError(Form("Stage (%d) should be >=0",stage));
+ return 0;
+ }
+
+ TString filename;
+ TString sourcedir;
+
+ if ( stage > 1 )
+ {
+ filename.Form("%s/%d/Stage_%d.xml",LocalDir().Data(),runNumber,stage);
+ sourcedir.Form("%s/%d/Stage_%d",RemoteDir().Data(),runNumber,stage-1);
+ }
+ else if ( stage == 1 )
+ {
+ sourcedir = GetMapValue("DataDirFormat");
+
+ if ( sourcedir.Length() == 0 )
+ {
+ AliError("Cannot make collections from an empty data dir !");
+ return 0;
+ }
+ filename.Form("%s/%d/Stage_%d.xml",LocalDir().Data(),runNumber,stage);
+ }
+ else
+ {
+ AliError("oups");
+ return 0;
+ }
+
+ UInt_t count(0);
+
+ TGridResult* res = gGrid->Query(Form(sourcedir.Data(),runNumber),fWhatToMerge.Data());
+
+ Int_t nFiles = res->GetEntries();
+
+ if (!nFiles)
+ {
+ AliError(Form("Got no file for run %d",runNumber));
+ return 0;
+ }
+
+ gSystem->mkdir(Form("%s/",gSystem->DirName(filename.Data())),kTRUE);
+
+ AliDebug(1,Form("Creating %s",filename.Data()));
+
+ std::ofstream out(filename.Data());
+
+ out << Form("<?xml version=\"1.0\"?>\n<alien>\n <collection name=\"%d-stage-%d\">",runNumber,stage) << std::endl;
+
+ Long64_t size(0);
+ const Double_t byte2GB(1024*1024*1024);
+
+ for (Int_t i = 0; i < nFiles; ++i)
+ {
+ ++count;
+
+ size += TString(res->GetKey(i,"size")).Atoll();
+
+ out << Form(" <event name=\"%d\">",count) << endl;
+ out << Form(" <file name=\"%s\" aclId=\"%s\" broken=\"%s\" ctime=\"%s\" "
+ "dir=\"%s\" entryId=\"%s\" expiretime=\"%s\" gowner=\"%s\" "
+ "guid=\"%s\" guidtime=\"%s\" lfn=\"%s\" md5=\"%s\" owner=\"%s\" "
+ " perm=\"%s\" replicated=\"%s\" size=\"%s\" turl=\"%s\" type=\"%s\" />",
+ gSystem->BaseName(res->GetKey(i,"lfn")),
+ res->GetKey(i,"aclId"),
+ res->GetKey(i,"broken"),
+ res->GetKey(i,"ctime"),
+ res->GetKey(i,"dir"),
+ res->GetKey(i,"entryId"),
+ res->GetKey(i,"expiretime"),
+ res->GetKey(i,"gowner"),
+ res->GetKey(i,"guid"),
+ res->GetKey(i,"guidtime"),
+ res->GetKey(i,"lfn"),
+ res->GetKey(i,"md5"),
+ res->GetKey(i,"owner"),
+ res->GetKey(i,"perm"),
+ res->GetKey(i,"replicated"),
+ res->GetKey(i,"size"),
+ res->GetKey(i,"turl"),
+ res->GetKey(i,"type")) << endl;
+ out << " </event>" << endl;
+ }
+
+ TString summary(Form("numberoffiles=\"%d\" size=\"%7.2f GB\" ",count,size/byte2GB));
+
+ out << Form(" <summary %s />",summary.Data()) << endl;
+ out << " </collection>" << endl;
+ out << "</alien>" << endl;
+
+ out.close();
+
+ delete res;
+
+ Bool_t ok = CopyFile(filename.Data());
+
+ if (!ok) return 0;
+
+ return count;
+}
+
+//_____________________________________________________________________________
+void AliMuonQAMergeSubmitter::Print(Option_t*) const
+{
+ std::cout << "SplitMaxInputFileNumber : " << GetSplitMaxInputFileNumber() << std::endl;
+ AliMuonGridSubmitter::Print();
+}
+
+//_____________________________________________________________________________
+Bool_t AliMuonQAMergeSubmitter::Run(const char* mode)
+{
+ if (!IsValid()) return kFALSE;
+
+ TString smode(mode);
+ smode.ToUpper();
+
+ if ( smode == "FULL")
+ {
+ return ( Run("LOCAL") && Run("UPLOAD") && Run("SUBMIT") );
+ }
+
+ if ( smode == "LOCAL")
+ {
+ return CopyTemplateFilesToLocal();
+ }
+
+ if ( smode == "UPLOAD" )
+ {
+ return CopyLocalFilesToRemote();
+ }
+
+ if ( smode == "TEST" )
+ {
+ Bool_t ok = Run("LOCAL") && Run("UPLOAD");
+ if ( ok )
+ {
+ ok = (Submit(kTRUE)>0);
+ }
+ return ok;
+ }
+
+ if ( smode == "SUBMIT" )
+ {
+ return (Submit(kFALSE)>0);
+ }
+
+ return kFALSE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliMuonQAMergeSubmitter::SetRemoteDir(const char* dir)
+{
+ if ( AliMuonGridSubmitter::SetRemoteDir(dir) )
+ {
+ Validate();
+ return kTRUE;
+ }
+ else
+ {
+ Invalidate();
+ return kFALSE;
+ }
+}
+
+//______________________________________________________________________________
+void AliMuonQAMergeSubmitter::ShowStage(Int_t runNumber)
+{
+ /// Show stage for a given run number
+
+ Int_t stage(0);
+
+ if ( RemoteFileExists(Form("%s/%d/%s",RemoteDir().Data(),runNumber,fWhatToMerge.Data())) )
+ {
+ stage = kFinal;
+ }
+ else
+ {
+ stage = GetLastStage(Form("%s/%d",RemoteDir().Data(),runNumber));
+ }
+
+ std::cout << "RUN " << runNumber << " ";
+
+ if ( stage == kFinal )
+ {
+ std::cout << "FINAL";
+ }
+ else
+ {
+ std::cout << "Stage " << stage;
+ }
+ std::cout << std::endl;
+}
+
+//______________________________________________________________________________
+void AliMuonQAMergeSubmitter::ShowStages()
+{
+ /// Show in remote dir the list of stages we're in for each run
+
+ TGridResult* r = gGrid->Ls(RemoteDir());
+ Int_t i(0);
+ std::map<int,std::vector<int> > stages;
+
+ while ( r->GetFileName(i) )
+ {
+ TString s(r->GetFileName(i));
+ if (s.IsDec())
+ {
+ Int_t runNumber = s.Atoi();
+ Int_t stage(0);
+
+ if ( RemoteFileExists(Form("%s/%d/%s",RemoteDir().Data(),runNumber,fWhatToMerge.Data())) )
+ {
+ stage = kFinal;
+ }
+ else
+ {
+ stage = GetLastStage(Form("%s/%d",RemoteDir().Data(),runNumber));
+ }
+
+ stages[stage].push_back(runNumber);
+ }
+ ++i;
+ }
+ delete r;
+
+ std::map<int,std::vector<int> >::const_iterator it;
+
+ for ( it = stages.begin(); it != stages.end(); ++it )
+ {
+ const std::vector<int>& runs = it->second;
+ Int_t stage = it->first;
+ if ( stage == kFinal )
+ {
+ std::cout << "FINAL";
+ }
+ else
+ {
+ std::cout << "Stage " << stage;
+ }
+ std::cout << std::endl;
+ for ( std::vector<int>::size_type irun = 0; irun < runs.size(); ++irun )
+ {
+ std::cout << runs[irun] << " ";
+ }
+ std::cout << std::endl;
+ }
+}
+
+
+//_____________________________________________________________________________
+Bool_t AliMuonQAMergeSubmitter::Submit(Int_t runNumber, Bool_t dryRun)
+{
+ /// Submit merging job for one run
+
+ TString runDir = GetRemoteDir(Form("%s/%d", RemoteDir().Data(), runNumber),kTRUE);
+
+ if (RemoteFileExists(Form("%s/%s", runDir.Data(),fWhatToMerge.Data())))
+ {
+ AliWarning(" ! final merging already done");
+ return kTRUE;
+ }
+
+ Int_t lastStage = GetLastStage(runDir.Data());
+
+ AliDebug(1,Form("lastStage=%d",lastStage));
+
+ ++lastStage;
+
+ UInt_t n = MakeXMLCollectionForRun(runNumber,lastStage);
+
+ Bool_t final = ( n < GetSplitMaxInputFileNumber() );
+
+ TString query;
+ TString jdl(MergeJDLName(final));
+
+ gGrid->Cd(RemoteDir().Data());
+
+ query.Form("submit %s %d %d", jdl.Data(), runNumber, lastStage);
+
+ AliInfo(Form("query=%s",query.Data()));
+
+ if (dryRun)
+ {
+ return kTRUE;
+ }
+
+ Bool_t done = kFALSE;
+ TGridResult *res = gGrid->Command(query);
+ if (res)
+ {
+ TString cjobId1 = res->GetKey(0,"jobId");
+ if (!cjobId1.IsDec())
+ {
+ AliError(" FAILED");
+ gGrid->Stdout();
+ gGrid->Stderr();
+ }
+ else
+ {
+ AliInfo(Form(" DONE\n --> the job Id is: %s \n", cjobId1.Data()));
+ done = kTRUE;
+ }
+ delete res;
+ }
+ else
+ {
+ AliError(" FAILED");
+ }
+
+ return done;
+}
+
+//_____________________________________________________________________________
+Int_t AliMuonQAMergeSubmitter::Submit(Bool_t dryRun)
+{
+ /// Submit merging jobs
+
+ if (!NofRuns())
+ {
+ AliError("No run to work with");
+ return 0;
+ }
+
+ const std::vector<int>& runs = RunList();
+
+ TString failed;
+
+ for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i )
+ {
+ Int_t run = runs[i];
+ Bool_t ok = Submit(run,dryRun);
+
+ if (!ok)
+ {
+ failed += TString::Format("%d",run);
+ failed += " ";
+ }
+ }
+
+ if (failed.Length()>0)
+ {
+ AliInfo(Form("List of failed runs : %s",failed.Data()));
+ return 0;
+ }
+
+ return 1;
+}
+
--- /dev/null
+#ifndef ALIMUONQAMERGESUBMITTER_H
+#define ALIMUONQAMERGESUBMITTER_H
+
+#include "AliMuonGridSubmitter.h"
+#include "TString.h"
+
+#include <vector>
+
+class AliMuonQAMergeSubmitter : public AliMuonGridSubmitter
+{
+public:
+ AliMuonQAMergeSubmitter(const char* period, const char* pass);
+ virtual ~AliMuonQAMergeSubmitter();
+
+ Bool_t Run(const char* mode);
+
+ Bool_t Submit(Int_t runNumber, Bool_t dryRun);
+
+ Int_t Submit(Bool_t dryRun);
+
+ TString MergeJDLName(Bool_t final) const { return (final ? "QAMerge_final.jdl" : "QAMerge.jdl"); }
+
+ Bool_t Generate(const char* name) const;
+
+ Bool_t SetRemoteDir(const char* dir);
+
+ UInt_t MakeXMLCollectionForRun(Int_t runNumber, Int_t stage);
+
+ UInt_t GetSplitMaxInputFileNumber() const { return fSplitMaxInputFileNumber; }
+
+ void SetSplitMaxInputFileNumber(UInt_t n) { fSplitMaxInputFileNumber=n; }
+
+ virtual void Print(Option_t* opt="") const;
+
+ void ShowStages();
+
+ void ShowStage(Int_t runNumber);
+
+private:
+
+ TString fPeriod;
+ TString fPass;
+ TString fWhatToMerge; // file to be merged
+ UInt_t fSplitMaxInputFileNumber;
+
+ ClassDef(AliMuonQAMergeSubmitter,1)
+};
+
+#endif
--- /dev/null
+#include "TSystem.h"
+#include "TList.h"
+#include "TObjString.h"
+#include "Riostream.h"
+#include "TRegexp.h"
+#include "AliMUONVTrackerData.h"
+#include "TFile.h"
+#include "TKey.h"
+#include "TGrid.h"
+#include "TGridResult.h"
+#include "TUrl.h"
+#include "TMath.h"
+#include "TFile.h"
+#include "TStopwatch.h"
+#include "TGridCollection.h"
+#include "TROOT.h"
+#include "TError.h"
+#include "TH1.h"
+#include "TMethodCall.h"
+
+void CopyFromRemote(Int_t runNumber, const char* period, const char* pass);
+void CopyFromRemote(const TList& files);
+TList* GetFileList(Int_t runNumber, const char* period, const char* pass);
+void QAMerge(Int_t runNumber, const char* period, const char* pass);
+void QAMerge(const TList& files, const char* outputfile);
+
+////______________________________________________________________________________
+//AliMUONVTrackerData* GetTrackerData(TDirectory* dir, const char* trackerDataName)
+//{
+// AliMUONVTrackerData* trackerData(0x0);
+//
+// TIter next(dir->GetListOfKeys());
+// TKey* key;
+//
+// while ( ( key = static_cast<TKey*>(next()) ) && !trackerData )
+// {
+// if ( key->IsFolder() )
+// {
+// trackerData = GetTrackerData(static_cast<TDirectory*>(key->ReadObj()),trackerDataName);
+// }
+// else
+// {
+// TString name(key->GetName());
+//
+// if ( name.Contains(trackerDataName) )
+// {
+// trackerData = dynamic_cast<AliMUONVTrackerData*>(key->ReadObj());
+// }
+// }
+// }
+//
+// return trackerData;
+//
+//}
+//
+////______________________________________________________________________________
+//AliMUONVTrackerData* GetTrackerData(const char* filename, const char* trackerDataName)
+//{
+// TFile* file = TFile::Open(filename);
+//
+// cout << filename << endl;
+//
+// if (!file) return 0x0;
+//
+// AliMUONVTrackerData* trackerData = GetTrackerData(file,trackerDataName);
+//
+// delete file;
+//
+// return trackerData;
+//
+//}
+
+////______________________________________________________________________________
+//AliMUONVTrackerData* MergeTrackerData(const TList& filelist, const char* trackerDataName)
+//{
+// TIter next(&filelist);
+// TObjString* s;
+//
+// s = static_cast<TObjString*>(next());
+//
+// AliMUONVTrackerData* d = GetTrackerData(s->String().Data(),trackerDataName);
+//
+// if (!d)
+// {
+// cout << Form("ERROR : no tracker data found in %s",s->String().Data()) << endl;
+// return 0x0;
+// }
+//
+// AliMUONVTrackerData* merged = static_cast<AliMUONVTrackerData*>(d->Clone(Form("%s-MERGED",trackerDataName)));
+//
+// while ( ( s = static_cast<TObjString*>(next()) ) )
+// {
+// d = GetTrackerData(s->String().Data(),trackerDataName);
+// if (d)
+// {
+// TList list;
+// list.Add(d);
+// cout << "Merging " << s->String().Data() << " " << d->GetName() << " " << d->NumberOfEvents(-1) << endl;
+//
+// merged->Merge(&list);
+// delete d;
+// }
+// }
+//
+// merged->SetName(Form("%s-MERGED-%d",trackerDataName,runNumber));
+//
+// merged->SetTitle(Form("%s merged for run %d",trackerDataName,runNumber));
+//
+//
+// return merged;
+//}
+
+//______________________________________________________________________________
+void GenerateFileList(const char* runlist="philippe.runlist")
+{
+ if (!gGrid)
+ {
+ TGrid::Connect("alien://");
+ }
+ if (!gGrid) return;
+
+ ifstream in(runlist);
+ Int_t run;
+
+ Int_t n(0);
+
+ while ( in >> run )
+ {
+ TString basedir("/alice/data/2009/LHC09d/");
+
+ TString dir(Form("%s%09d/ESDs/pass1/*/Merged.QA.Data.root",basedir.Data(),run));
+
+ TGridResult* r = gGrid->Ls(dir.Data());
+
+ Int_t i(0);
+
+ while ( r->GetFileName(i) )
+ {
+ cout << "alien://" << r->GetFileNamePath(i) << endl;
+ ++i;
+ }
+
+ delete r;
+
+ ++n;
+ }
+}
+
+//______________________________________________________________________________
+void CopyFromRemote(Int_t runNumber, const char* period, const char* pass)
+{
+ TList* list = GetFileList(runNumber,period,pass);
+ if ( list )
+ {
+ CopyFromRemote(*list);
+ }
+ delete list;
+}
+
+//______________________________________________________________________________
+void CopyFromRemote(const TList& files)
+{
+ TStopwatch timer;
+
+ TIter next(&files);
+ TObjString* line;
+
+ while ( ( line = static_cast<TObjString*>(next()) ) )
+ {
+ TUrl url(line->String());
+
+ if ( TString(url.GetProtocol()) == "alien" )
+ {
+ if (!gGrid)
+ {
+ TGrid::Connect("alien://");
+ if (!gGrid)
+ {
+ cout << "Cannot get alien connection" << endl;
+ return;
+ }
+ }
+ }
+
+ TString file(url.GetFile());
+
+ TString dir(gSystem->DirName(file));
+
+ gSystem->mkdir(dir.Data(),kTRUE);
+
+ if ( gSystem->AccessPathName(file.Data())==kFALSE)
+ {
+ cout << "Skipping copy of " << file.Data() << " as it already exists" << endl;
+ }
+ else
+ {
+ TFile::Cp(line->String().Data(),file.Data());
+ if ( line->String().Contains("root_archive.zip") )
+ {
+ gSystem->Exec(Form("unzip %s -d %s",file.Data(),gSystem->DirName(file.Data())));
+ gSystem->Exec(Form("rm %s",file.Data()));
+ }
+ }
+ }
+
+ timer.Print();
+}
+
+//______________________________________________________________________________
+TList* GetFileList(Int_t runNumber, const char* period, const char* pass)
+{
+ if (!gGrid) TGrid::Connect("alien://");
+ if (!gGrid)
+ {
+ return 0x0;
+ }
+
+ Int_t year;
+
+ TString speriod(period);
+
+ if (!speriod.BeginsWith("LHC"))
+ {
+ std::cerr << "Period not starting with LHC !" << std::endl;
+ return 0x0;
+ }
+
+ year = 2000 + TString(speriod(3,3)).Atoi();
+
+ TString sbasedir(Form("/alice/data/%d/%s/%09d/ESDs/%s",year,period,runNumber,pass));
+
+ std::cout << sbasedir.Data() << std::endl;
+
+ TString search("Merged.QA.Data.root");
+
+ TGridResult* res = gGrid->Query(sbasedir.Data(),search.Data());
+
+ Int_t nFiles = res->GetEntries();
+
+ nFiles = res->GetEntries();
+
+ Long64_t size(0);
+ Int_t count(0);
+ TList* files(0x0);
+
+ for (Int_t i = 0; i < nFiles; ++i)
+ {
+ Long64_t thisSize = TString(res->GetKey(i,"size")).Atoll();
+
+// TUrl url(res->GetKey(i,"turl"));
+
+ if (!files)
+ {
+ files = new TList;
+ files->SetOwner(kTRUE);
+ }
+
+ files->Add(new TObjString(res->GetKey(i,"turl")));
+
+ ++count;
+
+ size += thisSize;
+ }
+
+ std::cout << Form("%d files for a total of %d MB",count,TMath::Nint(size/1024.0/1024)) << std::endl;
+
+ delete res;
+
+ return files;
+}
+
+//______________________________________________________________________________
+void QAMerge(Int_t runNumber, const char* period, const char* pass)
+{
+ TList* list = GetFileList(runNumber,period,pass);
+ if ( list )
+ {
+ QAMerge(*list,Form("QA.%s.%s.%d.root",period,pass,runNumber));
+ }
+ delete list;
+
+}
+
+//______________________________________________________________________________
+TObject* GetObject(const char* filepath, const char* objectPath)
+{
+ TFile* f = TFile::Open(filepath);
+
+ if (!f)
+ {
+ std::cerr << "Could not open file " << filepath << std::endl;
+ return 0x0;
+ }
+
+ TObject* o = f->Get(objectPath);
+
+ if (!o)
+ {
+ std::cout << "Cannot get object " << objectPath << " from " << filepath << std::endl;
+ return 0x0;
+ }
+
+ if ( o->InheritsFrom("TH1") )
+ {
+ TH1* h = static_cast<TH1*>(o);
+ h->SetDirectory(0);
+ }
+
+ delete f;
+
+ return o;
+}
+
+//______________________________________________________________________________
+TObject* Merge(const TList& files, const char* objectPath)
+{
+ TIter next(&files);
+ TObjString* filename;
+
+ filename = static_cast<TObjString*>(next());
+
+ TObject* d = GetObject(filename->String().Data(),objectPath);
+
+ if (!d)
+ {
+ cout << Form("ERROR : no object found in %s",filename->String().Data()) << endl;
+ return 0x0;
+ }
+
+ TString oname(gSystem->BaseName(objectPath));
+
+ TObject* merged = d->Clone();
+
+ TMethodCall callEnv;
+
+ if ( merged->IsA() )
+ {
+ callEnv.InitWithPrototype(merged->IsA(), "Merge", "TCollection*");
+ }
+
+ if (!callEnv.IsValid())
+ {
+ std::cout << "callEnv invalid" << std::endl;
+ delete merged;
+ return 0x0;
+ }
+
+ while ( ( filename = static_cast<TObjString*>(next()) ) )
+ {
+// std::cout << filename->String().Data() << " : " << objectPath << std::endl;
+
+ d = GetObject(filename->String().Data(),objectPath);
+
+ if (!d)
+ {
+ continue;
+ }
+
+ TList list;
+ list.Add(d);
+ callEnv.SetParam((Long_t) (&list));
+ callEnv.Execute(merged);
+
+ delete d;
+ }
+
+ return merged;
+
+}
+
+//______________________________________________________________________________
+void QAMerge(const TList& files, const char* outputfile)
+{
+ const char* eventSpecie = "HighMultiplicity";
+
+ TList objectsToMerge;
+ objectsToMerge.SetOwner(kTRUE);
+
+ objectsToMerge.Add(new TObjString(Form("MUON/Raws/%s/Expert/%s_hTrackerDDLNofEventsSeen",eventSpecie,eventSpecie)));
+
+ objectsToMerge.Add(new TObjString(Form("MUON/RecPoints/%s/Expert/%s_RecPoints",eventSpecie,eventSpecie)));
+ objectsToMerge.Add(new TObjString(Form("MUON/RecPoints/%s/Expert/%s_RecCharges",eventSpecie,eventSpecie)));
+
+ objectsToMerge.Add(new TObjString(Form("MUON/Raws/%s/Expert/%s_RawCharges",eventSpecie,eventSpecie)));
+
+ for ( Int_t i = 1; i <= 10; ++i )
+ {
+ objectsToMerge.Add(new TObjString(Form("MUON/RecPoints/%s/Expert/%s_hTrackerClusterHitMapForChamber%d",eventSpecie,eventSpecie,i)));
+ objectsToMerge.Add(new TObjString(Form("MUON/ESDs/%s/Expert/%s_hESDClusterHitMap%d",eventSpecie,eventSpecie,i)));
+ }
+
+ TObjArray output;
+ output.SetOwner(kTRUE);
+
+ TIter next(&objectsToMerge);
+ TObjString* s;
+
+ while ( ( s = static_cast<TObjString*>(next())) )
+ {
+ output.Add(Merge(files,s->String().Data()));
+ }
+
+ TFile* f = TFile::Open(outputfile,"recreate");
+
+ next.Reset();
+
+ Int_t i(0);
+ while ( ( s = static_cast<TObjString*>(next())) )
+ {
+ TObject* o = output.At(i);
+ if (o)
+ {
+ TString dir = gSystem->DirName(s->String());
+ TString file = gSystem->BaseName(s->String());
+ TDirectory* tdir = static_cast<TDirectory*>(f->Get(dir.Data()));
+ if (!tdir)
+ {
+ f->mkdir(dir.Data()," ");
+ tdir = static_cast<TDirectory*>(f->Get(dir.Data()));
+ }
+ tdir->cd();
+ o->Write(file.Data());
+ }
+ ++i;
+ }
+
+ f->Write();
+
+ f->Close();
+
+ delete f;
+}
+
+//______________________________________________________________________________
+void QAMerge(const char* inputfilelist, const char* mergedFile)
+{
+ if (!gGrid)
+ {
+ TGrid::Connect("alien://");
+ }
+ if (!gGrid) return;
+
+ TString sinput(inputfilelist);
+ TList filelist;
+ filelist.SetOwner(kTRUE);
+
+ if (sinput.Contains(".xml"))
+ {
+ TGridCollection *coll = reinterpret_cast<TGridCollection*>(gROOT->ProcessLine(Form("TAlienCollection::Open(\"%s\");", inputfilelist)));
+ if (!coll)
+ {
+ ::Error("MergeOutput", "Input XML collection empty.");
+ return;
+ }
+ // Iterate grid collection
+ while (coll->Next())
+ {
+ filelist.Add(new TObjString(coll->GetTURL()));
+ }
+ }
+ else
+ {
+ ifstream in(inputfilelist);
+ char filename[1024];
+
+ while (in.getline(filename,1024,'\n'))
+ {
+ filelist.Add(new TObjString(filename));
+ }
+ }
+
+ if ( filelist.GetEntries()==0 )
+ {
+ std::cout << "No file to be merged !" << std::endl;
+ }
+ else
+ {
+ QAMerge(filelist,mergedFile);
+ }
+
+ ofstream out;
+ out.open("outputs_valid_merge", ios::out);
+ out.close();
+}
+
--- /dev/null
+#!/bin/bash
+export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
+echo "========================================="
+echo "############## PATH : ##############"
+echo $PATH
+echo "############## LD_LIBRARY_PATH : ##############"
+echo $LD_LIBRARY_PATH
+echo "############## ROOTSYS : ##############"
+echo $ROOTSYS
+echo "############## which root : ##############"
+which root
+echo "############## ALICE_ROOT : ##############"
+echo $ALICE_ROOT
+echo "############## which aliroot : ##############"
+which aliroot
+echo "############## system limits : ##############"
+ulimit -a
+echo "############## memory : ##############"
+free -m
+echo "========================================="
+
+aliroot -b << EOF
+gSystem->SetIncludePath("-I$ALICE_ROOT/MUON");
+.L QAMerge.C+
+QAMerge("$1","VAR_MERGED_OUTPUT_NAME");
+EOF
+
+echo "======== QAmerge.C finished with exit code: $? ========"
+echo "############## memory after: ##############"
+free -m
--- /dev/null
+#!/bin/bash
+
+##################################################
+validateout=`dirname $0`
+validatetime=`date`
+validated="0";
+error=0
+if [ -z $validateout ]
+then
+validateout="."
+fi
+
+cd $validateout;
+validateworkdir=`pwd`;
+
+echo "*******************************************************" >> stdout
+echo "* Automatically generated validation script *" >> stdout
+
+echo "* Time: $validatetime " >> stdout
+echo "* Dir: $validateout" >> stdout
+echo "* Workdir: $validateworkdir" >> stdout
+echo "* ----------------------------------------------------*" >> stdout
+ls -la ./ >> stdout
+echo "* ----------------------------------------------------*" >> stdout
+
+##################################################
+
+if [ ! -f stderr ] ; then
+error=1
+echo "* ########## Job not validated - no stderr ###" >> stdout
+echo "Error = $error" >> stdout
+fi
+parArch=`grep -Ei "Cannot Build the PAR Archive" stderr`
+segViol=`grep -Ei "Segmentation violation" stderr`
+segFault=`grep -Ei "Segmentation fault" stderr`
+glibcErr=`grep -Ei "*** glibc detected ***" stderr`
+
+if [ "$parArch" != "" ] ; then
+error=1
+echo "* ########## Job not validated - PAR archive not built ###" >> stdout
+echo "$parArch" >> stdout
+echo "Error = $error" >> stdout
+fi
+if [ "$segViol" != "" ] ; then
+error=1
+echo "* ########## Job not validated - Segment. violation ###" >> stdout
+echo "$segViol" >> stdout
+echo "Error = $error" >> stdout
+fi
+if [ "$segFault" != "" ] ; then
+error=1
+echo "* ########## Job not validated - Segment. fault ###" >> stdout
+echo "$segFault" >> stdout
+echo "Error = $error" >> stdout
+fi
+if [ "$glibcErr" != "" ] ; then
+error=1
+echo "* ########## Job not validated - *** glibc detected *** ###" >> stdout
+echo "$glibcErr" >> stdout
+echo "Error = $error" >> stdout
+fi
+# Only check all desired files have been merged properly.
+# Skip the validation by the analysis manager after the Terminate
+# since all the output files have not been registered at the
+# previous stage (like EventStat_temp.root or pyxsec_hists.root)
+# and the manager will complain about...
+if ! [ -f outputs_valid_merge ] ; then
+error=1
+echo "Output files were not validated by the analysis manager" >> stdout
+echo "Output files were not validated by the analysis manager" >> stderr
+fi
+if [ $error = 0 ] ; then
+echo "* ---------------- Job Validated ------------------*" >> stdout
+# echo "* === Logs std* will be deleted === "
+# rm -f std*
+fi
+echo "* ----------------------------------------------------*"
+echo "*******************************************************"
+cd -
+exit $error