O2-DQ User Interface 1.0.0
Loading...
Searching...
No Matches
dqTranscations.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# PYTHON_ARGCOMPLETE_OK
3# -*- coding: utf-8 -*-
4
5# Copyright 2019-2020 CERN and copyright holders of ALICE O2.
6# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
7# All rights not expressly granted are reserved.
8#
9# This software is distributed under the terms of the GNU General Public
10# License v3 (GPL Version 3), copied verbatim in the file "COPYING".
11#
12# In applying this license CERN does not waive the privileges and immunities
13# granted to it by virtue of its status as an Intergovernmental Organization
14# or submit itself to any jurisdiction.
15
16# \Author: ionut.cristian.arsene@cern.ch
17# \Interface: cevat.batuhan.tolon@cern.ch
18
19# All transcations managements in DQ Workflows
20
21import logging
22import sys
23import os
24
25from .dqExceptions import CentFilterError, CfgInvalidFormatError, ForgettedArgsError, MandatoryArgNotFoundError, NotInAlienvError, SelsAndCutsNotHaveSameNumberError, TasknameNotFoundInConfigFileError
26
27
28def aodFileChecker(aod: str):
29 """This function checks path for AO2D (both for .root and .txt)
30
31 Args:
32 aod (CLI argument): Provided arg for AO2D File or text file which includes AO2D list
33 """
34
35 if aod is not None:
36 argProvidedAod = aod
37 textAodList = argProvidedAod.startswith("@")
38 endsWithRoot = argProvidedAod.endswith(".root")
39 endsWithTxt = argProvidedAod.endswith("txt") or argProvidedAod.endswith("text")
40 if textAodList and endsWithTxt:
41 argProvidedAod = argProvidedAod.replace("@", "")
42 logging.info("You provided AO2D list as text file : %s", argProvidedAod)
43 try:
44 open(argProvidedAod, "r")
45 logging.info("%s has valid File Format and Path, File Found", argProvidedAod)
46
47 except FileNotFoundError:
48 logging.exception("%s AO2D file text list not found in path!!!", argProvidedAod)
49 sys.exit()
50
51 elif endsWithRoot:
52 logging.info("You provided single AO2D root file : %s", argProvidedAod)
53 try:
54 open(argProvidedAod, "r")
55 logging.info("%s has valid File Format and Path, File Found", argProvidedAod)
56
57 except FileNotFoundError:
58 logging.exception("%s AO2D single root file not found in path!!!", argProvidedAod)
59 sys.exit()
60 else:
61 try:
62 open(argProvidedAod, "r")
63 logging.info("%s has valid File Format and Path, File Found", argProvidedAod)
64
65 except FileNotFoundError:
66 logging.exception("%s Wrong formatted File, check your file extension!", argProvidedAod)
67 sys.exit()
68
69
70def trackPropTransaction(trackProp: bool, deps: list):
71 """This method automatically deletes the o2-analysis-trackextension(for run2) task from your workflow
72 when you add the o2-analysis-track-propagation (for run3)
73 task to your workflow. Two tasks are not compatible at the same time
74
75 Args:
76 trackProp (CLI argument): CLI argument to add the o2-analysis-track-propagation task
77 deps (list): Defined dependency list
78 """
79
80 if trackProp:
81 deps.remove("o2-analysis-trackextension")
82 logging.info("o2-analysis-trackextension is not valid dep for run 3, It will deleted from your workflow.")
83
84
85def trackPropChecker(commonDeps: list, barrelDeps: list):
86 """This method automatically deletes the o2-analysis-trackextension(for run2) task from your workflow
87 when you add the o2-analysis-track-propagation (for run3)
88 task to your workflow. Two tasks are not compatible at the same time
89
90 Args:
91 commonDeps (list): Common Dependency list for run to task
92 barrelDeps (list): The dependency list where the trackextension task is defined
93 """
94
95 if "o2-analysis-track-propagation" in commonDeps:
96 barrelDeps.remove("o2-analysis-trackextension")
97 logging.info("o2-analysis-trackextension is not valid dep for run 3, It will deleted from your workflow.")
98
99
100def mainTaskChecker(config: dict, taskNameInConfig: str):
101 """1. Checks whether the workflow you want to run in your JSON file has a main task.
102
103 2. Checks If you are running the O2Physics environment
104
105 Args:
106 taskNameInConfig (string): taskNameInConfig
107
108 Raises:
109 TasknameNotFoundInConfigFileError: if taskname not found in json config
110 NotInAlienvError: if you are not in O2Physics environment
111 """
112
113 O2PHYSICS_ROOT = os.environ.get("O2PHYSICS_ROOT")
114
115 try:
116 if taskNameInConfig not in config:
117 raise TasknameNotFoundInConfigFileError(taskNameInConfig)
118 else:
119 logging.info("%s is in your JSON Config File", taskNameInConfig)
120 except TasknameNotFoundInConfigFileError as e:
121 logging.exception(e)
122 sys.exit()
123
124 # Check alienv
125 try:
126 if O2PHYSICS_ROOT is None:
127 raise NotInAlienvError
128 else:
129 logging.info("You are in %s alienv", O2PHYSICS_ROOT)
130 except NotInAlienvError as e:
131 logging.exception(e)
132 #sys.exit()
133
134
135def jsonTypeChecker(cfgFileName: str):
136 """Checks if the JSON config file assigned by the CLI is in the correct format
137
138 Args:
139 cfgFileName (json): CLI argument as your input json config file
140
141 Raises:
142 CfgInvalidFormatError: If the file format is not correct
143 """
144
145 isConfigJson = cfgFileName.endswith(".json")
146
147 try:
148 if not isConfigJson:
149 raise CfgInvalidFormatError(cfgFileName)
150 else:
151 logging.info("%s is valid json config file", cfgFileName)
152
153 except CfgInvalidFormatError as e:
154 logging.exception(e)
155 sys.exit()
156
157
158# Transcation management for forgettining assign a value to parameters
159def forgettedArgsChecker(configuredCommands: dict):
160 """Checks for any arguments forgot to assign a value which you provided to command line
161
162 E.x. --process --syst PbPb (It will raise)
163
164 Args:
165 configuredCommands (dict): Dictionary of arguments entered from the CLI
166
167 Raises:
168 ForgettedArgsError: if there is an argument you forgot to configure
169 """
170 forgetParams = []
171 for key, value in configuredCommands.items():
172 if value is not None:
173 if (isinstance(value, str) or isinstance(value, list)) and len(value) == 0:
174 forgetParams.append(key)
175 try:
176 if len(forgetParams) > 0:
177 raise ForgettedArgsError(forgetParams)
178 except ForgettedArgsError as e:
179 logging.exception(e)
180 sys.exit()
181
182
183def centTranscation(config: dict, process, syst, centSearch):
184 """If you assign a centrality-related process function for the pp collision
185 system while trying to skim the data, an error will return.
186
187 Args:
188 process (CLI argument): process function in tableMaker/tableMakerMC
189 centSearch (list): List counting Cent sub strings in process function
190 syst (CLI argument): collision system
191
192 Raises:
193 CentFilterError: If you assign a centrality-related process function
194 """
195 if (process and len(centSearch) != 0 and (syst == "pp" or (syst is None and config["event-selection-task"]["syst"] == "pp"))):
196 logging.warning(
197 "JSON file does not include configs for centrality-table task, It's for DATA. Centrality will removed because you select pp collision system."
198 )
199 if process is not None:
200 processCentralityMatch = [s for s in process if "Cent" in s]
201 try:
202 if len(processCentralityMatch) > 0:
203 raise CentFilterError
204 else:
205 pass
206 except CentFilterError as e:
207 logging.exception(e)
208 sys.exit()
209
210
211def filterSelsTranscation(argBarrelSels: list, argMuonSels: list, argBarrelTrackCuts: list, argMuonsCuts: list, configuredCommands: dict):
212 """It checks whether the event filter selections and analysis cuts in the
213 Filter PP task are in the same number and order
214
215 Args:
216 argBarrelSels (CLI Argument): Event filter argument for barrel
217 argMuonSels (CLI Argument): Event filter argument for muons
218 argBarrelTrackCuts (CLI Argument): Analysis cut argument for barrel
219 argMuonsCuts (CLI Argument): Analysis cuts argument for muons
220 configuredCommands (dict): Dictionary of all arguments provided by the CLI
221
222 Raises:
223 MandatoryArgNotFoundError: If the required argument is not found
224 SelsAndCutsNotHaveSameNumberError : If Filter Selections and analysis cuts not in same number and order
225 """
226
227 argMuonSelsClean = []
228 argBarrelSelsClean = []
229
230 if argMuonSels:
231 try:
232 if argMuonsCuts is None:
233 raise MandatoryArgNotFoundError(argMuonsCuts)
234 else:
235 pass
236
237 except MandatoryArgNotFoundError as e:
238 logging.exception(e)
239 logging.error("For configure to cfgMuonSels (For DQ Filter PP Task), you must also configure cfgMuonsCuts!!!")
240 sys.exit()
241
242 # remove string values after :
243 for i in argMuonSels:
244 i = i[0 : i.index(":")]
245 argMuonSelsClean.append(i)
246
247 try:
248 if argMuonSelsClean == argMuonsCuts:
249 pass
250 else:
251 raise SelsAndCutsNotHaveSameNumberError
252
253 except SelsAndCutsNotHaveSameNumberError as e:
254 logging.exception(e)
255 logging.info(
256 "[INFO] For fixing this issue, you should have the same number of cuts (and in the same order) provided to the cfgMuonsCuts from dq-selection as those provided to the cfgMuonSels in the DQFilterPPTask."
257 )
258 logging.info(
259 "For example, if cfgMuonCuts is muonLowPt,muonHighPt,muonLowPt then the cfgMuonSels has to be something like: muonLowPt::1,muonHighPt::1,muonLowPt:pairNoCut:1"
260 )
261 sys.exit()
262
263 logging.info("Event filter configuration is valid for muons")
264
265 if argBarrelSels:
266
267 try:
268 if argBarrelTrackCuts is None:
269 raise MandatoryArgNotFoundError(argBarrelTrackCuts)
270 else:
271 pass
272
273 except MandatoryArgNotFoundError as e:
274 logging.exception(e)
275 logging.error("For configure to cfgBarrelSels (For DQ Filter PP Task), you must also configure cfgBarrelTrackCuts!!!")
276 sys.exit()
277
278 # remove string values after :
279 for i in argBarrelSels:
280 i = i[0 : i.index(":")]
281 argBarrelSelsClean.append(i)
282
283 try:
284 if argBarrelSelsClean == argBarrelTrackCuts:
285 pass
286 else:
287 raise SelsAndCutsNotHaveSameNumberError
288
289 except SelsAndCutsNotHaveSameNumberError as e:
290 logging.exception(e)
291 logging.info(
292 "For fixing this issue, you should have the same number of cuts (and in the same order) provided to the cfgBarrelTrackCuts from dq-selection as those provided to the cfgBarrelSels in the DQFilterPPTask."
293 )
294 logging.info(
295 "For example, if cfgBarrelTrackCuts is jpsiO2MCdebugCuts,jpsiO2MCdebugCuts2,jpsiO2MCdebugCuts then the cfgBarrelSels has to be something like: jpsiO2MCdebugCuts::1,jpsiO2MCdebugCuts2::1,jpsiO2MCdebugCuts:pairNoCut:1"
296 )
297 sys.exit()
298
299 logging.info("Event filter configuration is valid for barrel")
300
301
302"""
303def tableReaderDepsChecker(analysisCfg,processCfg,mixingCfg):
304
305 sameEventPairingDeps = {
306 ["JpsiToEE"]: ["trackSelection"],
307 ["JpsiToMuMu"]: ["muonSelection"],
308 ["JpsiToMuMuVertexing"]: ["muonSelection"],
309 ["VnJpsiToEE"]: ["trackSelection"],
310 ["JpsiToMuMu"]: ["muonSelection"],
311 ["ElectronMuon"] : ["trackSelection","muonSelection"],
312 ["All"] : ["trackSelection","muonSelection"]
313 }
314
315 eventMixingDeps = {
316 "Barrel": "trackSelection",
317 "Muon": "muonSelection",
318 "BarrelMuon": ["trackSelection","muonSelection"],
319 "BarrelVn": "trackSelection",
320 "MuonVn": "muonSelection"
321 }
322
323
324 for k,v in sameEventPairingDeps.items():
325 if (k in processCfg) and v not in analysisCfg:
326 raise
327
328 for k,v in eventMixingDeps.items():
329 if (k in mixingCfg) and v not in analysisCfg:
330 raise
331"""