CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 .primaryVertexResolution import PrimaryVertexResolution
14 from .TkAlExceptions import AllInOneError
15 from .trackSplittingValidation import TrackSplittingValidation
16 from .zMuMuValidation import ZMuMuValidation
17 from .overlapValidation import OverlapValidation
18 
19 class BasePlottingOptions(object, 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 
234  defaults = {}
235  validationclass = PrimaryVertexResolution
236  def __init__(self, config):
237  super(PlottingOptionsPVResolution, self).__init__(config, "pvresolution")
238 
239 def PlottingOptions(config, valType):
240  plottingOptionsClasses = {
241  "offline": PlottingOptionsOffline,
242  "split": PlottingOptionsTrackSplitting,
243  "zmumu": PlottingOptionsZMuMu,
244  "primaryvertex": PlottingOptionsPrimaryVertex,
245  "overlap": PlottingOptionsOverlap,
246  "pvresolution": PlottingOptionsPVResolution,
247  }
248  if isinstance(valType, type):
249  valType = valType.valType
250 
251  if valType not in globalDictionaries.plottingOptions:
252  if config is None:
253  raise ValueError("Have to provide a config the first time you call PlottingOptions for {}".format(valType))
254  globalDictionaries.plottingOptions[valType] = plottingOptionsClasses[valType](config)
255  return globalDictionaries.plottingOptions[valType].getRepMap()
256 
257 
258 
const uint16_t range(const Frame &aFrame)
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
def replaceByMap
— Helpers —############################