ATLAS Offline Software
Loading...
Searching...
No Matches
GenericMonitoringTool Namespace Reference

Classes

class  GenericMonitoringArray
class  GenericMonitoringTool

Functions

 _invalidName (flags, name)
 Check if name is an allowed histogram/branch name.
 _alias (varname)
 Generate an alias for a set of variables.
 _validateOptions (user, default)
 Validate user inputs for "opt" argument of defineHistogram.
 _options (opt)
 Generate dictionary entries for opt strings.
 defineHistogram (flags, varname, type='TH1F', path=None, title=None, weight=None, xbins=100, xmin=0, xmax=1, xlabels=None, ybins=None, ymin=None, ymax=None, ylabels=None, zmin=None, zmax=None, zlabels=None, opt=None, convention=None, cutmask=None, treedef=None, merge=None)
 Generate histogram definition string for the GenericMonitoringTool.Histograms property.
 defineTree (flags, varname, treedef, path=None, title=None, opt='', convention=None, cutmask=None)
 Generate tree definition string for the GenericMonitoringTool.Histograms property.

Function Documentation

◆ _alias()

GenericMonitoringTool._alias ( varname)
protected

Generate an alias for a set of variables.

A helper function is useful for this operation, since it is used both by the module function defineHistogram, as well as by the GenericMonitoringArray defineHistogram member function.

Parameters
varnameunparsed
Returns
varList, alias

Definition at line 199 of file GenericMonitoringTool.py.

199def _alias(varname):
200 variableAliasSplit = varname.split(';')
201 varList = [v.strip() for v in variableAliasSplit[0].split(',')]
202 if len(variableAliasSplit)==1:
203 return varList, '_vs_'.join(reversed(varList))
204 elif len(variableAliasSplit)==2:
205 return varList, variableAliasSplit[1]
206 else:
207 message = 'Invalid variable or alias for {}. Histogram(s) not defined.'
208 log.warning(message.format(varname))
209 return None, None
210
211
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177

◆ _invalidName()

GenericMonitoringTool._invalidName ( flags,
name )
protected

Check if name is an allowed histogram/branch name.

Certain characers are best avoided in ROOT histogram names as it makes interactive use awkward. Also there are additional constraints from OH and MDA archiving for online running (ATR-15173).

Parameters
flagsconfiguration flags
namestring to check
Returns
set of forbidden characters found

Definition at line 185 of file GenericMonitoringTool.py.

185def _invalidName(flags, name):
186 blocklist = '/\\'
187 if flags.Common.isOnline:
188 blocklist += '=,:.()'
189 return set(name).intersection(blocklist)
190
191
STL class.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)

◆ _options()

GenericMonitoringTool._options ( opt)
protected

Generate dictionary entries for opt strings.

Parameters
optstring or dictionary specifying type
Returns
dictionary full of options

Definition at line 238 of file GenericMonitoringTool.py.

238def _options(opt):
239 # Set the default dictionary of options
240 settings = {
241 'Sumw2': False, # store sum of squares of weights
242 'kLBNHistoryDepth': 0, # length of lumiblock history
243 'kAddBinsDynamically': False, # add new bins if fill is outside axis range
244 'kRebinAxes': False, # increase axis range without adding new bins
245 'kCanRebin': False, # allow all axes to be rebinned
246 'kVec': False, # add content to each bin from each element of a vector
247 'kVecUO': False, # same as above, but use 0th(last) element for underflow(overflow)
248 'kCumulative': False, # fill bin of monitored object's value, and every bin below it
249 'kLive': 0, # plot only the last N lumiblocks on y_vs_LB plots
250 'kAlwaysCreate': False # create the histogram, even if it is empty
251 }
252 if opt is None:
253 # If no options are provided, skip any further checks.
254 pass
255 elif isinstance(opt, dict):
256 # If the user provides a partial dictionary, update the default with user's.
257 _validateOptions(opt, settings) # check validity of user's options
258 settings.update(opt) # update the default dictionary
259 elif isinstance(opt, str) and len(opt)>0:
260 # If the user provides a comma- or space-separated string of options.
261 settings = _options (opt.replace(',',' ').split())
262
263 elif isinstance(opt,str):
264 # empty string case
265 pass
266 elif isinstance(opt, list):
267 # process each item in list
268 unknown = []
269 for o in opt:
270 kv = o.split('=', maxsplit=1)
271 key = kv[0]
272 if len(kv)==2:
273 value = False if kv[1]=='False' else int(kv[1]) # only bool and int supported
274 else:
275 value = True
276 if key in settings:
277 assert(type(settings[key])==type(value)) # ensure same type as in defaults
278 settings[key] = value
279 else:
280 unknown.append(key)
281
282 assert len(unknown)==0, f'Unknown option(s) provided: {", ".join(unknown)}.'
283 else:
284 raise ValueError("Unknown opt type")
285 return settings
286
287

