diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/java/GUI/TrigMaMGUI.java b/Trigger/TrigMonitoring/TrigHLTMonitoring/java/GUI/TrigMaMGUI.java index 72a809f0c7d0bb1ac3a6506a5c160f5db535d38a..0980580222e7de69810da37e677705087af72379 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/java/GUI/TrigMaMGUI.java +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/java/GUI/TrigMaMGUI.java @@ -1,7 +1,10 @@ -//// -//// GUI for TriggerHLTMonitoring MenuAwareMonitoring -//// built by Xanthe Hoad (xhoad@cern.ch) -//// +/* +Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// GUI for TriggerHLTMonitoring MenuAwareMonitoring +// Author: Xanthe Hoad (xanthe.hoad@cern.ch) +// See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information import java.awt.*; import java.awt.event.*; @@ -92,10 +95,10 @@ public class TrigMaMGUI extends JFrame { JScrollPane scrollPane = new JScrollPane(linkComment); scrollPane.setPreferredSize(new Dimension(200, 30)); SMK_MCK_link_subpanel_1.add(scrollPane); - JButton SMK_MCK_link_button = new JButton("Make SMK-MCK link"); JPanel SMK_MCK_link_subpanel_2 = new JPanel(new FlowLayout(FlowLayout.CENTER,1,1)); SMK_MCK_link_panel.add(SMK_MCK_link_subpanel_2); + JButton SMK_MCK_link_button = new JButton("Make SMK-MCK link"); SMK_MCK_link_subpanel_2.add(SMK_MCK_link_button); final JCheckBox force_link_checkbox = new JCheckBox("Force link upload (only tick if you are certain you want to do this)"); SMK_MCK_link_subpanel_2.add(force_link_checkbox); @@ -370,6 +373,11 @@ public class TrigMaMGUI extends JFrame { JButton ViewSMCKbutton = new JButton("View SMCK"); View_keys_subpanel_2.add(ViewSMCKbutton); + JPanel View_keys_subpanel_3 = new JPanel(new FlowLayout(FlowLayout.CENTER,1,1)); + View_keys_panel.add(View_keys_subpanel_3); + JButton ViewLinksButton = new JButton("View all SMK-MCK links"); + View_keys_subpanel_3.add(ViewLinksButton); + ViewSMKbutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //Get the selected SMK info @@ -396,6 +404,14 @@ public class TrigMaMGUI extends JFrame { RunProcess(viewSMCKcommand); } }); + + ViewLinksButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + //Get the selected MCK info + String viewLinksCommand = "from TrigHLTMonitoring.MenuAwareMonitoringStandalone import MenuAwareMonitoringStandalone;ms = MenuAwareMonitoringStandalone('"+dbalias+"');ms.print_all_mck_to_smk_links();"; + RunProcess(viewLinksCommand); + } + }); } //Setting up the tabbed pane diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_P1.sh b/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_P1.sh index 69b239abbd2f0a026c3cbd939023264a2acf53dc..75bce7414e52b0f22ad092c3e60b47f1a4b3068b 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_P1.sh +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_P1.sh @@ -1,9 +1,9 @@ # TO RUN THE GUI, PLEASE RUN THE COMMAND: # source TrigMaMGUI_P1.sh echo -echo " Trigger Menu Aware Monitoring Graphical User Interface" -echo " by Xanthe Hoad xanthe.hoad@cern.ch" -echo " For more info about Menu Aware Monitoring see" +echo " Trigger Menu-aware Monitoring Graphical User Interface" +echo " for use with TRIGGERDB" +echo " For more info about Menu-aware Monitoring see" echo " https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM" echo @@ -26,5 +26,8 @@ fi #Uncomment the following line to recompile the GUI #WARNING: If compiling, please call the script from an empty directory #The java compiler at P1 scrambles files when run in a non-empty directory -#javac $SCRIPTDIR/GUI/TrigMaMGUI.java -java -cp $SCRIPTDIR/GUI: TrigMaMGUI TRIGGERDBR2MAM +#javac -version $SCRIPTDIR/GUI/TrigMaMGUI.java +#java -cp -showversion $SCRIPTDIR/GUI: TrigMaMGUI TRIGGERDBR2MAM +#Need higher java version, use 1.8 +#/sw/atlas/sw/lcg/external/Java/JDK/1.8.0/amd64/bin/javac -version $SCRIPTDIR/GUI/TrigMaMGUI.java +/sw/atlas/sw/lcg/external/Java/JDK/1.8.0/amd64/jre/bin/java -cp -showversion $SCRIPTDIR/GUI: TrigMaMGUI TRIGGERDBR2MAM diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_TRIGGERDBREPR.sh b/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_TRIGGERDBREPR.sh index 8e38a7f89c3fc8662e59103f251fb3a5da4688d7..451c6719bde7cf799327324a7e2db56e7f2d6e7e 100755 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_TRIGGERDBREPR.sh +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/java/TrigMaMGUI_TRIGGERDBREPR.sh @@ -1,5 +1,5 @@ -# TO RUN THE GUI, PLEASE RUN THE COMMAND: -# source TrigMaMGUI_TRIGGERDBREPR.sh +# Author: Xanthe Hoad (xanthe.hoad@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information if [ -z "$AtlasProject" ] then @@ -10,10 +10,9 @@ then fi echo -echo " Trigger Menu Aware Monitoring Graphical User Interface" +echo " Trigger Menu-aware Monitoring Graphical User Interface" echo " for use with TRIGGERDBREPR" -echo " by Xanthe Hoad xanthe.hoad@cern.ch" -echo " For more info about Menu Aware Monitoring see" +echo " For more info about Menu-aware Monitoring see" echo " https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM" echo @@ -26,6 +25,8 @@ then fi SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TARGETDIR="/tmp/${USER}/MaMGUI" +mkdir -p $TARGETDIR -javac $SCRIPTDIR/../java/TrigMaMGUI.java -java -cp $SCRIPTDIR/../java: TrigMaMGUI TRIGGERDBREPR +javac $SCRIPTDIR/../java/TrigMaMGUI.java -d $TARGETDIR +java -cp $TARGETDIR: TrigMaMGUI TRIGGERDBREPR diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonFlags.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonFlags.py index 0fb8f05edf0851d2a759c2588a1e7b6f1bae48e7..7c6ab8df8ec7fe54e96daa8656eed2d5f93e73f1 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonFlags.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonFlags.py @@ -16,21 +16,42 @@ class doMonTier0(JobProperty): list+=[doMonTier0] class doGeneral(JobProperty): - """ switch for general HLTMon Tool""" + """ switch for general HLTMon Tool """ statusOn=True allowedTypes=['bool'] StoredValue=True list+=[doGeneral] class doMaM(JobProperty): - """ Global switch for menu-aware monitoring""" + """ Global switch for menu-aware monitoring """ statusOn=True allowedTypes=['bool'] - StoredValue=False + StoredValue=True list+=[doMaM] +class doMaM_ApplyMCK(JobProperty): + """ Switch for menu-aware monitoring: applying configurations defined by an MCK """ + statusOn=True + allowedTypes=['bool'] + StoredValue=True +list+=[doMaM_ApplyMCK] + +class MCK(JobProperty): + """ Monitoring Configuration Key (MCK) for menu-aware monitoring """ + statusOn=True + allowedTypes=['int'] + StoredValue=-1 +list+=[MCK] + +class doMaM_UseReproDB(JobProperty): + """ Switch for menu-aware monitoring: use MCKs in TRIGGERDBREPR, don't query COOL """ + statusOn=True + allowedTypes=['bool'] + StoredValue=False +list+=[doMaM_UseReproDB] + class doMaM_ExtractAndDumpConfigs(JobProperty): - """ Switch for menu-aware monitoring: exctraction of tool configurations, and output to a json file""" + """ Switch for menu-aware monitoring: extraction of tool configurations, and output to a json file """ statusOn=True allowedTypes=['bool'] StoredValue=False @@ -43,20 +64,6 @@ class MaM_OutputJSON(JobProperty): StoredValue='mam_configs.json' list+=[MaM_OutputJSON] -class doMaM_ApplyMCK(JobProperty): - """ Switch for menu-aware monitoring: applying configurations defined by an MCK""" - statusOn=True - allowedTypes=['bool'] - StoredValue=False -list+=[doMaM_ApplyMCK] - -class MCK(JobProperty): - """ Monitoring Configuration Key (MCK) for menu-aware monitoring """ - statusOn=True - allowedTypes=['int'] - StoredValue=-1 -list+=[MCK] - class doEgamma(JobProperty): """ Egamma switch for monitoring """ statusOn=True diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py index fc791b57b8ac61eeccad78a1b3833d8ede47217e..36649728922c0024b2c9aea5f9b30234dbb4291d 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/HLTMonTriggerList.py @@ -1,4 +1,3 @@ - # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration import TrigBjetMonitoring.TrigBjetMonitCategory as bjet @@ -53,12 +52,14 @@ class HLTMonTriggerList: monitoring_jet = [] primary_l1jet = [] primary_jet = [] - monitoring_met = [] + monitoring_met_shifter = [] + monitoring_met_expert = [] monitoring_minbias = [] monitoring_muonNonIso = [] monitoring_muonIso = [] monitoring_MSonly = [] monitoring_muonEFFS = [] + monitoring_muonLowpt = [] monitoring_muon_Support = [] monitoring_tau = [] monitoring_singleTau = [] @@ -159,7 +160,8 @@ class HLTMonTriggerList: self.primary_jet = jets.primary_jet # set the met triggers to the default values - self.monitoring_met = met.monitoring_met + self.monitoring_met_shifter = met.monitoring_met_shifter + self.monitoring_met_expert = met.monitoring_met_expert # set the minbias triggers to the default values self.monitoring_minbias = minbias.monitoring_minbias @@ -169,6 +171,7 @@ class HLTMonTriggerList: self.monitoring_muonIso = muon.monitoring_muonIso self.monitoring_MSonly = muon.monitoring_MSonly self.monitoring_muonEFFS = muon.monitoring_muonEFFS + self.monitoring_muonLowpt = muon.monitoring_muonLowpt self.monitoring_muon_Support = muon.monitoring_muon_Support # set the tau triggers to the default values @@ -188,12 +191,14 @@ class HLTMonTriggerList: self.primary_l1jet = jets.primary_l1jet_pp self.primary_jet = jets.primary_jet_pp - self.monitoring_met = met.monitoring_met_pp + self.monitoring_met_shifter = met.monitoring_met_shifter_pp + self.monitoring_met_expert = met.monitoring_met_expert_pp self.monitoring_muonNonIso = muon.monitoring_muonNonIso_pp self.monitoring_muonIso = muon.monitoring_muonIso_pp self.monitoring_MSonly = muon.monitoring_MSonly_pp self.monitoring_muonEFFS = muon.monitoring_muonEFFS_pp + self.monitoring_muonLowpt = muon.monitoring_muonLowpt self.monitoring_muon_Support = muon.monitoring_muon_Support_pp self.monitoring_tau = tau.monitoring_tau_pp @@ -209,12 +214,14 @@ class HLTMonTriggerList: self.primary_l1jet = jets.primary_l1jet_hi self.primary_jet = jets.primary_jet_hi - self.monitoring_met = [] + self.monitoring_met_shifter = [] + self.monitoring_met_expert = [] self.monitoring_muonNonIso = muon.monitoring_muonNonIso_HI self.monitoring_muonIso = muon.monitoring_muonIso_HI self.monitoring_MSonly = muon.monitoring_MSonly_HI self.monitoring_muonEFFS = muon.monitoring_muonEFFS_HI + self.monitoring_muonLowpt = muon.monitoring_muonLowpt self.monitoring_muon_Support = muon.monitoring_muon_Support_HI def set_HLTMonTrigList_cosmic (self): @@ -225,7 +232,8 @@ class HLTMonTriggerList: self.primary_l1jet = jets.primary_l1jet_cosmic self.primary_jet = jets.primary_jet_cosmic - self.monitoring_met = met.monitoring_met_cosmic + self.monitoring_met_shifter = met.monitoring_met_shifter_cosmic + self.monitoring_met_expert = met.monitoring_met_expert_cosmic self.monitoring_tau = tau.monitoring_tau_cosmic self.monitoring_singleTau = tau.monitoring_singleTau_cosmic diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoring.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoring.py index 68c690f1e8bf6ed16ffca5179b6789ae1c619d38..33a681ec1e8bc8b0987a2287efe25c81e556614b 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoring.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoring.py @@ -1,8 +1,7 @@ # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -# -# Authors: Ben Smart (Ben.Smart@cern.ch), Xanthe Hoad (Xanthe.Hoad@cern.ch) -# +# Authors: Ben Smart (ben.smart@cern.ch), Xanthe Hoad (xanthe.hoad@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information import sys,os,shutil,re from TrigHLTMonitoring.MenuAwareMonitoringStandalone import MenuAwareMonitoringStandalone @@ -23,8 +22,7 @@ from xml.dom import minidom # for monitoring mode setup from AthenaMonitoring.DQMonFlags import DQMonFlags -# all Menu-Aware Monitoring stuff in one class -# it uses OracleInterface to talk to the Oracle database +# MaM uses OracleInterface to talk to the Oracle database # and ToolInterrogator to talk to the local tools class MenuAwareMonitoring: """Menu-aware Monitoring class. @@ -40,30 +38,22 @@ class MenuAwareMonitoring: # flag for setting whether to print out anything to screen or not self.print_output = True - # flag so that diff instruction are only printed once self.firstdiff = True - # create MaMStandalone interaction object (includes connecting to oracle) self.ms = MenuAwareMonitoringStandalone(alias,database_username,database_password,database_name,database_directory) - # get athena version self.__get_athena_version__() - # holder for stream (bulk or express) self.stream = "" self.__get_stream__() - # print guide for user if this is an interactive session if self.ms.__is_session_interactive__(): - - print "Running in Athena release",self.ms.current_athena_version + print "Release detected:",self.ms.current_athena_version print "Stream detected:",self.stream - # create tool interrogator object self.ti = ToolInterrogator() - - # flag to prevent multiple calls to setup_all_local_tools, as it doesn't seem like the current config is picked up is this is tried + # flag to prevent multiple calls to setup_all_local_tools, as it doesn't seem like the current config is picked up if this is tried self.tools_setup = False self.setup_mode = "" @@ -103,7 +93,9 @@ class MenuAwareMonitoring: def __get_athena_version__(self): "Get the current Athena version." - self.ms.current_athena_version = self.get_release_setup().replace(",","-") + release = self.get_release_setup() + self.ms.current_athena_version = release[0].replace(",","-") + self.ms.current_nightly_version = release[1].replace(",","-") def get_release_setup(self): @@ -152,13 +144,26 @@ class MenuAwareMonitoring: release = os.environ['AtlasBuildBranch'] setup="%s,%s,%s"%(project,release,current_nightly) elif 'AtlasBuildStamp' in os.environ: - release = os.environ['AtlasBuildBranch'] - current_nightly = os.environ['AtlasBuildStamp'] # denotes a cmakegit nightly - setup="%s,%s,%s"%(project,release,current_nightly) + current_nightly = os.environ['AtlasBuildStamp'] + if current_nightly in os.environ['ATLAS_RELEASE_BASE']: + # this is a nightly + release = os.environ['AtlasBuildBranch'] + setup = "%s,%s,%s"%(project,release,current_nightly) + else: + # this is not a nightly + setup = "%s,%s"%(project,release) + # also save the nightly it was built from + release = os.environ['AtlasBuildBranch'] + base_nightly = "%s,%s,%s"%(project,release,current_nightly) else: setup="%s,%s"%(project,release) - return setup + try: + # this is a full release, save the base nightly + return setup,base_nightly + except: + # this is not a git/cmake release with a base nightly + return setup,setup def __get_tag__(self,package=""): @@ -184,6 +189,7 @@ class MenuAwareMonitoring: return packageVersion except ValueError: print "Warning, unusual output from cmt: %s\n" % line + elif 'CMAKE_PREFIX_PATH' in os.environ: # for cmake releases cpath = os.getenv("CMAKE_PREFIX_PATH") @@ -226,8 +232,9 @@ class MenuAwareMonitoring: npackages = npackages+1 except ValueError: print "Warning, unusual output from cmt: %s\n" % line + elif 'WorkDir_DIR' in os.environ : - # does this work for git packages? + # TODO check if this works for git builds print "Patch packages in your build are:\n" myfilepath = os.environ['WorkDir_DIR'] fname = str(myfilepath) + '/packages.txt' @@ -239,6 +246,7 @@ class MenuAwareMonitoring: npackages=npackages+1 else: print "A release area with locally installed packages has not been setup." + if npackages == 0: print "No patches found" return npackages @@ -248,7 +256,6 @@ class MenuAwareMonitoring: """List local running trigger-monitoring tools that have been discovered by the Tool Interrogator. These tool configurations are available in the <ThisVariable>.local dictionary.""" - # info for user print "The following local tools have had their configurations extracted by the ToolInterrogator:" # list the tools in self.ms.local_global_info['MONITORING_TOOL_DICT'] @@ -265,23 +272,18 @@ class MenuAwareMonitoring: print_output_here = self.print_output # returns True or False depending on whether the input is valid to be used in the current stage of Athena running - # if no input, then return false if input1 == "": return False - # if input is ALL, then return true if input1 == "ALL": return True - # if input is ESD, and doESD is true, then return true if input1 == "ESD": return rec.doESD - # if input is AOD, and doAOD is true, then return true if input1 == "AOD": return rec.doAOD - # if we have reached this far, then the input has not been recognised if print_output_here: print "The processing step",input1,"has not been recognised. Valid options are ALL, ESD, and AOD." @@ -300,15 +302,12 @@ class MenuAwareMonitoring: print_output_here = self.print_output # returns True or False depending on whether the input is valid to be used in the current stream - # if no input, then return false if input1 == "": return False - # if input is ALL, then return true if input1 == "ALL": return True - # if input equals self.stream, then return true if input1 == self.stream: return True @@ -326,31 +325,20 @@ class MenuAwareMonitoring: if print_output_here == "": print_output_here = self.print_output - # info for user if print_output_here: print "Attempting to get configurations of all locally running trigger-monitoring tools" # get list of locally running monitoring tools mon_tools = self.ti.get_available_trigger_monitoring_tools() - # print info about available local tools - if len(mon_tools) > 0: - if print_output_here: - print "The following trigger-monitoring tools have been found locally:" - print "" - # get smck_config for each of these tools for tool in mon_tools: - - # get smck_config smck_config = self.ti.get_smck_config_from_ToolSvc_tool_name(tool) - # check that smck_config has been found # if not (Athena oddities can cause this) then skip to the next tool # only correct, valid trig mon tools should survive this process if smck_config == -1: continue - # construct smck_info for this tool smck_info = {} smck_info['SMCK_CONFIG'] = smck_config @@ -359,32 +347,22 @@ class MenuAwareMonitoring: smck_info['SMCK_TOOL_TYPE'] = tool smck_info['SMCK_ATHENA_VERSION'] = self.ms.current_athena_version smck_info['SMCK_SVN_TAG'] = self.__get_tag__(str(smck_config['PackageName']).split(".")[0]) - # add this info to the local_global_info self.ms.local_global_info['MONITORING_TOOL_DICT'][tool] = smck_info - # print info about this tool - if print_output_here: - print "ToolSvc."+tool - print "The extracted data of this tool is stored in <ThisVariable>.local['"+tool+"']" - print "This can be passed to MaM methods with the string '"+tool+"'" - print "" - self.ms.__update_local_pointer__() - # add nice spacing if we have been printing tool info if len(mon_tools) > 0: if print_output_here: print "The extracted data of all local trigger-monitoring tools is stored in <ThisVariable>.ms.local" + print "The extracted data of a particular tool is stored in <ThisVariable>.local['ToolName'], for example <ThisVariable>.local['"+mon_tools[0]+"']" print "All local trigger-monitoring tools can be passed together as an 'MCK' to MaM diff and search methods with the string 'LOCAL'" - print "" - def setup_all_local_tools(self,mode=""): "Setup all local trigger-monitoring tools and runs get_current_local_info() to read them in using the Tool Interrogator." if self.tools_setup == True: - # this is a precautionary measure because it is not clear from testing that tools are resetup correctly if setup is attempted multiple times (probably because tools has protections against this implemented) + # this is a precautionary measure because it is not clear from testing that tools are resetup correctly if setup is attempted multiple times (probably because tools have protections against this implemented) print "Tools already set up." print "Quit and restart to setup again." return @@ -413,7 +391,6 @@ class MenuAwareMonitoring: # setup all local packages listed in PackagesToInterrogate via ToolInterrogator self.ti.load_all_tools() - # read in these tools with the Tool Interrogator self.get_current_local_info() @@ -427,7 +404,7 @@ class MenuAwareMonitoring: # is this session interactive? If not, return "ALL" if self.ms.__is_session_interactive__(): - # info for user + print "Please specify whether this upload is to be a default for an Athena release, or a patch." print "valid inputs are 'default' or 'patch'." @@ -437,28 +414,19 @@ class MenuAwareMonitoring: # if input is blank, interpret this as 'PATCH' if user_input == "": user_input = "PATCH" - - # confirmation to user print "You have selected",user_input - # valid input + # check for valid input # if need be, then this list can be extended at a later date valid_input = ['DEFAULT','PATCH'] - - # check for valid input # if input is not valid, ask for it again while not valid_input.__contains__(user_input): - # warning to user that input was not understood print "The input",user_input,"was not recognised. Please specify a valid option." - - # get user input user_input = raw_input("default or patch?: ").upper() - # if input is blank, interpret this as 'PATCH' if user_input == "": user_input = "PATCH" - # confirmation to user print "You have selected",user_input @@ -469,7 +437,6 @@ class MenuAwareMonitoring: return 0 else: - # this is not an interactive session, so we can not ask for input return 0 @@ -485,22 +452,17 @@ class MenuAwareMonitoring: # make input names of equal length, for nice printout spacing # if the inputs are already of the same length if len(input1) == len(input2): - # set the names to print name1 = input1 name2 = input2 - # else if input 1 is longer than input 2 elif len(input1) > len(input2): - # set the names to print # pad out the shorter one with spaces before it name1 = input1 name2 = ((len(input1)-len(input2))*" ") + input2 - # else if input 2 is longer than input 1 elif len(input1) < len(input2): - # set the names to print # pad out the shorter one with spaces before it name1 = ((len(input2)-len(input1))*" ") + input1 @@ -508,27 +470,20 @@ class MenuAwareMonitoring: # loop over the keys (and values) in dict1 for key, value1 in dict1.iteritems(): - # if this key is in the second dictionary if dict2.__contains__(key): - # value from dict2 value2 = dict2[key] - # if the value is a dict if type(value1) is dict: - # first print this dict key print tab_space+name1+"['"+key+"']:" print tab_space+name2+"['"+key+"']:" - # recursively call this function # add some space to tab_space, to indent the sub-dictionary self.__print_two_dicts__(value1,value2," "+tab_space,name1,name2) - # if the value is a list elif type(value1) is list: - # print the items nicely (no unicode u' features) print tab_space+name1+"['"+key+"'] = [", for n, item in enumerate(value1): @@ -548,37 +503,28 @@ class MenuAwareMonitoring: if n != len(value2)-1: print ",", print "]" - # else if this value is not a dict or a list, then we should print else: print tab_space+name1+"['"+key+"'] =",value1 print tab_space+name2+"['"+key+"'] =",value2 - # else if this key is only in dict1, then we print it anyway else: - # if this is a dict if type(value1) is dict: - # then use ms.__print_one_dict__ to print it self.ms.__print_one_dict__(value1,tab_space,name1) - # else just print it else: print tab_space+name1+"['"+key+"'] =",value1 # loop over the keys (and values) in dict2 for key, value2 in dict2.iteritems(): - # if this key is not in the first dictionary if not dict1.__contains__(key): - # if this is a dict if type(value2) is dict: - # then use ms.__print_one_dict__ to print it self.ms.__print_one_dict__(value2,tab_space,name2) - # else just print it else: print tab_space+name2+"['"+key+"'] =",value2 @@ -595,7 +541,7 @@ class MenuAwareMonitoring: "Is input1 a valid MCK_ID." if self.ms.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # if the input is blank, then no, it's not an mck @@ -608,7 +554,6 @@ class MenuAwareMonitoring: # if mck_info == -1 then we've not found an mck, so return False if mck_info == -1: return False - # else this is a valid mck else: return True @@ -618,25 +563,21 @@ class MenuAwareMonitoring: "Is input1 a valid SMCK_ID or SMCK_TOOL_PATCH_VERSION." if self.ms.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # check for empty print_output_here # if it is found, use self.print_output if print_output_here == "": print_output_here = self.print_output - # if the input is blank, then no, it's not an smck if input1 == "": return False - # search for this smck smck_id = self.ms.__get_smck_id_from_smck_identifier__(input1,print_output_here) - # if smck_id == -1 then we've not found an smck, so return False if smck_id == -1: return False - # else this is a valid smck else: return True @@ -648,7 +589,6 @@ class MenuAwareMonitoring: # import HLTMonTriggerList from TrigHLTMonitoring.HLTMonTriggerList import hltmonList - # now we rerun hltmonList.config() to update it with all the latest info from all slices hltmonList.config() @@ -669,7 +609,6 @@ class MenuAwareMonitoring: if print_output_here == "": print_output_here = self.print_output - #info for user if print_output_here: if self.firstdiff: print "" @@ -682,14 +621,9 @@ class MenuAwareMonitoring: # input flags must be specified # acceptable tags are SMCK and MCK - - # valid flags valid_flags = ['MCK','SMCK'] - # if any of the inputs or flags are missing if input1 == "" or flag1 == "" or input2 == "" or flag2 == "": - - #info for user if print_output_here: print "diff takes four arguments: input1, flag1, input2, flag2." print "The inputs specify what things are to be diffed." @@ -701,220 +635,155 @@ class MenuAwareMonitoring: print "1,'MCK',2,'MCK'" print "1,'MCK','HLTMuonMon','SMCK'" print "17,'SMCK','HLTMuonMon','SMCK'" - - # if input1 has not been provided if input1 == "": - - #info for user if print_output_here: print "The first input has not been provided. Please provide the first input." - - # if flag1 has not been provided if flag1 == "": - - #info for user if print_output_here: print "The first flag has not been provided. Please provide the first flag. Recognised flags are MCK and SMCK" - - # if input2 has not been provided if input2 == "": - - #info for user if print_output_here: print "The second input has not been provided. Please provide the second input." - - # if flag2 has not been provided if flag2 == "": - - #info for user if print_output_here: print "The second flag has not been provided. Please provide the second flag. Recognised flags are MCK and SMCK" - - # since one or more inputs are missing, we exit return # if flag 1 is not a string if type(flag1) is not str: - - #info for user if print_output_here: print "The flag '"+flag1+"' is not a string. Recognised flags are MCK and SMCK" return # if input 1 does not have a valid flag if not flag1.upper() in valid_flags: - - #info for user if print_output_here: print "The flag '"+flag1+"' is not a recognised flag. Recognised flags are MCK and SMCK" return # check if input 1 is a valid mck if flag1 == "MCK": - # if it is not a valid mck or local is_1_local = False if type(input1) is str: if input1.upper() == "LOCAL": is_1_local = True if is_1_local == False and not self.__is_input_an_mck__(input1): - - #info for user if print_output_here: print input1,"is not a valid MCK, or 'LOCAL' has not been selected." return # check if input 1 is a valid smck elif flag1 == "SMCK": - # if it is not a valid smck or local tool if not self.__is_input_an_smck__(input1,False) and not self.__is_input_a_local_tool__(input1): - - #info for user if print_output_here: print input1,"is not a valid SMCK or local tool." return # if flag 2 is not a string if type(flag2) is not str: - - #info for user if print_output_here: print "The flag '"+flag2+"' is not a string. Recognised flags are MCK and SMCK" return # if input 2 does not have a valid flag if not flag2.upper() in valid_flags: - - #info for user if print_output_here: print "The flag '"+flag2+"' is not a recognised flag. Recognised flags are MCK and SMCK" return # check if input 2 is a valid mck if flag2 == "MCK": - # if it is not a valid mck or local is_2_local = False if type(input2) is str: if input2.upper() == "LOCAL": is_2_local = True if is_2_local == False and not self.__is_input_an_mck__(input2): - - #info for user if print_output_here: print input2,"is not a valid MCK, or 'LOCAL' has not been selected." return # check if input 2 is a valid smck elif flag2 == "SMCK": - # if it is not a valid smck or local tool if not self.__is_input_an_smck__(input2,False) and not self.__is_input_a_local_tool__(input2): - - #info for user if print_output_here: print input2,"is not a valid SMCK or local tool." return # if we've reached this far then the inputs have been parsed # now we deal with the combinatorics of the options - # these are the dicts we will diff diff_input1_dict = {} diff_input2_dict = {} # if input 1 is an mck if flag1 == "MCK": - # if input 1 is local if is_1_local: - # then use currently stored local global info diff_input1_dict = self.ms.local_global_info - # else input 1 is an mck # (we know this because we checked if input 1 was a valid mck or 'local' above) else: - # get the global info from the database diff_input1_dict = self.ms.get_global_info_from_db(input1) # else input 1 is an smck elif flag1 == "SMCK": - # we must either get the smck from the database, or locally if it is a local tool # (it will be one or the other, as we have confirmed above) # we then need to construct a temporary global info for the diff - # construct the temporary global info for the diff diff_input1_dict['MONITORING_TOOL_DICT'] = {} - # is input 1 a local tool if self.__is_input_a_local_tool__(input1): - # set the tool name tool_name1 = input1 - # get the tool from the locally stored config diff_input1_dict['MONITORING_TOOL_DICT'][tool_name1] = self.ms.local_global_info['MONITORING_TOOL_DICT'][tool_name1] - # else the input is an smck in the database else: - # get the tool from the database smck_info1 = self.ms.get_smck_info_from_db(input1) - # set the tool name tool_name1 = smck_info1['SMCK_TOOL_TYPE'] - # get the tool from the database diff_input1_dict['MONITORING_TOOL_DICT'][tool_name1] = smck_info1 # if input 2 is an mck if flag2 == "MCK": - # if input 2 is local if is_2_local: - # then use currently stored local global info diff_input2_dict = self.ms.local_global_info - # else input 2 is an mck # (we know this because we checked if input 2 was a valid mck or 'local' above) else: - # get the global info from the database diff_input2_dict = self.ms.get_global_info_from_db(input2) # else input 2 is an smck elif flag2 == "SMCK": - # we must either get the smck from the database, or locally if it is a local tool # (it will be one or the other, as we have confirmed above) # we then need to construct a temporary global info for the diff - # construct the temporary global info for the diff diff_input2_dict['MONITORING_TOOL_DICT'] = {} - # is input 2 a local tool if self.__is_input_a_local_tool__(input2): - # set the tool name tool_name2 = input2 - # get the tool from the locally stored config diff_input2_dict['MONITORING_TOOL_DICT'][tool_name2] = self.ms.local_global_info['MONITORING_TOOL_DICT'][tool_name2] - # else the input is an smck in the database else: - # get the tool from the database smck_info2 = self.ms.get_smck_info_from_db(input2) - # set the tool name tool_name2 = smck_info2['SMCK_TOOL_TYPE'] - # get the tool from the database diff_input2_dict['MONITORING_TOOL_DICT'][tool_name2] = smck_info2 @@ -931,14 +800,12 @@ class MenuAwareMonitoring: # now we need to print this in a neat manner if print_output_here: - # recursively print the diffs self.__print_two_dicts__(diff_output1_dict,diff_output2_dict,"",input1,input2) # else we assume the user wants the diffs returned # (ie if this function has been called from within another function) else: - # return the diffed dictionaries return diff_output1_dict, diff_output2_dict @@ -947,47 +814,32 @@ class MenuAwareMonitoring: "Print the tables and entries in the current Oracle database." if self.ms.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # get SQL table and column names database_column_list = self.ms.oi.get_db_tables_and_columns() - # list of tables table_list = [] - # construct list of tables for line in database_column_list: - # if this table is not in the list if not line['TABLE_NAME'].upper() in table_list: - # add it to the list table_list.append(line['TABLE_NAME'].upper()) - # info for user - print "" print "The Menu-aware Monitoring Oracle database currently has the following format:" - print "" - # for each table for table in table_list: - # print the table name print "Table",table - # loop over the database_column_list for column in database_column_list: - # if this column is in this table if column['TABLE_NAME'].upper() == table: - # print this column info print " ",column['COLUMN_NAME'] - # nice spacing for user - print "" - def does_mck_athena_version_match_current_athena_version(self, mck_id): "Compares the current Athena version to the MCK athena version" @@ -995,7 +847,7 @@ class MenuAwareMonitoring: mck_info = self.ms.oi.read_mck_info_from_db(mck_id) mck_athena_version = mck_info['MCK_ATHENA_VERSION'] - return self.ms.check_compatibility_of_two_release_versions(mck_athena_version,self.ms.current_athena_version) + return self.ms.check_compatibility_of_two_release_versions(mck_athena_version,[self.ms.current_athena_version,self.ms.current_nightly_version]) def does_smck_athena_version_match_current_athena_version(self, smck_id): @@ -1004,14 +856,14 @@ class MenuAwareMonitoring: smck_info = self.ms.oi.read_smck_info_from_db(smck_id) smck_athena_version = smck_info['SMCK_ATHENA_VERSION'] - return self.ms.check_compatibility_of_two_release_versions(smck_athena_version,self.ms.current_athena_version) + return self.ms.check_compatibility_of_two_release_versions(smck_athena_version,[self.ms.current_athena_version,self.ms.current_nightly_version]) def apply_mck(self,input1="",print_output_here=""): "Apply an MCK to locally running tools." if self.ms.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return if print_output_here == "": @@ -1042,7 +894,7 @@ class MenuAwareMonitoring: "Apply an SMCK to a locally running tool." if self.ms.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # check for empty print_output_here @@ -1055,15 +907,12 @@ class MenuAwareMonitoring: # if we don't if smck_id == -1: - - # info for user if print_output_here: print "SMCK",input1,"has not been recognised as a valid SMCK." return # get the smck_info smck_info = self.ms.oi.read_smck_info_from_db(smck_id) - # get the release this SMCK was created for smck_athena_version = smck_info['SMCK_ATHENA_VERSION'] # compare to our release @@ -1074,8 +923,6 @@ class MenuAwareMonitoring: processing_step = smck_info['SMCK_PROCESSING_STEP'] # are we running in an appropriate processing step? if not self.__is_input_a_valid_current_processing_step_to_use__(processing_step): - - # info for user if print_output_here: print "SMCK",input1,"is for the Athena processing stage '"+processing_step+"' which we are not currently in -> this SMCK will not be applied." return @@ -1084,22 +931,17 @@ class MenuAwareMonitoring: processing_stream = smck_info['SMCK_PROCESSING_STREAM'] # are we running in an appropriate processing stream? if not self.__is_input_a_valid_current_processing_stream_to_use__(processing_stream): - - # info for user if print_output_here: print "SMCK",input1,"is for the Athena processing stream '"+processing_stream+"', which we are not currently using -> this SMCK will not be applied." return # get the ToolSvc_tool_name ToolSvc_tool_name = smck_info['SMCK_CONFIG']['ToolSvcName'] - # is the input a locally running tool tool_is_running = False tool_is_running = hasattr(ToolSvc,ToolSvc_tool_name) #exec "tool_is_running = hasattr(ToolSvc,%s)" % (ToolSvc_tool_name) if not tool_is_running: - - # info for user if print_output_here: print "SMCK",input1,"corresponds to the tool",ToolSvc_tool_name,"which is not running locally, so can not be configured with this SMCK." return @@ -1111,87 +953,60 @@ class MenuAwareMonitoring: # now we apply the config patch of the smck # for each variable in the patch for tool_key, tool_value in patch_config.iteritems(): - # test if the tool has this variable tool_contains_variable = False exec "tool_contains_variable = hasattr(ToolSvc.%s,tool_key)" % (ToolSvc_tool_name) - # if the tool has this variable if tool_contains_variable: - # get the type of the value type_to_set_to = type exec "type_to_set_to = type(ToolSvc.%s.%s)" % (ToolSvc_tool_name,tool_key) - # test that the value to be applied is of the same type as the existing value if type_to_set_to is type(tool_value): - # if this is a list, make it blank first # this is to avoid overzealous Athena type limiting # TODO Write this in a more generic way, ie. not just for lists if type_to_set_to is list: exec "ToolSvc.%s.%s = []" % (ToolSvc_tool_name,tool_key) - # apply the config for this variable exec "ToolSvc.%s.%s = tool_value" % (ToolSvc_tool_name,tool_key) - # if they are not the same type else: - - # info for user if print_output_here: print "ToolSvc."+str(ToolSvc_tool_name)+"."+str(tool_key)+" is of type "+str(type_to_set_to)+", however in SMCK",input1,str(ToolSvc_tool_name)+"."+str(tool_key),"is of type",type(tool_value) #print "Athena will only allow ToolSvc."+str(ToolSvc_tool_name)+"."+str(tool_key)+" to be set to values of type",type_to_set_to print "Attempting conversion...", - # get the type_to_set_to as a str type_to_set_to_str = str(type_to_set_to).split("'")[1] - # try to convert try: - # try the conversion exec "new_value = %s(tool_value)" % (type_to_set_to_str) - # if we've got this far then the conversion was a success - # info for user if print_output_here: print "conversion successful.", # check that the values are equal if new_value == tool_value: - # apply the config for this variable exec "ToolSvc.%s.%s = new_value" % (ToolSvc_tool_name,tool_key) - - # nice formatting for user - if print_output_here: - print "" - # if the values are not equal else: - - # info for user if print_output_here: print "However the values do not match. This tool variable will not be set." print "(",str(new_value),"!=",str(tool_value),")" # if the conversion has failed except: - - # info for user if print_output_here: print "conversion failed. This tool variable will not be set." # get the MonitCategory patch monitCategory_patch_config = self.ms.oi.__unicode_to_str__(smck_info['SMCK_CONFIG']['MonitCategoryInfo'] ) - # if monitCategory_patch_config is not empty, then we must apply this patch if not monitCategory_patch_config == {}: - # get the MonitCategory name monitCategory_name = self.ms.oi.__unicode_to_str__(smck_info['SMCK_CONFIG']['MonitCategoryName'] ) - # first we must import the relevant MonitCategory # we import it as monitCategory_object so that we have a handle on it monitCategory_object = "" @@ -1199,34 +1014,28 @@ class MenuAwareMonitoring: # we then need to apply each variable in monitCategory_patch_config to monitCategory_object for key, value in monitCategory_patch_config.iteritems(): - # test if the monitCategory_object has this variable monitCategory_object_contains_variable = False monitCategory_object_contains_variable = hasattr(monitCategory_object,key) # if the monitCategory_object has this variable if monitCategory_object_contains_variable: - # get the type of the value type_to_set_to = type exec "type_to_set_to = type(monitCategory_object.%s)" % (key) # test that the value to be applied is of the same type as the existing value if type_to_set_to is type(value): - # if this is a list, make it blank first # this is to avoid overzealous Athena type limiting # TODO Write this in a more generic way, ie. not just for lists if type_to_set_to is list: exec "monitCategory_object.%s = []" % (key) - # apply the config for this variable exec "monitCategory_object.%s = value" % (key) # if they are not the same type else: - - # info for user if print_output_here: print str(monitCategory_name)+"."+str(key)+" is of type "+str(type_to_set_to)+", however in SMCK",input1,str(monitCategory_name)+"."+str(key),"is of type",type(value) #print "Athena will only allow ToolSvc."+str(ToolSvc_tool_name)+"."+str(tool_key)+" to be set to values of type",type_to_set_to @@ -1237,44 +1046,32 @@ class MenuAwareMonitoring: # try to convert try: - # try the conversion exec "new_value = %s(tool_value)" % (type_to_set_to_str) - # if we've got this far then the conversion was a success - # info for user if print_output_here: print "conversion successful.", # check that the values are equal if new_value == tool_value: - # apply the config for this variable exec "ToolSvc.%s.%s = new_value" % (ToolSvc_tool_name,tool_key) - # nice formatting for user - if print_output_here: - print "" - # if the values are not equal else: - - # info for user if print_output_here: print "However the values do not match. This MonitCategory variable will not be set." print "(",str(new_value),"!=",str(tool_value),")" # if the conversion has failed except: - - # info for user if print_output_here: print "conversion failed. This MonitCategory variable will not be set." # finally we should refresh HLTMonTriggerList self.__refresh_HLTMonTriggerList__() - # info for user + if print_output_here: print "SMCK",input1,"has been applied as a config patch to tool",ToolSvc_tool_name @@ -1286,7 +1083,7 @@ class MenuAwareMonitoring: that the default tool configurations should be used.""" if self.ms.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # returns an empty list if no MCK or a list of the MCK details @@ -1299,41 +1096,6 @@ class MenuAwareMonitoring: return 0 - def dump_mck_to_json(self,mck_id,output_json_filename=""): - "Dump the contents of an MCK to a json file, including the contents of linked SMCKs" - - if not self.__is_input_an_mck__(mck_id): - print "MCK",mck_id,"has not been recognised as a valid MCK." - return - - if output_json_filename == "": - output_json_filename = "MCK_"+str(mck_id)+".json" - - output_file = open( output_json_filename, "w" ) - - mck_info = self.ms.oi.read_mck_info_from_db(mck_id) - smck_ids = self.ms.oi.read_mck_links_from_db(mck_id) - - mck_dump_info = {} - # datetime.datetime objects are not JSON serializable - # seeing as this info is not used later, we replace with the ctime - mck_info['MCK_CREATION_DATE'] = mck_info['MCK_CREATION_DATE'].ctime() - mck_dump_info['MCK'] = mck_info - - # need to add rest of MCK info - - #combine the info in the MONITORING_TOOL_DICT - mck_dump_info['MONITORING_TOOL_DICT'] = {} - for smck_id in smck_ids: - smck_info = self.ms.oi.read_smck_info_from_db(smck_id) - smck_info['SMCK_CREATION_DATE'] = smck_info['SMCK_CREATION_DATE'].ctime() - tool_type = smck_info['SMCK_TOOL_TYPE'] - mck_dump_info['MONITORING_TOOL_DICT'][tool_type] = smck_info - - json.dump(mck_dump_info, output_file, ensure_ascii=True, sort_keys=True) - output_file.close() - - def dump_local_config_to_json(self,output_json_filename="mam_configs.json",processing_step="",processing_stream="",comment="",default=""): "All locally read-in trigger monitoring tool configurations are output to a file." @@ -1349,18 +1111,15 @@ class MenuAwareMonitoring: # if this is a default... if default==1: - # then set the processing_step and processing_stream accordingly processing_step="ALL" processing_stream="ALL" # else if it's a patch... else: - # if no processing_step is provided, then ask for one if processing_step=="": processing_step = self.ms.__ask_for_processing_step__() - # if no processing_step is provided, then ask for one if processing_stream=="": processing_stream = self.ms.__ask_for_processing_stream__() @@ -1378,7 +1137,6 @@ class MenuAwareMonitoring: # fill extra smck_info for all tools for tool_key, tool_value in self.ms.local_global_info['MONITORING_TOOL_DICT'].iteritems(): - # fill extra smck_info tool_value['SMCK_PROCESSING_STEP'] = processing_step tool_value['SMCK_PROCESSING_STREAM'] = processing_stream @@ -1463,7 +1221,7 @@ class MenuAwareMonitoring: comment = self.ms.__ask_for_comment__() # need to get release accurately and in a form the command can run - use get_release_setup - release = self.get_release_setup() + release = self.get_release_setup()[0] # this is not a default, so we need to get the default and perform the diff before dumping print "Will get default in clean directory for release",release #release @@ -1480,8 +1238,6 @@ class MenuAwareMonitoring: UniqID = str(uuid.uuid4()) CleanDirName="default_"+UniqID - # print CleanDirName - default_json_filename = self.ms.current_athena_version+'_default.json' # do the getting of the default via a shell here @@ -1503,7 +1259,7 @@ class MenuAwareMonitoring: # if there are no local differences wrt the default, then we dump nothing and exit if diffed_global_info2 == {}: - print "No local differences have been found with respect to the default configuration for Athena version "+athena_version+"." + print "No local differences have been found with respect to the default configuration for Athena version "+release+"." print "Nothing shall be dumped to json as a result." return @@ -1521,7 +1277,6 @@ class MenuAwareMonitoring: # fill extra smck_info for all tools for tool_key, tool_value in diffed_global_info2['MONITORING_TOOL_DICT'].iteritems(): - # fill extra smck_info tool_value['SMCK_PROCESSING_STEP'] = processing_step tool_value['SMCK_PROCESSING_STREAM'] = processing_stream diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoringStandalone.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoringStandalone.py index b7e0981b508b5e23e646be8773e83599700c97ae..02ecb984b89194cde56489b6d504f2bbaeb08c78 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoringStandalone.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/MenuAwareMonitoringStandalone.py @@ -1,9 +1,8 @@ #!/usr/bin/env python # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -# -# Authors: Ben Smart (Ben.Smart@cern.ch), Xanthe Hoad (Xanthe.Hoad@cern.ch) -# +# Authors: Ben Smart (ben.smart@cern.ch), Xanthe Hoad (xanthe.hoad@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information import sys,os # import subprocess. Required to get user @@ -28,46 +27,33 @@ class MenuAwareMonitoringStandalone: and get the current default from the database (if it exists).""" # MaM code version - self.version = '1.4.6' - + self.version = '1.4.8' # flag for setting whether to print out anything to screen or not self.print_output = True - - # create oracle interaction object + # create oracle interaction objects self.oi = OracleInterface() - # holder for current user self.current_user = "" self.__get_current_user__() - # Since this code is Athena-independent, we use a dummy 'Athena version' # If called from MenuAwareMonitoring, this will be updated to the real version - self.current_athena_version = "MaM P1 GUI" - + self.current_athena_version = "MaMStandalone" + self.current_nightly_version = "MaMStandalone" # holder for default global_info self.default_global_info = {} - # holder for current local global_info self.local_global_info = {} self.local_global_info['MONITORING_TOOL_DICT'] = {} - # pointer to local tool info self.local = self.local_global_info['MONITORING_TOOL_DICT'] - # flag to record if we have connected to Oracle self.connected_to_oracle = False self.connection_alias = "" - # flag to indicate if we are connected to the replica database with a readonly connection self.readonly_db_connection = False - # second flag so MAM doesn't break - will remove this later - self.replica_db_connection = False - # greetings print "Welcome to Menu-aware Monitoring (MaM) version",self.version - print "Please report any bugs to xanthe.hoad@cern.ch" - print "You are",self.current_user - + print "See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more info" # now connect to oracle self.__connect_to_oracle__(alias,database_username,database_password,database_name,database_directory) if self.connected_to_oracle == False: @@ -78,34 +64,23 @@ class MenuAwareMonitoringStandalone: print "Some Menu-aware Monitoring functions will not be available to you" else: self.connection_alias = alias - self.replica_db_connection = self.readonly_db_connection def __connect_to_oracle__(self,alias,database_username,database_password,database_name,database_directory): "Connect to the Oracle server." - # if we are already connected if self.connected_to_oracle: - - # info for user - print "We are already connected to the Oracle database" - - # else if we are not + print "MaM is already connected to the Oracle database" else: - # info for user - print "We are now connecting to the Oracle database" - if alias is "CUSTOM_DB": print "Connecting to database",database_name,"with provided username, password and directory" - print "Caution: MaM may not work as expected while using a custom DB" + print "WARNING: MaM may not work as expected while using a custom DB" self.oi.connect_to_oracle(database_username,database_password,database_name,database_directory) self.connected_to_oracle = True elif alias in ("TRIGGERDB","TRIGGERDBREPR","TRIGGERDBREPR_R","TRIGGERDBR2MAM"): - # get the connection from authentication.xml connectionSvcs = self._getConnectionServicesForAlias(alias) - # print "Connection Services %s" % connectionSvcs for connectionSvc in connectionSvcs: print "Trying connection service",connectionSvc if 'oracle' in connectionSvc: @@ -143,7 +118,7 @@ class MenuAwareMonitoringStandalone: self.readonly_db_connection = True break except: - print "Oracle connection via Frontier not possible." + print "Oracle connection via Frontier not possible" self.connected_to_oracle = False else: print "Error while connecting to Oracle database, no connections found" @@ -156,13 +131,8 @@ class MenuAwareMonitoringStandalone: def __disconnect_from_oracle__(self): "Disconnect from the Oracle server." - # if we are connected to Oracle if self.connected_to_oracle: - - # info for user print "We are now disconnecting from the Oracle database" - - # disconnect from oracle if self.oi.disconnect_from_oracle(): #returns True if disconnection is successful self.connected_to_oracle = False self.readonly_db_connection = False @@ -179,7 +149,8 @@ class MenuAwareMonitoringStandalone: # TRIGGERDBREPR_R uses this path DBLOOKUP_PATH = 'CORAL_DBLOOKUP_PATH' if alias is "TRIGGERDBREPR_R": - # _R means we access the regular auth files instead of the ones with read/write access, need to change the alias back to TRIGGERDBREPR so that we look up the right details in the auth files + # _R means we access the regular auth files instead of the ones with read/write access + # need to now change the alias back to TRIGGERDBREPR so that we look up the right details in the auth files alias = "TRIGGERDBREPR" dblookupfilename = self._getFileLocalOrPath('dblookup.xml',DBLOOKUP_PATH) if dblookupfilename == None: return None @@ -245,9 +216,10 @@ class MenuAwareMonitoringStandalone: """looks for filename in local directory and then in all paths specified in environment variable 'pathenv' returns path/filename if existing, otherwise None """ - if os.path.exists(filename): - print( "Using local file %s" % filename) - return filename + #Removed: breaks some Tier0Tests + #if os.path.exists(filename): + # print( "Using local file %s" % filename) + # return filename pathlist = os.getenv(pathenv,'').split(os.pathsep) resolvedfilename = self.FindFile(filename, pathlist, os.R_OK) @@ -280,21 +252,17 @@ class MenuAwareMonitoringStandalone: # if the input is not a string, make it one if type(smck_config) is not str: - # use json to turn the config into a string smck_config_json = json.dumps(smck_config, ensure_ascii=True, sort_keys=True) - # else if it is a string else: - # use input string as string to hash - print "__get_config_hash__ has been passed a string, rather than an smck_config dict. This is unexpected, so you are being notified in case something has gone wrong. If it has, please contact the author: Ben Smart bsmart@cern.ch" + print "__get_config_hash__ has been passed a string, rather than an smck_config dict. This is unexpected! Continuing anyway..." print "input =",smck_config smck_config_json = smck_config # calculate hash return_hash = hashlib.sha512(smck_config_json.encode()).hexdigest() - # return hash return return_hash @@ -304,8 +272,6 @@ class MenuAwareMonitoringStandalone: # is this session interactive? If not, return "" if self.__is_session_interactive__(): - - # info for user print "Please enter a comment to be attached to this upload to the database." print "The comment is limited in length to 1000 characters" @@ -314,10 +280,8 @@ class MenuAwareMonitoringStandalone: # check that comment length is valid while len(user_input) > 1000: - # warn user that their input is too long, and give them the change to re-enter a comment print "Your comment was too long, (it was",len(user_input),"characters long). Please enter a shorter comment." - # get user input user_input = raw_input("comment: ") @@ -325,7 +289,6 @@ class MenuAwareMonitoringStandalone: return user_input else: - # this is not an interactive session, so we can not ask for input return "" @@ -337,48 +300,36 @@ class MenuAwareMonitoringStandalone: # is this session interactive? If not, return "ALL" if self.__is_session_interactive__(): - # info for user + # if need be, then this list can be extended at a later date + valid_input = ['ALL','ESD','AOD'] + print "Please specify which processing step(s) you wish this input to be for." print "The default is 'ALL' for all processing steps." - print "Valid options are 'ESD', 'AOD', and 'ALL'." + print "Valid options are:",valid_input print "Hit <enter> without any input to select the default option (ALL)" # now get user input user_input = raw_input("processing step: ").upper() - # if input is blank, interpret this as 'ALL' if user_input == "": user_input = "ALL" - - # confirmation to user print "You have selected",user_input - # valid input - # if need be, then this list can be extended at a later date - valid_input = ['ALL','ESD','AOD'] - # check for valid input # if input is not valid, ask for it again while not valid_input.__contains__(user_input): - # warning to user that input was not understood print "The input",user_input,"was not recognised. Please specify a valid option." - - # get user input user_input = raw_input("processing step: ") - # if input is blank, interpret this as 'ALL' if user_input == "": user_input = "ALL" - - # confirmation to user print "You have selected",user_input # return selected processing step return user_input else: - # this is not an interactive session, so we can not ask for input return "ALL" @@ -387,51 +338,40 @@ class MenuAwareMonitoringStandalone: """If running interactively, ask user for the processing stream(s) an upload will be valid for. 'ALL' is the default.""" + # is this session interactive? If not, return "ALL" if self.__is_session_interactive__(): - # info for user + # if need be, then this list can be extended at a later date + valid_input = ['ALL','BULK','EXPRESS'] + print "Please specify which processing stream(s) you wish this input to be for." print "The default is 'ALL' for all processing streams." - print "Valid options are 'BULK', 'EXPRESS', and 'ALL'." + print "Valid options are:",valid_input print "Hit <enter> without any input to select the default option (ALL)" # now get user input user_input = raw_input("processing stream: ").upper() - # if input is blank, interpret this as 'ALL' if user_input == "": user_input = "ALL" - - # confirmation to user print "You have selected",user_input - # valid input - # if need be, then this list can be extended at a later date - valid_input = ['ALL','BULK','EXPRESS'] - # check for valid input # if input is not valid, ask for it again while not valid_input.__contains__(user_input): - # warning to user that input was not understood print "The input",user_input,"was not recognised. Please specify a valid option." - - # get user input user_input = raw_input("processing stream: ") - # if input is blank, interpret this as 'ALL' if user_input == "": user_input = "ALL" - - # confirmation to user print "You have selected",user_input # return selected processing stream return user_input else: - # this is not an interactive session, so we can not ask for input return "ALL" @@ -459,8 +399,6 @@ class MenuAwareMonitoringStandalone: # if type(input_smk) is not int, then ask the user to input an SMK while type(input_smk) is not int: - - # info for user print "Please enter an SMK integer to be linked." # now get user input @@ -474,8 +412,6 @@ class MenuAwareMonitoringStandalone: # if type(input_mck_id) is not int, then ask the user to input an MCK while type(input_mck_id) is not int: - - # info for user print "Please enter an MCK_ID integer to be linked." # now get user input @@ -489,10 +425,8 @@ class MenuAwareMonitoringStandalone: # if this session is not interactive else: - # if the inputs are not valid if (type(input_mck_id) is not int) or (type(input_smk) is not int): - # return, as inputs are not valid # print for logfile print "Menu-aware monitoring: link_smk_to_mck(",input_smk,",",input_mck_id,",",comment,") inputs not valid. MCK and SMK must be integers." @@ -513,11 +447,8 @@ class MenuAwareMonitoringStandalone: # check if this link already exists as the active link if self.oi.check_if_smk_to_mck_link_exists_and_is_active(input_smk,input_mck_id): - # ensure all other links for this smk are deactivated self.oi.deactivate_all_links_for_given_smk_except_for_given_mck(input_smk,input_mck_id) - - # info for user, and return print "SMK",input_smk,"linked to MCK",input_mck_id,"is already the active link for this SMK." return @@ -526,9 +457,12 @@ class MenuAwareMonitoringStandalone: if len(active_smk_to_mck_link_search_results) > 0: # we have found an active link. Upload should not proceed for safety. - print "SMK",input_smk,"is already linked to MCK",active_smk_to_mck_link_search_results[0][0],". Will now print full link details." + print "SMK",input_smk,"is already linked to MCK",active_smk_to_mck_link_search_results[0][0] + print "Will now print full link details:" print active_smk_to_mck_link_search_results - print "Deactivate this link first if you want to create a new link. You can use force_deactivate_all_links_for_smk(smk) (or tick the force upload box if using the GUI), but be sure this is what you want to do." + print "Deactivate this link first if you want to create a new link." + print "You can use force_deactivate_all_links_for_smk(smk) (or tick the force upload box if using the GUI)." + print "You should make sure this is what you really want to do first before proceeding!" return # get the current user for the creator @@ -540,27 +474,18 @@ class MenuAwareMonitoringStandalone: # try to upload the link try: - - # info for user print "Now attempting to link MCK",input_mck_id,"to SMK",input_smk - if not self.oi.check_if_smk_to_mck_link_exists(input_smk,input_mck_id): # link does not exist # upload the link self.oi.upload_mck_to_smk_link(input_mck_id,input_smk,creator,comment) - self.oi.activate_smk_mck_link(input_smk,input_mck_id) - - # info for user print "MCK",input_mck_id,"has been linked to SMK",input_smk - # ensure all other links for this smk are deactivated (should already be true) self.oi.deactivate_all_links_for_given_smk_except_for_given_mck(input_smk,input_mck_id) # if the upload fails in some way except: - - # info for user print "An exception occurred:",sys.exc_info()[0],sys.exc_info()[1] print "Error in link upload." @@ -572,23 +497,25 @@ class MenuAwareMonitoringStandalone: active_smk_to_mck_link_search_results = self.oi.find_active_smk_to_mck_link(input_smk) if len(active_smk_to_mck_link_search_results) > 0: - print "SMK",input_smk,"is already linked to MCK",active_smk_to_mck_link_search_results[0][0],". Will now print full link details." + print "SMK",input_smk,"is already linked to MCK",active_smk_to_mck_link_search_results[0][0] + print "Will now print full link details." print active_smk_to_mck_link_search_results - else: - print "SMK",input_smk,"is not linked to any MCK." - return - if GUI is False: - print "Will force deactivate all links for SMK",input_smk,". Do you really want to do this?" - user_input = raw_input("y/n: ") + if GUI is False: + print "Requested force deactivate all links for SMK",input_smk + print "Do you really want to do this?" + user_input = raw_input("y/n: ") + if user_input != 'y': + print "Aborted." + return - if user_input != 'y': - print "Aborted." - return + print "Force deactivating all links for SMK",input_smk,"..." + self.oi.deactivate_all_links_for_given_smk(input_smk) + print "All links deactivated." - print "Force deactivating all links for SMK",input_smk,"..." - self.oi.deactivate_all_links_for_given_smk(input_smk) - print "All links deactivated." + else: + print "SMK",input_smk,"is not linked to any MCK." + return def print_all_mck_to_smk_links(self,print_deactivated_links=False): @@ -596,7 +523,7 @@ class MenuAwareMonitoringStandalone: print_all_mck_to_smk_links(True) to print all links.""" if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # get list of all mck_to_smk links @@ -608,7 +535,6 @@ class MenuAwareMonitoringStandalone: # loop over the list in reverse (lowest smk to largest smk) for link in mck_to_smk_links: - # print the results if link['ACTIVE'] == '1': print "SMK",link['SMK'],"is linked to MCK",link['MCK'],"(ACTIVE LINK)" @@ -620,7 +546,7 @@ class MenuAwareMonitoringStandalone: "Input can either be an SMCK_ID or an SMCK_TOOL_PATCH_VERSION. Output will be the the correct SMCK_ID." if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # check for empty print_output_here @@ -630,17 +556,14 @@ class MenuAwareMonitoringStandalone: # test if smck_identifier can be an int (smck_id) try: - # input could be 1.0 or 1, etc. smck_id = int(float(smck_identifier)) - # if we've got this far then we at least have an int # but is it a valid smck_id? smck_info = self.oi.read_smck_info_from_db(smck_id) # if smck_id is not valid, then smck_info will equal -1 if smck_info == -1: - # print warning and return -1, as the smck_identifier is not valid if print_output_here: print "No SMCK found with",smck_identifier @@ -648,19 +571,15 @@ class MenuAwareMonitoringStandalone: # else if it has been found, then return smck_id as it is valid smck_id else: - # return smck_id return smck_id # if smck_identifier is not a number except ValueError: - # get smck_id smck_id = self.oi.get_smck_id_from_smck_tool_patch_version(smck_identifier) - # if no smck_id is found if smck_id == -1: - # print warning and return -1 if print_output_here: print "No SMCK found with",smck_identifier @@ -668,7 +587,6 @@ class MenuAwareMonitoringStandalone: # else if it has been found, then return smck_id else: - # return smck_id return smck_id @@ -677,7 +595,7 @@ class MenuAwareMonitoringStandalone: "Get an SMCK configuration from the Oracle database." if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # check for empty print_output_here @@ -690,15 +608,11 @@ class MenuAwareMonitoringStandalone: # if an smck_id has not been found if smck_id == -1: - # return -1, as no smck_info can be obtained return -1 - else: - # get smck_info smck_info = self.oi.read_smck_info_from_db(smck_id) - # return this smck_info return smck_info @@ -707,23 +621,18 @@ class MenuAwareMonitoringStandalone: """ Check if two releases versions are compatible. If they do, MAM will apply MCKs from either release in the other.""" - project1 = "DummyProject" - project2 = project1 - - if ( "-" in version1 ) and ( "-" in version2 ): - project1 = version1.split("-")[0] - version1 = version1.split("-")[1] - project2 = version2.split("-")[0] - version2 = version2.split("-")[1] - - if ( version1.startswith(version2) or version1.startswith(version2) ) and project1.upper() == project2.upper(): - return True + if type(version2) is list: + if version1 in version2: + return True + elif version1 == version2: + return True + return False def clone_mck_for_new_release(self,mck_id,project="",version=""): if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return if self.readonly_db_connection == True: @@ -768,7 +677,6 @@ class MenuAwareMonitoringStandalone: # create the new mck, this modifies mck_info self.oi.upload_mck(mck_info) - clone_mck_id = mck_info['MCK_ID'] # link this new mck to the original smck_ids @@ -785,7 +693,7 @@ class MenuAwareMonitoringStandalone: Optional comment can be provided.""" if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return if self.readonly_db_connection == True: @@ -799,8 +707,6 @@ class MenuAwareMonitoringStandalone: # if the input is empty, then we exit if input_smck_list == []: - - # info for user if print_output_here: print "No list of SMCK has been provided." print "No MCK upload is possible without a list of SMCKs." @@ -822,11 +728,9 @@ class MenuAwareMonitoringStandalone: # smck is real and not already in the list, so add it smck_ids.append(smck_id) - # check if all smck_id have been found # TODO - CHECK THAT THE -1 CRITERIA IS CORRECT (ie do we need '-1' instead? I don't think so) if smck_ids.__contains__(-1): - # one or more smck are missing. Abort mck upload if print_output_here: print "One or more of the SMCK requested are missing. Aborting MCK upload." @@ -855,8 +759,6 @@ class MenuAwareMonitoringStandalone: # if mck does already exist, then say so and exit if mck_id != -1: - - # info for user if print_output_here: print "This MCK already exists. It is MCK",mck_id return @@ -878,11 +780,9 @@ class MenuAwareMonitoringStandalone: # link this mck to the smck_ids for smck_id in smck_ids: - # upload this link self.oi.upload_mck_smck_link(mck_id,smck_id) - # info for user if print_output_here: print "This MCK has been uploaded. It is MCK",int(mck_id) @@ -894,7 +794,7 @@ class MenuAwareMonitoringStandalone: Optional comment can be provided.""" if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return if self.readonly_db_connection == True: @@ -923,25 +823,18 @@ class MenuAwareMonitoringStandalone: # loop over input for smck_identifier in input_smck_list: - # get smck_id smck_id = self.__get_smck_id_from_smck_identifier__(smck_identifier) - # if an smck_id has not been found if smck_id == -1: - - # info for user if print_output_here: print "Problem with requested SMCK",smck_identifier - # add this smck_id to the smck_ids list smck_ids.append(smck_id) - # check if all smck_id have been found # TODO - CHECK THAT THE -1 CRITERIA IS CORRECT (ie do we need '-1' instead? I don't think so) if smck_ids.__contains__(-1): - # one or more smck are missing. Abort mck upload if print_output_here: print "One or more of the SMCK requested are missing. Aborting MCK upload." @@ -952,8 +845,6 @@ class MenuAwareMonitoringStandalone: # if mck does already exist, then say so and exit if mck_id != -1: - - # info for user if print_output_here: print "This MCK already exists. It is MCK",int(mck_id) return @@ -974,11 +865,9 @@ class MenuAwareMonitoringStandalone: # link this mck to the smck_ids for smck_id in smck_ids: - # upload this link self.oi.upload_mck_smck_link(mck_id,smck_id) - # info for user if print_output_here: print "This MCK has been uploaded. It is MCK",int(mck_id) @@ -994,13 +883,10 @@ class MenuAwareMonitoringStandalone: # create a file-like-object to read the json from input_file = open( input_json_filename , "r" ) - # json decode the local global info, and pass it to self.local_global_info, converting unicode to str self.local_global_info = self.oi.__unicode_to_str__( json.load(input_file) ) - # update self.local self.__update_local_pointer__() - # close the input file input_file.close() @@ -1010,7 +896,7 @@ class MenuAwareMonitoringStandalone: and upload these configurations to the database.""" if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return if self.readonly_db_connection == True: @@ -1022,125 +908,42 @@ class MenuAwareMonitoringStandalone: # check that there are SMCK in this upload if len(self.local_global_info['MONITORING_TOOL_DICT']) == 0: - - # info for user print "The file",input_json_filename,"contains no tool configurations to be uploaded." return # then we extract whether this is a default configuration or not default = int(self.local_global_info['MCK']['MCK_DEFAULT']) - # and we extract the comment, athena version, stream, step, and user - """ - comment = self.local_global_info['MCK']['MCK_COMMENT'] - athena_version = self.local_global_info['MCK']['MCK_ATHENA_VERSION'] - user = self.local_global_info['MCK']['MCK_CREATOR'] - for value in self.local_global_info['MONITORING_TOOL_DICT'].values(): - processing_stream = value['SMCK_PROCESSING_STREAM'] - processing_step = value['SMCK_PROCESSING_STEP'] - break - """ - - # if this is a default config, then use upload_default + # Don't upload defaults to the DB if default == 1: - print "Defaults should not be uploaded to the DB." - #self.upload_default(comment,athena_version,user,print_output_here) - else: - # depreciated: - #self.upload_all_local_changes_as_smck(processing_step,processing_stream,comment,athena_version,user,print_output_here) - - # upload this self.local_global_info to the database, and get the new mck_id and smck_ids - mck_id, smck_ids = self.oi.upload_mck_and_smck(self.local_global_info) - - # print smck info - print "The following SMCK have been created or already exist:" - print "" - - for smck_id in smck_ids: - - # get smck_info - tool_value = self.get_smck_info_from_db(smck_id) - - # print info for this smck - print "SMCK_ID =",tool_value['SMCK_ID'] - print "SMCK_TOOL_PATCH_VERSION =",tool_value['SMCK_TOOL_PATCH_VERSION'] - - # also print mck info - print "" - print "An MCK has been created or already exists, linking to the above SMCK:" - print "MCK_ID =",mck_id - print "" - - # if we are running silently, still return the new_mck_id and new_smck_ids - # (ie. in case this function has been called by another function, which might like to know the new_mck_id and new_smck_ids) - return mck_id, smck_ids - - - def get_default_mck_id_from_db(self,input_athena_version=""): - """Get the MCK number (MCK_ID) of the default for this Athena version. - If input_athena_version=='', the current Athena version is used.""" - - if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "Defaults cannot be uploaded to the DB." return - # if no input Athena version is provided, then use the current version - if input_athena_version == "": - input_athena_version = self.current_athena_version - - # search for default mck - return self.oi.read_default_mck_id_from_db(input_athena_version) - - - def get_default_from_db(self,input_athena_version="",print_output_here=""): - """Prints default MCK number (MCK_ID) for an Athena version. - If no Athena version is specified, the current Athena version being run in is used. - All default information is made available in the <ThisVariable>.default_global_info dictionary.""" - - if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." - return - - # check for empty print_output_here - # if it is found, use self.print_output - if print_output_here == "": - print_output_here = self.print_output - - # info for user - if print_output_here: - print "Attempting to get default tool configuration from database" - - # if no input Athena version is provided, then use the current version - if input_athena_version == "": - input_athena_version = self.current_athena_version + # upload this self.local_global_info to the database, and get the new mck_id and smck_ids + mck_id, smck_ids = self.oi.upload_mck_and_smck(self.local_global_info) - # search for default mck - default_mck = self.get_default_mck_id_from_db(input_athena_version) - - # if a valid default mck exists - if default_mck >= 0: - - # info for user - if print_output_here: - print "Default MCK for Athena version "+input_athena_version+" is",default_mck - - # fill self.default_global_info - self.default_global_info = self.get_global_info_from_db(default_mck) + # print smck info + print "The following SMCK have been created (or already exist):" + for smck_id in smck_ids: + # get smck_info + tool_value = self.get_smck_info_from_db(smck_id) + # print info for this smck + print "SMCK_ID =",tool_value['SMCK_ID'] + print "SMCK_TOOL_PATCH_VERSION =",tool_value['SMCK_TOOL_PATCH_VERSION'] - # if there is no default for this Athena version - else: + # also print mck info + print "An MCK has also been created (or already exists), linking to the above SMCK:" + print "MCK_ID =",int(mck_id) - # info for user - if print_output_here: - print "No default for Athena version "+self.current_athena_version+" has been uploaded" - print "If you are not running with any local changes to the default, then consider running the command \"<ThisVariable>.upload_default()\"" + # return the new_mck_id and new_smck_ids + return mck_id, smck_ids def get_global_info_from_db(self,mck_id): "For an input MCK number (MCK_ID), get all related MCK and SMCK info, and return it as a dictionary." if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # get mck_info for this mck @@ -1153,10 +956,8 @@ class MenuAwareMonitoringStandalone: # loop over smck_ids and get smck_info for smck_id in smck_ids: - # get smck_info smck_info = self.oi.read_smck_info_from_db(smck_id) - # generate monitoring_tool_dict key, a combination of the tool name, # the processing step (if not ALL), # and the processing stream (if not ALL) @@ -1165,7 +966,6 @@ class MenuAwareMonitoringStandalone: smck_key += "_"+smck_info['SMCK_PROCESSING_STEP'] if smck_info['SMCK_PROCESSING_STREAM'] != "ALL": smck_key += "_"+smck_info['SMCK_PROCESSING_STREAM'] - # add this smck_info to monitoring_tool_dict global_info['MONITORING_TOOL_DICT'][smck_key] = smck_info @@ -1173,81 +973,6 @@ class MenuAwareMonitoringStandalone: return global_info - def upload_default(self,comment="",athena_version="",user="",print_output_here=""): - "Upload all current trigger-monitoring tool configurations as default for this Athena version." - - print "Defaults should not be uploaded to the DB." - - # check for empty print_output_here - # if it is found, use self.print_output - if print_output_here == "": - print_output_here = self.print_output - - # check for empty athena_version - # if it is found, use self.current_athena_version - if athena_version == "": - athena_version=self.current_athena_version - - # check for empty user - # if it is found, use self.current_user - if user == "": - user=self.current_user - - # search for default mck - default_mck = self.get_default_mck_id_from_db(athena_version) - - # if it already exists - if default_mck >= 0: - - if print_output_here: - print "There already exists a default MCK for this Athena version:" - print "Athena version: "+athena_version - print "Default MCK:",default_mck - - else: - - # if no comment is provided, then ask for one - if comment=="": - comment = self.__ask_for_comment__() - - # fill mck_info - self.local_global_info['MCK'] = {} - self.local_global_info['MCK']['MCK_DEFAULT'] = 1 - self.local_global_info['MCK']['MCK_ATHENA_VERSION'] = athena_version - self.local_global_info['MCK']['MCK_CREATOR'] = user - self.local_global_info['MCK']['MCK_COMMENT'] = comment - - # update self.local - self.__update_local_pointer__() - - # for each local tool - for tool, smck_info in self.local_global_info['MONITORING_TOOL_DICT'].iteritems(): - - # fill smck_info - smck_info['SMCK_PROCESSING_STEP'] = "ALL" - smck_info['SMCK_PROCESSING_STREAM'] = "ALL" - smck_info['SMCK_DEFAULT'] = 1 - smck_info['SMCK_CREATOR'] = user - smck_info['SMCK_COMMENT'] = comment - - # upload this self.local_global_info to the database, and get the new mck_id and smck_ids - mck_id, smck_ids = self.oi.upload_mck_and_smck(self.local_global_info) - - # info for user - if print_output_here: - print "The default for this Athena version ("+athena_version+") has been uploaded" - print "It has been given the MCK",mck_id - print "" - print "The following tools have had their current configurations uploaded as defaults:" - print "" - for smck_id in smck_ids: - smck_info = self.oi.read_smck_info_from_db(smck_id) - print "Tool:",smck_info['SMCK_TOOL_TYPE'] - print "SMCK:",smck_id - print "SMCK tool patch version:",smck_info['SMCK_TOOL_PATCH_VERSION'] - print "" - - def get_default_from_json(self,input_json_filename=""): """Get a default configuration from a json file and store it as self.default_global_info""" @@ -1261,170 +986,37 @@ class MenuAwareMonitoringStandalone: input_file.close() - def upload_all_local_changes_as_smck(self,processing_step="",processing_stream="",comment="",athena_version="",user="",print_output_here=""): - """Upload all local configuration changes wrt the default. - Optional processing step, stream, and comment can be provided.""" - - print "This function is depreciated, please use mam.make_patch_json and mam.ms.upload_config_from_json instead." - - if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." - return - - if self.readonly_db_connection == True: - print "Your connection is read only, so this function is not available to you." - return - - # check for empty print_output_here - # if it is found, use self.print_output - if print_output_here == "": - print_output_here = self.print_output - - # check for empty athena_version - # if it is found, use self.current_athena_version - if athena_version == "": - athena_version=self.current_athena_version - - # check for empty user - # if it is found, use self.current_user - if user == "": - user=self.current_user - - # search for default mck - default_mck = self.get_default_mck_id_from_db(athena_version) - - # if the default does not exist - if default_mck < 0: - - # info for user - if print_output_here: - print "No default for Athena version "+athena_version+" has been uploaded" - print "If you are not running with any local changes to the default, then consider running the command \"<ThisVariable>.upload_default()\"" - return - - # if no tools are running locally - if len(self.local_global_info['MONITORING_TOOL_DICT']) == 0: - - # exit and suggest to the user how to start the tools, if they so wish - if print_output_here: - print "No trigger monitoring tools are currently set up locally and read in, so they can not have their local configurations uploaded as SMCK." - print "To set up and read in all trigger monitoring tools locally, please run \"<ThisVariable>.setup_all_local_tools()\"" - print "To read in all local tools currently set up, please run \"<ThisVariable>.get_current_local_info()\"" - - return - - # get default from database - self.get_default_from_db(athena_version) - - # create diff of global_info - # we want diffed_global_info2, - # which is the 'patch' to apply to the default to get the current local configuration - diffed_global_info1, diffed_global_info2 = self.__calculate_diff__(self.default_global_info,self.local_global_info,False) - - # if there are no local differences wrt the default, then we upload nothing and exit - if diffed_global_info2 == {}: - # info for user - if print_output_here: - print "No local differences have been found with respect to the default MCK ("+str(default_mck)+") for Athena version "+athena_version+"." - print "Nothing shall be uploaded to the Oracle database as a result." - return - - # if no processing_step is provided, then ask for one - if processing_step=="": - processing_step = self.__ask_for_processing_step__() + def dump_mck_to_json(self,mck_id,output_json_filename=""): + "Dump the contents of an MCK to a json file, including the contents of linked SMCKs" - # if no processing_step is provided, then ask for one - if processing_stream=="": - processing_stream = self.__ask_for_processing_stream__() - - # if no comment is provided, then ask for one - if comment=="": - comment = self.__ask_for_comment__() - - # fill extra mck_info - diffed_global_info2['MCK'] = {} - diffed_global_info2['MCK']['MCK_DEFAULT'] = 0 - diffed_global_info2['MCK']['MCK_ATHENA_VERSION'] = athena_version - diffed_global_info2['MCK']['MCK_CREATOR'] = user - diffed_global_info2['MCK']['MCK_COMMENT'] = comment - - # in case we want to remove any diffed_global_info2['MONITORING_TOOL_DICT'] items, we must make a list of the keys, - # and then delete these keys after we have finished iterating over diffed_global_info2['MONITORING_TOOL_DICT'] - # It is not possible to delete elements while iterating over a list or dict - keys_to_delete = [] - - # fill extra smck_info for all tools - for tool_key, tool_value in diffed_global_info2['MONITORING_TOOL_DICT'].iteritems(): - - # fill extra smck_info - tool_value['SMCK_PROCESSING_STEP'] = processing_step - tool_value['SMCK_PROCESSING_STREAM'] = processing_stream - if not tool_value.__contains__('SMCK_CONFIG'): - tool_value['SMCK_CONFIG'] = {} - tool_value['SMCK_CONFIG']['PackageName'] = self.local_global_info['MONITORING_TOOL_DICT'][tool_key]['SMCK_CONFIG']['PackageName'] - tool_value['SMCK_CONFIG']['ToolName'] = self.local_global_info['MONITORING_TOOL_DICT'][tool_key]['SMCK_CONFIG']['ToolName'] - tool_value['SMCK_CONFIG']['ToolSvcName'] = self.local_global_info['MONITORING_TOOL_DICT'][tool_key]['SMCK_CONFIG']['ToolSvcName'] - if not tool_value['SMCK_CONFIG'].__contains__('ToolInfo'): - tool_value['SMCK_CONFIG']['ToolInfo'] = {} - tool_value['SMCK_CONFIG']['SliceType'] = self.local_global_info['MONITORING_TOOL_DICT'][tool_key]['SMCK_CONFIG']['SliceType'] - tool_value['SMCK_CONFIG']['MonitCategoryName'] = self.local_global_info['MONITORING_TOOL_DICT'][tool_key]['SMCK_CONFIG']['MonitCategoryName'] - if not tool_value['SMCK_CONFIG'].__contains__('MonitCategoryInfo'): - tool_value['SMCK_CONFIG']['MonitCategoryInfo'] = {} - tool_value['SMCK_CONFIG_HASH'] = self.__get_config_hash__(tool_value['SMCK_CONFIG']) - tool_value['SMCK_TOOL_TYPE'] = tool_key - tool_value['SMCK_SLICE_TYPE'] = self.local_global_info['MONITORING_TOOL_DICT'][tool_key]['SMCK_SLICE_TYPE'] - tool_value['SMCK_DEFAULT'] = 0 - tool_value['SMCK_ATHENA_VERSION'] = athena_version - tool_value['SMCK_SVN_TAG'] = self.local_global_info['MONITORING_TOOL_DICT'][tool_key]['SMCK_SVN_TAG'] - tool_value['SMCK_CREATOR'] = user - tool_value['SMCK_COMMENT'] = comment - - # if tool_value['SMCK_CONFIG']['ToolInfo'] and tool_value['SMCK_CONFIG']['MonitCategoryInfo'] are both empty, then we don't want to include this as a new SMCK - if tool_value['SMCK_CONFIG']['ToolInfo'] == {} and tool_value['SMCK_CONFIG']['MonitCategoryInfo'] == {}: - keys_to_delete.append(tool_key) - - # if there are any items in keys_to_delete to be deleted from diffed_global_info2['MONITORING_TOOL_DICT'] then delete them now - for tool_key in keys_to_delete: - diffed_global_info2['MONITORING_TOOL_DICT'].__delitem__(tool_key) - - # if there are no items in diffed_global_info2['MONITORING_TOOL_DICT'] then we do not want to upload anything - if len(diffed_global_info2['MONITORING_TOOL_DICT']) == 0: - - # info for user - if print_output_here: - print "No local differences have been found with respect to the default MCK ("+str(default_mck)+") for Athena version "+athena_version+"." - print "Nothing shall be uploaded to the Oracle database as a result." + mck_info = self.oi.read_mck_info_from_db(mck_id) + if mck_info == -1: + print "MCK",mck_id,"has not been recognised as a valid MCK." return - # upload global_info (diffed_global_info2) - new_mck_id, new_smck_ids = self.oi.upload_mck_and_smck(diffed_global_info2) - - # info for user - if print_output_here: - - # print smck info - print "The following SMCK have been created or already exist:" - print "" + smck_ids = self.oi.read_mck_links_from_db(mck_id) - for smck_id in new_smck_ids: + if output_json_filename == "": + output_json_filename = "MCK_"+str(mck_id)+".json" - # get smck_info - tool_value = self.get_smck_info_from_db(smck_id) + output_file = open( output_json_filename, "w" ) - # print info for this smck - print "SMCK_ID =",tool_value['SMCK_ID'] - print "SMCK_TOOL_PATCH_VERSION =",tool_value['SMCK_TOOL_PATCH_VERSION'] + mck_dump_info = {} + # datetime.datetime objects are not JSON serializable + # seeing as this info is not used later, we replace with the ctime + mck_info['MCK_CREATION_DATE'] = mck_info['MCK_CREATION_DATE'].ctime() + mck_dump_info['MCK'] = mck_info - # also print mck info - print "" - print "An MCK has been created or already exists, linking to the above SMCK:" - print "MCK_ID =",new_mck_id - print "" + # combine rest of the MCK info in the MONITORING_TOOL_DICT + mck_dump_info['MONITORING_TOOL_DICT'] = {} + for smck_id in smck_ids: + smck_info = self.oi.read_smck_info_from_db(smck_id) + smck_info['SMCK_CREATION_DATE'] = smck_info['SMCK_CREATION_DATE'].ctime() + tool_type = smck_info['SMCK_TOOL_TYPE'] + mck_dump_info['MONITORING_TOOL_DICT'][tool_type] = smck_info - # if we are running silently, still return the new_mck_id and new_smck_ids - # (ie. in case this function has been called by another function, which might like to know the new_mck_id and new_smck_ids) - else: - return new_mck_id, new_smck_ids + json.dump(mck_dump_info, output_file, ensure_ascii=True, sort_keys=True) + output_file.close() def search(self,flag1="",input1="",print_output_here=""): @@ -1433,7 +1025,7 @@ class MenuAwareMonitoringStandalone: flag1 specifies what kind of input input1 is.""" if self.connected_to_oracle == False: - print "You are not connected to the database, so this function is not available." + print "MaM is not connected to the database, so this function is not available." return # check for empty print_output_here @@ -1454,8 +1046,6 @@ class MenuAwareMonitoringStandalone: # if the input or flag are missing if flag1 == "": - - #info for user if print_output_here: print "search takes two arguments: flag, input." print "The input is what is to be searched for." @@ -1467,17 +1057,13 @@ class MenuAwareMonitoringStandalone: print "'SMCK_TOOL_TYPE','HLTMuonMon'" print "'MCK_CREATOR','bsmart'" print "'SMCK_SLICE_TYPE','Muon'" - print "" print "Recognised flags are:" # print available columns for row in database_column_list: - # print this column name, with a preceding - print row['COLUMN_NAME'] - # nice spacing for the user - print "" print "You can leave the input blank to print all entries for the flag, but you must enter a flag." # if we do not have the flag, then we can not search, and so must exit @@ -1493,31 +1079,23 @@ class MenuAwareMonitoringStandalone: # loop over columns for row in database_column_list: - # check if this column matches if flag1.upper() == row['COLUMN_NAME']: - # then extract the table name and column name table_name = row['TABLE_NAME'] column_name = row['COLUMN_NAME'] - # and set column_match and break out of this loop column_match = True break # check that we have found the column if not column_match: - - #info for user if print_output_here: print "The flag '"+flag1+"' has not been recognised as a valid flag. Recognised flags are:" - # print available columns for row in database_column_list: - # print this column name, with a preceding - print "-"+row['COLUMN_NAME'] - # no valid flag (column) means we can not search, and so must exit return @@ -1529,46 +1107,31 @@ class MenuAwareMonitoringStandalone: # the input they have provided could be hashed, and the hash could be searched for if flag1 == "smck_config": - # info for the user if print_output_here: - # explain problem - print "" print "You have attempted to search for an SMCK_CONFIG." print "Unfortunately, due to limitations in Oracle, this is not possible." print "This is because the SMCK_CONFIG is stored as a CLOB, and in Oracle it is not possible to perform SQL query comparisons to CLOB objects, (WHERE SMCK_CONFIG = user_input)." - # explain the alternative - print "" print "To allow for SMCK_CONFIG comparisons, each config is hashed (using sha512) and hashes are compared." print "Your input will now be hashed, and that hash will be searched for." print "As this may not be exactly what you intended, do take care when interpreting these search results." - print "" - # convert the flag flag1 = 'smck_config_hash' - # convert the input to a hash input1 = self.__get_config_hash__(input1) - # now lets search search_results_list = self.oi.column_search(input1,table_name,column_name) # and print our results in a neat manner if print_output_here: - # remind the user what was searched for - print "" - print input1,"has been searched for in the column",column_name,"of table",table_name,"in the menu-aware monitoring Oracle database." - print "" + print input1,"has been searched for in the column",column_name,"of table",table_name,"in the Menu-aware Monitoring Oracle database." # if no results have been found if len(search_results_list) == 0: - - # let the user know print "No results have been found." - print "" return # else if results have been found @@ -1576,7 +1139,6 @@ class MenuAwareMonitoringStandalone: # loop over the search results for n, row_dict in enumerate(search_results_list): - # create a name for the row # this is just "Result_n" where n is the row number row_name = "Result_"+str(n) @@ -1589,11 +1151,9 @@ class MenuAwareMonitoringStandalone: # added bonus for the user # if this is an mck table, then we shall find and print out the list of smck that this mck links to if table_name == "MCK_TABLE": - # get the smck_ids smck_ids = self.oi.read_mck_links_from_db(row_dict['MCK_ID']) - # info for user print "" if smck_ids is -1: print row_name,"is an MCK which links to no SMCKs. This MCK is empty." @@ -1613,10 +1173,8 @@ class MenuAwareMonitoringStandalone: # for each smck_id for smck_id in smck_ids: - # get the smck_info smck_info = self.oi.read_smck_info_from_db(smck_id) - # add it to smck_info_dict smck_info_dict[smck_id] = smck_info @@ -1631,10 +1189,8 @@ class MenuAwareMonitoringStandalone: # now we print stuff # for each smck_id for smck_id in smck_ids: - # get the smck_info from the above dictionary smck_info = smck_info_dict[smck_id] - # print some formatted info on this smck print "[ SMCK_ID = "+str(smck_id).ljust(id_ljust)+" , SMCK_TOOL_PATCH_VERSION = "+str(smck_info['SMCK_TOOL_PATCH_VERSION']).ljust(version_ljust)+" , SMCK_SLICE_TYPE = "+str(smck_info['SMCK_SLICE_TYPE']).ljust(slice_ljust)+" ]" @@ -1659,58 +1215,42 @@ class MenuAwareMonitoringStandalone: # loop over the first dictionary for key, value1 in dict1.iteritems(): - # if this key is in the second dictionary if dict2.__contains__(key): - # get the value in the second dictionary value2 = dict2[key] - # first check if the values are equal # (if they are equal, then we don't want to put anything for this key into the return dictionaries) if str(value1) != str(value2): - # are value1 and value2 dictionaries? if so, recursively call __calculate_diff__ if type(value1) is dict and type(value2) is dict: - # recursively call __calculate_diff__ and fill return dictionaries return_dict1_temp, return_dict2_temp = self.__calculate_diff__(value1,value2,diff_all) - # check that the output is not identical # this catches the case when diff_all==False # where str(value1) != str(value2) because at least one of the dicts contains a key that the other doesn't # but all the matching keys have identical values # which causes the return_dicts to be equal (blank) if return_dict1_temp != return_dict2_temp: - # fill return dictionaries return_dict1[key] = return_dict1_temp return_dict2[key] = return_dict2_temp - else: - # fill return dictionaries with the different values return_dict1[key] = value1 return_dict2[key] = value2 - # else if this key is not in the second dictionary else: - #if we are adding all differences to the return dicts if diff_all: - # then add this key and value to the first return dict return_dict1[key] = value1 - #if we are adding all differences to the return dicts if diff_all: - # loop over the second dictionary for key, value2 in dict2.iteritems(): - # if this key is not in the first dictionary if not dict1.__contains__(key): - # then add this key and value to the second return dict return_dict2[key] = value2 @@ -1723,20 +1263,15 @@ class MenuAwareMonitoringStandalone: # loop over the keys (and values) in dict1 for key, value1 in dict1.iteritems(): - # if the value is a dict if type(value1) is dict: - # first print this dict key print tab_space+name1+"['"+key+"']:" - # recursively call this function # add some space to tab_space, to indent the sub-dictionary self.__print_one_dict__(value1," "+tab_space,name1) - # if the value is a list elif type(value1) is list: - # print the items nicely (no unicode u' features) print tab_space+name1+"['"+key+"'] = [", for n, item in enumerate(value1): @@ -1747,14 +1282,13 @@ class MenuAwareMonitoringStandalone: if n != len(value1)-1: print ",", print "]" - # else if this value is not a dict or a list, then we should print else: print tab_space+name1+"['"+key+"'] =",value1 def create_sqlite_file_to_copy_to_cool(self,mck,run,runend="",info="",project="",version=""): - """Create ad sqlite file which can be used to manually add data to COOL""" + """Create an sqlite file which can be used to manually add data to COOL""" # this way https://twiki.cern.ch/twiki/bin/view/AtlasComputing/CoolPublishing#Updating_data_on_the_online_data if runend and run >= runend: @@ -1777,7 +1311,7 @@ class MenuAwareMonitoringStandalone: print "If you want to assign an MCK to a new release consider using the function mam.ms.clone_mck_for_new_release(mck_id,project="",version="")" print "Continuing but ignoring project and version variables..." - # TO ADD: check that run exists + # TODO: check that run exists # something similar to http://acode-browser.usatlas.bnl.gov/lxr/ident?_i=getOnlineRun from PyCool import cool @@ -1790,7 +1324,7 @@ class MenuAwareMonitoringStandalone: # column definition schema = [('MonConfigKey', cool.StorageType.UInt32), # the mck - ('Info', cool.StorageType.String4k)] # optional info (currently unused) + ('Info', cool.StorageType.String4k)] # optional info # create sqlite file print 'Creating sqlite file' diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/OracleInterface.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/OracleInterface.py index 1a1a0ae00d8b4df9bcbb7a1400c2b1e7115c5d58..ba23ef7ed2c85b87cf3f0a151015531d6aa153a8 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/OracleInterface.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/OracleInterface.py @@ -1,8 +1,7 @@ # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -# -# Authors: Ben Smart (bsmart@cern.ch) & Xanthe Hoad (xanthe.hoad@cern.ch) -# +# Authors: Ben Smart (ben.smart@cern.ch), Xanthe Hoad (xanthe.hoad@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information import sys # needed for oracle database connection @@ -209,10 +208,8 @@ class OracleInterface: # dict of new smck smck_ids = [] - # make new smck for tool_key, tool_info in tool_list.iteritems(): - # upload each smck, and add the smck_id to the list # if the smck config already exists, then the existing smck_id will be returned smck_ids.append(self.upload_smck(tool_info)) @@ -222,16 +219,12 @@ class OracleInterface: # if the mck does not already exist if mck_id == -1: - # get the mck info mck_info = global_info['MCK'] - # make a new mck mck_id = self.upload_mck(mck_info) - # now link the mck to the smck for smck_id in smck_ids: - # create link self.upload_mck_smck_link(mck_id,smck_id) @@ -284,15 +277,12 @@ class OracleInterface: # if it is not in the database if smck_id == -1: - # get new smck_tool_patch_version smck_info['SMCK_TOOL_PATCH_VERSION'] = self.get_next_smck_tool_patch_version(smck_info['SMCK_TOOL_TYPE']) - # prepare insert data insert = {} for key in smck_info.keys(): - #if key != 'SMCK_CONFIG': - insert[key] = ":"+key + insert[key] = ":"+key # prepare insert data for things that are set by the server insert['SMCK_ID'] = self.directory+"seq_smck_table_id.NEXTVAL" # from sequence @@ -329,12 +319,9 @@ class OracleInterface: # if the smck_info is already in database else: - # get existing smck_info existing_smck_info = self.read_smck_info_from_db(smck_id) - # fill with the existing values - #smck_info = existing_smck_info # why doesn't this work? smck_info['SMCK_ID'] = smck_id smck_info['SMCK_TOOL_PATCH_VERSION'] = existing_smck_info['SMCK_TOOL_PATCH_VERSION'] @@ -364,20 +351,16 @@ class OracleInterface: # check if mck already exists search_results = self.check_if_mck_exists(smck_ids) - # check if there is an exact match # if not, leave mck_id = -1 mck_id = -1 # first check if links were found if search_results != -1: - # loop over possible matches for row_mck_id in search_results: - # check if this is an exact match if len(self.read_mck_links_from_db(row_mck_id)) == len(smck_ids): - # if so, this is the existing mck mck_id = row_mck_id break @@ -397,7 +380,6 @@ class OracleInterface: # for each smck_id, find mck that link to that smck # returned mck_id must link to all smck for smck_id in smck_ids: - # add a sub-query for each smck query += "AND "+self.directory+"mck_table.mck_id IN (SELECT "+self.directory+"mck_to_smck_link.link_mck FROM "+self.directory+"mck_to_smck_link WHERE "+self.directory+"mck_to_smck_link.link_smck = "+str(smck_id)+" ) " @@ -735,17 +717,14 @@ class OracleInterface: # test that the table and column names are valid table_and_column_match = False for row in database_schema: - # check if the table and column match if row['TABLE_NAME'] == table_name.upper() and row['COLUMN_NAME'] == column_name.upper(): - # we have a match table_and_column_match = True break # if there was no match if not table_and_column_match: - # no match, so return the empty list return return_list @@ -758,8 +737,6 @@ class OracleInterface: query = query+" WHERE "+column_name+" = :INPUT1" parameters_dict['INPUT1'] = input1 - #query = "SELECT * FROM "+self.directory+table_name+" WHERE "+column_name+" = :INPUT1" - # perform the search search_results = self.fetch(query,parameters_dict) @@ -769,7 +746,6 @@ class OracleInterface: # if this row belongs to the desired table if schema_row['TABLE_NAME'] == table_name: - # then we add this column name to our list # we need to add it to the start of the list (insert before element 0), # as the database table/column search function returns the results in reversed order(?) @@ -779,10 +755,8 @@ class OracleInterface: # loop over results for result_row in search_results: - # the length of column_list should be the same as the length of result_row if len(column_list) != len(result_row): - # something has gone very wrong print "ERROR in OracleInterface.column_search(",input1,",",table_name,",",column_name,")" print "column_list =",column_list @@ -795,7 +769,6 @@ class OracleInterface: # need to check if this is an smck, # in which case we need to turn the json CLOB into a dict if table_name == 'SMCK_TABLE': - # first we read out the CLOB # then we turn the json string into a dict #row_dict['SMCK_CONFIG'] = json.loads(row_dict['SMCK_CONFIG'].read()) diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/PackagesToInterrogate.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/PackagesToInterrogate.py index b0073c3de9b2d57208e92295b18a7f47fdb89bf6..64125dd269570c7219c9b4263ebd18d540af95bf 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/PackagesToInterrogate.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/PackagesToInterrogate.py @@ -1,8 +1,7 @@ # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -# -# Author: Ben Smart (bsmart@cern.ch) -# +# Authors: Ben Smart (ben.smart@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information # put all storage of information on tool package names etc. in a single class class PackagesToInterrogate: diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/ToolInterrogator.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/ToolInterrogator.py index 09a34eb68c521b2e6177ca390bb1189241c33955..1194f1b70fe6bd07d418687c373fb41e9601296f 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/ToolInterrogator.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/ToolInterrogator.py @@ -1,8 +1,7 @@ # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -# -# Author: Ben Smart (bsmart@cern.ch) -# +# Authors: Ben Smart (ben.smart@cern.ch), Xanthe Hoad (xanthe.hoad@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information import sys # needed for getting package names etc. of tools @@ -29,7 +28,7 @@ class ToolInterrogator: def load_all_tools(self): "Set up all trigger-monitoring tools, such that they can be interrogated." - # info for user + print "Now setting up all trigger-monitoring tools." print "" print "#"*10 @@ -44,7 +43,7 @@ class ToolInterrogator: # then initialise the tool exec "%s()" % (value['ToolName']) - # info for user + print "" print "#"*10 print "" @@ -229,7 +228,7 @@ class ToolInterrogator: # # is the object equal to itself after packing and unpacking (it should be) # if throwaway_test_object != value: - # # info for user + # # print "In",tool_ToolSvc_name,", the object",prop,"has the value",value # print "However, after json dumping and loading, this object has the value",throwaway_test_object # print "As these values are not equal, the object can not be stored and accurately retrieved from the database, and thus will not be stored." @@ -292,7 +291,7 @@ class ToolInterrogator: # # is the object equal to itself after packing and unpacking (it should be) # if throwaway_test_object != item_value: - # # info for user + # # print "In",monitCategoryName,", the object",item_name,"has the value",item_value # print "However, after json dumping and loading, this object has the value",throwaway_test_object # print "As these values are not equal, the object can not be stored and accurately retrieved from the database, and thus will not be stored." diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/scripts/MCKtoCOOLmanual.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/scripts/MCKtoCOOLmanual.py index 5e373e753b2504a36a1546a1ae99210299c77b8c..9d302014838199ec1e87dd5754e46023a09aad2c 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/python/scripts/MCKtoCOOLmanual.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/python/scripts/MCKtoCOOLmanual.py @@ -1,7 +1,8 @@ # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -# Author: X. Hoad <xhoad@cern.ch> -# for use at P1 from /det/tdaq/hlt/mam/python +# Script to update MCKs in COOL for use at P1 +# Author: Xanthe Hoad (xanthe.hoad@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information import argparse import sys diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/run/TrigHLTMon_tf.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/run/TrigHLTMon_tf.py index 9f7b4ac30f406be1ca04503363a7aede0e2790f5..9ccfaa3a18304e2a725e673f38b36cd513ef1a4c 100755 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/run/TrigHLTMon_tf.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/run/TrigHLTMon_tf.py @@ -6,7 +6,7 @@ __doc__ = """JobTransform to run TrigHLTMonitoring standalone jobs""" import sys from PyJobTransforms.transform import transform -from PyJobTransforms.trfExe import athenaExecutor +from PyJobTransforms.trfExe import athenaExecutor,DQMergeExecutor from PyJobTransforms.trfArgs import addAthenaArguments, addDetectorArguments import PyJobTransforms.trfArgClasses as trfArgClasses @@ -14,15 +14,15 @@ if __name__ == '__main__': executorSet = set() executorSet.add(athenaExecutor(name = 'HLTMon', skeletonFile = 'TrigHLTMonitoring/skeleton.HLTMon_tf.py', - substep = 'r2a', inData = ['BS','AOD'], outData = ['HIST'])) - - trf = transform(executor = executorSet) + substep = 'r2a', inData = ['BS','AOD'], outData = ['HIST_TEMP'])) + executorSet.add(DQMergeExecutor(name = 'DQHistogramMerge', inData = ['HIST_TEMP'], outData = ['HIST'])) + trf = transform(executor = executorSet) addAthenaArguments(trf.parser) - trf.parser.defineArgGroup('TrigHLTMon', 'HLT Monitoring transform arguments') + trf.parser.defineArgGroup('TrigHLTMon args', 'HLT Monitoring transform arguments') trf.parser.add_argument('--inputBSFile', nargs='+', type=trfArgClasses.argFactory(trfArgClasses.argBSFile, io='input'), help='Input bytestream file', group='TrigHLTMon args') - + trf.parser.add_argument('--inputAODFile', nargs='+', type=trfArgClasses.argFactory(trfArgClasses.argPOOLFile, io='input'), help='Input pool file', group='TrigHLTMon args') @@ -33,11 +33,9 @@ if __name__ == '__main__': trf.parser.add_argument('--useDB',type=trfArgClasses.argFactory(trfArgClasses.argBool),help='Use TrigConfigSvc',) - trf.parser.defineArgGroup('Monitoring Args', 'Monitoring options') + trf.parser.defineArgGroup('Monitoring args', 'Monitoring options') trf.parser.add_argument('--monFlags', nargs='+',type=trfArgClasses.argFactory(trfArgClasses.argList), - help='TrigHLTMon histogram switches', group='TrigHLTMon args') + help='TrigHLTMon histogram switches', group='Monitoring args') trf.parseCmdLineArgs(sys.argv[1:]) trf.execute() trf.generateReport() - - diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/HLTMonitoring_topOptions.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/HLTMonitoring_topOptions.py index 4390f1b0e7c048b8bf8bc72eb30cdf8b7f49d20e..ef946cf29b8b5c78dd69a5c49fab474e5ee6277e 100755 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/HLTMonitoring_topOptions.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/HLTMonitoring_topOptions.py @@ -9,7 +9,6 @@ if not 'DQMonFlags' in dir(): from AthenaMonitoring.DQMonFlags import DQMonFlags ########## control step assignment ######### - if DQMonFlags.monManEnvironment == 'tier0Raw': # we are in RAW->ESD step # run all tools *except* the following (these are run in ESD->AOD) @@ -26,6 +25,7 @@ if DQMonFlags.monManEnvironment == 'tier0Raw': HLTMonFlags.doMinBias = False HLTMonFlags.doDump = False HLTMonFlags.doOfflineTauTTP = False + HLTMonFlags.doMaM = False elif DQMonFlags.monManEnvironment == 'tier0ESD': log.info('Environment is tier0ESD') # we are in ESD->AOD step @@ -41,6 +41,7 @@ else : log.info('Switching all tools off...') HLTMonFlags.doGeneral = False HLTMonFlags.doMonTier0 = False + HLTMonFlags.doMaM = False # remove flag for IDJpsi monitoring in anticipation of the code # being removed diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/TrigHLTMonCommon_jobOptions.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/TrigHLTMonCommon_jobOptions.py index 0536060a911fa2a2e381fab2e4331a4fe5aa74f2..060a9fae2665d273eafd2e100b84c76505d2fcae 100755 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/TrigHLTMonCommon_jobOptions.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/TrigHLTMonCommon_jobOptions.py @@ -30,6 +30,10 @@ log.info("Beam type %s",beam_type) log.info("Trigger stream %s",rec.triggerStream()) #log.info("Event type %s",evt_type) +# enable PerfMon +from PerfMonComps.PerfMonFlags import jobproperties +jobproperties.PerfMonFlags.doFastMon = True + #set up DQMonFlags required for HLTMonitoring from AthenaMonitoring.DQMonFlags import DQMonFlags if globalflags.DataSource.get_Value() == 'geant4': @@ -55,10 +59,14 @@ if data_type == 'pool': DQMonFlags.monManEnvironment = 'tier0' DQMonFlags.monManStream=rec.triggerStream() -log.info('DQMonFlags %s',DQMonFlags) +DQMonFlags.monManRun=runNb +log.info('DQMonFlags %s',DQMonFlags) log.info('RecFlags %s', rec) +from AthenaCommon.AlgSequence import AlgSequence +topSequence = AlgSequence() + if not 'HLTMonFlags' in dir(): from TrigHLTMonitoring.HLTMonFlags import HLTMonFlags @@ -71,8 +79,6 @@ if HLTMonFlags.doBphys: #-- set up job ------------------------------------------------------------------------------ if data_type == 'bytestream': log.info('BS to HIST Monitoring') - from AthenaCommon.AlgSequence import AlgSequence - topSequence = AlgSequence() # Only doGeneral monitoring from RAW HLTMonFlags.set_All_Off() @@ -103,7 +109,6 @@ if data_type == 'bytestream': if data_type == 'pool': log.info('AOD to HIST Monitoring') - algseq = CfgMgr.AthSequencer("AthAlgSeq") import AthenaPoolCnvSvc.ReadAthenaPool svcMgr.EventSelector.InputCollections=athenaCommonFlags.PoolAODInput() @@ -123,15 +128,55 @@ if data_type == 'pool': if runArgs.useDB: from TriggerJobOpts.TriggerConfigGetter import TriggerConfigGetter cfg = TriggerConfigGetter() - ToolSvc.TrigDecisionTool.TrigConfigSvc = "Trig::TrigConfigSvc/TrigConfigSvc" + else: + log.info("Configure TrigConfigSvc by default") + from TriggerJobOpts.TriggerConfigGetter import TriggerConfigGetter + cfg = TriggerConfigGetter() + ToolSvc.TrigDecisionTool.TrigConfigSvc = "Trig::TrigConfigSvc/TrigConfigSvc" - # enable basic flags to run monitoring - # all other flags go through runArgs.monFlags - HLTMonFlags.doGeneral = True + # enable slices for monitoring + # otherwise enable slices via monFlags HLTMonFlags.doMonTier0 = True - + if not hasattr(runArgs,"monFlags"): + HLTMonFlags.doGeneral = True + HLTMonFlags.doEgamma = True + HLTMonFlags.doMET = True + HLTMonFlags.doJet = True + HLTMonFlags.doBjet = True + HLTMonFlags.doTau = True + HLTMonFlags.doMuon = True + HLTMonFlags.doIDtrk = True + HLTMonFlags.doIDJpsiMon = True + HLTMonFlags.doCalo = True + HLTMonFlags.doBphys = False + HLTMonFlags.doMinBias = False + + #-- setup DQTDataFlow ------------------------------------------------------------------------------ + from AthenaMonitoring.AthenaMonitoringConf import AthenaMonManager + topSequence += AthenaMonManager( "GlobalMonManager" ) + ManagedAthenaGlobalMon = topSequence.GlobalMonManager + ManagedAthenaGlobalMon.FileKey = "GLOBAL" + ManagedAthenaGlobalMon.ManualDataTypeSetup = DQMonFlags.monManManualDataTypeSetup() + ManagedAthenaGlobalMon.DataType = DQMonFlags.monManDataType() + ManagedAthenaGlobalMon.Environment = DQMonFlags.monManEnvironment() + + from DataQualityTools.DataQualityToolsConf import DQTDataFlowMonTool + import os + if 'AtlasProject' in os.environ and 'AtlasVersion' in os.environ: + releaseString = '%s-%s' % (os.environ['AtlasProject'], + os.environ['AtlasVersion']) + else: + releaseString = 'Unknown' + + DQTDataFlowMon = DQTDataFlowMonTool(name = 'DQTDataFlowMon', + histoPathBase = '/GLOBAL/DQTDataFlow', + releaseString = releaseString) + ToolSvc += DQTDataFlowMon + ManagedAthenaGlobalMon.AthenaMonTools += [ DQTDataFlowMon ] + #-- set up output histogram file ------------------------------------------------------------------------------ +log.info('HLTFlags %s', HLTMonFlags) from GaudiSvc.GaudiSvcConf import THistSvc svcMgr += THistSvc() @@ -139,14 +184,15 @@ svcMgr.THistSvc.Output += ["GLOBAL DATAFILE='" + DQMonFlags.histogramFile() + "' include( "TrigHLTMonitoring/HLTMonitoring_topOptions.py" ) -if hasattr(runArgs,"useDB") or data_type == 'bytestream': - pass -else: - log.info("Update tools to use xAODConfigTool") - for tool in ToolSvc.getAllChildren(): - tool_prop = tool.getDefaultProperties() - for prop,value in tool_prop.iteritems(): - if prop == "TrigConfigTool": - log.info("Set TrigConfigTool %s",tool.getName()) - tool.TrigConfigTool="TrigConf::xAODConfigTool" - +if hasattr(runArgs,"useDB"): + if runArgs.useDB: + pass + elif not runArgs.useDB: + log.info("Update tools to use xAODConfigTool") + for tool in ToolSvc.getAllChildren(): + tool_prop = tool.getDefaultProperties() + for prop,value in tool_prop.iteritems(): + if prop == "TrigConfigTool": + log.info("Set TrigConfigTool %s",tool.getName()) + tool.TrigConfigTool="TrigConf::xAODConfigTool" + diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/addMonTools.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/addMonTools.py index 7bef6912a1ed91ce26fff1f801cf7bf90627e0b5..6bf5dd7c525924ad5834a25b5ec0b945044d6838 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/addMonTools.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/addMonTools.py @@ -19,8 +19,8 @@ from RecExConfig.RecFlags import rec # if not 'HLTMonFlags' in dir(): # from TrigHLTMonitoring.HLTMonFlags import HLTMonFlags # -# if not 'DQMonFlags' in dir(): -# from AthenaMonitoring.DQMonFlags import DQMonFlags +if not 'DQMonFlags' in dir(): + from AthenaMonitoring.DQMonFlags import DQMonFlags ################ Mon Tools ################# @@ -29,7 +29,10 @@ if HLTMonFlags.doMonTier0: if HLTMonFlags.doBphys and rec.doInDet: include( "TrigBphysMonitoring/RunJpsiFinder.py" ) -topSequence += AthenaMonManager( "HLTMonManager") +topSequence += AthenaMonManager("HLTMonManager", + Run=DQMonFlags.monManRun(), + DataType=DQMonFlags.monManDataType(), + Environment=DQMonFlags.monManEnvironment()) HLTMonManager = topSequence.HLTMonManager #Global HLTMonTool @@ -41,13 +44,10 @@ if HLTMonFlags.doGeneral: log.info("Problems with the general HLTMonTool, tool not enabled") if HLTMonFlags.doMonTier0: - # HLTEgammaMonTool - Calculates basic efficiencies if HLTMonFlags.doEgamma: try: if rec.doCalo and rec.doInDet: -# from TrigEgammaMonitoring.TrigEgammaMonitoringConfig import HLTEgammaMonitoringTool -# HLTMonManager.AthenaMonTools += HLTEgammaMonitoringTool() from TrigEgammaMonitoring.TrigEgammaMonitoringConfig import TrigEgammaMonitoringTool HLTMonManager.AthenaMonTools += TrigEgammaMonitoringTool() except: @@ -159,145 +159,10 @@ if HLTMonFlags.doDump: except: log.info("Problems with OfflineTauTTP, tool not enabled") -############################################ ########## Menu-aware Monitoring ########### -#HLTMonFlags.doMaM = True -#HLTMonFlags.doMaM_ApplyMCK = True - if HLTMonFlags.doMaM == True: - - # MaM needs to check whether it is running in a Trigger reprocessing job or not, and start an instance of MaM connected to the correct database accordingly - trigger_reco_tf_job = False - - if hasattr(runArgs, "DBserver") and runArgs.DBserver == "TRIGGERDBREPR": - trigger_reco_tf_job = True - elif hasattr(runArgs, "triggerConfig") and "TRIGGERDBREPR" in runArgs.triggerConfig: - trigger_reco_tf_job = True - - from TrigHLTMonitoring.MenuAwareMonitoring import MenuAwareMonitoring - if trigger_reco_tf_job: - log.info("Will attempt to doMaM with TRIGGERDBREPR") - mam = MenuAwareMonitoring("TRIGGERDBREPR_R") - else: - log.info("Will attempt to doMaM with TRIGGERDB") - mam = MenuAwareMonitoring() - - if mam.ms.connected_to_oracle == False: - log.error("Menu-Aware Monitoring: Cannot doMaM without database connection") - else: - # if a specific Monitoring Configuration Key (MCK) has been set, then use it - if HLTMonFlags.MCK.StoredValue > 0: - if mam.ms.oi.check_if_mck_id_exists( HLTMonFlags.MCK.StoredValue ): - if mam.does_mck_athena_version_match_current_athena_version( HLTMonFlags.MCK.StoredValue ): - log.info("MCK found via transform %d" % HLTMonFlags.MCK.StoredValue ) - # if we are applying configurations to tools according to an MCK, then do that here - if HLTMonFlags.doMaM_ApplyMCK: - log.info("Applying MCK %d" % HLTMonFlags.MCK.StoredValue) - mam.apply_mck( HLTMonFlags.MCK.StoredValue ) - else: - log.error("MCK for a different release found via transform: %d" % HLTMonFlags.MCK.StoredValue ) - else: - log.error("MCK found via transform (%d) is not a vaid MCK." % HLTMonFlags.MCK.StoredValue ) - - # if HLTMonFlags.MCK is -1 (the default) we try to determine the MCK automatically, as long as this is not MC - is_not_sim = True - from RecExConfig.InputFilePeeker import inputFileSummary - if inputFileSummary.__contains__('evt_type'): - if 'IS_SIMULATION' in inputFileSummary['evt_type']: - log.info("Will not try to get MCK automatically as we are running on MC") - is_not_sim = False - - if HLTMonFlags.MCK.StoredValue == -1 and is_not_sim: - if trigger_reco_tf_job: - # for trigger repro jobs, need to check the transform arguments and get the SMK from there, then use the linked MCK. - # no COOL interaction in these jobs - SMKrepr = None - - if hasattr(runArgs, "DBsmkey") and runArgs.DBsmkey!="NONE": - SMKrepr = int(runArgs.DBsmkey) - - elif hasattr(runArgs, "triggerConfig") and runArgs.triggerConfig!="NONE": - SMKrepr = int(runArgs.triggerConfig.split(":")[-1].split(",")[0]) - - else: - log.error("Menu-Aware Monitoring: Could not get SMK from DBsmkey or triggerConfig runArgs") - - if SMKrepr is not None: - log.info("SMK from runArgs %d" % SMKrepr) - # we now have the required input info. Use mam to get the appropriate MCK - MCKfromSMKrepr = mam.get_mck_id_from_smk(SMKrepr) - - # if the MCK is > 0 and is from the right release then apply it, otherwise use the default tool configurations - if MCKfromSMKrepr > 0: - if mam.does_mck_athena_version_match_current_athena_version( MCKfromSMKrepr ): - HLTMonFlags.MCK.StoredValue = MCKfromSMKrepr - log.info("MCK found via SMK link %d" % HLTMonFlags.MCK.StoredValue) - if HLTMonFlags.doMaM_ApplyMCK: - log.info("Applying MCK %d" % HLTMonFlags.MCK.StoredValue) - mam.apply_mck( HLTMonFlags.MCK.StoredValue ) - else: - log.info("MCK for a different release found via SMK link: %d -> MCK ignored." % HLTMonFlags.MCK.StoredValue) - elif MCKfromSMKrepr == 0: - HLTMonFlags.MCK.StoredValue = MCKfromSMKrepr - log.info("MCK found via SMK link: 0 -> Default configuration used.") - - else: - # try to get the MCK from COOL - if inputFileSummary.__contains__('bs_metadata') or inputFileSummary.__contains__('run_number'): - # get the run number for the input - if inputFileSummary.__contains__('bs_metadata'): - run_number = inputFileSummary['bs_metadata']['run_number'] - else: - run_number = int(inputFileSummary['run_number'][0]) - pointintime = (int(run_number)<<32) - - from PyCool import cool - # try to connect to the COOL database - from CoolConvUtilities.AtlCoolLib import indirectOpen - connstring = "COOLONL_TRIGGER/CONDBR2" # get the MCK from COOL - coolDB=indirectOpen(connstring,oracle='True') - if coolDB is None: - log.error("Menu-Aware Monitoring: Unable to connect to %s to get MCK from COOL." % connstring) - else: - # try to get the MCK out of COOL - foldername = 'MenuAwareMonConfigKey' - MCKfolder=coolDB.getFolder('/TRIGGER/HLT/' + foldername ) - release_tag = foldername + '-' + mam.ms.current_athena_version - - # need to retrieve for the right release using tags using a try-except - try: - retrieved_obj=MCKfolder.findObject(pointintime,0,release_tag) - retrieved_payload=retrieved_obj.payload() - retrieved_format=retrieved_payload['MonConfigKey'] - MonitoringConfigurationKey = int(retrieved_format) - HLTMonFlags.MCK.StoredValue = MonitoringConfigurationKey - coolDB.closeDatabase() - if HLTMonFlags.MCK.StoredValue == 0: - log.info("MCK 0 found in COOL folder %s for release %s -> No MCK applied." % (foldername,mam.ms.current_athena_version)) - except: - log.info("No MCK in COOL folder %s for release %s -> No MCK applied." % (foldername,mam.ms.current_athena_version)) - - if HLTMonFlags.MCK.StoredValue > 0: - if mam.ms.oi.check_if_mck_id_exists( HLTMonFlags.MCK.StoredValue ): - if mam.does_mck_athena_version_match_current_athena_version( HLTMonFlags.MCK.StoredValue ): - log.info("MCK found via COOL %d" % HLTMonFlags.MCK.StoredValue) - if HLTMonFlags.doMaM_ApplyMCK: - log.info("Applying MCK %d" % HLTMonFlags.MCK.StoredValue) - mam.apply_mck( HLTMonFlags.MCK.StoredValue ) - else: - log.error("MCK for a different release (%d) found in COOL folder (%s) with tag (%s)." % (HLTMonFlags.MCK.StoredValue,foldername,release_tag)) - else: - log.error("MCK found via COOL (%d) in COOL folder (%s) with tag (%s) is not a vaid MCK." % (HLTMonFlags.MCK.StoredValue,foldername,release_tag)) - else: - log.error("Menu-Aware Monitoring: Unable to get run number from metadata") - - # if dumping the tool configurations (as a .json file) has been requested, then do that here - if HLTMonFlags.doMaM_ExtractAndDumpConfigs == True: - log.info("Will attempt to extract final trigger monitoring tool configurations and dump them to %s" % (HLTMonFlags.MaM_OutputJSON.StoredValue)) - # get updated configs for all tools, and dump them to HLTMonFlags.MaM_OutputJSON.StoredValue - mam.get_current_local_info() - mam.make_default_json(HLTMonFlags.MaM_OutputJSON.StoredValue,comment="Final job config") + include( "TrigHLTMonitoring/runMaM.py" ) ############################################ diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/runMaM.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/runMaM.py new file mode 100644 index 0000000000000000000000000000000000000000..05ed5574aaf772aa7ec656ced2d2be50f4c31f2c --- /dev/null +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/runMaM.py @@ -0,0 +1,148 @@ +# Authors: Ben Smart (ben.smart@cern.ch), Xanthe Hoad (xanthe.hoad@cern.ch) +# See https://twiki.cern.ch/twiki/bin/view/Atlas/MaDQM for more information + +from AthenaCommon.Logging import logging +log = logging.getLogger( 'TrigHLTMonitoring/MenuAwareMonitoring' ) + +########## Menu-aware Monitoring ########### + +if HLTMonFlags.doMaM == True: + + # check whether we are running in a trigger reprocessing job or not + checkSMKrepr = True; + for arg in sys.argv: + if 'HLTMon_tf' in arg: + HLTMonFlags.doMaM_UseReproDB.set_Value_and_Lock( True ) + checkSMKrepr = False + if HLTMonFlags.doMaM_UseReproDB.get_Value() == False: + if hasattr(runArgs, "DBserver") and runArgs.DBserver == "TRIGGERDBREPR": + HLTMonFlags.doMaM_UseReproDB.set_Value_and_Lock( True ) + elif hasattr(runArgs, "triggerConfig") and "TRIGGERDBREPR" in runArgs.triggerConfig: + HLTMonFlags.doMaM_UseReproDB.set_Value_and_Lock( True ) + + # start an instance of MaM connected to the correct database accordingly + from TrigHLTMonitoring.MenuAwareMonitoring import MenuAwareMonitoring + if HLTMonFlags.doMaM_UseReproDB.get_Value() == True: + log.info("Will attempt to doMaM with TRIGGERDBREPR") + mam = MenuAwareMonitoring("TRIGGERDBREPR_R") + else: + log.info("Will attempt to doMaM with TRIGGERDB") + mam = MenuAwareMonitoring() + + if mam.ms.connected_to_oracle == False: + log.error("Cannot doMaM without database connection") + else: + # if a specific Monitoring Configuration Key (MCK) has been set, then use it + if HLTMonFlags.MCK.get_Value() > 0: + if mam.ms.oi.check_if_mck_id_exists( HLTMonFlags.MCK.get_Value() ): + if mam.does_mck_athena_version_match_current_athena_version( HLTMonFlags.MCK.get_Value() ): + log.info("MCK found via transform %d" % HLTMonFlags.MCK.get_Value()) + # if we are applying configurations to tools according to an MCK, then do that here + if HLTMonFlags.doMaM_ApplyMCK: + log.info("Applying MCK %d" % HLTMonFlags.MCK.get_Value()) + mam.apply_mck( HLTMonFlags.MCK.get_Value() ) + else: + log.error("MCK for a different release found via transform: %d" % HLTMonFlags.MCK.get_Value() ) + else: + log.error("MCK found via transform (%d) is not a valid MCK" % HLTMonFlags.MCK.get_Value() ) + + # if HLTMonFlags.MCK is -1 (the default) we try to determine the MCK automatically, as long as this is not MC + isNotSIM = True + from RecExConfig.InputFilePeeker import inputFileSummary + if inputFileSummary.__contains__('evt_type'): + if 'IS_SIMULATION' in inputFileSummary['evt_type']: + log.info("Will not try to get MCK automatically as we are running on MC") + isNotSIM = False + + if HLTMonFlags.MCK.get_Value() == -1 and isNotSIM: + if HLTMonFlags.doMaM_UseReproDB.get_Value() == True: + if checkSMKrepr == True: + # for Trig_reco_tf, check the transform arguments and get the SMK from there, then use the linked MCK + # don't check via SMK for TrigHLTMon_tf + # no COOL interaction in these jobs + SMKrepr = None + if hasattr(runArgs, "DBsmkey") and runArgs.DBsmkey!="NONE": + SMKrepr = int(runArgs.DBsmkey) + elif hasattr(runArgs, "triggerConfig") and runArgs.triggerConfig!="NONE": + SMKrepr = int(runArgs.triggerConfig.split(":")[-1].split(",")[0]) + else: + log.info("Could not get SMK from DBsmkey or triggerConfig runArgs") + + if SMKrepr is not None: + log.info("SMK from runArgs %d" % SMKrepr) + # we now have the required input info. Use MaM to get the appropriate MCK + MCKfromSMKrepr = mam.get_mck_id_from_smk( SMKrepr ) + # if the MCK is > 0 and is from the right release then apply it, otherwise use the default tool configurations + if MCKfromSMKrepr > 0: + if mam.does_mck_athena_version_match_current_athena_version( MCKfromSMKrepr ): + HLTMonFlags.MCK.set_Value_and_Lock( MCKfromSMKrepr ) + log.info("MCK %d found via SMK link" % HLTMonFlags.MCK.get_Value()) + if HLTMonFlags.doMaM_ApplyMCK: + log.info("Applying MCK %d" % HLTMonFlags.MCK.get_Value()) + mam.apply_mck( HLTMonFlags.MCK.get_Value() ) + else: + log.info("MCK %d found via SMK link is not valid in this release -> no MCK will be applied" % HLTMonFlags.MCK.get_Value()) + elif MCKfromSMKrepr == 0: + HLTMonFlags.MCK.set_Value_and_Lock( MCKfromSMKrepr ) + log.info("MCK 0 found via SMK link -> no MCK will be applied") + else: + log.info("Not checking for MCK via SMK link (TrigHLTMon_tf mode)") + + else: + # try to get the MCK from COOL + if inputFileSummary.__contains__('bs_metadata') or inputFileSummary.__contains__('run_number'): + + # get the run number + if inputFileSummary.__contains__('bs_metadata'): + run_number = inputFileSummary['bs_metadata']['run_number'] + else: + run_number = int(inputFileSummary['run_number'][0]) + pointintime = (int(run_number)<<32) + + # try to connect to the COOL database + from PyCool import cool + from CoolConvUtilities.AtlCoolLib import indirectOpen + connstring = "COOLONL_TRIGGER/CONDBR2" # get the MCK from COOL + coolDB=indirectOpen(connstring,oracle='True') + + if coolDB is None: + log.error("Unable to connect to %s to get MCK from COOL" % connstring) + else: + # try to get the MCK out of COOL + foldername = 'MenuAwareMonConfigKey' + MCKfolder=coolDB.getFolder('/TRIGGER/HLT/' + foldername) + release_tag = foldername + '-' + mam.ms.current_athena_version + + # try retrieve and MCK for the correct release + try: + retrieved_obj=MCKfolder.findObject(pointintime,0,release_tag) + retrieved_payload=retrieved_obj.payload() + retrieved_format=retrieved_payload['MonConfigKey'] + MonitoringConfigurationKey = int(retrieved_format) + HLTMonFlags.MCK.set_Value_and_Lock( MonitoringConfigurationKey ) + coolDB.closeDatabase() + if HLTMonFlags.MCK.get_Value() == 0: + log.info("MCK 0 found in COOL folder %s for release %s -> no MCK will be applied" % (foldername,mam.ms.current_athena_version)) + except: + log.info("No MCK in COOL folder %s for release %s -> no MCK will be applied" % (foldername,mam.ms.current_athena_version)) + + if HLTMonFlags.MCK.get_Value() > 0: + if mam.ms.oi.check_if_mck_id_exists(HLTMonFlags.MCK.get_Value()): + if mam.does_mck_athena_version_match_current_athena_version(HLTMonFlags.MCK.get_Value()): + log.info("MCK %d found in COOL folder %s for release %s" % (HLTMonFlags.MCK.get_Value(),foldername,release_tag)) + if HLTMonFlags.doMaM_ApplyMCK: + log.info("Applying MCK %d" % HLTMonFlags.MCK.get_Value()) + mam.apply_mck(HLTMonFlags.MCK.get_Value()) + else: + log.error("MCK %d found in COOL folder %s with tag %s is not a valid in this release" % (HLTMonFlags.MCK.get_Value(),foldername,release_tag)) + else: + log.error("MCK %d found in COOL folder %s with tag %s is not a valid MCK" % (HLTMonFlags.MCK.get_Value(),foldername,release_tag)) + else: + log.error("Unable to get run number from metadata") + + # if dumping the tool configurations (as a .json file) has been requested, then do that here + if HLTMonFlags.doMaM_ExtractAndDumpConfigs == True: + log.info("Will attempt to extract final trigger monitoring tool configurations and dump them to %s" % (HLTMonFlags.MaM_OutputJSON.get_Value())) + # get updated configs for all tools, and dump them to HLTMonFlags.MaM_OutputJSON.get_Value() + mam.get_current_local_info(print_output_here=False) + mam.make_default_json(HLTMonFlags.MaM_OutputJSON.get_Value(),comment="Final job config") diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/skeleton.HLTMon_tf.py b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/skeleton.HLTMon_tf.py index a40b60d8d45bcd0593cccbfb734bf201751856de..b94b17765a0150b315064d7a998ea1b0f385e674 100644 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/share/skeleton.HLTMon_tf.py +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/share/skeleton.HLTMon_tf.py @@ -34,40 +34,43 @@ monDict = { 'Bjet':False, 'MinBias':False, 'IDJpsiMon':False, + 'MaM':True, + 'MaM_ApplyMCK':True, + 'MaM_UseReproDB':False } if hasattr(runArgs,"inputBSFile"): - rec.readRDO.set_Value_and_Lock( True ) + rec.readRDO.set_Value_and_Lock(True) rec.doAOD=True globalflags.InputFormat.set_Value_and_Lock('bytestream') athenaCommonFlags.BSRDOInput.set_Value_and_Lock( runArgs.inputBSFile ) if hasattr(runArgs,"inputAODFile"): rec.readAOD.set_Value_and_Lock(True) - rec.readRDO.set_Value_and_Lock( False ) - + rec.readRDO.set_Value_and_Lock(False) + globalflags.InputFormat.set_Value_and_Lock('pool') athenaCommonFlags.PoolAODInput.set_Value_and_Lock( runArgs.inputAODFile ) -if hasattr(runArgs,"outputHISTFile"): +if hasattr(runArgs,"outputHIST_TEMPFile"): rec.doMonitoring.set_Value_and_Lock(False) from AthenaMonitoring.DQMonFlags import DQMonFlags DQMonFlags.doMonitoring.set_Value_and_Lock(False) - DQMonFlags.histogramFile.set_Value_and_Lock( runArgs.outputHISTFile ) + DQMonFlags.histogramFile.set_Value_and_Lock( runArgs.outputHIST_TEMPFile ) DQMonFlags.doHLTMon.set_Value_and_Lock(True) if hasattr(runArgs,"monFlags"): for flag in runArgs.monFlags: onoff = flag[:2] monType = flag[2:] - # Note that we can add new validation types on the fly + # Note that we can add new validation types on the fly if onoff == 'do': monDict[monType] = True elif onoff == 'no': monDict[monType] = False else: monLog.warning("Ignored unrecognised validation control string for {0}: {1}".format(monType, flag)) - + monLog.info("Validation switches are set to: {0}".format(monDict)) # Schedule individual validations if not 'HLTMonFlags' in dir(): diff --git a/Trigger/TrigMonitoring/TrigHLTMonitoring/src/HLTMonTool.cxx b/Trigger/TrigMonitoring/TrigHLTMonitoring/src/HLTMonTool.cxx index 31aa267d59c608c0e9dfda393fcd202c15fb27cb..4421c7f0571cfdb48802480e047475f807514e6c 100755 --- a/Trigger/TrigMonitoring/TrigHLTMonitoring/src/HLTMonTool.cxx +++ b/Trigger/TrigMonitoring/TrigHLTMonitoring/src/HLTMonTool.cxx @@ -548,10 +548,11 @@ StatusCode HLTMonTool::fillForChain(const std::string& chain){ // ------------ Fill RoI Histograms --------------- if (rsIt->first=="RAW" && isHLTChain) { std::vector<Trig::Feature<TrigRoiDescriptor> >::const_iterator roiIt; - //Hack to avoid combinatorics from GSC chains ATR-16670 - if (chain.find("gsc") != std::string::npos) { - continue; - } + //Hack to avoid combinatorics from GSC chains ATR-16670 + //Removed in 2018/2019 pseudomerged following fix in jet trigger monitoring https://gitlab.cern.ch/atlas/athenaprivate1/merge_requests/16753 + //if (chain.find("gsc") != std::string::npos) { + //continue; + //} const std::vector<Trig::Feature<TrigRoiDescriptor> > rois = (getTDT()->features(chain)).get<TrigRoiDescriptor>("initialRoI"); for (roiIt=rois.begin(); roiIt!=rois.end(); ++roiIt) { const TrigRoiDescriptor* roi = roiIt->cptr(); diff --git a/Trigger/TrigMonitoring/TrigMuonMonitoring/python/TrigMuonMonitCategory.py b/Trigger/TrigMonitoring/TrigMuonMonitoring/python/TrigMuonMonitCategory.py index 292685694b0c90a567aba75bc2df6747ff27ae5d..5f6e786270651a756e002bd831c52f03fdf9e1cd 100644 --- a/Trigger/TrigMonitoring/TrigMuonMonitoring/python/TrigMuonMonitCategory.py +++ b/Trigger/TrigMonitoring/TrigMuonMonitoring/python/TrigMuonMonitCategory.py @@ -13,6 +13,7 @@ monitoring_muonIso_pp = ['HLT_mu26_ivarmedium'] monitoring_MSonly = ['HLT_mu60_0eta105_msonly'] monitoring_MSonly_HI = ['HLT_mu15_msonly'] monitoring_MSonly_pp = ['HLT_mu60_0eta105_msonly'] +monitoring_MSonly_pp = [''] #monitoring_muonEFFS = ['HLT_mu22_mu8noL1'] monitoring_muonEFFS = ['HLT_mu24_mu8noL1']