diff --git a/docker/rivet-herwig/Dockerfile b/docker/rivet-herwig/Dockerfile --- a/docker/rivet-herwig/Dockerfile +++ b/docker/rivet-herwig/Dockerfile @@ -1,31 +1,38 @@ -FROM hepstore/rivet:2.7.2 +FROM hepstore/rivet:3.0.1 MAINTAINER Andy Buckley RUN dnf install -y boost-devel RUN mkdir /code && cd /code \ && wget https://www.hepforge.org/archive/lhapdf/LHAPDF-6.2.3.tar.gz -O- | tar xz \ && cd LHAPDF-*/ && ./configure --prefix=/usr/local \ && make -j5 && make install \ && cd ../.. && rm -rf /code RUN lhapdf install MMHT2014{,n}lo68cl # RUN cd /usr/local/share/LHAPDF/ && \ # for pdf in MMHT2014{,n}lo68cl; do \ # wget https://lhapdf.hepforge.org/downloads?f=pdfsets/current/$pdf.tar.gz -O- | tar xz; \ # done +RUN dnf install -y mercurial libtool + RUN mkdir /code && cd /code \ && wget https://www.hepforge.org/archive/thepeg/ThePEG-2.1.5.tar.bz2 -O- | tar xj \ - && cd ThePEG-*/ && ./configure --enable-shared --{prefix,with-{fastjet,hepmc,lhapdf,rivet}}=/usr/local \ + && cd ThePEG-*/ && ./configure --enable-shared --{prefix,with-{fastjet,hepmc,lhapdf}}=/usr/local \ && make -j5 && make install \ && cd ../.. && rm -rf /code +#&& hg clone https://phab.hepforge.org/source/thepeghg ThePEG-hg -b release-2-1 -r 15cd9c8ceac1 \ +#&& (cd ThePEG-*/ && hg up 15cd9c8ceac1 && autoreconf -i) \ +#&& cd ThePEG-*/ && ./configure --enable-shared --{prefix,with-{fastjet,hepmc,lhapdf,rivet}}=/usr/local \ + + RUN mkdir /code && cd /code \ && wget https://www.hepforge.org/archive/herwig/Herwig-7.1.5.tar.bz2 -O- | tar xj \ && cd Herwig-*/ \ && ./configure --{prefix,with-{thepeg,fastjet}}=/usr/local \ && make -j5 && make install \ && cd ../.. && rm -rf /code WORKDIR /work diff --git a/docker/rivet-pythia/Dockerfile b/docker/rivet-pythia/Dockerfile --- a/docker/rivet-pythia/Dockerfile +++ b/docker/rivet-pythia/Dockerfile @@ -1,25 +1,25 @@ -FROM hepstore/rivet:3.0.0 +FROM hepstore/rivet:3.0.1 MAINTAINER Andy Buckley RUN dnf install -y rsync RUN mkdir /code && cd /code \ && wget https://www.hepforge.org/archive/lhapdf/LHAPDF-6.2.3.tar.gz -O- | tar xz \ && cd LHAPDF-*/ && ./configure --prefix=/usr/local \ && make -j5 && make install \ && cd ../.. && rm -r /code RUN mkdir /code && cd /code \ - && wget http://home.thep.lu.se/~torbjorn/pythia8/pythia8240.tgz -O- | tar xz \ + && wget http://home.thep.lu.se/~torbjorn/pythia8/pythia8243.tgz -O- | tar xz \ && cd pythia*/ && ./configure --enable-shared --{prefix,with-{hepmc2,lhapdf6}}=/usr/local \ && make -j5 && make install \ && cd ../.. && rm -r /code RUN mkdir /code && cd /code \ && wget https://agile.hepforge.org/downloads/?f=Sacrifice-1.1.2.tar.gz -O- | tar xz \ && cd Sacrifice-*/ \ && ./configure --{prefix,with-{pythia,hepmc,LHAPDF}}=/usr/local \ && make -j5 && make install \ && cd ../.. && rm -r /code WORKDIR /work diff --git a/docker/rivet-sherpa/Dockerfile b/docker/rivet-sherpa/Dockerfile --- a/docker/rivet-sherpa/Dockerfile +++ b/docker/rivet-sherpa/Dockerfile @@ -1,25 +1,44 @@ -FROM hepstore/rivet:2.7.1 +FROM hepstore/rivet:3.0.1 MAINTAINER Andy Buckley -RUN dnf install -y rsync - RUN mkdir /code && cd /code \ - && wget https://www.hepforge.org/archive/lhapdf/LHAPDF-6.2.1.tar.gz -O- | tar xz \ + && wget https://www.hepforge.org/archive/lhapdf/LHAPDF-6.2.3.tar.gz -O- | tar xz \ && cd LHAPDF-*/ && ./configure --prefix=/usr/local \ && make -j5 && make install \ && cd ../.. && rm -r /code -RUN mkdir /code && cd /code \ - && wget http://home.thep.lu.se/~torbjorn/pythia8/pythia8240.tgz -O- | tar xz \ - && cd pythia*/ && ./configure --enable-shared --{prefix,with-{hepmc2,lhapdf6}}=/usr/local \ - && make -j5 && make install \ - && cd ../.. && rm -r /code +RUN dnf install -y rsync git pypy \ + && cd /usr/local \ + && git clone https://gitlab.com/openloops/OpenLoops.git \ + && cd OpenLoops && ./scons \ + && ./openloops libinstall ppll pptt + +RUN dnf install -y libtool texinfo sqlite-devel swig pypy openmpi openmpi-devel +ENV PATH="${PATH}:/usr/lib64/openmpi/bin" RUN mkdir /code && cd /code \ - && wget https://agile.hepforge.org/downloads/?f=Sacrifice-1.1.2.tar.gz -O- | tar xz \ - && cd Sacrifice-*/ \ - && ./configure --{prefix,with-{pythia,hepmc,LHAPDF}}=/usr/local \ - && make -j5 && make install \ + && git clone -b rel-2-2-7 https://gitlab.com/sherpa-team/sherpa.git && cd sherpa && autoreconf -fi \ + && ./configure --prefix=/usr/local \ + --enable-lhapdf=/usr/local --enable-fastjet=/usr/local \ + --enable-hepmc2=/usr/local --enable-openloops=/usr/local/OpenLoops \ + --enable-pyext --enable-gzip --enable-analysis \ + --enable-mpi CC=mpicc CXX=mpic++ \ + && make -j1 CXXFLAGS="-O2 -std=c++11" AM_CXXFLAGS="-O2 -std=c++11" \ + && make install \ + && mkdir /usr/local/Sherpa \ + && mv Examples /usr/local/Sherpa \ && cd ../.. && rm -r /code +# wget https://sherpa.hepforge.org/downloads/?f=SHERPA-MC-2.2.7.tar.gz -O - | tar xf && cd SHERPA-MC-2.2.7 + +# RUN apt-get update; \ +# apt-get -q -y --no-install-recommends install pypy; \ +# apt autoremove; apt-get autoclean; \ +# rm -rf /var/lib/apt/lists /var/cache/apt; \ +# rm -rf $(find / -name doc 2>&1 | grep -v Permission) + +# RUN echo "export PATH=/usr/local/bin:\$PATH\n\ +# export LD_LIBRARY_PATH=/usr/local/lib:\$LD_LIBRARY_PATH\n\ +# . /usr/local/rivetenv.sh\n\ +# if [ "\$PS1" ]; then PS1='\\h:\\w\\$ '; fi" > /etc/bash.bashrc WORKDIR /work diff --git a/docker/rivet-tutorial/Dockerfile b/docker/rivet-tutorial/Dockerfile --- a/docker/rivet-tutorial/Dockerfile +++ b/docker/rivet-tutorial/Dockerfile @@ -1,9 +1,9 @@ -FROM hepstore/rivet-pythia:3.0.0-8240 +FROM hepstore/rivet-pythia:3.0.1-8243 MAINTAINER Andy Buckley CMD /bin/bash WORKDIR /work ADD . /work RUN rm /work/Dockerfile diff --git a/docker/rivet/Dockerfile b/docker/rivet/Dockerfile --- a/docker/rivet/Dockerfile +++ b/docker/rivet/Dockerfile @@ -1,26 +1,26 @@ -FROM fedora:27 +FROM fedora:30 LABEL maintainer="rivet@projects.hepforge.org" RUN dnf update -y \ && dnf install -y \ make gcc-c++ gcc-gfortran redhat-rpm-config \ wget tar less bzip2 findutils which nano zlib-devel \ python python-devel python-requests file python-matplotlib gsl-devel \ texlive-latex-bin texlive-texconfig-bin texlive-pst-tools \ ghostscript ImageMagick texlive-dvips texlive-relsize \ texlive-cm texlive-hyphen-base texlive-collection-fontsrecommended \ && dnf clean all RUN mkdir /code && cd /code \ - && wget https://phab.hepforge.org/source/rivetbootstraphg/browse/3.0.0/rivet-bootstrap?view=raw -O rivet-bootstrap \ + && wget https://phab.hepforge.org/source/rivetbootstraphg/browse/3.0.1/rivet-bootstrap?view=raw -O rivet-bootstrap \ && chmod +x rivet-bootstrap \ && INSTALL_PREFIX=/usr/local INSTALL_GSL=0 INSTALL_RIVETDEV=0 MAKE="make -j7" ./rivet-bootstrap \ && echo "source /usr/local/share/Rivet/rivet-completion" > /etc/profile.d/rivet-completion.sh \ && echo "source /usr/local/share/YODA/yoda-completion" > /etc/profile.d/yoda-completion.sh \ && texconfig rehash \ && rm -rf /code ENV LD_LIBRARY_PATH /usr/local/lib ENV PYTHONPATH /usr/local/lib64/python2.7/site-packages WORKDIR /work diff --git a/include/Rivet/AnalysisHandler.hh b/include/Rivet/AnalysisHandler.hh --- a/include/Rivet/AnalysisHandler.hh +++ b/include/Rivet/AnalysisHandler.hh @@ -1,370 +1,374 @@ // -*- C++ -*- #ifndef RIVET_RivetHandler_HH #define RIVET_RivetHandler_HH #include "Rivet/Config/RivetCommon.hh" #include "Rivet/Particle.hh" #include "Rivet/AnalysisLoader.hh" #include "Rivet/Tools/RivetYODA.hh" namespace Rivet { // Forward declaration and smart pointer for Analysis class Analysis; typedef std::shared_ptr AnaHandle; /// A class which handles a number of analysis objects to be applied to /// generated events. An {@link Analysis}' AnalysisHandler is also responsible /// for handling the final writing-out of histograms. class AnalysisHandler { public: /// @name Constructors and destructors. */ //@{ /// Preferred constructor, with optional run name. AnalysisHandler(const string& runname=""); /// @brief Destructor /// The destructor is not virtual, as this class should not be inherited from. ~AnalysisHandler(); //@} private: /// Get a logger object. Log& getLog() const; public: /// @name Run properties and weights //@{ /// Get the name of this run. string runName() const; /// Get the number of events seen. Should only really be used by external /// steering code or analyses in the finalize phase. size_t numEvents() const; /// @brief Access the sum of the event weights seen /// /// This is the weighted equivalent of the number of events. It should only /// be used by external steering code or analyses in the finalize phase. double sumW() const { return _eventCounter->sumW(); } /// Access to the sum of squared-weights double sumW2() const { return _eventCounter->sumW2(); } /// Names of event weight categories const vector& weightNames() const { return _weightNames; } /// Are any of the weights non-numeric? size_t numWeights() const { return _weightNames.size(); } /// Are any of the weights non-numeric? bool haveNamedWeights() const; /// Set the weight names from a GenEvent void setWeightNames(const GenEvent& ge); /// Get the index of the nominal weight-stream size_t defaultWeightIndex() const { return _defaultWeightIdx; } //@} /// @name Cross-sections //@{ - /// Get the cross-section known to the handler. + /// Get the cross-section known to the handler Scatter1DPtr crossSection() const { return _xs; } - /// Set the cross-section for the process being generated. + /// Set the cross-section for the process being generated void setCrossSection(pair xsec); + /// Set the cross-section for the process being generated (alternative signature) + void setCrossSection(double xsec, double xsecerr) { + setCrossSection({xsec, xsecerr}); + } /// Get the nominal cross-section double nominalCrossSection() const { _xs.get()->setActiveWeightIdx(_defaultWeightIdx); const YODA::Scatter1D::Points& ps = _xs->points(); if (ps.size() != 1) { string errMsg = "cross section missing when requesting nominal cross section"; throw Error(errMsg); } double xs = ps[0].x(); _xs.get()->unsetActiveWeight(); return xs; } //@} /// @name Beams //@{ /// Set the beam particles for this run AnalysisHandler& setRunBeams(const ParticlePair& beams) { _beams = beams; MSG_DEBUG("Setting run beams = " << beams << " @ " << sqrtS()/GeV << " GeV"); return *this; } /// Get the beam particles for this run, usually determined from the first event. const ParticlePair& beams() const { return _beams; } /// Get beam IDs for this run, usually determined from the first event. /// @deprecated Use standalone beamIds(ah.beams()), to clean AH interface PdgIdPair beamIds() const; /// Get energy for this run, usually determined from the first event. /// @deprecated Use standalone sqrtS(ah.beams()), to clean AH interface double sqrtS() const; /// Setter for _ignoreBeams void setIgnoreBeams(bool ignore=true); /// Setter for _skipWeights void skipMultiWeights(bool ignore=false); //@} /// @name Handle analyses //@{ /// Get a list of the currently registered analyses' names. std::vector analysisNames() const; /// Get the collection of currently registered analyses. const std::map& analysesMap() const { return _analyses; } /// Get the collection of currently registered analyses. std::vector analyses() const { std::vector rtn; rtn.reserve(_analyses.size()); for (const auto& apair : _analyses) rtn.push_back(apair.second); return rtn; } /// Get a registered analysis by name. AnaHandle analysis(const std::string& analysisname) { if ( _analyses.find(analysisname) == _analyses.end() ) throw LookupError("No analysis named '" + analysisname + "' registered in AnalysisHandler"); try { return _analyses[analysisname]; } catch (...) { throw LookupError("No analysis named '" + analysisname + "' registered in AnalysisHandler"); } } /// Add an analysis to the run list by object AnalysisHandler& addAnalysis(Analysis* analysis); /// @brief Add an analysis to the run list using its name. /// /// The actual Analysis to be used will be obtained via /// AnalysisLoader::getAnalysis(string). If no matching analysis is found, /// no analysis is added (i.e. the null pointer is checked and discarded. AnalysisHandler& addAnalysis(const std::string& analysisname); /// @brief Add an analysis with a map of analysis options. AnalysisHandler& addAnalysis(const std::string& analysisname, std::map pars); /// @brief Add analyses to the run list using their names. /// /// The actual {@link Analysis}' to be used will be obtained via /// AnalysisHandler::addAnalysis(string), which in turn uses /// AnalysisLoader::getAnalysis(string). If no matching analysis is found /// for a given name, no analysis is added, but also no error is thrown. AnalysisHandler& addAnalyses(const std::vector& analysisnames); /// Remove an analysis from the run list using its name. AnalysisHandler& removeAnalysis(const std::string& analysisname); /// Remove analyses from the run list using their names. AnalysisHandler& removeAnalyses(const std::vector& analysisnames); - /// + /// //@} /// @name Main init/execute/finalise //@{ /// Initialize a run, with the run beams taken from the example event. void init(const GenEvent& event); /// @brief Analyze the given \a event by reference. /// /// This function will call the AnalysisBase::analyze() function of all /// included analysis objects. void analyze(const GenEvent& event); /// @brief Analyze the given \a event by pointer. /// /// This function will call the AnalysisBase::analyze() function of all /// included analysis objects, after checking the event pointer validity. void analyze(const GenEvent* event); - + /// Finalize a run. This function calls the AnalysisBase::finalize() /// functions of all included analysis objects. void finalize(); //@} /// @name Histogram / data object access //@{ /// After all subevents in an event group has been processed push /// all histo fills to the relevant histograms. void pushToPersistent(); /// Read analysis plots into the histo collection (via addData) from the named file. void readData(const std::string& filename); /// Get all multi-weight Rivet analysis object wrappers vector getRivetAOs() const; /// Get a pointer to a preloaded yoda object with the given path, /// or null if path is not found. const YODA::AnalysisObjectPtr getPreload(string path) const { auto it = _preloads.find(path); if ( it == _preloads.end() ) return nullptr; return it->second; } /// Write all analyses' plots (via getData) to the named file. void writeData(const std::string& filename) const; /// Tell Rivet to dump intermediate result to a file named @a /// dumpfile every @a period'th event. If @period is not positive, /// no dumping will be done. void dump(string dumpfile, int period) { _dumpPeriod = period; _dumpFile = dumpfile; } /// Take the vector of yoda files and merge them together using /// the cross section and weight information provided in each /// file. Each file in @a aofiles is assumed to have been produced /// by Rivet. By default the files are assumed to contain /// different processes (or the same processs but mutually /// exclusive cuts), but if @a equiv if ture, the files are /// assumed to contain output of completely equivalent (but /// statistically independent) Rivet runs. The corresponding /// analyses will be loaded and their analysis objects will be /// filled with the merged result. finalize() will be run on each /// relevant analysis. The resulting YODA file can then be rwitten /// out by writeData(). If delopts is non-empty, it is assumed to /// contain names different options to be merged into the same /// analysis objects. void mergeYodas(const vector & aofiles, const vector & delopts = vector(), bool equiv = false); /// Helper function to strip specific options from data object paths. void stripOptions(YODA::AnalysisObjectPtr ao, const vector & delopts) const; //@} /// Indicate which Rivet stage we're in. /// At the moment, only INIT is used to enable booking. enum class Stage { OTHER, INIT, FINALIZE }; /// Which stage are we in? Stage stage() const { return _stage; } private: /// Current handler stage Stage _stage = Stage::OTHER; /// The collection of Analysis objects to be used. std::map _analyses; /// A vector of pre-loaded object which do not have a valid /// Analysis plugged in. map _preloads; /// A vector containing copies of analysis objects after /// finalize() has been run. vector _finalizedAOs; /// @name Run properties //@{ /// Weight names std::vector _weightNames; std::vector > _subEventWeights; size_t _numWeightTypes; // always == WeightVector.size() /// Run name std::string _runname; /// Event counter mutable CounterPtr _eventCounter; /// Cross-section known to AH Scatter1DPtr _xs; /// Beams used by this run. ParticlePair _beams; /// Flag to check if init has been called bool _initialised; /// Flag whether input event beams should be ignored in compatibility check bool _ignoreBeams; /// Flag to check if multiweights should be included bool _skipWeights; /// Current event number int _eventNumber; /// The index in the weight vector for the nominal weight stream size_t _defaultWeightIdx; /// Determines how often Rivet runs finalize() and writes the /// result to a YODA file. int _dumpPeriod; /// The name of a YODA file to which Rivet periodically dumps /// results. string _dumpFile; /// Flag to indicate periodic dumping is in progress bool _dumping; //@} private: /// The assignment operator is private and must never be called. /// In fact, it should not even be implemented. AnalysisHandler& operator=(const AnalysisHandler&); /// The copy constructor is private and must never be called. In /// fact, it should not even be implemented. AnalysisHandler(const AnalysisHandler&); }; } #endif diff --git a/pyext/rivet/aopaths.py b/pyext/rivet/aopaths.py --- a/pyext/rivet/aopaths.py +++ b/pyext/rivet/aopaths.py @@ -1,116 +1,122 @@ def isRefPath(path): return path.startswith("/REF") +def isTheoryPath(path): + return path.startswith("/THY") + def isRawPath(path): return path.startswith("/RAW") def isRawAO(ao): return isRawPath(ao.path) +def isTheoryAO(ao): + return isTheryPath(ao.path) + def stripOptions(path): import re return re.sub(r':\w+=[^:/]+', "", path) def stripWeightName(path): import re return re.sub(r'\[.*\]', "", path) def extractOptionString(path): import re re_opts = re.compile(r"^.*(:\w+=[^:/]+)+") m = re_opts.match(path) if not m: return "" opts = list(m.groups()) for i in range(len(opts)): opts[i] = opts[i].strip(':') return " [" + ",".join(opts) + "]" def isRefAO(ao): return int(ao.annotation("IsRef")) == 1 or isRefPath(ao.path) def isTmpPath(path): return "/_" in path #< match *any* underscore-prefixed path component def isTmpAO(ao): return isTmpPath(ao.path) class AOPath(object): """ Object representation of analysis object path structures. TODO: move to YODA? """ import re re_aopath = re.compile(r"^(/[^\[\]\@\#]+)(\[[A-Za-z\d\._=]+\])?(#\d+|@[\d\.]+)?$") def __init__(self, path): import os self.origpath = path m = self.re_aopath.match(path) if not m: raise Exception("Supplied path '%s' does not meet required structure" % path) self._basepath = m.group(1) self._varid = m.group(2).lstrip("[").rstrip("]") if m.group(2) else None self._binid = int(m.group(3).lstrip("#")) if m.group(3) else None self._isref = isRefPath(self._basepath) def basepath(self, keepref=False): "Main 'Unix-like' part of the AO path, optionally including a /REF prefix" p = self._basepath.rstrip("/") if not keepref and p.startswith("/REF"): p = p[4:] return p def varpath(self, keepref=False, defaultvarid=None): "The basepath, plus any bracketed variation identifier" p = self.basepath(keepref) if self.varid(defaultvarid) is not None: p += "[%s]" % str(self.varid(defaultvarid)) return p def binpath(self, keepref=False, defaultbinid=None, defaultvarid=None): "The varpath, plus any #-prefixed bin number identifier" p = self.varpath(keepref, defaultvarid) if self.binid(defaultbinid) is not None: p += "#%d" % self.binid(defaultbinid) return p def basepathparts(self, keepref=False): "List of basepath components, split by forward slashes" return self.basepath(keepref).strip("/").split("/") # TODO: basepathhead, basepathtail def dirname(self, keepref=False): "The non-final (i.e. dir-like) part of the basepath" return os.path.dirname(self.basepath(keepref)) def dirnameparts(self, keepref=False): "List of dirname components, split by forward slashes" return self.dirname(keepref).strip("/").split("/") def basename(self): "The final (i.e. file-like) part of the basepath" return os.path.basename(self._basepath) def varid(self, default=None): "The variation identifier (without brackets) if there is one, otherwise None" return self._varid if self._varid is not None else default def binid(self, default=None): "The bin identifier (without #) if there is one, otherwise None" return self._binid if self._binid is not None else default def isref(self): "Is there a /REF prefix in the original path?" return self._isref def istmp(self): "Do any basepath components start with an underscore, used to hide them from plotting?" return isTmpPath(self.basepath()) def israw(self): "Do any basepath components start with /RAW, used to hide them from plotting?" return isRawPath(self.basepath())