◆ _validateOptions()

GenericMonitoringTool._validateOptions ( user,
default )
protected

Validate user inputs for "opt" argument of defineHistogram.

Check that the user-provided option for a specific "opt" argument exists in the default dictionary, and that it has the expected type.

Parameters
userthe option dictionary provided by the user
defaultthe default dictionary of options

Definition at line 218 of file GenericMonitoringTool.py.

218def _validateOptions(user, default):
219 for key, userVal in user.items():
220 # (1) Check that the requested key exists
221 assert key in default,\
222 f'Unknown option {key} provided. Choices are [{", ".join(default)}].'
223 # (2) Check that the provided type is correct
224 userType = type(userVal)
225 defaultVal = default[key]
226 defaultType = type(defaultVal)
227 if isinstance(userVal, bool) or isinstance(defaultVal, bool):
228 assert isinstance(userVal, bool) and isinstance(defaultVal, bool),\
229 f'{key} provided {userType}, expected bool.'
230 else:
231 assert isinstance(defaultVal, userType),\
232 f'{key} provided {userType}, expected {defaultType}'
233
234

◆ defineHistogram()

GenericMonitoringTool.defineHistogram ( flags,
varname,
type = 'TH1F',
path = None,
title = None,
weight = None,
xbins = 100,
xmin = 0,
xmax = 1,
xlabels = None,
ybins = None,
ymin = None,
ymax = None,
ylabels = None,
zmin = None,
zmax = None,
zlabels = None,
opt = None,
convention = None,
cutmask = None,
treedef = None,
merge = None )

Generate histogram definition string for the GenericMonitoringTool.Histograms property.

For full details see the GenericMonitoringTool documentation.

Parameters
flagsconfiguration flags object
varnameone (1D) or two (2D) variable names separated by comma optionally give histogram name by appending ";" plus the name
typehistogram type
pathtop-level histogram directory (e.g. EXPERT, SHIFT, etc.)
titleHistogram title and optional axis title (same syntax as in TH constructor)
weightName of the variable containing the fill weight
cutmaskName of the boolean-castable variable that determines if the plot is filled
optString or dictionary of histogram options (see _options())
treedefInternal use only. Use defineTree() method.
xlabelsList of x bin labels.
ylabelsList of y bin labels.
zlabelsList of x bin labels.
mergeMerge method to use for object, if not default. Possible algorithms for offline DQM are given in https://twiki.cern.ch/twiki/bin/view/Atlas/DQMergeAlgs

Definition at line 306 of file GenericMonitoringTool.py.

