]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGLF/FORWARD/analysis2/sim/FastSim.C
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / sim / FastSim.C
index 9e4a68a9464615cdced6545313e9fab78721e52b..9863b7f3031e672c93a3f09e1b2d53e0b85dde54 100644 (file)
@@ -28,6 +28,8 @@
 # include <TFile.h>
 # include <TProofOutputFile.h>
 # include <TCanvas.h>
+# include <TTimer.h>
+# include <TUrl.h>
 # include <fstream>
 #else
 class AliGenerator;
@@ -44,8 +46,26 @@ class TFile;
 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
@@ -58,26 +78,29 @@ struct FastMonitor : public TObject, public TQObject
    * 
    * @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);
@@ -89,9 +112,6 @@ struct FastMonitor : public TObject, public TQObject
     RegisterDraw(2, "b",      "", 0);
     RegisterDraw(3, "cent",   "", 0);
     RegisterDraw(4, "dNdeta", "", 0x8);
-
-
-    // divide the canvas 
   }
   /** 
    * Register a draw of a an object 
@@ -126,7 +146,6 @@ struct FastMonitor : public TObject, public TQObject
     if (flags & 0x2) p->SetLogy();
     if (flags & 0x4) p->SetLogz();
     if (flags & 0x8) p->SetBit(BIT(15));
-    
   }
   /** 
    * Desctructor 
@@ -184,6 +203,12 @@ struct FastMonitor : public TObject, public TQObject
       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())) {
@@ -194,30 +219,50 @@ struct FastMonitor : public TObject, public TQObject
 
       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);
 };
 
@@ -239,13 +284,17 @@ struct FastSim : public TSelector
   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),
@@ -270,7 +319,28 @@ struct FastSim : public TSelector
     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;
       }
     }
@@ -280,6 +350,8 @@ struct FastSim : public TSelector
       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 
    * 
@@ -306,7 +378,7 @@ struct FastSim : public TSelector
     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);
@@ -323,6 +395,11 @@ struct FastSim : public TSelector
     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;
@@ -441,10 +518,14 @@ struct FastSim : public TSelector
       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;
@@ -456,12 +537,13 @@ struct FastSim : public TSelector
    * 
    * @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");
@@ -566,11 +648,12 @@ struct FastSim : public TSelector
     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);
@@ -610,8 +693,8 @@ struct FastSim : public TSelector
       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();
     }
@@ -633,16 +716,56 @@ struct FastSim : public TSelector
        }
       }
       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) {
@@ -650,48 +773,75 @@ struct FastSim : public TSelector
       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() &&
@@ -702,7 +852,9 @@ struct FastSim : public TSelector
       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;
@@ -804,8 +956,6 @@ struct FastSim : public TSelector
     fGenerator->Write();
     fRunLoader->Write();
 
-    Info("SlaveTerminate", "fFile=%p fProofFile=%p", fFile, fProofFile);
-
     if (fFile) {
       if (fProofFile) {
        fOutput->Add(fProofFile);
@@ -825,6 +975,8 @@ struct FastSim : public TSelector
    */
   void Terminate()
   {
+    if (gProof) gProof->ClearFeedback();
+    
     if (!fList)
       fList = static_cast<TList*>(fOutput->FindObject("histograms"));
     if (!fList) {
@@ -838,11 +990,8 @@ struct FastSim : public TSelector
       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");
     
@@ -900,7 +1049,10 @@ struct FastSim : public TSelector
   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
   /* @} */
   /** 
    * @{ 
@@ -944,7 +1096,8 @@ struct FastSim : public TSelector
   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;
@@ -956,38 +1109,56 @@ struct FastSim : public TSelector
   } 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;
@@ -1018,26 +1189,31 @@ struct FastSim : public TSelector
                        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)");
@@ -1057,12 +1233,132 @@ struct FastSim : public TSelector
     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); 
 };