# include <TFile.h>
# include <TProofOutputFile.h>
# include <TCanvas.h>
+# include <TTimer.h>
+# include <TUrl.h>
# include <fstream>
#else
class AliGenerator;
class TProofOutputFile;
class TCanvas;
class TVirtualPad;
+class TTimer;
+class TUrl;
#endif
+/** To get DPMJEt common block */
+typedef struct {
+ Double_t rproj;
+ Double_t rtarg;
+ Double_t bimpac;
+ Int_t nwtsam;
+ Int_t nwasam;
+ Int_t nwbsam;
+ Int_t nwtacc;
+ Int_t nwtaac;
+ Int_t nwtbac;
+ Int_t ncp;
+ Int_t nct;
+} DtglcpCommon;
+DtglcpCommon* _dtglcp = 0;
+
//====================================================================
/**
* Monitor output objects
*
* @return
*/
- FastMonitor()
- : fName(""),
- fCanvas(0)
+ FastMonitor(TSelector* s=0)
+ : fName("FastMonitor"),
+ fCanvas(0),
+ fSelector(s)
{
- if (!gProof) return;
-
- fName = gProof->GetSessionTag();
- gDirectory->Add(this);
- Bool_t ret = gProof->Connect("Feedback(TList *objs)", "FastMonitor", this,
- "Feedback(TList *objs)");
- if (!ret) {
- Warning("FastMonitor", "Failed to connect to Proof");
- return;
- }
if (gROOT->IsBatch()) {
Warning("FastMonitor", "Batch processing, no monitoring");
return;
}
-
+ if (gProof) {
+ fName = gProof->GetSessionTag();
+ gDirectory->Add(this);
+ Bool_t ret = gProof->Connect("Feedback(TList *objs)",
+ "FastMonitor", this,
+ "Feedback(TList *objs)");
+ if (!ret) {
+ Warning("FastMonitor", "Failed to connect to Proof");
+ return;
+ }
+ }
+ else if (!s) return;
+
fCanvas = new TCanvas(fName, Form("Monitor %s", fName.Data()), 1000, 800);
fCanvas->SetFillColor(0);
fCanvas->SetFillStyle(0);
RegisterDraw(2, "b", "", 0);
RegisterDraw(3, "cent", "", 0);
RegisterDraw(4, "dNdeta", "", 0x8);
-
-
- // divide the canvas
}
/**
* Register a draw of a an object
if (flags & 0x2) p->SetLogy();
if (flags & 0x4) p->SetLogz();
if (flags & 0x8) p->SetBit(BIT(15));
-
}
/**
* Desctructor
return;
}
Int_t nEvents = 1;
+ TObject* oIpz = l->FindObject("ipZ");
+ if (oIpz && oIpz->IsA()->InheritsFrom(TH1::Class()))
+ nEvents = static_cast<TH1*>(oIpz)->GetEntries();
+ else
+ Warning("Feedback", "Histogram ipZ not found");
+
TIter next(l);
TObject* o = 0;
while ((o = next())) {
p->cd();
if (o->IsA()->InheritsFrom(TH1::Class())) {
- TH1* h = static_cast<TH1*>(o);
- TString n(o->GetName());
- if (n == "type") nEvents = h->GetEntries();
-
+ TH1* h = static_cast<TH1*>(o);
TH1* c = h->DrawCopy(p->GetTitle());
c->SetDirectory(0);
+ c->SetBit(TObject::kCanDelete);
if (p->TestBit(BIT(15))) {
- Info("Feedback", "Scaling %s by 1./%d and width",
- n.Data(), nEvents);
+ // Info("Feedback", "Scaling %s by 1./%d and width",
+ // c->GetName(), nEvents);
c->Scale(1./nEvents, "width");
}
}
- else
- o->DrawClone(p->GetTitle());
+ else {
+ TObject* c = o->DrawClone(p->GetTitle());
+ c->SetBit(TObject::kCanDelete);
+ }
p->Modified();
}
fCanvas->Modified();
fCanvas->Update();
fCanvas->cd();
}
+ /**
+ * Function to handle connect signals
+ *
+ */
+ void Handle()
+ {
+ HandleTimer(0);
+ }
+ /**
+ * Function to handle timer events
+ */
+ Bool_t HandleTimer(TTimer*)
+ {
+ Info("HandleTimer", "Selector=%p", fSelector);
+ if (!fSelector) return false;
+ Feedback(fSelector->GetOutputList());
+ return true;
+ }
/** Our name */
TString fName;
/** Our canvas */
- TCanvas* fCanvas;
+ TCanvas* fCanvas;
+ /** Possibly link to selector */
+ TSelector* fSelector;
ClassDef(FastMonitor,1);
};
FastSim(const char* eg="",
ULong_t runNo=0,
Double_t bMin=0,
- Double_t bMax=20)
+ Double_t bMax=20,
+ Long64_t nEvents=0)
: TSelector(),
fEGName(eg),
fRunNo(runNo),
fBMin(bMin),
fBMax(bMax),
fGRP(0),
+ fNEvents(nEvents),
+ fIsTgtA(false),
+ fIsProjA(false),
fGenerator(0),
fRunLoader(0),
fStack(0),
if (fn.IsNull()) {
if (!fFileName.IsNull()) fn = fFileName;
else {
- fn = Form("%s_%09d.root", fEGName.Data(), fRunNo);
+ const char* egName = (fGenerator ?
+ fGenerator->GetName() :
+ fEGName.Data());
+ fn = Form("%s_%09d", egName, fRunNo);
+ if (fGenerator) {
+ TString tgt, proj;
+ Int_t tgtA, tgtZ, projA, projZ;
+ fGenerator->GetTarget(tgt, tgtA, tgtZ);
+ fGenerator->GetProjectile(proj, projA, projZ);
+ fn.Append(Form("_%s%s", tgt.Data(), proj.Data()));
+ fn.Append(Form("_%05d", Int_t(fGenerator->GetEnergyCMS())));
+ }
+
+ if (fNEvents > 0) {
+ if (fNEvents >= 1000000)
+ fn.Append(Form("_%lldM", fNEvents/1000000));
+ else if (fNEvents >= 1000)
+ fn.Append(Form("_%lldk", fNEvents/1000));
+ else
+ fn.Append(Form("_%lld", fNEvents));
+ }
+ fn.Append(".root");
fFileName = fn;
}
}
fFileName = Form("%s_%09d.root", fEGName.Data(), fRunNo);
return fFileName.Data();*/
}
+ const char* GetName() const { return "FastSim"; }
+ const char* GetTitle() const { return "ALICE Event Generator simulation"; }
/**
* Create our outputs
*
fTree = new TTree("T", "T");
fParticles = new TClonesArray("TParticle");
fTree->Branch("header", &fShortHead,
- "run/i:event:npart:nbin:type:ipx/D:ipy:ipz:b:c:phir");
+ "run/i:event:ntgt:nproj:nbin:type:ipx/D:ipy:ipz:b:c:phir");
fTree->Branch("particles", &fParticles);
fTree->AutoSave();
fTree->SetDirectory(fFile);
fTree->SetAlias("pion", "(abs(particles.fPdgCode)==211)");
fTree->SetAlias("kaon", "(abs(particles.fPdgCode)==321)");
fTree->SetAlias("proton", "(abs(particles.fPdgCode)==2212)");
+ fTree->SetAlias("electron","(abs(particles.fPdgCode)==11)");
+ fTree->SetAlias("other", "(!pion&&!kaon&&!proton&&!electron)");
+ fTree->SetAlias("beta", "(particles.P()/particle.Energy())");
+ fTree->SetAlias("gamma", "(1./sqrt(1-beta*beta))");
+ fTree->SetAlias("npart", "(header.ntgt+header.nproj)");
Info("SetupOutput", "Making histograms");
Double_t maxEta = 10;
return false;
}
fGenerator = reinterpret_cast<AliGenerator*>(egPtr);
+ TString tgt, proj;
+ Int_t tgtA=0, tgtZ=0, projA=0, projZ=0;
+ fGenerator->GetTarget(tgt, tgtA, tgtZ);
+ fGenerator->GetProjectile(proj, projA, projZ);
+ fIsTgtA = (tgtA == tgtZ && tgtA == 1);
+ fIsProjA = (projA == projZ && projZ == 1);
-
- if (fFileName.IsNull())
- fFileName = Form("%s_%09d.root", fGenerator->GetName(), fRunNo);
+ if (fFileName.IsNull()) FileName();
Info("SetupRun", "File name is '%s'", fFileName.Data());
return true;
*
* @return true on success
*/
- Bool_t SetupRun(UInt_t nev=0xFFFFFFF)
+ Bool_t SetupRun()
{
// --- gAlice (bare ROOT) ----------------------------------------
if (!gAlice)
new AliRun("gAlice", "The ALICE Off-line framework");
+ Long64_t nev = (fNEvents <= 0 ? 0xFFFFFFFF : fNEvents);
// --- Run-loader, stack, etc -----------------------------------
Info("SetupRun", "Set-up run Loader");
fRunLoader = AliRunLoader::Open("galice.root", "FASTRUN", "RECREATE");
fShortHead.fIpX = 1024;
fShortHead.fIpY = 1024;
fShortHead.fIpZ = 1024;
- fShortHead.fNpart = -1;
+ fShortHead.fNtgt = -1;
+ fShortHead.fNproj = -1;
fShortHead.fNbin = -1;
fShortHead.fPhiR = -1;
- fShortHead.fB = 1024;
- fShortHead.fC = -1;
+ fShortHead.fB = -1;
+ fShortHead.fC = -1;
fParticles->Clear();
// --- Reset header, etc. ---------------------------------------
fHeader->Reset(fRunNo, iEv);
dynamic_cast<AliGenHerwigEventHeader*>(genHeader);
if (geometry) {
fShortHead.fB = geometry->ImpactParameter();
- fShortHead.fNpart = (geometry->ProjectileParticipants() +
- geometry->TargetParticipants());
+ fShortHead.fNtgt = geometry->TargetParticipants();
+ fShortHead.fNproj = geometry->ProjectileParticipants();
fShortHead.fNbin = geometry->NN();
fShortHead.fPhiR = geometry->ReactionPlaneAngle();
}
}
}
fShortHead.fB = pythia->GetImpactParameter();
- fShortHead.fNpart = 2;
+ fShortHead.fNtgt = 1;
+ fShortHead.fNproj = 1;
fShortHead.fNbin = 1;
}
if (dpm) {
Int_t type = dpm->ProcessType();
+#ifndef NO_DPMJET_TYPE
switch (type) {
case 5: case 6: sd = true;
-
case 7: dd = true;
+ }
+#else
+ static bool first = true;
+
+ if (first) {
+ Func_t add = gSystem->DynFindSymbol("*", "dtglcp_");
+ if (!add)
+ Warning("", "Didn't find dtglcp_");
+ else
+ _dtglcp = (DtglcpCommon*)add;
+ }
+ // The below - or rather a different implementation with some
+ // errors - was proposed by Cvetan - I don't think it's right
+ // though. See also
+ //
+ // https://cern.ch/twiki/pub/ALICE/PAPaperCentrality/normalization.pdf
+ // https://cern.ch/twiki/bin/view/ALICE/PAMCProductionStudies
+ //
+ Int_t nsd1=0, nsd2=0, ndd=0;
+ Int_t npP = dpm->ProjectileParticipants();
+ Int_t npT = dpm->TargetParticipants();
+ // Get the numbeer of single and double diffractive participants
+ dpm->GetNDiffractive(nsd1,nsd2,ndd);
+ // Check if all partipants are single/double diffractive
+ if ((ndd == 0) && ((npP == nsd1) || (npT == nsd2))) sd = true;
+ else if (ndd == (npP + npT)) dd = true;
+ Int_t ncp = dpm->NN();
+ Int_t nct = dpm->NNw();
+ Int_t nwp = dpm->NwN();
+ Int_t nwt = dpm->NwNw();
+ Int_t nwtacc = _dtglcp->nwtacc;
+ Int_t nwtsam = _dtglcp->nwtsam;
+ if (first) {
+ Printf("@ Npp sd1 Npt sd2 dd tpe Ncp Nct Nwp Nwt acc sam");
+ first = false;
}
+ Printf("@ %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d",
+ npP, nsd1, npT, nsd2, ndd, type, ncp, nct, nwp, nwt,
+ nwtacc, nwtsam);
+#endif
}
if (gev) fShortHead.fPhiR = gev->GetEventPlane();
if (herwig) {
switch (type) {
case 5: case 6: sd = true; break;
}
- fShortHead.fNpart = 2;
+ fShortHead.fNtgt = 1;
+ fShortHead.fNproj = 1;
fShortHead.fNbin = 1;
}
fShortHead.fType = (sd ? 0x1 : 0) | (dd ? 0x2 : 0);
// --- Check centrality -----------------------------------------
- // PbPb only
- // Updated 4th of November 2014 from
- // cern.ch/twiki/bin/view/ALICE/CentStudies#Tables_with_centrality_bins_AN1
- Float_t np = 0;
- UInt_t nc = 0;
- Double_t c = 0;
+ Float_t np = -1;
+ Float_t nc = -1;
+ Double_t c = -1;
Double_t b = fShortHead.fB;
- if (0.00 >= b && b < 1.57) { c=0.5; np=403.8; nc=1861; }
- else if (1.57 >= b && b < 2.22) { c=1.5; np=393.6; nc=1766; }
- else if (2.22 >= b && b < 2.71) { c=2.5; np=382.9; nc=1678; }
- else if (2.71 >= b && b < 3.13) { c=3.5; np=372; nc=1597; }
- else if (3.13 >= b && b < 3.50) { c=4.5; np=361.1; nc=1520; }
- else if (3.50 >= b && b < 4.94) { c=7.5; np=329.4; nc=1316; }
- else if (4.94 >= b && b < 6.05) { c=12.5; np=281.2; nc=1032; }
- else if (6.05 >= b && b < 6.98) { c=17.5; np=239; nc=809.8; }
- else if (6.98 >= b && b < 7.81) { c=22.5; np=202.1; nc=629.6; }
- else if (7.81 >= b && b < 8.55) { c=27.5; np=169.5; nc=483.7; }
- else if (8.55 >= b && b < 9.23) { c=32.5; np=141; nc=366.7; }
- else if (9.23 >= b && b < 9.88) { c=37.5; np=116; nc=273.4; }
- else if (9.88 >= b && b < 10.47) { c=42.5; np=94.11; nc=199.4; }
- else if (10.47 >= b && b < 11.04) { c=47.5; np=75.3; nc=143.1; }
- else if (11.04 >= b && b < 11.58) { c=52.5; np=59.24; nc=100.1; }
- else if (11.58 >= b && b < 12.09) { c=57.5; np=45.58; nc=68.46; }
- else if (12.09 >= b && b < 12.58) { c=62.5; np=34.33; nc=45.79; }
- else if (12.58 >= b && b < 13.05) { c=67.5; np=25.21; nc=29.92; }
- else if (13.05 >= b && b < 13.52) { c=72.5; np=17.96; nc=19.08; }
- else if (13.52 >= b && b < 13.97) { c=77.5; np=12.58; nc=12.07; }
- else if (13.97 >= b && b < 14.43) { c=82.5; np=8.812; nc=7.682; }
- else if (14.43 >= b && b < 14.96) { c=87.5; np=6.158; nc=4.904; }
- else if (14.96 >= b && b < 15.67) { c=92.5; np=4.376; nc=3.181; }
- else if (15.67 >= b && b < 20.00) { c=97.5; np=3.064; nc=1.994; }
- fShortHead.fC = c;
+ if (b >= 0 && fIsProjA && fIsTgtA &&
+ TMath::Abs(fGenerator->GetEnergyCMS()-2760) < 10) {
+ // PbPb @ 2.76TeV only
+ // Updated 4th of November 2014 from
+ // cern.ch/twiki/bin/view/ALICE/CentStudies
+ // #Tables_with_centrality_bins_AN1
+ if (0.00 >= b && b < 1.57) { c=0.5; np=403.8; nc=1861; }
+ else if (1.57 >= b && b < 2.22) { c=1.5; np=393.6; nc=1766; }
+ else if (2.22 >= b && b < 2.71) { c=2.5; np=382.9; nc=1678; }
+ else if (2.71 >= b && b < 3.13) { c=3.5; np=372; nc=1597; }
+ else if (3.13 >= b && b < 3.50) { c=4.5; np=361.1; nc=1520; }
+ else if (3.50 >= b && b < 4.94) { c=7.5; np=329.4; nc=1316; }
+ else if (4.94 >= b && b < 6.05) { c=12.5; np=281.2; nc=1032; }
+ else if (6.05 >= b && b < 6.98) { c=17.5; np=239; nc=809.8; }
+ else if (6.98 >= b && b < 7.81) { c=22.5; np=202.1; nc=629.6; }
+ else if (7.81 >= b && b < 8.55) { c=27.5; np=169.5; nc=483.7; }
+ else if (8.55 >= b && b < 9.23) { c=32.5; np=141; nc=366.7; }
+ else if (9.23 >= b && b < 9.88) { c=37.5; np=116; nc=273.4; }
+ else if (9.88 >= b && b < 10.47) { c=42.5; np=94.11; nc=199.4; }
+ else if (10.47 >= b && b < 11.04) { c=47.5; np=75.3; nc=143.1; }
+ else if (11.04 >= b && b < 11.58) { c=52.5; np=59.24; nc=100.1; }
+ else if (11.58 >= b && b < 12.09) { c=57.5; np=45.58; nc=68.46; }
+ else if (12.09 >= b && b < 12.58) { c=62.5; np=34.33; nc=45.79; }
+ else if (12.58 >= b && b < 13.05) { c=67.5; np=25.21; nc=29.92; }
+ else if (13.05 >= b && b < 13.52) { c=72.5; np=17.96; nc=19.08; }
+ else if (13.52 >= b && b < 13.97) { c=77.5; np=12.58; nc=12.07; }
+ else if (13.97 >= b && b < 14.43) { c=82.5; np=8.812; nc=7.682; }
+ else if (14.43 >= b && b < 14.96) { c=87.5; np=6.158; nc=4.904; }
+ else if (14.96 >= b && b < 15.67) { c=92.5; np=4.376; nc=3.181; }
+ else if (15.67 >= b && b < 20.00) { c=97.5; np=3.064; nc=1.994; }
+ }
+ else if (b >= 0 && (fIsTgtA || fIsProjA) &&
+ TMath::Abs(fGenerator->GetEnergyCMS()-5023) < 10) {
+ // pPb/Pbp @ 5.02TeV
+ // From Glauber
+ // cern.ch/twiki/bin/viewauth/ALICE/PACentStudies
+ // #Ncoll_in_centrality_bins_from_CL
+ Double_t ac[] = { 2.5, 7.5, 15., 30., 50., 70., 90. };
+ Double_t ab[] = { 100., 14.4, 13.8, 12.7, 10.2, 6.30, 3.10, 1.44, 0 };
+ for (Int_t i = 0; i < 7; i++) {
+ Double_t bC = ab[i+1];
+ Double_t bH = bC + (ab[i] - bC) / 2;
+ Double_t bL = bC - (bC - ab[i+2]) / 2;
+ if (b >= bL && b < bH) {
+ c = ac[i];
+ break;
+ }
+ }
+ }
+ if (c >= 0) fShortHead.fC = c;
+ Double_t nb = nc/2;
// Be careful to round off
- if (fShortHead.fNpart <= 0) fShortHead.fNpart = Int_t(np+.5);
- if (fShortHead.fNbin <= 0) fShortHead.fNbin = Int_t(nc+.5)/2;
-
+ if ((fShortHead.fNtgt+fShortHead.fNproj) <= 0 && np >= 0) {
+ fShortHead.fNtgt = Int_t(np-nb+.5);
+ fShortHead.fNproj = Int_t(nb+.5);
+ }
+ if (fShortHead.fNbin <= 0 && nb >= 0)
+ fShortHead.fNbin = Int_t(nb+.5);
// --- Check if within vertex cut -------------------------------
Bool_t selected = (fShortHead.fIpZ <= fHIpz->GetXaxis()->GetXmax() &&
fHPhiR->Fill(fShortHead.fPhiR*TMath::RadToDeg());
fHB->Fill(fShortHead.fB);
fHIpz->Fill(fShortHead.fIpZ);
- fHType->Fill(dd ? 3 : sd ? 2 : 1);
+ if (dd) fHType->Fill(3);
+ if (sd) fHType->Fill(2);
+ if (!dd && !sd) fHType->Fill(1);
fHCent->Fill(c);
}
return selected;
fGenerator->Write();
fRunLoader->Write();
- Info("SlaveTerminate", "fFile=%p fProofFile=%p", fFile, fProofFile);
-
if (fFile) {
if (fProofFile) {
fOutput->Add(fProofFile);
*/
void Terminate()
{
+ if (gProof) gProof->ClearFeedback();
+
if (!fList)
fList = static_cast<TList*>(fOutput->FindObject("histograms"));
if (!fList) {
fProofFile =
static_cast<TProofOutputFile*>(fOutput->FindObject(FileName()));
}
- if (fProofFile) {
- Info("Terminate", "Got a Proof file %s/%s",
- fProofFile->GetFileName(), fProofFile->GetOutputFileName());
+ if (fProofFile)
fFile = fProofFile->OpenFile("UPDATE");
- }
if (!fFile)
fFile = TFile::Open(FileName(),"UPDATE");
Int_t fRunNo; // Run to simulate
Double_t fBMin; // Least impact parameter
Double_t fBMax; // Largest impact parameter
- TObject* fGRP; //! GRP in one line
+ TObject* fGRP; //! GRP in one line
+ Long64_t fNEvents; // Number of requested events
+ Bool_t fIsTgtA; //! True if target beam is nuclei
+ Bool_t fIsProjA; //! True if projectile beam is nuclei
/* @} */
/**
* @{
struct ShortHeader {
UInt_t fRunNo;
UInt_t fEventId;
- UInt_t fNpart;
+ UInt_t fNtgt;
+ UInt_t fNproj;
UInt_t fNbin;
UInt_t fType;
Double_t fIpX;
} fShortHead;
#endif
/**
- * Run a job locally
+ * Run this selector as a normal process
*
- * @param nev Number of events
- * @param gen Event generator
+ * @param nev Number of events
+ * @param run Run number to anchor in
+ * @param gen Generator
+ * @param bMin Least impact parameter [fm]
+ * @param bMax Largest impact parameter [fm]
+ * @param monitor Monitor frequency [s]
*
- * @return
+ * @return true on succes
*/
- static Bool_t Run(Long64_t nev,
- UInt_t run,
- const char* gen,
- Double_t bMin,
- Double_t bMax,
- Int_t monitor)
+ static Bool_t LocalRun(Long64_t nev,
+ UInt_t run,
+ const TString& gen,
+ Double_t bMin,
+ Double_t bMax,
+ Int_t monitor)
{
- TStopwatch timer;
- timer.Start();
-
- FastSim* sim = new FastSim(gen,run,bMin,bMax);
+ FastSim* sim = new FastSim(gen,run,bMin,bMax,nev);
sim->Begin(0);
sim->SlaveBegin(0);
+ TTimer* timer = 0;
+ if (monitor > 0) {
+ // timer = new TTimer(new FastMonitor(sim), monitor*1000,true);
+ timer = new TTimer(1000);
+ timer->Connect("Timeout()","FastMonitor",
+ new FastMonitor(sim), "Handle()");
+ ::Info("Run", "Turning on monitoring");
+ timer->Start(-1,false);
+ }
+
for (Long64_t i=0; i <nev; i++) {
Printf("=== Event # %6lld/%6lld ==========================",
i+1, nev);
sim->Process(i);
+ if (timer && (i > 0) && (i % 500 == 0)) {
+ if (timer->CheckTimer(gSystem->Now()))
+ Printf("Fired timer");
+ }
}
+ if (timer) timer->TurnOff();
sim->SlaveTerminate();
sim->Terminate();
- timer.Print();
return true;
}
+ /**
+ * Load needed libraries in a proof serssion
+ */
static void ProofLoadLibs()
{
if (!gProof) return;
obj->GetName(), obj->GetTitle()));
}
}
-
- static Bool_t Proof(Long64_t nev,
- UInt_t run,
- const char* gen,
- Double_t bMin,
- Double_t bMax,
- Int_t monitor=-1,
- const char* opt="")
+ /**
+ * Run this selector in PROOF(Lite)
+ *
+ * @param url Proof URL
+ * @param nev Number of events
+ * @param run Run number to anchor in
+ * @param gen Generator
+ * @param bMin Least impact parameter [fm]
+ * @param bMax Largest impact parameter [fm]
+ * @param monitor Monitor frequency [s]
+ * @param opt Compilation options
+ *
+ * @return true on succes
+ */
+ static Bool_t ProofRun(const TUrl& url,
+ Long64_t nev,
+ UInt_t run,
+ const TString& gen,
+ Double_t bMin,
+ Double_t bMax,
+ Int_t monitor=-1,
+ const char* opt="")
{
- Printf("# events: %lld", nev);
- Printf("Run #: %u", run);
- Printf("Generator: %s", gen);
- Printf("b range: %5.1f-%5.1f", bMin, bMax);
- Printf("monitor: %ds", monitor);
-
- TStopwatch timer;
- timer.Start();
-
- TProof::Reset("lite:///?workers=8");
- TProof::Open("lite:///?workers=8");
+ TProof::Reset(url.GetUrl());
+ TProof::Open(url.GetUrl());
gProof->ClearCache();
TString ali = gSystem->ExpandPathName("$(ALICE_ROOT)");
else gProof->SetParameter("PROOF_FeedbackPeriod",
monitor*1000/*ms*/);
- FastSim* sim = new FastSim(gen,run,bMin,bMax);
+ FastSim* sim = new FastSim(gen,run,bMin,bMax,nev);
gProof->Process(sim, nev, "");
- timer.Print();
return true; // status >= 0;
}
+ /**
+ * Extract key value pair from string
+ *
+ * @param in Input string
+ * @param key On return, the key
+ * @param val On return, the value
+ * @param sep Separator between key an value
+ *
+ * @return false of separator isn't found in input
+ */
+ static Bool_t Str2KeyVal(const TString& in,
+ TString& key,
+ TString& val,
+ const char sep='=')
+ {
+ Int_t idx = in.Index(sep);
+ if (idx == kNPOS) return false;
+
+ key = in(0,idx);
+ val = in(idx+1, in.Length()-idx-1);
+ return true;
+ }
+ /**
+ * Run a simulation.
+ *
+ * @a url is the execution URL of the form
+ *
+ * @verbatim
+ PROTOCOL://[HOST[:PORT]]/[?OPTIONS]
+ @endverbatim
+ *
+ * Where PROTOCOL is one of
+ *
+ * - local for local (single thread) execution
+ * - lite for Proof-Lite execution
+ * - proof for Proof exection
+ *
+ * HOST and PORT is only relevant for Proof.
+ *
+ * Options is a list of & separated options
+ *
+ * - events=NEV Set the number of events to process
+ * - run=RUNNO Set the run number to anchor in
+ * - eg=NAME Set the event generator
+ * - b=RANGE Set the impact parameter range in fermi
+ * - monitor=SEC Set the update rate in seconds of monitor histograms
+ *
+ *
+ * @param url Exection URL
+ * @param opt Optimization used when compiling
+ *
+ * @return true on success
+ */
+ static Bool_t Run(const char* url, const char* opt="")
+ {
+ Long64_t nev = 10000;
+ UInt_t run = 0;
+ TString eg = "default";
+ Double_t bMin = 0;
+ Double_t bMax = 20;
+ Int_t monitor = -1;
+ TUrl u(url);
+ TString out;
+ TObjArray* opts = TString(u.GetOptions()).Tokenize("&");
+ TObjString* token = 0;
+ TIter nextToken(opts);
+ while ((token = static_cast<TObjString*>(nextToken()))) {
+ TString& str = token->String();
+ if (str.IsNull()) continue;
+
+ TString key, val;
+ if (!Str2KeyVal(str,key,val)) {
+ if (!out.IsNull()) out.Append("&");
+ out.Append(str);
+ continue;
+ }
+
+ if (key.EqualTo("events")) nev = val.Atoll();
+ else if (key.EqualTo("run")) run = val.Atoi();
+ else if (key.EqualTo("eg")) eg = val;
+ else if (key.EqualTo("monitor"))monitor = val.Atoi();
+ else if (key.EqualTo("b")) {
+ TString min, max;
+ if (Str2KeyVal(val, min, max, '-')) {
+ bMin = min.Atof();
+ bMax = max.Atof();
+ }
+ }
+ else {
+ if (!out.IsNull()) out.Append("&");
+ out.Append(str);
+ }
+ }
+ opts->Delete();
+ u.SetOptions(out);
+ if (!u.IsValid()) {
+ Printf("Error: FastSim::Run: URL %s is invalid", u.GetUrl());
+ return false;
+ }
+
+ Bool_t isLocal = TString(u.GetProtocol()).EqualTo("local");
+
+ Printf("Run %s for %lld events anchored at %d\n"
+ " Impact paramter range: %5.1f-%5.1f fm\n"
+ " Monitor frequency: %d sec\n"
+ " Execution url: %s",
+ eg.Data(), nev, run, bMin, bMax, monitor, u.GetUrl());
+
+ TStopwatch timer;
+ timer.Start();
+
+ Bool_t ret = false;
+ if (isLocal)
+ ret = LocalRun(nev, run, eg, bMin, bMax, monitor);
+ else
+ ret = ProofRun(u, nev, run, eg, bMin, bMax, monitor, opt);
+ timer.Print();
+
+ return ret;
+ }
+
ClassDef(FastSim,1);
};