312 treedef=None, merge=None):
313
314 # All of these fields default to an empty string
315 stringSettingsKeys = ['xvar', 'yvar', 'zvar', 'type', 'path', 'title', 'weight',
316 'cutMask', 'convention', 'alias', 'treeDef', 'merge']
317 # All of these fileds default to 0
318 numberSettingsKeys = ['xbins', 'xmin', 'xmax', 'ybins', 'ymin', 'ymax', 'zbins',
319 'zmin', 'zmax']
320 # All of these fields default to an empty array
321 arraySettingsKeys = ['allvars', 'xlabels', 'xarray', 'ylabels', 'yarray', 'zlabels']
322 # Initialize a dictionary with all possible fields
323 settings = dict((key, '') for key in stringSettingsKeys)
324 settings.update(dict((key, 0.0) for key in numberSettingsKeys))
325 settings.update(dict((key, []) for key in arraySettingsKeys))
326
327 # Alias
328 varList, alias = _alias(varname)
329 if alias is None or alias.strip() == '':
330 log.warning(f'Unable to define histogram using definition "{varname}" since we cannot determine its name.')
331 return ''
332
333 invalid = _invalidName(flags, alias)
334 if invalid:
335 log.warning('%s is not a valid histogram name. Illegal characters: %s',
336 alias, ' '.join(invalid))
337 return ''
338
339 settings['alias'] = alias
340
341 # Variable names
342 nVars = len(varList)
343 if nVars>0:
344 settings['xvar'] = varList[0]
345 if nVars>1:
346 settings['yvar'] = varList[1]
347 if nVars>2:
348 settings['zvar'] = varList[2]
349 settings['allvars'] = varList
350
351 # Type
352 if flags.Common.isOnline and type in ['TTree']:
353 log.warning('Object %s of type %s is not supported for online running and '
354 'will not be added.', varname, type)
355 return ''
356
357 # Allowed histogram dimensions
358 if type.startswith('TH1'):
359 dims = {1}
360 elif type.startswith('TH2'):
361 dims = {2}
362 elif type=='TProfile':
363 dims = {2}
364 elif type=='TProfile2D':
365 dims = {3}
366 elif type=='TEfficiency':
367 dims = {2, 3}
368
369 assert type=='TTree' or nVars in dims,\
370 f'Number of monitored variables {varList} for "{path}/{alias}" '\
371 f'does not match histogram dimension for {type}'
372
373 settings['type'] = type
374
375 # Path
376 if path is None:
377 path = ''
378 settings['path'] = path
379
380 # Title
381 if title is None:
382 title = varname
383 settings['title'] = title
384
385 # Weight
386 if weight is not None:
387 settings['weight'] = weight
388
389 # Cutmask
390 if cutmask is not None:
391 settings['cutMask'] = cutmask
392
393 # Output path naming convention
394 if convention is not None:
395 settings['convention'] = convention
396
397 # Bin counts and ranges
398 # Possible types allowed for bin counts
399 binTypes = (int, list, tuple)
400
401 # X axis count and range
402 assert isinstance(xbins, binTypes),'xbins argument must be int, list, or tuple'
403 if isinstance(xbins, int): # equal x bin widths
404 settings['xbins'], settings['xarray'] = xbins, []
405 else: # x bin edges are set explicitly
406 settings['xbins'], settings['xarray'] = len(xbins)-1, xbins
407 settings['xmin'] = xmin
408 settings['xmax'] = xmax
409
410 # Y axis count and range
411 if ybins is not None:
412 assert isinstance(ybins, binTypes),'ybins argument must be int, list, or tuple'
413 if isinstance(ybins, int): # equal y bin widths
414 settings['ybins'], settings['yarray'] = ybins, []
415 else: # y bin edges are set explicitly
416 settings['ybins'], settings['yarray'] = len(ybins)-1, ybins
417 if ymin is not None:
418 settings['ymin'] = ymin
419 if ymax is not None:
420 settings['ymax'] = ymax
421
422 # Z axis count and range
423 if zmin is not None:
424 settings['zmin'] = zmin
425 if zmax is not None:
426 settings['zmax'] = zmax
427
428 # Then, parse the [xyz]label arguments
429 if xlabels is not None and len(xlabels)>0:
430 assert isinstance(xlabels, (list, tuple)),'xlabels must be list or tuple'
431 settings['xbins'] = len(xlabels)
432 settings['xlabels'] = xlabels
433 if ylabels is not None and len(ylabels)>0:
434 assert isinstance(ylabels, (list, tuple)),'ylabels must be list or tuple'
435 settings['ybins'] = len(ylabels)
436 settings['ylabels'] = ylabels
437 # if user did not specify ymin and ymax, set it here, as cannot have ymin=ymax=0
438 if ymin is None: settings["ymin"] = 0
439 if ymax is None: settings["ymax"] = settings["ymin"]+1
440 if zlabels is not None and len(zlabels)>0:
441 assert isinstance(zlabels, (list, tuple)),'zlabels must be list or tuple'
442 settings['zlabels'] = zlabels
443
444 # Tree branches
445 if treedef is not None:
446 assert type=='TTree','cannot define tree branches for a non-TTree object'
447 settings['treeDef'] = treedef
448
449 # Add all other options
450 settings.update(_options(opt))
451
452 # some things need merging
453 if ((settings['kAddBinsDynamically'] or settings['kRebinAxes'] or settings['kCanRebin'])
454 and (not flags.Common.isOnline and 'OFFLINE' in settings['convention'])):
455 if merge is None:
456 log.warning(f'Merge method for {alias} is not specified but needs to be "merge" due to histogram definition; overriding for your convenience')
457 merge = 'merge'
458
459 # merge method
460 if merge is not None:
461 assert type not in ['TEfficiency', 'TTree', 'TGraph'],'only default merge defined for non-histogram objects'
462 settings['merge'] = merge
463
464 # LB histograms always need to be published online (ADHI-4947)
465 if settings['kLBNHistoryDepth']>0 and flags.Common.isOnline:
466 settings['kAlwaysCreate'] = True
467 log.debug('Setting kAlwaysCreate for lumiblock histogram "%s"', varname)
468
469 # Check that kLBNHistoryDepth and kLive are both non-negative
470 assert settings['kLBNHistoryDepth']>=0, f'Histogram "{alias}" has invalid kLBNHistoryDepth.'
471 assert settings['kLive']>=0, f'Histogram "{alias}" has invalid kLive.'
472 # kLBNHistoryDepth and kLive options are mutually exclusive. User may not specify both.
473 assert settings['kLBNHistoryDepth']==0 or settings['kLive']==0,\
474 f'Cannot use both kLBNHistoryDepth and kLive for histogram {alias}.'
475 # kLive histograms are only available for Online monitoring.
476 assert settings['kLive']==0 or flags.Common.isOnline,\
477 f'Cannot use kLive with offline histogram {alias}.'
478
479 return json.dumps(settings)
480
481

