diff --git a/Alignment/CommonAlignment/scripts/tkal_create_file_lists.py b/Alignment/CommonAlignment/scripts/tkal_create_file_lists.py index 3f28d7b37a3f5..80e4ff6125050 100755 --- a/Alignment/CommonAlignment/scripts/tkal_create_file_lists.py +++ b/Alignment/CommonAlignment/scripts/tkal_create_file_lists.py @@ -215,7 +215,7 @@ def _validate_input(self): self._args.events = float("inf") print_msg("Using all tracks for alignment") elif (self._args.tracks is None) and (self._args.rate is None): - msg = ("either -n/--events-for-alignment or both of " + msg = ("either -n/--events-for-alignment, --all-events, or both of " "--tracks-for-alignment and --track-rate are required") self._parser.error(msg) elif (((self._args.tracks is not None) and (self._args.rate is None)) or @@ -461,7 +461,7 @@ def _split_hippy_jobs(self): eventsinthisjob = float("inf") for fileinfo in self._files_alignment: if fileinfo.dataset != dataset: continue - miniiovs = self._get_iovs(fileinfo.runs, useminiiovs=True) + miniiovs = set(self._get_iovs(fileinfo.runs, useminiiovs=True)) if miniiov not in miniiovs: continue if len(miniiovs) > 1: hippyjobs[dataset,miniiov] = [] diff --git a/Alignment/HIPAlignmentAlgorithm/python/OptionParser/HipPyOptionParser.py b/Alignment/HIPAlignmentAlgorithm/python/OptionParser/HipPyOptionParser.py index ee96d4592a459..f06d7a30a2394 100644 --- a/Alignment/HIPAlignmentAlgorithm/python/OptionParser/HipPyOptionParser.py +++ b/Alignment/HIPAlignmentAlgorithm/python/OptionParser/HipPyOptionParser.py @@ -198,7 +198,7 @@ def interpretOptions(self): self.uniformetaformula=val ## Options for mMin. bias # Apply vertex constraint - elif (key=="primaryvertextpye" or key=="pvtype"): + elif (key=="primaryvertextype" or key=="pvtype"): val=val.lower() if (val=="nobs" or val=="withbs"): self.PVtype=val diff --git a/Alignment/HIPAlignmentAlgorithm/python/align_tpl_py.txt b/Alignment/HIPAlignmentAlgorithm/python/align_tpl_py.txt index 8e1cfde5aef2f..1159df9bd3bed 100644 --- a/Alignment/HIPAlignmentAlgorithm/python/align_tpl_py.txt +++ b/Alignment/HIPAlignmentAlgorithm/python/align_tpl_py.txt @@ -31,21 +31,16 @@ if "generic" in optpy.CPEtype: # CPE type is defaulted to "template" in HipPyOpt sourceFileList=[ ] -if strflaglower == "cosmics": - process.source = cms.Source("PoolSource", - #useCSA08Kludge = cms.untracked.bool(True), - fileNames = cms.untracked.vstring(sourceFileList) - ) -elif strflaglower == "cdcs": - process.source = cms.Source("PoolSource", - #useCSA08Kludge = cms.untracked.bool(True), - fileNames = cms.untracked.vstring(sourceFileList) - ) -else: - process.source = cms.Source("PoolSource", - #useCSA08Kludge = cms.untracked.bool(True), - fileNames = cms.untracked.vstring(sourceFileList) - ) +import os, sys +if sys.argv[0] == "cmsRun": __file__ = sys.argv[1] +try: + sourceFileList = [_ for _ in sourceFileList if _ not in open(os.path.join(os.path.dirname(__file__), "../../../run/DataFiles/baddatafiles.txt")).read()] +except IOError: + pass + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(sourceFileList) + ) if hasattr(optpy, "LumiJSON"): import FWCore.PythonUtilities.LumiList as LumiList diff --git a/Alignment/HIPAlignmentAlgorithm/scripts/hippyaddtobaddatafiles.py b/Alignment/HIPAlignmentAlgorithm/scripts/hippyaddtobaddatafiles.py new file mode 100755 index 0000000000000..e44ae2a9a728b --- /dev/null +++ b/Alignment/HIPAlignmentAlgorithm/scripts/hippyaddtobaddatafiles.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import argparse, contextlib, os, re, shutil, subprocess, tempfile, time + +if __name__ == "__main__": + def abspath(path): + if not os.path.exists(path): raise ValueError(path+" does not exist") + return os.path.abspath(path) + + p = argparse.ArgumentParser() + p.add_argument("cfgfile", type=abspath) + p.add_argument("baddatafileslist", nargs="?", default=None) + args = p.parse_args() + +def runcfg(cfgfile, badfilelist): + try: + subprocess.check_output(["cmsRun", cfgfile], stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + if "FallbackFileOpenError" in e.output: + output = e.output.split("An exception of category 'FallbackFileOpenError' occurred while")[1] + filename = re.search("Failed to open the file '[^']*(/store/.*[.]root)", output).group(1) + with OneAtATime(badfilelist+".tmp", 2) as f: + with open(badfilelist) as f: + contents = set(f.read().split()) + if filename in contents: + raise RuntimeError(filename+"\nis already in\n"+badfilelist+"\n\nExiting to avoid an infinite loop. Maybe you have this running on the same cfg file multiple times?") + contents.add(filename) + contents = sorted(contents) + with open(badfilelist, "w") as f: + f.write("\n".join(contents)+"\n") + print("found and added a bad file:\n"+filename) + else: + raise + return runcfg(cfgfile, badfilelist) + print("all files left are good") + +@contextlib.contextmanager +def cd(newdir): + """http://stackoverflow.com/a/24176022/5228524""" + prevdir = os.getcwd() + os.chdir(os.path.expanduser(newdir)) + try: + yield + finally: + os.chdir(prevdir) + +def cdtemp(): return cd(tempfile.mkdtemp()) + +class KeepWhileOpenFile(object): + def __init__(self, name, message=None): + self.filename = name + self.__message = message + self.pwd = os.getcwd() + self.fd = self.f = None + self.bool = False + + @property + def wouldbevalid(self): + if self: return True + with self: + return bool(self) + + def __open(self): + self.fd = os.open(self.filename, os.O_CREAT | os.O_EXCL | os.O_WRONLY) + + def __enter__(self): + with cd(self.pwd): + try: + self.__open() + except OSError: + return None + + self.f = os.fdopen(self.fd, 'w') + + try: + if self.__message is not None: + self.f.write(self.__message+"\n") + except IOError: + pass + try: + self.f.close() + except IOError: + pass + self.bool = True + return True + + def __exit__(self, *args): + if self: + try: + with cd(self.pwd): + os.remove(self.filename) + except OSError: + pass #ignore it + self.fd = self.f = None + self.bool = False + + def __nonzero__(self): + return self.bool + +class OneAtATime(KeepWhileOpenFile): + def __init__(self, name, delay, message=None, printmessage=None, task="doing this"): + super(OneAtATime, self).__init__(name, message=message) + self.delay = delay + if printmessage is None: + printmessage = "Another process is already {task}! Waiting {delay} seconds." + printmessage = printmessage.format(delay=delay, task=task) + self.__printmessage = printmessage + + def __enter__(self): + while True: + result = super(OneAtATime, self).__enter__() + if result: + return result + print(self.__printmessage) + time.sleep(self.delay) + +if __name__ == "__main__": + with cdtemp(): + shutil.copy(args.cfgfile, ".") + + badfilelist = args.badfilelist + if badfilelist is None: + badfilelist = os.path.join(os.path.dirname(cfgfile, "../../../run/DataFiles/baddatafiles.txt")) + + runcfg(os.path.basename(args.cfgfile), args.badfilelist) diff --git a/Alignment/HIPAlignmentAlgorithm/scripts/makeHippyCampaign.py b/Alignment/HIPAlignmentAlgorithm/scripts/makeHippyCampaign.py index 24f162aa71e24..59091e396efda 100755 --- a/Alignment/HIPAlignmentAlgorithm/scripts/makeHippyCampaign.py +++ b/Alignment/HIPAlignmentAlgorithm/scripts/makeHippyCampaign.py @@ -21,7 +21,7 @@ def main(): parser.add_argument("--cmssw", default=os.environ["CMSSW_VERSION"]) parser.add_argument("--scram-arch", default=os.environ["SCRAM_ARCH"]) parser.add_argument("--subfolder", default="", help="subfolder within "+basedir+" to make 'foldername' in.") - parser.add_argument("--merge-topic", action="append", help="things to cms-merge-topic within the CMSSW release created") + parser.add_argument("--merge-topic", action="append", help="things to cms-merge-topic within the CMSSW release created", default=[]) parser.add_argument("--print-sys-path", action="store_true", help=argparse.SUPPRESS) #internal, don't use this args = parser.parse_args() @@ -80,6 +80,14 @@ def main(): f.write(os.path.join(os.getcwd(), "cosmics.txt") + ",,COSMICS,Datatype:1 APVMode:deco Bfield:3.8T\n") f.write(os.path.join(os.getcwd(), "CDCs.txt") + ",,CDCS,Datatype:1 APVMode:deco Bfield:3.8T\n") subprocess.check_call(["git", "add", "data_example.lst"]) + if not os.path.exists("baddatafiles.txt"): + with open("baddatafiles.txt", "w") as f: + f.write("If any data files are bad (e.g. not at CERN), put them here,\n") + f.write("separated by newlines or spaces or nothing or whatever you like.\n") + f.write("Anything else in this file, like these lines, will be ignored.\n") + f.write("You can also run hippyaddtobaddatafiles.py .../align_cfg.py to automatically\n") + f.write("find bad data files.\n") + f.write("Running jobs will automatically pick up changes here next time they resubmit.") mkdir_p("IOV") with cd("IOV"): diff --git a/Alignment/HIPAlignmentAlgorithm/test/hippysubmittertemplate.sh b/Alignment/HIPAlignmentAlgorithm/test/hippysubmittertemplate.sh index 627caa372b968..3468295a195a9 100644 --- a/Alignment/HIPAlignmentAlgorithm/test/hippysubmittertemplate.sh +++ b/Alignment/HIPAlignmentAlgorithm/test/hippysubmittertemplate.sh @@ -18,9 +18,9 @@ extraopts="--redirectproxy" #alignmentname=pick a name #niterations=pick a number -[ -e $lstfile ] || echo "$lstfile does not exist!" -[ -e $common ] || echo "$common does not exist!" -[ -e $IOVfile ] || echo "$IOVfile does not exist!" +[ -e $lstfile ] || (echo "$lstfile does not exist!"; exit 1) +[ -e $common ] || (echo "$common does not exist!"; exit 1) +[ -e $IOVfile ] || (echo "$IOVfile does not exist!"; exit 1) commitid=$(git rev-parse HEAD) diff --git a/CalibTracker/SiPixelESProducers/interface/SiPixelQualityESProducer.h b/CalibTracker/SiPixelESProducers/interface/SiPixelQualityESProducer.h index 25703943e98d5..5a19a019f1511 100644 --- a/CalibTracker/SiPixelESProducers/interface/SiPixelQualityESProducer.h +++ b/CalibTracker/SiPixelESProducers/interface/SiPixelQualityESProducer.h @@ -44,8 +44,9 @@ class SiPixelQualityESProducer : public edm::ESProducer, public edm::EventSetupR /* virtual*/ std::unique_ptr produce(const SiPixelQualityRcd & iRecord) ; + /* virtual*/ std::unique_ptr produceWithLabel(const SiPixelQualityRcd & iRecord); -protected: + protected: void setIntervalFor( const edm::eventsetup::EventSetupRecordKey&, const edm::IOVSyncValue&, @@ -54,10 +55,11 @@ class SiPixelQualityESProducer : public edm::ESProducer, public edm::EventSetupR private: + std::string label; edm::FileInPath fp_; typedef std::vector< edm::ParameterSet > Parameters; Parameters toGet; - - + std::unique_ptr get_pointer(const SiPixelQualityRcd & iRecord, std::string label); + }; #endif diff --git a/CalibTracker/SiPixelESProducers/plugins/SiPixelQualityESProducer.cc b/CalibTracker/SiPixelESProducers/plugins/SiPixelQualityESProducer.cc index 2ddf608fe4a20..acb6d036b08c2 100644 --- a/CalibTracker/SiPixelESProducers/plugins/SiPixelQualityESProducer.cc +++ b/CalibTracker/SiPixelESProducers/plugins/SiPixelQualityESProducer.cc @@ -37,16 +37,19 @@ using namespace edm; SiPixelQualityESProducer::SiPixelQualityESProducer(const edm::ParameterSet& conf_) : //fp_(conf_.getParameter("file")), - toGet(conf_.getParameter("ListOfRecordToMerge")) + label(conf_.exists("siPixelQualityLabel")?conf_.getParameter("siPixelQualityLabel"):""), + toGet(conf_.getParameter("ListOfRecordToMerge")) { - edm::LogInfo("SiPixelQualityESProducer::SiPixelQualityESProducer"); + edm::LogInfo("SiPixelQualityESProducer::SiPixelQualityESProducer"); //the following line is needed to tell the framework what // data is being produced setWhatProduced(this); - findingRecord(); + if (label == "forDigitizer"){ + setWhatProduced(this, &SiPixelQualityESProducer::produceWithLabel, edm::es::Label(label)); + } + findingRecord(); } - SiPixelQualityESProducer::~SiPixelQualityESProducer() { @@ -55,8 +58,8 @@ SiPixelQualityESProducer::~SiPixelQualityESProducer() } -std::unique_ptr SiPixelQualityESProducer::produce(const SiPixelQualityRcd & iRecord) -{ +std::unique_ptr SiPixelQualityESProducer::get_pointer(const SiPixelQualityRcd & iRecord, std::string label){ + std::string recordName; @@ -72,32 +75,41 @@ std::unique_ptr SiPixelQualityESProducer::produce(const SiPixelQ //SiPixelQuality::disabledModuleType BadModule; //BadModule.DetID = 1; BadModule.errorType = 0; BadModule.BadRocs = 65535; obj->addDisabledModule(BadModule); - //start with the record thta existed already to decouple the debugging + //start with the record thta existed already to decouple the debugging //here i can do whatever i need with the detVoff - + edm::ESHandle Voff; edm::ESHandle dbobject; - + for( Parameters::iterator itToGet = toGet.begin(); itToGet != toGet.end(); ++itToGet ) { recordName = itToGet->getParameter("record"); - + if (recordName=="SiPixelDetVOffRcd") - iRecord.getRecord().get(Voff); - if (recordName=="SiPixelQualityFromDbRcd") - iRecord.getRecord().get(dbobject); + iRecord.getRecord().get(Voff); + if (recordName=="SiPixelQualityFromDbRcd"){ + iRecord.getRecord().get(label, dbobject); + } } //end getting the records from the parameters - + //now the dbobject is the one copied from the db - //here make a copy of dbobject, but now the label has to be empty not to interfeare with the Reco auto dbptr = std::make_unique(*(dbobject)); - + //here is the magic line in which it switches off Bad Modules dbptr->add(Voff.product()); - return dbptr; } + +std::unique_ptr SiPixelQualityESProducer::produce(const SiPixelQualityRcd & iRecord) +{ + return get_pointer(iRecord, ""); +} +std::unique_ptr SiPixelQualityESProducer::produceWithLabel(const SiPixelQualityRcd & iRecord) +{ + return get_pointer(iRecord, label); +} + void SiPixelQualityESProducer::setIntervalFor( const edm::eventsetup::EventSetupRecordKey&, const edm::IOVSyncValue& iosv, edm::ValidityInterval& oValidity ) { diff --git a/CalibTracker/SiPixelESProducers/python/SiPixelQualityESProducer_cfi.py b/CalibTracker/SiPixelESProducers/python/SiPixelQualityESProducer_cfi.py index 19100bcb79690..8f9d2bcd3aa4a 100644 --- a/CalibTracker/SiPixelESProducers/python/SiPixelQualityESProducer_cfi.py +++ b/CalibTracker/SiPixelESProducers/python/SiPixelQualityESProducer_cfi.py @@ -1,12 +1,14 @@ import FWCore.ParameterSet.Config as cms -siPixelQualityESProducer = cms.ESProducer("SiPixelQualityESProducer", - ListOfRecordToMerge = cms.VPSet( - cms.PSet( record = cms.string( "SiPixelQualityFromDbRcd" ), - tag = cms.string( "" ) - ), - cms.PSet( record = cms.string( "SiPixelDetVOffRcd" ), - tag = cms.string( "" ) - ) - ) - ) +siPixelQualityESProducer = cms.ESProducer( + "SiPixelQualityESProducer", + ListOfRecordToMerge = cms.VPSet( + cms.PSet( record = cms.string( "SiPixelQualityFromDbRcd" ), + tag = cms.string( "" ) + ), + cms.PSet( record = cms.string( "SiPixelDetVOffRcd" ), + tag = cms.string( "" ) + ) + ), + siPixelQualityLabel = cms.string(""), + ) diff --git a/Configuration/AlCa/python/autoCond.py b/Configuration/AlCa/python/autoCond.py index 7dbd9c54a5dd1..2d1855f0ba053 100644 --- a/Configuration/AlCa/python/autoCond.py +++ b/Configuration/AlCa/python/autoCond.py @@ -56,7 +56,7 @@ # GlobalTag for MC production with realistic conditions for full Phase1 2018 detector 'phase1_2018_realistic' : '105X_upgrade2018_realistic_v2', # GlobalTag for MC production with realistic conditions for full Phase1 2018 detector for Heavy Ion - 'phase1_2018_realistic_hi' : '103X_upgrade2018_realistic_HI_v11', + 'phase1_2018_realistic_hi' : '103X_upgrade2018_realistic_HI_v12', # GlobalTag for MC production with realistic conditions for full Phase1 2018 detector: HEM-15-16 fail 'phase1_2018_realistic_HEfail' : '105X_upgrade2018_realistic_HEfail_v3', # GlobalTag for MC production (cosmics) with realistic conditions for full Phase1 2018 detector, Strip tracker in DECO mode diff --git a/Configuration/Eras/python/Era_Run2_2018_cff.py b/Configuration/Eras/python/Era_Run2_2018_cff.py index 843ce33cc1687..02bbd4001d43c 100644 --- a/Configuration/Eras/python/Era_Run2_2018_cff.py +++ b/Configuration/Eras/python/Era_Run2_2018_cff.py @@ -8,5 +8,6 @@ from Configuration.Eras.Modifier_run2_HE_2018_cff import run2_HE_2018 from Configuration.Eras.Modifier_run2_HCAL_2018_cff import run2_HCAL_2018 from Configuration.Eras.Modifier_run2_DT_2018_cff import run2_DT_2018 +from Configuration.Eras.Modifier_run2_SiPixel_2018_cff import run2_SiPixel_2018 -Run2_2018 = cms.ModifierChain(Run2_2017.copyAndExclude([run2_HEPlan1_2017]), run2_CSC_2018, run2_HCAL_2018, run2_HB_2018, run2_HE_2018,run2_DT_2018) +Run2_2018 = cms.ModifierChain(Run2_2017.copyAndExclude([run2_HEPlan1_2017]), run2_CSC_2018, run2_HCAL_2018, run2_HB_2018, run2_HE_2018,run2_DT_2018, run2_SiPixel_2018) diff --git a/Configuration/Eras/python/Modifier_run2_SiPixel_2018_cff.py b/Configuration/Eras/python/Modifier_run2_SiPixel_2018_cff.py new file mode 100644 index 0000000000000..79c53918865f4 --- /dev/null +++ b/Configuration/Eras/python/Modifier_run2_SiPixel_2018_cff.py @@ -0,0 +1,5 @@ +import FWCore.ParameterSet.Config as cms + +# This modifier is for SiPixel-specific changes + +run2_SiPixel_2018 = cms.Modifier() diff --git a/DataFormats/Provenance/interface/ProductRegistry.h b/DataFormats/Provenance/interface/ProductRegistry.h index 8bb42e5ffebc4..a8297cebba503 100644 --- a/DataFormats/Provenance/interface/ProductRegistry.h +++ b/DataFormats/Provenance/interface/ProductRegistry.h @@ -59,6 +59,8 @@ namespace edm { std::set const& elementTypesConsumed, std::string const& processName); + void setUnscheduledProducts(std::set const& unscheduledLabels); + std::string merge(ProductRegistry const& other, std::string const& fileName, BranchDescription::MatchMode branchesMustMatch = BranchDescription::Permissive); diff --git a/DataFormats/Provenance/src/BranchDescription.cc b/DataFormats/Provenance/src/BranchDescription.cc index bf468ba5fb5ac..b024377cc81eb 100644 --- a/DataFormats/Provenance/src/BranchDescription.cc +++ b/DataFormats/Provenance/src/BranchDescription.cc @@ -100,7 +100,7 @@ namespace edm { transient_() { setDropped(false); setProduced(aliasForBranch.produced()); - setOnDemand(aliasForBranch.onDemand()); + setOnDemand(false); // will be re-set externally to the aliasForBranch.onDemand() after that one has been set transient_.availableOnlyAtEndTransition_=aliasForBranch.availableOnlyAtEndTransition(); transient_.moduleName_ = aliasForBranch.moduleName(); transient_.parameterSetID_ = aliasForBranch.parameterSetID(); @@ -254,7 +254,7 @@ namespace edm { } branchAliases_ = aliasForBranch.branchAliases(); - transient_.switchAliasForBranchID_ = aliasForBranch.branchID(); + transient_.switchAliasForBranchID_ = aliasForBranch.originalBranchID(); transient_.availableOnlyAtEndTransition_ = aliasForBranch.availableOnlyAtEndTransition(); } diff --git a/DataFormats/Provenance/src/ProductRegistry.cc b/DataFormats/Provenance/src/ProductRegistry.cc index 3351f9bec2e9d..69a82bafdbaa0 100644 --- a/DataFormats/Provenance/src/ProductRegistry.cc +++ b/DataFormats/Provenance/src/ProductRegistry.cc @@ -248,6 +248,38 @@ namespace edm { } } + void + ProductRegistry::setUnscheduledProducts(std::set const& unscheduledLabels) { + throwIfFrozen(); + + bool hasAliases = false; + std::vector onDemandIDs; + for(auto& prod: productList_) { + if(prod.second.produced() && + prod.second.branchType() == InEvent && + unscheduledLabels.end() != unscheduledLabels.find(prod.second.moduleLabel())) { + + prod.second.setOnDemand(true); + onDemandIDs.push_back(prod.second.branchID()); + } + if(prod.second.produced() && prod.second.isAlias()) { + hasAliases = true; + } + } + + // Need to loop over EDAliases to set their on-demand flag based on the pointed-to branch + if(hasAliases) { + std::sort(onDemandIDs.begin(), onDemandIDs.end()); + for(auto& prod: productList_) { + if(prod.second.isAlias()) { + if(std::binary_search(onDemandIDs.begin(), onDemandIDs.end(), prod.second.aliasForBranchID())) { + prod.second.setOnDemand(true); + } + } + } + } + } + std::string ProductRegistry::merge(ProductRegistry const& other, std::string const& fileName, diff --git a/FWCore/Framework/bin/BuildFile.xml b/FWCore/Framework/bin/BuildFile.xml index ac23a200e8376..bf56799ed708d 100644 --- a/FWCore/Framework/bin/BuildFile.xml +++ b/FWCore/Framework/bin/BuildFile.xml @@ -70,3 +70,19 @@ + + + + + + + + + + + + + + + + diff --git a/FWCore/Framework/bin/cmsRunPyDev.cpp b/FWCore/Framework/bin/cmsRunPyDev.cpp new file mode 100644 index 0000000000000..cf3ffe5e8a22f --- /dev/null +++ b/FWCore/Framework/bin/cmsRunPyDev.cpp @@ -0,0 +1,398 @@ +/*---------------------------------------------------------------------- +This is a generic main that can be used with any plugin and a +PSet script. See notes in EventProcessor.cpp for details about it. +----------------------------------------------------------------------*/ + +#include "FWCore/Framework/interface/EventProcessor.h" +#include "FWCore/Framework/interface/defaultCmsRunServices.h" +#include "FWCore/MessageLogger/interface/ExceptionMessages.h" +#include "FWCore/MessageLogger/interface/JobReport.h" +#include "FWCore/MessageLogger/interface/MessageDrop.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ProcessDesc.h" +#include "FWCore/ParameterSet/interface/validateTopLevelParameterSets.h" +#include "FWCore/PluginManager/interface/PluginManager.h" +#include "FWCore/PluginManager/interface/PresenceFactory.h" +#include "FWCore/PluginManager/interface/standard.h" +//#include "FWCore/ParameterSetReader/interface/ParameterSetReader.h" +#include "FWCore/ServiceRegistry/interface/ServiceRegistry.h" +#include "FWCore/ServiceRegistry/interface/ServiceToken.h" +#include "FWCore/ServiceRegistry/interface/ServiceWrapper.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Utilities/interface/EDMException.h" +#include "FWCore/Utilities/interface/ConvertException.h" +#include "FWCore/Utilities/interface/Presence.h" +#include "FWCore/Utilities/interface/TimingServiceBase.h" +#include "FWCore/PyDevParameterSet/interface/MakePyBind11ParameterSets.h" +#include "TError.h" + +#include "boost/program_options.hpp" +#include "tbb/task_scheduler_init.h" + +#include +#include +#include +#include +#include +#include +#include + +//Command line parameters +static char const* const kParameterSetOpt = "parameter-set"; +static char const* const kPythonOpt = "pythonOptions"; +static char const* const kParameterSetCommandOpt = "parameter-set,p"; +static char const* const kJobreportCommandOpt = "jobreport,j"; +static char const* const kJobreportOpt = "jobreport"; +static char const* const kEnableJobreportCommandOpt = "enablejobreport,e"; +static const char* const kEnableJobreportOpt = "enablejobreport"; +static char const* const kJobModeCommandOpt = "mode,m"; +static char const* const kJobModeOpt="mode"; +static char const* const kMultiThreadMessageLoggerOpt = "multithreadML,t"; +static char const* const kNumberOfThreadsCommandOpt = "numThreads,n"; +static char const* const kNumberOfThreadsOpt = "numThreads"; +static char const* const kSizeOfStackForThreadCommandOpt = "sizeOfStackForThreadsInKB,s"; +static char const* const kSizeOfStackForThreadOpt = "sizeOfStackForThreadsInKB"; +static char const* const kHelpOpt = "help"; +static char const* const kHelpCommandOpt = "help,h"; +static char const* const kStrictOpt = "strict"; + +constexpr unsigned int kDefaultSizeOfStackForThreadsInKB = 10*1024; //10MB +// ----------------------------------------------- +namespace { + class EventProcessorWithSentry { + public: + explicit EventProcessorWithSentry() : ep_(nullptr), callEndJob_(false) {} + explicit EventProcessorWithSentry(std::unique_ptr ep) : + ep_(std::move(ep)), + callEndJob_(false) {} + ~EventProcessorWithSentry() { + if(callEndJob_ && ep_.get()) { + try { + ep_->endJob(); + } + catch (...) { + edm::LogSystem("MoreExceptions") + << "After a fatal primary exception was caught, there was an attempt to run\n" + << "endJob methods. Another exception was caught while endJob was running\n" + << "and we give up trying to run endJob."; + } + } + edm::clearMessageLog(); + } + EventProcessorWithSentry(EventProcessorWithSentry const&) = delete; + EventProcessorWithSentry const& operator=(EventProcessorWithSentry const&) = delete; + EventProcessorWithSentry(EventProcessorWithSentry&&) = default; // Allow Moving + EventProcessorWithSentry& operator=(EventProcessorWithSentry&&) = default; // Allow moving + + void on() { + callEndJob_ = true; + } + void off() { + callEndJob_ = false; + } + edm::EventProcessor* operator->() { + return ep_.get(); + } + private: + std::unique_ptr ep_; + bool callEndJob_; + }; + + unsigned int setNThreads(unsigned int iNThreads, + unsigned int iStackSize, + std::unique_ptr& oPtr) { + //The TBB documentation doesn't explicitly say this, but when the task_scheduler_init's + // destructor is run it does a 'wait all' for all tasks to finish and then shuts down all the threads. + // This provides a clean synchronization point. + //We have to destroy the old scheduler before starting a new one in order to + // get tbb to actually switch the number of threads. If we do not, tbb stays at 1 threads + + //stack size is given in KB but passed in as bytes + iStackSize *= 1024; + + oPtr.reset(); + if(0==iNThreads) { + //Allow TBB to decide how many threads. This is normally the number of CPUs in the machine. + iNThreads = tbb::task_scheduler_init::default_num_threads(); + } + oPtr = std::make_unique(static_cast(iNThreads),iStackSize); + + return iNThreads; + } +} + +int main(int argc, char* argv[]) { + + edm::TimingServiceBase::jobStarted(); + + int returnCode = 0; + std::string context; + bool alwaysAddContext = true; + //Default to only use 1 thread. We define this early (before parsing the command line options + // and python configuration) since the plugin system or message logger may be using TBB. + //NOTE: with new version of TBB (44_20160316oss) we can only construct 1 tbb::task_scheduler_init per job + // else we get a crash. So for now we can't have any services use tasks in their constructors. + std::unique_ptr tsiPtr = std::make_unique(edm::s_defaultNumberOfThreads, kDefaultSizeOfStackForThreadsInKB * 1024); + std::shared_ptr theMessageServicePresence; + std::unique_ptr jobReportStreamPtr; + std::shared_ptr > jobRep; + EventProcessorWithSentry proc; + + try { + returnCode = edm::convertException::wrap([&]()->int { + + // NOTE: MacOs X has a lower rlimit for opened file descriptor than Linux (256 + // in Snow Leopard vs 512 in SLC5). This is a problem for some of the workflows + // that open many small root datafiles. Notice that this is safe to do also + // for Linux, but we agreed not to change the behavior there for the moment. + // Also the limits imposed by ulimit are not affected and still apply, if + // there. +#ifdef __APPLE__ + context = "Setting file descriptor limit"; + struct rlimit limits; + getrlimit(RLIMIT_NOFILE, &limits); + limits.rlim_cur = (OPEN_MAX < limits.rlim_max) ? OPEN_MAX : limits.rlim_max; + setrlimit(RLIMIT_NOFILE, &limits); +#endif + + context = "Initializing plug-in manager"; + edmplugin::PluginManager::configure(edmplugin::standard::config()); + + // Decide whether to use the multi-thread or single-thread message logger + // (Just walk the command-line arguments, since the boost parser will + // be run below and can lead to error messages which should be sent via + // the message logger) + context = "Initializing either multi-threaded or single-threaded message logger"; + bool multiThreadML = false; + for(int i = 0; i < argc; ++i) { + if((std::strncmp (argv[i], "-t", 20) == 0) || + (std::strncmp (argv[i], "--multithreadML", 20) == 0)) { + multiThreadML = true; + break; + } + } + + // Load the message service plug-in + + if(multiThreadML) { + theMessageServicePresence = std::shared_ptr(edm::PresenceFactory::get()-> + makePresence("MessageServicePresence").release()); + } + else { + theMessageServicePresence = std::shared_ptr(edm::PresenceFactory::get()-> + makePresence("SingleThreadMSPresence").release()); + } + + context = "Processing command line arguments"; + std::string descString(argv[0]); + descString += " [options] [--"; + descString += kParameterSetOpt; + descString += "] config_file \nAllowed options"; + boost::program_options::options_description desc(descString); + + desc.add_options() + (kHelpCommandOpt, "produce help message") + (kParameterSetCommandOpt, boost::program_options::value(), "configuration file") + (kJobreportCommandOpt, boost::program_options::value(), + "file name to use for a job report file: default extension is .xml") + (kEnableJobreportCommandOpt, + "enable job report files (if any) specified in configuration file") + (kJobModeCommandOpt, boost::program_options::value(), + "Job Mode for MessageLogger defaults - default mode is grid") + (kNumberOfThreadsCommandOpt,boost::program_options::value(), + "Number of threads to use in job (0 is use all CPUs)") + (kSizeOfStackForThreadCommandOpt,boost::program_options::value(), + "Size of stack in KB to use for extra threads (0 is use system default size)") + (kMultiThreadMessageLoggerOpt, + "MessageLogger handles multiple threads - default is single-thread") + (kStrictOpt, "strict parsing"); + + // anything at the end will be ignored, and sent to python + boost::program_options::positional_options_description p; + p.add(kParameterSetOpt, 1).add(kPythonOpt, -1); + + // This --fwk option is not used anymore, but I'm leaving it around as + // it might be useful again in the future for code development + // purposes. We originally used it when implementing the boost + // state machine code. + boost::program_options::options_description hidden("hidden options"); + hidden.add_options()("fwk", "For use only by Framework Developers") + (kPythonOpt, boost::program_options::value< std::vector >(), + "options at the end to be passed to python"); + + boost::program_options::options_description all_options("All Options"); + all_options.add(desc).add(hidden); + + boost::program_options::variables_map vm; + try { + store(boost::program_options::command_line_parser(argc, argv).options(all_options).positional(p).run(), vm); + notify(vm); + } + catch (boost::program_options::error const& iException) { + edm::LogAbsolute("CommandLineProcessing") << "cmsRun: Error while trying to process command line arguments:\n" + << iException.what() + << "\nFor usage and an options list, please do 'cmsRun --help'."; + return edm::errors::CommandLineProcessing; + } + + if (vm.count(kHelpOpt)) { + std::cout << desc << std::endl; + if (!vm.count(kParameterSetOpt)) edm::HaltMessageLogging(); + return 0; + } + + if (!vm.count(kParameterSetOpt)) { + edm::LogAbsolute("ConfigFileNotFound") << "cmsRun: No configuration file given.\n" + << "For usage and an options list, please do 'cmsRun --help'."; + edm::HaltMessageLogging(); + return edm::errors::ConfigFileNotFound; + } + std::string fileName(vm[kParameterSetOpt].as()); + + if (vm.count(kStrictOpt)) { + //edm::setStrictParsing(true); + edm::LogSystem("CommandLineProcessing") << "Strict configuration processing is now done from python"; + } + + context = "Creating the JobReport Service"; + // Decide whether to enable creation of job report xml file + // We do this first so any errors will be reported + std::string jobReportFile; + if (vm.count(kJobreportOpt)) { + jobReportFile = vm[kJobreportOpt].as(); + } else if(vm.count(kEnableJobreportOpt)) { + jobReportFile = "FrameworkJobReport.xml"; + } + jobReportStreamPtr = jobReportFile.empty() ? nullptr : std::make_unique(jobReportFile.c_str()); + + //NOTE: JobReport must have a lifetime shorter than jobReportStreamPtr so that when the JobReport destructor + // is called jobReportStreamPtr is still valid + auto jobRepPtr = std::make_unique(jobReportStreamPtr.get()); + jobRep.reset(new edm::serviceregistry::ServiceWrapper(std::move(jobRepPtr))); + edm::ServiceToken jobReportToken = + edm::ServiceRegistry::createContaining(jobRep); + + context = "Processing the python configuration file named "; + context += fileName; + std::shared_ptr processDesc; + try { + std::unique_ptr parameterSet = edm::cmspybind11::readConfig(fileName, argc, argv); + processDesc.reset(new edm::ProcessDesc(std::move(parameterSet))); + } + catch(cms::Exception& iException) { + edm::Exception e(edm::errors::ConfigFileReadError, "", iException); + throw e; + } + + // Determine the number of threads to use, and the per-thread stack size: + // - from the command line + // - from the "options" ParameterSet, if it exists + // - from default values (currently, 1 thread and 10 MB) + // + // Since TBB has already been initialised with the default values, re-initialise + // it only if different values are discovered. + // + // Finally, reflect the values being used in the "options" top level ParameterSet. + context = "Setting up number of threads"; + { + // default values + unsigned int nThreads = edm::s_defaultNumberOfThreads; + unsigned int stackSize = kDefaultSizeOfStackForThreadsInKB; + + // check the "options" ParameterSet + std::shared_ptr pset = processDesc->getProcessPSet(); + if (pset->existsAs("options", false)) { + auto const& ops = pset->getUntrackedParameterSet("options"); + if (ops.existsAs("numberOfThreads", false)) { + nThreads = ops.getUntrackedParameter("numberOfThreads"); + } + if (ops.existsAs("sizeOfStackForThreadsInKB", false)) { + stackSize = ops.getUntrackedParameter("sizeOfStackForThreadsInKB"); + } + } + + // check the command line options + if (vm.count(kNumberOfThreadsOpt)) { + nThreads = vm[kNumberOfThreadsOpt].as(); + } + if (vm.count(kSizeOfStackForThreadOpt)) { + stackSize = vm[kSizeOfStackForThreadOpt].as(); + } + + // if needed, re-initialise TBB + if (nThreads != edm::s_defaultNumberOfThreads or stackSize != kDefaultSizeOfStackForThreadsInKB) { + nThreads = setNThreads(nThreads, stackSize, tsiPtr); + } + + // update the numberOfThreads and sizeOfStackForThreadsInKB in the "options" ParameterSet + edm::ParameterSet newOp; + if (pset->existsAs("options", false)) { + newOp = pset->getUntrackedParameterSet("options"); + } + newOp.addUntrackedParameter("numberOfThreads", nThreads); + newOp.addUntrackedParameter("sizeOfStackForThreadsInKB", stackSize); + pset->insertParameterSet(true, "options", edm::ParameterSetEntry(newOp, false)); + } + + context = "Initializing default service configurations"; + + // Default parameters will be used for the default services + // if they are not overridden from the configuration files. + processDesc->addServices(edm::defaultCmsRunServices()); + + context = "Setting MessageLogger defaults"; + // Decide what mode of hardcoded MessageLogger defaults to use + if (vm.count(kJobModeOpt)) { + std::string jobMode = vm[kJobModeOpt].as(); + edm::MessageDrop::instance()->jobMode = jobMode; + } + + context = "Constructing the EventProcessor"; + EventProcessorWithSentry procTmp( + std::make_unique(processDesc, jobReportToken, edm::serviceregistry::kTokenOverrides)); + proc = std::move(procTmp); + + alwaysAddContext = false; + context = "Calling beginJob"; + proc->beginJob(); + + alwaysAddContext = false; + context = "Calling EventProcessor::runToCompletion (which does almost everything after beginJob and before endJob)"; + proc.on(); + auto status = proc->runToCompletion(); + if (status == edm::EventProcessor::epSignal) { + returnCode = edm::errors::CaughtSignal; + } + proc.off(); + + context = "Calling endJob"; + proc->endJob(); + return returnCode; + }); + } + // All exceptions which are not handled before propagating + // into main will get caught here. + catch (cms::Exception& ex) { + returnCode = ex.returnCode(); + if (!context.empty()) { + if (alwaysAddContext) { + ex.addContext(context); + } + else if (ex.context().empty()) { + ex.addContext(context); + } + } + if (!ex.alreadyPrinted()) { + if (jobRep.get() != nullptr) { + edm::printCmsException(ex, &(jobRep->get()), returnCode); + } + else { + edm::printCmsException(ex); + } + } + } + // Disable Root Error Handler. + SetErrorHandler(DefaultErrorHandler); + return returnCode; +} diff --git a/FWCore/Framework/interface/WorkerManager.h b/FWCore/Framework/interface/WorkerManager.h index 431a5d6dde303..28a235cb5d738 100644 --- a/FWCore/Framework/interface/WorkerManager.h +++ b/FWCore/Framework/interface/WorkerManager.h @@ -46,8 +46,6 @@ namespace edm { std::set& unscheduledLabels, std::vector& shouldBeUsedLabels); - void setOnDemandProducts(ProductRegistry& pregistry, std::set const& unscheduledLabels) const; - template void processOneOccurrence(typename T::MyPrincipal& principal, EventSetupImpl const& eventSetup, diff --git a/FWCore/Framework/src/Principal.cc b/FWCore/Framework/src/Principal.cc index c9aed7a137978..f7653b8761d50 100644 --- a/FWCore/Framework/src/Principal.cc +++ b/FWCore/Framework/src/Principal.cc @@ -139,12 +139,15 @@ namespace edm { // So, the non-alias product holders must be created first. // Therefore, on this first pass, skip current EDAliases. bool hasAliases = false; + bool hasSwitchAliases = false; for(auto const& prod : prodsList) { BranchDescription const& bd = prod.second; if(bd.branchType() == branchType_) { if(isForPrimaryProcess or bd.processName() == pc.processName()) { - if(bd.isAnyAlias()) { + if(bd.isAlias()) { hasAliases = true; + } else if(bd.isSwitchAlias()) { + hasSwitchAliases = true; } else { auto cbd = std::make_shared(bd); if(bd.produced()) { @@ -171,24 +174,28 @@ namespace edm { if(hasAliases) { for(auto const& prod : prodsList) { BranchDescription const& bd = prod.second; - if(bd.isAnyAlias() && bd.branchType() == branchType_) { + if(bd.isAlias() && bd.branchType() == branchType_) { + addAliasedProduct(std::make_shared(bd)); + } + } + } + // Finally process any SwitchProducer aliases + if(hasSwitchAliases) { + for(auto const& prod : prodsList) { + BranchDescription const& bd = prod.second; + if(bd.isSwitchAlias() && bd.branchType() == branchType_) { + assert(branchType_ == InEvent); auto cbd = std::make_shared(bd); - if(bd.isSwitchAlias()) { - assert(branchType_ == InEvent); - // Need different implementation for SwitchProducers not - // in any Path (onDemand) and for those in a Path in order - // to prevent the switch-aliased-for EDProducers from - // being run when the SwitchProducer is in a Path after a - // failing EDFilter. - if(bd.onDemand()) { - addSwitchAliasProduct(cbd); - } - else { - addSwitchProducerProduct(cbd); - } + // Need different implementation for SwitchProducers not + // in any Path (onDemand) and for those in a Path in order + // to prevent the switch-aliased-for EDProducers from + // being run when the SwitchProducer is in a Path after a + // failing EDFilter. + if(bd.onDemand()) { + addSwitchAliasProduct(cbd); } else { - addAliasedProduct(cbd); + addSwitchProducerProduct(cbd); } } } @@ -343,7 +350,7 @@ namespace edm { ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID()); assert(index != ProductResolverIndexInvalid); - addProductOrThrow(std::make_unique(std::move(bd), dynamic_cast(*productResolvers_[index]))); + addProductOrThrow(std::make_unique(std::move(bd), dynamic_cast(*productResolvers_[index]))); } void @@ -351,7 +358,7 @@ namespace edm { ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID()); assert(index != ProductResolverIndexInvalid); - addProductOrThrow(std::make_unique(std::move(bd), dynamic_cast(*productResolvers_[index]))); + addProductOrThrow(std::make_unique(std::move(bd), dynamic_cast(*productResolvers_[index]))); } void @@ -359,7 +366,7 @@ namespace edm { ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID()); assert(index != ProductResolverIndexInvalid); - addProductOrThrow(std::make_unique(std::move(bd), dynamic_cast(*productResolvers_[index]))); + addProductOrThrow(std::make_unique(std::move(bd), dynamic_cast(*productResolvers_[index]))); } void diff --git a/FWCore/Framework/src/ProductResolvers.cc b/FWCore/Framework/src/ProductResolvers.cc index c95721de8d805..2dd24438d65aa 100644 --- a/FWCore/Framework/src/ProductResolvers.cc +++ b/FWCore/Framework/src/ProductResolvers.cc @@ -656,7 +656,7 @@ namespace edm { } - SwitchBaseProductResolver::SwitchBaseProductResolver(std::shared_ptr bd, ProducedProductResolver& realProduct): + SwitchBaseProductResolver::SwitchBaseProductResolver(std::shared_ptr bd, DataManagingOrAliasProductResolver& realProduct): realProduct_(realProduct), productData_(std::move(bd)), prefetchRequested_(false), @@ -664,7 +664,7 @@ namespace edm { { // Parentage of this branch is always the same by construction, so we can compute the ID just "once" here. Parentage p; - p.setParents(std::vector{realProduct.branchDescription().branchID()}); + p.setParents(std::vector{realProduct.branchDescription().originalBranchID()}); parentageID_ = p.id(); ParentageRegistry::instance()->insertMapped(p); } diff --git a/FWCore/Framework/src/ProductResolvers.h b/FWCore/Framework/src/ProductResolvers.h index 8b26d7976ac2d..9ed23f3e6cd3c 100644 --- a/FWCore/Framework/src/ProductResolvers.h +++ b/FWCore/Framework/src/ProductResolvers.h @@ -33,7 +33,15 @@ namespace edm { class Worker; class ServiceToken; - class DataManagingProductResolver : public ProductResolverBase { + class DataManagingOrAliasProductResolver: public ProductResolverBase { + public: + DataManagingOrAliasProductResolver(): ProductResolverBase{} {} + + // Give AliasProductResolver and SwitchBaseProductResolver access by moving this method to public + void resetProductData_(bool deleteEarly) override = 0; + }; + + class DataManagingProductResolver : public DataManagingOrAliasProductResolver { public: enum class ProductStatus { ProductSet, @@ -43,7 +51,7 @@ namespace edm { ProductDeleted }; - DataManagingProductResolver(std::shared_ptr bd,ProductStatus iDefaultStatus): ProductResolverBase(), + DataManagingProductResolver(std::shared_ptr bd,ProductStatus iDefaultStatus): DataManagingOrAliasProductResolver(), productData_(bd), theStatus_(iDefaultStatus), defaultStatus_(iDefaultStatus){} @@ -52,7 +60,6 @@ namespace edm { void resetStatus() {theStatus_ = defaultStatus_;} - //Give AliasProductResolver access void resetProductData_(bool deleteEarly) override; protected: @@ -204,10 +211,10 @@ namespace edm { mutable std::atomic prefetchRequested_; }; - class AliasProductResolver : public ProductResolverBase { + class AliasProductResolver : public DataManagingOrAliasProductResolver { public: typedef ProducedProductResolver::ProductStatus ProductStatus; - explicit AliasProductResolver(std::shared_ptr bd, ProducedProductResolver& realProduct) : ProductResolverBase(), realProduct_(realProduct), bd_(bd) {} + explicit AliasProductResolver(std::shared_ptr bd, DataManagingOrAliasProductResolver& realProduct) : DataManagingOrAliasProductResolver(), realProduct_(realProduct), bd_(bd) {} void connectTo(ProductResolverBase const& iOther, Principal const* iParentPrincipal) final { realProduct_.connectTo(iOther, iParentPrincipal ); @@ -249,15 +256,15 @@ namespace edm { void resetProductData_(bool deleteEarly) override; bool singleProduct_() const override; - ProducedProductResolver& realProduct_; + DataManagingOrAliasProductResolver& realProduct_; std::shared_ptr bd_; }; // Switch is a mixture of DataManaging (for worker and provenance) and Alias (for product) - class SwitchBaseProductResolver: public ProductResolverBase { + class SwitchBaseProductResolver: public DataManagingOrAliasProductResolver { public: using ProductStatus = DataManagingProductResolver::ProductStatus; - SwitchBaseProductResolver(std::shared_ptr bd, ProducedProductResolver& realProduct); + SwitchBaseProductResolver(std::shared_ptr bd, DataManagingOrAliasProductResolver& realProduct); void connectTo(ProductResolverBase const& iOther, Principal const *iParentPrincipal) final; void setupUnscheduled(UnscheduledConfigurator const& iConfigure) final; @@ -267,7 +274,7 @@ namespace edm { WaitingTaskList& waitingTasks() const {return waitingTasks_;} Worker *worker() const {return worker_;} ProductStatus status() const {return status_;} - ProducedProductResolver const& realProduct() const {return realProduct_;} + DataManagingOrAliasProductResolver const& realProduct() const {return realProduct_;} std::atomic& prefetchRequested() const {return prefetchRequested_;} private: @@ -289,7 +296,7 @@ namespace edm { constexpr static const ProductStatus defaultStatus_ = ProductStatus::NotPut; // for "alias" view - ProducedProductResolver& realProduct_; + DataManagingOrAliasProductResolver& realProduct_; // for "product" view ProductData productData_; Worker *worker_ = nullptr; @@ -304,7 +311,7 @@ namespace edm { // For the case when SwitchProducer is on a Path class SwitchProducerProductResolver: public SwitchBaseProductResolver { public: - SwitchProducerProductResolver(std::shared_ptr bd, ProducedProductResolver& realProduct): + SwitchProducerProductResolver(std::shared_ptr bd, DataManagingOrAliasProductResolver& realProduct): SwitchBaseProductResolver(std::move(bd), realProduct) {} private: Resolution resolveProduct_(Principal const& principal, @@ -324,7 +331,7 @@ namespace edm { // For the case when SwitchProducer is not on any Path class SwitchAliasProductResolver: public SwitchBaseProductResolver { public: - SwitchAliasProductResolver(std::shared_ptr bd, ProducedProductResolver& realProduct): + SwitchAliasProductResolver(std::shared_ptr bd, DataManagingOrAliasProductResolver& realProduct): SwitchBaseProductResolver(std::move(bd), realProduct) {} private: Resolution resolveProduct_(Principal const& principal, diff --git a/FWCore/Framework/src/ProductSelector.cc b/FWCore/Framework/src/ProductSelector.cc index da0ea4ef2d390..4807efb2381d8 100644 --- a/FWCore/Framework/src/ProductSelector.cc +++ b/FWCore/Framework/src/ProductSelector.cc @@ -79,15 +79,24 @@ namespace edm { // Check if an equivalent branch has already been selected due to an EDAlias. // We only need the check for products produced in this process. if(desc.produced()) { + auto check = [&](BranchID const& branchID) { + auto iter = trueBranchIDToKeptBranchDesc.find(branchID); + if(iter != trueBranchIDToKeptBranchDesc.end()) { + throw edm::Exception(errors::Configuration, "Duplicate Output Selection") + << "Two (or more) equivalent branches have been selected for output.\n" + << "#1: " << BranchKey(desc) << "\n" + << "#2: " << BranchKey(*iter->second) << "\n" + << "Please drop at least one of them.\n"; + } + }; BranchID const& trueBranchID = desc.originalBranchID(); - std::map::const_iterator iter = trueBranchIDToKeptBranchDesc.find(trueBranchID); - if(iter != trueBranchIDToKeptBranchDesc.end()) { - throw edm::Exception(errors::Configuration, "Duplicate Output Selection") - << "Two (or more) equivalent branches have been selected for output.\n" - << "#1: " << BranchKey(desc) << "\n" - << "#2: " << BranchKey(*iter->second) << "\n" - << "Please drop at least one of them.\n"; + check(trueBranchID); + // In case of SwitchProducer, we have to check also the + // aliased-for BranchID for the case that the chosen case is an EDAlias + if(desc.isSwitchAlias()) { + check(desc.switchAliasForBranchID()); } + trueBranchIDToKeptBranchDesc.insert(std::make_pair(trueBranchID, &desc)); } } diff --git a/FWCore/Framework/src/Schedule.cc b/FWCore/Framework/src/Schedule.cc index c65e60049f080..581e3a8d7c84a 100644 --- a/FWCore/Framework/src/Schedule.cc +++ b/FWCore/Framework/src/Schedule.cc @@ -184,6 +184,17 @@ namespace edm { } } + if(auto iter = aliasMap.find(key); iter != aliasMap.end()) { + // If the same EDAlias defines multiple products pointing to the same product, throw + if(iter->second.moduleLabel() == alias) { + throw Exception(errors::Configuration, "EDAlias conflict\n") + << "The module label alias '" << alias << "' is used for multiple products of type '" + << friendlyClassName << "' with module label '" << moduleLabel << "' and instance name '" + << productInstanceName << "'. One alias has the instance name '" << iter->first.productInstanceName() + << "' and the other has the instance name '" << instanceAlias << "'."; + } + } + std::string const& theInstanceAlias(instanceAlias == star ? productInstanceName : instanceAlias); BranchKey aliasKey(friendlyClassName, alias, theInstanceAlias, processName); if(preg.productList().find(aliasKey) != preg.productList().end()) { @@ -284,7 +295,6 @@ namespace edm { assert(it != preg.productList().end()); preg.addLabelAlias(it->second, aliasEntry.second.moduleLabel(), aliasEntry.second.productInstanceName()); } - } typedef std::vector vstring; @@ -332,6 +342,7 @@ namespace edm { } // Check that non-chosen cases declare exactly the same branches + // Also set the alias-for branches to transient std::vector foundBranches; for(auto const& switchItem: switchMap) { auto const& switchLabel = switchItem.first; @@ -340,8 +351,19 @@ namespace edm { foundBranches.resize(chosenBranches.size()); for(auto const& caseLabel: caseLabels) { std::fill(foundBranches.begin(), foundBranches.end(), false); - for(auto const& item: preg.productList()) { + for(auto& nonConstItem: preg.productListUpdator()) { + auto const& item = nonConstItem; if(item.first.moduleLabel() == caseLabel) { + // Set the alias-for branch as transient so it gets fully ignored in output. + // I tried first to implicitly drop all branches with + // '@' in ProductSelector, but that gave problems on + // input (those branches would be implicitly dropped on + // input as well, leading to the SwitchProducer branches + // do be dropped as dependent ones, as the alias + // detection logic in RootFile says that the + // SwitchProducer branches are not alias branches) + nonConstItem.second.setTransient(true); + auto range = std::equal_range(chosenBranches.begin(), chosenBranches.end(), BranchKey(item.first.friendlyClassName(), switchLabel, item.first.productInstanceName(), @@ -587,11 +609,11 @@ namespace edm { } } //The unscheduled modules are at the end of the list, but we want them at the front - unsigned int n = streamSchedules_[0]->numberOfUnscheduledModules(); - if(n>0) { + unsigned int const nUnscheduledModules = streamSchedules_[0]->numberOfUnscheduledModules(); + if(nUnscheduledModules>0) { std::vector temp; temp.reserve(modulesToUse.size()); - auto itBeginUnscheduled = modulesToUse.begin()+modulesToUse.size()-n; + auto itBeginUnscheduled = modulesToUse.begin()+modulesToUse.size()-nUnscheduledModules; std::copy(itBeginUnscheduled,modulesToUse.end(), std::back_inserter(temp)); std::copy(modulesToUse.begin(),itBeginUnscheduled,std::back_inserter(temp)); @@ -621,6 +643,14 @@ namespace edm { reduceParameterSet(proc_pset, tns.getEndPaths(), modulesInConfig, usedModuleLabels, outputModulePathPositions); processEDAliases(proc_pset, processConfiguration->processName(), preg); + + // At this point all BranchDescriptions are created. Mark now the + // ones of unscheduled workers to be on-demand. + if(nUnscheduledModules > 0) { + std::set unscheduledModules(modulesToUse.begin(), modulesToUse.begin()+nUnscheduledModules); + preg.setUnscheduledProducts(unscheduledModules); + } + processSwitchProducers(proc_pset, processConfiguration->processName(), preg); proc_pset.registerIt(); processConfiguration->setParameterSetID(proc_pset.id()); diff --git a/FWCore/Framework/src/StreamSchedule.cc b/FWCore/Framework/src/StreamSchedule.cc index 4a7595b3a6533..8cb503384a10f 100644 --- a/FWCore/Framework/src/StreamSchedule.cc +++ b/FWCore/Framework/src/StreamSchedule.cc @@ -234,11 +234,7 @@ namespace edm { << "\n"; } } - if (!unscheduledLabels.empty()) { - number_of_unscheduled_modules_=unscheduledLabels.size(); - workerManager_.setOnDemandProducts(preg, unscheduledLabels); - } - + number_of_unscheduled_modules_ = unscheduledLabels.size(); initializeEarlyDelete(*modReg, opts,preg,allowEarlyDelete); diff --git a/FWCore/Framework/src/WorkerManager.cc b/FWCore/Framework/src/WorkerManager.cc index 3d3cb0a2b0d92..c0b179b9fdc27 100644 --- a/FWCore/Framework/src/WorkerManager.cc +++ b/FWCore/Framework/src/WorkerManager.cc @@ -67,16 +67,6 @@ namespace edm { } } - void WorkerManager::setOnDemandProducts(ProductRegistry& pregistry, std::set const& unscheduledLabels) const { - for(auto& prod : pregistry.productListUpdator()) { - if(prod.second.produced() && - prod.second.branchType() == InEvent && - unscheduledLabels.end() != unscheduledLabels.find(prod.second.moduleLabel())) { - prod.second.setOnDemand(true); - } - } - } - void WorkerManager::endJob() { for(auto& worker : allWorkers_) { worker->endJob(); diff --git a/FWCore/Framework/test/stubs/ToyIntProducers.cc b/FWCore/Framework/test/stubs/ToyIntProducers.cc index d2a7d3c522f3b..bf4dfffb948fb 100644 --- a/FWCore/Framework/test/stubs/ToyIntProducers.cc +++ b/FWCore/Framework/test/stubs/ToyIntProducers.cc @@ -471,6 +471,52 @@ namespace edmtest { } } + // + // Produces multiple IntProduct products based on other products + // + + class ManyIntWhenRegisteredProducer: public edm::global::EDProducer<> { + public: + explicit ManyIntWhenRegisteredProducer(edm::ParameterSet const& p): + sourceLabel_(p.getParameter("src")) + { + callWhenNewProductsRegistered([=](edm::BranchDescription const& iBranch) { + if(iBranch.moduleLabel() == sourceLabel_) { + if(iBranch.branchType() != edm::InEvent) { + throw edm::Exception(edm::errors::UnimplementedFeature) << "ManyIntWhenRegisteredProducer supports only event branches"; + } + + this->tokens_.push_back(Tokens{this->consumes(edm::InputTag{iBranch.moduleLabel(), iBranch.productInstanceName(), iBranch.processName()}), + this->produces(iBranch.productInstanceName())}); + } + }); + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("src"); + descriptions.addDefault(desc); + } + + void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override; + + private: + struct Tokens { + edm::EDGetTokenT get; + edm::EDPutTokenT put; + }; + + std::string sourceLabel_; + std::vector tokens_; + }; + + void + ManyIntWhenRegisteredProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const { + for(auto const& toks: tokens_) { + e.emplace(toks.put, e.get(toks.get)); + } + }; + } using edmtest::FailingProducer; @@ -487,6 +533,7 @@ using edmtest::IntProducerFromTransient; using edmtest::Int16_tProducer; using edmtest::AddIntsProducer; using edmtest::ManyIntProducer; +using edmtest::ManyIntWhenRegisteredProducer; DEFINE_FWK_MODULE(FailingProducer); DEFINE_FWK_MODULE(edmtest::FailingInRunProducer); DEFINE_FWK_MODULE(NonProducer); @@ -502,3 +549,4 @@ DEFINE_FWK_MODULE(IntProducerFromTransient); DEFINE_FWK_MODULE(Int16_tProducer); DEFINE_FWK_MODULE(AddIntsProducer); DEFINE_FWK_MODULE(ManyIntProducer); +DEFINE_FWK_MODULE(ManyIntWhenRegisteredProducer); diff --git a/FWCore/Integration/test/BuildFile.xml b/FWCore/Integration/test/BuildFile.xml index 2a96a680f7b55..f9934fbd76983 100644 --- a/FWCore/Integration/test/BuildFile.xml +++ b/FWCore/Integration/test/BuildFile.xml @@ -114,6 +114,10 @@ + + + + @@ -139,6 +143,13 @@ + + + + + + + diff --git a/FWCore/Integration/test/EDAlias_t.cpp b/FWCore/Integration/test/EDAlias_t.cpp new file mode 100644 index 0000000000000..00fd6429a5aba --- /dev/null +++ b/FWCore/Integration/test/EDAlias_t.cpp @@ -0,0 +1,114 @@ +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +#include "DataFormats/TestObjects/interface/ToyProducts.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/PythonParameterSet/interface/MakeParameterSets.h" +#include "FWCore/TestProcessor/interface/TestProcessor.h" + +#include + +static constexpr auto s_tag = "[EDAlias]"; + +TEST_CASE("Configuration", s_tag) { + const std::string baseConfig{ +R"_(from FWCore.TestProcessor.TestProcess import * +import FWCore.ParameterSet.Config as cms + +process = TestProcess() + +process.intprod = cms.EDProducer('IntProducer', ivalue = cms.int32(1)) +process.intalias = cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct')))) + +# Module to be tested can not be an EDAlias +process.test = cms.EDProducer('AddIntsProducer', labels = cms.vstring('intalias')) + +process.moduleToTest(process.test, cms.Task(process.intprod)) +)_"}; + + edm::test::TestProcessor::Config config{ baseConfig }; + + SECTION("Base configuration is OK") { + REQUIRE_NOTHROW(edm::test::TestProcessor(config)); + } + + SECTION("No event data") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.test()); + } + + SECTION("beginJob and endJob only") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.testBeginAndEndJobOnly()); + } + + SECTION("Run with no LuminosityBlocks") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.testRunWithNoLuminosityBlocks()); + } + + SECTION("LuminosityBlock with no Events") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.testLuminosityBlockWithNoEvents()); + } + + SECTION("Getting value") { + edm::test::TestProcessor tester(config); + auto event = tester.test(); + REQUIRE(event.get()->value == 1); + } +} + +TEST_CASE("Configuration with two instance aliases to a single product", s_tag) { + const std::string baseConfig{ +R"_(from FWCore.TestProcessor.TestProcess import * +import FWCore.ParameterSet.Config as cms + +process = TestProcess() + +process.intprod = cms.EDProducer('IntProducer', ivalue = cms.int32(1)) +process.intalias = cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct')), + cms.PSet(type = cms.string('edmtestIntProduct'), + fromProductInstance = cms.string(''), + toProductInstance = cms.string('bar')) + ) +) + +# Module to be tested can not be an EDAlias +process.test = cms.EDProducer('AddIntsProducer', labels = cms.vstring('intalias', 'intalias:bar')) + +process.moduleToTest(process.test, cms.Task(process.intprod)) +)_"}; + + edm::test::TestProcessor::Config config{ baseConfig }; + + SECTION("Alias with two instances pointing to the same product is not allowed") { + REQUIRE_THROWS_WITH(edm::test::TestProcessor(config), Catch::Contains("EDAlias conflict") && Catch::Contains("is used for multiple products of type") && Catch::Contains("with module label") && Catch::Contains("and instance name") && Catch::Contains("alias has the instance name") && Catch::Contains("and the other has the instance name")); + } +} + +TEST_CASE("Configuration with two identical aliases pointing to different products") { + const std::string baseConfig{ +R"_(from FWCore.TestProcessor.TestProcess import * +import FWCore.ParameterSet.Config as cms + +process = TestProcess() + +process.intprod = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3)))) +process.intalias = cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct'), toProductInstance = cms.string(''), fromProductInstance = cms.string('')), + cms.PSet(type = cms.string('edmtestIntProduct'), toProductInstance = cms.string(''), fromProductInstance = cms.string('foo')) + ) +) + +# Module to be tested can not be an EDAlias +process.test = cms.EDProducer('AddIntsProducer', labels = cms.vstring('intalias')) + +process.moduleToTest(process.test, cms.Task(process.intprod)) +)_"}; + + edm::test::TestProcessor::Config config{ baseConfig }; + + SECTION("Alias with two instances pointing to the same product is not allowed") { + REQUIRE_THROWS_WITH(edm::test::TestProcessor(config), Catch::Contains("EDAlias conflict") && Catch::Contains("and product instance alias") && Catch::Contains("are used for multiple products of type") && Catch::Contains("One has module label") && Catch::Contains("the other has module label")); + } +} diff --git a/FWCore/Integration/test/SwitchProducerProvenanceAnalyzer.cc b/FWCore/Integration/test/SwitchProducerProvenanceAnalyzer.cc index 234597741db2b..81cbe4f1e7fb9 100644 --- a/FWCore/Integration/test/SwitchProducerProvenanceAnalyzer.cc +++ b/FWCore/Integration/test/SwitchProducerProvenanceAnalyzer.cc @@ -25,11 +25,15 @@ namespace edmtest { edm::EDGetTokenT inputToken1_; edm::EDGetTokenT inputToken2_; + std::string producerPrefix_; + bool const aliasMode_; }; SwitchProducerProvenanceAnalyzer::SwitchProducerProvenanceAnalyzer(edm::ParameterSet const& iConfig): inputToken1_(consumes(iConfig.getParameter("src1"))), - inputToken2_(consumes(iConfig.getParameter("src2"))) + inputToken2_(consumes(iConfig.getParameter("src2"))), + producerPrefix_(iConfig.getParameter("producerPrefix")), + aliasMode_(iConfig.getParameter("aliasMode")) {} void SwitchProducerProvenanceAnalyzer::analyze(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const& iSetup) const { @@ -82,15 +86,27 @@ namespace edmtest { // Here is where Switch differs from a normal EDProducer: each Switch output branch has exactly one parent assert(parent.parents().size() == 1); auto const& parentProvenance = iEvent.getProvenance(parent.parents()[0]); - assert(parentProvenance.branchDescription().moduleLabel() == moduleLabel+"@test"+std::to_string(mode)); + edm::ProductProvenance const *parentProductProvenance = nullptr; + if(not (aliasMode_ and mode == 2)) { + // If parent is EDAlias, it is skipped in the provenance, so in + // that case the normal grandparent can be found on the place of + // the parent. - // Check grandparent as well - auto const *parentProductProvenance = parentProvenance.productProvenance(); - assert(parentProductProvenance != nullptr); - auto const& grandParent = parentProductProvenance->parentage(); + assert(parentProvenance.branchDescription().moduleLabel() == moduleLabel+"@test"+std::to_string(mode)); + + // Check grandparent as well + parentProductProvenance = parentProvenance.productProvenance(); + assert(parentProductProvenance != nullptr); + } + auto const& grandParent = parentProductProvenance ? parentProductProvenance->parentage() : parent; + //auto const& grandParent = parentProductProvenance->parentage(); assert(grandParent.parents().size() == 1); // behaviour of the AddIntsProducer auto const& grandParentProvenance = iEvent.getProvenance(grandParent.parents()[0]); - assert(grandParentProvenance.branchDescription().moduleLabel() == moduleLabel+std::to_string(mode)); + int postfix = mode; + if(aliasMode_ and mode == 2) { + postfix = 3; + } + assert(grandParentProvenance.branchDescription().moduleLabel() == producerPrefix_+std::to_string(postfix)); } } using edmtest::SwitchProducerProvenanceAnalyzer; diff --git a/FWCore/Integration/test/SwitchProducer_t.cpp b/FWCore/Integration/test/SwitchProducer_t.cpp index 696c979799510..cec34fea8bfe8 100644 --- a/FWCore/Integration/test/SwitchProducer_t.cpp +++ b/FWCore/Integration/test/SwitchProducer_t.cpp @@ -10,8 +10,17 @@ static constexpr auto s_tag = "[SwitchProducer]"; -TEST_CASE("Configuration", s_tag) { - const std::string baseConfig{ +namespace { + std::string makeConfig(bool test2Enabled, const std::string& test1, const std::string& test2, + const std::string& otherprod = "", const std::string& othername = "") { + std::string otherline; + std::string othertask; + if(not otherprod.empty()) { + otherline = "process."+othername+" = "+otherprod+"\n"; + othertask = ", cms.Task(process."+othername+")"; + } + + return std::string{ R"_(from FWCore.TestProcessor.TestProcess import * import FWCore.ParameterSet.Config as cms @@ -20,36 +29,82 @@ class SwitchProducerTest(cms.SwitchProducer): super(SwitchProducerTest,self).__init__( dict( test1 = lambda: (True, -10), - test2 = lambda: (True, -9) - ), **kargs) - + test2 = lambda: ()_"} + (test2Enabled ? "True" : "False") + ", -9)\n" + +R"_( ), **kargs) process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('IntProducer', ivalue = cms.int32(1)), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet()) -) -process.moduleToTest(process.s) -)_"}; +)_" + otherline + +R"_(process.s = SwitchProducerTest( + test1 = )_" + test1 + ",\n" + +" test2 = " + test2 + "\n" + +")\n" + +"process.moduleToTest(process.s"+othertask+")\n"; + } +} - const std::string baseConfigTest2Disabled{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms +TEST_CASE("Configuration", s_tag) { + const std::string test1{"cms.EDProducer('IntProducer', ivalue = cms.int32(1))"}; + const std::string test2{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet())"}; -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (False, -9) - ), **kargs) + const std::string baseConfig = makeConfig(true, test1, test2); + const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2); -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('IntProducer', ivalue = cms.int32(1)), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet()) -) -process.moduleToTest(process.s) -)_"}; + SECTION("Configuration hash is not changed") { + auto pset = edm::boost_python::readConfig(baseConfig); + auto psetTest2Disabled = edm::boost_python::readConfig(baseConfigTest2Disabled); + pset->registerIt(); + psetTest2Disabled->registerIt(); + REQUIRE(pset->id() == psetTest2Disabled->id()); + } + + edm::test::TestProcessor::Config config{ baseConfig }; + edm::test::TestProcessor::Config configTest2Disabled{ baseConfigTest2Disabled }; + + SECTION("Base configuration is OK") { + REQUIRE_NOTHROW(edm::test::TestProcessor(config)); + } + + SECTION("No event data") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.test()); + } + + SECTION("beginJob and endJob only") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.testBeginAndEndJobOnly()); + } + + SECTION("Run with no LuminosityBlocks") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.testRunWithNoLuminosityBlocks()); + } + + SECTION("LuminosityBlock with no Events") { + edm::test::TestProcessor tester(config); + REQUIRE_NOTHROW(tester.testLuminosityBlockWithNoEvents()); + } + + SECTION("Test2 enabled") { + edm::test::TestProcessor tester(config); + auto event = tester.test(); + REQUIRE(event.get()->value == 2); + } + + SECTION("Test2 disabled") { + edm::test::TestProcessor tester(configTest2Disabled); + auto event = tester.test(); + REQUIRE(event.get()->value == 1); + } +} + +TEST_CASE("Configuration with EDAlias", s_tag) { + const std::string otherprod{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet())"}; + const std::string othername{"intprod"}; + + const std::string test1{"cms.EDProducer('IntProducer', ivalue = cms.int32(1))"}; + const std::string test2{"cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct'))))"}; + + const std::string baseConfig = makeConfig(true, test1, test2, otherprod, othername); + const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2, otherprod, othername); SECTION("Configuration hash is not changed") { auto pset = edm::boost_python::readConfig(baseConfig); @@ -97,51 +152,52 @@ process.moduleToTest(process.s) auto event = tester.test(); REQUIRE(event.get()->value == 1); } -}; +} + TEST_CASE("Configuration with many branches", s_tag) { - const std::string baseConfig{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms + const std::string test1{R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(11)), + cms.PSet(instance=cms.string('bar'),value=cms.int32(21)))))_"}; + const std::string test2{R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(12)), + cms.PSet(instance=cms.string('bar'),value=cms.int32(22)))))_"}; -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (True, -9) - ), **kargs) + const std::string baseConfig = makeConfig(true, test1, test2); + const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2); -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(11)), - cms.PSet(instance=cms.string('bar'),value=cms.int32(21)))), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(12)), - cms.PSet(instance=cms.string('bar'),value=cms.int32(22)))) -) -process.moduleToTest(process.s) -)_"}; - const std::string baseConfigTest2Disabled{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms + edm::test::TestProcessor::Config config{ baseConfig }; + edm::test::TestProcessor::Config configTest2Disabled{ baseConfigTest2Disabled }; -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (False, -9) - ), **kargs) + SECTION("Test2 enabled") { + edm::test::TestProcessor tester(config); + auto event = tester.test(); + REQUIRE(event.get()->value == 2); + REQUIRE(event.get("foo")->value == 12); + REQUIRE(event.get("bar")->value == 22); + } -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(11)), - cms.PSet(instance=cms.string('bar'),value=cms.int32(21)))), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(12)), + SECTION("Test2 disabled") { + edm::test::TestProcessor tester(configTest2Disabled); + auto event = tester.test(); + REQUIRE(event.get()->value == 1); + REQUIRE(event.get("foo")->value == 11); + REQUIRE(event.get("bar")->value == 21); + } +} + +TEST_CASE("Configuration with many branches with EDAlias", s_tag) { + const std::string otherprod{R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(12)), cms.PSet(instance=cms.string('bar'),value=cms.int32(22)))) -) -process.moduleToTest(process.s) )_"}; + const std::string othername{"intprod"}; + + const std::string test1{R"_(cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(11)), + cms.PSet(instance=cms.string('bar'),value=cms.int32(21)))))_"}; + const std::string test2{R"_(cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string(''), toProductInstance = cms.string('')), + cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string('foo'), toProductInstance = cms.string('foo')), + cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string('bar'), toProductInstance = cms.string('bar')))))_"}; + + const std::string baseConfig = makeConfig(true, test1, test2, otherprod, othername); + const std::string baseConfigTest2Disabled = makeConfig(false, test1, test2, otherprod, othername); edm::test::TestProcessor::Config config{ baseConfig }; edm::test::TestProcessor::Config configTest2Disabled{ baseConfigTest2Disabled }; @@ -166,45 +222,31 @@ process.moduleToTest(process.s) TEST_CASE("Configuration with different branches", s_tag) { - const std::string baseConfig1{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms + const std::string test1{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet())"}; + const std::string test2{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3))))"}; -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (True, -9) - ), **kargs) + const std::string baseConfig1 = makeConfig(true, test1, test2); + const std::string baseConfig2 = makeConfig(false, test1, test2); -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet()), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3)))) -) -process.moduleToTest(process.s) -)_"}; + SECTION("Different branches are not allowed") { + edm::test::TestProcessor::Config config1{ baseConfig1 }; + REQUIRE_THROWS_WITH(edm::test::TestProcessor(config1), Catch::Contains("that does not produce a product") && Catch::Contains("that is produced by the chosen case")); - const std::string baseConfig2{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms + edm::test::TestProcessor::Config config2{ baseConfig2 }; + REQUIRE_THROWS(edm::test::TestProcessor(config1), Catch::Contains("with a product") && Catch::Contains("that is not produced by the chosen case")); + } +} -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (True, -9) - ), **kargs) +TEST_CASE("Configuration with different branches with EDAlias", s_tag) { + const std::string otherprod{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3))))"}; + const std::string othername{"intprod"}; -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3)))), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet()) -) -process.moduleToTest(process.s, cms.Task(process.i)) -)_"}; + const std::string test1{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet())"}; + const std::string test2{R"_(cms.EDAlias(intprod = cms.VPSet(cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string(''), toProductInstance = cms.string('')), + cms.PSet(type = cms.string('edmtestIntProduct'), fromProductInstance = cms.string('foo'), toProductInstance = cms.string('foo')))))_"}; + + const std::string baseConfig1 = makeConfig(true, test1, test2, otherprod, othername); + const std::string baseConfig2 = makeConfig(false, test1, test2, otherprod, othername); SECTION("Different branches are not allowed") { edm::test::TestProcessor::Config config1{ baseConfig1 }; @@ -218,25 +260,9 @@ process.moduleToTest(process.s, cms.Task(process.i)) TEST_CASE("Configuration with lumi and run", s_tag) { - const std::string baseConfig{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms - -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (True, -9) - ), **kargs) - -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('ThingProducer', nThings = cms.int32(10)), - test2 = cms.EDProducer('ThingProducer', nThings = cms.int32(20)) -) -process.moduleToTest(process.s) -)_"}; + const std::string test1{"cms.EDProducer('ThingProducer', nThings = cms.int32(10))"}; + const std::string test2{"cms.EDProducer('ThingProducer', nThings = cms.int32(20))"}; + const std::string baseConfig = makeConfig(true, test1, test2); edm::test::TestProcessor::Config config{ baseConfig }; @@ -247,45 +273,11 @@ process.moduleToTest(process.s) TEST_CASE("Configuration with ROOT branch alias", s_tag) { - const std::string baseConfig1{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms + const std::string test1{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3))))"}; + const std::string test2{"cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(4),branchAlias=cms.string('bar'))))"}; -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (True, -9) - ), **kargs) - -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3)))), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(4),branchAlias=cms.string('bar')))) -) -process.moduleToTest(process.s) -)_"}; - - const std::string baseConfig2{ -R"_(from FWCore.TestProcessor.TestProcess import * -import FWCore.ParameterSet.Config as cms - -class SwitchProducerTest(cms.SwitchProducer): - def __init__(self, **kargs): - super(SwitchProducerTest,self).__init__( - dict( - test1 = lambda: (True, -10), - test2 = lambda: (True, -9) - ), **kargs) - -process = TestProcess() -process.s = SwitchProducerTest( - test1 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(1), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(3),branchAlias=cms.string('bar')))), - test2 = cms.EDProducer('ManyIntProducer', ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string('foo'),value=cms.int32(4)))) -) -process.moduleToTest(process.s) -)_"}; + const std::string baseConfig1 = makeConfig(true, test1, test2); + const std::string baseConfig2 = makeConfig(false, test1, test2); SECTION("ROOT branch aliases are not supported for the chosen case") { edm::test::TestProcessor::Config config{ baseConfig1 }; diff --git a/FWCore/Integration/test/run_TestEDAlias.sh b/FWCore/Integration/test/run_TestEDAlias.sh new file mode 100755 index 0000000000000..fe4ef4186aafc --- /dev/null +++ b/FWCore/Integration/test/run_TestEDAlias.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +test=testEDAlias + +function die { echo Failure $1: status $2 ; exit $2 ; } + +pushd ${LOCAL_TMP_DIR} + + echo "*************************************************" + echo "EDAlias consumer in a Task" + cmsRun ${LOCAL_TEST_DIR}/${test}Task_cfg.py || die "cmsRun ${test}Task_cfg.py 1" $? + + echo "*************************************************" + echo "Test output" + cmsRun ${LOCAL_TEST_DIR}/${test}Analyze_cfg.py testEDAliasTask.root || die "cmsRun ${test}Analyze_cfg.py testEDAliasTask.root" $? + + echo "*************************************************" + echo "EDAlias consumer in a Path" + cmsRun ${LOCAL_TEST_DIR}/${test}Path_cfg.py || die "cmsRun ${test}Path_cfg.py 1" $? + + echo "*************************************************" + echo "Test output" + cmsRun ${LOCAL_TEST_DIR}/${test}Analyze_cfg.py testEDAliasTask.root || die "cmsRun ${test}Analyze_cfg.py testEDAliasPath.root" $? + +popd + +exit 0 diff --git a/FWCore/Integration/test/run_TestSwitchProducer.sh b/FWCore/Integration/test/run_TestSwitchProducer.sh index 59e08ee40780b..422303d651959 100755 --- a/FWCore/Integration/test/run_TestSwitchProducer.sh +++ b/FWCore/Integration/test/run_TestSwitchProducer.sh @@ -46,6 +46,22 @@ pushd ${LOCAL_TMP_DIR} echo "SwitchProducer in a Path after a failing filter, case test2 disabled" cmsRun ${LOCAL_TEST_DIR}/${test}PathFilter_cfg.py disableTest2 || die "cmsRun ${test}PathFilter_cfg.py 2" $? + + echo "*************************************************" + echo "Keeping SwitchProducer-with-EDAlias and the aliased-for product should fail" + cmsRun ${LOCAL_TEST_DIR}/${test}AliasOutput_cfg.py && die "cmsRun ${test}AliasOutput_cfg.py did not throw an exception" $? + + echo "*************************************************" + echo "Alias to non-existent product should fail only when a corresponding product is accessed" + cmsRun ${LOCAL_TEST_DIR}/${test}AliasToNonExistent_cfg.py && die "cmsRun ${test}AliasToNonExistent_cfg.py did not throw an exception" $? + + echo "*************************************************" + echo "SwitchProducer-with-EDAlias being before the aliased-for producer in a Path should fail" + cmsRun ${LOCAL_TEST_DIR}/${test}PathWrongOrder_cfg.py && die "cmsRun ${test}PathWrongOrder_cfg.py did not throw an exception" $? + + echo "SwitchProducer tests succeeded" + echo "*************************************************" + popd exit 0 diff --git a/FWCore/Integration/test/testEDAliasAnalyze_cfg.py b/FWCore/Integration/test/testEDAliasAnalyze_cfg.py new file mode 100644 index 0000000000000..8ba51743e6c56 --- /dev/null +++ b/FWCore/Integration/test/testEDAliasAnalyze_cfg.py @@ -0,0 +1,15 @@ +import FWCore.ParameterSet.Config as cms +import sys + +process = cms.Process("ANA1") + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring("file:"+sys.argv[-1]) +) + +process.analyzer = cms.EDAnalyzer("IntTestAnalyzer", + moduleLabel = cms.untracked.string("intProducer"), + valueMustMatch = cms.untracked.int32(1) +) + +process.p = cms.Path(process.analyzer) diff --git a/FWCore/Integration/test/testEDAliasPath_cfg.py b/FWCore/Integration/test/testEDAliasPath_cfg.py new file mode 100644 index 0000000000000..118388aebcd33 --- /dev/null +++ b/FWCore/Integration/test/testEDAliasPath_cfg.py @@ -0,0 +1,35 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("PROD1") + +process.options = cms.untracked.PSet( + numberOfStreams = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1) +) + +process.source = cms.Source("EmptySource") + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(3) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testEDAliasPath.root'), + outputCommands = cms.untracked.vstring( + 'keep *_intProducer_*_*', + ) +) + +process.intProducerOrig = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(1)) + +process.intAlias = cms.EDAlias( + intProducerOrig = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"))) +) + +process.intProducer = cms.EDProducer("ManyIntWhenRegisteredProducer", src = cms.string("intAlias")) + +process.t = cms.Task(process.intProducerOrig) +process.p = cms.Path(process.intProducer, process.t) + +process.e = cms.EndPath(process.out) diff --git a/FWCore/Integration/test/testEDAliasTask_cfg.py b/FWCore/Integration/test/testEDAliasTask_cfg.py new file mode 100644 index 0000000000000..9b1bef9cd5fa7 --- /dev/null +++ b/FWCore/Integration/test/testEDAliasTask_cfg.py @@ -0,0 +1,35 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("PROD1") + +process.options = cms.untracked.PSet( + numberOfStreams = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1) +) + +process.source = cms.Source("EmptySource") + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(3) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testEDAliasTask.root'), + outputCommands = cms.untracked.vstring( + 'keep *_intProducer_*_*', + ) +) + +process.intProducerOrig = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(1)) + +process.intAlias = cms.EDAlias( + intProducerOrig = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"))) +) + +process.intProducer = cms.EDProducer("ManyIntWhenRegisteredProducer", src = cms.string("intAlias")) + +process.t = cms.Task(process.intProducer, process.intProducerOrig) +process.p = cms.Path(process.t) + +process.e = cms.EndPath(process.out) diff --git a/FWCore/Integration/test/testSwitchProducerAliasOutput_cfg.py b/FWCore/Integration/test/testSwitchProducerAliasOutput_cfg.py new file mode 100644 index 0000000000000..4aa9907dadcfd --- /dev/null +++ b/FWCore/Integration/test/testSwitchProducerAliasOutput_cfg.py @@ -0,0 +1,45 @@ +import FWCore.ParameterSet.Config as cms + +class SwitchProducerTest(cms.SwitchProducer): + def __init__(self, **kargs): + super(SwitchProducerTest,self).__init__( + dict( + test1 = lambda: (True, -10), + test2 = lambda: (True, -9) + ), **kargs) + +process = cms.Process("PROD1") + +process.options = cms.untracked.PSet( + numberOfStreams = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1) +) + +process.source = cms.Source("EmptySource") + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(3) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testSwitchProducerAliasOutput.root'), + outputCommands = cms.untracked.vstring( + 'keep *_intProducer3_*_*', + 'keep *_intProducerAlias_*_*' + ) +) + +process.intProducer1 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(1), throw = cms.untracked.bool(True)) +process.intProducer3 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string("foo"),value=cms.int32(2)))) + +process.intProducerAlias = SwitchProducerTest( + test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), + test2 = cms.EDAlias(intProducer3 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string(""), toProductInstance = cms.string("")), + cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string("foo"), toProductInstance = cms.string("other")))) +) + +process.t = cms.Task(process.intProducerAlias, process.intProducer1, process.intProducer3) +process.p = cms.Path(process.t) + +process.e = cms.EndPath(process.out) diff --git a/FWCore/Integration/test/testSwitchProducerAliasToNonExistent_cfg.py b/FWCore/Integration/test/testSwitchProducerAliasToNonExistent_cfg.py new file mode 100644 index 0000000000000..b45874a15215b --- /dev/null +++ b/FWCore/Integration/test/testSwitchProducerAliasToNonExistent_cfg.py @@ -0,0 +1,46 @@ +import FWCore.ParameterSet.Config as cms + +class SwitchProducerTest(cms.SwitchProducer): + def __init__(self, **kargs): + super(SwitchProducerTest,self).__init__( + dict( + test1 = lambda: (True, -10), + test2 = lambda: (True, -9) + ), **kargs) + +process = cms.Process("PROD1") + +process.options = cms.untracked.PSet( + numberOfStreams = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1) +) + +process.source = cms.Source("EmptySource") + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(3) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testSwitchProducerAliasOutput.root'), + outputCommands = cms.untracked.vstring( + 'keep *_intProducer3_*_*', + 'keep *_intProducerAlias__*' + ) +) + +process.intProducer1 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(1), throw = cms.untracked.bool(True)) +process.intProducer4 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(42), throw = cms.untracked.bool(True)) + +process.intProducerAlias = SwitchProducerTest( + test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), + test2 = cms.EDAlias(intProducer4 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string(""), toProductInstance = cms.string(""))), + intProducer3 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string("foo"), toProductInstance = cms.string("")) +)) +) + +process.t = cms.Task(process.intProducerAlias, process.intProducer1, process.intProducer4) +process.p = cms.Path(process.t) + +process.e = cms.EndPath(process.out) diff --git a/FWCore/Integration/test/testSwitchProducerPathFilter_cfg.py b/FWCore/Integration/test/testSwitchProducerPathFilter_cfg.py index 1fc15b49f2fea..f376c7875fec8 100644 --- a/FWCore/Integration/test/testSwitchProducerPathFilter_cfg.py +++ b/FWCore/Integration/test/testSwitchProducerPathFilter_cfg.py @@ -35,15 +35,27 @@ def __init__(self, **kargs): process.intProducer1 = cms.EDProducer("FailingProducer") process.intProducer2 = cms.EDProducer("FailingProducer") +process.intProducer3 = cms.EDProducer("ManyIntProducer", + ivalue = cms.int32(3), + values = cms.VPSet(cms.PSet(instance=cms.string("foo"),value=cms.int32(31))), + throw = cms.untracked.bool(True) +) process.intProducer = SwitchProducerTest( test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), test2 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer2")) ) +# SwitchProducer with an alias +process.intProducerAlias = SwitchProducerTest( + test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), + test2 = cms.EDAlias(intProducer3 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string(""), toProductInstance = cms.string("")), + cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string("foo"), toProductInstance = cms.string("other")))) +) + process.f = cms.EDFilter("TestFilterModule", acceptValue = cms.untracked.int32(-1)) -process.t = cms.Task(process.intProducer1, process.intProducer2) +process.t = cms.Task(process.intProducer1, process.intProducer2, process.intProducer3) process.p = cms.Path(process.f+process.intProducer, process.t) process.e = cms.EndPath(process.out) diff --git a/FWCore/Integration/test/testSwitchProducerPathWrongOrder_cfg.py b/FWCore/Integration/test/testSwitchProducerPathWrongOrder_cfg.py new file mode 100644 index 0000000000000..9580d8dc84a94 --- /dev/null +++ b/FWCore/Integration/test/testSwitchProducerPathWrongOrder_cfg.py @@ -0,0 +1,45 @@ +import FWCore.ParameterSet.Config as cms + +class SwitchProducerTest(cms.SwitchProducer): + def __init__(self, **kargs): + super(SwitchProducerTest,self).__init__( + dict( + test1 = lambda: (True, -10), + test2 = lambda: (True, -9) + ), **kargs) + +process = cms.Process("PROD1") + +process.options = cms.untracked.PSet( + numberOfStreams = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1) +) + +process.source = cms.Source("EmptySource") + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(3) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testSwitchProducerPathWrongOrder.root'), + outputCommands = cms.untracked.vstring( + 'keep *_intProducerAlias_*_*' + ) +) + +process.intProducer1 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(1), throw = cms.untracked.bool(True)) +process.intProducer3 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(3), values = cms.VPSet(cms.PSet(instance=cms.string("foo"),value=cms.int32(31)))) + +# SwitchProducer with an alias +process.intProducerAlias = SwitchProducerTest( + test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), + test2 = cms.EDAlias(intProducer3 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string(""), toProductInstance = cms.string("")), + cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string("foo"), toProductInstance = cms.string("other")))) +) + +process.t = cms.Task(process.intProducer1) +process.p = cms.Path(process.intProducerAlias + process.intProducer3, process.t) + +process.e = cms.EndPath(process.out) diff --git a/FWCore/Integration/test/testSwitchProducerPath_cfg.py b/FWCore/Integration/test/testSwitchProducerPath_cfg.py index d8d042878de73..3a956bc943720 100644 --- a/FWCore/Integration/test/testSwitchProducerPath_cfg.py +++ b/FWCore/Integration/test/testSwitchProducerPath_cfg.py @@ -35,17 +35,25 @@ def __init__(self, **kargs): process.intProducer1 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(1)) process.intProducer2 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(2)) +process.intProducer3 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(3), values = cms.VPSet(cms.PSet(instance=cms.string("foo"),value=cms.int32(31)))) if enableTest2: process.intProducer1.throw = cms.untracked.bool(True) else: process.intProducer2.throw = cms.untracked.bool(True) + process.intProducer3.throw = cms.untracked.bool(True) process.intProducer = SwitchProducerTest( test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), test2 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer2")) ) +# SwitchProducer with an alias +process.intProducerAlias = SwitchProducerTest( + test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), + test2 = cms.EDAlias(intProducer3 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string(""), toProductInstance = cms.string("")), + cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string("foo"), toProductInstance = cms.string("other")))) +) -process.t = cms.Task(process.intProducer1, process.intProducer2) -process.p = cms.Path(process.intProducer, process.t) +process.t = cms.Task(process.intProducer1, process.intProducer2, process.intProducer3) +process.p = cms.Path(process.intProducer + process.intProducerAlias, process.t) process.e = cms.EndPath(process.out) diff --git a/FWCore/Integration/test/testSwitchProducerProvenanceAnalyzer_cfg.py b/FWCore/Integration/test/testSwitchProducerProvenanceAnalyzer_cfg.py index 60ff3e0cbb4ed..1647f89c63402 100644 --- a/FWCore/Integration/test/testSwitchProducerProvenanceAnalyzer_cfg.py +++ b/FWCore/Integration/test/testSwitchProducerProvenanceAnalyzer_cfg.py @@ -9,7 +9,16 @@ process.analyzer = cms.EDAnalyzer("SwitchProducerProvenanceAnalyzer", src1 = cms.InputTag("intProducer"), - src2 = cms.InputTag("intProducer", "other") + src2 = cms.InputTag("intProducer", "other"), + producerPrefix = cms.string("intProducer"), + aliasMode = cms.bool(False) ) -process.p = cms.Path(process.analyzer) +process.analyzerAlias = cms.EDAnalyzer("SwitchProducerProvenanceAnalyzer", + src1 = cms.InputTag("intProducerAlias"), + src2 = cms.InputTag("intProducerAlias", "other"), + producerPrefix = cms.string("intProducer"), + aliasMode = cms.bool(True) +) + +process.p = cms.Path(process.analyzer + process.analyzerAlias) diff --git a/FWCore/Integration/test/testSwitchProducerTask_cfg.py b/FWCore/Integration/test/testSwitchProducerTask_cfg.py index f6711c302eaeb..c69b2e14e1a35 100644 --- a/FWCore/Integration/test/testSwitchProducerTask_cfg.py +++ b/FWCore/Integration/test/testSwitchProducerTask_cfg.py @@ -30,29 +30,46 @@ def __init__(self, **kargs): fileName = cms.untracked.string('testSwitchProducerTask%d.root' % (1 if enableTest2 else 2,)), outputCommands = cms.untracked.vstring( 'keep *_intProducer_*_*', - 'keep *_intProducerOther_*_*' + 'keep *_intProducerOther_*_*', + 'keep *_intProducerAlias_*_*', + 'keep *_intProducerAlias2_foo_*', ) ) process.intProducer1 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(1)) process.intProducer2 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(2)) +process.intProducer3 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(2), values = cms.VPSet(cms.PSet(instance=cms.string("foo"),value=cms.int32(2)))) +process.intProducer4 = cms.EDProducer("ManyIntProducer", ivalue = cms.int32(42), throw = cms.untracked.bool(True)) if enableTest2: process.intProducer1.throw = cms.untracked.bool(True) else: process.intProducer2.throw = cms.untracked.bool(True) + process.intProducer3.throw = cms.untracked.bool(True) process.intProducer = SwitchProducerTest( test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), test2 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer2")) ) - # Test also existence of another SwitchProducer here process.intProducerOther = SwitchProducerTest( test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), test2 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer2")) ) +# SwitchProducer with an alias +process.intProducerAlias = SwitchProducerTest( + test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), + test2 = cms.EDAlias(intProducer3 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string(""), toProductInstance = cms.string("")), + cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string("foo"), toProductInstance = cms.string("other")))) +) + +process.intProducerAlias2 = SwitchProducerTest( + test1 = cms.EDProducer("AddIntsProducer", labels = cms.vstring("intProducer1")), + test2 = cms.EDAlias(intProducer4 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string(""), toProductInstance = cms.string(""))), + intProducer3 = cms.VPSet(cms.PSet(type = cms.string("edmtestIntProduct"), fromProductInstance = cms.string("foo"), toProductInstance = cms.string("other")))) +) -process.t = cms.Task(process.intProducer, process.intProducerOther, process.intProducer1, process.intProducer2) +process.t = cms.Task(process.intProducer, process.intProducerOther, process.intProducerAlias, process.intProducerAlias2, + process.intProducer1, process.intProducer2, process.intProducer3, process.intProducer4) process.p = cms.Path(process.t) process.e = cms.EndPath(process.out) diff --git a/FWCore/ParameterSet/python/Config.py b/FWCore/ParameterSet/python/Config.py index d8566c5c13551..063dafa2a56df 100644 --- a/FWCore/ParameterSet/python/Config.py +++ b/FWCore/ParameterSet/python/Config.py @@ -109,6 +109,7 @@ def __init__(self,name,*Mods): raise RuntimeError("Error: The process name is an empty string or contains non-alphanumeric characters") self.__dict__['_Process__filters'] = {} self.__dict__['_Process__producers'] = {} + self.__dict__['_Process__switchproducers'] = {} self.__dict__['_Process__source'] = None self.__dict__['_Process__looper'] = None self.__dict__['_Process__subProcesses'] = [] @@ -143,6 +144,9 @@ def setStrict(self, value): def producerNames(self): """Returns a string containing all the EDProducer labels separated by a blank""" return ' '.join(self.producers_().keys()) + def switchProducerNames(self): + """Returns a string containing all the SwitchProducer labels separated by a blank""" + return ' '.join(self.switchProducers_().keys()) def analyzerNames(self): """Returns a string containing all the EDAnalyzer labels separated by a blank""" return ' '.join(self.analyzers_().keys()) @@ -185,6 +189,10 @@ def producers_(self): """returns a dict of the producers that have been added to the Process""" return DictTypes.FixedKeysDict(self.__producers) producers = property(producers_,doc="dictionary containing the producers for the process") + def switchProducers_(self): + """returns a dict of the SwitchProducers that have been added to the Process""" + return DictTypes.FixedKeysDict(self.__switchproducers) + switchProducers = property(switchProducers_,doc="dictionary containing the SwitchProducers for the process") def source_(self): """returns the source that has been added to the Process or None if none have been added""" return self.__source @@ -520,6 +528,8 @@ def _placeOutputModule(self,name,mod): self._place(name, mod, self.__outputmodules) def _placeProducer(self,name,mod): self._place(name, mod, self.__producers) + def _placeSwitchProducer(self,name,mod): + self._place(name, mod, self.__switchproducers) def _placeFilter(self,name,mod): self._place(name, mod, self.__filters) def _placeAnalyzer(self,name,mod): @@ -673,6 +683,9 @@ def dumpConfig(self, options=PrintOptions()): config+=self._dumpConfigNamedList(six.iteritems(self.producers_()), 'module', options) + config+=self._dumpConfigNamedList(six.iteritems(self.switchProducers_()), + 'module', + options) config+=self._dumpConfigNamedList(six.iteritems(self.filters_()), 'module', options) @@ -818,8 +831,9 @@ def _dumpPython(self, d, options): return result def dumpPython(self, options=PrintOptions()): """return a string containing the equivalent process defined using python""" - result = "import FWCore.ParameterSet.Config as cms\n\n" - result += "process = cms.Process(\""+self.__name+"\")\n\n" + specialImportRegistry._reset() + header = "import FWCore.ParameterSet.Config as cms" + result = "process = cms.Process(\""+self.__name+"\")\n\n" if self.source_(): result += "process.source = "+self.source_().dumpPython(options) if self.looper_(): @@ -828,6 +842,7 @@ def dumpPython(self, options=PrintOptions()): result+=self._dumpPythonList(self.vpsets, options) result+=self._dumpPythonSubProcesses(self.subProcesses_(), options) result+=self._dumpPythonList(self.producers_(), options) + result+=self._dumpPythonList(self.switchProducers_(), options) result+=self._dumpPythonList(self.filters_() , options) result+=self._dumpPythonList(self.analyzers_(), options) result+=self._dumpPythonList(self.outputModules_(), options) @@ -842,7 +857,11 @@ def dumpPython(self, options=PrintOptions()): result+=self._dumpPythonList(self.aliases_(), options) if not self.schedule_() == None: result += 'process.schedule = ' + self.schedule.dumpPython(options) - return result + imports = specialImportRegistry.getSpecialImports() + if len(imports) > 0: + header += "\n" + "\n".join(imports) + header += "\n\n" + return header+result def _replaceInSequences(self, label, new): old = getattr(self,label) #TODO - replace by iterator concatenation @@ -885,6 +904,16 @@ def _insertManyInto(self, parameterSet, label, itemDict, tracked): # alphabetical order is easier to compare with old language l.sort() parameterSet.addVString(tracked, label, l) + def _insertSwitchProducersInto(self, parameterSet, labelModules, labelAliases, itemDict, tracked): + modules = parameterSet.getVString(tracked, labelModules) + aliases = parameterSet.getVString(tracked, labelAliases) + for name,value in six.iteritems(itemDict): + value.appendToProcessDescLists_(modules, aliases, name) + value.insertInto(parameterSet, name) + modules.sort() + aliases.sort() + parameterSet.addVString(tracked, labelModules, modules) + parameterSet.addVString(tracked, labelAliases, aliases) def _insertSubProcessesInto(self, parameterSet, label, itemList, tracked): l = [] subprocs = [] @@ -992,6 +1021,7 @@ def prune(self,verbose=False,keepUnresolvedSequencePlaceholders=False): temp = Schedule(*pths) usedModules=set(temp.moduleNames()) unneededModules = self._pruneModules(self.producers_(), usedModules) + unneededModules.update(self._pruneModules(self.switchProducers_(), usedModules)) unneededModules.update(self._pruneModules(self.filters_(), usedModules)) unneededModules.update(self._pruneModules(self.analyzers_(), usedModules)) #remove sequences that do not appear in remaining paths and endpaths @@ -1073,6 +1103,9 @@ def __extractPSet(self,pset): self._insertPaths(adaptor, nodeVisitor) all_modules_onTasksOrScheduled = { key:value for key, value in six.iteritems(all_modules) if value in nodeVisitor.modules } self._insertManyInto(adaptor, "@all_modules", all_modules_onTasksOrScheduled, True) + all_switches = self.switchProducers_().copy() + all_switches_onTasksOrScheduled = {key:value for key, value in six.iteritems(all_switches) if value in nodeVisitor.modules } + self._insertSwitchProducersInto(adaptor, "@all_modules", "@all_aliases", all_switches_onTasksOrScheduled, True) # Same as nodeVisitor except this one visits all the Tasks attached # to the process. processNodeVisitor = NodeVisitor() @@ -1495,6 +1528,13 @@ def __init__(self): self.values = dict() def __insertValue(self,tracked,label,value): self.values[label]=(tracked,value) + def __getValue(self,tracked,label): + pair = self.values[label] + if pair[0] != tracked: + raise Exception("Asked for %s parameter '%s', but it is %s" % ("tracked" if tracked else "untracked", + label, + "tracked" if pair[0] else "untracked")) + return pair[1] def addInt32(self,tracked,label,value): self.__insertValue(tracked,label,value) def addVInt32(self,tracked,label,value): @@ -1521,6 +1561,8 @@ def addString(self,tracked,label,value): self.__insertValue(tracked,label,value) def addVString(self,tracked,label,value): self.__insertValue(tracked,label,value) + def getVString(self,tracked,label): + return self.__getValue(tracked, label) def addInputTag(self,tracked,label,value): self.__insertValue(tracked,label,value) def addVInputTag(self,tracked,label,value): @@ -1559,6 +1601,7 @@ def __init__(self, **kargs): test3 = lambda: (True, -8), test4 = lambda: (True, -7) ), **kargs) + specialImportRegistry.registerSpecialImportForType(SwitchProducerTest, "from test import SwitchProducerTest") class TestModuleCommand(unittest.TestCase): def setUp(self): @@ -2688,6 +2731,61 @@ def testSwitchProducer(self): self.assertEqual((True,"Bar"), p.values["sp@test1"][1].values["@module_type"]) self.assertEqual((True,"EDProducer"), p.values["sp@test2"][1].values["@module_edm_type"]) self.assertEqual((True,"Foo"), p.values["sp@test2"][1].values["@module_type"]) + dump = proc.dumpPython() + self.assertEqual(dump.find('@'), -1) + self.assertEqual(specialImportRegistry.getSpecialImports(), ["from test import SwitchProducerTest"]) + self.assertTrue(dump.find("\nfrom test import SwitchProducerTest\n") != -1) + + # EDAlias as non-chosen case + proc = Process("test") + proc.sp = SwitchProducerTest(test2 = EDProducer("Foo", + a = int32(1), + b = PSet(c = int32(2))), + test1 = EDAlias(a = VPSet(PSet(type = string("Bar"))))) + proc.a = EDProducer("A") + proc.s = Sequence(proc.a + proc.sp) + proc.t = Task(proc.a, proc.sp) + proc.p = Path() + proc.p.associate(proc.t) + p = TestMakePSet() + proc.fillProcessDesc(p) + self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"]) + self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"]) + self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"]) + self.assertEqual((True, ["sp@test1", "sp@test2"]), p.values["sp"][1].values["@all_cases"]) + self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"]) + self.assertEqual(["a", "sp", "sp@test2"], p.values["@all_modules"][1]) + self.assertEqual(["sp@test1"], p.values["@all_aliases"][1]) + self.assertEqual((True,"EDProducer"), p.values["sp@test2"][1].values["@module_edm_type"]) + self.assertEqual((True,"Foo"), p.values["sp@test2"][1].values["@module_type"]) + self.assertEqual((True,"EDAlias"), p.values["sp@test1"][1].values["@module_edm_type"]) + self.assertEqual((True,"Bar"), p.values["sp@test1"][1].values["a"][1][0].values["type"]) + + # EDAlias as chosen case + proc = Process("test") + proc.sp = SwitchProducerTest(test1 = EDProducer("Foo", + a = int32(1), + b = PSet(c = int32(2))), + test2 = EDAlias(a = VPSet(PSet(type = string("Bar"))))) + proc.a = EDProducer("A") + proc.s = Sequence(proc.a + proc.sp) + proc.t = Task(proc.a, proc.sp) + proc.p = Path() + proc.p.associate(proc.t) + p = TestMakePSet() + proc.fillProcessDesc(p) + self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"]) + self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"]) + self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"]) + self.assertEqual((True, ["sp@test1", "sp@test2"]), p.values["sp"][1].values["@all_cases"]) + self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"]) + self.assertEqual(["a", "sp", "sp@test1"], p.values["@all_modules"][1]) + self.assertEqual(["sp@test2"], p.values["@all_aliases"][1]) + self.assertEqual((True,"EDProducer"), p.values["sp@test1"][1].values["@module_edm_type"]) + self.assertEqual((True,"Foo"), p.values["sp@test1"][1].values["@module_type"]) + self.assertEqual((True,"EDAlias"), p.values["sp@test2"][1].values["@module_edm_type"]) + self.assertEqual((True,"Bar"), p.values["sp@test2"][1].values["a"][1][0].values["type"]) + def testPrune(self): p = Process("test") p.a = EDAnalyzer("MyAnalyzer") @@ -3224,6 +3322,28 @@ def __init__(self): (m3 | m4).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer4")) self.assertEqual(p.a.type_(), "YourAnalyzer3") + # EDAlias + a = EDAlias(foo2 = VPSet(PSet(type = string("Foo2")))) + m = Modifier() + m._setChosen() + # Modify parameters + m.toModify(a, foo2 = {0: dict(type = "Foo3")}) + self.assertEqual(a.foo2[0].type, "Foo3") + # Add an alias + m.toModify(a, foo4 = VPSet(PSet(type = string("Foo4")))) + self.assertEqual(a.foo2[0].type, "Foo3") + self.assertEqual(a.foo4[0].type, "Foo4") + # Remove an alias + m.toModify(a, foo2 = None) + self.assertFalse(hasattr(a, "foo2")) + self.assertEqual(a.foo4[0].type, "Foo4") + # Replace (doesn't work out of the box because EDAlias is not _Parameterizable + m.toReplaceWith(a, EDAlias(bar = VPSet(PSet(type = string("Bar"))))) + self.assertFalse(hasattr(a, "foo2")) + self.assertFalse(hasattr(a, "foo4")) + self.assertTrue(hasattr(a, "bar")) + self.assertEqual(a.bar[0].type, "Bar") + # SwitchProducer sp = SwitchProducerTest(test1 = EDProducer("Foo", a = int32(1), @@ -3260,5 +3380,18 @@ def __init__(self): # Remove a producer m.toModify(sp, test2 = None) self.assertEqual(hasattr(sp, "test2"), False) + # Add an alias + m.toModify(sp, test2 = EDAlias(foo = VPSet(PSet(type = string("int"))))) + self.assertTrue(hasattr(sp.test2, "foo")) + # Replace an alias + m.toReplaceWith(sp.test2, EDAlias(bar = VPSet(PSet(type = string("int"))))) + self.assertTrue(hasattr(sp.test2, "bar")) + # Alternative way + m.toModify(sp, test2 = EDAlias(xyzzy = VPSet(PSet(type = string("int"))))) + self.assertTrue(hasattr(sp.test2, "xyzzy")) + # Replace an alias with EDProducer + self.assertRaises(TypeError, lambda: m.toReplaceWith(sp.test2, EDProducer("Foo"))) + m.toModify(sp, test2 = EDProducer("Foo")) + unittest.main() diff --git a/FWCore/ParameterSet/python/Mixins.py b/FWCore/ParameterSet/python/Mixins.py index ffa32a1c1c05e..6797eaf230134 100644 --- a/FWCore/ParameterSet/python/Mixins.py +++ b/FWCore/ParameterSet/python/Mixins.py @@ -19,6 +19,37 @@ def indent(self): def unindent(self): self.indent_ -= self.deltaIndent_ +class _SpecialImportRegistry(object): + """This class collects special import statements of configuration types""" + def __init__(self): + self._registry = {} + + def _reset(self): + for lst in six.itervalues(self._registry): + lst[1] = False + + def registerSpecialImportForType(self, cls, impStatement): + className = cls.__name__ + if className in self._registry: + raise RuntimeError("Error: the configuration type '%s' already has an import statement registered '%s'" % (className, self._registry[className][0])) + self._registry[className] = [impStatement, False] + + def registerUse(self, obj): + className = obj.__class__.__name__ + try: + self._registry[className][1] = True + except KeyError: + pass + + def getSpecialImports(self): + coll = set() + for (imp, used) in six.itervalues(self._registry): + if used: + coll.add(imp) + return sorted(coll) + +specialImportRegistry = _SpecialImportRegistry() + class _ParameterTypeBase(object): """base class for classes which are used as the 'parameters' for a ParameterSet""" def __init__(self): @@ -38,6 +69,7 @@ def pythonTypeName(self): return 'cms.'+type(self).__name__ return 'cms.untracked.'+type(self).__name__ def dumpPython(self, options=PrintOptions()): + specialImportRegistry.registerUse(self) return self.pythonTypeName()+"("+self.pythonValue(options)+")" def __repr__(self): return self.dumpPython() @@ -248,6 +280,7 @@ def __delattr__(self,name): def __raiseBadSetAttr(name): raise TypeError(name+" does not already exist, so it can only be set to a CMS python configuration type") def dumpPython(self, options=PrintOptions()): + specialImportRegistry.registerUse(self) sortedNames = sorted(self.parameterNames_()) if len(sortedNames) > 200: #Too many parameters for a python function call @@ -417,6 +450,7 @@ def dumpConfig(self, options=PrintOptions()): return config def dumpPython(self, options=PrintOptions()): + specialImportRegistry.registerUse(self) result = "cms."+str(type(self).__name__)+'("'+self.type_()+'"' nparam = len(self.parameterNames_()) if nparam == 0: @@ -591,6 +625,7 @@ def pythonValueForItem(self,item, options): def __repr__(self): return self.dumpPython() def dumpPython(self, options=PrintOptions()): + specialImportRegistry.registerUse(self) result = self.pythonTypeName()+"(" n = len(self) if hasattr(self, "_nPerLine"): @@ -663,12 +698,12 @@ def _modifyParametersFromDict(params, newParams, errorRaiser, keyDepth=""): plist[k] = v else: raise ValueError("Attempted to change non PSet value "+keyDepth+" using a dictionary") - elif isinstance(value,_ParameterTypeBase) or (isinstance(key, int)) or isinstance(value, _TypedParameterizable): + elif isinstance(value,_ParameterTypeBase) or (isinstance(key, int)) or isinstance(value, _Parameterizable): params[key] = value else: params[key].setValue(value) else: - if isinstance(value,_ParameterTypeBase) or isinstance(value, _TypedParameterizable): + if isinstance(value,_ParameterTypeBase) or isinstance(value, _Parameterizable): params[key]=value else: errorRaiser(key) @@ -797,4 +832,19 @@ def __init__(self): p = tLPTest("MyType",** dict( [ ("a"+str(x), tLPTestType(x)) for x in xrange(0,300) ] ) ) #check they are the same self.assertEqual(p.dumpPython(), eval(p.dumpPython(),{"cms": __DummyModule()}).dumpPython()) + def testSpecialImportRegistry(self): + reg = _SpecialImportRegistry() + reg.registerSpecialImportForType(int, "import foo") + self.assertRaises(lambda x: reg.registerSpecialImportForType(int, "import bar")) + reg.registerSpecialImportForType(str, "import bar") + self.assertEqual(reg.getSpecialImports(), []) + reg.registerUse([1]) + self.assertEqual(reg.getSpecialImports(), []) + reg.registerUse(1) + self.assertEqual(reg.getSpecialImports(), ["import foo"]) + reg.registerUse(1) + self.assertEqual(reg.getSpecialImports(), ["import foo"]) + reg.registerUse("a") + self.assertEqual(reg.getSpecialImports(), ["import bar", "import foo"]) + unittest.main() diff --git a/FWCore/ParameterSet/python/Modules.py b/FWCore/ParameterSet/python/Modules.py index e2ba2a3fa82d3..29bed419681e2 100644 --- a/FWCore/ParameterSet/python/Modules.py +++ b/FWCore/ParameterSet/python/Modules.py @@ -1,8 +1,8 @@ from Mixins import _ConfigureComponent, saveOrigin from Mixins import _Unlabelable, _Labelable -from Mixins import _TypedParameterizable, _Parameterizable, PrintOptions +from Mixins import _TypedParameterizable, _Parameterizable, PrintOptions, specialImportRegistry from SequenceTypes import _SequenceLeaf -from Types import vstring +from Types import vstring, EDAlias import six import copy @@ -272,9 +272,13 @@ def _getProducer(self): """Returns the EDroducer of the chosen case""" return self.__dict__[self._chooseCase()] + @staticmethod + def __typeIsValid(typ): + return (isinstance(typ, EDProducer) and not isinstance(typ, SwitchProducer)) or isinstance(typ, EDAlias) + def __addParameter(self, name, value): - if not (isinstance(value, EDProducer) and not isinstance(value, SwitchProducer)): - raise TypeError(name+" does not already exist, so it can only be set to a cms.EDProducer") + if not self.__typeIsValid(value): + raise TypeError(name+" does not already exist, so it can only be set to a cms.EDProducer or cms.EDAlias") if name not in self._caseFunctionDict: raise ValueError("Case '%s' is not allowed (allowed ones are %s)" % (name, ",".join(six.iterkeys(self._caseFunctionDict)))) if name in self.__dict__: @@ -309,8 +313,8 @@ def __setattr__(self, name, value): self.__addParameter(name, value) self._isModified = True else: - if not (isinstance(value, EDProducer) and not isinstance(value, SwitchProducer)): - raise TypeError(name+" can only be set to a cms.EDProducer") + if not self.__typeIsValid(value): + raise TypeError(name+" can only be set to a cms.EDProducer or cms.EDAlias") # We should always receive an cms.EDProducer self.__dict__[name] = value self._isModified = True @@ -342,6 +346,7 @@ def dumpPython(self, options=PrintOptions()): # Note that if anyone uses the generic SwitchProducer instead # of a derived-one, the information on the functions for the # producer decision is lost + specialImportRegistry.registerUse(self) result = "%s(" % self.__class__.__name__ # not including cms. since the deriving classes are not in cms "namespace" options.indent() for resource in sorted(self.parameterNames_()): @@ -358,12 +363,15 @@ def moduleLabel_(self, myname): return myname def caseLabel_(self, name, case): return name+"@"+case - def appendToProcessDescList_(self, lst, myname): + def appendToProcessDescLists_(self, modules, aliases, myname): # This way we can insert the chosen EDProducer to @all_modules # so that we get easily a worker for it - lst.append(myname) + modules.append(myname) for case in self.parameterNames_(): - lst.append(self.caseLabel_(myname, case)) + if isinstance(self.__dict__[case], EDAlias): + aliases.append(self.caseLabel_(myname, case)) + else: + modules.append(self.caseLabel_(myname, case)) def insertInto(self, parameterSet, myname): for case in self.parameterNames_(): @@ -378,12 +386,19 @@ def insertInto(self, parameterSet, myname): parameterSet.addPSet(True, self.nameInProcessDesc_(myname), newpset) def _placeImpl(self,name,proc): - proc._placeProducer(name,self) - for case in self.parameterNames_(): - # Note that these don't end up in @all_modules - # automatically because they're not part of any - # Task/Sequence/Path - proc._placeProducer(self.caseLabel_(name, case), self.__dict__[case]) + proc._placeSwitchProducer(name,self) +# for case in self.parameterNames_(): +# caseLabel = self.caseLabel_(name, case) +# caseObj = self.__dict__[case] +# +# if isinstance(caseObj, EDAlias): +# # EDAliases end up in @all_aliases automatically +# proc._placeAlias(caseLabel, caseObj) +# else: +# # Note that these don't end up in @all_modules +# # automatically because they're not part of any +# # Task/Sequence/Path +# proc._placeProducer(caseLabel, caseObj) def _clonesequence(self, lookuptable): try: @@ -539,7 +554,6 @@ def testSwitchProducer(self): self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = Source("Foo"))) self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = OutputModule("Foo"))) self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = Looper("Foo"))) - self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = EDAlias())) self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = Service("Foo"))) self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = ESSource("Foo"))) self.assertRaises(TypeError, lambda: SwitchProducerTest(test1 = ESProducer("Foo"))) @@ -574,6 +588,7 @@ def testSwitchProducer(self): self.assertEqual(cl.test2.type_(), "Bar") self.assertEqual(cl.test2.aa.value(), 11) self.assertEqual(cl.test2.bb.cc.value(), 12) + self.assertEqual(sp._getProducer().type_(), "Bar") # Modify clone cl.test1.a = 3 self.assertEqual(cl.test1.a.value(), 3) @@ -635,4 +650,58 @@ def _assignSwitchProducer(): unpkl = pickle.loads(pkl) self.assertEqual(unpkl.cpu.type_(), "Foo") + def testSwithProducerWithAlias(self): + # Constructor + sp = SwitchProducerTest(test1 = EDProducer("Foo"), test2 = EDAlias()) + self.assertEqual(sp.test1.type_(), "Foo") + self.assertTrue(isinstance(sp.test2, EDAlias)) + + # Modifications + from Types import int32, string, PSet, VPSet + sp = SwitchProducerTest(test1 = EDProducer("Foo"), + test2 = EDAlias(foo = VPSet(PSet(type = string("Foo2"))))) + + # Simple clone + cl = sp.clone() + self.assertTrue(hasattr(cl.test2, "foo")) + # Modify clone + cl.test2.foo[0].type = "Foo3" + self.assertEqual(cl.test2.foo[0].type, "Foo3") + # Modify values with a dict + cl = sp.clone(test2 = dict(foo = {0: dict(type = "Foo4")})) + self.assertEqual(cl.test2.foo[0].type, "Foo4") + # Replace or add EDAlias + cl = sp.clone(test1 = EDAlias(foo = VPSet(PSet(type = string("Foo5")))), + test3 = EDAlias(foo = VPSet(PSet(type = string("Foo6"))))) + self.assertEqual(cl.test1.foo[0].type, "Foo5") + self.assertEqual(cl.test3.foo[0].type, "Foo6") + # Modify clone + cl.test1 = EDProducer("Xyzzy") + self.assertEqual(cl.test1.type_(), "Xyzzy") + cl.test1 = EDAlias(foo = VPSet(PSet(type = string("Foo7")))) + self.assertEqual(cl.test1.foo[0].type, "Foo7") + + + # Dump + from Types import int32, string, PSet, VPSet + sp = SwitchProducerTest(test1 = EDProducer("Foo"), + test2 = EDAlias(foo = VPSet(PSet(type = string("Foo2"))))) + + self.assertEqual(sp.dumpPython(), +"""SwitchProducerTest( + test1 = cms.EDProducer("Foo"), + test2 = cms.EDAlias( + foo = cms.VPSet(cms.PSet( + type = cms.string('Foo2') + )) +) +) +""") + + # Pickle + import pickle + sp = SwitchProducerPickleable(cpu = EDAlias(foo = VPSet(PSet(type = string("Foo2"))))) + pkl = pickle.dumps(sp) + unpkl = pickle.loads(pkl) + self.assertEqual(sp.cpu.foo[0].type, "Foo2") unittest.main() diff --git a/FWCore/ParameterSet/python/Types.py b/FWCore/ParameterSet/python/Types.py index 558cbcc1e086b..9a4669df73cdf 100644 --- a/FWCore/ParameterSet/python/Types.py +++ b/FWCore/ParameterSet/python/Types.py @@ -1,5 +1,5 @@ -from Mixins import PrintOptions, _SimpleParameterTypeBase, _ParameterTypeBase, _Parameterizable, _ConfigureComponent, _Labelable, _TypedParameterizable, _Unlabelable, _modifyParametersFromDict -from Mixins import _ValidatingParameterListBase +from Mixins import PrintOptions, _SimpleParameterTypeBase, _ParameterTypeBase, _Parameterizable, _ConfigureComponent, _Labelable, _TypedParameterizable, _Unlabelable, _modifyParametersFromDict, saveOrigin +from Mixins import _ValidatingParameterListBase, specialImportRegistry from ExceptionHandling import format_typename, format_outerframe import copy @@ -1136,30 +1136,21 @@ def convertToVPSet( **kw ): return returnValue -class EDAlias(_ConfigureComponent,_Labelable): +class EDAlias(_ConfigureComponent,_Labelable,_Parameterizable): def __init__(self,*arg,**kargs): - super(EDAlias,self).__init__() - self.__dict__['_EDAlias__parameterNames'] = [] - self.__setParameters(kargs) + super(EDAlias,self).__init__(**kargs) - def parameterNames_(self): - """Returns the name of the parameters""" - return self.__parameterNames[:] - - def __addParameter(self, name, value): - if not isinstance(value,_ParameterTypeBase): - self.__raiseBadSetAttr(name) - self.__dict__[name]=value - self.__parameterNames.append(name) + def clone(self, *args, **params): + returnValue = EDAlias.__new__(type(self)) + myparams = self.parameters_() + if len(myparams) == 0 and len(params) and len(args): + args.append(None) - def __delattr__(self,attr): - if attr in self.__parameterNames: - self.__parameterNames.remove(attr) - return super(EDAlias,self).__delattr__(attr) + _modifyParametersFromDict(myparams, params, self._Parameterizable__raiseBadSetAttr) - def __setParameters(self,parameters): - for name,value in six.iteritems(parameters): - self.__addParameter(name, value) + returnValue.__init__(*args, **myparams) + saveOrigin(returnValue, 1) + return returnValue def _place(self,name,proc): proc._placeAlias(name,self) @@ -1181,6 +1172,7 @@ def insertInto(self, parameterSet, myname): parameterSet.addPSet(True, self.nameInProcessDesc_(myname), newpset) def dumpPython(self, options=PrintOptions()): + specialImportRegistry.registerUse(self) resultList = ['cms.EDAlias('] separator = "" for name in self.parameterNames_(): @@ -1439,6 +1431,21 @@ def testEDAlias(self): self.assert_(not hasattr(aliasfoo2,"foo2")) self.assert_("foo2" not in aliasfoo2.parameterNames_()) + aliasfoo2 = EDAlias(foo2 = VPSet(PSet(type = string("Foo2")))) + aliasfoo3 = aliasfoo2.clone( + foo2 = {0: dict(type = "Foo4")}, + foo3 = VPSet(PSet(type = string("Foo3"))) + ) + self.assertTrue(hasattr(aliasfoo3, "foo2")) + self.assertTrue(hasattr(aliasfoo3, "foo3")) + self.assertEqual(aliasfoo3.foo2[0].type, "Foo4") + self.assertEqual(aliasfoo3.foo3[0].type, "Foo3") + + aliasfoo4 = aliasfoo3.clone(foo2 = None) + self.assertFalse(hasattr(aliasfoo4, "foo2")) + self.assertTrue(hasattr(aliasfoo4, "foo3")) + self.assertEqual(aliasfoo4.foo3[0].type, "Foo3") + def testFileInPath(self): f = FileInPath("FWCore/ParameterSet/python/Types.py") self.assertEqual(f.configValue(), "'FWCore/ParameterSet/python/Types.py'") diff --git a/FWCore/PyDevParameterSet/BuildFile.xml b/FWCore/PyDevParameterSet/BuildFile.xml new file mode 100644 index 0000000000000..883d5efcb1b41 --- /dev/null +++ b/FWCore/PyDevParameterSet/BuildFile.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/FWCore/PyDevParameterSet/interface/MakePyBind11ParameterSets.h b/FWCore/PyDevParameterSet/interface/MakePyBind11ParameterSets.h new file mode 100644 index 0000000000000..7bd16e71d990e --- /dev/null +++ b/FWCore/PyDevParameterSet/interface/MakePyBind11ParameterSets.h @@ -0,0 +1,35 @@ +#ifndef FWCore_PyBind11ParameterSet_MakePyBind11ParameterSets_h +#define FWCore_PyBind11ParameterSet_MakePyBind11ParameterSets_h + +//---------------------------------------------------------------------- +// Declare functions used to create ParameterSets. +//---------------------------------------------------------------------- + +#include + +#include +#include + +namespace edm { + class ParameterSet; + namespace cmspybind11 { + // input can either be a python file name or a python config string + std::unique_ptr + readConfig(std::string const& config); + + /// same, but with arguments + std::unique_ptr + readConfig(std::string const& config, int argc, char* argv[]); + + /// essentially the same as the previous method + void + makeParameterSets(std::string const& configtext, + std::unique_ptr& main); + + /**finds all the PSets used in the top level module referred as a file or as a string containing + python commands. These PSets are bundled into a top level PSet from which they can be retrieved + */ + std::unique_ptr readPSetsFrom(std::string const& fileOrString); + } +} // namespace edm +#endif diff --git a/FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h b/FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h new file mode 100644 index 0000000000000..ed52900348c8c --- /dev/null +++ b/FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h @@ -0,0 +1,56 @@ +#ifndef FWCore_PyBind11ParameterSet_PyBind11ProcessDesc_h +#define FWCore_PyBind11ParameterSet_PyBind11ProcessDesc_h + +#include "FWCore/PyDevParameterSet/interface/Python11ParameterSet.h" + +#include + +#include +#include + +namespace edm { + class ParameterSet; + class ProcessDesc; +} + +class PyBind11ProcessDesc { +public: + PyBind11ProcessDesc(); + /** This constructor will parse the given file or string + and create two objects in python-land: + * a PythonProcessDesc named 'processDesc' + * a PythonParameterSet named 'processPSet' + It decides whether it's a file or string by seeing if + it ends in '.py' + */ + PyBind11ProcessDesc(std::string const& config); + + // PyBind11ProcessDesc(std::string const& config, int argc, char * argv[]); + + ~PyBind11ProcessDesc(); + + Python11ParameterSet newPSet() const {return Python11ParameterSet();} + + Python11ParameterSet& pset() { return theProcessPSet;} + + std::string dump() const; + + // makes a new (copy) of the ParameterSet + std::unique_ptr parameterSet() const; + + // makes a new (copy) of a ProcessDesc + // For backward compatibility only. Remove when no longer needed. + std::unique_ptr processDesc() const; + +private: + void prepareToRead(); + void read(std::string const& config); + void readFile(std::string const& fileName); + void readString(std::string const& pyConfig); + + Python11ParameterSet theProcessPSet; + pybind11::object theMainModule; + // pybind11::object theMainNamespace; +}; + +#endif diff --git a/FWCore/PyDevParameterSet/interface/Python11ParameterSet.h b/FWCore/PyDevParameterSet/interface/Python11ParameterSet.h new file mode 100644 index 0000000000000..f205582d049bf --- /dev/null +++ b/FWCore/PyDevParameterSet/interface/Python11ParameterSet.h @@ -0,0 +1,131 @@ +#ifndef FWCore_PyBind11ParameterSet_Python11ParameterSet_h +#define FWCore_PyBind11ParameterSet_Python11ParameterSet_h +#include + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/PyDevParameterSet/src/PyBind11Wrapper.h" + +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/ESInputTag.h" +#include "DataFormats/Provenance/interface/EventRange.h" +#include "DataFormats/Provenance/interface/LuminosityBlockID.h" +#include "DataFormats/Provenance/interface/LuminosityBlockRange.h" +#include "DataFormats/Provenance/interface/EventID.h" +#include "DataFormats/Provenance/interface/RunLumiEventNumber.h" + +#include +#include + +class Python11ParameterSet { +public: + Python11ParameterSet(); + + Python11ParameterSet(edm::ParameterSet const& p) + : theParameterSet(p) {} + + template + T + getParameter(bool tracked, std::string const& name) const { + T result; + if(tracked) { + result = theParameterSet.template getParameter(name); + } else { + result = theParameterSet.template getUntrackedParameter(name); + } + return result; + } + + + template + void + addParameter(bool tracked, std::string const& name, T const& value) { + if(tracked) { + theParameterSet.template addParameter(name, value); + } else { + theParameterSet.template addUntrackedParameter(name, value); + } + } + + + /// templated on the type of the contained object + template + pybind11::list + getParameters(bool tracked, std::string const& name) const { + std::vector v = getParameter >(tracked, name); + return edm::toPython11List(v); + } + + /// unfortunate side effect: destroys the original list! + template + void + addParameters(bool tracked, std::string const& name, + pybind11::list value) { + std::vector v = edm::toVector(value); + addParameter(tracked, name, v); + } + + + /// these custom classes do seem to be a hassle + /// to wrap, compared to, say, InputTag + /// maybe we will need to template these someday + void addPSet(bool tracked, std::string const& name, + Python11ParameterSet const& ppset) { + addParameter(tracked, name, ppset.theParameterSet); + } + + + Python11ParameterSet getPSet(bool tracked, std::string const& name) const { + return Python11ParameterSet(getParameter(tracked, name)); + } + + + void addVPSet(bool tracked, std::string const& name, + pybind11::list value); + + pybind11::list getVPSet(bool tracked, std::string const& name); + + // no way to interface straight into the other python InputTag + edm::InputTag newInputTag(std::string const& label, + std::string const& instance, + std::string const& process) { + return edm::InputTag(label, instance, process); + } + + edm::ESInputTag newESInputTag(std::string const& module, + std::string const& data) { + return edm::ESInputTag(module, data); + } + + edm::EventID newEventID(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event) { + return edm::EventID(run, lumi, event); + } + + edm::LuminosityBlockID newLuminosityBlockID(unsigned int run, unsigned int lumi) { + return edm::LuminosityBlockID(run, lumi); + } + + edm::LuminosityBlockRange newLuminosityBlockRange(unsigned int start, unsigned int startSub, + unsigned int end, unsigned int endSub) { + return edm::LuminosityBlockRange(start, startSub, end, endSub); + } + + edm::EventRange newEventRange(edm::RunNumber_t start, edm::LuminosityBlockNumber_t startLumi, edm::EventNumber_t startSub, + edm::RunNumber_t end, edm::LuminosityBlockNumber_t endLumi, edm::EventNumber_t endSub) { + return edm::EventRange(start, startLumi, startSub, end, endLumi, endSub); + } + + void addNewFileInPath(bool tracked, std::string const& name, std::string const& value); + + Python11ParameterSet newPSet() const {return Python11ParameterSet();} + + edm::ParameterSet& pset() {return theParameterSet;} + + edm::ParameterSet const& pset() const {return theParameterSet;} + + std::string dump() const {return theParameterSet.dump();} + +private: + edm::ParameterSet theParameterSet; +}; + +#endif diff --git a/FWCore/PyDevParameterSet/src/MakePyBind11ParameterSets.cc b/FWCore/PyDevParameterSet/src/MakePyBind11ParameterSets.cc new file mode 100644 index 0000000000000..812ad524976b9 --- /dev/null +++ b/FWCore/PyDevParameterSet/src/MakePyBind11ParameterSets.cc @@ -0,0 +1,76 @@ +#include "FWCore/PyDevParameterSet/interface/MakePyBind11ParameterSets.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/PyDevParameterSet/interface/Python11ParameterSet.h" +#include "FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h" +#include "initializePyBind11Module.h" +#include + +static +void +makePSetsFromFile(std::string const& fileName) { + std::string initCommand("from FWCore.ParameterSet.Types import makeCppPSet\n" + "execfile('"); + initCommand += fileName + "')"; + + pybind11::exec(initCommand); + pybind11::exec("makeCppPSet(locals(), topPSet)"); +} + +static +void +makePSetsFromString(std::string const& module) { + std::string command = module; + command += "\nfrom FWCore.ParameterSet.Types import makeCppPSet\nmakeCppPSet(locals(), topPSet)"; + pybind11::exec(command); +} + +namespace edm { + namespace cmspybind11 { + std::unique_ptr + readConfig(std::string const& config) { + PyBind11ProcessDesc pythonProcessDesc(config); + return pythonProcessDesc.parameterSet(); + } + + std::unique_ptr + readConfig(std::string const& config, int argc, char* argv[]) { + PyBind11ProcessDesc pythonProcessDesc(config);//, argc, argv); + return pythonProcessDesc.parameterSet(); + } + + void + makeParameterSets(std::string const& configtext, + std::unique_ptr& main) { + PyBind11ProcessDesc pythonProcessDesc(configtext); + main = pythonProcessDesc.parameterSet(); + } + + std::unique_ptr + readPSetsFrom(std::string const& module) { + + pybind11::scoped_interpreter guard{}; + python::initializePyBind11Module(); + std::unique_ptr retVal; + { + Python11ParameterSet theProcessPSet; + pybind11::object mainModule = pybind11::module::import("__main__"); + mainModule.attr("topPSet") = pybind11::cast(&theProcessPSet); + + try { + // if it ends with py, it's a file + if(module.substr(module.size()-3) == ".py") { + makePSetsFromFile(module); + } else { + makePSetsFromString(module); + } + } + catch( pybind11::error_already_set const &e ) { + pythonToCppException("Configuration",e.what()); + } + retVal=std::make_unique(ParameterSet(theProcessPSet.pset())); + } + return retVal; + } + } +} // namespace edm diff --git a/FWCore/PyDevParameterSet/src/PyBind11Module.h b/FWCore/PyDevParameterSet/src/PyBind11Module.h new file mode 100644 index 0000000000000..2f71869a4dd30 --- /dev/null +++ b/FWCore/PyDevParameterSet/src/PyBind11Module.h @@ -0,0 +1,179 @@ +#ifndef FWCore_PythonParameterSet_PyBind11Module_h +#define FWCore_PythonParameterSet_PyBind11Module_h + +#include "FWCore/PyDevParameterSet/interface/Python11ParameterSet.h" +#include "FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h" + +#include "DataFormats/Provenance/interface/EventRange.h" +#include "DataFormats/Provenance/interface/LuminosityBlockID.h" +#include "DataFormats/Provenance/interface/LuminosityBlockRange.h" +#include "DataFormats/Provenance/interface/EventID.h" +#include "DataFormats/Provenance/interface/RunLumiEventNumber.h" +#include "FWCore/Utilities/interface/ESInputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include +#include + +// This is to give some special handling to cms::Exceptions thrown +// in C++ code called by python. Only at the very top level do +// we need the exception message returned by the function "what". +// We only need the central message here as this will get converted +// back into a cms::Exception again when control rises back into +// the C++ code. If necessary it would probably be possible to +// improve these messages even more by adding something in the python +// to add module type and label context to the messages being caught +// here. At this point we did not think it worth the time to implement. +//namespace { +// void translatorlibFWCorePythonParameterSet(cms::Exception const& ex) { +// PyErr_SetString(PyExc_RuntimeError, ex.message().c_str()); +// } +//} + +#include + +PYBIND11_MODULE(libFWCorePyDevParameterSet,m) +{ + + // pybind11::register_exception_translator(translatorlibFWCorePythonParameterSet); + + pybind11::class_(m,"InputTag") + .def(pybind11::init<>()) + .def(pybind11::init()) + .def(pybind11::init()) + .def(pybind11::init()) + .def("label", &edm::InputTag::label, pybind11::return_value_policy::copy) + .def("instance", &edm::InputTag::instance, pybind11::return_value_policy::copy) + .def("process", &edm::InputTag::process, pybind11::return_value_policy::copy) + ; + + pybind11::class_(m,"ESInputTag") + .def(pybind11::init()) + .def(pybind11::init()) + .def("module", &edm::ESInputTag::module, pybind11::return_value_policy::copy) + .def("data", &edm::ESInputTag::data, pybind11::return_value_policy::copy) + ; + + pybind11::class_(m,"EventID") + .def(pybind11::init()) + .def("run", &edm::EventID::run) + .def("luminosityBlock", &edm::EventID::luminosityBlock) + .def("event", &edm::EventID::event) + ; + + pybind11::class_(m,"LuminosityBlockID") + .def(pybind11::init()) + .def("run", &edm::LuminosityBlockID::run) + .def("luminosityBlock", &edm::LuminosityBlockID::luminosityBlock) + ; + + pybind11::class_(m,"FileInPath") + .def(pybind11::init()) + .def("fullPath", &edm::FileInPath::fullPath) + .def("relativePath", &edm::FileInPath::relativePath) + ; + + pybind11::class_(m,"LuminosityBlockRange") + .def(pybind11::init()) + .def("start", &edm::LuminosityBlockRange::startRun) + .def("startSub", &edm::LuminosityBlockRange::startLumi) + .def("end", &edm::LuminosityBlockRange::endRun) + .def("endSub", &edm::LuminosityBlockRange::endLumi) + ; + + pybind11::class_(m,"EventRange") + .def(pybind11::init()) + .def("start", &edm::EventRange::startRun) + .def("startLumi", &edm::EventRange::startLumi) + .def("startSub", &edm::EventRange::startEvent) + .def("end", &edm::EventRange::endRun) + .def("endLumi", &edm::EventRange::endLumi) + .def("endSub", &edm::EventRange::endEvent) + ; + + pybind11::class_(m,"ParameterSet") + .def(pybind11::init<>()) + .def("addInt32", &Python11ParameterSet::addParameter) + .def("getInt32", &Python11ParameterSet::getParameter) + .def("addVInt32", &Python11ParameterSet::addParameters) + .def("getVInt32", &Python11ParameterSet::getParameters) + .def("addUInt32", &Python11ParameterSet::addParameter) + .def("getUInt32", &Python11ParameterSet::getParameter) + .def("addVUInt32", &Python11ParameterSet::addParameters) + .def("getVUInt32", &Python11ParameterSet::getParameters) + .def("addInt64", &Python11ParameterSet::addParameter) + .def("getInt64", &Python11ParameterSet::getParameter) + .def("addUInt64", &Python11ParameterSet::addParameter) + .def("getUInt64", &Python11ParameterSet::getParameter) + .def("addVInt64", &Python11ParameterSet::addParameters) + .def("getVInt64", &Python11ParameterSet::getParameters) + .def("addVUInt64", &Python11ParameterSet::addParameters) + .def("getVUInt64", &Python11ParameterSet::getParameters) + .def("addDouble", &Python11ParameterSet::addParameter) + .def("getDouble", &Python11ParameterSet::getParameter) + .def("addVDouble", &Python11ParameterSet::addParameters) + .def("getVDouble", &Python11ParameterSet::getParameters) + .def("addBool", &Python11ParameterSet::addParameter) + .def("getBool", &Python11ParameterSet::getParameter) + .def("addString", &Python11ParameterSet::addParameter) + .def("getString", &Python11ParameterSet::getParameter) + .def("addVString", &Python11ParameterSet::addParameters) + .def("getVString", &Python11ParameterSet::getParameters) + .def("addInputTag", &Python11ParameterSet::addParameter) + .def("getInputTag", &Python11ParameterSet::getParameter) + .def("addVInputTag", &Python11ParameterSet::addParameters) + .def("getVInputTag", &Python11ParameterSet::getParameters) + .def("addESInputTag", &Python11ParameterSet::addParameter) + .def("getESInputTag", &Python11ParameterSet::getParameter) + .def("addVESInputTag", &Python11ParameterSet::addParameters) + .def("getVESInputTag", &Python11ParameterSet::getParameters) + .def("addEventID", &Python11ParameterSet::addParameter) + .def("getEventID", &Python11ParameterSet::getParameter) + .def("addVEventID", &Python11ParameterSet::addParameters) + .def("getVEventID", &Python11ParameterSet::getParameters) + .def("addLuminosityBlockID", &Python11ParameterSet::addParameter) + .def("getLuminosityBlockID", &Python11ParameterSet::getParameter) + .def("addVLuminosityBlockID", &Python11ParameterSet::addParameters) + .def("getVLuminosityBlockID", &Python11ParameterSet::getParameters) + .def("addLuminosityBlockRange", &Python11ParameterSet::addParameter) + .def("getLuminosityBlockRange", &Python11ParameterSet::getParameter) + .def("addVLuminosityBlockRange", &Python11ParameterSet::addParameters) + .def("getVLuminosityBlockRange", &Python11ParameterSet::getParameters) + .def("addEventRange", &Python11ParameterSet::addParameter) + .def("getEventRange", &Python11ParameterSet::getParameter) + .def("addVEventRange", &Python11ParameterSet::addParameters) + .def("getVEventRange", &Python11ParameterSet::getParameters) + .def("addPSet", &Python11ParameterSet::addPSet) + .def("getPSet", &Python11ParameterSet::getPSet) + .def("addVPSet", &Python11ParameterSet::addVPSet) + .def("getVPSet", &Python11ParameterSet::getVPSet) + .def("addFileInPath", &Python11ParameterSet::addParameter) + .def("getFileInPath", &Python11ParameterSet::getParameter) + .def("newInputTag", &Python11ParameterSet::newInputTag) + .def("newESInputTag", &Python11ParameterSet::newESInputTag) + .def("newEventID", &Python11ParameterSet::newEventID) + .def("newLuminosityBlockID", &Python11ParameterSet::newLuminosityBlockID) + .def("newLuminosityBlockRange", &Python11ParameterSet::newLuminosityBlockRange) + .def("newEventRange", &Python11ParameterSet::newEventRange) + .def("addNewFileInPath", &Python11ParameterSet::addNewFileInPath) + .def("newPSet", &Python11ParameterSet::newPSet) + .def("dump", &Python11ParameterSet::dump) + ; + + pybind11::class_(m,"ProcessDesc")//, pybind11::init<>()) + .def(pybind11::init<>()) + .def(pybind11::init()) + .def("newPSet", &PyBind11ProcessDesc::newPSet) + .def("pset", &PyBind11ProcessDesc::pset, pybind11::return_value_policy::reference) + .def("dump", &PyBind11ProcessDesc::dump) + ; + +} + + + + + + +#endif diff --git a/FWCore/PyDevParameterSet/src/PyBind11ProcessDesc.cc b/FWCore/PyDevParameterSet/src/PyBind11ProcessDesc.cc new file mode 100644 index 0000000000000..f447c05f34215 --- /dev/null +++ b/FWCore/PyDevParameterSet/src/PyBind11ProcessDesc.cc @@ -0,0 +1,99 @@ +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ProcessDesc.h" +#include "FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h" +#include "FWCore/PyDevParameterSet/src/initializePyBind11Module.h" +#include "FWCore/PyDevParameterSet/src/PyBind11Wrapper.h" +#include +#include + +#include +#include + +PyBind11ProcessDesc::PyBind11ProcessDesc() : + theProcessPSet(), + theMainModule() +{ + pybind11::initialize_interpreter(); +} + +PyBind11ProcessDesc::PyBind11ProcessDesc(std::string const& config) : + theProcessPSet(), + theMainModule() +{ + pybind11::initialize_interpreter(); + edm::python::initializePyBind11Module(); + prepareToRead(); + read(config); +} + +/* +PyBind11ProcessDesc::PyBind11ProcessDesc(std::string const& config, int argc, char* argv[]) : + theProcessPSet(), + theMainModule() +{ + pybind11::initialize_interpreter(); + edm::python::initializePyBind11Module(); + prepareToRead(); + PySys_SetArgv(argc, argv); + read(config); + //py::module::import("sys").attr("argv") = py::make_tuple("test.py", "embed.cpp"); might work +} +*/ + +PyBind11ProcessDesc::~PyBind11ProcessDesc() { + theMainModule=pybind11::object(); + pybind11::finalize_interpreter(); + +} + +void PyBind11ProcessDesc::prepareToRead() { + // pybind11::scoped_interpreter guard{}; + theMainModule = pybind11::module::import("__main__"); + theMainModule.attr("processDesc")=this; + theMainModule.attr("processPSet")=&theProcessPSet; +} + +void PyBind11ProcessDesc::read(std::string const& config) { + try { + // if it ends with py, it's a file + if(config.substr(config.size()-3) == ".py") { + readFile(config); + } else { + readString(config); + } + } + catch(pybind11::error_already_set const&e) { + edm::pythonToCppException("Configuration",e.what()); + } +} + +void PyBind11ProcessDesc::readFile(std::string const& fileName) { + std::string initCommand("import FWCore.ParameterSet.Config as cms\n" + "execfile('"); + initCommand += fileName + "')"; + + pybind11::exec(initCommand.c_str()); + std::string command("process.fillProcessDesc(processPSet)"); + pybind11::exec(command.c_str()); +} + +void PyBind11ProcessDesc::readString(std::string const& pyConfig) { + std::string command = pyConfig; + command += "\nprocess.fillProcessDesc(processPSet)"; + pybind11::exec(command.c_str()); +} + +std::unique_ptr PyBind11ProcessDesc::parameterSet() const { + return std::make_unique(theProcessPSet.pset()); +} + +std::string PyBind11ProcessDesc::dump() const { + std::ostringstream os; + os << theProcessPSet.dump(); + return os.str(); +} + +// For backward compatibility only. Remove when no longer used. +std::unique_ptr PyBind11ProcessDesc::processDesc() const { + return std::make_unique(parameterSet()); +} diff --git a/FWCore/PyDevParameterSet/src/PyBind11Wrapper.cc b/FWCore/PyDevParameterSet/src/PyBind11Wrapper.cc new file mode 100644 index 0000000000000..21e123b4447c1 --- /dev/null +++ b/FWCore/PyDevParameterSet/src/PyBind11Wrapper.cc @@ -0,0 +1,12 @@ +#include "PyBind11Wrapper.h" +#include "FWCore/Utilities/interface/Exception.h" +//#include +namespace edm { + + void pythonToCppException(const std::string& iType, const std::string &error) + { + throw cms::Exception(iType)<<" unknown python problem occurred.\n"<< error << std::endl; + } +} + + diff --git a/FWCore/PyDevParameterSet/src/PyBind11Wrapper.h b/FWCore/PyDevParameterSet/src/PyBind11Wrapper.h new file mode 100644 index 0000000000000..aad78ccd6c71c --- /dev/null +++ b/FWCore/PyDevParameterSet/src/PyBind11Wrapper.h @@ -0,0 +1,39 @@ +#ifndef FWCore_PyBind11ParameterSet_PyBind11Wrapper_h +#define FWCore_PyBind11ParameterSet_PyBind11Wrapper_h + +#include +#include +#include +#include + +namespace edm { +void + pythonToCppException(const std::string& iType, const std::string& error); + + // utility to translate from an STL vector of strings to + // a Python list + + template + pybind11::list toPython11List(const std::vector & v) { + pybind11::list result; + for(const auto & i: v) { + result.append(i); + } + return result; + } + + // and back. Destroys the input via pop()s - well probably not + template + std::vector toVector(pybind11::list & l) + { + std::vector result; + result.reserve(l.size()); + for(unsigned i = 0; i < l.size(); ++i) + { + result.push_back(l[i].cast()); + } + return result; + } +} + +#endif diff --git a/FWCore/PyDevParameterSet/src/Python11ParameterSet.cc b/FWCore/PyDevParameterSet/src/Python11ParameterSet.cc new file mode 100644 index 0000000000000..53c0ece7ffbea --- /dev/null +++ b/FWCore/PyDevParameterSet/src/Python11ParameterSet.cc @@ -0,0 +1,46 @@ +#include "FWCore/PyDevParameterSet/interface/Python11ParameterSet.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" + +Python11ParameterSet::Python11ParameterSet() +: theParameterSet() +{ +} + + +void Python11ParameterSet::addVPSet(bool tracked, std::string const& name, + pybind11::list value) +{ + std::vector v + = edm::toVector(value); + std::vector v2; + v2.reserve(v.size()); + for(std::vector::iterator ppsetItr = v.begin(), ppsetItrEnd = v.end(); + ppsetItr != ppsetItrEnd; ++ppsetItr) + { + v2.push_back(ppsetItr->theParameterSet); + } + addParameter(tracked, name, v2); +} + + +pybind11::list Python11ParameterSet::getVPSet(bool tracked, std::string const& name) +{ + std::vector const& v = + (tracked ? theParameterSet.getParameterSetVector(name) : theParameterSet.getUntrackedParameterSetVector(name)); + + // convert to Python11ParameterSets + pybind11::list l; + for(std::vector::const_iterator psetItr = v.begin(), psetItrEnd = v.end(); + psetItr != psetItrEnd; ++psetItr) + { + l.append(Python11ParameterSet(*psetItr)); + } + + return l; +} + + +void Python11ParameterSet::addNewFileInPath(bool tracked, std::string const & name, std::string const & value) +{ + addParameter(tracked, name, edm::FileInPath(value)); +} diff --git a/FWCore/PyDevParameterSet/src/initializePyBind11Module.cc b/FWCore/PyDevParameterSet/src/initializePyBind11Module.cc new file mode 100644 index 0000000000000..4258cb600be80 --- /dev/null +++ b/FWCore/PyDevParameterSet/src/initializePyBind11Module.cc @@ -0,0 +1,19 @@ +// -*- C++ -*- +// +// Package: PyBind11ParameterSet +// Class : initializePyBind11Module +// + +#include "FWCore/PyDevParameterSet/src/initializePyBind11Module.h" +#include "PyBind11Module.h" +#include +#include + +namespace edm { + namespace python { + void initializePyBind11Module() { + char *libFWCoreParameterSet = const_cast("libFWCorePyDevParameterSet"); + pybind11::module::import(libFWCoreParameterSet); + } + } +} diff --git a/FWCore/PyDevParameterSet/src/initializePyBind11Module.h b/FWCore/PyDevParameterSet/src/initializePyBind11Module.h new file mode 100644 index 0000000000000..6336fcd9255f5 --- /dev/null +++ b/FWCore/PyDevParameterSet/src/initializePyBind11Module.h @@ -0,0 +1,16 @@ +#ifndef FWCore_PyBind11ParameterSet_initializePyBind11Module_h +#define FWCore_PyBind11ParameterSet_initializePyBind11Module_h + +// system include files + +// user include files + +// forward declarations +namespace edm { + namespace python { + void initializePyBind11Module(); + } +} + + +#endif diff --git a/FWCore/PyDevParameterSet/test/BuildFile.xml b/FWCore/PyDevParameterSet/test/BuildFile.xml new file mode 100644 index 0000000000000..c812b96f9cd8e --- /dev/null +++ b/FWCore/PyDevParameterSet/test/BuildFile.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/FWCore/PyDevParameterSet/test/fip.txt b/FWCore/PyDevParameterSet/test/fip.txt new file mode 100644 index 0000000000000..a52b9dba51d13 --- /dev/null +++ b/FWCore/PyDevParameterSet/test/fip.txt @@ -0,0 +1 @@ +Dummy file for the FileInPath test. diff --git a/FWCore/PyDevParameterSet/test/makeprocess_t.cppunit.cc b/FWCore/PyDevParameterSet/test/makeprocess_t.cppunit.cc new file mode 100644 index 0000000000000..4b75ba1783644 --- /dev/null +++ b/FWCore/PyDevParameterSet/test/makeprocess_t.cppunit.cc @@ -0,0 +1,775 @@ +/* + * makeprocess_t.cc + * EDMProto + * + * Created by Chris Jones on 5/18/05. + * + */ + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +class testmakeprocess: public CppUnit::TestFixture { +CPPUNIT_TEST_SUITE(testmakeprocess); +CPPUNIT_TEST(simpleProcessTest); +CPPUNIT_TEST(usingTest); +CPPUNIT_TEST(pathTest); +CPPUNIT_TEST(moduleTest); +CPPUNIT_TEST(emptyModuleTest); +CPPUNIT_TEST(taskTest); +CPPUNIT_TEST(taskTestWithEmptySchedule); +CPPUNIT_TEST(taskTestWithSchedule); +//CPPUNIT_TEST(windowsLineEndingTest); +//CPPUNIT_TEST_EXCEPTION(emptyPsetTest,edm::Exception); +CPPUNIT_TEST_SUITE_END(); +public: + void setUp(){} + void tearDown(){} + void simpleProcessTest(); + void usingTest(); + void pathTest(); + void moduleTest(); + void emptyModuleTest(); + void taskTest(); + void taskTestWithEmptySchedule(); + void taskTestWithSchedule(); + //void windowsLineEndingTest(); +private: + + typedef std::shared_ptr ParameterSetPtr; + ParameterSetPtr pSet(char const* c) { + + //ParameterSetPtr result( new edm::ProcessDesc(std::string(c)) ); + ParameterSetPtr result = PyBind11ProcessDesc(std::string(c)).parameterSet(); + CPPUNIT_ASSERT(result->getParameter("@process_name") == "test"); + return result; + } + // void emptyPsetTest(); +}; + +///registration of the test so that the runner can find it +CPPUNIT_TEST_SUITE_REGISTRATION(testmakeprocess); + +void testmakeprocess::simpleProcessTest() { + char const* kTest = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "dummy = cms.PSet(b = cms.bool(True))\n"; + ParameterSetPtr test = pSet(kTest); +} + +void testmakeprocess::usingTest() { + char const* kTest = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.dummy = cms.PSet(\n" + " b = cms.bool(True)\n" + ")\n" + "process.dummy2 = cms.PSet(\n" + " d = cms.bool(True)\n" + ")\n" + "process.m1 = cms.EDFilter('Dummy',\n" + " process.dummy\n" + ")\n" + "process.m2 = cms.EDFilter('Dummy2',\n" + " process.dummy2\n" + ")\n" + "process.p = cms.Path(process.m1+process.m2)\n"; + + ParameterSetPtr test = pSet(kTest); + + //CPPUNIT_ASSERT(test->getParameterSet("dummy").getBool("b") == true); + CPPUNIT_ASSERT(test->getParameterSet("m1").getParameter("b") == true); + CPPUNIT_ASSERT(test->getParameterSet("m2").getParameter("d") == true); +} + +void testmakeprocess::pathTest() { + char const* kTest = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.cone5 = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(5)\n" + ")\n" + "process.cone7 = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.jtanalyzer = cms.EDAnalyzer('jtanalyzer')\n" + "process.writer = cms.OutputModule('Writer')\n" + "process.cones = cms.Sequence(process.cone5*process.cone7)\n" + "process.term1 = cms.Path(process.cones+process.jtanalyzer)\n" + "process.atEnd = cms.EndPath(process.writer)\n"; + + + ParameterSetPtr test = pSet(kTest); + //CPPUNIT_ASSERT(test->pathFragments().size() == 5); + + edm::ParameterSet& myparams = *(test); + myparams.registerIt(); + std::string rep = myparams.toString(); + edm::ParameterSet copy(rep); + CPPUNIT_ASSERT(copy == myparams); +} + + +edm::ParameterSet modulePSet(std::string const& iLabel, std::string const& iType, std::string const& iCppType) { + edm::ParameterSet temp; + temp.addParameter("s", 1); + temp.addParameter("@module_label", iLabel); + temp.addParameter("@module_type", iType); + temp.addParameter("@module_edm_type", iCppType); + return temp; +} + +void testmakeprocess::moduleTest() { + char const* kTest = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.cones = cms.EDFilter('Module',\n" + " s = cms.int32(1)\n" + ")\n" + "process.NoLabelModule = cms.ESProducer('NoLabelModule',\n" + " s = cms.int32(1)\n" + ")\n" + "process.labeled = cms.ESProducer('LabelModule',\n" + " s = cms.int32(1)\n" + ")\n" + "process.source = cms.Source('InputSource',\n" + " s = cms.int32(1)\n" + ")\n" + "process.NoLabelRetriever = cms.ESSource('NoLabelRetriever',\n" + " s = cms.int32(1)\n" + ")\n" + "process.label = cms.ESSource('LabelRetriever',\n" + " s = cms.int32(1)\n" + ")\n" + "process.p = cms.Path(process.cones)\n"; + + + ParameterSetPtr test = pSet(kTest); + + static edm::ParameterSet const kEmpty; + edm::ParameterSet const kCone(modulePSet("cones", "Module","EDFilter")); + std::ostringstream out; + out << kCone.toString() << std::endl; + out << test->getParameterSet("cones").toString() << std::endl; + + edm::ParameterSet const kMainInput(modulePSet("@main_input","InputSource","Source")); + + edm::ParameterSet const kNoLabelModule(modulePSet("", "NoLabelModule","ESProducer")); + edm::ParameterSet const kLabelModule(modulePSet("labeled", "LabelModule","ESProducer")); + edm::ParameterSet const kNoLabelRetriever(modulePSet("", "NoLabelRetriever","ESSource")); + edm::ParameterSet const kLabelRetriever(modulePSet("label", "LabelRetriever","ESSource")); + + CPPUNIT_ASSERT(kEmpty != (test->getParameterSet("cones"))); + CPPUNIT_ASSERT(kCone == test->getParameterSet("cones")); + + CPPUNIT_ASSERT(kEmpty != (test->getParameterSet("@main_input"))); + CPPUNIT_ASSERT(kMainInput == (test->getParameterSet("@main_input"))); + + CPPUNIT_ASSERT(kEmpty != (test->getParameterSet("NoLabelModule@"))); + CPPUNIT_ASSERT(kNoLabelModule == test->getParameterSet("NoLabelModule@")); + + CPPUNIT_ASSERT(kEmpty != (test->getParameterSet("LabelModule@labeled"))); + CPPUNIT_ASSERT(kLabelModule == test->getParameterSet("LabelModule@labeled")); + + CPPUNIT_ASSERT(kEmpty != (test->getParameterSet("NoLabelRetriever@"))); + CPPUNIT_ASSERT(kNoLabelRetriever == test->getParameterSet("NoLabelRetriever@")); + + CPPUNIT_ASSERT(kEmpty != (test->getParameterSet("LabelRetriever@label"))); + CPPUNIT_ASSERT(kLabelRetriever == test->getParameterSet("LabelRetriever@label")); +} + +void testmakeprocess::emptyModuleTest() { + char const* kTest = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.thing = cms.EDFilter('XX')\n" + "process.p = cms.Path(process.thing)\n"; + + ParameterSetPtr test = pSet(kTest); + + edm::ParameterSet& myparams = *(test); + myparams.registerIt(); + std::string rep = myparams.toString(); + edm::ParameterSet copy(rep); + CPPUNIT_ASSERT(copy == myparams); +} + +void testmakeprocess::taskTest() { + char const* kTest = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.load(\"FWCore.PythonParameterSet.test.testTask_cff\")\n" + "t10 = cms.Task(process.m29, process.m30, process.f29, process.f30," + "process.ess27, process.ess28, process.esp27, process.esp28," + "process.serv27, process.serv28)\n"; + + ParameterSetPtr test = pSet(kTest); + + + CPPUNIT_ASSERT(!test->existsAs("m1") && + !test->existsAs("m2") && + test->existsAs("m3") && + test->existsAs("m4") && + test->existsAs("m5") && + test->existsAs("m6") && + test->existsAs("m7") && + test->existsAs("m8") && + test->existsAs("m9") && + test->existsAs("m10") && + test->existsAs("m11") && + test->existsAs("m12") && + test->existsAs("m13") && + test->existsAs("m14") && + test->existsAs("m15") && + test->existsAs("m16") && + test->existsAs("m17") && + test->existsAs("m18") && + test->existsAs("m19") && + test->existsAs("m20") && + test->existsAs("m21") && + test->existsAs("m22") && + test->existsAs("m23") && + test->existsAs("m24") && + test->existsAs("m25") && + test->existsAs("m26") && + !test->existsAs("m27") && + !test->existsAs("m28") && + !test->existsAs("m29") && + !test->existsAs("m30")); + + CPPUNIT_ASSERT(!test->existsAs("f1") && + !test->existsAs("f2") && + test->existsAs("f3") && + test->existsAs("f4") && + test->existsAs("f5") && + test->existsAs("f6") && + test->existsAs("f7") && + test->existsAs("f8") && + test->existsAs("f9") && + test->existsAs("f10") && + test->existsAs("f11") && + test->existsAs("f12") && + test->existsAs("f13") && + test->existsAs("f14") && + test->existsAs("f15") && + test->existsAs("f16") && + test->existsAs("f17") && + test->existsAs("f18") && + test->existsAs("f19") && + test->existsAs("f20") && + test->existsAs("f21") && + test->existsAs("f22") && + test->existsAs("f23") && + test->existsAs("f24") && + test->existsAs("f25") && + test->existsAs("f26") && + !test->existsAs("f27") && + !test->existsAs("f28") && + !test->existsAs("f29") && + !test->existsAs("f30")); + + CPPUNIT_ASSERT(!test->existsAs("a1") && + !test->existsAs("a2") && + test->existsAs("a3") && + test->existsAs("a4") && + test->existsAs("a5") && + test->existsAs("a6") && + test->existsAs("a7") && + test->existsAs("a8") && + test->existsAs("a9") && + test->existsAs("a10")); + + CPPUNIT_ASSERT(!test->existsAs("o1") && + !test->existsAs("o2") && + test->existsAs("o7") && + test->existsAs("o8") && + test->existsAs("o9") && + test->existsAs("o10")); + + CPPUNIT_ASSERT(test->existsAs("ess@ess1") && + test->existsAs("ess2@") && + !test->existsAs("ess@ess3") && + !test->existsAs("ess4@") && + test->existsAs("ess@ess11") && + test->existsAs("ess12@") && + test->existsAs("ess@ess13") && + test->existsAs("ess14@") && + test->existsAs("ess@ess15") && + test->existsAs("ess16@") && + test->existsAs("ess@ess17") && + test->existsAs("ess18@") && + test->existsAs("ess@ess19") && + test->existsAs("ess20@") && + test->existsAs("ess@ess21") && + test->existsAs("ess22@") && + test->existsAs("ess@ess23") && + test->existsAs("ess24@") && + test->existsAs("ess@ess25") && + test->existsAs("ess26@") && + test->existsAs("ess@ess27") && + test->existsAs("ess28@")); + + CPPUNIT_ASSERT(test->existsAs("esp@esp1") && + test->existsAs("esp2@") && + !test->existsAs("esp@esp3") && + !test->existsAs("esp4@") && + test->existsAs("esp@esp11") && + test->existsAs("esp12@") && + test->existsAs("esp@esp13") && + test->existsAs("esp14@") && + test->existsAs("esp@esp15") && + test->existsAs("esp16@") && + test->existsAs("esp@esp17") && + test->existsAs("esp18@") && + test->existsAs("esp@esp19") && + test->existsAs("esp20@") && + test->existsAs("esp@esp21") && + test->existsAs("esp22@") && + test->existsAs("esp@esp23") && + test->existsAs("esp24@") && + test->existsAs("esp@esp25") && + test->existsAs("esp26@") && + test->existsAs("esp@esp27") && + test->existsAs("esp28@")); + + std::vector const& vpsetServices = test->getUntrackedParameterSetVector("services"); + // Note that the vector is not sorted. The order + // depends on the order of a python iteration through a dictionary + // which could be anything. + std::set serviceNames; + for (auto const& pset : vpsetServices) { + serviceNames.insert(pset.getParameter("@service_type")); + } + std::vector expectedServiceNames; + expectedServiceNames.emplace_back("serv1"); + expectedServiceNames.emplace_back("serv2"); + expectedServiceNames.emplace_back("serv11"); + expectedServiceNames.emplace_back("serv12"); + expectedServiceNames.emplace_back("serv13"); + expectedServiceNames.emplace_back("serv14"); + expectedServiceNames.emplace_back("serv15"); + expectedServiceNames.emplace_back("serv16"); + expectedServiceNames.emplace_back("serv17"); + expectedServiceNames.emplace_back("serv18"); + expectedServiceNames.emplace_back("serv19"); + expectedServiceNames.emplace_back("serv20"); + expectedServiceNames.emplace_back("serv21"); + expectedServiceNames.emplace_back("serv22"); + expectedServiceNames.emplace_back("serv23"); + expectedServiceNames.emplace_back("serv24"); + expectedServiceNames.emplace_back("serv25"); + expectedServiceNames.emplace_back("serv26"); + expectedServiceNames.emplace_back("serv27"); + expectedServiceNames.emplace_back("serv28"); + bool result = true; + for (auto const& name : expectedServiceNames) { + if (serviceNames.find(name) == serviceNames.end()) { + result = false; + } + } + if (serviceNames.size() != expectedServiceNames.size()) { + result = false; + } + CPPUNIT_ASSERT(result); +} + +void testmakeprocess::taskTestWithEmptySchedule() { + char const* kTest = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.load(\"FWCore.PythonParameterSet.test.testTask_cff\")\n" + "t10 = cms.Task(process.m29, process.m30, process.f29, process.f30," + "process.ess27, process.ess28, process.esp27, process.esp28," + "process.serv27, process.serv28)\n" + "process.schedule = cms.Schedule()\n"; + + ParameterSetPtr test = pSet(kTest); + + CPPUNIT_ASSERT(!test->existsAs("m1") && + !test->existsAs("m2") && + !test->existsAs("m3") && + !test->existsAs("m4") && + !test->existsAs("m5") && + !test->existsAs("m6") && + !test->existsAs("m7") && + !test->existsAs("m8") && + !test->existsAs("m9") && + !test->existsAs("m10") && + !test->existsAs("m11") && + !test->existsAs("m12") && + !test->existsAs("m13") && + !test->existsAs("m14") && + !test->existsAs("m15") && + !test->existsAs("m16") && + !test->existsAs("m17") && + !test->existsAs("m18") && + !test->existsAs("m19") && + !test->existsAs("m20") && + !test->existsAs("m21") && + !test->existsAs("m22") && + !test->existsAs("m23") && + !test->existsAs("m24") && + !test->existsAs("m25") && + !test->existsAs("m26") && + !test->existsAs("m27") && + !test->existsAs("m28") && + !test->existsAs("m29") && + !test->existsAs("m30")); + + CPPUNIT_ASSERT(!test->existsAs("f1") && + !test->existsAs("f2") && + !test->existsAs("f3") && + !test->existsAs("f4") && + !test->existsAs("f5") && + !test->existsAs("f6") && + !test->existsAs("f7") && + !test->existsAs("f8") && + !test->existsAs("f9") && + !test->existsAs("f10") && + !test->existsAs("f11") && + !test->existsAs("f12") && + !test->existsAs("f13") && + !test->existsAs("f14") && + !test->existsAs("f15") && + !test->existsAs("f16") && + !test->existsAs("f17") && + !test->existsAs("f18") && + !test->existsAs("f19") && + !test->existsAs("f20") && + !test->existsAs("f21") && + !test->existsAs("f22") && + !test->existsAs("f23") && + !test->existsAs("f24") && + !test->existsAs("f25") && + !test->existsAs("f26") && + !test->existsAs("f27") && + !test->existsAs("f28") && + !test->existsAs("f29") && + !test->existsAs("f30")); + + CPPUNIT_ASSERT(!test->existsAs("a1") && + !test->existsAs("a2") && + !test->existsAs("a3") && + !test->existsAs("a4") && + !test->existsAs("a5") && + !test->existsAs("a6") && + !test->existsAs("a7") && + !test->existsAs("a8") && + !test->existsAs("a9") && + !test->existsAs("a10")); + + CPPUNIT_ASSERT(!test->existsAs("o1") && + !test->existsAs("o2") && + !test->existsAs("o7") && + !test->existsAs("o8") && + !test->existsAs("o9") && + !test->existsAs("o10")); + + CPPUNIT_ASSERT(test->existsAs("ess@ess1") && + test->existsAs("ess2@") && + !test->existsAs("ess@ess3") && + !test->existsAs("ess4@") && + !test->existsAs("ess@ess11") && + !test->existsAs("ess12@") && + !test->existsAs("ess@ess13") && + !test->existsAs("ess14@") && + !test->existsAs("ess@ess15") && + !test->existsAs("ess16@") && + !test->existsAs("ess@ess17") && + !test->existsAs("ess18@") && + !test->existsAs("ess@ess19") && + !test->existsAs("ess20@") && + !test->existsAs("ess@ess21") && + !test->existsAs("ess22@") && + !test->existsAs("ess@ess23") && + !test->existsAs("ess24@") && + !test->existsAs("ess@ess25") && + !test->existsAs("ess26@") && + test->existsAs("ess@ess27") && + test->existsAs("ess28@")); + + CPPUNIT_ASSERT(test->existsAs("esp@esp1") && + test->existsAs("esp2@") && + !test->existsAs("esp@esp3") && + !test->existsAs("esp4@") && + !test->existsAs("esp@esp11") && + !test->existsAs("esp12@") && + !test->existsAs("esp@esp13") && + !test->existsAs("esp14@") && + !test->existsAs("esp@esp15") && + !test->existsAs("esp16@") && + !test->existsAs("esp@esp17") && + !test->existsAs("esp18@") && + !test->existsAs("esp@esp19") && + !test->existsAs("esp20@") && + !test->existsAs("esp@esp21") && + !test->existsAs("esp22@") && + !test->existsAs("esp@esp23") && + !test->existsAs("esp24@") && + !test->existsAs("esp@esp25") && + !test->existsAs("esp26@") && + test->existsAs("esp@esp27") && + test->existsAs("esp28@")); + + std::vector const& vpsetServices = test->getUntrackedParameterSetVector("services"); + // Note that the vector is not sorted. The order + // depends on the order of a python iteration through a dictionary + // which could be anything. + std::set serviceNames; + for (auto const& pset : vpsetServices) { + serviceNames.insert(pset.getParameter("@service_type")); + } + std::vector expectedServiceNames; + expectedServiceNames.emplace_back("serv1"); + expectedServiceNames.emplace_back("serv2"); + expectedServiceNames.emplace_back("serv27"); + expectedServiceNames.emplace_back("serv28"); + bool result = true; + for (auto const& name : expectedServiceNames) { + if (serviceNames.find(name) == serviceNames.end()) { + result = false; + } + } + if (serviceNames.size() != expectedServiceNames.size()) { + result = false; + } + CPPUNIT_ASSERT(result); +} + +void testmakeprocess::taskTestWithSchedule() { + char const* kTest = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.load(\"FWCore.PythonParameterSet.test.testTask_cff\")\n" + "t10 = cms.Task(process.m29, process.m30, process.f29, process.f30," + "process.ess27, process.ess28, process.esp27, process.esp28," + "process.serv27, process.serv28)\n" + "process.schedule = cms.Schedule(process.p1, process.p2, process.e1, process.e2," + "process.pf1, process.pf2, process.ef1, process.ef2," + "process.pa1, process.pa2, process.ea1, process.ea2," + "process.eo1, process.eo2, process.pess2, process.eess2," + "process.pesp2, process.eesp2, process.pserv2, process.eserv2," + "tasks=[process.t9, process.tf9, process.tess10,process.tesp10," + "process.tserv10])\n"; + + ParameterSetPtr test = pSet(kTest); + + CPPUNIT_ASSERT(!test->existsAs("m1") && + !test->existsAs("m2") && + test->existsAs("m3") && + test->existsAs("m4") && + test->existsAs("m5") && + test->existsAs("m6") && + test->existsAs("m7") && + test->existsAs("m8") && + test->existsAs("m9") && + test->existsAs("m10") && + test->existsAs("m11") && + test->existsAs("m12") && + test->existsAs("m13") && + test->existsAs("m14") && + test->existsAs("m15") && + test->existsAs("m16") && + test->existsAs("m17") && + test->existsAs("m18") && + test->existsAs("m19") && + test->existsAs("m20") && + test->existsAs("m21") && + test->existsAs("m22") && + test->existsAs("m23") && + test->existsAs("m24") && + test->existsAs("m25") && + test->existsAs("m26") && + test->existsAs("m27") && + test->existsAs("m28") && + !test->existsAs("m29") && + !test->existsAs("m30")); + + CPPUNIT_ASSERT(!test->existsAs("f1") && + !test->existsAs("f2") && + test->existsAs("f3") && + test->existsAs("f4") && + test->existsAs("f5") && + test->existsAs("f6") && + test->existsAs("f7") && + test->existsAs("f8") && + test->existsAs("f9") && + test->existsAs("f10") && + test->existsAs("f11") && + test->existsAs("f12") && + test->existsAs("f13") && + test->existsAs("f14") && + test->existsAs("f15") && + test->existsAs("f16") && + test->existsAs("f17") && + test->existsAs("f18") && + test->existsAs("f19") && + test->existsAs("f20") && + test->existsAs("f21") && + test->existsAs("f22") && + test->existsAs("f23") && + test->existsAs("f24") && + test->existsAs("f25") && + test->existsAs("f26") && + test->existsAs("f27") && + test->existsAs("f28") && + !test->existsAs("f29") && + !test->existsAs("f30")); + + CPPUNIT_ASSERT(!test->existsAs("a1") && + !test->existsAs("a2") && + test->existsAs("a3") && + test->existsAs("a4") && + test->existsAs("a5") && + test->existsAs("a6") && + test->existsAs("a7") && + test->existsAs("a8") && + test->existsAs("a9") && + test->existsAs("a10")); + + CPPUNIT_ASSERT(!test->existsAs("o1") && + !test->existsAs("o2") && + test->existsAs("o7") && + test->existsAs("o8") && + test->existsAs("o9") && + test->existsAs("o10")); + + CPPUNIT_ASSERT(test->existsAs("ess@ess1") && + test->existsAs("ess2@") && + test->existsAs("ess@ess3") && + test->existsAs("ess4@") && + test->existsAs("ess@ess11") && + test->existsAs("ess12@") && + test->existsAs("ess@ess13") && + test->existsAs("ess14@") && + test->existsAs("ess@ess15") && + test->existsAs("ess16@") && + test->existsAs("ess@ess17") && + test->existsAs("ess18@") && + test->existsAs("ess@ess19") && + test->existsAs("ess20@") && + test->existsAs("ess@ess21") && + test->existsAs("ess22@") && + test->existsAs("ess@ess23") && + test->existsAs("ess24@") && + test->existsAs("ess@ess25") && + test->existsAs("ess26@") && + test->existsAs("ess@ess27") && + test->existsAs("ess28@")); + + CPPUNIT_ASSERT(test->existsAs("esp@esp1") && + test->existsAs("esp2@") && + test->existsAs("esp@esp3") && + test->existsAs("esp4@") && + test->existsAs("esp@esp11") && + test->existsAs("esp12@") && + test->existsAs("esp@esp13") && + test->existsAs("esp14@") && + test->existsAs("esp@esp15") && + test->existsAs("esp16@") && + test->existsAs("esp@esp17") && + test->existsAs("esp18@") && + test->existsAs("esp@esp19") && + test->existsAs("esp20@") && + test->existsAs("esp@esp21") && + test->existsAs("esp22@") && + test->existsAs("esp@esp23") && + test->existsAs("esp24@") && + test->existsAs("esp@esp25") && + test->existsAs("esp26@") && + test->existsAs("esp@esp27") && + test->existsAs("esp28@")); + + std::vector const& vpsetServices = test->getUntrackedParameterSetVector("services"); + // Note that the vector is not sorted. The order + // depends on the order of a python iteration through a dictionary + // which could be anything. + std::set serviceNames; + for (auto const& pset : vpsetServices) { + serviceNames.insert(pset.getParameter("@service_type")); + } + std::vector expectedServiceNames; + expectedServiceNames.emplace_back("serv1"); + expectedServiceNames.emplace_back("serv2"); + expectedServiceNames.emplace_back("serv3"); + expectedServiceNames.emplace_back("serv4"); + expectedServiceNames.emplace_back("serv11"); + expectedServiceNames.emplace_back("serv12"); + expectedServiceNames.emplace_back("serv13"); + expectedServiceNames.emplace_back("serv14"); + expectedServiceNames.emplace_back("serv15"); + expectedServiceNames.emplace_back("serv16"); + expectedServiceNames.emplace_back("serv17"); + expectedServiceNames.emplace_back("serv18"); + expectedServiceNames.emplace_back("serv19"); + expectedServiceNames.emplace_back("serv20"); + expectedServiceNames.emplace_back("serv21"); + expectedServiceNames.emplace_back("serv22"); + expectedServiceNames.emplace_back("serv23"); + expectedServiceNames.emplace_back("serv24"); + expectedServiceNames.emplace_back("serv25"); + expectedServiceNames.emplace_back("serv26"); + expectedServiceNames.emplace_back("serv27"); + expectedServiceNames.emplace_back("serv28"); + bool result = true; + for (auto const& name : expectedServiceNames) { + if (serviceNames.find(name) == serviceNames.end()) { + result = false; + } + } + if (serviceNames.size() != expectedServiceNames.size()) { + result = false; + } + CPPUNIT_ASSERT(result); +} + +/* +void testmakeprocess::windowsLineEndingTest() { + + std::ostringstream oss; + char const ret = '\r'; + char const nl = '\n'; + char const dquote = '"'; + char const backsl = '\\'; + + oss << ret << nl + << "import FWCore.ParameterSet.Config as cms" << ret << nl + << "process = cms.Process('test')" << ret << nl + << " source = cms.Source('InputSource'," << ret << nl + << " i=cms.int32(1)" << ret << nl + << " s1 = cms.string(" << dquote << ret << dquote << ')' <getProcessPSet()); + + edm::ParameterSet src = p.getParameterSet("@main_input"); + CPPUNIT_ASSERT(src.getParameter("i") == 1); + std::string s1 = src.getParameter("s1"); + std::string s2 = src.getParameter("s2"); + + std::cerr << "\nsize of s1 is: " << s1.size(); + std::cerr << "\nsize of s2 is: " << s2.size() << '\n'; + + CPPUNIT_ASSERT(s1.size() == 1); + CPPUNIT_ASSERT(s1[0] == ret); + + CPPUNIT_ASSERT(s2.size() == 2); + CPPUNIT_ASSERT(s2[0] == backsl); + CPPUNIT_ASSERT(s2[1] == 'r'); +} +*/ diff --git a/FWCore/PyDevParameterSet/test/makepset_t.cppunit.cc b/FWCore/PyDevParameterSet/test/makepset_t.cppunit.cc new file mode 100644 index 0000000000000..95fe0395a6f13 --- /dev/null +++ b/FWCore/PyDevParameterSet/test/makepset_t.cppunit.cc @@ -0,0 +1,503 @@ +/* + * makepset_t.cc + * EDMProto + * + * Created by Chris Jones on 5/18/05. + * + */ + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/PyDevParameterSet/interface/PyBind11ProcessDesc.h" +#include "FWCore/Utilities/interface/EDMException.h" +#include "FWCore/Utilities/interface/resolveSymbolicLinks.h" + +#include "cppunit/extensions/HelperMacros.h" + +#include + +#include +#include +#include +#include // for setenv; is likely to fail +#include +#include +#include + +class testmakepset: public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(testmakepset); + CPPUNIT_TEST(typesTest); + CPPUNIT_TEST(secsourceTest); + CPPUNIT_TEST(usingBlockTest); + CPPUNIT_TEST(fileinpathTest); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp(){} + void tearDown(){} + void typesTest(); + void secsourceTest(); + void usingBlockTest(); + void fileinpathTest(); + + private: + void secsourceAux(); + void usingBlockAux(); + void fileinpathAux(); +}; + +///registration of the test so that the runner can find it +CPPUNIT_TEST_SUITE_REGISTRATION(testmakepset); + +void testmakepset::secsourceTest() { + try { this->secsourceAux(); } + catch (cms::Exception& x) { + std::cerr << "testmakepset::secsourceTest() caught a cms::Exception\n"; + std::cerr << x.what() << '\n'; + throw; + } + catch (std::exception& x) { + std::cerr << "testmakepset::secsourceTest() caught a std::exception\n"; + std::cerr << x.what() << '\n'; + throw; + } + catch (...) { + std::cerr << "testmakepset::secsourceTest() caught an unidentified exception\n"; + throw; + } +} + +void testmakepset::secsourceAux() { + char const* kTest = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('PROD')\n" + "process.maxEvents = cms.untracked.PSet(\n" + " input = cms.untracked.int32(2)\n" + ")\n" + "process.source = cms.Source('PoolSource',\n" + " fileNames = cms.untracked.vstring('file:main.root')\n" + ")\n" + "process.out = cms.OutputModule('PoolOutputModule',\n" + " fileName = cms.string('file:CumHits.root')\n" + ")\n" + "process.mix = cms.EDFilter('MixingModule',\n" + " input = cms.SecSource('EmbeddedRootSource',\n" + " fileNames = cms.untracked.vstring('file:pileup.root')\n" + " ),\n" + " max_bunch = cms.int32(3),\n" + " average_number = cms.double(14.3),\n" + " min_bunch = cms.int32(-5),\n" + " type = cms.string('fixed')\n" + ")\n" + "process.p = cms.Path(process.mix)\n" + "process.ep = cms.EndPath(process.out)\n"; + + std::string config(kTest); + + // Create the ParameterSet object from this configuration string. + PyBind11ProcessDesc builder(config); + std::shared_ptr ps = builder.parameterSet(); + + CPPUNIT_ASSERT(nullptr != ps.get()); + + // Make sure this ParameterSet object has the right contents + edm::ParameterSet const& mixingModuleParams = ps->getParameterSet("mix"); + edm::ParameterSet const& secondarySourceParams = mixingModuleParams.getParameterSet("input"); + CPPUNIT_ASSERT(secondarySourceParams.getParameter("@module_type") == "EmbeddedRootSource"); + CPPUNIT_ASSERT(secondarySourceParams.getParameter("@module_label") == "input"); + CPPUNIT_ASSERT(secondarySourceParams.getUntrackedParameter >("fileNames")[0] == "file:pileup.root"); +} + +void testmakepset::usingBlockTest() { + try { this->usingBlockAux(); } + catch (cms::Exception& x) { + std::cerr << "testmakepset::usingBlockTest() caught a cms::Exception\n"; + std::cerr << x.what() << '\n'; + throw; + } + catch (...) { + std::cerr << "testmakepset::usingBlockTest() caught an unidentified exception\n"; + throw; + } +} + +void testmakepset::usingBlockAux() { + char const* kTest = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('PROD')\n" + "process.maxEvents = cms.untracked.PSet(\n" + " input = cms.untracked.int32(2)\n" + ")\n" + "process.source = cms.Source('PoolSource',\n" + " fileNames = cms.untracked.vstring('file:main.root')\n" + ")\n" + "process.b = cms.PSet(\n" + " s = cms.string('original'),\n" + " r = cms.double(1.5)\n" + ")\n" + "process.m1 = cms.EDFilter('Class1',\n" + " process.b,\n" + " i = cms.int32(1)\n" + ")\n" + "process.m2 = cms.EDFilter('Class2',\n" + " process.b,\n" + " i = cms.int32(2),\n" + " j = cms.int32(3),\n" + " u = cms.uint64(1011),\n" + " l = cms.int64(101010)\n" + ")\n" + "process.p = cms.Path(process.m1+process.m2)\n"; + + std::string config(kTest); + // Create the ParameterSet object from this configuration string. + PyBind11ProcessDesc builder(config); + std::shared_ptr ps = builder.parameterSet(); + CPPUNIT_ASSERT(nullptr != ps.get()); + + // Make sure this ParameterSet object has the right contents + edm::ParameterSet const& m1Params = ps->getParameterSet("m1"); + edm::ParameterSet const& m2Params = ps->getParameterSet("m2"); + CPPUNIT_ASSERT(m1Params.getParameter("i") == 1); + CPPUNIT_ASSERT(m2Params.getParameter("i") == 2); + CPPUNIT_ASSERT(m2Params.getParameter("j") == 3); + CPPUNIT_ASSERT(m2Params.getParameter("l") == 101010); + CPPUNIT_ASSERT(m2Params.getParameter("u") == 1011); + + CPPUNIT_ASSERT(m1Params.getParameter("s") == "original"); + CPPUNIT_ASSERT(m2Params.getParameter("s") == "original"); + + CPPUNIT_ASSERT(m1Params.getParameter("r") == 1.5); + CPPUNIT_ASSERT(m2Params.getParameter("r") == 1.5); +} + +void testmakepset::fileinpathTest() { + try { this->fileinpathAux(); } + catch (cms::Exception& x) { + std::cerr << "testmakepset::fileinpathTest() caught a cms::Exception\n"; + std::cerr << x.what() << '\n'; + throw; + } + catch (...) { + std::cerr << "testmakepset::fileinpathTest() caught an unidentified exception\n"; + throw; + } +} + +void testmakepset::fileinpathAux() { + char const* kTest = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('PROD')\n" + "process.main = cms.PSet(\n" + " topo = cms.FileInPath('Geometry/TrackerSimData/data/trackersens.xml'),\n" + " fip = cms.FileInPath('FWCore/PyDevParameterSet/test/fip.txt'),\n" + " ufip = cms.untracked.FileInPath('FWCore/PyDevParameterSet/test/ufip.txt'),\n" + " extraneous = cms.int32(12)\n" + ")\n" + "process.source = cms.Source('EmptySource')\n"; + + std::string config(kTest); + std::string tmpout; + bool localArea=false; + // Create the ParameterSet object from this configuration string. + { + PyBind11ProcessDesc builder(config); + std::shared_ptr ps = builder.parameterSet(); + CPPUNIT_ASSERT(nullptr != ps.get()); + + edm::ParameterSet const& innerps = ps->getParameterSet("main"); + edm::FileInPath fip = innerps.getParameter("fip"); + edm::FileInPath ufip = innerps.getUntrackedParameter("ufip"); + CPPUNIT_ASSERT(innerps.existsAs("extraneous")); + CPPUNIT_ASSERT(!innerps.existsAs("absent")); + char *releaseBase = getenv("CMSSW_RELEASE_BASE"); + char *localBase = getenv("CMSSW_BASE"); + localArea = (releaseBase != nullptr && strlen(releaseBase) != 0 && strcmp(releaseBase, localBase)); + if(localArea) { + // Need to account for possible symbolic links + std::string const src("/src"); + std::string release = releaseBase + src; + std::string local = localBase + src; + edm::resolveSymbolicLinks(release); + edm::resolveSymbolicLinks(local); + localArea = (local != release); + } + + if(localArea) { + CPPUNIT_ASSERT(fip.location() == edm::FileInPath::Local); + } + CPPUNIT_ASSERT(fip.relativePath() == "FWCore/PyDevParameterSet/test/fip.txt"); + CPPUNIT_ASSERT(ufip.relativePath() == "FWCore/PyDevParameterSet/test/ufip.txt"); + std::string fullpath = fip.fullPath(); + std::cerr << "fullPath is: " << fip.fullPath() << std::endl; + std::cerr << "copy of fullPath is: " << fullpath << std::endl; + + CPPUNIT_ASSERT(!fullpath.empty()); + + tmpout = fullpath.substr(0, fullpath.find("FWCore/PyDevParameterSet/test/fip.txt")) + "tmp.py"; + + edm::FileInPath topo = innerps.getParameter("topo"); + // if the file is local, then just disable this check as then it is expected to fail + { + std::string const src("/src"); + std::string local = localBase + src; + std::string localFile = local + "/Geometry/TrackerSimData/data/trackersens.xml"; + if (!boost::filesystem::exists(localFile) ) + CPPUNIT_ASSERT(topo.location() != edm::FileInPath::Local); + else + std::cerr << "Disabling test against local path for trackersens.xml as package is checked out in this test" << std::endl; + } + CPPUNIT_ASSERT(topo.relativePath() == "Geometry/TrackerSimData/data/trackersens.xml"); + fullpath = topo.fullPath(); + CPPUNIT_ASSERT(!fullpath.empty()); + + std::vector v(1); + CPPUNIT_ASSERT(innerps.getAllFileInPaths(v) == 3); + + CPPUNIT_ASSERT(v.size() == 4); + CPPUNIT_ASSERT(std::count(v.begin(), v.end(), fip) == 1); + CPPUNIT_ASSERT(std::count(v.begin(), v.end(), topo) == 1); + + edm::ParameterSet empty; + v.clear(); + CPPUNIT_ASSERT(empty.getAllFileInPaths(v) == 0); + CPPUNIT_ASSERT(v.empty()); + } + // This last test checks that a FileInPath parameter can be read + // successfully even if the associated file no longer exists. + std::ofstream out(tmpout.c_str()); + CPPUNIT_ASSERT(!(!out)); + + char const* kTest2 = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('PROD')\n" + "process.main = cms.PSet(\n" + " fip2 = cms.FileInPath('tmp.py')\n" + ")\n" + "process.source = cms.Source('EmptySource')\n"; + + std::string config2(kTest2); + // Create the ParameterSet object from this configuration string. + PyBind11ProcessDesc builder2(config2); + unlink(tmpout.c_str()); + std::shared_ptr ps2 = builder2.parameterSet(); + + CPPUNIT_ASSERT(nullptr != ps2.get()); + + edm::ParameterSet const& innerps2 = ps2->getParameterSet("main"); + edm::FileInPath fip2 = innerps2.getParameter("fip2"); + if (localArea) { + CPPUNIT_ASSERT(fip2.location() == edm::FileInPath::Local); + } + CPPUNIT_ASSERT(fip2.relativePath() == "tmp.py"); + std::string fullpath2 = fip2.fullPath(); + std::cerr << "fullPath is: " << fip2.fullPath() << std::endl; + std::cerr << "copy of fullPath is: " << fullpath2 << std::endl; + CPPUNIT_ASSERT(!fullpath2.empty()); +} + +void testmakepset::typesTest() { + //vbool vb = {true, false}; + char const* kTest = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('t')\n" + "process.p = cms.PSet(\n" + " input2 = cms.InputTag('Label2','Instance2'),\n" + " sb3 = cms.string(' '),\n" + " input1 = cms.InputTag('Label1','Instance1'),\n" + " input6 = cms.InputTag('source'),\n" + " ##justasbig = cms.double(inf),\n" + " input4 = cms.InputTag('Label4','Instance4','Process4'),\n" + " input3 = cms.untracked.InputTag('Label3','Instance3'),\n" + " h2 = cms.uint32(255),\n" + " vi = cms.vint32(1, -2),\n" + " input8 = cms.string('deprecatedString:tag'),\n" + " h1 = cms.int32(74),\n" + " vs = cms.vstring('','1', \n" + " '2', \n" + " 'a', 'XXX'),\n" + " vs2 = cms.vstring(), vs3 = cms.vstring(''),\n" + " sb2 = cms.string(''),\n" + " input7 = cms.InputTag('source','sink'),\n" + " ps = cms.PSet(\n" + " b2 = cms.untracked.bool(True)\n" + " ),\n" + " input5 = cms.InputTag('Label5','','Process5'),\n" + " h3 = cms.untracked.uint32(3487559679),\n" + " input = cms.InputTag('Label'),\n" + " vps = cms.VPSet(cms.PSet(\n" + " b3 = cms.bool(False)\n" + " )),\n" + " ##indebt = cms.double(-inf),\n" + " ##big = cms.double(inf),\n" + " vinput = cms.VInputTag(cms.InputTag('l1','i1'), cms.InputTag('l2'), cms.InputTag('l3','i3','p3'), cms.InputTag('l4','','p4'), cms.InputTag('source'), \n" + " cms.InputTag('source','sink')),\n" + " ui = cms.uint32(1),\n" + " eventID = cms.EventID(1, 0, 1),\n" + " b = cms.untracked.bool(True),\n" + " d = cms.double(1.0),\n" + " i = cms.int32(1),\n" + " vui = cms.vuint32(1, 2, 1, 255),\n" + " s = cms.string('this string'),\n" + " sb1 = cms.string(''),\n" + " emptyString = cms.untracked.string(''),\n" + " vEventID = cms.VEventID('1:1', '2:2','3:3'),\n" + " lumi = cms.LuminosityBlockID(55, 65),\n" + " vlumis = cms.VLuminosityBlockID('75:85', '95:105'),\n" + " einput1 = cms.ESInputTag(),\n" + " einput2 = cms.ESInputTag(data='blah'),\n" + " einput3 = cms.ESInputTag('ESProd'),\n" + " einput4 = cms.ESInputTag('ESProd','something'),\n" + " einput5 = cms.ESInputTag('ESProd:something'),\n" + " veinput1 = cms.VESInputTag(),\n" + " veinput2 = cms.VESInputTag(cms.ESInputTag(data='blah'),cms.ESInputTag('ESProd'))\n" + ")\n" + + ; + + std::string config2(kTest); + // Create the ParameterSet object from this configuration string. + PyBind11ProcessDesc builder2(config2); + std::shared_ptr ps2 = builder2.parameterSet(); + edm::ParameterSet const& test = ps2->getParameterSet("p"); + + CPPUNIT_ASSERT(1 == test.getParameter("i")); + CPPUNIT_ASSERT(test.retrieve("i").isTracked()); + CPPUNIT_ASSERT(1 == test.getParameter("ui")); + CPPUNIT_ASSERT(1 == test.getParameter("d")); + //CPPUNIT_ASSERT(100000. < test.getParameter("big")); + //CPPUNIT_ASSERT(100000. < test.getParameter("justasbig")); + //CPPUNIT_ASSERT(-1000000. > test.getParameter("indebt")); + + // test hex numbers + CPPUNIT_ASSERT(74 == test.getParameter("h1")); + CPPUNIT_ASSERT(255 == test.getParameter("h2")); + CPPUNIT_ASSERT(3487559679U == test.getUntrackedParameter("h3")); + + CPPUNIT_ASSERT("this string" == test.getParameter("s")); + CPPUNIT_ASSERT("" == test.getParameter("sb1")); + CPPUNIT_ASSERT("" == test.getUntrackedParameter("emptyString", "default")); + CPPUNIT_ASSERT("" == test.getParameter("sb2")); + CPPUNIT_ASSERT(4 == test.getParameter("sb3").size()); + std::vector vs = test.getParameter >("vs"); + int vssize = vs.size(); + //FIXME doesn't do spaces right + edm::Entry e(test.retrieve("vs")); + CPPUNIT_ASSERT(5 == vssize); + CPPUNIT_ASSERT(vssize && "" == vs[0]); + CPPUNIT_ASSERT(vssize >1 && "1" == vs[1]); + CPPUNIT_ASSERT(vssize >1 && "a" == vs[3]); + vs = test.getParameter >("vs2"); + CPPUNIT_ASSERT(vs.size() == 0); + vs = test.getParameter >("vs3"); + CPPUNIT_ASSERT(vs.size() == 1); + CPPUNIT_ASSERT(vs[0] == ""); + + static unsigned int const vuia[] = {1,2,1,255}; + static std::vector const vui(vuia, vuia+sizeof(vuia)/sizeof(unsigned int)); + CPPUNIT_ASSERT(vui == test.getParameter >("vui")); + + static int const via[] = {1,-2}; + static std::vector const vi(via, via+sizeof(via)/sizeof(int)); + test.getParameter >("vi"); + CPPUNIT_ASSERT(true == test.getUntrackedParameter("b", false)); + CPPUNIT_ASSERT(test.retrieve("vi").isTracked()); + //test.getParameter >("vb"); + edm::ParameterSet const& ps = test.getParameterSet("ps"); + CPPUNIT_ASSERT(true == ps.getUntrackedParameter("b2", false)); + std::vector const& vps = test.getParameterSetVector("vps"); + CPPUNIT_ASSERT(1 == vps.size()); + CPPUNIT_ASSERT(false == vps.front().getParameter("b3")); + + // InputTag + edm::InputTag inputProduct = test.getParameter("input"); + edm::InputTag inputProduct1 = test.getParameter("input1"); + edm::InputTag inputProduct2 = test.getParameter("input2"); + edm::InputTag inputProduct3 = test.getUntrackedParameter("input3"); + edm::InputTag inputProduct4 = test.getParameter("input4"); + edm::InputTag inputProduct5 = test.getParameter("input5"); + edm::InputTag inputProduct6 = test.getParameter("input6"); + edm::InputTag inputProduct7 = test.getParameter("input7"); + edm::InputTag inputProduct8 = test.getParameter("input8"); + + //edm::OutputTag outputProduct = test.getParameter("output"); + + CPPUNIT_ASSERT("Label" == inputProduct.label()); + CPPUNIT_ASSERT("Label1" == inputProduct1.label()); + CPPUNIT_ASSERT("Label2" == inputProduct2.label()); + CPPUNIT_ASSERT("Instance2" == inputProduct2.instance()); + CPPUNIT_ASSERT("Label3" == inputProduct3.label()); + CPPUNIT_ASSERT("Instance3" == inputProduct3.instance()); + CPPUNIT_ASSERT("Label4" == inputProduct4.label()); + CPPUNIT_ASSERT("Instance4" == inputProduct4.instance()); + CPPUNIT_ASSERT("Process4" == inputProduct4.process()); + CPPUNIT_ASSERT("Label5" == inputProduct5.label()); + CPPUNIT_ASSERT("" == inputProduct5.instance()); + CPPUNIT_ASSERT("Process5" == inputProduct5.process()); + CPPUNIT_ASSERT("source" == inputProduct6.label()); + CPPUNIT_ASSERT("source" == inputProduct7.label()); + CPPUNIT_ASSERT("deprecatedString" == inputProduct8.label()); + + // vector of InputTags + + std::vector vtags = test.getParameter >("vinput"); + CPPUNIT_ASSERT("l1" == vtags[0].label()); + CPPUNIT_ASSERT("i1" == vtags[0].instance()); + CPPUNIT_ASSERT("l2" == vtags[1].label()); + CPPUNIT_ASSERT("l3" == vtags[2].label()); + CPPUNIT_ASSERT("i3" == vtags[2].instance()); + CPPUNIT_ASSERT("p3" == vtags[2].process()); + CPPUNIT_ASSERT("l4" == vtags[3].label()); + CPPUNIT_ASSERT("" == vtags[3].instance()); + CPPUNIT_ASSERT("p4" == vtags[3].process()); + CPPUNIT_ASSERT("source" == vtags[4].label()); + CPPUNIT_ASSERT("source" == vtags[5].label()); + + // ESInputTag + edm::ESInputTag einput1 = test.getParameter("einput1"); + edm::ESInputTag einput2 = test.getParameter("einput2"); + edm::ESInputTag einput3 = test.getParameter("einput3"); + edm::ESInputTag einput4 = test.getParameter("einput4"); + edm::ESInputTag einput5 = test.getParameter("einput5"); + CPPUNIT_ASSERT("" == einput1.module()); + CPPUNIT_ASSERT("" == einput1.data()); + CPPUNIT_ASSERT("" == einput2.module()); + CPPUNIT_ASSERT("blah" == einput2.data()); + CPPUNIT_ASSERT("ESProd" == einput3.module()); + CPPUNIT_ASSERT("" == einput3.data()); + CPPUNIT_ASSERT("ESProd" == einput4.module()); + CPPUNIT_ASSERT("something" == einput4.data()); + CPPUNIT_ASSERT("ESProd" == einput5.module()); + CPPUNIT_ASSERT("something" == einput5.data()); + + std::vector veinput1 = test.getParameter >("veinput1"); + std::vector veinput2 = test.getParameter >("veinput2"); + CPPUNIT_ASSERT(0 == veinput1.size()); + CPPUNIT_ASSERT(2 == veinput2.size()); + CPPUNIT_ASSERT("" == veinput2[0].module()); + CPPUNIT_ASSERT("blah" == veinput2[0].data()); + CPPUNIT_ASSERT("ESProd" == veinput2[1].module()); + CPPUNIT_ASSERT("" == veinput2[1].data()); + + edm::EventID eventID = test.getParameter("eventID"); + std::vector vEventID = test.getParameter >("vEventID"); + CPPUNIT_ASSERT(1 == eventID.run()); + CPPUNIT_ASSERT(1 == eventID.event()); + CPPUNIT_ASSERT(1 == vEventID[0].run()); + CPPUNIT_ASSERT(1 == vEventID[0].event()); + CPPUNIT_ASSERT(3 == vEventID[2].run()); + CPPUNIT_ASSERT(3 == vEventID[2].event()); + + edm::LuminosityBlockID lumi = test.getParameter("lumi"); + CPPUNIT_ASSERT(55 == lumi.run()); + CPPUNIT_ASSERT(65 == lumi.luminosityBlock()); + std::vector vlumis = test.getParameter >("vlumis"); + CPPUNIT_ASSERT(vlumis.size() == 2); + CPPUNIT_ASSERT(vlumis[0].run() == 75); + CPPUNIT_ASSERT(vlumis[0].luminosityBlock() == 85); + CPPUNIT_ASSERT(vlumis[1].run() == 95); + CPPUNIT_ASSERT(vlumis[1].luminosityBlock() == 105); + + //CPPUNIT_ASSERT("Label2" == outputProduct.label()); + //CPPUNIT_ASSERT("" == outputProduct.instance()); + //CPPUNIT_ASSERT("Alias2" == outputProduct.alias()); + //BOOST_CHECK_THROW(makePSet(*nodeList), std::runtime_error); +} diff --git a/FWCore/PyDevParameterSet/test/processbuilder_t.cppunit.cpp b/FWCore/PyDevParameterSet/test/processbuilder_t.cppunit.cpp new file mode 100644 index 0000000000000..7df92d2692cc5 --- /dev/null +++ b/FWCore/PyDevParameterSet/test/processbuilder_t.cppunit.cpp @@ -0,0 +1,404 @@ +/** + +@file : processbuilder_t.cpp + +@brief test suit for process building and schedule validation + +*/ + +#include + +#include +#include +#include "FWCore/Utilities/interface/EDMException.h" + +#include + +#include +#include +#include + +class testProcessDesc: public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(testProcessDesc); + + CPPUNIT_TEST(trivialPathTest); + CPPUNIT_TEST(simplePathTest); + CPPUNIT_TEST(sequenceSubstitutionTest); + CPPUNIT_TEST(attriggertest); + CPPUNIT_TEST(nestedSequenceSubstitutionTest); + CPPUNIT_TEST(sequenceSubstitutionTest2); + CPPUNIT_TEST(sequenceSubstitutionTest3); + CPPUNIT_TEST(multiplePathsTest); + // python throws some different exception + //CPPUNIT_TEST_EXCEPTION(inconsistentPathTest,edm::Exception); + //CPPUNIT_TEST_EXCEPTION(inconsistentMultiplePathTest,edm::Exception); + + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() {} + void tearDown() {} + + void trivialPathTest(); + void simplePathTest(); + void sequenceSubstitutionTest(); + void attriggertest(); + void nestedSequenceSubstitutionTest(); + void sequenceSubstitutionTest2(); + void sequenceSubstitutionTest3(); + void multiplePathsTest(); + void inconsistentPathTest(); + void inconsistentMultiplePathTest(); +}; + +///registration of the test so that the runner can find it +CPPUNIT_TEST_SUITE_REGISTRATION(testProcessDesc); + +void testProcessDesc::trivialPathTest() { + std::string str = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('X')\n" + "process.a = cms.EDFilter('A',\n" + " p = cms.int32(3)\n" + ")\n" + "process.b = cms.EDProducer('B')\n" + "process.c = cms.EDProducer('C')\n" + "process.p = cms.Path(process.a*process.b*process.c)\n"; + + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + Strs s = (*test).getParameter >("p"); + CPPUNIT_ASSERT(s[0]=="a"); + //CPPUNIT_ASSERT(b->getDependencies("a")==""); +} + +void testProcessDesc::simplePathTest() { + + std::string str = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('X')\n" + "process.a = cms.EDFilter('A',\n" + " p = cms.int32(3)\n" + ")\n" + "process.b = cms.EDFilter('A',\n" + " p = cms.int32(3)\n" + ")\n" + "process.c = cms.EDFilter('A',\n" + " p = cms.int32(3)\n" + ")\n" + "process.p = cms.Path(process.a*process.b*process.c)\n"; + + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + Strs s = (*test).getParameter >("p"); + CPPUNIT_ASSERT(s[0]=="a"); + CPPUNIT_ASSERT(s[1]=="b"); + CPPUNIT_ASSERT(s[2]=="c"); + + //CPPUNIT_ASSERT (b->getDependencies("a")==""); + //CPPUNIT_ASSERT (b->getDependencies("b")=="a,"); + //CPPUNIT_ASSERT (b->getDependencies("c")=="a,b,"); +} + +void testProcessDesc:: attriggertest () { + + std::string str = + "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.cone1 = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(5)\n" + ")\n" + "process.cone2 = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.somejet1 = cms.EDFilter('PhonyJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.somejet2 = cms.EDFilter('PhonyJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.jtanalyzer = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.output = cms.OutputModule('OutputModule')\n" + "process.cones = cms.Sequence(process.cone1*process.cone2)\n" + "process.jets = cms.Sequence(process.somejet1*process.somejet2)\n" + "process.path1 = cms.Path(process.cones*process.jets*process.jtanalyzer)\n" + "process.epath = cms.EndPath(process.output)\n"; + + try { + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + edm::ParameterSet const& trig_pset = + (*test).getParameterSet("@trigger_paths"); + Strs tnames = trig_pset.getParameter("@trigger_paths"); + Strs enames = (*test).getParameter("@end_paths"); + + CPPUNIT_ASSERT(tnames[0]=="path1"); + CPPUNIT_ASSERT(enames[0]=="epath"); + + // see if the auto-schedule is correct + Strs schedule = (*test).getParameter("@paths"); + CPPUNIT_ASSERT(schedule.size() == 2); + CPPUNIT_ASSERT(schedule[0] == "path1"); + CPPUNIT_ASSERT(schedule[1] == "epath"); + + } + catch (cms::Exception& exc) { + std::cerr << "Got an cms::Exception: " << exc.what() << "\n"; + throw; + } + catch (std::exception& exc) { + std::cerr << "Got an std::exception: " << exc.what() << "\n"; + throw; + } + catch (...) { + std::cerr << "Got an unknown exception: " << "\n"; + throw; + } +} + +void testProcessDesc:: sequenceSubstitutionTest () { + + std::string str = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.cone1 = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(5)\n" + ")\n" + "process.cone2 = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.somejet1 = cms.EDFilter('PhonyJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.somejet2 = cms.EDFilter('PhonyJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.jtanalyzer = cms.EDFilter('PhonyConeJet',\n" + " i = cms.int32(7)\n" + ")\n" + "process.cones = cms.Sequence(process.cone1*process.cone2)\n" + "process.jets = cms.Sequence(process.somejet1*process.somejet2)\n" + "process.path1 = cms.Path(process.cones*process.jets*process.jtanalyzer)\n"; + + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + Strs s = (*test).getParameter >("path1"); + CPPUNIT_ASSERT(s[0]=="cone1"); + CPPUNIT_ASSERT(s[1]=="cone2"); + CPPUNIT_ASSERT(s[2]=="somejet1"); + CPPUNIT_ASSERT(s[3]=="somejet2"); + CPPUNIT_ASSERT(s[4]=="jtanalyzer"); + + //CPPUNIT_ASSERT (b->getDependencies("cone1")==""); + //CPPUNIT_ASSERT (b->getDependencies("cone2")=="cone1,"); + //CPPUNIT_ASSERT (b->getDependencies("somejet1")=="cone1,cone2,"); + //CPPUNIT_ASSERT (b->getDependencies("somejet2")=="cone1,cone2,somejet1,"); + //CPPUNIT_ASSERT (b->getDependencies("jtanalyzer")=="cone1,cone2,somejet1,somejet2,"); +} + +void testProcessDesc::nestedSequenceSubstitutionTest() { + + std::string str = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.a = cms.EDProducer('PhonyConeJet', i = cms.int32(5))\n" + "process.b = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.c = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.d = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.s1 = cms.Sequence( process.a+ process.b)\n" + "process.s2 = cms.Sequence(process.s1+ process.c)\n" + "process.path1 = cms.Path(process.s2+process.d)\n"; + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + Strs s = (*test).getParameter >("path1"); + CPPUNIT_ASSERT(s[0]=="a"); + CPPUNIT_ASSERT(s[1]=="b"); + CPPUNIT_ASSERT(s[2]=="c"); + CPPUNIT_ASSERT(s[3]=="d"); + + //CPPUNIT_ASSERT (b.getDependencies("a")==""); + //CPPUNIT_ASSERT (b.getDependencies("b")=="a,"); + //CPPUNIT_ASSERT (b.getDependencies("c")=="a,b,"); + //CPPUNIT_ASSERT (b.getDependencies("d")=="a,b,c,"); +} + +void testProcessDesc::sequenceSubstitutionTest2() { + + std::string str = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.cone1 = cms.EDProducer('PhonyConeJet', i = cms.int32(5))\n" + "process.cone2 = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.cone3 = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.somejet1 = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.somejet2 = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.jtanalyzer = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.cones = cms.Sequence(process.cone1+ process.cone2+ process.cone3)\n" + "process.jets = cms.Sequence(process.somejet1+ process.somejet2)\n" + "process.path1 = cms.Path(process.cones+process.jets+ process.jtanalyzer)\n"; + + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + Strs s = (*test).getParameter >("path1"); + CPPUNIT_ASSERT(s[0]=="cone1"); + CPPUNIT_ASSERT(s[1]=="cone2"); + CPPUNIT_ASSERT(s[2]=="cone3"); + CPPUNIT_ASSERT(s[3]=="somejet1"); + CPPUNIT_ASSERT(s[4]=="somejet2"); + CPPUNIT_ASSERT(s[5]=="jtanalyzer"); + + //CPPUNIT_ASSERT (b.getDependencies("cone1")==""); + //CPPUNIT_ASSERT (b.getDependencies("cone2")=="cone1,"); + //CPPUNIT_ASSERT (b.getDependencies("cone3")=="cone1,cone2,"); + //CPPUNIT_ASSERT (b.getDependencies("somejet1")=="cone1,cone2,cone3,"); + //CPPUNIT_ASSERT (b.getDependencies("somejet2")=="cone1,cone2,cone3,somejet1,"); + //CPPUNIT_ASSERT (b.getDependencies("jtanalyzer")=="cone1,cone2,cone3,somejet1,somejet2,"); +} + +void testProcessDesc::sequenceSubstitutionTest3() { + + std::string str = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.a = cms.EDProducer('PhonyConeJet', i = cms.int32(5))\n" + "process.b = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.c = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.aa = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.bb = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.cc = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.dd = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.aaa = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.bbb = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.ccc = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.ddd = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.eee = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.last = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + + "process.s1 = cms.Sequence(process.a* process.b* process.c)\n" + "process.s2 = cms.Sequence(process.aa*process.bb*cms.ignore(process.cc)*process.dd)\n" + "process.s3 = cms.Sequence(process.aaa*process.bbb*~process.ccc*process.ddd*process.eee)\n" + "process.path1 = cms.Path(process.s1+process.s3+process.s2+process.last)\n"; + + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + Strs s = (*test).getParameter >("path1"); + CPPUNIT_ASSERT(s[0]=="a"); + CPPUNIT_ASSERT(s[1]=="b"); + CPPUNIT_ASSERT(s[2]=="c"); + CPPUNIT_ASSERT(s[3]=="aaa"); + CPPUNIT_ASSERT(s[4]=="bbb"); + CPPUNIT_ASSERT(s[5]=="!ccc"); + CPPUNIT_ASSERT(s[6]=="ddd"); + CPPUNIT_ASSERT(s[7]=="eee"); + CPPUNIT_ASSERT(s[8]=="aa"); + CPPUNIT_ASSERT(s[9]=="bb"); + CPPUNIT_ASSERT(s[10]=="-cc"); + CPPUNIT_ASSERT(s[11]=="dd"); + CPPUNIT_ASSERT(s[12]=="last"); + + //CPPUNIT_ASSERT (b.getDependencies("a")==""); + //CPPUNIT_ASSERT (b.getDependencies("b")=="a,"); + //CPPUNIT_ASSERT (b.getDependencies("c")=="a,b,"); + //CPPUNIT_ASSERT (b.getDependencies("aaa")=="a,b,c,"); + //CPPUNIT_ASSERT (b.getDependencies("bbb")=="a,aaa,b,c,"); + //CPPUNIT_ASSERT (b.getDependencies("ccc")=="a,aaa,b,bbb,c,"); + //CPPUNIT_ASSERT (b.getDependencies("ddd")=="a,aaa,b,bbb,c,ccc,"); + //CPPUNIT_ASSERT (b.getDependencies("eee")=="a,aaa,b,bbb,c,ccc,ddd,"); + //CPPUNIT_ASSERT (b.getDependencies("aa")=="a,aaa,b,bbb,c,ccc,ddd,eee,"); + //CPPUNIT_ASSERT (b.getDependencies("bb")=="a,aa,aaa,b,bbb,c,ccc,ddd,eee,"); + //CPPUNIT_ASSERT (b.getDependencies("cc")=="a,aa,aaa,b,bb,bbb,c,ccc,ddd,eee,"); + //CPPUNIT_ASSERT (b.getDependencies("dd")=="a,aa,aaa,b,bb,bbb,c,cc,ccc,ddd,eee,"); + //CPPUNIT_ASSERT (b.getDependencies("last")=="a,aa,aaa,b,bb,bbb,c,cc,ccc,dd,ddd,eee,"); + +} + +void testProcessDesc::multiplePathsTest() { + + std::string str = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.cone1 = cms.EDProducer('PhonyConeJet', i = cms.int32(5))\n" + "process.cone2 = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.cone3 = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.somejet1 = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.somejet2 = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.jtanalyzer = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.anotherjtanalyzer = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.cones = cms.Sequence(process.cone1* process.cone2* process.cone3)\n" + "process.jets = cms.Sequence(process.somejet1* process.somejet2)\n" + "process.path1 = cms.Path(process.cones+ process.jtanalyzer)\n" + "process.path2 = cms.Path(process.jets+ process.anotherjtanalyzer)\n" + "process.schedule = cms.Schedule(process.path2, process.path1)\n"; + + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); + + typedef std::vector Strs; + + Strs s = (*test).getParameter >("path1"); + CPPUNIT_ASSERT(s[0]=="cone1"); + CPPUNIT_ASSERT(s[1]=="cone2"); + CPPUNIT_ASSERT(s[2]=="cone3"); + CPPUNIT_ASSERT(s[3]=="jtanalyzer"); + + //CPPUNIT_ASSERT (b.getDependencies("cone1")==""); + //CPPUNIT_ASSERT (b.getDependencies("cone2")=="cone1,"); + //CPPUNIT_ASSERT (b.getDependencies("cone3")=="cone1,cone2,"); + //CPPUNIT_ASSERT (b.getDependencies("jtanalyzer")=="cone1,cone2,cone3,"); + + s = (*test).getParameter >("path2"); + CPPUNIT_ASSERT(s[0]=="somejet1"); + CPPUNIT_ASSERT(s[1]=="somejet2"); + CPPUNIT_ASSERT(s[2]=="anotherjtanalyzer"); + + //CPPUNIT_ASSERT (b.getDependencies("somejet1")==""); + //CPPUNIT_ASSERT (b.getDependencies("somejet2")=="somejet1,"); + //CPPUNIT_ASSERT (b.getDependencies("anotherjtanalyzer")=="somejet1,somejet2,"); + + Strs schedule = (*test).getParameter >("@paths"); + + CPPUNIT_ASSERT (schedule.size() == 2); + CPPUNIT_ASSERT (schedule[0] == "path2"); + CPPUNIT_ASSERT (schedule[1] == "path1"); +} + +void testProcessDesc::inconsistentPathTest() { + + std::string str = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.a = cms.EDProducer('PhonyConeJet', i = cms.int32(5))\n" + "process.b = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.c = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.path1 = cms.Path((process.a*process.b)+ (process.c*process.b))\n"; + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); +} + +void testProcessDesc::inconsistentMultiplePathTest() { + + std::string str = "import FWCore.ParameterSet.Config as cms\n" + "process = cms.Process('test')\n" + "process.cone1 = cms.EDProducer('PhonyConeJet', i = cms.int32(5))\n" + "process.cone2 = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.somejet1 = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.somejet2 = cms.EDProducer('PhonyJet', i = cms.int32(7))\n" + "process.jtanalyzer = cms.EDProducer('PhonyConeJet', i = cms.int32(7))\n" + "process.cones = cms.Sequence(process.cone1+ process.cone2)\n" + "process.jets = cms.Sequence(process.somejet1* process.somejet2)\n" + "process.path1 = cms.Path(process.cones*process.jtanalyzer)\n" + "process.path2 = cms.Path(process.jets*process.jtanalyzer)\n"; + + std::shared_ptr test = PyBind11ProcessDesc(str).parameterSet(); +} + +#include diff --git a/FWCore/PyDevParameterSet/test/readpsetsfrom_t.cppunit.cc b/FWCore/PyDevParameterSet/test/readpsetsfrom_t.cppunit.cc new file mode 100644 index 0000000000000..f6ba9d8536809 --- /dev/null +++ b/FWCore/PyDevParameterSet/test/readpsetsfrom_t.cppunit.cc @@ -0,0 +1,53 @@ +/* + * makeprocess_t.cc + * EDMProto + * + * Created by Chris Jones on 5/18/05. + * Changed by Viji Sundararajan on 8-Jul-05. + * + */ + + +#include + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/PyDevParameterSet/interface/MakePyBind11ParameterSets.h" + +#include + +#include +#include +#include +#include +#include + +class testreadpsetsfrom: public CppUnit::TestFixture +{ +CPPUNIT_TEST_SUITE(testreadpsetsfrom); +CPPUNIT_TEST(simpleTest); +CPPUNIT_TEST_SUITE_END(); +public: + void setUp(){} + void tearDown(){} + void simpleTest(); +private: + +}; + + + +///registration of the test so that the runner can find it +CPPUNIT_TEST_SUITE_REGISTRATION(testreadpsetsfrom); + +void testreadpsetsfrom::simpleTest() +{ + const char* kTest ="import FWCore.ParameterSet.Config as cms\n" + "dummy = cms.PSet(b = cms.bool(True))\n" + "foo = cms.PSet(a = cms.string('blah'))\n" + ; + std::shared_ptr test = edm::cmspybind11::readPSetsFrom(kTest); + + CPPUNIT_ASSERT(test->getParameterSet("dummy").getParameter("b")==true); + CPPUNIT_ASSERT(test->getParameterSet("foo").getParameter("a")==std::string("blah")); +} + diff --git a/FWCore/PyDevParameterSet/test/ufip.txt b/FWCore/PyDevParameterSet/test/ufip.txt new file mode 100644 index 0000000000000..a52b9dba51d13 --- /dev/null +++ b/FWCore/PyDevParameterSet/test/ufip.txt @@ -0,0 +1 @@ +Dummy file for the FileInPath test. diff --git a/GeneratorInterface/AMPTInterface/src/AMPTHadronizer.cc b/GeneratorInterface/AMPTInterface/src/AMPTHadronizer.cc index f9c242096cf59..962a9f542ec6f 100644 --- a/GeneratorInterface/AMPTInterface/src/AMPTHadronizer.cc +++ b/GeneratorInterface/AMPTInterface/src/AMPTHadronizer.cc @@ -30,9 +30,8 @@ static CLHEP::HepRandomEngine* amptRandomEngine; extern "C" { - float gen::ranart_(int *idummy) + float gen::ranart_(int *) { - if(false) idummy = idummy; float rannum = amptRandomEngine->flat(); return rannum; } @@ -40,9 +39,8 @@ extern "C" extern "C" { - float gen::ran1_(int *idummy) + float gen::ran1_(int *) { - if(false) idummy = idummy; return amptRandomEngine->flat(); } } diff --git a/GeneratorInterface/Core/src/PythiaHepMCFilterGammaGamma.cc b/GeneratorInterface/Core/src/PythiaHepMCFilterGammaGamma.cc index 963b0edd5f347..66e10a23a5f30 100644 --- a/GeneratorInterface/Core/src/PythiaHepMCFilterGammaGamma.cc +++ b/GeneratorInterface/Core/src/PythiaHepMCFilterGammaGamma.cc @@ -59,8 +59,6 @@ bool PythiaHepMCFilterGammaGamma::filter(const HepMC::GenEvent* myGenEvent) { // around candidates std::vector stable; - std::vector::const_iterator itPart, itStable, itEn; - //---------- // 1. find electron/photon seeds //---------- @@ -140,7 +138,7 @@ bool PythiaHepMCFilterGammaGamma::filter(const HepMC::GenEvent* myGenEvent) { TLorentzVector energy, narrowCone, temp1, temp2, tempseed; tempseed.SetXYZM((*itSeed)->momentum().px(), (*itSeed)->momentum().py(), (*itSeed)->momentum().pz(), 0); - for(itEn = egamma.begin(); itEn != egamma.end(); ++itEn) { + for(auto itEn = egamma.begin(); itEn != egamma.end(); ++itEn) { temp1.SetXYZM((*itEn)->momentum().px(), (*itEn)->momentum().py(), (*itEn)->momentum().pz(), 0); double DR = temp1.DeltaR(tempseed); @@ -168,7 +166,7 @@ bool PythiaHepMCFilterGammaGamma::filter(const HepMC::GenEvent* myGenEvent) { temp2.SetXYZM(energy.Px(), energy.Py(), energy.Pz(), 0); // count number of stable particles within cone around candidate - for(itStable = stable.begin(); itStable != stable.end(); ++itStable) { + for(auto itStable = stable.begin(); itStable != stable.end(); ++itStable) { temp1.SetXYZM((*itStable)->momentum().px(), (*itStable)->momentum().py(), (*itStable)->momentum().pz(), 0); double DR = temp1.DeltaR(temp2); if (DR < dRTkMax) counter++; diff --git a/GeneratorInterface/GenFilters/interface/MCPdgIndexFilter.h b/GeneratorInterface/GenFilters/interface/MCPdgIndexFilter.h index 0d1617fabd7bb..bbcc8b09c6413 100644 --- a/GeneratorInterface/GenFilters/interface/MCPdgIndexFilter.h +++ b/GeneratorInterface/GenFilters/interface/MCPdgIndexFilter.h @@ -10,7 +10,7 @@ #include #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDFilter.h" +#include "FWCore/Framework/interface/global/EDFilter.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -21,19 +21,19 @@ namespace edm { class HepMCProduct; } -class MCPdgIndexFilter : public edm::EDFilter { +class MCPdgIndexFilter : public edm::global::EDFilter<> { public: explicit MCPdgIndexFilter(const edm::ParameterSet&); ~MCPdgIndexFilter() override {}; - bool filter(edm::Event&, const edm::EventSetup&) override; + bool filter(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; private: - bool pass(const edm::Event&); + bool pass(const edm::Event&) const; const edm::EDGetTokenT token_; const std::vector pdgID; const std::vector index; + edm::EDPutTokenT putToken_; const unsigned maxIndex; const bool taggingMode; - const std::string tag; }; #endif diff --git a/GeneratorInterface/GenFilters/src/MCPdgIndexFilter.cc b/GeneratorInterface/GenFilters/src/MCPdgIndexFilter.cc index 74811a9624fb5..ab28a43b24181 100644 --- a/GeneratorInterface/GenFilters/src/MCPdgIndexFilter.cc +++ b/GeneratorInterface/GenFilters/src/MCPdgIndexFilter.cc @@ -7,8 +7,7 @@ MCPdgIndexFilter::MCPdgIndexFilter(const edm::ParameterSet& cfg) : pdgID(cfg.getParameter >("PdgId")), index(cfg.getParameter >("Index")), maxIndex(*std::max_element(index.begin(),index.end())), - taggingMode(cfg.getUntrackedParameter("TagMode",false)), - tag(cfg.getUntrackedParameter("Tag","")) + taggingMode(cfg.getUntrackedParameter("TagMode",false)) { if (pdgID.size() != index.size()) edm::LogWarning("MCPdgIndexFilter") @@ -16,22 +15,23 @@ MCPdgIndexFilter::MCPdgIndexFilter(const edm::ParameterSet& cfg) : << "Sizes of array parameters 'PdgId' and 'Index' differ."; if (taggingMode) { - produces(tag); + auto tag = cfg.getUntrackedParameter("Tag",""); + putToken_ = produces(tag); edm::LogInfo("TagMode") << "Filter result in '" << tag << "', filtering disabled."; } } -bool MCPdgIndexFilter::filter(edm::Event& evt, const edm::EventSetup&) { +bool MCPdgIndexFilter::filter(edm::StreamID, edm::Event& evt, const edm::EventSetup&) const { bool result = pass(evt); LogDebug("FilterResult") << (result?"Pass":"Fail"); if (!taggingMode) return result; - evt.put(std::move(std::unique_ptr(new bool(result))), tag); + evt.emplace(putToken_,result); return true; } -bool MCPdgIndexFilter::pass(const edm::Event& evt) { +bool MCPdgIndexFilter::pass(const edm::Event& evt) const { edm::Handle hepmc; evt.getByToken(token_, hepmc); diff --git a/GeneratorInterface/ReggeGribovPartonMCInterface/src/LzmaFile.cc b/GeneratorInterface/ReggeGribovPartonMCInterface/src/LzmaFile.cc index 825d6e810e998..1e88bf0e92d5b 100644 --- a/GeneratorInterface/ReggeGribovPartonMCInterface/src/LzmaFile.cc +++ b/GeneratorInterface/ReggeGribovPartonMCInterface/src/LzmaFile.cc @@ -18,8 +18,8 @@ const char *kCantWriteMessage = "Can not write output file"; const char *kCantAllocateMessage = "Can not allocate memory"; const char *kDataErrorMessage = "Data error"; -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static void *SzAlloc(void *, size_t size) { return MyAlloc(size); } +static void SzFree(void *, void *address) { MyFree(address); } static ISzAlloc g_Alloc = { SzAlloc, SzFree }; LzmaFile::LzmaFile() diff --git a/GeneratorInterface/RivetInterface/plugins/HTXSRivetProducer.cc b/GeneratorInterface/RivetInterface/plugins/HTXSRivetProducer.cc index ddb4b8c8eb5a2..2f0788da0b622 100644 --- a/GeneratorInterface/RivetInterface/plugins/HTXSRivetProducer.cc +++ b/GeneratorInterface/RivetInterface/plugins/HTXSRivetProducer.cc @@ -44,11 +44,10 @@ class HTXSRivetProducer : public edm::one::EDProducer { produces("HiggsClassification").setBranchAlias("HiggsClassification"); } - ~HTXSRivetProducer() ; private: - void produce( edm::Event&, const edm::EventSetup&) ; + void produce( edm::Event&, const edm::EventSetup&) override; void beginRun(edm::Run const& iRun, edm::EventSetup const& es) override ; void endRun(edm::Run const& iRun, edm::EventSetup const& es) override ; @@ -67,9 +66,6 @@ class HTXSRivetProducer : public edm::one::EDProducer { }; -HTXSRivetProducer::~HTXSRivetProducer(){ -} - void HTXSRivetProducer::produce( edm::Event & iEvent, const edm::EventSetup & ) { //get the hepmc product from the event diff --git a/Geometry/GEMGeometry/interface/GEMGeometry.h b/Geometry/GEMGeometry/interface/GEMGeometry.h index 94488dc2b4519..06210c0792889 100644 --- a/Geometry/GEMGeometry/interface/GEMGeometry.h +++ b/Geometry/GEMGeometry/interface/GEMGeometry.h @@ -119,7 +119,7 @@ class GEMGeometry : public TrackingGeometry { mapIdToDet theMap; std::vector allEtaPartitions; // Are not owned by this class; are owned by their chamber. - std::vector allChambers; // Are not owned by this class; are owned by their chamber. + std::vector allChambers; // Are not owned by this class; are owned by their superchamber. std::vector allSuperChambers; // Are owned by this class. std::vector allRings; // Are owned by this class. std::vector allStations; // Are owned by this class. diff --git a/Geometry/GEMGeometryBuilder/src/GEMGeometryBuilderFromDDD.cc b/Geometry/GEMGeometryBuilder/src/GEMGeometryBuilderFromDDD.cc index 621dcb1a2bf92..9b9e8e5964b99 100644 --- a/Geometry/GEMGeometryBuilder/src/GEMGeometryBuilderFromDDD.cc +++ b/Geometry/GEMGeometryBuilder/src/GEMGeometryBuilderFromDDD.cc @@ -49,6 +49,7 @@ GEMGeometryBuilderFromDDD::build( GEMGeometry& theGeometry, bool doSuper = fv.firstChild(); LogDebug("GEMGeometryBuilderFromDDD") << "doSuperChamber = " << doSuper; // loop over superchambers + std::vector superChambers; while (doSuper){ // getting chamber id from eta partitions @@ -65,7 +66,7 @@ GEMGeometryBuilderFromDDD::build( GEMGeometry& theGeometry, // making superchamber out of the first chamber layer including the gap between chambers if (detIdCh.layer() == 1){// only make superChambers when doing layer 1 GEMSuperChamber *gemSuperChamber = buildSuperChamber(fv, detIdCh); - theGeometry.add(gemSuperChamber); + superChambers.push_back(gemSuperChamber); } GEMChamber *gemChamber = buildChamber(fv, detIdCh); @@ -102,8 +103,7 @@ GEMGeometryBuilderFromDDD::build( GEMGeometry& theGeometry, if (!loopExecuted) delete gemChamber; } - auto& superChambers(theGeometry.superChambers()); - // construct the regions, stations and rings. + // construct the regions, stations and rings. for (int re = -1; re <= 1; re = re+2) { GEMRegion* region = new GEMRegion(re); for (int st=1; st<=GEMDetId::maxStationId; ++st) { @@ -113,8 +113,7 @@ GEMGeometryBuilderFromDDD::build( GEMGeometry& theGeometry, station->setName(name); for (int ri=1; ri<=1; ++ri) { GEMRing* ring = new GEMRing(re, st, ri); - for (auto sch : superChambers){ - GEMSuperChamber* superChamber = const_cast(sch); + for (auto superChamber : superChambers){ const GEMDetId detId(superChamber->id()); if (detId.region() != re || detId.station() != st || detId.ring() != ri) continue; @@ -122,6 +121,7 @@ GEMGeometryBuilderFromDDD::build( GEMGeometry& theGeometry, superChamber->add( theGeometry.chamber(GEMDetId(detId.region(),detId.ring(),detId.station(),2,detId.chamber(),0))); ring->add(superChamber); + theGeometry.add(superChamber); LogDebug("GEMGeometryBuilderFromDDD") << "Adding super chamber " << detId << " to ring: " << "re " << re << " st " << st << " ri " << ri << std::endl; } diff --git a/Mixing/Base/src/SecondaryEventProvider.cc b/Mixing/Base/src/SecondaryEventProvider.cc index ef3dd93442154..d84ece5904d6b 100644 --- a/Mixing/Base/src/SecondaryEventProvider.cc +++ b/Mixing/Base/src/SecondaryEventProvider.cc @@ -3,6 +3,7 @@ #include "FWCore/Framework/src/PreallocationConfiguration.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/StreamID.h" +#include "DataFormats/Provenance/interface/ProductRegistry.h" namespace edm { SecondaryEventProvider::SecondaryEventProvider(std::vector& psets, @@ -24,7 +25,7 @@ namespace edm { shouldBeUsedLabels); } if(!unscheduledLabels.empty()) { - workerManager_.setOnDemandProducts(preg, unscheduledLabels); + preg.setUnscheduledProducts(unscheduledLabels); } } // SecondaryEventProvider::SecondaryEventProvider diff --git a/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSCProducer.cc b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSCProducer.cc index 24e3ad89e33f8..7d2a8b9f064c5 100644 --- a/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSCProducer.cc +++ b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSCProducer.cc @@ -167,7 +167,6 @@ void LowPtGsfElectronSCProducer::produce( edm::Event& event, const edm::EventSet sc.setCorrectedEnergy(energy); sc.setSeed(seed); sc.setClusters(clusters); - for ( const auto clu : clusters ) { sc.addCluster(clu); } PFClusterWidthAlgo pfwidth(barePtrs); sc.setEtaWidth(pfwidth.pflowEtaWidth()); sc.setPhiWidth(pfwidth.pflowPhiWidth()); diff --git a/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSeedProducer.cc b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSeedProducer.cc index 4782baf7f2f32..132a5e64100ff 100644 --- a/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSeedProducer.cc +++ b/RecoEgamma/EgammaElectronProducers/plugins/LowPtGsfElectronSeedProducer.cc @@ -35,7 +35,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// // -LowPtGsfElectronSeedProducer::LowPtGsfElectronSeedProducer( const edm::ParameterSet& conf, +LowPtGsfElectronSeedProducer::LowPtGsfElectronSeedProducer( const edm::ParameterSet& conf, const lowptgsfeleseed::HeavyObjectCache* ) : field_(), fitterPtr_(), @@ -57,7 +57,7 @@ LowPtGsfElectronSeedProducer::LowPtGsfElectronSeedProducer( const edm::Parameter maxPtThreshold_(conf.getParameter("MaxPtThreshold")) { if ( usePfTracks_ ) { - pfTracks_ = consumes(conf.getParameter("pfTracks")); + pfTracks_ = consumes(conf.getParameter("pfTracks")); hcalClusters_ = consumes(conf.getParameter("hcalClusters")); } kfTracks_ = consumes(conf.getParameter("tracks")); @@ -74,18 +74,18 @@ LowPtGsfElectronSeedProducer::~LowPtGsfElectronSeedProducer() {} ////////////////////////////////////////////////////////////////////////////////////////// // -void LowPtGsfElectronSeedProducer::beginLuminosityBlock( edm::LuminosityBlock const&, - edm::EventSetup const& setup ) +void LowPtGsfElectronSeedProducer::beginLuminosityBlock( edm::LuminosityBlock const&, + edm::EventSetup const& setup ) { setup.get().get(field_); } ////////////////////////////////////////////////////////////////////////////////////////// // -void LowPtGsfElectronSeedProducer::produce( edm::Event& event, - const edm::EventSetup& setup ) +void LowPtGsfElectronSeedProducer::produce( edm::Event& event, + const edm::EventSetup& setup ) { - + // Products auto seeds = std::make_unique(); auto ecalPreIds = std::make_unique(); @@ -93,7 +93,7 @@ void LowPtGsfElectronSeedProducer::produce( edm::Event& event, const edm::RefProd preIdsRefProd = event.getRefBeforePut(); - + // HCAL clusters (only used with PF tracks) edm::Handle hcalClusters; @@ -102,14 +102,14 @@ void LowPtGsfElectronSeedProducer::produce( edm::Event& event, event.getByToken(kfTracks_, kfTracks); TrackIndxMap trksToPreIdIndx; - if ( usePfTracks_ ) { + if ( usePfTracks_ ) { edm::Handle pfTracks; event.getByToken(pfTracks_, pfTracks); event.getByToken(hcalClusters_,hcalClusters); //check consistency between kfTracks and pfTracks collection - for(auto& trk : *pfTracks){ + for(auto& trk : *pfTracks){ if(trk.trackRef().isNonnull()){ if(trk.trackRef().id() != kfTracks.id()){ throw cms::Exception("ConfigError") << "kfTracks is not the collection that pfTracks was built from, please fix this"; @@ -127,7 +127,7 @@ void LowPtGsfElectronSeedProducer::produce( edm::Event& event, event, setup); - } else { + } else { loop(kfTracks, // KF tracks hcalClusters, @@ -149,13 +149,13 @@ void LowPtGsfElectronSeedProducer::produce( edm::Event& event, fillPreIdRefValueMap(kfTracks,trksToPreIdIndx,ecalPreIdsHandle,mapFiller); mapFiller.fill(); event.put(std::move(preIdVMOut)); - + } ////////////////////////////////////////////////////////////////////////////////////////// // Return reco::Track from edm::Ref -reco::TrackRef LowPtGsfElectronSeedProducer::getBaseRef( edm::Handle< std::vector > handle, int idx ) const +reco::TrackRef LowPtGsfElectronSeedProducer::getBaseRef( edm::Handle< std::vector > handle, int idx ) const { return reco::TrackRef(handle,idx); } @@ -166,22 +166,22 @@ reco::TrackRef LowPtGsfElectronSeedProducer::getBaseRef( edm::Handle< std::vecto } ////////////////////////////////////////////////////////////////////////////////////////// -// Template function, instantiated for both reco::Tracks and reco::PFRecTracks +// Template function, instantiated for both reco::Tracks and reco::PFRecTracks template void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >& handle, // PF or KF tracks edm::Handle& hcalClusters, reco::ElectronSeedCollection& seeds, - reco::PreIdCollection& ecalPreIds, + reco::PreIdCollection& ecalPreIds, reco::PreIdCollection& hcalPreIds, TrackIndxMap& trksToPreIdIndx, edm::Event& event, const edm::EventSetup& setup ) { - + // Pileup edm::Handle rho; event.getByToken(rho_,rho); - + // Beam spot edm::Handle spot; event.getByToken(beamSpot_,spot); @@ -209,7 +209,7 @@ void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >& ha // Utility to access to shower shape vars noZS::EcalClusterLazyTools ecalTools(event,setup,ebRecHits_,eeRecHits_); - + // Ensure each cluster is only matched once to a track std::vector matchedEcalClusters; std::vector matchedHcalClusters; @@ -218,7 +218,7 @@ void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >& ha seeds.reserve(handle->size()); ecalPreIds.reserve(handle->size()); hcalPreIds.reserve(handle->size()); - + // Iterate through (PF or KF) tracks for ( unsigned int itrk = 0; itrk < handle.product()->size(); itrk++ ) { @@ -227,11 +227,11 @@ void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >& ha if ( !(trackRef->quality(reco::TrackBase::qualityByName("highPurity"))) ) { continue; } if ( !passThrough_ && ( trackRef->pt() < minPtThreshold_ ) ) { continue; } - - // Create ElectronSeed + if(trackRef->algo() == 11) continue; //Skip jetcore tracks because the seeds are hitless + // Create ElectronSeed reco::ElectronSeed seed( *(trackRef->seedRef()) ); seed.setCtfTrack(trackRef); - + // Create PreIds unsigned int nModels = globalCache()->modelNames().size(); reco::PreId ecalPreId(nModels); @@ -249,16 +249,16 @@ void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >& ha matchedHcalClusters, ecalPreId, hcalPreId ); - + // Add variables related to GSF tracks to PreId - lightGsfTracking(ecalPreId,trackRef,seed,setup); + lightGsfTracking(ecalPreId,trackRef,seed,setup); - // Decision based on BDT + // Decision based on BDT bool result = decision(templatedRef,ecalPreId,hcalPreId,*rho,*spot,ecalTools); // If fails BDT, do not store seed if ( !result ) { continue; } - + // Store PreId ecalPreIds.push_back(ecalPreId); hcalPreIds.push_back(hcalPreId); @@ -273,11 +273,11 @@ void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >& ha ////////////////////////////////////////////////////////////////////////////////////////// // Template instantiation for reco::Tracks -template +template void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >&, edm::Handle& hcalClusters, reco::ElectronSeedCollection& seeds, - reco::PreIdCollection& ecalPreIds, + reco::PreIdCollection& ecalPreIds, reco::PreIdCollection& hcalPreIds, TrackIndxMap& trksToPreIdIndx, edm::Event&, @@ -285,11 +285,11 @@ void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::ve ////////////////////////////////////////////////////////////////////////////////////////// // Template instantiation for reco::PFRecTracks -template +template void LowPtGsfElectronSeedProducer::loop( const edm::Handle< std::vector >&, edm::Handle& hcalClusters, reco::ElectronSeedCollection& seeds, - reco::PreIdCollection& ecalPreIds, + reco::PreIdCollection& ecalPreIds, reco::PreIdCollection& hcalPreIds, TrackIndxMap& trksToPreIdIndx, edm::Event&, @@ -302,8 +302,8 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::PFRecTrackR const edm::Handle& hcalClusters, std::vector& matchedEcalClusters, std::vector& matchedHcalClusters, - reco::PreId& ecalPreId, - reco::PreId& hcalPreId ) + reco::PreId& ecalPreId, + reco::PreId& hcalPreId ) { propagateTrackToCalo( pfTrackRef, ecalClusters, matchedEcalClusters, ecalPreId, true ); propagateTrackToCalo( pfTrackRef, hcalClusters, matchedHcalClusters, hcalPreId, false ); @@ -326,7 +326,7 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::PFRecTrackR float dphi = 1.e6; math::XYZPoint showerPos = math::XYZPoint(0.,0.,0.); } info; - + // Find closest "seed cluster" to KF track extrapolated to ECAL (or HCAL) reco::PFTrajectoryPoint point; if ( ecal ) { point = pfTrackRef->extrapolatedPoint(reco::PFTrajectoryPoint::LayerType::ECALShowerMax); } @@ -348,7 +348,7 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::PFRecTrackR info.dr2min = dr2; info.cluRef = cluRef; info.deta = cluRef->positionREP().eta() - point.positionREP().eta(); - info.dphi = + info.dphi = reco::deltaPhi( cluRef->positionREP().phi(), point.positionREP().phi() ) * pfTrackRef->trackRef()->charge(); info.showerPos = point.position(); @@ -358,11 +358,11 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::PFRecTrackR } // Set PreId content if match found - if ( info.dr2min < 1.e5 ) { + if ( info.dr2min < 1.e5 ) { float ep = info.cluRef->correctedEnergy() / std::sqrt( pfTrackRef->trackRef()->innerMomentum().mag2() ); preId.setECALMatchingProperties( info.cluRef, point.position(), // ECAL or HCAL surface - info.showerPos, // + info.showerPos, // info.deta, info.dphi, 0.f, // chieta @@ -382,8 +382,8 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::TrackRef& k const edm::Handle& hcalClusters, // not used std::vector& matchedEcalClusters, std::vector& matchedHcalClusters, // not used - reco::PreId& ecalPreId, - reco::PreId& hcalPreId /* not used */ ) + reco::PreId& ecalPreId, + reco::PreId& hcalPreId /* not used */ ) { // Store info for PreId @@ -410,7 +410,7 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::TrackRef& k particle.setCharge(kfTrackRef->charge()); particle.propagateToEcalEntrance(false); if ( particle.getSuccess() == 0 ) { return; } - + // ECAL entry point for track GlobalPoint ecal_pos(particle.vertex().x(), particle.vertex().y(), @@ -418,16 +418,16 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::TrackRef& k // Preshower limit bool below_ps = pow(ecal_pos.z(),2.) > boundary_*ecal_pos.perp2(); - - // Iterate through ECAL clusters + + // Iterate through ECAL clusters for ( unsigned int iclu = 0; iclu < ecalClusters.product()->size(); iclu++ ) { reco::PFClusterRef cluRef(ecalClusters,iclu); - // Correct ecal_pos for shower depth + // Correct ecal_pos for shower depth double shower_depth = reco::PFCluster::getDepthCorrection(cluRef->correctedEnergy(), below_ps, false); - GlobalPoint showerPos = ecal_pos + + GlobalPoint showerPos = ecal_pos + GlobalVector(particle.momentum().x(), particle.momentum().y(), particle.momentum().z()).unit() * shower_depth; @@ -440,12 +440,12 @@ void LowPtGsfElectronSeedProducer::propagateTrackToCalo( const reco::TrackRef& k info.dr2min = dr2; info.cluRef = cluRef; info.deta = std::abs( cluRef->positionREP().eta() - showerPos.eta() ); - info.dphi = - std::abs( reco::deltaPhi( cluRef->positionREP().phi(), showerPos.phi() )) * + info.dphi = + std::abs( reco::deltaPhi( cluRef->positionREP().phi(), showerPos.phi() )) * kfTrackRef->charge(); info.showerPos = showerPos; } - + } // Populate PreId object @@ -478,7 +478,7 @@ bool LowPtGsfElectronSeedProducer::lightGsfTracking( reco::PreId& preId, for ( unsigned int ihit = 0; ihit < trackRef->recHitsSize(); ++ihit ) { hits.push_back( trackRef->recHit(ihit)->cloneSH() ); } - + GlobalVector gv( trackRef->innerMomentum().x(), trackRef->innerMomentum().y(), trackRef->innerMomentum().z() ); @@ -535,7 +535,7 @@ bool LowPtGsfElectronSeedProducer::decision( const reco::PFRecTrackRef& pfTrackR } ////////////////////////////////////////////////////////////////////////////////////////// -// +// bool LowPtGsfElectronSeedProducer::decision( const reco::TrackRef& kfTrackRef, reco::PreId& ecalPreId, reco::PreId& hcalPreId, @@ -546,7 +546,7 @@ bool LowPtGsfElectronSeedProducer::decision( const reco::TrackRef& kfTrackRef, // No implementation currently return passThrough_; } - + template void LowPtGsfElectronSeedProducer::fillPreIdRefValueMap( edm::Handle tracksHandle, const TrackIndxMap& trksToPreIdIndx, diff --git a/RecoParticleFlow/PFClusterProducer/plugins/RBXAndHPDCleaner.cc b/RecoParticleFlow/PFClusterProducer/plugins/RBXAndHPDCleaner.cc index ecd842c8b546c..6aa336a759ab8 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/RBXAndHPDCleaner.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/RBXAndHPDCleaner.cc @@ -64,11 +64,6 @@ clean(const edm::Handle& input, } // loop on the rbx's we found and clean RBX's with tons of rechits // and lots of energy - double totalEta = 0., totalEtaW = 0., totalPhi = 0., totalPhiW = 0., - totalEnergy = 0.; - double totalEta2 = 1E-9, totalEta2W = 1E-9, totalPhi2 = 1E-9, - totalPhi2W = 1E-9, totalEnergy2 = 1E-9; - unsigned nSeeds = 0, nSeeds0 = 0; std::unordered_map > theHPDs; std::unordered_multimap theEnergies; for( const auto& itrbx : _rbxs ) { @@ -77,9 +72,7 @@ clean(const edm::Handle& input, const std::vector& rechits = itrbx.second; theHPDs.clear(); theEnergies.clear(); - totalEta = totalEtaW = totalPhi = totalPhiW = totalEnergy = 0.; - totalEta2 = totalEta2W = totalPhi2 = totalPhi2W = totalEnergy2 = 1e-9; - nSeeds = nSeeds0 = rechits.size(); + int nSeeds0 = rechits.size(); for( unsigned jh = 0; jh < rechits.size(); ++jh ) { const reco::PFRecHit& rechit = (*input)[jh]; // check if rechit is a seed @@ -89,7 +82,7 @@ clean(const edm::Handle& input, for( auto k : neighbours4 ) { auto const & neighbour = (*input)[k]; if( neighbour.energy() > rechit.energy() ) { - --nSeeds; --nSeeds0; + --nSeeds0; isASeed = false; break; } else { @@ -111,37 +104,8 @@ clean(const edm::Handle& input, break; } const double rhenergy = rechit.energy(); - const double rhphi = rechit.position().phi(); - const double rhphi2 = rhphi*rhphi; - const double rheta = rechit.position().eta(); - const double rheta2 = rheta*rheta; theEnergies.emplace(rhenergy,rechits[jh]); - totalEnergy += rhenergy; - totalPhi += std::abs(rhphi); - totalPhiW += std::abs(rhphi)*rhenergy; - totalEta += rheta; - totalEtaW += rheta*rhenergy; - totalEnergy2 += rhenergy*rhenergy; - totalPhi2 += rhphi2; - totalPhi2W += rhphi2*rhenergy; - totalEta2 += rheta2; - totalEta2W += rheta2*rhenergy; } - totalPhi /= rechits.size(); - totalEta /= rechits.size(); - totalPhiW /= totalEnergy; - totalEtaW /= totalEnergy; - totalPhi2 /= rechits.size(); - totalEta2 /= rechits.size(); - totalPhi2W /= totalEnergy; - totalEta2W /= totalEnergy; - totalPhi2 = std::sqrt(totalPhi2 - totalPhi*totalPhi); - totalEta2 = std::sqrt(totalEta2 - totalEta*totalEta); - totalPhi2W = std::sqrt(totalPhi2W - totalPhiW*totalPhi2); - totalEta2W = std::sqrt(totalEta2W - totalEtaW*totalEtaW); - totalEnergy /= rechits.size(); - totalEnergy2 /= rechits.size(); - totalEnergy2 = std::sqrt(totalEnergy2 - totalEnergy*totalEnergy); if( nSeeds0 > 6 ) { unsigned nHPD15 = 0; for( const auto& itHPD : theHPDs ) { @@ -178,18 +142,10 @@ clean(const edm::Handle& input, for( const auto& ithpd : _hpds ) { const std::vector& rechits = ithpd.second; theEnergies.clear(); - totalEnergy = 0; - totalEnergy2 = 1e-9; for( const unsigned rhidx : rechits ) { const reco::PFRecHit & rechit = input->at(rhidx); - const double e = rechit.energy(); - totalEnergy += e; - totalEnergy2 += e*e; theEnergies.emplace(rechit.energy(),rhidx); } - totalEnergy /= rechits.size(); - totalEnergy2 /= rechits.size(); - totalEnergy2 = std::sqrt(totalEnergy2 - totalEnergy*totalEnergy); const int thehpd = ithpd.first; switch( std::abs(thehpd) ) { diff --git a/RecoParticleFlow/PFTracking/plugins/GoodSeedProducer.cc b/RecoParticleFlow/PFTracking/plugins/GoodSeedProducer.cc index 5701aa58c8e5f..76aa1c919ef20 100644 --- a/RecoParticleFlow/PFTracking/plugins/GoodSeedProducer.cc +++ b/RecoParticleFlow/PFTracking/plugins/GoodSeedProducer.cc @@ -206,7 +206,7 @@ GoodSeedProducer::produce(Event& iEvent, const EventSetup& iSetup) for(unsigned int i=0;iinnerLayer(pairLayers).detLayer(); + const DetLayer * secondLayer = thePairGenerator->outerLayer(pairLayers).detLayer(); + if (!firstLayer || !secondLayer) return; + int size = thirdLayers.size(); const RecHitsSortedInPhi **thirdHitMap = new const RecHitsSortedInPhi*[size]; @@ -66,10 +70,6 @@ void PixelTripletNoTipGenerator::hitTriplets( thirdHitMap[il] = &(*theLayerCache)(thirdLayers[il], region, es); } - const DetLayer * firstLayer = thePairGenerator->innerLayer(pairLayers).detLayer(); - const DetLayer * secondLayer = thePairGenerator->outerLayer(pairLayers).detLayer(); - if (!firstLayer || !secondLayer) return; - MultipleScatteringParametrisation sigma1RPhi( firstLayer, es); MultipleScatteringParametrisation sigma2RPhi( secondLayer, es); diff --git a/RecoTracker/CkfPattern/BuildFile.xml b/RecoTracker/CkfPattern/BuildFile.xml index 62ab868ad22bb..7fd63c3d8a9e4 100644 --- a/RecoTracker/CkfPattern/BuildFile.xml +++ b/RecoTracker/CkfPattern/BuildFile.xml @@ -19,5 +19,6 @@ + diff --git a/RecoTracker/CkfPattern/src/CkfTrackCandidateMakerBase.cc b/RecoTracker/CkfPattern/src/CkfTrackCandidateMakerBase.cc index 3b64772bd1c33..b88c415061171 100644 --- a/RecoTracker/CkfPattern/src/CkfTrackCandidateMakerBase.cc +++ b/RecoTracker/CkfPattern/src/CkfTrackCandidateMakerBase.cc @@ -11,6 +11,8 @@ #include "DataFormats/TrackReco/interface/SeedStopInfo.h" #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +// #include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" + #include "TrackingTools/PatternTools/interface/Trajectory.h" #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h" @@ -27,6 +29,10 @@ #include "RecoTracker/CkfPattern/interface/CachingSeedCleanerBySharedInput.h" #include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h" +// #include "RecoTracker/TransientTrackingRecHit/interface/TRecHit2DPosConstraint.h" +// #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h" +// #include "DataFormats/GeometrySurface/interface/SimpleCylinderBounds.h" +// #include "DataFormats/GeometrySurface/interface/Cylinder.h" #include "RecoTracker/Record/interface/NavigationSchoolRecord.h" #include "TrackingTools/DetLayers/interface/NavigationSchool.h" @@ -154,6 +160,10 @@ namespace cms{ // set the correct navigation // NavigationSetter setter( *theNavigationSchool); + + //geometry, for jetCore iteration + // edm::ESHandle geometry_; + // es.get().get(geometry_); // propagator edm::ESHandle thePropagator; @@ -317,7 +327,7 @@ namespace cms{ // Optionally continue building trajectory back through // seed and if possible further inwards. - + // std::cout << theTrajectoryCleanerName <<", DEBUG doSeedingRegionRebuilding=" << doSeedingRegionRebuilding << std::endl; if (doSeedingRegionRebuilding) { theTrajectoryBuilder->rebuildTrajectories(startTraj,(*collseed)[j],theTmpTrajectories); @@ -491,17 +501,57 @@ namespace cms{ // Get inner state const bool doBackFit = (!doSeedingRegionRebuilding) & (!reverseTrajectories); + // if(theTrajectoryCleanerName=="jetCoreTrajectoryCleanerBySharedHits" && doBackFit){ //jetCore seed appended to the trajectory + + // //add fake hit on lay 2 + // PTrajectoryStateOnDet seedPTSODL2 = trialTrajectory.seed().startingState(); //this is the state of the seed (produced on L2) + // LocalPoint seedPosL2 = seedPTSODL2.parameters().position(); + // LocalError seedErrL2 = LocalError(seedPTSODL2.error(9),0.0,seedPTSODL2.error(14)) ; + // const GeomDet* seedDetL2 = geometry_->idToDet(trialTrajectory.seed().startingState().detId()); + // // const Surface *seedSurfaceL2 = &geometry_->idToDet(seed.startingState().detId())->specificSurface(); + // const Surface *seedSurfaceL2 = &seedDetL2->specificSurface(); + // TrackingRecHit::RecHitPointer seedHitL2 = TRecHit2DPosConstraint::build(seedPosL2, seedErrL2, seedSurfaceL2); + // assert(!seedHitL2->canImproveWithTrack()); + // TrajectoryStateOnSurface seedTSOSL2 = trajectoryStateTransform::transientState( trialTrajectory.seed().startingState(), seedSurfaceL2, theMagField.product()); + // auto seedTrajectoryMeasurementL2 = TrajectoryMeasurement(seedTSOSL2,seedHitL2); + // std::cout << "size before (l3):" << trialTrajectory.measurements().size(); + // trialTrajectory.measurements().insert(trialTrajectory.measurements().begin(), seedTrajectoryMeasurementL2); + // std::cout << ", size after (l2):" << trialTrajectory.measurements().size() << std::endl; + + // //add the fake hit on lay1 + // PropagationDirection backFitDirection = trialTrajectory.direction() == alongMomentum ? oppositeToMomentum: alongMomentum; + // SteppingHelixPropagator seedProp = SteppingHelixPropagator(theMagField.product(),backFitDirection); + // auto cylBoundL1 = new SimpleCylinderBounds(2.85f,2.9f,-100000,100000);//cilinder bounds centered at IP, R=lay1 + // Surface::RotationType rot; //cylinder radius + // const Cylinder* cylL1 = new Cylinder(Cylinder::computeRadius(*cylBoundL1), Surface::PositionType(0, 0, 0), rot, cylBoundL1); //cylinder + // std::pair seedTSOSL1_wlen = seedProp.propagateWithPath(*seedTSOSL2.freeState(),*cylL1); + // TrajectoryStateOnSurface seedTSOSL1 = seedTSOSL1_wlen.first; //the state on L1 + // LocalPoint seedPosL1 = seedTSOSL1.localPosition(); + // LocalError seedErrL1 = LocalError(seedTSOSL1.localError().matrix()(3,3),0.0,seedTSOSL1.localError().matrix()(4,4)); + // const Surface * seedSurfaceL1 = &seedTSOSL1.surface(); + // TrackingRecHit::RecHitPointer seedHitL1 = TRecHit2DPosConstraint::build(seedPosL1, seedErrL1, seedSurfaceL1); //the fake hit on L1 + // assert(!seedHitL1->canImproveWithTrack()); + // auto seedTrajectoryMeasurementL1 = TrajectoryMeasurement(seedTSOSL1,seedHitL1); + // trialTrajectory.measurements().insert(trialTrajectory.measurements().begin(), seedTrajectoryMeasurementL1); + // std::cout << ", size after (l1):" << trialTrajectory.measurements().size() << "prop len=" <innerState(trialTrajectory, doBackFit); + if (theTrajectoryCleanerName=="jetCoreTrajectoryCleanerBySharedHits") std::cout << "DEBUG deepCore, doBackFit=" << doBackFit<< std::endl; // Check if that was successful failed = (!initState.first.isValid()) || initState.second == nullptr || edm::isNotFinite(initState.first.globalPosition().x()); + if (theTrajectoryCleanerName=="jetCoreTrajectoryCleanerBySharedHits") std::cout << "DEBUG deepCore,smoothing" << failed<< ", nHits=" << trialTrajectory.foundHits()<< std::endl; } while(failed && trialTrajectory.foundHits() > 3); if(failed) { + if (theTrajectoryCleanerName=="jetCoreTrajectoryCleanerBySharedHits") std::cout << "DEBUG deepCore,failed smoothing" << std::endl; const auto seedIndex = it->seedRef().key(); (*outputSeedStopInfos)[seedIndex].setStopReason(SeedStopReason::SMOOTHING_FAILED); continue; } + if (theTrajectoryCleanerName=="jetCoreTrajectoryCleanerBySharedHits") std::cout <<"DEBUG deepCore,success smoothing" << std::endl; diff --git a/RecoTracker/CkfPattern/src/TransientInitialStateEstimator.cc b/RecoTracker/CkfPattern/src/TransientInitialStateEstimator.cc index ac5a0aa98e8e1..b55beecf4ce63 100644 --- a/RecoTracker/CkfPattern/src/TransientInitialStateEstimator.cc +++ b/RecoTracker/CkfPattern/src/TransientInitialStateEstimator.cc @@ -76,6 +76,8 @@ TransientInitialStateEstimator::innerState( const Trajectory& traj, bool doBackF TSOS startingState = measvec[actualLast].updatedState(); startingState.rescaleError(100.); + std::cout << "DEBUG DEEPCORE: distance first hit" << measvec[0].recHit()->globalPosition().perp() << std::endl; + // avoid cloning... KFUpdator const aKFUpdator; Chi2MeasurementEstimator const aChi2MeasurementEstimator( 100., 3); @@ -124,7 +126,9 @@ TransientInitialStateEstimator::innerState( const Trajectory& traj, bool doBackF <<"\n it's field pointer is: "<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>:\n" << "initial parameters:" << ", inv.Pt=" << firstState.freeState()->parameters().signedInverseTransverseMomentum() << ", trans.Curv=" <transverseCurvature()<< ", p=" << firstState.freeState()->momentum().mag() << ", pt=" << firstState.freeState()->momentum().perp() <<", phi=" <momentum().phi() << ", eta="<momentum().eta() << std::endl; + std::cout << firstState << std::endl; return std::pair( std::move(firstState), firstMeas.recHit()->det()); } diff --git a/RecoTracker/IterativeTracking/python/JetCoreRegionalStep_cff.py b/RecoTracker/IterativeTracking/python/JetCoreRegionalStep_cff.py index 18de06b618012..2899bd6ae8171 100644 --- a/RecoTracker/IterativeTracking/python/JetCoreRegionalStep_cff.py +++ b/RecoTracker/IterativeTracking/python/JetCoreRegionalStep_cff.py @@ -17,9 +17,9 @@ # SEEDING LAYERS jetCoreRegionalStepSeedLayers = cms.EDProducer("SeedingLayersEDProducer", - layerList = cms.vstring('BPix1+BPix2', 'BPix1+BPix3', 'BPix2+BPix3', - 'BPix1+FPix1_pos', 'BPix1+FPix1_neg', - 'BPix2+FPix1_pos', 'BPix2+FPix1_neg', + layerList = cms.vstring('BPix1+BPix2', 'BPix1+BPix3', 'BPix2+BPix3', + 'BPix1+FPix1_pos', 'BPix1+FPix1_neg', + 'BPix2+FPix1_pos', 'BPix2+FPix1_neg', 'FPix1_pos+FPix2_pos', 'FPix1_neg+FPix2_neg', #'BPix2+TIB1','BPix2+TIB2', 'BPix3+TIB1','BPix3+TIB2'), @@ -87,9 +87,18 @@ # QUALITY CUTS DURING TRACK BUILDING import TrackingTools.TrajectoryFiltering.TrajectoryFilter_cff jetCoreRegionalStepTrajectoryFilter = TrackingTools.TrajectoryFiltering.TrajectoryFilter_cff.CkfBaseTrajectoryFilter_block.clone( - minimumNumberOfHits = 4, - seedPairPenalty = 0, - minPt = 0.1 + minPt = 0.1, + maxCCCLostHits = cms.int32(9999), + maxConsecLostHits = cms.int32(2), + maxLostHits = cms.int32(999), + maxLostHitsFraction = cms.double(1.1), + maxNumberOfHits = cms.int32(100), + minimumNumberOfHits = cms.int32(2), + pixelSeedExtension = cms.bool(False), + seedExtension = cms.int32(0), + seedPairPenalty = cms.int32(0), + strictSeedExtension = cms.bool(False) + ) from Configuration.Eras.Modifier_pp_on_XeXe_2017_cff import pp_on_XeXe_2017 @@ -111,20 +120,72 @@ jetCoreRegionalStepTrajectoryBuilder = RecoTracker.CkfPattern.GroupedCkfTrajectoryBuilder_cfi.GroupedCkfTrajectoryBuilder.clone( MeasurementTrackerName = '', trajectoryFilter = cms.PSet(refToPSet_ = cms.string('jetCoreRegionalStepTrajectoryFilter')), - #clustersToSkip = cms.InputTag('jetCoreRegionalStepClusters'), maxCand = 50, estimator = cms.string('jetCoreRegionalStepChi2Est'), maxDPhiForLooperReconstruction = cms.double(2.0), - maxPtForLooperReconstruction = cms.double(0.7) + maxPtForLooperReconstruction = cms.double(0), + keepOriginalIfRebuildFails = True, + lockHits = False, + requireSeedHitsInRebuild = False, + ) + +#customized cleaner +trajectoryCleanerBySharedHits_JetCore = cms.ESProducer("TrajectoryCleanerESProducer", + ComponentName = cms.string('jetCoreTrajectoryCleanerBySharedHits'), + ComponentType = cms.string('TrajectoryCleanerBySharedHits'), + MissingHitPenalty = cms.double(20.0), + ValidHitBonus = cms.double(5.0), + allowSharedFirstHit = cms.bool(True), + fractionShared = cms.double(0.45) +) + +CkfBaseTrajectoryFilter_blockLoose = cms.PSet( + ComponentType = cms.string('CkfBaseTrajectoryFilter'), + chargeSignificance = cms.double(-1.0), + constantValueForLostHitsFractionFilter = cms.double(2.0), + extraNumberOfHitsBeforeTheFirstLoop = cms.int32(4), + maxCCCLostHits = cms.int32(9999), + maxConsecLostHits = cms.int32(2), + maxLostHits = cms.int32(999), + maxLostHitsFraction = cms.double(1.1), + maxNumberOfHits = cms.int32(100), + minGoodStripCharge = cms.PSet( + refToPSet_ = cms.string('SiStripClusterChargeCutNone') + ), + minHitsMinPt = cms.int32(3), + minNumberOfHitsForLoopers = cms.int32(13), + minNumberOfHitsPerLoop = cms.int32(4), + minPt = cms.double(0.9), + minimumNumberOfHits = cms.int32(2), + nSigmaMinPt = cms.double(5.0), + pixelSeedExtension = cms.bool(False), + seedExtension = cms.int32(0), + seedPairPenalty = cms.int32(0), + strictSeedExtension = cms.bool(False) +) + + + +import RecoTracker.TkSeedGenerator.jetCoreDirectSeedGenerator_cfi +import RecoTracker.TkSeedGenerator.jetCorePerfectSeedGenerator_cfi +jetCoreRegionalStepSeeds = RecoTracker.TkSeedGenerator.jetCoreDirectSeedGenerator_cfi.jetCoreDirectSeedGenerator.clone( +# jetCoreSeeds = RecoTracker.TkSeedGenerator.jetCoreDirectSeedGenerator_cfi.jetCoreDirectSeedGenerator.clone( +# jetCoreSeeds = RecoTracker.TkSeedGenerator.jetCorePerfectSeedGenerator_cfi.JetCorePerfectSeedGenerator.clone( +vertices="firstStepPrimaryVertices" +) + # MAKING OF TRACK CANDIDATES import RecoTracker.CkfPattern.CkfTrackCandidates_cfi jetCoreRegionalStepTrackCandidates = RecoTracker.CkfPattern.CkfTrackCandidates_cfi.ckfTrackCandidates.clone( src = cms.InputTag('jetCoreRegionalStepSeeds'), + # src = cms.InputTag('jetCoreSeeds'), maxSeedsBeforeCleaning = cms.uint32(10000), TrajectoryBuilderPSet = cms.PSet( refToPSet_ = cms.string('jetCoreRegionalStepTrajectoryBuilder')), + TrajectoryCleaner = 'jetCoreTrajectoryCleanerBySharedHits', NavigationSchool = cms.string('SimpleNavigationSchool'), + doSeedingRegionRebuilding = False, ### these two parameters are relevant only for the CachingSeedCleanerBySharedInput #numHitsForSeedCleaner = cms.int32(50), #onlyPixelHitsForSeedCleaner = cms.bool(True), @@ -198,19 +259,22 @@ )) (trackingPhase1 & fastSim).toModify(jetCoreRegionalStep,vertices = "firstStepPrimaryVerticesBeforeMixing") + + # Final sequence -JetCoreRegionalStepTask = cms.Task(jetsForCoreTracking, +JetCoreRegionalStepTask = cms.Task(jetsForCoreTracking, firstStepGoodPrimaryVertices, #jetCoreRegionalStepClusters, jetCoreRegionalStepSeedLayers, jetCoreRegionalStepTrackingRegions, jetCoreRegionalStepHitDoublets, jetCoreRegionalStepSeeds, + # jetCoreSeeds, jetCoreRegionalStepTrackCandidates, jetCoreRegionalStepTracks, # jetCoreRegionalStepClassifier1,jetCoreRegionalStepClassifier2, jetCoreRegionalStep) JetCoreRegionalStep = cms.Sequence(JetCoreRegionalStepTask) -fastSim.toReplaceWith(JetCoreRegionalStepTask, +fastSim.toReplaceWith(JetCoreRegionalStepTask, cms.Task(jetCoreRegionalStepTracks, jetCoreRegionalStep)) diff --git a/RecoTracker/TkSeedGenerator/data/JetCoreDirectSeedGenerator_TrainedModel.pb b/RecoTracker/TkSeedGenerator/data/JetCoreDirectSeedGenerator_TrainedModel.pb new file mode 100644 index 0000000000000..1a07d75c44ced Binary files /dev/null and b/RecoTracker/TkSeedGenerator/data/JetCoreDirectSeedGenerator_TrainedModel.pb differ diff --git a/RecoTracker/TkSeedGenerator/plugins/BuildFile.xml b/RecoTracker/TkSeedGenerator/plugins/BuildFile.xml index 03a79068c2223..6222a3735fbf6 100644 --- a/RecoTracker/TkSeedGenerator/plugins/BuildFile.xml +++ b/RecoTracker/TkSeedGenerator/plugins/BuildFile.xml @@ -3,6 +3,10 @@ + + + + diff --git a/RecoTracker/TkSeedGenerator/plugins/JetCoreDirectSeedGenerator.cc b/RecoTracker/TkSeedGenerator/plugins/JetCoreDirectSeedGenerator.cc new file mode 100644 index 0000000000000..13b82c1846383 --- /dev/null +++ b/RecoTracker/TkSeedGenerator/plugins/JetCoreDirectSeedGenerator.cc @@ -0,0 +1,792 @@ +// -*- C++ -*- +// +// Package: trackJet/JetCoreDirectSeedGenerator +// Class: JetCoreDirectSeedGenerator +// +/**\class JetCoreDirectSeedGenerator JetCoreDirectSeedGenerator.cc trackJet/JetCoreDirectSeedGenerator/plugins/JetCoreDirectSeedGenerator.cc + + Description: [one line class summary] + + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Valerio Bertacchi +// Created: Mon, 18 Dec 2017 16:35:04 GMT +// +// + + +// system include files + +#define jetDimX 30 +#define jetDimY 30 +#define Nlayer 4 +#define Nover 3 +#define Npar 5 + +#include "JetCoreDirectSeedGenerator.h" + +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" +#include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h" +#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" +#include "Geometry/Records/interface/TrackerTopologyRcd.h" + +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/DetSetVector.h" +#include "DataFormats/Common/interface/DetSet.h" +#include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h" +#include "DataFormats/VertexReco/interface/Vertex.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/JetReco/interface/Jet.h" +#include "DataFormats/SiPixelDigi/interface/PixelDigi.h" +#include "DataFormats/GeometryVector/interface/VectorUtil.h" +#include "DataFormats/SiPixelDetId/interface/PXBDetId.h" +#include "DataFormats/Math/interface/Point3D.h" +#include "DataFormats/Math/interface/Vector3D.h" +#include "DataFormats/Candidate/interface/Candidate.h" + + +#include "RecoLocalTracker/ClusterParameterEstimator/interface/PixelClusterParameterEstimator.h" +#include "RecoLocalTracker/Records/interface/TkPixelCPERecord.h" + +#include "SimDataFormats/TrackerDigiSimLink/interface/PixelDigiSimLink.h" + +#include "TrackingTools/GeomPropagators/interface/StraightLinePlaneCrossing.h" +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" + +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" + + + +#include +#include +#include "boost/multi_array.hpp" + +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" + +// #include "SimG4Core/Application/interface/G4SimTrack.h" +// #include "SimDataFormats/Track/interface/SimTrack.h" + +#include "SimDataFormats/Vertex/interface/SimVertex.h" + + +#include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h" + +#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" + + + +#include "TTree.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" + + +// +// class declaration +// + +// If the analyzer does not use TFileService, please remove +// the template argument to the base class so the class inherits +// from edm::one::EDAnalyzer<> and also remove the line from +// constructor "usesResource("TFileService");" +// This will improve performance in multithreaded jobs. + + + +JetCoreDirectSeedGenerator::JetCoreDirectSeedGenerator(const edm::ParameterSet& iConfig) : + + vertices_(consumes(iConfig.getParameter("vertices"))), + pixelClusters_(consumes >(iConfig.getParameter("pixelClusters"))), + cores_(consumes >(iConfig.getParameter("cores"))), + ptMin_(iConfig.getParameter("ptMin")), + deltaR_(iConfig.getParameter("deltaR")), + chargeFracMin_(iConfig.getParameter("chargeFractionMin")), + centralMIPCharge_(iConfig.getParameter("centralMIPCharge")), + pixelCPE_(iConfig.getParameter("pixelCPE")), + + weightfilename_(iConfig.getParameter("weightFile").fullPath()), + inputTensorName_(iConfig.getParameter>("inputTensorName")), + outputTensorName_(iConfig.getParameter>("outputTensorName")), + nThreads(iConfig.getParameter("nThreads")), + singleThreadPool(iConfig.getParameter("singleThreadPool")), + probThr(iConfig.getParameter("probThr")) + +{ + produces(); + produces(); + + + + // edm::Service fileService; + // + // JetCoreDirectSeedGeneratorTree= fileService->make("JetCoreDirectSeedGeneratorTree","JetCoreDirectSeedGeneratorTree"); + // JetCoreDirectSeedGeneratorTree->Branch("cluster_measured",clusterMeas,"cluster_measured[30][30][4]/D"); + // JetCoreDirectSeedGeneratorTree->Branch("jet_eta",&jet_eta); + // JetCoreDirectSeedGeneratorTree->Branch("jet_pt",&jet_pt); + + + // for(int i=0; i(); + auto resultTracks = std::make_unique(); + + //-------------------TensorFlow setup - session (1/2)----------------------// + + tensorflow::setLogging("3"); + graph_=tensorflow::loadGraphDef(weightfilename_); + // output_names_=iConfig.getParameter>("outputNames"); + // for(const auto & s : iConfig.getParameter>("outputFormulas")) { output_formulas_.push_back(StringObjectFunction>(s));} + tensorflow::SessionOptions sessionOptions; + tensorflow::setThreading(sessionOptions, nThreads, singleThreadPool); + session_ = tensorflow::createSession(graph_, sessionOptions); + tensorflow::TensorShape input_size_eta({1,1}) ; + tensorflow::TensorShape input_size_pt({1,1}) ; + tensorflow::TensorShape input_size_cluster({1,jetDimX,jetDimY,Nlayer}); + + // std::cout << "input_size_cluster=" << input_size_cluster.num_elements() << "," << "," << input_size_cluster.dims() << "," << input_size_cluster.dim_size(0) << "," << input_size_cluster.dim_size(1) <<"," << input_size_cluster.dim_size(2) <<"," << input_size_cluster.dim_size(3) << std::endl; + + // input_size_cluster.set_dim(0,1); + // input_size_cluster.set_dim(1,jetDimX); + // input_size_cluster.set_dim(2,jetDimY); + // input_size_cluster.set_dim(3,Nlayer); + ; + + // tensorflow::TensorShape input_size_cluster {1,1,1,1} ; + //-----------------end of TF setup (1/2)----------------------// + + evt_counter++; +// std::cout << "event number (iterative)=" << evt_counter<< ", event number (id)="<< iEvent.id().event() << std::endl; + + + using namespace edm; + using namespace reco; + + + iSetup.get().get( magfield_ ); + iSetup.get().get(geometry_); + iSetup.get().get( "AnalyticalPropagator", propagator_ ); + + iEvent.getByToken(pixelClusters_, inputPixelClusters); + allSiPixelClusters.clear(); siPixelDetsWithClusters.clear(); + allSiPixelClusters.reserve(inputPixelClusters->dataSize()); // this is important, otherwise push_back invalidates the iterators + + // edm::Handle > simtracks; + // iEvent.getByToken(simtracksToken, simtracks); + // edm::Handle > simvertex; + // iEvent.getByToken(simvertexToken, simvertex); + + Handle > vertices; + iEvent.getByToken(vertices_, vertices); + + Handle > cores; + iEvent.getByToken(cores_, cores); + + // iEvent.getByToken(pixeldigisimlinkToken, pixeldigisimlink); + + //--------------------------debuging lines ---------------------// + edm::ESHandle pe; + const PixelClusterParameterEstimator* pp; + iSetup.get().get(pixelCPE_, pe); + pp = pe.product(); + //--------------------------end ---------------------// + + edm::ESHandle tTopoHandle; + iSetup.get().get(tTopoHandle); + const TrackerTopology* const tTopo = tTopoHandle.product(); + + auto output = std::make_unique>(); + +print = false; +int jet_number = 0; + for (unsigned int ji = 0; ji < cores->size(); ji++) { //loop jet + jet_number++; + + if ((*cores)[ji].pt() > ptMin_) { +// std::cout << "|____________________NEW JET_______________________________| jet number=" << jet_number << " " << (*cores)[ji].pt() << " " << (*cores)[ji].eta() << " " << (*cores)[ji].phi() << std::endl; + + std::set ids; + const reco::Candidate& jet = (*cores)[ji]; + const reco::Vertex& jetVertex = (*vertices)[0]; + + std::vector splitClustDirSet = splittedClusterDirections(jet, tTopo, pp, jetVertex, 1); + //std::vector splitClustDirSet = splittedClusterDirections(jet, tTopo, pp, jetVertex); + bool l2off=(splitClustDirSet.size()==0); + if(splitClustDirSet.size()==0) {//if layer 1 is broken find direcitons on layer 2 + splitClustDirSet = splittedClusterDirections(jet, tTopo, pp, jetVertex, 2); + // std::cout << "split on lay2, in numero=" << splitClustDirSet.size() << "+jetDir" << std::endl; + } + splitClustDirSet.push_back(GlobalVector(jet.px(),jet.py(),jet.pz())); + // std::cout << "splitted cluster number=" << splitClustDirSet.size() << std::endl;; + for(int cc=0; cc<(int)splitClustDirSet.size(); cc++){ + + //-------------------TensorFlow setup - tensor (2/2)----------------------// + tensorflow::NamedTensorList input_tensors; + input_tensors.resize(3); + input_tensors[0] = tensorflow::NamedTensor(inputTensorName_[0], tensorflow::Tensor(tensorflow::DT_FLOAT, input_size_eta)); + input_tensors[1] = tensorflow::NamedTensor(inputTensorName_[1], tensorflow::Tensor(tensorflow::DT_FLOAT, input_size_pt)); + input_tensors[2] = tensorflow::NamedTensor(inputTensorName_[2], tensorflow::Tensor(tensorflow::DT_FLOAT, {input_size_cluster})); + + //put all the input tensor to 0 + input_tensors[0].second.matrix()(0,0) =0.0; + input_tensors[1].second.matrix()(0,0) = 0.0; + for(int x=0; x()(0,x,y,l) = 0.0; + } + } + } + // auto input_matrix_eta = input_tensors[0].second.tensor(); + // auto input_matrix_pt = input_tensors[1].second.tensor(); + // auto input_matrix_cluster = input_tensors[2].second.tensor(); + + // + // std::vector inputs; + // std::vector input_names; + // + // ouput_names.push_back(inputTensorName_[0]); + // ouput_names.push_back(inputTensorName_[1]); + // ouput_names.push_back(inputTensorName_[2]); + + + + + //-----------------end of TF setup (2/2)----------------------// + + GlobalVector bigClustDir = splitClustDirSet.at(cc); + + LocalPoint jetInter(0,0,0); + + jet_eta = jet.eta(); + jet_pt = jet.pt(); + // input_tensors(0).at(0) = jet.eta(); + // input_tensors[1](0) = jet.pt(); + // input_matrix_eta(0,0) = jet.eta(); + // input_matrix_pt(0,0) = jet.pt(); + input_tensors[0].second.matrix()(0,0) = jet.eta(); + input_tensors[1].second.matrix()(0,0) = jet.pt(); + + auto jetVert = jetVertex; //trackInfo filling + + + + edmNew::DetSetVector::const_iterator detIt = inputPixelClusters->begin(); + + const GeomDet* globDet = DetectorSelector(2, jet, bigClustDir, jetVertex, tTopo); //select detector mostly hitten by the jet + + if(globDet == 0) continue; + + const GeomDet* goodDet1 = DetectorSelector(1, jet, bigClustDir, jetVertex, tTopo); + const GeomDet* goodDet3 = DetectorSelector(3, jet, bigClustDir, jetVertex, tTopo); + const GeomDet* goodDet4 = DetectorSelector(4, jet, bigClustDir, jetVertex, tTopo); + + + + for (; detIt != inputPixelClusters->end(); detIt++) { //loop deset + const edmNew::DetSet& detset = *detIt; + const GeomDet* det = geometry_->idToDet(detset.id()); //lui sa il layer con cast a PXBDetId (vedi dentro il layer function) + + for (auto cluster = detset.begin(); cluster != detset.end(); cluster++) { //loop cluster + + const SiPixelCluster& aCluster = *cluster; + det_id_type aClusterID= detset.id(); + if(DetId(aClusterID).subdetId()!=1) continue; + + int lay = tTopo->layer(det->geographicalId()); + + std::pair> interPair = findIntersection(bigClustDir,(reco::Candidate::Point)jetVertex.position(), det); + if(interPair.first==false) continue; + Basic3DVector inter = interPair.second; + auto localInter = det->specificSurface().toLocal((GlobalPoint)inter); + + GlobalPoint pointVertex(jetVertex.position().x(), jetVertex.position().y(), jetVertex.position().z()); + + + // GlobalPoint cPos = det->surface().toGlobal(pp->localParametersV(aCluster,(*geometry_->idToDetUnit(detIt->id())))[0].first); + LocalPoint cPos_local = pp->localParametersV(aCluster,(*geometry_->idToDetUnit(detIt->id())))[0].first; + + if(std::abs(cPos_local.x()-localInter.x())/pitchX<=jetDimX/2 && std::abs(cPos_local.y()-localInter.y())/pitchY<=jetDimY/2){ // per ora preso baricentro, da migliorare + + if(det==goodDet1 || det==goodDet3 || det==goodDet4 || det==globDet) { + // fillPixelMatrix(aCluster,lay,localInter, det, input_matrix_cluster); + fillPixelMatrix(aCluster,lay,localInter, det, input_tensors); + + } + } //cluster in ROI + } //cluster + } //detset + + // JetCoreDirectSeedGeneratorTree->Fill(); + + //HERE SOMEHOW THE NN PRODUCE THE SEED FROM THE FILLED INPUT +// std::cout << "Filling complete" << std::endl; + std::pair seedParamNN = JetCoreDirectSeedGenerator::SeedEvaluation(input_tensors); + + for(int i=0; i(0.75-o*0.1-(l2off?0.25:0))){//0.99=probThr (doesn't work the variable, SOLVE THIS ISSUE!!) + if(seedParamNN.second[i][j][o]>(0.85-o*0.1-(l2off?0.35:0))){//0.99=probThr (doesn't work the variable, SOLVE THIS ISSUE!!) + + // std::cout << "prob success=" << seedParamNN.second[i][j][o]<< ", for (x,y)=" << i <<"," <geographicalId(); + LocalTrajectoryParameters localParam(localSeedPoint, localSeedDir, TrackCharge(1)); + result->push_back(TrajectorySeed( PTrajectoryStateOnDet (localParam, pt, em, detId, /*surfaceSide*/ 0), edm::OwnVector< TrackingRecHit >() , PropagationDirection::alongMomentum)); + // LocalTrajectoryParameters localParam2(localSeedPoint, localSeedDir2, TrackCharge(1)); + // result->push_back(TrajectorySeed( PTrajectoryStateOnDet (localParam2, pt2, em, detId, /*surfaceSide*/ 0), edm::OwnVector< TrackingRecHit >() , PropagationDirection::alongMomentum)); + + GlobalPoint globalSeedPoint = globDet->surface().toGlobal(localSeedPoint); + reco::Track::CovarianceMatrix mm; + resultTracks->push_back(reco::Track(1,1,reco::Track::Point(globalSeedPoint.x(),globalSeedPoint.y(),globalSeedPoint.z()),reco::Track::Vector(globSeedDir.x(),globSeedDir.y(),globSeedDir.z()),1,mm)); + } + } + } + } + } + + + +// std::cout << "FILL!" << std::endl; + + // for(int i=0; i pt + } //jet + std::cout <<"numero di seed=" << result->size() <<", " << resultTracks->size() << std::endl; +iEvent.put(std::move(result)); +iEvent.put(std::move(resultTracks)); +} + + + + + + + + + + + + + +std::pair> JetCoreDirectSeedGenerator::findIntersection(const GlobalVector & dir,const reco::Candidate::Point & vertex, const GeomDet* det){ + StraightLinePlaneCrossing vertexPlane(Basic3DVector(vertex.x(),vertex.y(),vertex.z()), Basic3DVector(dir.x(),dir.y(),dir.z())); + + std::pair> pos = vertexPlane.position(det->specificSurface()); + + return pos; +} + + +std::pair JetCoreDirectSeedGenerator::local2Pixel(double locX, double locY, const GeomDet* det){ + LocalPoint locXY(locX,locY); + float pixX=(dynamic_cast(det))->specificTopology().pixel(locXY).first; + float pixY=(dynamic_cast(det))->specificTopology().pixel(locXY).second; + std::pair out(pixX,pixY); + return out; +} + +LocalPoint JetCoreDirectSeedGenerator::pixel2Local(int pixX, int pixY, const GeomDet* det){ + float locX=(dynamic_cast(det))->specificTopology().localX(pixX); + float locY=(dynamic_cast(det))->specificTopology().localY(pixY); + LocalPoint locXY(locX,locY); + return locXY; +} + + int JetCoreDirectSeedGenerator::pixelFlipper(const GeomDet* det){ + int out =1; + LocalVector locZdir(0,0,1); + GlobalVector globZdir = det->specificSurface().toGlobal(locZdir); + GlobalPoint globDetCenter = det->position(); + float direction = globZdir.x()*globDetCenter.x()+ globZdir.y()*globDetCenter.y()+ globZdir.z()*globDetCenter.z(); + //float direction = globZdir.dot(globDetCenter); + if(direction<0) out =-1; + // out=1; + return out; +} + + + +void JetCoreDirectSeedGenerator::fillPixelMatrix(const SiPixelCluster & cluster, int layer, auto inter, const GeomDet* det, tensorflow::NamedTensorList input_tensors ){//tensorflow::NamedTensorList input_tensors){ + + int flip = pixelFlipper(det); // 1=not flip, -1=flip + + for(int i=0; i pixInter = local2Pixel(inter.x(),inter.y(),det); + int nx = pix.x-pixInter.first; + int ny = pix.y-pixInter.second; + nx=flip*nx; + + if(abs(nx)=0 && nx>=0 && ny>=0) { + // clusterMeas[nx][ny][layer-1] += (pix.adc)/(float)(14000);//std::cout << "clusterMeas[nx][ny][layer-1] += (pix.adc)/(float)(14000) =" << (pix.adc)/(float)(14000) << std::endl;; + // } + } + } + +} + +std::pair JetCoreDirectSeedGenerator::SeedEvaluation(tensorflow::NamedTensorList input_tensors){ + + // tensorflow::TensorShape input_size_cluster {1,jetDimX,jetDimY,Nlayer} ; + // tensorflow::TensorShape input_size_pt {1} ; + // tensorflow::TensorShape input_size_eta {1} ; + // tensorflow::NamedTensorList input_tensors; + // input_tensors.resize(3); + // input_tensors[0] = tensorflow::NamedTensor(inputTensorName_[0], tensorflow::Tensor(tensorflow::DT_FLOAT, input_size_eta)); + // input_tensors[1] = tensorflow::NamedTensor(inputTensorName_[1], tensorflow::Tensor(tensorflow::DT_FLOAT, input_size_pt)); + // input_tensors[2] = tensorflow::NamedTensor(inputTensorName_[2], tensorflow::Tensor(tensorflow::DT_FLOAT, input_size_cluster)); + + // for(int lay=0; lay()(0,nx,ny,layer-1) = clusterMeas[nx][ny][layer-1]; + // } + // } + // + // // for(size_t j =0; j < values_.size();j++) { + // // input_tensors[0].second.matrix()(0,j) = values_[j]; + // // } + + // debug!!! +/* + for(int x=0; x()(0,x,y,l)!=0){ + std::cout << "input, " << "x=" << x << ", y=" << y <<", lay=" << l << ", val =" << input_tensors[2].second.tensor()(0,x,y,l) << std::endl; + } + } + } + } //end of debug +*/ + std::vector outputs; + std::vector output_names; + output_names.push_back(outputTensorName_[0]); + output_names.push_back(outputTensorName_[1]); + tensorflow::run(session_, input_tensors, output_names, &outputs); + auto matrix_output_par = outputs.at(0).tensor(); + auto matrix_output_prob = outputs.at(1).tensor(); + + // double trackPar[jetDimX][jetDimY][Nover][Npar+1]; //NOFLAG + // double trackProb[jetDimX][jetDimY][Nover]; + + std::pair output_combined; + + + for(int x=0; x()(0,x,y,trk); + output_combined.second[x][y][trk]=matrix_output_prob(0,x,y,trk,0);//outputs.at(1).matrix()(0,x,y,trk); + + for(int p=0; p()(0,x,y,trk,p); + output_combined.first[x][y][trk][p]=matrix_output_par(0,x,y,trk,p);//outputs.at(0).matrix()(0,x,y,trk,p); +// if(matrix_output_prob(0,x,y,trk,0)>0.9) std::cout << "internal output, prob= "< +#include +#include "boost/multi_array.hpp" + +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" + +// #include "SimG4Core/Application/interface/G4SimTrack.h" +// #include "SimDataFormats/Track/interface/SimTrack.h" + +#include "SimDataFormats/Vertex/interface/SimVertex.h" + + +#include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h" + +#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" + + + +#include "TTree.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" + + +namespace edm { class Event; class EventSetup; } + + +class JetCoreDirectSeedGenerator : public edm::one::EDProducer { + public: + explicit JetCoreDirectSeedGenerator(const edm::ParameterSet&); + ~JetCoreDirectSeedGenerator(); + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + // A pointer to a cluster and a list of tracks on it + struct TrackAndState + { + TrackAndState(const reco::Track *aTrack, TrajectoryStateOnSurface aState) : + track(aTrack), state(aState) {} + const reco::Track* track; + TrajectoryStateOnSurface state; + }; + + + template + struct ClusterWithTracks + { + ClusterWithTracks(const Cluster &c) : cluster(&c) {} + const Cluster* cluster; + std::vector tracks; + }; + + typedef ClusterWithTracks SiPixelClusterWithTracks; + + typedef boost::sub_range > SiPixelClustersWithTracks; + + TFile* JetCoreDirectSeedGenerator_out; + TTree* JetCoreDirectSeedGeneratorTree; + // static const int jetDimX =30; + // static const int jetDimY =30; + // static const int Nlayer =4; + // static const int Nover = 3; + // static const int Npar = 4; + + // double clusterMeas[jetDimX][jetDimY][Nlayer]; + double jet_pt; + double jet_eta; + double pitchX = 0.01; + double pitchY = 0.015; + bool print = false; + int evt_counter =0; + + + private: + virtual void beginJob() override; + virtual void produce( edm::Event&, const edm::EventSetup&) override; + virtual void endJob() override; + + + // ----------member data --------------------------- + std::string propagatorName_; + edm::ESHandle magfield_; + edm::ESHandle geometry_; + edm::ESHandle propagator_; + + edm::EDGetTokenT > vertices_; + edm::EDGetTokenT > pixelClusters_; + std::vector allSiPixelClusters; + std::map siPixelDetsWithClusters; + edm::Handle< edm::DetSetVector > pixeldigisimlink; + edm::Handle > inputPixelClusters; + edm::EDGetTokenT< edm::DetSetVector > pixeldigisimlinkToken; + edm::EDGetTokenT > cores_; + // edm::EDGetTokenT > simtracksToken; + // edm::EDGetTokenT > simvertexToken; + + double ptMin_; + double deltaR_; + double chargeFracMin_; + double centralMIPCharge_; + + std::string pixelCPE_; + std::string weightfilename_; + std::vector inputTensorName_; + std::vector outputTensorName_; + size_t nThreads; + std::string singleThreadPool; + + double probThr; + + + tensorflow::GraphDef* graph_; + tensorflow::Session* session_; + + + + std::pair> findIntersection(const GlobalVector & , const reco::Candidate::Point & ,const GeomDet*); + + void fillPixelMatrix(const SiPixelCluster &, int, auto, const GeomDet*, tensorflow::NamedTensorList); + + std::pair local2Pixel(double, double, const GeomDet*); + + LocalPoint pixel2Local(int, int, const GeomDet*); + + int pixelFlipper(const GeomDet*); + + const GeomDet* DetectorSelector(int ,const reco::Candidate& jet, GlobalVector, const reco::Vertex& jetVertex, const TrackerTopology* const); + + std::vector splittedClusterDirectionsOld(const reco::Candidate&, const TrackerTopology* const, auto pp, const reco::Vertex& jetVertex ); + std::vector splittedClusterDirections(const reco::Candidate&, const TrackerTopology* const, auto pp, const reco::Vertex& jetVertex, int ); + + std::pair SeedEvaluation(tensorflow::NamedTensorList); + + + +}; +#endif diff --git a/RecoTracker/TkSeedGenerator/plugins/JetCorePerfectSeedGenerator.cc b/RecoTracker/TkSeedGenerator/plugins/JetCorePerfectSeedGenerator.cc new file mode 100644 index 0000000000000..af60f72481e00 --- /dev/null +++ b/RecoTracker/TkSeedGenerator/plugins/JetCorePerfectSeedGenerator.cc @@ -0,0 +1,730 @@ +// -*- C++ -*- +// +// Package: trackJet/JetCorePerfectSeedGenerator +// Class: JetCorePerfectSeedGenerator +// +/**\class JetCorePerfectSeedGenerator JetCorePerfectSeedGenerator.cc trackJet/JetCorePerfectSeedGenerator/plugins/JetCorePerfectSeedGenerator.cc + Description: [one line class summary] + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Valerio Bertacchi +// Created: Mon, 18 Dec 2017 16:35:04 GMT +// +// + + +// system include files + +#define jetDimX 30 +#define jetDimY 30 +#define Nlayer 4 +#define Nover 3 +#define Npar 5 + +#include "JetCorePerfectSeedGenerator.h" + +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" +#include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h" +#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" +#include "Geometry/Records/interface/TrackerTopologyRcd.h" + +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/DetSetVector.h" +#include "DataFormats/Common/interface/DetSet.h" +#include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h" +#include "DataFormats/VertexReco/interface/Vertex.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/JetReco/interface/Jet.h" +#include "DataFormats/SiPixelDigi/interface/PixelDigi.h" +#include "DataFormats/GeometryVector/interface/VectorUtil.h" +#include "DataFormats/SiPixelDetId/interface/PXBDetId.h" +#include "DataFormats/Math/interface/Point3D.h" +#include "DataFormats/Math/interface/Vector3D.h" +#include "DataFormats/Candidate/interface/Candidate.h" +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" + + +#include "RecoLocalTracker/ClusterParameterEstimator/interface/PixelClusterParameterEstimator.h" +#include "RecoLocalTracker/Records/interface/TkPixelCPERecord.h" + +#include "SimDataFormats/TrackerDigiSimLink/interface/PixelDigiSimLink.h" + +#include "TrackingTools/GeomPropagators/interface/StraightLinePlaneCrossing.h" +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" + +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" + + + +#include +#include +#include "boost/multi_array.hpp" + +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" + +// #include "SimG4Core/Application/interface/G4SimTrack.h" +#include "SimDataFormats/Track/interface/SimTrack.h" +#include "SimDataFormats/Vertex/interface/SimVertex.h" + + +#include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h" + +#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" + + +#include "TTree.h" + + +// +// class declaration +// + +// If the analyzer does not use TFileService, please remove +// the template argument to the base class so the class inherits +// from edm::one::EDAnalyzer<> and also remove the line from +// constructor "usesResource("TFileService");" +// This will improve performance in multithreaded jobs. + + + +JetCorePerfectSeedGenerator::JetCorePerfectSeedGenerator(const edm::ParameterSet& iConfig) : + + vertices_(consumes(iConfig.getParameter("vertices"))), + pixelClusters_(consumes >(iConfig.getParameter("pixelClusters"))), + cores_(consumes >(iConfig.getParameter("cores"))), + simtracksToken(consumes >(iConfig.getParameter("simTracks"))), + simvertexToken(consumes >(iConfig.getParameter("simVertex"))), + PSimHitToken(consumes >(iConfig.getParameter("simHit"))), + ptMin_(iConfig.getParameter("ptMin")), + deltaR_(iConfig.getParameter("deltaR")), + chargeFracMin_(iConfig.getParameter("chargeFractionMin")), + centralMIPCharge_(iConfig.getParameter("centralMIPCharge")), + pixelCPE_(iConfig.getParameter("pixelCPE")) + +{ + produces(); + produces(); + + + + // edm::Service fileService; + // JetCorePerfectSeedGeneratorTree= fileService->make("JetCorePerfectSeedGeneratorTree","JetCorePerfectSeedGeneratorTree"); + // JetCorePerfectSeedGeneratorTree->Branch("cluster_measured",clusterMeas,"cluster_measured[30][30][4]/D"); + // JetCorePerfectSeedGeneratorTree->Branch("jet_eta",&jet_eta); + // JetCorePerfectSeedGeneratorTree->Branch("jet_pt",&jet_pt); + + // for(int i=0; i(); + auto resultTracks = std::make_unique(); + + // evt_counter++; +// std::cout << "event number (iterative)=" << evt_counter<< ", event number (id)="<< iEvent.id().event() << std::endl; + + using namespace edm; + using namespace reco; + + + iSetup.get().get( magfield_ ); + iSetup.get().get(geometry_); + iSetup.get().get( "AnalyticalPropagator", propagator_ ); + + iEvent.getByToken(pixelClusters_, inputPixelClusters); + allSiPixelClusters.clear(); siPixelDetsWithClusters.clear(); + allSiPixelClusters.reserve(inputPixelClusters->dataSize()); // this is important, otherwise push_back invalidates the iterators + + edm::Handle > simtracks; + iEvent.getByToken(simtracksToken, simtracks); + edm::Handle > simvertex; + iEvent.getByToken(simvertexToken, simvertex); + + iEvent.getByToken(PSimHitToken, simhits); + + Handle > vertices; + iEvent.getByToken(vertices_, vertices); + + Handle > cores; + iEvent.getByToken(cores_, cores); + + // iEvent.getByToken(pixeldigisimlinkToken, pixeldigisimlink); + + //--------------------------debuging lines ---------------------// + edm::ESHandle pe; + const PixelClusterParameterEstimator* pp; + iSetup.get().get(pixelCPE_, pe); + pp = pe.product(); + //--------------------------end ---------------------// + + edm::ESHandle tTopoHandle; + iSetup.get().get(tTopoHandle); + const TrackerTopology* const tTopo = tTopoHandle.product(); + + auto output = std::make_unique>(); + +print = false; +int jet_number = 0; +int seed_number = 0; + + + for (unsigned int ji = 0; ji < cores->size(); ji++) { //loop jet + jet_number++; + + if ((*cores)[ji].pt() > ptMin_) { +// std::cout << "|____________________NEW JET_______________________________| jet number=" << jet_number << " " << (*cores)[ji].pt() << " " << (*cores)[ji].eta() << " " << (*cores)[ji].phi() << std::endl; + + std::set ids; + const reco::Candidate& jet = (*cores)[ji]; + const reco::Vertex& jetVertex = (*vertices)[0]; + + std::vector splitClustDirSet = splittedClusterDirections(jet, tTopo, pp, jetVertex, 1); + //std::vector splitClustDirSet = splittedClusterDirections(jet, tTopo, pp, jetVertex); + // bool l2off=(splitClustDirSet.size()==0); + if(splitClustDirSet.size()==0) {//if layer 1 is broken find direcitons on layer 2 + splitClustDirSet = splittedClusterDirections(jet, tTopo, pp, jetVertex, 2); + // std::cout << "split on lay2, in numero=" << splitClustDirSet.size() << "+jetDir" << std::endl; + } + if(inclusiveConeSeed) splitClustDirSet.clear(); + splitClustDirSet.push_back(GlobalVector(jet.px(),jet.py(),jet.pz())); + // std::cout << "splitted cluster number=" << splitClustDirSet.size() << std::endl;; + + for(int cc=0; cc<(int)splitClustDirSet.size(); cc++){ + + + GlobalVector bigClustDir = splitClustDirSet.at(cc); + + const auto & simtracksVector = simtracks.product(); + const auto & simvertexVector = simvertex.product(); + + LocalPoint jetInter(0,0,0); + + jet_eta = jet.eta(); + jet_pt = jet.pt(); + + auto jetVert = jetVertex; //trackInfo filling + + std::vector goodSimHit; + + // edmNew::DetSetVector::const_iterator detIt = inputPixelClusters->begin(); + + const GeomDet* globDet = DetectorSelector(2, jet, bigClustDir, jetVertex, tTopo); //select detector mostly hitten by the jet + + if(globDet == 0) continue; + + // const GeomDet* goodDet1 = DetectorSelector(1, jet, bigClustDir, jetVertex, tTopo); + // const GeomDet* goodDet3 = DetectorSelector(3, jet, bigClustDir, jetVertex, tTopo); + // const GeomDet* goodDet4 = DetectorSelector(4, jet, bigClustDir, jetVertex, tTopo); + + + + // for (; detIt != inputPixelClusters->end(); detIt++) { //loop deset //COMMENTATO DA QUIIIII + // const edmNew::DetSet& detset = *detIt; + // const GeomDet* det = geometry_->idToDet(detset.id()); //lui sa il layer con cast a PXBDetId (vedi dentro il layer function) + // + // for (auto cluster = detset.begin(); cluster != detset.end(); cluster++) { //loop cluster + // + // const SiPixelCluster& aCluster = *cluster; + // det_id_type aClusterID= detset.id(); + // if(DetId(aClusterID).subdetId()!=1) continue; + // + // int lay = tTopo->layer(det->geographicalId()); + // + // std::pair> interPair = findIntersection(bigClustDir,(reco::Candidate::Point)jetVertex.position(), det); + // if(interPair.first==false) continue; + // Basic3DVector inter = interPair.second; + // auto localInter = det->specificSurface().toLocal((GlobalPoint)inter); + // + // GlobalPoint pointVertex(jetVertex.position().x(), jetVertex.position().y(), jetVertex.position().z()); + // + // + // // GlobalPoint cPos = det->surface().toGlobal(pp->localParametersV(aCluster,(*geometry_->idToDetUnit(detIt->id())))[0].first); + // LocalPoint cPos_local = pp->localParametersV(aCluster,(*geometry_->idToDetUnit(detIt->id())))[0].first; + // + // if(std::abs(cPos_local.x()-localInter.x())/pitchX<=jetDimX/2 && std::abs(cPos_local.y()-localInter.y())/pitchY<=jetDimY/2){ // per ora preso baricentro, da migliorare + // + // if(det==goodDet1 || det==goodDet3 || det==goodDet4 || det==globDet) { + // // fillPixelMatrix(aCluster,lay,localInter, det, input_matrix_cluster); + // fillPixelMatrix(aCluster,lay,localInter, det, input_tensors); + // } + // } //cluster in ROI + // } //cluster + // } //detset + std::pair,std::vector> goodSimTkVx; + + if(inclusiveConeSeed) { + auto jetVert = jetVertex; + goodSimTkVx = JetCorePerfectSeedGenerator::coreTracksFillingDeltaR(simtracksVector, simvertexVector,globDet,jet,jetVert ); + } + else { + std::vector goodSimHit = JetCorePerfectSeedGenerator::coreHitsFilling(simhits,globDet,bigClustDir,jetVertex); + goodSimTkVx = JetCorePerfectSeedGenerator::coreTracksFilling(goodSimHit,simtracksVector, simvertexVector); + } + seed_number = goodSimTkVx.first.size(); + std::cout << "seed number in deltaR cone =" << seed_number << std::endl; + + std::vector> seedVector = JetCorePerfectSeedGenerator::seedParFilling(goodSimTkVx,globDet, jet); + std::cout << "seedVector.size()=" << seedVector.size()<< std::endl; + + + for(uint tk=0; tkgeographicalId(); + LocalTrajectoryParameters localParam(localSeedPoint, localSeedDir, TrackCharge(1)); + result->push_back(TrajectorySeed( PTrajectoryStateOnDet (localParam, pt, em, detId, /*surfaceSide*/ 0), edm::OwnVector< TrackingRecHit >() , PropagationDirection::alongMomentum)); + + GlobalPoint globalSeedPoint = globDet->surface().toGlobal(localSeedPoint); + reco::Track::CovarianceMatrix mm; + resultTracks->push_back(reco::Track(1,1,reco::Track::Point(globalSeedPoint.x(),globalSeedPoint.y(),globalSeedPoint.z()),reco::Track::Vector(globSeedDir.x(),globSeedDir.y(),globSeedDir.z()),1,mm)); + std::cout << "seed " << tk<< ", out, pt=" << pt << ", eta="<< globSeedDir.eta() << ", phi=" << globSeedDir.phi() < pt + } //jet +iEvent.put(std::move(result)); +iEvent.put(std::move(resultTracks)); +} + + + + + + + + + + + + + +std::pair> JetCorePerfectSeedGenerator::findIntersection(const GlobalVector & dir,const reco::Candidate::Point & vertex, const GeomDet* det){ + StraightLinePlaneCrossing vertexPlane(Basic3DVector(vertex.x(),vertex.y(),vertex.z()), Basic3DVector(dir.x(),dir.y(),dir.z())); + + std::pair> pos = vertexPlane.position(det->specificSurface()); + + return pos; +} + + +std::pair JetCorePerfectSeedGenerator::local2Pixel(double locX, double locY, const GeomDet* det){ + LocalPoint locXY(locX,locY); + float pixX=(dynamic_cast(det))->specificTopology().pixel(locXY).first; + float pixY=(dynamic_cast(det))->specificTopology().pixel(locXY).second; + std::pair out(pixX,pixY); + return out; +} + +LocalPoint JetCorePerfectSeedGenerator::pixel2Local(int pixX, int pixY, const GeomDet* det){ + float locX=(dynamic_cast(det))->specificTopology().localX(pixX); + float locY=(dynamic_cast(det))->specificTopology().localY(pixY); + LocalPoint locXY(locX,locY); + return locXY; +} + + int JetCorePerfectSeedGenerator::pixelFlipper(const GeomDet* det){ + int out =1; + LocalVector locZdir(0,0,1); + GlobalVector globZdir = det->specificSurface().toGlobal(locZdir); + GlobalPoint globDetCenter = det->position(); + float direction = globZdir.x()*globDetCenter.x()+ globZdir.y()*globDetCenter.y()+ globZdir.z()*globDetCenter.z(); + //float direction = globZdir.dot(globDetCenter); + if(direction<0) out =-1; + // out=1; + return out; +} + + + +void JetCorePerfectSeedGenerator::fillPixelMatrix(const SiPixelCluster & cluster, int layer, auto inter, const GeomDet* det, tensorflow::NamedTensorList input_tensors ){//tensorflow::NamedTensorList input_tensors){ + + int flip = pixelFlipper(det); // 1=not flip, -1=flip + + for(int i=0; i pixInter = local2Pixel(inter.x(),inter.y(),det); + int nx = pix.x-pixInter.first; + int ny = pix.y-pixInter.second; + nx=flip*nx; + + if(abs(nx)=0 && nx>=0 && ny>=0) { + // clusterMeas[nx][ny][layer-1] += (pix.adc)/(float)(14000);//std::cout << "clusterMeas[nx][ny][layer-1] += (pix.adc)/(float)(14000) =" << (pix.adc)/(float)(14000) << std::endl;; + // } + } + } + +} + + + + +const GeomDet* JetCorePerfectSeedGenerator::DetectorSelector(int llay, const reco::Candidate& jet, GlobalVector jetDir, const reco::Vertex& jetVertex, const TrackerTopology* const tTopo){ + + struct trkNumCompare { + bool operator()(std::pair x, std::pair y) const + {return x.first > y.first;} + }; + + std::set, trkNumCompare> track4detSet; + + LocalPoint jetInter(0,0,0); + + edmNew::DetSetVector::const_iterator detIt = inputPixelClusters->begin(); + + double minDist = 0.0; + GeomDet* output = (GeomDet*)0; + + for (; detIt != inputPixelClusters->end(); detIt++) { //loop deset + + const edmNew::DetSet& detset = *detIt; + const GeomDet* det = geometry_->idToDet(detset.id()); //lui sa il layer con cast a PXBDetId (vedi dentro il layer function) + for (auto cluster = detset.begin(); cluster != detset.end(); cluster++) { //loop cluster + // const SiPixelCluster& aCluster = *cluster; + auto aClusterID= detset.id(); + if(DetId(aClusterID).subdetId()!=1) continue; + int lay = tTopo->layer(det->geographicalId()); + if(lay!=llay) continue; + std::pair> interPair = findIntersection(jetDir,(reco::Candidate::Point)jetVertex.position(), det); + if(interPair.first==false) continue; + Basic3DVector inter = interPair.second; + auto localInter = det->specificSurface().toLocal((GlobalPoint)inter); + if((minDist==0.0 || std::abs(localInter.x()),std::vector> JetCorePerfectSeedGenerator::coreTracksFilling(std::vector goodSimHit, const auto & simtracksVector, const auto & simvertexVector){ + std::vector goodSimTrk; + std::vector goodSimVtx; + + + + for(uint j=0; jsize(); j++){ + for(std::vector::const_iterator it=goodSimHit.begin(); it!=goodSimHit.end(); ++it) { + SimTrack st = simtracksVector->at(j); + if(st.trackId()==(*it).trackId()) { + // goodSimTrk.push_back(st); + + for(uint v =0; vsize(); v++) { + SimVertex sv = simvertexVector->at(v); + if((int)sv.vertexId()==(int)st.vertIndex()){ + // if(st.vertIndex()==-1) goodSimVtx.push_back((SimVertex)jVert); + //else + goodSimTrk.push_back(st); + goodSimVtx.push_back(sv); + } + } + } + } + } + std::pair,std::vector> output(goodSimTrk,goodSimVtx); + return output; +} + +std::pair,std::vector> JetCorePerfectSeedGenerator::coreTracksFillingDeltaR( const auto & simtracksVector, const auto & simvertexVector,const GeomDet* globDet, const reco::Candidate& jet, auto jetVertex){ + std::vector goodSimTrk; + std::vector goodSimVtx; + + GlobalVector jetDir(jet.px(), jet.py(), jet.pz()); + + for(uint j=0; jsize(); j++){ + SimTrack st = simtracksVector->at(j); + GlobalVector trkDir(st.momentum().Px(), st.momentum().Py(), st.momentum().Pz()); + if(Geom::deltaR(jetDir, trkDir) < deltaR_){ + if(st.charge()==0) continue; + // if((int)st.vertIndex()==-1) { + // goodSimTrk.push_back(st); + // // goodSimVtx.push_back((SimVertex)jetVertex); + // std::cout << "problema" << std::endl; + // } + // else { + for(uint v =0; vsize(); v++) { + SimVertex sv = simvertexVector->at(v); + if((int)sv.vertexId()==(int)st.vertIndex()){ + // if(st.vertIndex()==-1) goodSimVtx.push_back((SimVertex)jVert); + //else + // std::cout << "goodsimtrack " << j<< ", filling good st, pt" << st.momentum().Pt() << ", eta="<< st.momentum().Eta() << ", phi=" << st.momentum().Phi() << std::endl; + goodSimTrk.push_back(st); + goodSimVtx.push_back(sv); + } + } + // } + + } + // else std::cout << "BAD sim track " << j<< ", pt" << st.momentum().Pt() << ", eta="<< st.momentum().Eta() << ", phi=" << st.momentum().Phi() << std::endl; + } + std::pair,std::vector> output(goodSimTrk,goodSimVtx); + return output; +} + + +std::vector> JetCorePerfectSeedGenerator::seedParFilling(std::pair,std::vector> goodSimTkVx,const GeomDet* globDet, const reco::Candidate& jet){ + std::vector> output; + std::vector goodSimTrk=goodSimTkVx.first; + std::vector goodSimVtx=goodSimTkVx.second; + + std::cout << "goodSimTrk.size()" << goodSimTrk.size() << std::endl; + for(uint j=0; j> trkInterPair; + // std::cout << "sv " << (int)sv.vertexId() << "/// st " << (int)st.vertIndex()<< std::endl; + trkInterPair = findIntersection(trkMom,(reco::Candidate::Point)trkPos, globDet); + if(trkInterPair.first==false) { + GlobalVector jetDir(jet.px(), jet.py(), jet.pz()); + double deltar = Geom::deltaR(jetDir, trkMom); + // std::cout << "not intersection, deltaR=" << deltar << std::endl; + + continue; + } + Basic3DVector trkInter = trkInterPair.second; + + auto localTrkInter = globDet->specificSurface().toLocal((GlobalPoint)trkInter); + // std::cout << ", localtrackInter" << localTrkInter.x() << ", " << localTrkInter.y() << std::endl; + + + + // double tkpar[Npar]; + // // for(uint v =0; vsize(); v++) { + // // SimVertex sv = simvertexVector->at(v); + // // if((int)sv.vertexId()==(int)st.vertIndex()){ + // // + // // } + // // } + // + // tkpar[0] = localTrkInter.x(); + // tkpar[1] = localTrkInter.y(); + // tkpar[2] = st.momentum().Eta(); + // tkpar[3] = st.momentum().Phi(); + // tkpar[4] = 1/st.momentum().Pt(); + + // std::cout << "IN, pt=" < +#include +#include "boost/multi_array.hpp" + +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" + +// #include "SimG4Core/Application/interface/G4SimTrack.h" +#include "SimDataFormats/Track/interface/SimTrack.h" + +#include "SimDataFormats/Vertex/interface/SimVertex.h" + + +#include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h" + +#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" + +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" + + +#include "TTree.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" + + +namespace edm { class Event; class EventSetup; } + + +class JetCorePerfectSeedGenerator : public edm::one::EDProducer { + public: + explicit JetCorePerfectSeedGenerator(const edm::ParameterSet&); + ~JetCorePerfectSeedGenerator(); + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + // A pointer to a cluster and a list of tracks on it + struct TrackAndState + { + TrackAndState(const reco::Track *aTrack, TrajectoryStateOnSurface aState) : + track(aTrack), state(aState) {} + const reco::Track* track; + TrajectoryStateOnSurface state; + }; + + + template + struct ClusterWithTracks + { + ClusterWithTracks(const Cluster &c) : cluster(&c) {} + const Cluster* cluster; + std::vector tracks; + }; + + typedef ClusterWithTracks SiPixelClusterWithTracks; + + typedef boost::sub_range > SiPixelClustersWithTracks; + + TFile* JetCorePerfectSeedGenerator_out; + TTree* JetCorePerfectSeedGeneratorTree; + // static const int jetDimX =30; + // static const int jetDimY =30; + // static const int Nlayer =4; + // static const int Nover = 3; + // static const int Npar = 4; + + // double clusterMeas[jetDimX][jetDimY][Nlayer]; + double jet_pt; + double jet_eta; + double pitchX = 0.01; + double pitchY = 0.015; + bool print = false; + int evt_counter =0; + bool inclusiveConeSeed = true; //true= fill tracks in a cone of deltaR_, false=fill tracks which produce SimHit on globDet + + + private: + virtual void beginJob() override; + virtual void produce( edm::Event&, const edm::EventSetup&) override; + virtual void endJob() override; + + + // ----------member data --------------------------- + std::string propagatorName_; + edm::ESHandle magfield_; + edm::ESHandle geometry_; + edm::ESHandle propagator_; + + edm::EDGetTokenT > vertices_; + edm::EDGetTokenT > pixelClusters_; + std::vector allSiPixelClusters; + std::map siPixelDetsWithClusters; + edm::Handle< edm::DetSetVector > pixeldigisimlink; + edm::Handle > inputPixelClusters; + edm::EDGetTokenT< edm::DetSetVector > pixeldigisimlinkToken; + edm::EDGetTokenT > cores_; + edm::EDGetTokenT > simtracksToken; + edm::EDGetTokenT > simvertexToken; + edm::EDGetTokenT > PSimHitToken; + edm::Handle > simhits; + + double ptMin_; + double deltaR_; + double chargeFracMin_; + double centralMIPCharge_; + + std::string pixelCPE_; + + tensorflow::GraphDef* graph_; + tensorflow::Session* session_; + + + + std::pair> findIntersection(const GlobalVector & , const reco::Candidate::Point & ,const GeomDet*); + + void fillPixelMatrix(const SiPixelCluster &, int, auto, const GeomDet*, tensorflow::NamedTensorList); + + std::pair local2Pixel(double, double, const GeomDet*); + + LocalPoint pixel2Local(int, int, const GeomDet*); + + int pixelFlipper(const GeomDet*); + + const GeomDet* DetectorSelector(int ,const reco::Candidate& jet, GlobalVector, const reco::Vertex& jetVertex, const TrackerTopology* const); + + std::vector splittedClusterDirections(const reco::Candidate&, const TrackerTopology* const, auto pp, const reco::Vertex& jetVertex, int ); + + std::vector coreHitsFilling(auto,const GeomDet*,GlobalVector,const reco::Vertex&); + std::pair,std::vector> coreTracksFilling(std::vector, const auto &, const auto &); + + std::vector> seedParFilling(std::pair,std::vector>,const GeomDet*, const reco::Candidate&); + + std::pair,std::vector> coreTracksFillingDeltaR( const auto &, const auto &,const GeomDet* , const reco::Candidate&,auto ); + + +}; +#endif diff --git a/RecoTracker/TkSeedGenerator/plugins/SealModules.cc b/RecoTracker/TkSeedGenerator/plugins/SealModules.cc index 2ad71ffae8943..9599d9b22a6da 100644 --- a/RecoTracker/TkSeedGenerator/plugins/SealModules.cc +++ b/RecoTracker/TkSeedGenerator/plugins/SealModules.cc @@ -35,3 +35,9 @@ DEFINE_FWK_MODULE(SeedCreatorFromRegionConsecutiveHitsEDProducer); using SeedCreatorFromRegionConsecutiveHitsTripletOnlyEDProducer = SeedCreatorFromRegionHitsEDProducerT; DEFINE_FWK_MODULE(SeedCreatorFromRegionConsecutiveHitsTripletOnlyEDProducer); + +#include "RecoTracker/TkSeedGenerator/plugins/JetCoreDirectSeedGenerator.h" +DEFINE_FWK_MODULE(JetCoreDirectSeedGenerator); + +#include "RecoTracker/TkSeedGenerator/plugins/JetCorePerfectSeedGenerator.h" +DEFINE_FWK_MODULE(JetCorePerfectSeedGenerator); diff --git a/RecoTracker/TkSeedGenerator/python/jetCoreDirectSeedGenerator_cfi.py b/RecoTracker/TkSeedGenerator/python/jetCoreDirectSeedGenerator_cfi.py new file mode 100644 index 0000000000000..48106708be6cf --- /dev/null +++ b/RecoTracker/TkSeedGenerator/python/jetCoreDirectSeedGenerator_cfi.py @@ -0,0 +1,18 @@ +import FWCore.ParameterSet.Config as cms + +jetCoreDirectSeedGenerator = cms.EDProducer("JetCoreDirectSeedGenerator", + vertices= cms.InputTag("offlinePrimaryVertices"), + pixelClusters= cms.InputTag("siPixelClustersPreSplitting"), + cores= cms.InputTag("jetsForCoreTracking"), + ptMin= cms.double(300), + deltaR= cms.double(0.1), + chargeFractionMin= cms.double(18000.0), + centralMIPCharge= cms.double(2), + pixelCPE= cms.string( "PixelCPEGeneric" ), + weightFile= cms.FileInPath("RecoTracker/TkSeedGenerator/data/JetCoreDirectSeedGenerator_TrainedModel.pb"), + inputTensorName= cms.vstring(["input_1","input_2","input_3"]), + outputTensorName= cms.vstring(["output_node0","output_node1"]), + nThreads= cms.uint32(1), + singleThreadPool= cms.string("no_threads"), + probThr = cms.double(0.99), +) diff --git a/RecoTracker/TkSeedGenerator/python/jetCorePerfectSeedGenerator_cfi.py b/RecoTracker/TkSeedGenerator/python/jetCorePerfectSeedGenerator_cfi.py new file mode 100644 index 0000000000000..4ade6668c734b --- /dev/null +++ b/RecoTracker/TkSeedGenerator/python/jetCorePerfectSeedGenerator_cfi.py @@ -0,0 +1,15 @@ +import FWCore.ParameterSet.Config as cms + +JetCorePerfectSeedGenerator = cms.EDProducer("JetCorePerfectSeedGenerator", + vertices= cms.InputTag("offlinePrimaryVertices"), + pixelClusters= cms.InputTag("siPixelClustersPreSplitting"), + cores= cms.InputTag("jetsForCoreTracking"), + ptMin= cms.double(300), + deltaR= cms.double(0.3), + chargeFractionMin= cms.double(18000.0), + simTracks= cms.InputTag("g4SimHits"), + simVertex= cms.InputTag("g4SimHits"), + simHit= cms.InputTag("g4SimHits","TrackerHitsPixelBarrelLowTof"), + centralMIPCharge= cms.double(2), + pixelCPE= cms.string( "PixelCPEGeneric" ) +) diff --git a/SimGeneral/MixingModule/python/SiPixelSimParameters_cfi.py b/SimGeneral/MixingModule/python/SiPixelSimParameters_cfi.py index dbc6de73422c1..a54b8f6fa2a29 100644 --- a/SimGeneral/MixingModule/python/SiPixelSimParameters_cfi.py +++ b/SimGeneral/MixingModule/python/SiPixelSimParameters_cfi.py @@ -39,6 +39,7 @@ def _modifyPixelDigitizerForPhase1Pixel( digitizer ) : SiPixelSimBlock = cms.PSet( + SiPixelQualityLabel = cms.string(''), KillBadFEDChannels = cms.bool(False), UseReweighting = cms.bool(False), PrintClusters = cms.bool(False), @@ -103,6 +104,12 @@ def _modifyPixelDigitizerForPhase1Pixel( digitizer ) : from Configuration.Eras.Modifier_phase1Pixel_cff import phase1Pixel phase1Pixel.toModify( SiPixelSimBlock, func=_modifyPixelDigitizerForPhase1Pixel ) +# use Label 'forDigitizer' for years >= 2018 +from CalibTracker.SiPixelESProducers.SiPixelQualityESProducer_cfi import siPixelQualityESProducer +from Configuration.Eras.Modifier_run2_SiPixel_2018_cff import run2_SiPixel_2018 +run2_SiPixel_2018.toModify(siPixelQualityESProducer,siPixelQualityLabel = 'forDigitizer',) +run2_SiPixel_2018.toModify(SiPixelSimBlock, SiPixelQualityLabel = 'forDigitizer',) + from Configuration.ProcessModifiers.premix_stage1_cff import premix_stage1 premix_stage1.toModify(SiPixelSimBlock, AddNoise = True, diff --git a/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.cc b/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.cc index af0ca335d2ec0..69cb5b5417400 100644 --- a/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.cc +++ b/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.cc @@ -118,7 +118,7 @@ void SiPixelDigitizerAlgorithm::init(const edm::EventSetup& es) { theSiPixelGainCalibrationService_->setESObjects( es ); } if(use_deadmodule_DB_) { - es.get().get(SiPixelBadModule_); + es.get().get(siPixelQualityLabel, SiPixelBadModule_); } if(use_LorentzAngle_DB_) { // Get Lorentz angle from DB record @@ -191,7 +191,8 @@ void SiPixelDigitizerAlgorithm::init(const edm::EventSetup& es) { //========================================================================= SiPixelDigitizerAlgorithm::SiPixelDigitizerAlgorithm(const edm::ParameterSet& conf) : - + + siPixelQualityLabel(conf.getParameter("SiPixelQualityLabel")), //string to specify SiPixelQuality label _signal(), makeDigiSimLinks_(conf.getUntrackedParameter("makeDigiSimLinks", true)), use_ineff_from_db_(conf.getParameter("useDB")), diff --git a/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.h b/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.h index 87c1abbb00e0a..55b549ed6aedf 100644 --- a/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.h +++ b/SimTracker/SiPixelDigitizer/plugins/SiPixelDigitizerAlgorithm.h @@ -96,6 +96,7 @@ class SiPixelDigitizerAlgorithm { edm::ESHandle SiPixelLorentzAngle_; //Accessing Dead pixel modules from DB: + std::string siPixelQualityLabel; edm::ESHandle SiPixelBadModule_; //Accessing Map and Geom: diff --git a/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cff.py b/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cff.py index 5074c697f4321..50ba8124cd782 100644 --- a/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cff.py +++ b/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cff.py @@ -1,6 +1,7 @@ import FWCore.ParameterSet.Config as cms from SimTracker.TrackAssociatorProducers.quickTrackAssociatorByHits_cfi import * +from SimTracker.TrackAssociatorProducers.trackAssociatorByChi2_cfi import * from SimTracker.TrackAssociation.trackingParticleRecoTrackAsssociation_cfi import * import SimTracker.TrackAssociation.trackingParticleRecoTrackAsssociation_cfi @@ -14,4 +15,3 @@ assoc2GsfTracks.label_tr = 'electronGsfTracks' assocOutInConversionTracks.label_tr = 'ckfOutInTracksFromConversions' assocInOutConversionTracks.label_tr = 'ckfInOutTracksFromConversions' - diff --git a/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cfi.py b/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cfi.py index cdc07e07c9fd8..47592623ea727 100644 --- a/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cfi.py +++ b/SimTracker/TrackAssociation/python/trackingParticleRecoTrackAsssociation_cfi.py @@ -2,6 +2,7 @@ trackingParticleRecoTrackAsssociation = cms.EDProducer("TrackAssociatorEDProducer", associator = cms.InputTag('quickTrackAssociatorByHits'), + # associator = cms.InputTag('trackAssociatorByChi2'), label_tp = cms.InputTag("mix","MergedTrackTruth"), label_tr = cms.InputTag("generalTracks"), ignoremissingtrackcollection=cms.untracked.bool(False) @@ -9,4 +10,3 @@ from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 premix_stage2.toModify(trackingParticleRecoTrackAsssociation, label_tp = "mixData:MergedTrackTruth") - diff --git a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Impl.cc b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Impl.cc index d3b27276f5796..e86e9b3b6e651 100644 --- a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Impl.cc +++ b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Impl.cc @@ -20,12 +20,12 @@ double TrackAssociatorByChi2Impl::getChi2(const TrackBase::ParameterVector& rPar } -RecoToSimCollection TrackAssociatorByChi2Impl::associateRecoToSim(const edm::RefToBaseVector& tC, +RecoToSimCollection TrackAssociatorByChi2Impl::associateRecoToSim(const edm::RefToBaseVector& tC, const edm::RefVector& tPCH) const { const reco::BeamSpot& bs = *theBeamSpot; - RecoToSimCollection outputCollection; + RecoToSimCollection outputCollection(productGetter_);; //dereference the edm::Refs only once std::vector tPC; @@ -40,7 +40,7 @@ RecoToSimCollection TrackAssociatorByChi2Impl::associateRecoToSim(const edm::Ref LogDebug("TrackAssociator") << "=========LOOKING FOR ASSOCIATION===========" << "\n" << "rec::Track #"<parameters(); TrackBase::CovarianceMatrix recoTrackCovMatrix = (*rt)->covariance(); @@ -50,13 +50,13 @@ RecoToSimCollection TrackAssociatorByChi2Impl::associateRecoToSim(const edm::Ref if (i!=j) recoTrackCovMatrix(i,j)=0; } } - } + } recoTrackCovMatrix.Invert(); int tpindex =0; for (auto tp=tPC.begin(); tp!=tPC.end(); tp++, ++tpindex){ - + //skip tps with a very small pt //if (sqrt((*tp)->momentum().perp2())<0.5) continue; int charge = (*tp)->charge(); @@ -65,9 +65,9 @@ RecoToSimCollection TrackAssociatorByChi2Impl::associateRecoToSim(const edm::Ref Basic3DVector vert=(Basic3DVector) (*tp)->vertex(); double chi2 = getChi2(rParameters,recoTrackCovMatrix,momAtVtx,vert,charge,bs); - + if (chi2& tC, +SimToRecoCollection TrackAssociatorByChi2Impl::associateSimToReco(const edm::RefToBaseVector& tC, const edm::RefVector& tPCH) const { const reco::BeamSpot& bs = *theBeamSpot; - SimToRecoCollection outputCollection; + SimToRecoCollection outputCollection(productGetter_); int tpindex =0; for (auto tp=tPCH.begin(); tp!=tPCH.end(); tp++, ++tpindex){ - + //skip tps with a very small pt //if (sqrt(tp->momentum().perp2())<0.5) continue; int charge = (*tp)->charge(); if (charge==0) continue; - + LogDebug("TrackAssociator") << "=========LOOKING FOR ASSOCIATION===========" << "\n" << "TrackingParticle #"< momAtVtx((*tp)->momentum().x(),(*tp)->momentum().y(),(*tp)->momentum().z()); Basic3DVector vert((*tp)->vertex().x(),(*tp)->vertex().y(),(*tp)->vertex().z()); - + int tindex=0; for (RefToBaseVector::const_iterator rt=tC.begin(); rt!=tC.end(); rt++, tindex++){ - - TrackBase::ParameterVector rParameters = (*rt)->parameters(); + + TrackBase::ParameterVector rParameters = (*rt)->parameters(); TrackBase::CovarianceMatrix recoTrackCovMatrix = (*rt)->covariance(); if (onlyDiagonal) { for (unsigned int i=0;i<5;i++){ @@ -112,9 +112,9 @@ SimToRecoCollection TrackAssociatorByChi2Impl::associateSimToReco(const edm::Ref } } recoTrackCovMatrix.Invert(); - + double chi2 = getChi2(rParameters,recoTrackCovMatrix,momAtVtx,vert,charge,bs); - + if (chi2, double> > - GenToRecoCollection; - typedef edm::AssociationMap, reco::GenParticleCollection, double> > - RecoToGenCollection; + RecoToGenCollection; } @@ -45,18 +49,20 @@ class TrackAssociatorByChi2Impl : public reco::TrackToTrackingParticleAssociator chi2cut(conf.getParameter("chi2cut")), onlyDiagonal(conf.getParameter("onlyDiagonal")), bsSrc(conf.getParameter("beamSpot")) { - theMF=mF; + theMF=mF; if (onlyDiagonal) edm::LogInfo("TrackAssociator") << " ---- Using Off Diagonal Covariance Terms = 0 ---- " << "\n"; - else + else edm::LogInfo("TrackAssociator") << " ---- Using Off Diagonal Covariance Terms != 0 ---- " << "\n"; } */ /// Constructor - TrackAssociatorByChi2Impl(const MagneticField& mF, + TrackAssociatorByChi2Impl(edm::EDProductGetter const& productGetter, + const MagneticField& mF, const reco::BeamSpot& bs, double chi2Cut, bool onlyDiag): + productGetter_(&productGetter), theMF(&mF), theBeamSpot(&bs), chi2cut(chi2Cut), @@ -65,27 +71,27 @@ class TrackAssociatorByChi2Impl : public reco::TrackToTrackingParticleAssociator /// Association Reco To Sim with Collections - + reco::RecoToSimCollection associateRecoToSim(const edm::RefToBaseVector&, const edm::RefVector&) const override; /// Association Sim To Reco with Collections - + reco::SimToRecoCollection associateSimToReco(const edm::RefToBaseVector&, const edm::RefVector&) const override; - + /// compare reco to sim the handle of reco::Track and TrackingParticle collections - - reco::RecoToSimCollection associateRecoToSim(const edm::Handle >& tCH, + + reco::RecoToSimCollection associateRecoToSim(const edm::Handle >& tCH, const edm::Handle& tPCH) const override { return TrackToTrackingParticleAssociatorBaseImpl::associateRecoToSim(tCH,tPCH); } - + /// compare reco to sim the handle of reco::Track and TrackingParticle collections - - reco::SimToRecoCollection associateSimToReco(const edm::Handle >& tCH, + + reco::SimToRecoCollection associateSimToReco(const edm::Handle >& tCH, const edm::Handle& tPCH) const override { return TrackToTrackingParticleAssociatorBaseImpl::associateSimToReco(tCH,tPCH); - } + } private: /// basic method where chi2 is computed @@ -96,6 +102,8 @@ class TrackAssociatorByChi2Impl : public reco::TrackToTrackingParticleAssociator int charge, const reco::BeamSpot&) const; + edm::EDProductGetter const* productGetter_; + const MagneticField* theMF; const reco::BeamSpot* theBeamSpot; double chi2cut; diff --git a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Producer.cc b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Producer.cc index 0605645e435e8..e1fc1cd70bce0 100644 --- a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Producer.cc +++ b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Producer.cc @@ -2,7 +2,7 @@ // // Package: SimTracker/TrackAssociatorProducers // Class: TrackAssociatorByChi2Producer -// +// /**\class TrackAssociatorByChi2Producer TrackAssociatorByChi2Producer.cc SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByChi2Producer.cc Description: [one line class summary] @@ -34,7 +34,7 @@ #include "SimDataFormats/Associations/interface/TrackToGenParticleAssociator.h" #include "SimDataFormats/Associations/interface/TrackToTrackingParticleAssociatorBaseImpl.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" #include "TrackAssociatorByChi2Impl.h" #include "TrackGenAssociatorByChi2Impl.h" @@ -47,12 +47,12 @@ class TrackAssociatorByChi2Producer : public edm::global::EDProducer<> { public: explicit TrackAssociatorByChi2Producer(const edm::ParameterSet&); ~TrackAssociatorByChi2Producer() override; - + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - + private: void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; - + // ----------member data --------------------------- edm::EDGetTokenT bsToken_; const double chi2cut_; @@ -84,7 +84,7 @@ TrackAssociatorByChi2Producer::TrackAssociatorByChi2Producer(const edm::Paramete TrackAssociatorByChi2Producer::~TrackAssociatorByChi2Producer() { - + // do anything here that needs to be done at desctruction time // (e.g. close files, deallocate resources etc.) @@ -108,13 +108,14 @@ TrackAssociatorByChi2Producer::produce(edm::StreamID, edm::Event& iEvent, const iEvent.getByToken(bsToken_,beamSpot); { - std::unique_ptr impl( new TrackAssociatorByChi2Impl(*magField, - *beamSpot, + std::unique_ptr impl( new TrackAssociatorByChi2Impl(iEvent.productGetter(), + *magField, + *beamSpot, chi2cut_, onlyDiagonal_)); - + std::unique_ptr assoc(new reco::TrackToTrackingParticleAssociator(std::move(impl))); - + iEvent.put(std::move(assoc)); } @@ -123,14 +124,14 @@ TrackAssociatorByChi2Producer::produce(edm::StreamID, edm::Event& iEvent, const *beamSpot, chi2cut_, onlyDiagonal_)); - + std::unique_ptr assoc(new reco::TrackToGenParticleAssociator(std::move(impl))); - + iEvent.put(std::move(assoc)); } } - + // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ void TrackAssociatorByChi2Producer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { diff --git a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.cc b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.cc index 8e7ef7b0ab089..ae6d9d8b781dc 100644 --- a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.cc +++ b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.cc @@ -20,7 +20,7 @@ TrajectoryStateOnSurface TrackAssociatorByPositionImpl::getState(const TrackingP clusterTPpairWithDummyTP, [](const SimHitTPPair& iLHS, const SimHitTPPair& iRHS) -> bool { return iLHS.first.key()> iRHS.first.key(); }); - + // TrackingParticle* simtrack = const_cast(&st); //loop over PSimHits const PSimHit * psimhit=nullptr; @@ -33,14 +33,14 @@ TrajectoryStateOnSurface TrackAssociatorByPositionImpl::getState(const TrackingP LogDebug("TrackAssociatorByPositionImpl")<second; //get the detid DetId dd(psit->detUnitId()); - if (!theConsiderAllSimHits && dd.det()!=DetId::Tracker) continue; + if (!theConsiderAllSimHits && dd.det()!=DetId::Tracker) continue; LogDebug("TrackAssociatorByPositionImpl")<toGlobal(psimhit->localPosition()); GlobalVector initialMomentum=plane->toGlobal(psimhit->momentumAtEntry()); int initialCharge = (psimhit->particleType()>0) ? -1:1; - CartesianTrajectoryError initialCartesianErrors; //no error at initial state + CartesianTrajectoryError initialCartesianErrors; //no error at initial state const GlobalTrajectoryParameters initialParameters(initialPoint,initialMomentum,initialCharge,thePropagator->magneticField()); return TrajectoryStateOnSurface(initialParameters,initialCartesianErrors,*plane,surfaceside);} else{ @@ -110,9 +110,9 @@ double TrackAssociatorByPositionImpl::quality(const TrajectoryStateOnSurface & t } -RecoToSimCollection TrackAssociatorByPositionImpl::associateRecoToSim(const edm::RefToBaseVector& tCH, +RecoToSimCollection TrackAssociatorByPositionImpl::associateRecoToSim(const edm::RefToBaseVector& tCH, const edm::RefVector& tPCH) const { - RecoToSimCollection outputCollection; + RecoToSimCollection outputCollection(productGetter_); //for each reco track find a matching tracking particle std::pair minPair; const double dQmin_default=1542543; @@ -130,14 +130,14 @@ RecoToSimCollection TrackAssociatorByPositionImpl::associateRecoToSim(const edm: bool atLeastOne=false; // for each tracking particle, find a state position and the plane to propagate the track to. for (unsigned int TPi=0;TPi!=tPCH.size();++TPi) { - //get a state in the muon system + //get a state in the muon system TrajectoryStateOnSurface simReferenceState = getState((tPCH)[TPi],*theSimHitsTPAssoc); if (!simReferenceState.isValid()) continue; //propagate the TRACK to the surface TrajectoryStateOnSurface trackReferenceState = thePropagator->propagate(iState,simReferenceState.surface()); - if (!trackReferenceState.isValid()) continue; - + if (!trackReferenceState.isValid()) continue; + //comparison double dQ= quality(trackReferenceState,simReferenceState); if (dQ < theQCut){ @@ -161,9 +161,9 @@ RecoToSimCollection TrackAssociatorByPositionImpl::associateRecoToSim(const edm: -SimToRecoCollection TrackAssociatorByPositionImpl::associateSimToReco(const edm::RefToBaseVector& tCH, +SimToRecoCollection TrackAssociatorByPositionImpl::associateSimToReco(const edm::RefToBaseVector& tCH, const edm::RefVector& tPCH) const { - SimToRecoCollection outputCollection; + SimToRecoCollection outputCollection(productGetter_); //for each tracking particle, find matching tracks. std::pair minPair; @@ -178,19 +178,19 @@ SimToRecoCollection TrackAssociatorByPositionImpl::associateSimToReco(const edm: for (unsigned int TPi=0;TPi!=tPCH.size();++TPi){ //get a state in the muon system TrajectoryStateOnSurface simReferenceState= getState((tPCH)[TPi],*theSimHitsTPAssoc); - - if (!simReferenceState.isValid()) continue; + + if (!simReferenceState.isValid()) continue; bool atLeastOne=false; - // propagate every track from any state (initial, inner, outter) to the surface + // propagate every track from any state (initial, inner, outter) to the surface // and make the position test for (unsigned int Ti=0; Ti!=tCH.size();++Ti){ //initial state FreeTrajectoryState iState = getState(*(tCH)[Ti]); - + //propagation to surface TrajectoryStateOnSurface trackReferenceState = thePropagator->propagate(iState,simReferenceState.surface()); if (!trackReferenceState.isValid()) continue; - + //comparison double dQ= quality(trackReferenceState, simReferenceState); if (dQ < theQCut){ @@ -208,7 +208,7 @@ SimToRecoCollection TrackAssociatorByPositionImpl::associateSimToReco(const edm: outputCollection.insert(tPCH[minPair.first], std::make_pair(tCH[minPair.second],-dQmin));} }//loop over tracking particles - + outputCollection.post_insert(); return outputCollection; } diff --git a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.h b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.h index 2ef14af422fae..5b538732374eb 100644 --- a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.h +++ b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionImpl.h @@ -24,6 +24,10 @@ #include +namespace edm { + class EDProductGetter; +} + //Note that the Association Map is filled with -ch2 and not chi2 because it is ordered using std::greater: //the track with the lowest association chi2 will be the first in the output map. @@ -34,7 +38,8 @@ class TrackAssociatorByPositionImpl : public reco::TrackToTrackingParticleAssoci typedef std::vector SimHitTPAssociationList; enum class Method { chi2, dist, momdr, posdr}; - TrackAssociatorByPositionImpl(const TrackingGeometry* geo, + TrackAssociatorByPositionImpl(edm::EDProductGetter const& productGetter, + const TrackingGeometry* geo, const Propagator* prop, const SimHitTPAssociationList* assocList, double qMinCut, @@ -43,7 +48,8 @@ class TrackAssociatorByPositionImpl : public reco::TrackToTrackingParticleAssoci Method method, bool minIfNoMatch, bool considerAllSimHits): - theGeometry(geo), + productGetter_(&productGetter), + theGeometry(geo), thePropagator(prop), theSimHitsTPAssoc(assocList), theQminCut(qMinCut), @@ -52,15 +58,15 @@ class TrackAssociatorByPositionImpl : public reco::TrackToTrackingParticleAssoci theMethod(method), theMinIfNoMatch(minIfNoMatch), theConsiderAllSimHits(considerAllSimHits) {} - - + + /// compare reco to sim the handle of reco::Track and TrackingParticle collections - + reco::RecoToSimCollection associateRecoToSim(const edm::RefToBaseVector&, const edm::RefVector& ) const override; /// compare reco to sim the handle of reco::Track and TrackingParticle collections - + reco::SimToRecoCollection associateSimToReco(const edm::RefToBaseVector&, const edm::RefVector&) const override; @@ -68,6 +74,9 @@ class TrackAssociatorByPositionImpl : public reco::TrackToTrackingParticleAssoci private: double quality(const TrajectoryStateOnSurface&, const TrajectoryStateOnSurface &)const; + + edm::EDProductGetter const* productGetter_; + const TrackingGeometry * theGeometry; const Propagator * thePropagator; const SimHitTPAssociationList* theSimHitsTPAssoc; @@ -77,7 +86,7 @@ class TrackAssociatorByPositionImpl : public reco::TrackToTrackingParticleAssoci Method theMethod; bool theMinIfNoMatch; bool theConsiderAllSimHits; - + FreeTrajectoryState getState(const reco::Track &) const; TrajectoryStateOnSurface getState(const TrackingParticleRef&, const SimHitTPAssociationList& simHitsTPAssoc)const; //edm::InputTag _simHitTpMapTag; diff --git a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionProducer.cc b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionProducer.cc index 277e6c8dd3cfb..21de947fb2428 100644 --- a/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionProducer.cc +++ b/SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionProducer.cc @@ -2,7 +2,7 @@ // // Package: SimTracker/TrackAssociatorProducers // Class: TrackAssociatorByPositionProducer -// +// /**\class TrackAssociatorByPositionProducer TrackAssociatorByPositionProducer.cc SimTracker/TrackAssociatorProducers/plugins/TrackAssociatorByPositionProducer.cc Description: [one line class summary] @@ -48,7 +48,7 @@ class TrackAssociatorByPositionProducer : public edm::global::EDProducer<> { private: void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; - + // ----------member data --------------------------- edm::EDGetTokenT theSimHitTpMapToken; std::string thePname; @@ -99,7 +99,7 @@ TrackAssociatorByPositionProducer::TrackAssociatorByPositionProducer(const edm:: TrackAssociatorByPositionProducer::~TrackAssociatorByPositionProducer() { - + // do anything here that needs to be done at desctruction time // (e.g. close files, deallocate resources etc.) @@ -121,12 +121,13 @@ TrackAssociatorByPositionProducer::produce(edm::StreamID, edm::Event& iEvent, co edm::ESHandle theP; iSetup.get().get(thePname,theP); - + edm::ESHandle theG; iSetup.get().get(theG); - std::unique_ptr impl{ - new TrackAssociatorByPositionImpl(theG.product(), + std::unique_ptr impl{ + new TrackAssociatorByPositionImpl(iEvent.productGetter(), + theG.product(), theP.product(), assocList.product(), theQminCut, @@ -142,7 +143,7 @@ TrackAssociatorByPositionProducer::produce(edm::StreamID, edm::Event& iEvent, co } - + // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ void TrackAssociatorByPositionProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { diff --git a/Validation/RecoTrack/plugins/MultiTrackValidator.cc b/Validation/RecoTrack/plugins/MultiTrackValidator.cc index bc2342f35f602..b64bde4fa8773 100644 --- a/Validation/RecoTrack/plugins/MultiTrackValidator.cc +++ b/Validation/RecoTrack/plugins/MultiTrackValidator.cc @@ -289,6 +289,7 @@ void MultiTrackValidator::bookHistograms(DQMStore::ConcurrentBooker& ibook, edm: ibook.setCurrentFolder(dirName); const bool doResolutionPlots = doResolutionPlots_[www]; + // const bool doResolutionPlots = true; if(doSimTrackPlots_) { histoProducerAlgo_->bookSimTrackHistos(ibook, histograms.histoProducerAlgo, doResolutionPlots); @@ -1067,13 +1068,17 @@ void MultiTrackValidator::dqmAnalyze(const edm::Event& event, const edm::EventSe */ + // if(doResolutionPlots_[www] || 1) { if(doResolutionPlots_[www]) { //Get tracking particle parameters at point of closest approach to the beamline TrackingParticleRef tpr = tpFound->val.begin()->first; TrackingParticle::Vector momentumTP = parametersDefinerTP->momentum(event,setup,tpr); TrackingParticle::Point vertexTP = parametersDefinerTP->vertex(event,setup,tpr); int chargeTP = tpr->charge(); - + if( doSeedPlots_) std::cout<< "DEBUG SEEDING-----------------------------------------------------------------------> ALGO="<< track->algo() << std::endl; + if (dirName_=="Tracking/jetCoreRegionalStep/") std::cout << "DEBUG direct JETCORE iteration ----------------------------" << std::endl; + std::cout << "directory:"<< dirName_<fill_ResoAndPull_recoTrack_histos(histograms.histoProducerAlgo,w,momentumTP,vertexTP,chargeTP, *track,bs.position()); } @@ -1086,7 +1091,6 @@ void MultiTrackValidator::dqmAnalyze(const edm::Event& event, const edm::EventSe } // End of for(View::size_type i=0; ifill_trackBased_histos(histograms.histoProducerAlgo,w,at,rT, n_selTrack_dr, n_selTP_dr); // Fill seed-specific histograms if(doSeedPlots_) { diff --git a/Validation/RecoTrack/plugins/TrackFromSeedProducer.cc b/Validation/RecoTrack/plugins/TrackFromSeedProducer.cc index 426744bdb07e0..99567e35aba75 100644 --- a/Validation/RecoTrack/plugins/TrackFromSeedProducer.cc +++ b/Validation/RecoTrack/plugins/TrackFromSeedProducer.cc @@ -41,6 +41,8 @@ #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" #include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" +#include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h" // // class declaration @@ -129,17 +131,33 @@ TrackFromSeedProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Eve edm::ESHandle theMF; iSetup.get().get(theMF); + edm::ESHandle httopo; iSetup.get().get(httopo); const TrackerTopology& ttopo = *httopo; + + edm::ESHandle geometry_; + iSetup.get().get(geometry_); + // create tracks from seeds int nfailed = 0; for(size_t iSeed=0; iSeed < seeds.size(); ++iSeed) { + auto const& seed = seeds[iSeed]; // try to create a track + TrajectoryStateOnSurface state; + if(seed.nHits()==0) { //deepCore seeds (jetCoreDirectSeedGenerator) + std::cout << "DEBUG: 0 hit seed " << std::endl; + const Surface *deepCore_sruface = &geometry_->idToDet(seed.startingState().detId())->specificSurface(); + state = trajectoryStateTransform::transientState( seed.startingState(), deepCore_sruface, theMF.product()); + } + else { TransientTrackingRecHit::RecHitPointer lastRecHit = tTRHBuilder->build(&*(seed.recHits().second-1)); - TrajectoryStateOnSurface state = trajectoryStateTransform::transientState( seed.startingState(), lastRecHit->surface(), theMF.product()); + // TrajectoryStateOnSurface state = trajectoryStateTransform::transientState( seed.startingState(), lastRecHit->surface(), theMF.product()); + state = trajectoryStateTransform::transientState( seed.startingState(), lastRecHit->surface(), theMF.product()); + } + TrajectoryStateClosestToBeamLine tsAtClosestApproachSeed = tscblBuilder(*state.freeState(),*beamSpot);//as in TrackProducerAlgorithm if(tsAtClosestApproachSeed.isValid()) { const reco::TrackBase::Point vSeed1(tsAtClosestApproachSeed.trackStateAtPCA().position().x(), @@ -151,11 +169,19 @@ TrackFromSeedProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Eve //GlobalPoint vSeed(vSeed1.x()-beamSpot->x0(),vSeed1.y()-beamSpot->y0(),vSeed1.z()-beamSpot->z0()); PerigeeTrajectoryError seedPerigeeErrors = PerigeeConversions::ftsToPerigeeError(tsAtClosestApproachSeed.trackStateAtPCA()); tracks->emplace_back(0.,0., vSeed1, pSeed, state.charge(), seedPerigeeErrors.covarianceMatrix()); + // std::cout << "DEBUG: SEED VALIDATOR PASSED ------------" << std::endl; + // std::cout << "initial parameters:" << ", inv.Pt=" << state.freeState()->parameters().signedInverseTransverseMomentum() << ", trans.Curv=" <transverseCurvature()<< ", p=" << state.freeState()->momentum().mag() << ", pt=" << state.freeState()->momentum().perp() <<", phi=" <momentum().phi() << ", eta="<momentum().eta() << std::endl; + // std::cout << "initial matrix (diag)=" << std::sqrt(state.freeState()->curvilinearError().matrix()(0, 0)) << " , " << std::sqrt(state.freeState()->curvilinearError().matrix()(1, 1)) << " , " << std::sqrt(state.freeState()->curvilinearError().matrix()(2, 2)) << " , " << std::sqrt(state.freeState()->curvilinearError().matrix()(3, 3)) << " , " << std::sqrt(state.freeState()->curvilinearError().matrix()(4, 4)) << std::endl; + // std::cout << "initial matrix (diag)=" << std::sqrt(state.localError().matrix()(0, 0)) << " , " << std::sqrt(state.localError().matrix()(1, 1)) << " , " << std::sqrt(state.localError().matrix()(2, 2)) << " , " << std::sqrt(state.localError().matrix()(3, 3)) << " , " << std::sqrt(state.localError().matrix()(4, 4)) << std::endl; + // std::cout << "PCA parameters:" << ", inv.Pt=" << tsAtClosestApproachSeed.trackStateAtPCA().parameters().signedInverseTransverseMomentum() << ", trans.Curv=" <emplace_back(-1, -1, reco::TrackBase::Point(), reco::TrackBase::Vector(), 0, reco::TrackBase::CovarianceMatrix()); nfailed++; } diff --git a/Validation/RecoTrack/python/MultiTrackValidator_cfi.py b/Validation/RecoTrack/python/MultiTrackValidator_cfi.py index 66d6f839b8040..c777b21739281 100644 --- a/Validation/RecoTrack/python/MultiTrackValidator_cfi.py +++ b/Validation/RecoTrack/python/MultiTrackValidator_cfi.py @@ -30,6 +30,7 @@ # if False, the src's above should specify the TP-RecoTrack association # if True, the src's above should specify the associator UseAssociators = cms.bool(False), + # UseAssociators = cms.bool(True), ### sim input configuration ### label_tp_effic = cms.InputTag("mix","MergedTrackTruth"), @@ -100,6 +101,7 @@ doResolutionPlotsForLabels = cms.VInputTag(), cores = cms.InputTag("highPtJetsForTrk"), #ak4CaloJets with pt>1 TeV + ) from Configuration.Eras.Modifier_fastSim_cff import fastSim diff --git a/Validation/RecoTrack/python/PostProcessorTracker_cfi.py b/Validation/RecoTrack/python/PostProcessorTracker_cfi.py index 4fb8870bd8de4..9f3e3d199ddd2 100644 --- a/Validation/RecoTrack/python/PostProcessorTracker_cfi.py +++ b/Validation/RecoTrack/python/PostProcessorTracker_cfi.py @@ -2,7 +2,7 @@ from DQMServices.Core.DQMEDHarvester import DQMEDHarvester postProcessorTrack = DQMEDHarvester("DQMGenericClient", - subDirs = cms.untracked.vstring("Tracking/Track/*", "Tracking/TrackTPPtLess09/*", "Tracking/TrackFromPV/*", "Tracking/TrackFromPVAllTP/*", "Tracking/TrackAllTPEffic/*", "Tracking/TrackBuilding/*", "Tracking/TrackConversion/*", "Tracking/TrackGsf/*", "Tracking/TrackBHadron/*"), + subDirs = cms.untracked.vstring("Tracking/Track/*", "Tracking/TrackTPPtLess09/*", "Tracking/TrackFromPV/*", "Tracking/TrackFromPVAllTP/*", "Tracking/TrackAllTPEffic/*", "Tracking/TrackBuilding/*", "Tracking/TrackConversion/*", "Tracking/TrackGsf/*", "Tracking/TrackBHadron/*", "Tracking/jetCoreRegionalStep/*"), efficiency = cms.vstring( "effic 'Efficiency vs #eta' num_assoc(simToReco)_eta num_simul_eta", "efficPt 'Efficiency vs p_{T}' num_assoc(simToReco)_pT num_simul_pT", @@ -254,7 +254,7 @@ def _addNoFlow(module): _addNoFlow(postProcessorTrackNrecVsNsim) postProcessorTrackSummary = DQMEDHarvester("DQMGenericClient", - subDirs = cms.untracked.vstring("Tracking/Track", "Tracking/TrackTPPtLess09", "Tracking/TrackFromPV", "Tracking/TrackFromPVAllTP", "Tracking/TrackAllTPEffic", "Tracking/TrackBuilding", "Tracking/TrackConversion", "Tracking/TrackGsf", "Tracking/TrackBHadron"), + subDirs = cms.untracked.vstring("Tracking/Track", "Tracking/TrackTPPtLess09", "Tracking/TrackFromPV", "Tracking/TrackFromPVAllTP", "Tracking/TrackAllTPEffic", "Tracking/TrackBuilding", "Tracking/TrackConversion", "Tracking/TrackGsf", "Tracking/TrackBHadron", "Tracking/jetCoreRegionalStep"), efficiency = cms.vstring( "effic_vs_coll 'Efficiency vs track collection' num_assoc(simToReco)_coll num_simul_coll", "effic_vs_coll_allPt 'Efficiency vs track collection' num_assoc(simToReco)_coll_allPt num_simul_coll_allPt", diff --git a/Validation/RecoTrack/python/TrackValidation_cff.py b/Validation/RecoTrack/python/TrackValidation_cff.py index 715fd9dbac8cd..911714d4e3591 100644 --- a/Validation/RecoTrack/python/TrackValidation_cff.py +++ b/Validation/RecoTrack/python/TrackValidation_cff.py @@ -1,6 +1,8 @@ import FWCore.ParameterSet.Config as cms -import SimTracker.TrackAssociatorProducers.trackAssociatorByChi2_cfi +# import SimTracker.TrackAssociatorProducers.trackAssociatorByChi2_cfi +from SimTracker.TrackAssociatorProducers.trackAssociatorByChi2_cfi import * +from SimTracker.TrackAssociatorProducers.trackAssociatorByPosition_cfi import * from SimTracker.TrackAssociatorProducers.quickTrackAssociatorByHits_cfi import * from SimTracker.TrackAssociation.trackingParticleRecoTrackAsssociation_cfi import * import Validation.RecoTrack.MultiTrackValidator_cfi @@ -349,16 +351,49 @@ def _getMVASelectors(postfix): ) # Select jets for JetCore tracking -highPtJets = cms.EDFilter("CandPtrSelector", src = cms.InputTag("ak4CaloJets"), cut = cms.string("pt()>1000")) +# highPtJets = cms.EDFilter("CandPtrSelector", src = cms.InputTag("ak4CaloJets"), cut = cms.string("pt()>1000")) #perfectSeeding used in Connecting the Dots +highPtJets = cms.EDFilter("CandPtrSelector", src = cms.InputTag("ak4CaloJets"), cut = cms.string("pt()>1000 && eta()<1.4 && eta()>-1.4")) highPtJetsForTrk = highPtJetsForTrk = highPtJets.clone(src = "ak4CaloJetsForTrk") # Select B-hadron TPs trackingParticlesBHadron = _trackingParticleBHadronRefSelector.clone() +# MTVtrackAssociatorByChi2 = SimTracker.TrackAssociatorProducers.trackAssociatorByChi2_cfi.trackAssociatorByChi2.clone() #maybe modification needed + +MTVTrackAssociationByChi2 = trackingParticleRecoTrackAsssociation.clone( + associator = cms.InputTag('trackAssociatorByChi2'), + # UseAssociators = cms.bool(True) +) + +# associatorByHitLoose = SimTracker.TrackAssociatorProducers.quickTrackAssociatorByHits_cfi.quickTrackAssociatorByHits.clone() +# associatorByHitLoose = quickTrackAssociatorByHits.clone( +# Cut_RecoToSim = cms.double(0.5), +# Quality_SimToReco = cms.double(0.3), +# Purity_SimToReco = cms.double(0.5), +# ThreeHitTracksAreSpecial =cms.bool(False), +# usePixels = cms.bool(False) +# ) + +# MTVTrackAssociationByHitsLoose = trackingParticleRecoTrackAsssociation.clone( +# associator = cms.InputTag('associatorByHitLoose'), +# ) + +# associatorByDeltaR = trackAssociatorByPosition.clone( +# QCut = cms.double(0.01), +# method = cms.string('momdr'), +# ConsiderAllSimHits = cms.bool(False) +# ) +# MTVTrackAssociationByDeltaR = trackingParticleRecoTrackAsssociation.clone( +# associator = cms.InputTag('associatorByDeltaR'), +# # UseAssociators = cms.bool(True) +# ) + + ## MTV instances trackValidator = Validation.RecoTrack.MultiTrackValidator_cfi.multiTrackValidator.clone( useLogPt = cms.untracked.bool(True), dodEdxPlots = True, + associators=cms.untracked.VInputTag('MTVTrackAssociationByChi2'), doPVAssociationPlots = True #,minpT = cms.double(-1) #,maxpT = cms.double(3) @@ -382,6 +417,7 @@ def _getMVASelectors(postfix): locals()["_generalTracksHp"+_postfix], "generalTracksPt09", "cutsRecoTracksBtvLike", + "cutsRecoTracksJetCoreRegionalStepByOriginalAlgo", ] ) _setForEra(trackValidator.histoProducerAlgoBlock, _eraName, _era, seedingLayerSets=locals()["_seedingLayerSets"+_postfix]) @@ -465,7 +501,10 @@ def _getMVASelectors(postfix): ) trackValidatorBuilding = _trackValidatorSeedingBuilding.clone( dirName = "Tracking/TrackBuilding/", + associators = ["trackAssociatorByChi2"], + UseAssociators = True, doMVAPlots = True, + doResolutionPlotsForLabels = ['jetCoreRegionalStepTracks'] ) trackValidatorBuildingPreSplitting = trackValidatorBuilding.clone( associators = ["quickTrackAssociatorByHitsPreSplitting"], @@ -530,7 +569,17 @@ def _uniqueFirstLayers(layerList): for _eraName, _postfix, _era in _relevantEras: _setForEra(trackValidatorGsfTracks.histoProducerAlgoBlock, _eraName, _era, seedingLayerSets=trackValidator.histoProducerAlgoBlock.seedingLayerSets.value()+locals()["_seedingLayerSetsForElectrons"+_postfix]) - +# For jetCore tracks +trackValidatorJetCore = trackValidator.clone( + dirName = "Tracking/jetCoreRegionalStep/", + useLogPt = cms.untracked.bool(True), + dodEdxPlots = False, + associators= ["trackAssociatorByChi2"],#cms.untracked.VInputTag('MTVTrackAssociationByChi2'), + UseAssociators = True, + doPVAssociationPlots = True, + label = ['jetCoreRegionalStepTracks'], + doResolutionPlotsForLabels = ['jetCoreRegionalStepTracks'], +) # for B-hadrons trackValidatorBHadron = trackValidator.clone( @@ -559,6 +608,12 @@ def _uniqueFirstLayers(layerList): tracksValidationTruth = cms.Task( tpClusterProducer, tpClusterProducerPreSplitting, + trackAssociatorByChi2, + # associatorByHitLoose, + # associatorByDeltaR, + # MTVTrackAssociationByHitsLoose, + MTVTrackAssociationByChi2, + # MTVTrackAssociationByDeltaR, quickTrackAssociatorByHits, quickTrackAssociatorByHitsPreSplitting, trackingParticleRecoTrackAsssociation, @@ -720,8 +775,11 @@ def _uniqueFirstLayers(layerList): trackValidatorSeedingTrackingOnly = _trackValidatorSeedingBuilding.clone( dirName = "Tracking/TrackSeeding/", + associators = ["trackAssociatorByChi2"], + UseAssociators = True, label = _seedSelectors, doSeedPlots = True, + doResolutionPlotsForLabels = [ "seedTracksjetCoreRegionalStepSeeds",] ) trackValidatorSeedingPreSplittingTrackingOnly = trackValidatorSeedingTrackingOnly.clone( associators = ["quickTrackAssociatorByHitsPreSplitting"], @@ -758,6 +816,7 @@ def _uniqueFirstLayers(layerList): trackValidatorsTrackingOnly += trackValidatorSeedingPreSplittingTrackingOnly trackValidatorsTrackingOnly += trackValidatorBuilding trackValidatorsTrackingOnly += trackValidatorBuildingPreSplitting +trackValidatorsTrackingOnly += trackValidatorJetCore trackValidatorsTrackingOnly.replace(trackValidatorConversionStandalone, trackValidatorConversionTrackingOnly) trackValidatorsTrackingOnly.remove(trackValidatorGsfTracksStandalone) trackValidatorsTrackingOnly.replace(trackValidatorBHadronStandalone, trackValidatorBHadronTrackingOnly) @@ -819,9 +878,9 @@ def _uniqueFirstLayers(layerList): ## customization for timing from Configuration.Eras.Modifier_phase2_timing_layer_cff import phase2_timing_layer -phase2_timing_layer.toModify( generalTracksFromPV, - timesTag = cms.InputTag('trackTimeValueMapProducer:generalTracksConfigurableFlatResolutionModel'), - timeResosTag = cms.InputTag('trackTimeValueMapProducer:generalTracksConfigurableFlatResolutionModelResolution'), +phase2_timing_layer.toModify( generalTracksFromPV, + timesTag = cms.InputTag('trackTimeValueMapProducer:generalTracksConfigurableFlatResolutionModel'), + timeResosTag = cms.InputTag('trackTimeValueMapProducer:generalTracksConfigurableFlatResolutionModelResolution'), nSigmaDtVertex = cms.double(3) ) phase2_timing_layer.toModify( trackValidatorStandalone, label_vertex = cms.untracked.InputTag('offlinePrimaryVertices4D') ) @@ -836,6 +895,6 @@ def _uniqueFirstLayers(layerList): from Configuration.Eras.Modifier_phase2_timing_layer_tile_cff import phase2_timing_layer_tile from Configuration.Eras.Modifier_phase2_timing_layer_bar_cff import phase2_timing_layer_bar -(phase2_timing_layer_tile | phase2_timing_layer_bar).toModify( generalTracksFromPV, - timesTag = cms.InputTag('tofPID:t0'), +(phase2_timing_layer_tile | phase2_timing_layer_bar).toModify( generalTracksFromPV, + timesTag = cms.InputTag('tofPID:t0'), timeResosTag = cms.InputTag('tofPID:sigmat0') ) diff --git a/Validation/RecoTrack/python/associators_cff.py b/Validation/RecoTrack/python/associators_cff.py index 73c6f416e509c..6bfd14512b112 100644 --- a/Validation/RecoTrack/python/associators_cff.py +++ b/Validation/RecoTrack/python/associators_cff.py @@ -2,6 +2,7 @@ #### TrackAssociation import SimTracker.TrackAssociatorProducers.quickTrackAssociatorByHits_cfi +import SimTracker.TrackAssociatorProducers.trackAssociatorByChi2_cfi import SimTracker.TrackAssociatorProducers.trackAssociatorByPosition_cfi from SimTracker.TrackerHitAssociation.tpClusterProducer_cfi import tpClusterProducer as _tpClusterProducer from SimTracker.TrackAssociation.trackingParticleRecoTrackAsssociation_cfi import trackingParticleRecoTrackAsssociation as _trackingParticleRecoTrackAsssociation @@ -18,6 +19,11 @@ hltTrackAssociatorByHits.UseSplitting = cms.bool( False ) hltTrackAssociatorByHits.ThreeHitTracksAreSpecial = cms.bool( False ) +#NOT BY HIT NOW!!! uncomment lines 16-20 to do byhits +# hltTrackAssociatorByHits = SimTracker.TrackAssociatorProducers.trackAssociatorByChi2_cfi.trackAssociatorByChi2.clone() + + + hltTrackAssociatorByDeltaR = SimTracker.TrackAssociatorProducers.trackAssociatorByPosition_cfi.trackAssociatorByPosition.clone() hltTrackAssociatorByDeltaR.method = cms.string('momdr') hltTrackAssociatorByDeltaR.QCut = cms.double(0.5) diff --git a/Validation/RecoTrack/src/MTVHistoProducerAlgoForTracker.cc b/Validation/RecoTrack/src/MTVHistoProducerAlgoForTracker.cc index 49b28ea4109c9..f523d74491b41 100644 --- a/Validation/RecoTrack/src/MTVHistoProducerAlgoForTracker.cc +++ b/Validation/RecoTrack/src/MTVHistoProducerAlgoForTracker.cc @@ -207,25 +207,25 @@ MTVHistoProducerAlgoForTracker::MTVHistoProducerAlgoForTracker(const edm::Parame nintMVA = pset.getParameter("nintMVA"); //parameters for resolution plots - ptRes_rangeMin = pset.getParameter("ptRes_rangeMin"); - ptRes_rangeMax = pset.getParameter("ptRes_rangeMax"); - ptRes_nbin = pset.getParameter("ptRes_nbin"); + ptRes_rangeMin = 10*pset.getParameter("ptRes_rangeMin"); + ptRes_rangeMax = 10*pset.getParameter("ptRes_rangeMax"); + ptRes_nbin = 10*pset.getParameter("ptRes_nbin"); - phiRes_rangeMin = pset.getParameter("phiRes_rangeMin"); - phiRes_rangeMax = pset.getParameter("phiRes_rangeMax"); - phiRes_nbin = pset.getParameter("phiRes_nbin"); + phiRes_rangeMin = 10*pset.getParameter("phiRes_rangeMin"); + phiRes_rangeMax = 10*pset.getParameter("phiRes_rangeMax"); + phiRes_nbin = 10*pset.getParameter("phiRes_nbin"); - cotThetaRes_rangeMin = pset.getParameter("cotThetaRes_rangeMin"); - cotThetaRes_rangeMax = pset.getParameter("cotThetaRes_rangeMax"); - cotThetaRes_nbin = pset.getParameter("cotThetaRes_nbin"); + cotThetaRes_rangeMin = 10*pset.getParameter("cotThetaRes_rangeMin"); + cotThetaRes_rangeMax = 10*pset.getParameter("cotThetaRes_rangeMax"); + cotThetaRes_nbin = 10*pset.getParameter("cotThetaRes_nbin"); - dxyRes_rangeMin = pset.getParameter("dxyRes_rangeMin"); - dxyRes_rangeMax = pset.getParameter("dxyRes_rangeMax"); - dxyRes_nbin = pset.getParameter("dxyRes_nbin"); + dxyRes_rangeMin = 10*pset.getParameter("dxyRes_rangeMin"); + dxyRes_rangeMax = 10*pset.getParameter("dxyRes_rangeMax"); + dxyRes_nbin = 10*pset.getParameter("dxyRes_nbin"); - dzRes_rangeMin = pset.getParameter("dzRes_rangeMin"); - dzRes_rangeMax = pset.getParameter("dzRes_rangeMax"); - dzRes_nbin = pset.getParameter("dzRes_nbin"); + dzRes_rangeMin = 10*pset.getParameter("dzRes_rangeMin"); + dzRes_rangeMax = 10*pset.getParameter("dzRes_rangeMax"); + dzRes_nbin = 10*pset.getParameter("dzRes_nbin"); maxDzpvCum = pset.getParameter("maxDzpvCumulative"); @@ -1402,6 +1402,17 @@ void MTVHistoProducerAlgoForTracker::fill_ResoAndPull_recoTrack_histos(const His double phiPull=phiRes/phiErrorRec; double dxyPull=dxyRes/track.dxyError(); double dzPull=dzRes/track.dzError(); + + // if(track.algo()==0) + // std::cout << "reco track par:" <<"pt="<