diff --git a/CMSSW.arch b/CMSSW.arch index a367b8d..2ba0e36 100644 --- a/CMSSW.arch +++ b/CMSSW.arch @@ -1 +1 @@ -slc6_amd64_gcc630 +slc7_amd64_gcc700 diff --git a/CMSSW.release b/CMSSW.release index bbf0317..14f182c 100644 --- a/CMSSW.release +++ b/CMSSW.release @@ -1 +1 @@ -CMSSW_9_4_9 +CMSSW_10_2_9 diff --git a/bootstrap_jenkins.sh b/bootstrap_jenkins.sh index 37f6ec0..825d1f8 100644 --- a/bootstrap_jenkins.sh +++ b/bootstrap_jenkins.sh @@ -22,7 +22,8 @@ function cms-merge-commit() git cms-init --upstream-only echo "---> Merging recipes..." -git cms-merge-topic UAEDF-tomc:eleCutBasedId_94X_V2 +git cms-merge-topic cms-egamma:EgammaID_1023 ## for Photon ID Fall17 V2 (will be included in 10_2_10) +git cms-merge-topic cms-egamma:EgammaPostRecoTools ## add recipes here echo "---> Running git cms-checkdeps" @@ -30,3 +31,11 @@ git cms-checkdeps -a echo "---> Adding TreeWrapper" git clone -o upstream https://github.com/blinkseb/TreeWrapper.git cp3_llbb/TreeWrapper + +if [ -d "cp3_llbb/Framework" ]; then + if ! python -c 'import requests' 2>/dev/null ; then + pushd "cp3_llbb/Framework" &> /dev/null + source "$(dirname $0)/install_requests.sh" + popd &> /dev/null + fi +fi diff --git a/install_requests.sh b/install_requests.sh new file mode 100644 index 0000000..9e0623b --- /dev/null +++ b/install_requests.sh @@ -0,0 +1,72 @@ +# no shebang, must be sourced + +## based on SĂbastien Brochet's install-tensorflow.sh script in cp3-llbb/HHTools) + +reqversion="2.21.0" + +## deduce source location from the script name +if [[ -z "${ZSH_NAME}" ]]; then + thisscript="$(readlink -f ${BASH_SOURCE})" +else + thisscript="$(readlink -f ${0})" +fi +pipinstall="$(dirname ${thisscript})/.python" + +# Check if in CMSSW +if [ -z "$CMSSW_BASE" ]; then + echo "You must use this package inside a CMSSW environment" + return 1 +fi +pymajmin=$(python -c 'import sys; print(".".join(str(num) for num in sys.version_info[:2]))') +if [[ "${pymajmin}" != "2.7" ]]; then + echo "--> Only python 2.7 is supported" + return 1 +fi + +# Check if it is already installed +scram tool info py2-requests > /dev/null 2> /dev/null +if [ $? -eq 0 ]; then + echo "--> already installed (according to scram)" + return 0 +fi + +# First, download and install pip, if needed +bk_pythonpath="${PYTHONPATH}" +python -m pip --version > /dev/null 2> /dev/null +if [ $? -ne 0 ]; then + echo "--> No pip found, bootstrapping in ${pipinstall}" + [ -d "${pipinstall}" ] || mkdir "${pipinstall}" + if [ ! -f "${pipinstall}/bin/pip" ]; then + wget -O "${pipinstall}/get-pip.py" "https://bootstrap.pypa.io/get-pip.py" + python "${pipinstall}/get-pip.py" --prefix="${pipinstall}" --no-setuptools + fi + export PYTHONPATH="${pipinstall}/lib/python${pymajmin}/site-packages:${PYTHONPATH}" +fi + +## install dependencies +installpath="${CMSSW_BASE}/install/py2-requests" +echo "--> Installing requests" +python -m pip install --prefix="${installpath}" --ignore-installed --upgrade --upgrade-strategy=only-if-needed requests=="${reqversion}" + +# root_interface toolfile +toolfile="${installpath}/py2-requests.xml" +cat <"${toolfile}" + + + + + + + + +EOF_TOOLFILE + +## cleanup +rm -rf "${pipinstall}" +export PYTHONPATH="${bk_pythonpath}" + +echo "--> Updating environment" +scram setup "${toolfile}" +eval `scram runtime -sh` ## cmsenv + +echo "--> requests is installed. The package can normally be installed with 'scram b' now" diff --git a/interface/Analyzer.h b/interface/Analyzer.h index 7d27dc4..135e092 100644 --- a/interface/Analyzer.h +++ b/interface/Analyzer.h @@ -35,6 +35,7 @@ namespace Framework { tree(tree_), m_systematics(config.getUntrackedParameter("systematics", false)) { } + virtual ~Analyzer() = default; virtual void analyze(const edm::Event&, const edm::EventSetup&, const ProducersManager&, const AnalyzersManager&, const CategoryManager&) = 0; virtual void doConsumes(const edm::ParameterSet&, edm::ConsumesCollector&& collector) {} diff --git a/interface/AnalyzerGetter.h b/interface/AnalyzerGetter.h index 3aed42a..7346e4c 100644 --- a/interface/AnalyzerGetter.h +++ b/interface/AnalyzerGetter.h @@ -8,6 +8,7 @@ namespace Framework { class AnalyzerGetter { public: + virtual ~AnalyzerGetter() noexcept(false); // to silence warning, and because subclass ExTreeMaker inherits a throwing constructor virtual const Framework::Analyzer& getAnalyzer(const std::string& name) const = 0; virtual bool analyzerExists(const std::string& name) const = 0; }; diff --git a/interface/BTaggingScaleFactors.h b/interface/BTaggingScaleFactors.h index c71d72f..b76d426 100644 --- a/interface/BTaggingScaleFactors.h +++ b/interface/BTaggingScaleFactors.h @@ -45,6 +45,7 @@ class BTaggingScaleFactors { m_tree(tree) { // Empty } + virtual ~BTaggingScaleFactors() = default; virtual void create_branches(const edm::ParameterSet&) final; diff --git a/interface/BinnedValues.h b/interface/BinnedValues.h index f439d7b..fc206f7 100644 --- a/interface/BinnedValues.h +++ b/interface/BinnedValues.h @@ -109,6 +109,8 @@ class BinnedValues { BinnedValues() = default; + virtual ~BinnedValues() = default; + private: template std::vector<_Value> get(Histogram<_Value, float>& h, const std::vector& bins, bool& outOfRange) const { diff --git a/interface/BinnedValuesJSONParser.h b/interface/BinnedValuesJSONParser.h index d4add08..9b2a4e3 100644 --- a/interface/BinnedValuesJSONParser.h +++ b/interface/BinnedValuesJSONParser.h @@ -16,6 +16,8 @@ class BinnedValuesJSONParser { parse_file(file); } + virtual ~BinnedValuesJSONParser() = default; + virtual BinnedValues&& get_values() final { return std::move(m_values); } diff --git a/interface/Category.h b/interface/Category.h index 1fbabe4..71b8eab 100644 --- a/interface/Category.h +++ b/interface/Category.h @@ -19,6 +19,8 @@ struct CategoryMetadata { class Category { public: + virtual ~Category() = default; + virtual void configure(const edm::ParameterSet& config) {}; virtual bool event_in_category_pre_analyzers(const ProducersManager& producers) const = 0; diff --git a/interface/Filter.h b/interface/Filter.h index 88052bd..00a0946 100644 --- a/interface/Filter.h +++ b/interface/Filter.h @@ -24,6 +24,7 @@ namespace Framework { Filter(const std::string& name, const edm::ParameterSet& config): m_name(name) { } + virtual ~Filter() = default; virtual bool filter(edm::Event&, const edm::EventSetup&) = 0; virtual void doConsumes(const edm::ParameterSet&, edm::ConsumesCollector&& collector) {} diff --git a/interface/Framework.h b/interface/Framework.h index 3b3f9cd..f8af865 100644 --- a/interface/Framework.h +++ b/interface/Framework.h @@ -30,7 +30,7 @@ class ExTreeMaker: public edm::EDProducer, ProducerGetter, AnalyzerGetter { public: explicit ExTreeMaker(const edm::ParameterSet&); - ~ExTreeMaker(); + virtual ~ExTreeMaker(); private: virtual void beginJob() override; diff --git a/interface/Histogram.h b/interface/Histogram.h index e1f8f36..c8f5e0f 100644 --- a/interface/Histogram.h +++ b/interface/Histogram.h @@ -52,6 +52,7 @@ class Histogram { m_errors_low.reset(new T[m_size]); m_errors_high.reset(new T[m_size]); } + virtual ~Histogram() = default; static size_t findBin(const std::vector<_Bin>& array, _Bin value) { for (std::size_t i = 0; i < array.size() - 1; i++) { diff --git a/interface/Identifiable.h b/interface/Identifiable.h index 25450ef..431b3a6 100644 --- a/interface/Identifiable.h +++ b/interface/Identifiable.h @@ -18,6 +18,7 @@ class Identifiable { ids(tree["ids"].write>>()) { // Empty } + virtual ~Identifiable() = default; template void produce_id(const edm::Ref& ref) { std::map ids_; diff --git a/interface/Producer.h b/interface/Producer.h index faeef26..672e732 100644 --- a/interface/Producer.h +++ b/interface/Producer.h @@ -49,6 +49,8 @@ namespace Framework { m_systematics(config.getUntrackedParameter("systematics", false)) { } + virtual ~Producer() = default; + //! Main method of the producer, called for each event. /*! * You have direct access to the event via the CMSSW interface with the @p event and @p setup parameters. diff --git a/interface/ProducerGetter.h b/interface/ProducerGetter.h index 6340700..df9a8ee 100644 --- a/interface/ProducerGetter.h +++ b/interface/ProducerGetter.h @@ -8,6 +8,7 @@ namespace Framework { class ProducerGetter { public: + virtual ~ProducerGetter() noexcept(false); // to silence warning, and because subclass ExTreeMaker inherits a throwing constructor virtual const Framework::Producer& getProducer(const std::string& name) const = 0; virtual bool producerExists(const std::string& name) const = 0; }; diff --git a/interface/ScaleFactors.h b/interface/ScaleFactors.h index 40503d1..f31f276 100644 --- a/interface/ScaleFactors.h +++ b/interface/ScaleFactors.h @@ -17,6 +17,7 @@ class ScaleFactors { m_tree(tree) { // Empty } + virtual ~ScaleFactors() = default; virtual void create_branches(const edm::ParameterSet&) final; virtual void create_branch(const std::string& scale_factor, const std::string& branch_name); diff --git a/python/ElectronsProducer.py b/python/ElectronsProducer.py index 3d685d7..a78381d 100644 --- a/python/ElectronsProducer.py +++ b/python/ElectronsProducer.py @@ -1,5 +1,7 @@ import FWCore.ParameterSet.Config as cms +mvaTag = "Run2Fall17IsoV2" + default_configuration = cms.PSet( type = cms.string('electrons'), prefix = cms.string('electron_'), @@ -12,11 +14,15 @@ cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Fall17-94X-V2-veto"), cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Fall17-94X-V2-loose"), cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Fall17-94X-V2-medium"), - cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Fall17-94X-V2-tight") + cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Fall17-94X-V2-tight"), + cms.InputTag("egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wp80"), + cms.InputTag("egmGsfElectronIDs:mvaEleID-Fall17-iso-V2-wp90"), + cms.InputTag("egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wp80"), + cms.InputTag("egmGsfElectronIDs:mvaEleID-Fall17-noIso-V2-wp90") ), mva_id = cms.untracked.PSet( - values=cms.untracked.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV1Values"), - categories=cms.untracked.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV1Categories")), + values=cms.untracked.InputTag("electronMVAValueMapProducer:ElectronMVAEstimator{0}Values".format(mvaTag)), + categories=cms.untracked.InputTag("electronMVAValueMapProducer:ElectronMVAEstimator{0}Categories".format(mvaTag))), scale_factors = cms.untracked.PSet( ## name=cms.untracked.FileInPath(), ) diff --git a/python/Framework.py b/python/Framework.py index ee974aa..0f347de 100644 --- a/python/Framework.py +++ b/python/Framework.py @@ -52,7 +52,7 @@ def __init__(self, options, verbose=True): print("CP3 llbb framework:") print(" - Running over %s" % ("data" if self.isData else "simulation")) print(" - global tag: %s" % self.globalTag) - print(" - era: %s" % {eras.Run2_25ns:"25ns", eras.Run2_50ns:"50ns", eras.Run2_2016:"2016"}[self.era]) + print(" - era: %s" % {eras.Run2_25ns:"25ns", eras.Run2_50ns:"50ns", eras.Run2_2016:"2016", eras.Run2_2017:"2017", eras.Run2_2018:"2018"}[self.era]) print("") # Create CMSSW process and configure it with sane default values @@ -110,6 +110,33 @@ def create(self): print("Changing hlt process name from %r to %r..." % ('HLT', self.hltProcessName)) change_process_name(self.process.framework, 'HLT', self.hltProcessName) + ## ECAL endcap noise filter for 2017 and 2018 + ## https://twiki.cern.ch/twiki/bin/viewauth/CMS/MissingETOptionalFiltersRun2#How_to_run_ecal_BadCalibReducedM + if self.era in (eras.Run2_2017, eras.Run2_2017): + self.process.load('RecoMET.METFilters.ecalBadCalibFilter_cfi') + + baddetEcallist = cms.vuint32( + [872439604,872422825,872420274,872423218, + 872423215,872416066,872435036,872439336, + 872420273,872436907,872420147,872439731, + 872436657,872420397,872439732,872439339, + 872439603,872422436,872439861,872437051, + 872437052,872420649,872422436,872421950, + 872437185,872422564,872421566,872421695, + 872421955,872421567,872437184,872421951, + 872421694,872437056,872437057,872437313]) + + self.process.ecalBadCalibReducedMINIAODFilter = cms.EDFilter( + "EcalBadCalibFilter", + EcalRecHitSource = cms.InputTag("reducedEgamma:reducedEERecHits"), + ecalMinEt = cms.double(50.), + baddetEcal = baddetEcallist, + taggingMode = cms.bool(True), + debug = cms.bool(False) + ) + + self.path += self.process.ecalBadCalibReducedMINIAODFilter + if len(self.__systematics) > 0: if self.verbose: print("") @@ -277,32 +304,38 @@ def redoJEC(self, JECDatabase=None, addBtagDiscriminators=None): self.useJECDatabase(JECDatabase) from cp3_llbb.Framework.Tools import recorrect_jets, recorrect_met - jet_collection, prodNames_jet = recorrect_jets(self.process, self.isData, 'AK4PFchs', self.__miniaod_jet_collection, addBtagDiscriminators=addBtagDiscriminators) - met_collection, prodNames_met = recorrect_met(self.process, self.isData, self.__miniaod_met_collection, jet_collection) + jet_collection = recorrect_jets(self.process, self.isData, 'AK4PFchs', self.__miniaod_jet_collection, addBtagDiscriminators=addBtagDiscriminators) + met_collection = recorrect_met(self.process, self.isData, self.__miniaod_met_collection, jet_collection, fixEE2017=(self.era == eras.Run2_2017)) + from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask + self.path.associate(getPatAlgosToolsTask(self.process)) # Fat jets - fat_jet_collection, prodNames_fatjet = recorrect_jets(self.process, self.isData, 'AK8PFchs', self.__miniaod_fat_jet_collection, addBtagDiscriminators=addBtagDiscriminators) - - self.path.associate(cms.Task(*(getattr(self.process, name) for name in chain(prodNames_jet, prodNames_met, prodNames_fatjet)))) + ## fat_jet_collection = recorrect_jets(self.process, self.isData, 'AK8PFchs', self.__miniaod_fat_jet_collection, addBtagDiscriminators=addBtagDiscriminators) ## FIXME disable for now # Look for producers using the default jet and met collections - for producer in self.producers: - p = getattr(self.process.framework.producers, producer) - change_input_tags_and_strings(p, self.__miniaod_jet_collection, jet_collection, 'producers.' + producer, ' ') - change_input_tags_and_strings(p, self.__miniaod_fat_jet_collection, fat_jet_collection, 'producers.' + producer, ' ') - change_input_tags_and_strings(p, self.__miniaod_met_collection, met_collection, 'producers.' + producer, ' ') - - if p.type == 'met': - p.parameters.slimmed = cms.untracked.bool(False) + repls = [ (self.__miniaod_jet_collection, jet_collection), + ##(self.__miniaod_fat_jet_collection, fat_jet_collection), + (self.__miniaod_met_collection, met_collection) ] + for produName in self.producers: + producer = getattr(self.process.framework.producers, produName) + for tgFrom, tgTo in repls: + change_input_tags_and_strings(producer, tgFrom, tgTo, "producers.{0}".format(produName), " ") + if producer.type == 'met': + producer.parameters.slimmed = cms.untracked.bool(False) + for anaName in self.analyzers: + analyzer = getattr(self.process.framework.analyzers, anaName) + for tgFrom, tgTo in repls: + change_input_tags_and_strings(analyzer, tgFrom, tgTo, "analyzers.{0}".format(anaName), " ") # Change the default collections to the newly created self.__miniaod_jet_collection = jet_collection self.__miniaod_unsmeared_jet_collection = jet_collection - self.__miniaod_fat_jet_collection = fat_jet_collection + ## self.__miniaod_fat_jet_collection = fat_jet_collection self.__miniaod_met_collection = met_collection if self.verbose: - print("New jets and MET collections: %r, %r and %r" % (jet_collection, fat_jet_collection, met_collection)) + ## print("New jets and MET collections: %r, %r and %r" % (jet_collection, fat_jet_collection, met_collection)) + print("New jets and MET collections: %r, and %r" % (jet_collection, met_collection)) print("") @@ -424,86 +457,22 @@ def applyMuonCorrection(self, type, tag=None, input=None): if self.verbose: print("New muons collection: %r" % (self.__miniaod_muon_collection)) - @dep(before=("create", "electronRegression"), performs=("correction", "electronRegression")) - def applyElectronRegression(self): + @dep(before=("create", "electronPostReco"), performs=("correction", "electronPostReco")) + def applyElectronPostReco(self): """ - Apply electron regression from - https://twiki.cern.ch/twiki/bin/view/CMS/EGMRegression - """ - - if self.verbose: - print("") - print("Applying electron regression...") - - # Read corrections for database - from EgammaAnalysis.ElectronTools.regressionWeights_cfi import regressionWeights - regressionWeights(self.process) - - self.process.load('EgammaAnalysis.ElectronTools.regressionApplication_cff') - - # Rename the collection - self.process.slimmedElectronsWithRegression = self.process.slimmedElectrons.clone() - self.path.associate(cms.Task(self.process.slimmedElectronsWithRegression)) - - # Look for producers using the default electron input - for producer in self.producers: - p = getattr(self.process.framework.producers, producer) - change_input_tags_and_strings(p, self.__miniaod_electron_collection, 'slimmedElectronsWithRegression', 'producers.' + producer, ' ') - - self.__miniaod_electron_collection = 'slimmedElectronsWithRegression' - - if self.verbose: - print("New electrons collection: %r" % (self.__miniaod_electron_collection)) - - @dep(before=("create", "electronSmearing"), after="electronRegression", performs=("electronSmearing", "correction")) - def applyElectronSmearing(self, tag): + Apply electron post-reco (scale&smearings), see + https://twiki.cern.ch/twiki/bin/viewauth/CMS/EgammaMiniAODV2 """ - Apply electron smearing from - https://twiki.cern.ch/twiki/bin/view/CMS/EGMSmearer - - Parameters: - tag: correction file to use (from EgammaAnalysis.ElectronTools.calibrationTablesRun2.files) - """ - - if self.verbose: - print("") - print("Applying electron smearing...") - - from EgammaAnalysis.ElectronTools.calibratedPatElectronsRun2_cfi import calibratedPatElectrons - from EgammaAnalysis.ElectronTools.calibrationTablesRun2 import files - - # FIXME: Add a preselection on electron to prevent a crash in the producer - # Remove when it's no longer needed (see twiki) - self.process.selectedElectrons = cms.EDFilter("PATElectronSelector", - src = cms.InputTag(self.__miniaod_electron_collection), - cut = cms.string("pt > 5 && abs(superCluster.eta) < 2.5") - ) - - self.process.slimmedElectronsSmeared = calibratedPatElectrons.clone( - electrons = "selectedElectrons", - isMC = not self.isData, - correctionFile = files[tag] - ) - - self.process.load('Configuration.StandardSequences.Services_cff') - self.process.RandomNumberGeneratorService = cms.Service("RandomNumberGeneratorService", - slimmedElectronsSmeared = cms.PSet( - initialSeed = cms.untracked.uint32(42), - engineName = cms.untracked.string('TRandom3') - ) - ) - - self.path.associate(cms.Task(self.process.selectedElectrons, self.process.slimmedElectronsSmeared, self.process.RandomNumberGeneratorService)) - - # Look for producers using the default electron input - for producer in self.producers: - p = getattr(self.process.framework.producers, producer) - change_input_tags_and_strings(p, self.__miniaod_electron_collection, 'slimmedElectronsSmeared', 'producers.' + producer, ' ') - - self.__miniaod_electron_collection = 'slimmedElectronsSmeared' - - if self.verbose: - print("New electrons collection: %r" % (self.__miniaod_electron_collection)) + from RecoEgamma.EgammaTools.EgammaPostRecoTools import setupEgammaPostRecoSeq + if self.era == eras.Run2_2016: + setupEgammaPostRecoSeq(self.process, runEnergyCorrections=False, era='2016-Legacy') + elif self.era == eras.Run2_2017: + setupEgammaPostRecoSeq(self.process, runEnergyCorrections=True, era='2017-Nov17ReReco') + elif self.era == eras.Run2_2018: + setupEgammaPostRecoSeq(self.process, runEnergyCorrections=False, era='2018-Prompt') + else: + raise RuntimeError("Electron post-reco is not supported for this era") + self.path.associate(self.process.egammaScaleSmearTask) @dep(before="create") def doSystematics(self, systematics, **kwargs): @@ -533,16 +502,20 @@ def configureElectronId_(self): self.process.egmGsfElectronIDs.physicsObjectSrc = self.__miniaod_electron_collection id_modules = [ + 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_GeneralPurpose_V1_cff', + 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_HZZ_V1_cff', 'RecoEgamma.ElectronIdentification.Identification.cutBasedElectronID_Fall17_94X_V2_cff', 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V1_cff', - 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V1_cff' + 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V1_cff', + 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_noIso_V2_cff', + 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Fall17_iso_V2_cff' ] for mod in id_modules: setupAllVIDIdsInModule(self.process, mod, setupVIDElectronSelection) - self.path.associate(cms.Task(self.process.electronMVAValueMapProducer)) - self.path.associate(cms.Task(self.process.egmGsfElectronIDs)) + from RecoEgamma.ElectronIdentification.egmGsfElectronIDs_cff import egmGsfElectronIDTask + self.path.associate(egmGsfElectronIDTask) self.process.electronMVAValueMapProducer.srcMiniAOD = self.__miniaod_electron_collection @@ -552,7 +525,7 @@ def _configureFramework(self): from cp3_llbb.Framework import GenParticlesProducer from cp3_llbb.Framework import HLTProducer from cp3_llbb.Framework import JetsProducer - from cp3_llbb.Framework import FatJetsProducer + ## from cp3_llbb.Framework import FatJetsProducer from cp3_llbb.Framework import METProducer from cp3_llbb.Framework import MuonsProducer from cp3_llbb.Framework import ElectronsProducer @@ -568,7 +541,7 @@ def _configureFramework(self): self.addProducer('event', copy.deepcopy(EventProducer.default_configuration)) self.addProducer('hlt', copy.deepcopy(HLTProducer.default_configuration)) self.addProducer('jets', copy.deepcopy(JetsProducer.default_configuration)) - self.addProducer('fat_jets', copy.deepcopy(FatJetsProducer.default_configuration)) + ## self.addProducer('fat_jets', copy.deepcopy(FatJetsProducer.default_configuration)) self.addProducer('met', copy.deepcopy(METProducer.default_configuration)) self.addProducer('muons', copy.deepcopy(MuonsProducer.default_configuration)) self.addProducer('electrons', copy.deepcopy(ElectronsProducer.default_configuration)) diff --git a/python/Tools.py b/python/Tools.py index c33bbef..387d4a5 100644 --- a/python/Tools.py +++ b/python/Tools.py @@ -161,19 +161,11 @@ def recorrect_jets(process, isData, jetAlgo, jetCollection, addBtagDiscriminator ) if addBtagDiscriminators is None: - outName = 'updatedPatJets{}'.format(label) - return outName, ("patJetCorrFactors{}".format(label), "metrawCaloNewJEC", outName,) + return 'updatedPatJets{}'.format(label) else: - outName = 'selectedUpdatedPatJets{}'.format(label) - tagModNames = set(dNm.split(":")[0] for dNm in addBtagDiscriminators if ":" in dNm) - tagModNamesMap = { "pfDeepCSVJetTags" : ("pfDeepCSVJetTags", "pfDeepCSVTagInfos", "pfInclusiveSecondaryVertexFinderTagInfos", "pfImpactParameterTagInfos") } - return outName, tuple(chain( - ("{0}{1}".format(modNm, label) for modNm in chain( - ("patJetCorrFactors", "updatedPatJets", "selectedUpdatedPatJets", "patJetCorrFactorsTransientCorrected", "updatedPatJetsTransientCorrected") - , chain.from_iterable(tagModNamesMap[tmn] for tmn in tagModNames) - )), [outName])) - -def recorrect_met(process, isData, metCollection, jetCollection): + return 'selectedUpdatedPatJets{}'.format(label) + +def recorrect_met(process, isData, metCollection, jetCollection, fixEE2017=False): """ Create a new MET collection, propagating new JEC from jetCollection @@ -194,23 +186,9 @@ def recorrect_met(process, isData, metCollection, jetCollection): )) from PhysicsTools.PatUtils.tools.runMETCorrectionsAndUncertainties import runMetCorAndUncFromMiniAOD - runMetCorAndUncFromMiniAOD(process, isData=isData, jetCollUnskimmed=jetCollection, postfix="NewJEC") - return 'slimmedMETsNewJEC', tuple(([genMetTag, "genMetExtractorNewJEC"] if not isData else [])+list( - "{}NewJEC".format(modName) for modName in chain( - [ "basicJetsForMet", "jetSelectorForMet", "cleanedPatJets", "patJetCorrFactorsReapplyJEC", "patJetsReapplyJEC", "pfMet", "patPFMet", "patPFMetT1", "patPFMetT1T2Corr", "slimmedMETs" ] - , ("{0}{1}{2}".format(aMod, var, vDir) - for aMod in ("shiftedPat", "shiftedPatMETCorr", "patPFMetT1") - for var in ["JetEn", "MuonEn", "ElectronEn", "PhotonEn", "TauEn", "UnclusteredEn"]+(["JetRes"] if not isData else []) ## "JetRes" for MC - for vDir in ("Up", "Down")) - , [ "pfCandsForUnclusteredUnc", "pfCandsNoJetsNoEleNoMuNoTau", "pfCandsNoJetsNoEleNoMu", "pfCandsNoJetsNoEle", "pfCandsNoJets" ] - , [ "patPFMetT1Smear", "patPFMetT1T2SmearCorr", "selectedPatJetsForMetT1T2SmearCorr", "patSmearedJets" ] - , ([ "{0}SmearedJetRes{1}".format(mod, vDir) for mod in ("shiftedPat", "shiftedPatMETCorr") for vDir in ("Up", "Down") ] if not isData else - [ "patPFMetT1JetRes{0}".format(vDir) for vDir in ("Up", "Down") ]) - , [ "patPFMetT1SmearJet{0}{1}".format(qty, vDir) for qty in ("Res", "En") for vDir in ("Up", "Down") ] - , [ "patPFMetT1Txy", "patPFMetTxyCorr" ] - ))+ - (["ak4PFCHS{0}Corrector".format(corrType) for corrType in ("L1FastL2L3", "L1Fastjet", "L2Relative", "L3Absolute", "L1FastL2L3Residual", "Residual")] if isData else [])+ - [ "patCaloMet", "patCHSMet", "pfMetCHS", "pfCHS", "patTrkMet", "pfMetTrk", "pfTrk", "metrawCaloNewJEC" ]) + runMetCorAndUncFromMiniAOD(process, isData=isData, jetCollUnskimmed=jetCollection, postfix="NewJEC", + fixEE2017=fixEE2017, fixEE2017Params={'userawPt': True, 'ptThreshold':50.0, 'minEtaThreshold':2.65, 'maxEtaThreshold': 3.139}) + return 'slimmedMETsNewJEC' def check_tag_(db_file, tag): import sqlite3 diff --git a/setup_project_with_framework.sh b/setup_project_with_framework.sh index 577357e..a9e01e2 100644 --- a/setup_project_with_framework.sh +++ b/setup_project_with_framework.sh @@ -3,7 +3,7 @@ # Bootstrap a CMSSW installation ready for a given framework version # Usage: source setup_project_with_framework.sh [-j N] [-o NAME] [ -b BRANCH || --pr PULLREQUESTID ] -FRAMEWORK_GITHUB=https://github.com/cp3-llbb/Framework +FRAMEWORK_GITHUB=https://github.com/cp3-llbb/Framework.git # Default options CORE=4 @@ -29,12 +29,25 @@ do shift # past argument ;; -b|--branch) + GITREF="$2" BRANCH="$2" shift # past argument ;; + -a|--arch) + CMSSW_ARCH="$2" + shift + ;; + -r|--release) + CMSSW_VERSION="$2" + shift + ;; + -d|--bootstrap) + DEPENDENCIES="$2" + shift + ;; *) # unknown option - echo "Usage: source setup_project_with_framework.sh [-j N] [-o NAME] [ -b BRANCH OR --pr PULLREQUESTID ]" + echo "Usage: source setup_project_with_framework.sh [-j N] [-o NAME] [ -b BRANCH OR --pr PULLREQUESTID ] [-a ARC] [-r CMSSW_X_Y_Z] [-b dependencies.sh]" return 1 ;; esac @@ -58,9 +71,15 @@ if [ -n "${GITREF}" ]; then popd &> /dev/null fi -CMSSW_ARCH=$(cat "${FWKDIR_TMP}/CMSSW.arch") -CMSSW_VERSION=$(cat "${FWKDIR_TMP}/CMSSW.release") -DEPENDENCIES="${FWKDIR_TMP}/bootstrap_jenkins.sh" +if [ -z "${CMSSW_ARCH}" ]; then + CMSSW_ARCH=$(cat "${FWKDIR_TMP}/CMSSW.arch") +fi +if [ -z "${CMSSW_VERSION}" ]; then + CMSSW_VERSION=$(cat "${FWKDIR_TMP}/CMSSW.release") +fi +if [ -z "${DEPENDENCIES}" ]; then + DEPENDENCIES="${FWKDIR_TMP}/bootstrap_jenkins.sh" +fi if [ -z "${OUTPUT}" ]; then OUTPUT="${CMSSW_VERSION}" diff --git a/src/Framework.cc b/src/Framework.cc index 30ce9f5..84f6512 100644 --- a/src/Framework.cc +++ b/src/Framework.cc @@ -202,6 +202,9 @@ ExTreeMaker::ExTreeMaker(const edm::ParameterSet& iConfig): std::cout << std::endl; } +// to silence warning, and because inherits a throwing constructor, so they need to be all consistent +ProducerGetter::~ProducerGetter() noexcept(false) {} +AnalyzerGetter::~AnalyzerGetter() noexcept(false) {} ExTreeMaker::~ExTreeMaker() { diff --git a/test/unit_tests_data.py b/test/unit_tests_data.py index c607046..724e8f2 100644 --- a/test/unit_tests_data.py +++ b/test/unit_tests_data.py @@ -5,17 +5,14 @@ from cp3_llbb.Framework import Framework from cp3_llbb.Framework.CmdLine import CmdLine -options = CmdLine(defaults=dict(runOnData=1, era="25ns", globalTag='80X_dataRun2_Prompt_ICHEP16JEC_v0', process="RECO")) +options = CmdLine(defaults=dict(runOnData=1, era="2016", globalTag='94X_dataRun2_v10', process="RECO")) framework = Framework.Framework(options) -from cp3_llbb.Framework.JetsProducer import discriminators_deepFlavour -framework.redoJEC(addBtagDiscriminators=discriminators_deepFlavour) - process = framework.create() process.source.fileNames = cms.untracked.vstring( - 'file://DoubleMuon_Run2016B_PromptReco-v2_reduced.root' + "/store/data/Run2016B/DoubleMuon/MINIAOD/17Jul2018_ver2-v1/00000/F0736B77-E38B-E811-BED7-3417EBE528B2.root" ) process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) diff --git a/test/unit_tests_mc.py b/test/unit_tests_mc.py index 2ab47fd..d2ddffc 100644 --- a/test/unit_tests_mc.py +++ b/test/unit_tests_mc.py @@ -5,31 +5,19 @@ from cp3_llbb.Framework import Framework from cp3_llbb.Framework.CmdLine import CmdLine -options = CmdLine(defaults=dict(runOnData=0, era="25ns", globalTag='80X_mcRun2_asymptotic_2016_miniAODv2_v1')) +options = CmdLine(defaults=dict(runOnData=0, era="2016", globalTag='94X_mcRun2_asymptotic_v3')) framework = Framework.Framework(options) -from cp3_llbb.Framework.JetsProducer import discriminators_deepFlavour -framework.redoJEC(addBtagDiscriminators=discriminators_deepFlavour) +framework.redoJEC() framework.smearJets() -#framework.applyMuonCorrection("kamuca", tag="MC_80X_13TeV") -##framework.applyElectronRegression() -##framework.applyElectronSmearing(tag='Moriond17_23Jan') -framework.doSystematics(['jec', 'jer']) +#framework.applyMuonCorrection("kamuca", tag="MC_80X_13TeV") ## TODO update to rochester +framework.applyElectronPostReco() +##framework.doSystematics(['jec', 'jer']) process = framework.create() -import os -v1,v2,v3 = tuple(int(tok) for tok in os.getenv("CMSSW_VERSION").split("_")[1:4]) -if v1 > 9 or ( v1 == 8 and v2 == 0 and v3 > 30 ) or ( v1 == 9 and v2 >= 3 ): - ## Don't use the deterministic seed yet - ## for agreement between >=CMSSW_8_0_31 and <=CMSSW_8_0_30 (see PR#20241) - ## and between >=CMSSW_9_3_0 and earlier CMSSW_9_X (see PR#20240) - framework.process.slimmedJetsSmeared.useDeterministicSeed = cms.bool(False) - framework.process.selectedUpdatedPatJetsAK4PFchsNewJECJERUp.useDeterministicSeed = cms.bool(False) - framework.process.selectedUpdatedPatJetsAK4PFchsNewJECJERDown.useDeterministicSeed = cms.bool(False) - process.source.fileNames = cms.untracked.vstring( - 'file://TTTo2L2Nu_13TeV-powheg_RunIISpring16MiniAODv2_reduced.root' + '/store/mc/RunIISummer16MiniAODv3/TTTo2L2Nu_TuneCUETP8M2_ttHtranche3_13TeV-powheg-pythia8/MINIAODSIM/PUMoriond17_94X_mcRun2_asymptotic_v3-v2/270000/248C6048-5FEE-E811-80C4-0025902D144A.root' ) process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) diff --git a/test/unit_tests_mc_with_db.py b/test/unit_tests_mc_with_db.py index de2d679..e7ca72b 100644 --- a/test/unit_tests_mc_with_db.py +++ b/test/unit_tests_mc_with_db.py @@ -5,15 +5,14 @@ from cp3_llbb.Framework import Framework from cp3_llbb.Framework.CmdLine import CmdLine -options = CmdLine(defaults=dict(runOnData=0, era="25ns", globalTag='80X_mcRun2_asymptotic_2016_miniAODv2_v1')) +options = CmdLine(defaults=dict(runOnData=0, era="2016", globalTag='94X_mcRun2_asymptotic_v3')) framework = Framework.Framework(options) -from cp3_llbb.Framework.JetsProducer import discriminators_deepFlavour -framework.redoJEC(JECDatabase='Spring16_25nsV1_MC.db', addBtagDiscriminators=discriminators_deepFlavour) +framework.redoJEC(JECDatabase='Spring16_25nsV1_MC.db') process = framework.create() process.source.fileNames = cms.untracked.vstring( - 'file://TTTo2L2Nu_13TeV-powheg_RunIISpring16MiniAODv2_reduced.root' + '/store/mc/RunIISummer16MiniAODv3/TTTo2L2Nu_TuneCUETP8M2_ttHtranche3_13TeV-powheg-pythia8/MINIAODSIM/PUMoriond17_94X_mcRun2_asymptotic_v3-v2/270000/248C6048-5FEE-E811-80C4-0025902D144A.root' ) process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10))