CMS 3D CMS Logo

plottingOptions.py
Go to the documentation of this file.
1 from __future__ import absolute_import
2 from builtins import range
3 import os
4 import random
5 
6 from . import globalDictionaries
7 from . import configTemplates
8 
9 from .genericValidation import ValidationMetaClass, ValidationWithComparison, ValidationWithPlots
10 from .helperFunctions import getCommandOutput2, replaceByMap, cppboolstring
11 from .offlineValidation import OfflineValidation
12 from .primaryVertexValidation import PrimaryVertexValidation
13 from .TkAlExceptions import AllInOneError
14 from .trackSplittingValidation import TrackSplittingValidation
15 from .zMuMuValidation import ZMuMuValidation
16 from .overlapValidation import OverlapValidation
17 
19  __metaclass__ = ValidationMetaClass
20  defaults = {
21  "cmssw" : os.environ["CMSSW_BASE"],
22  "publicationstatus" : "",
23  "customtitle" : "",
24  "customrighttitle" : "",
25  "era" : "NONE",
26  "legendheader" : "",
27  "legendoptions":"all",
28  }
29  mandatories = set()
30  needpackages = {"Alignment/OfflineValidation"}
31  def __init__(self, config, valType):
32  import random
33  self.type = valType
34  self.general = config.getGeneral()
35  self.randomWorkdirPart = "%0i"%random.randint(1,10e9)
36  self.config = config
37 
38  theUpdate = config.getResultingSection("plots:"+self.type,
39  defaultDict = self.defaults,
40  demandPars = self.mandatories)
41  self.general.update(theUpdate)
42 
43  self.cmssw = self.general["cmssw"]
44  badcharacters = r"\'"
45  for character in badcharacters:
46  if character in self.cmssw:
47  raise AllInOneError("The bad characters " + badcharacters + " are not allowed in the cmssw\n"
48  "path name. If you really have it in such a ridiculously named location,\n"
49  "try making a symbolic link somewhere with a decent name.")
50  try:
51  os.listdir(self.cmssw)
52  except OSError:
53  raise AllInOneError("Your cmssw release " + self.cmssw + ' does not exist')
54 
55  if self.cmssw == os.environ["CMSSW_BASE"]:
56  self.scramarch = os.environ["SCRAM_ARCH"]
57  self.cmsswreleasebase = os.environ["CMSSW_RELEASE_BASE"]
58  else:
59  command = ("cd '" + self.cmssw + "' && eval `scramv1 ru -sh 2> /dev/null`"
60  ' && echo "$CMSSW_BASE\n$SCRAM_ARCH\n$CMSSW_RELEASE_BASE"')
61  commandoutput = getCommandOutput2(command).split('\n')
62  self.cmssw = commandoutput[0]
63  self.scramarch = commandoutput[1]
64  self.cmsswreleasebase = commandoutput[2]
65 
66  for package in self.needpackages:
67  for placetolook in self.cmssw, self.cmsswreleasebase:
68  pkgpath = os.path.join(placetolook, "src", package)
69  if os.path.exists(pkgpath):
70  self.general[package] = pkgpath
71  break
72  else:
73  raise AllInOneError("Package {} does not exist in {} or {}!".format(package, self.cmssw, self.cmsswreleasebase))
74 
75  self.general["publicationstatus"] = self.general["publicationstatus"].upper()
76  self.general["era"] = self.general["era"].upper()
77 
78  if not self.general["publicationstatus"] and not self.general["customtitle"]:
79  self.general["publicationstatus"] = "INTERNAL"
80  if self.general["customtitle"] and not self.general["publicationstatus"]:
81  self.general["publicationstatus"] = "CUSTOM"
82 
83  if self.general["publicationstatus"] != "CUSTOM" and self.general["customtitle"]:
84  raise AllInOneError("If you would like to use a custom title, please leave out the 'publicationstatus' parameter")
85  if self.general["publicationstatus"] == "CUSTOM" and not self.general["customtitle"]:
86  raise AllInOneError("If you want to use a custom title, you should provide it using 'customtitle' in the [plots:%s] section" % valType)
87 
88  if self.general["era"] != "NONE" and self.general["customrighttitle"]:
89  raise AllInOneError("If you would like to use a custom right title, please leave out the 'era' parameter")
90 
91  publicationstatusenum = ["INTERNAL", "INTERNAL_SIMULATION", "PRELIMINARY", "PUBLIC", "SIMULATION", "UNPUBLISHED", "CUSTOM"]
92  eraenum = ["NONE", "CRUZET15", "CRAFT15", "COLL0T15"]
93  if self.general["publicationstatus"] not in publicationstatusenum:
94  raise AllInOneError("Publication status must be one of " + ", ".join(publicationstatusenum) + "!")
95  if self.general["era"] not in eraenum:
96  raise AllInOneError("Era must be one of " + ", ".join(eraenum) + "!")
97 
98  knownOpts = set(self.defaults.keys())|self.mandatories|self.optionals
99  ignoreOpts = []
100  config.checkInput("plots:"+self.type,
101  knownSimpleOptions = knownOpts,
102  ignoreOptions = ignoreOpts)
103 
104  def getRepMap(self):
105  result = self.general
106  result.update({
107  "workdir": os.path.join(self.general["workdir"],
108  self.randomWorkdirPart),
109  "datadir": self.general["datadir"],
110  "logdir": self.general["logdir"],
111  "CMSSW_BASE": self.cmssw,
112  "SCRAM_ARCH": self.scramarch,
113  "CMSSW_RELEASE_BASE": self.cmsswreleasebase,
114  "validationId": self.validationclass.__name__,
115  })
116  if issubclass(self.validationclass, ValidationWithPlots):
117  result["plottingscriptname"] = self.validationclass.plottingscriptname()
118  result["plottingscriptpath"] = ".oO[scriptsdir]Oo./.oO[plottingscriptname]Oo."
119  result["PlotsDirName"] = self.validationclass.plotsdirname()
120  if issubclass(self.validationclass, ValidationWithComparison):
121  result["compareAlignmentsPath"] = self.validationclass.comparealignmentspath()
122  result["compareAlignmentsName"] = self.validationclass.comparealignmentsname()
123  return result
124 
126  defaults = {
127  "outliercut": "-1.0",
128  "subdetector": "none",
129  }
130  needpackages = {"Alignment/CommonAlignmentProducer"}
131  validationclass = TrackSplittingValidation
132  def __init__(self, config):
133  super(PlottingOptionsTrackSplitting, self).__init__(config, "split")
134  validsubdets = self.validsubdets()
135  if self.general["subdetector"] not in validsubdets:
136  raise AllInOneError("'%s' is not a valid subdetector!\n" % self.general["subdetector"] + "The options are: " + ", ".join(validsubdets))
137 
138  def validsubdets(self):
139  filename = replaceByMap(".oO[Alignment/CommonAlignmentProducer]Oo./python/AlignmentTrackSelector_cfi.py", self.getRepMap())
140  with open(filename) as f:
141  trackselector = f.read()
142 
143  minhitspersubdet = trackselector.split("minHitsPerSubDet")[1].split("(",1)[1]
144 
145  parenthesesdepth = 0
146  i = 0
147  for character in minhitspersubdet:
148  if character == "(":
149  parenthesesdepth += 1
150  if character == ")":
151  parenthesesdepth -= 1
152  if parenthesesdepth < 0:
153  break
154  i += 1
155  minhitspersubdet = minhitspersubdet[0:i]
156 
157  results = minhitspersubdet.split(",")
158  empty = []
159  for i in range(len(results)):
160  results[i] = results[i].split("=")[0].strip().replace("in", "", 1)
161 
162  results.append("none")
163 
164  return [a for a in results if a]
165 
167  defaults = {
168  "resonance": "Z",
169  "switchONfit": "false",
170  "rebinphi": "4",
171  "rebinetadiff": "2",
172  "rebineta": "2",
173  "rebinpt": "8",
174  "AutoSetRange": "false",
175  }
176  needpackages = {"MuonAnalysis/MomentumScaleCalibration"}
177  validationclass = ZMuMuValidation
178  def __init__(self, config):
179  super(PlottingOptionsZMuMu, self).__init__(config, "zmumu")
180  self.general["switchONfit"] = cppboolstring(self.general["switchONfit"], "switchONfit")
181 
183  defaults = {
184  "DMRMethod":"median,rmsNorm",
185  "DMRMinimum":"30",
186  "DMROptions":"",
187  "OfflineTreeBaseDir":"TrackHitFilter",
188  "SurfaceShapes":"coarse",
189  "bigtext":"false",
190  "mergeOfflineParJobsScriptPath": ".oO[scriptsdir]Oo./TkAlOfflineJobsMerge.C",
191  "usefit": "false","moduleid": ""
192  }
193  validationclass = OfflineValidation
194  def __init__(self, config):
195  super(PlottingOptionsOffline, self).__init__(config, "offline")
196  for name in "usefit", "bigtext":
197  self.general[name] = cppboolstring(self.general[name], name)
198 
199 
201  defaults = {
202  "autoLimits":"false",
203  "doMaps":"false",
204  "stdResiduals":"true",
205  "m_dxyPhiMax":"40",
206  "m_dzPhiMax":"40",
207  "m_dxyEtaMax":"40",
208  "m_dzEtaMax":"40",
209  "m_dxyPhiNormMax":"0.5",
210  "m_dzPhiNormMax":"0.5",
211  "m_dxyEtaNormMax":"0.5",
212  "m_dzEtaNormMax":"0.5",
213  "w_dxyPhiMax":"150",
214  "w_dzPhiMax":"150",
215  "w_dxyEtaMax":"150",
216  "w_dzEtaMax":"1000",
217  "w_dxyPhiNormMax":"1.8",
218  "w_dzPhiNormMax":"1.8",
219  "w_dxyEtaNormMax":"1.8",
220  "w_dzEtaNormMax":"1.8",
221  }
222  validationclass = PrimaryVertexValidation
223  def __init__(self, config):
224  super(PlottingOptionsPrimaryVertex, self).__init__(config, "primaryvertex")
225  for name in "autoLimits", "doMaps", "stdResiduals":
226  self.general[name] = cppboolstring(self.general[name], name)
227 
229  validationclass = OverlapValidation
230  def __init__(self, config):
231  super(PlottingOptionsOverlap, self).__init__(config, "overlap")
232 
233 def PlottingOptions(config, valType):
234  plottingOptionsClasses = {
235  "offline": PlottingOptionsOffline,
236  "split": PlottingOptionsTrackSplitting,
237  "zmumu": PlottingOptionsZMuMu,
238  "primaryvertex": PlottingOptionsPrimaryVertex,
239  "overlap": PlottingOptionsOverlap
240  }
241  if isinstance(valType, type):
242  valType = valType.valType
243 
244  if valType not in globalDictionaries.plottingOptions:
245  if config is None:
246  raise ValueError("Have to provide a config the first time you call PlottingOptions for {}".format(valType))
247  globalDictionaries.plottingOptions[valType] = plottingOptionsClasses[valType](config)
248  return globalDictionaries.plottingOptions[valType].getRepMap()
249 
250 
251 
std::vector< std::string_view > split(std::string_view, const char *)
def replace(string, replacements)
def getCommandOutput2(command)
def cppboolstring(string, name)
def __init__(self, config, valType)
def PlottingOptions(config, valType)
def replaceByMap(target, the_map)
— Helpers —############################
static std::string join(char **cmd)
Definition: RemoteFile.cc:17