ATLAS Offline Software
GetCrossSectionAMITool.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
2 
3 from AthenaCommon.Logging import logging
4 import re
5 
6 
10  def __init__(self):
11  self.log = logging.getLogger('GetCrossSectionAMI')
12 
13  try:
14  import pyAMI.client
15  import pyAMI.atlas.api as api
16  except ImportError:
17  self.log.fatal('Unable to import the pyAMI client. Did you run "lsetup pyami; voms-proxy-init -voms atlas"?')
18  exit()
19 
20  self.ami_api = api
21  self.ami_client = pyAMI.client.Client('atlas')
22  self.ami_api.init()
23 
24  @property
25  def crossSection(self):
26  return self.xsec
27 
28  @property
29  def filterEfficiency(self):
30  return self.filtereff
31 
32  def getDatasetNameFromPath(self, path):
33  import re
34  datasetRegex = r'mc.._.*TeV\..*|valid.\..*' # mc??_????TeV.??? or valid?.???
35  parts = path.split('/')
36  for part in parts: # Do any of these parts look like a dataset name?
37  if re.match(datasetRegex, part):
38  return part
39 
40  self.log.error('Unable to figure out the MC dataset name from the path, you must supply it yourself as MCDatasetName')
41 
42  def cleanupDatasetName(self, dataset):
43  dataset = re.sub('_tid[0-9]{8}_[0-9]{2}', '', dataset)
44  dataset = re.sub('_sub[0-9]{10}', '', dataset)
45  dataset = re.sub('/$', '', dataset)
46  return dataset
47 
48  def convertDatasetNameToEVNT(self, dataset):
49  dsid = dataset.split('.')[1]
50  try:
51  res_d = self.ami_api.get_dataset_prov(self.ami_client, dataset)
52  except Exception as reason:
53  self.log.fatal('Unable to query AMI. Do you have a grid certificate? "voms-proxy-init -voms atlas"')
54  self.log.fatal('You can also supply the MCCrossSection and MCFilterEfficiency by hand for this sample')
55  self.log.fatal(f'The reason for failure was: {reason}')
56  exit()
57 
58  previous_nodes = [
59  n for n in res_d['node']
60  if 'logicalDatasetName' in n.keys() and n['logicalDatasetName'].split('.')[1] == dsid and 'EVNT' in n['logicalDatasetName']
61  ]
62 
63  sorted_nodes = sorted(previous_nodes, key=lambda n: n['distance'])
64  # We pick the latest one, just in case the cross section was modified (shouldn't have)
65  evnt_dataset = sorted_nodes[0]['logicalDatasetName']
66 
67  if 'EVNT' in evnt_dataset:
68  self.log.info('Found the original EVNT dataset using AMI provenance.')
69  self.log.info(f'Went from: {dataset}')
70  self.log.info(f' to: {evnt_dataset}')
71  return evnt_dataset
72  else:
73  self.log.fatal('Unable to get the original EVNT dataset from AMI provenance, you must supply it yourself as MCDatasetName')
74  self.log.fatal('You can also supply the MCCrossSection and MCFilterEfficiency by hand for this sample')
75  exit()
76 
77  def queryAmi(self, dataset):
78  if 'EVNT' not in dataset:
79  dataset = self.convertDatasetNameToEVNT(self.cleanupDatasetName(dataset))
80  self.dataset = dataset
81  self.log.info(f'Looking up details of {self.dataset} on AMI')
82 
83  # search for EVNT file
84  fields = 'cross_section,generator_filter_efficiency'
85  try:
86  res_l = self.ami_api.list_datasets(self.ami_client, patterns=self.dataset, fields=fields)
87  except Exception as reason:
88  self.log.fatal('Unable to query AMI. Do you have a grid certificate? "voms-proxy-init -voms atlas"')
89  self.log.fatal('You can also supply the MCCrossSection and MCFilterEfficiency by hand for this sample')
90  self.log.fatal(f'The reason for failure was: {reason}')
91  exit()
92 
93  if len(res_l) == 0:
94  self.log.fatal(f'The dataset "{dataset}" was not found in AMI')
95  self.log.fatal('You can also supply the MCCrossSection and MCFilterEfficiency by hand for this sample')
96  exit()
97  elif len(res_l) > 1:
98  self.log.fatal(f'More than one dataset "{dataset}" was found in AMI.')
99  exit()
100 
101  xsec = res_l[0]['cross_section']
102  gfe = res_l[0]['generator_filter_efficiency']
103 
104  if xsec == 'NULL' or gfe == 'NULL':
105  self.log.fatal(f'NULL cross section/filter efficiency values set on AMI for the dataset "{dataset}"')
106  self.log.fatal('You can supply the MCCrossSection and MCFilterEfficiency by hand for this sample')
107  exit()
108 
109  try:
110  self.xsec = float(xsec)
111  self.filtereff = float(gfe)
112  except ValueError:
113  self.log.fatal('Coudn\'t convert cross section/filter efficiency values to floats')
114  self.log.fatal(f' Cross Section: {xsec}')
115  self.log.fatal(f'Filter Efficiency: {gfe}')
116  self.log.fatal('You can supply the MCCrossSection and MCFilterEfficiency by hand for this sample')
117  exit()
118 
119  if self.xsec and self.filtereff:
120  self.log.info('################## ################## AMI Query Complete ################## ################## ')
121  self.log.info(f' Cross section: {self.xsec} nb')
122  self.log.info(f'Filter efficiency: {self.filtereff}')
123  self.log.info('You may want to supply these numbers directly in future as MCCrossSection and MCFilterEfficiency for speed')
124  self.log.info('################## ################## ################## ################## ################### ')
125  else:
126  self.log.fatal(f'The cross section and/or filter efficiency values for the dataset "{dataset}" are set to 0 on AMI')
127  self.log.fatal('You can supply the MCCrossSection and MCFilterEfficiency by hand for this sample')
128  exit()
grepfile.info
info
Definition: grepfile.py:38
python.GetCrossSectionAMITool.GetCrossSectionAMI.dataset
dataset
Definition: GetCrossSectionAMITool.py:80
python.GetCrossSectionAMITool.GetCrossSectionAMI.xsec
xsec
Definition: GetCrossSectionAMITool.py:110
python.GetCrossSectionAMITool.GetCrossSectionAMI.ami_api
ami_api
Definition: GetCrossSectionAMITool.py:20
python.GetCrossSectionAMITool.GetCrossSectionAMI.getDatasetNameFromPath
def getDatasetNameFromPath(self, path)
Definition: GetCrossSectionAMITool.py:32
python.GetCrossSectionAMITool.GetCrossSectionAMI.log
log
Definition: GetCrossSectionAMITool.py:11
python.GetCrossSectionAMITool.GetCrossSectionAMI.filtereff
filtereff
Definition: GetCrossSectionAMITool.py:111
python.GetCrossSectionAMITool.GetCrossSectionAMI.cleanupDatasetName
def cleanupDatasetName(self, dataset)
Definition: GetCrossSectionAMITool.py:42
python.GetCrossSectionAMITool.GetCrossSectionAMI.__init__
def __init__(self)
Definition: GetCrossSectionAMITool.py:10
python.GetCrossSectionAMITool.GetCrossSectionAMI
Basic wrapper around pyAMI for getting MC dataset cross sections & maniuplating dataset name strings.
Definition: GetCrossSectionAMITool.py:9
python.GetCrossSectionAMITool.GetCrossSectionAMI.ami_client
ami_client
Definition: GetCrossSectionAMITool.py:21
python.GetCrossSectionAMITool.GetCrossSectionAMI.queryAmi
def queryAmi(self, dataset)
Definition: GetCrossSectionAMITool.py:77
calibdata.exit
exit
Definition: calibdata.py:236
python.GetCrossSectionAMITool.GetCrossSectionAMI.filterEfficiency
def filterEfficiency(self)
Definition: GetCrossSectionAMITool.py:29
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
python.GetCrossSectionAMITool.GetCrossSectionAMI.crossSection
def crossSection(self)
Definition: GetCrossSectionAMITool.py:25
python.PyKernel.init
def init(v_theApp, v_rootStream=None)
Definition: PyKernel.py:45
python.GetCrossSectionAMITool.GetCrossSectionAMI.convertDatasetNameToEVNT
def convertDatasetNameToEVNT(self, dataset)
Definition: GetCrossSectionAMITool.py:48
error
Definition: IImpactPoint3dEstimator.h:70
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38