+ /**
+ * 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;
+ }
+