Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:40:24

0001 from __future__ import absolute_import
0002 from builtins import range
0003 import os
0004 import random
0005 
0006 from . import globalDictionaries
0007 from . import configTemplates
0008 
0009 from .genericValidation import ValidationMetaClass, ValidationWithComparison, ValidationWithPlots
0010 from .helperFunctions import getCommandOutput2, replaceByMap, cppboolstring
0011 from .offlineValidation import OfflineValidation
0012 from .primaryVertexValidation import PrimaryVertexValidation
0013 from .primaryVertexResolution import PrimaryVertexResolution
0014 from .TkAlExceptions import AllInOneError
0015 from .trackSplittingValidation import TrackSplittingValidation
0016 from .zMuMuValidation import ZMuMuValidation
0017 from .overlapValidation import OverlapValidation
0018 
0019 class BasePlottingOptions(object, metaclass=ValidationMetaClass):
0020     defaults = {
0021                 "cmssw" : os.environ["CMSSW_BASE"],
0022                 "publicationstatus" : "",
0023                 "customtitle" : "",
0024                 "customrighttitle" : "",
0025                 "era" : "NONE",
0026                 "legendheader" : "",
0027                 "legendoptions":"all",
0028                }
0029     mandatories = set()
0030     needpackages = {"Alignment/OfflineValidation"}
0031     def __init__(self, config, valType):
0032         import random
0033         self.type = valType
0034         self.general = config.getGeneral()
0035         self.randomWorkdirPart = "%0i"%random.randint(1,10e9)
0036         self.config = config
0037 
0038         theUpdate = config.getResultingSection("plots:"+self.type,
0039                                                defaultDict = self.defaults,
0040                                                demandPars = self.mandatories)
0041         self.general.update(theUpdate)
0042 
0043         self.cmssw = self.general["cmssw"]
0044         badcharacters = r"\'"
0045         for character in badcharacters:
0046             if character in self.cmssw:
0047                 raise AllInOneError("The bad characters " + badcharacters + " are not allowed in the cmssw\n"
0048                                     "path name.  If you really have it in such a ridiculously named location,\n"
0049                                     "try making a symbolic link somewhere with a decent name.")
0050         try:
0051             os.listdir(self.cmssw)
0052         except OSError:
0053             raise AllInOneError("Your cmssw release " + self.cmssw + ' does not exist')
0054 
0055         if self.cmssw == os.environ["CMSSW_BASE"]:
0056             self.scramarch = os.environ["SCRAM_ARCH"]
0057             self.cmsswreleasebase = os.environ["CMSSW_RELEASE_BASE"]
0058         else:
0059             command = ("cd '" + self.cmssw + "' && eval `scramv1 ru -sh 2> /dev/null`"
0060                        ' && echo "$CMSSW_BASE\n$SCRAM_ARCH\n$CMSSW_RELEASE_BASE"')
0061             commandoutput = getCommandOutput2(command).split('\n')
0062             self.cmssw = commandoutput[0]
0063             self.scramarch = commandoutput[1]
0064             self.cmsswreleasebase = commandoutput[2]
0065 
0066         for package in self.needpackages:
0067             for placetolook in self.cmssw, self.cmsswreleasebase:
0068                 pkgpath = os.path.join(placetolook, "src", package)
0069                 if os.path.exists(pkgpath):
0070                     self.general[package] = pkgpath
0071                     break
0072             else:
0073                 raise AllInOneError("Package {} does not exist in {} or {}!".format(package, self.cmssw, self.cmsswreleasebase))
0074 
0075         self.general["publicationstatus"] = self.general["publicationstatus"].upper()
0076         self.general["era"] = self.general["era"].upper()
0077 
0078         if not self.general["publicationstatus"] and not self.general["customtitle"]:
0079             self.general["publicationstatus"] = "INTERNAL"
0080         if self.general["customtitle"] and not self.general["publicationstatus"]:
0081             self.general["publicationstatus"] = "CUSTOM"
0082 
0083         if self.general["publicationstatus"] != "CUSTOM" and self.general["customtitle"]:
0084             raise AllInOneError("If you would like to use a custom title, please leave out the 'publicationstatus' parameter")
0085         if self.general["publicationstatus"] == "CUSTOM" and not self.general["customtitle"]:
0086             raise AllInOneError("If you want to use a custom title, you should provide it using 'customtitle' in the [plots:%s] section" % valType)
0087 
0088         if self.general["era"] != "NONE" and self.general["customrighttitle"]:
0089             raise AllInOneError("If you would like to use a custom right title, please leave out the 'era' parameter")
0090 
0091         publicationstatusenum = ["INTERNAL", "INTERNAL_SIMULATION", "PRELIMINARY", "PUBLIC", "SIMULATION", "UNPUBLISHED", "CUSTOM"]
0092         eraenum = ["NONE", "CRUZET15", "CRAFT15", "COLL0T15"]
0093         if self.general["publicationstatus"] not in publicationstatusenum:
0094             raise AllInOneError("Publication status must be one of " + ", ".join(publicationstatusenum) + "!")
0095         if self.general["era"] not in eraenum:
0096             raise AllInOneError("Era must be one of " + ", ".join(eraenum) + "!")
0097 
0098         knownOpts = set(self.defaults.keys())|self.mandatories|self.optionals
0099         ignoreOpts = []
0100         config.checkInput("plots:"+self.type,
0101                           knownSimpleOptions = knownOpts,
0102                           ignoreOptions = ignoreOpts)
0103 
0104     def getRepMap(self):
0105         result = self.general
0106         result.update({
0107                 "workdir": os.path.join(self.general["workdir"],
0108                                         self.randomWorkdirPart),
0109                 "datadir": self.general["datadir"],
0110                 "logdir": self.general["logdir"],
0111                 "CMSSW_BASE": self.cmssw,
0112                 "SCRAM_ARCH": self.scramarch,
0113                 "CMSSW_RELEASE_BASE": self.cmsswreleasebase,
0114                 "validationId": self.validationclass.__name__,
0115                 })
0116         if issubclass(self.validationclass, ValidationWithPlots):
0117             result["plottingscriptname"] = self.validationclass.plottingscriptname()
0118             result["plottingscriptpath"] = ".oO[scriptsdir]Oo./.oO[plottingscriptname]Oo."
0119             result["PlotsDirName"] = self.validationclass.plotsdirname()
0120         if issubclass(self.validationclass, ValidationWithComparison):
0121             result["compareAlignmentsPath"] = self.validationclass.comparealignmentspath()
0122             result["compareAlignmentsName"] = self.validationclass.comparealignmentsname()
0123         return result
0124 
0125 class PlottingOptionsTrackSplitting(BasePlottingOptions):
0126     defaults = {
0127                 "outliercut": "-1.0",
0128                 "subdetector": "none",
0129                }
0130     needpackages = {"Alignment/CommonAlignmentProducer"}
0131     validationclass = TrackSplittingValidation
0132     def __init__(self, config):
0133         super(PlottingOptionsTrackSplitting, self).__init__(config, "split")
0134         validsubdets = self.validsubdets()
0135         if self.general["subdetector"] not in validsubdets:
0136             raise AllInOneError("'%s' is not a valid subdetector!\n" % self.general["subdetector"] + "The options are: " + ", ".join(validsubdets))
0137 
0138     def validsubdets(self):
0139         filename = replaceByMap(".oO[Alignment/CommonAlignmentProducer]Oo./python/AlignmentTrackSelector_cfi.py", self.getRepMap())
0140         with open(filename) as f:
0141             trackselector = f.read()
0142 
0143         minhitspersubdet = trackselector.split("minHitsPerSubDet")[1].split("(",1)[1]
0144 
0145         parenthesesdepth = 0
0146         i = 0
0147         for character in minhitspersubdet:
0148             if character == "(":
0149                 parenthesesdepth += 1
0150             if character == ")":
0151                 parenthesesdepth -= 1
0152             if parenthesesdepth < 0:
0153                 break
0154             i += 1
0155         minhitspersubdet = minhitspersubdet[0:i]
0156 
0157         results = minhitspersubdet.split(",")
0158         empty = []
0159         for i in range(len(results)):
0160             results[i] = results[i].split("=")[0].strip().replace("in", "", 1)
0161 
0162         results.append("none")
0163 
0164         return [a for a in results if a]
0165 
0166 class PlottingOptionsZMuMu(BasePlottingOptions):
0167     defaults = {
0168                 "resonance": "Z",
0169                 "switchONfit": "false",
0170                 "rebinphi": "4",
0171                 "rebinetadiff": "2",
0172                 "rebineta": "2",
0173                 "rebinpt": "8",
0174                 "AutoSetRange": "false",                
0175                }
0176     needpackages = {"MuonAnalysis/MomentumScaleCalibration"}
0177     validationclass = ZMuMuValidation
0178     def __init__(self, config):
0179         super(PlottingOptionsZMuMu, self).__init__(config, "zmumu")
0180         self.general["switchONfit"] = cppboolstring(self.general["switchONfit"], "switchONfit")
0181 
0182 class PlottingOptionsOffline(BasePlottingOptions):
0183     defaults = {
0184                 "DMRMethod":"median,rmsNorm",
0185                 "DMRMinimum":"30",
0186                 "DMROptions":"",
0187                 "OfflineTreeBaseDir":"TrackHitFilter",
0188                 "SurfaceShapes":"coarse",
0189                 "bigtext":"false",
0190                 "mergeOfflineParJobsScriptPath": ".oO[scriptsdir]Oo./TkAlOfflineJobsMerge.C",
0191                 "usefit": "false","moduleid": ""
0192                }
0193     validationclass = OfflineValidation
0194     def __init__(self, config):
0195         super(PlottingOptionsOffline, self).__init__(config, "offline")
0196         for name in "usefit", "bigtext":
0197             self.general[name] = cppboolstring(self.general[name], name)
0198 
0199 
0200 class PlottingOptionsPrimaryVertex(BasePlottingOptions):
0201     defaults = {
0202                 "autoLimits":"false",
0203                 "doMaps":"false",
0204                 "stdResiduals":"true",
0205                 "m_dxyPhiMax":"40",
0206                 "m_dzPhiMax":"40",
0207                 "m_dxyEtaMax":"40",
0208                 "m_dzEtaMax":"40",
0209                 "m_dxyPhiNormMax":"0.5",
0210                 "m_dzPhiNormMax":"0.5",
0211                 "m_dxyEtaNormMax":"0.5",
0212                 "m_dzEtaNormMax":"0.5",
0213                 "w_dxyPhiMax":"150",
0214                 "w_dzPhiMax":"150",
0215                 "w_dxyEtaMax":"150",
0216                 "w_dzEtaMax":"1000",
0217                 "w_dxyPhiNormMax":"1.8",
0218                 "w_dzPhiNormMax":"1.8",
0219                 "w_dxyEtaNormMax":"1.8",
0220                 "w_dzEtaNormMax":"1.8",
0221                 }
0222     validationclass = PrimaryVertexValidation
0223     def __init__(self, config):
0224         super(PlottingOptionsPrimaryVertex, self).__init__(config, "primaryvertex")
0225         for name in "autoLimits", "doMaps", "stdResiduals":
0226             self.general[name] = cppboolstring(self.general[name], name)
0227 
0228 class PlottingOptionsOverlap(BasePlottingOptions):
0229     validationclass = OverlapValidation
0230     def __init__(self, config):
0231         super(PlottingOptionsOverlap, self).__init__(config, "overlap")
0232 
0233 class PlottingOptionsPVResolution(BasePlottingOptions):
0234     defaults = {}
0235     validationclass = PrimaryVertexResolution
0236     def __init__(self, config):
0237         super(PlottingOptionsPVResolution, self).__init__(config, "pvresolution")
0238 
0239 def PlottingOptions(config, valType):
0240     plottingOptionsClasses = {
0241                               "offline": PlottingOptionsOffline,
0242                               "split": PlottingOptionsTrackSplitting,
0243                               "zmumu": PlottingOptionsZMuMu,
0244                               "primaryvertex": PlottingOptionsPrimaryVertex,
0245                               "overlap": PlottingOptionsOverlap,
0246                               "pvresolution": PlottingOptionsPVResolution,
0247                              }
0248     if isinstance(valType, type):
0249         valType = valType.valType
0250 
0251     if valType not in globalDictionaries.plottingOptions:
0252         if config is None:
0253             raise ValueError("Have to provide a config the first time you call PlottingOptions for {}".format(valType))
0254         globalDictionaries.plottingOptions[valType] = plottingOptionsClasses[valType](config)
0255     return globalDictionaries.plottingOptions[valType].getRepMap()
0256 
0257 
0258