◆ defineTree()

GenericMonitoringTool.defineTree ( flags,
varname,
treedef,
path = None,
title = None,
opt = '',
convention = None,
cutmask = None )

Generate tree definition string for the GenericMonitoringTool.Histograms property.

Convenience tool for

For full details see the GenericMonitoringTool documentation.

Parameters
flagsconfiguration flags object
varnameat least one variable name (more than one should be separated by comma); optionally give the name of the tree by appending ";" plus the tree name
treedefTTree branch definition string. Looks like the standard TTree definition (see https://root.cern.ch/doc/master/classTTree.html#addcolumnoffundamentaltypes). In fact if only scalars are given, it is exactly the same as you would use to define the TTree directly: "varA/F:varB/I:...". Vectors can be defined by giving "vector<int>", etc., instead of "I".
pathtop-level histogram directory (e.g. EXPERT, SHIFT, etc.)
titleHistogram title and optional axis title (same syntax as in TH constructor)
cutmaskName of the boolean-castable variable that determines if the plot is filled
optTTree options (none currently)
conventionExpert option for how the objects are placed in ROOT

Definition at line 498 of file GenericMonitoringTool.py.

500 cutmask=None):
501 return defineHistogram(flags, varname, type='TTree', path=path, title=title,
502 treedef=treedef, opt=opt, convention=convention,
503 cutmask=cutmask)