Source code for bsmart.scripts.prepare_bsmart

#!/usr/bin/env python3
from __future__ import annotations
"""

Script to create or update template json files for BSMArt.

Use after prepareModel
This is used by the example scripts too, so you can have multiple scans per model without rerunning all the codes


The only relevant argument is the model name, which should correspond to a file in the ScriptsAndLogs directory (BSMArt_data_<modelname>.json)

2025/01/29

"""



import os
import sys

import shutil
import json
import collections

import argparse

#import compactJSON





[docs] class CompactJSONEncoder(json.JSONEncoder): """A JSON Encoder that puts small containers on single lines.""" CONTAINER_TYPES = (list, tuple, dict) """Container datatypes include primitives or other containers.""" MAX_WIDTH = 70 """Maximum width of a container that might be put on a single line.""" MAX_ITEMS = 10 """Maximum number of items in container that might be put on single line.""" def __init__(self, *args, **kwargs): # using this class without indentation is pointless if kwargs.get("indent") is None: kwargs["indent"] = 4 super().__init__(*args, **kwargs) self.indentation_level = 0
[docs] def encode(self, o): """Encode JSON object *o* with respect to single line lists.""" if isinstance(o, (list, tuple)): return self._encode_list(o) if isinstance(o, dict): return self._encode_object(o) if isinstance(o, float): # Use scientific notation for floats return format(o, "g") return json.dumps( o, skipkeys=self.skipkeys, ensure_ascii=self.ensure_ascii, check_circular=self.check_circular, allow_nan=self.allow_nan, sort_keys=self.sort_keys, indent=self.indent, separators=(self.item_separator, self.key_separator), default=self.default if hasattr(self, "default") else None, )
def _encode_list(self, o): if self._put_on_single_line(o): return "[" + ", ".join(self.encode(el) for el in o) + "]" self.indentation_level += 1 output = [self.indent_str + self.encode(el) for el in o] self.indentation_level -= 1 return "[\n" + ",\n".join(output) + "\n" + self.indent_str + "]" def _encode_object(self, o): if not o: return "{}" # ensure keys are converted to strings o = {str(k) if k is not None else "null": v for k, v in o.items()} if self.sort_keys: o = dict(sorted(o.items(), key=lambda x: x[0])) if self._put_on_single_line(o): return ( "{ " + ", ".join( f"{json.dumps(k)}: {self.encode(el)}" for k, el in o.items() ) + " }" ) self.indentation_level += 1 output = [ f"{self.indent_str}{json.dumps(k)}: {self.encode(v)}" for k, v in o.items() ] self.indentation_level -= 1 return "{\n" + ",\n".join(output) + "\n" + self.indent_str + "}"
[docs] def iterencode(self, o, **kwargs): """Required to also work with `json.dump`.""" return self.encode(o)
def _put_on_single_line(self, o): return ( self._primitives_only(o) and len(o) <= self.MAX_ITEMS and len(str(o)) - 2 <= self.MAX_WIDTH ) def _primitives_only(self, o: list | tuple | dict): if isinstance(o, (list, tuple)): return not any(isinstance(el, self.CONTAINER_TYPES) for el in o) elif isinstance(o, dict): return not any(isinstance(el, self.CONTAINER_TYPES) for el in o.values()) @property def indent_str(self) -> str: if isinstance(self.indent, int): return " " * (self.indentation_level * self.indent) elif isinstance(self.indent, str): return self.indentation_level * self.indent else: raise ValueError( f"indent must either be of type int or str (is: {type(self.indent)})" )
######################################################################################################## #def updateBSMArtTemplate(modelname,bsmart_dict,paths_dict,includecodes,template_dict,template_name):
[docs] def updateBSMArtTemplate(modelname,bsmart_dict,paths_dict,in_includecodes,template,template_name=None): with open(template,'r') as IF: template_dict = json.load(IF,object_pairs_hook=collections.OrderedDict) # need the name of the template file -> we'll keep it if template_name is None: template_path,template_name = os.path.split(template) else: template_path,_ = os.path.split(template) cwd=os.getcwd() includecodes={} for code in in_includecodes: if in_includecodes[code] and code in paths_dict: includecodes[code] = True else: includecodes[code] = False if 'VevaciousPlusPlus' in template_dict: includecodes['VevaciousPlusPlus'] = includecodes['Vevacious++'] if 'SARAH' not in paths_dict: includecodes['VevaciousPlusPlus'] = False else: includecodes['VevaciousPlusPlus'] = False outjson=template_dict if 'SPhenoOutputDir' in bsmart_dict and 'BSMArtmodelname' in bsmart_dict and includecodes['SPheno']: sarahsphdir=bsmart_dict["SPhenoOutputDir"] internalmodelname=str(bsmart_dict['BSMArtmodelname']) #sphenotarget=os.path.join(paths_dict["SPheno"],modelname) else: sarahsphdir=None internalmodelname=modelname #sphenotarget=None includecodes['SPheno'] = False BSMArtScanDir=os.path.join(cwd,'BSMArt_'+modelname) if not os.path.exists(BSMArtScanDir): os.makedirs(BSMArtScanDir) if 'SPheno' in template_dict['Codes']: if includecodes['SPheno']: outjson['Codes']['SPheno']['Command'] = os.path.join(paths_dict['SPheno'],'bin','SPheno'+internalmodelname) #template='LesHouches.in.'+internalmodelname #template_low='LesHouches.in.'+internalmodelname+'_low' inputfile=os.path.basename(template_dict['Codes']['SPheno']['InputFile']) if inputfile== '': inputfile='LesHouches.in.'+internalmodelname paramfile=os.path.join(template_path,inputfile) if not os.path.exists(paramfile): # take default :) paramfile =os.path.join(sarahsphdir,'Input_Files','LesHouches.in.'+internalmodelname) if os.path.exists(paramfile): shutil.copy(paramfile,BSMArtScanDir) outputfile='' #if 'FlexibleSUSY' in template_dict['Codes']: # why??? # outputfile=os.path.basename(template_dict['Codes']['FlexibleSUSY'].get('OutputFile','')) outputfile=os.path.basename(template_dict['Codes']['SPheno'].get('OutputFile','')) if outputfile == '': outputfile='SPheno.spc.'+internalmodelname paramfile2=os.path.join(sarahsphdir,'Input_Files','LesHouches.in.'+internalmodelname+'_low') if os.path.exists(paramfile2): shutil.copy(paramfile2,BSMArtScanDir) QNUMBERS_slha='QNUMBERS_'+internalmodelname+'.slha' if os.path.exists(os.path.join(sarahsphdir,'Input_Files',QNUMBERS_slha)): shutil.copy(os.path.join(sarahsphdir,'Input_Files',QNUMBERS_slha),BSMArtScanDir) else: QNUMBERS_slha='QNUMBERS_'+modelname+'.slha' if os.path.exists(os.path.join(cwd,'ScriptsAndLogs',QNUMBERS_slha)): ## in this case, older version of SARAH so no duplicate shutil.copy(os.path.join(cwd,'ScriptsAndLogs',QNUMBERS_slha),BSMArtScanDir) outjson['Codes']['SPheno']['InputFile']=inputfile outjson['Codes']['SPheno']['OutputFile'] = outputfile if 'Spectrum File' not in outjson['Setup'] or outjson['Setup']['Spectrum File'] == '': outjson['Setup']['Spectrum File'] = outputfile #QNUMBERS_slha=os.path.join(BSMArtScanDir,QNUMBERS_slha) else: #outjson['Codes']['SPheno']["Run"] = "False" outjson['Codes'].pop('SPheno') # delete!! if 'FlexibleSUSY' in template_dict['Codes']: if includecodes['FlexibleSUSY'] and 'FSmodelname' in bsmart_dict: FSmodelname=bsmart_dict['FSmodelname'] FSmodeldir=os.path.join(paths_dict['FlexibleSUSY'],'models',FSmodelname) outjson['Codes']['FlexibleSUSY']['Command'] = os.path.join(FSmodeldir,'run_'+FSmodelname+'.x') #template='LesHouches.in.'+internalmodelname #template_low='LesHouches.in.'+internalmodelname+'_low' inputfile=os.path.basename(template_dict['Codes']['FlexibleSUSY']['InputFile']) if inputfile== '': inputfile='LesHouches.in.'+FSmodelname outputfile=os.path.basename(template_dict['Codes']['FlexibleSUSY'].get('OutputFile','')) if outputfile == '': outputfile='FlexibleSUSY.spc.'+FSmodelname paramfile=os.path.join(template_path,inputfile) #if os.path.exists(inputfile): # paramfile=inputfile #else: if not os.path.exists(paramfile): paramfile =os.path.join(FSmodeldir,inputfile) if os.path.exists(paramfile): destparamfile=os.path.join(BSMArtScanDir,inputfile) if os.path.exists(destparamfile): # if initial template actually contained the correct input then we are using both SPheno & FS, so ok # Otherwise we need to rename if template_dict['Codes']['FlexibleSUSY']['InputFile'] == '': inputfile+='.FS' destparamfile=os.path.join(BSMArtScanDir,inputfile) shutil.copy(paramfile,destparamfile) else: shutil.copy(paramfile,destparamfile) outjson['Codes']['FlexibleSUSY']['InputFile']=inputfile outjson['Codes']['FlexibleSUSY']['OutputFile'] = outputfile ## Cannot run SPheno and FlexibleSUSY at the same time by default (needs special care) if 'SPheno' in outjson['Codes'] and eval(outjson['Codes']['SPheno']['Run']): outjson['Codes']['FlexibleSUSY']['Run'] = "False" else: #outjson['Codes']['FlexibleSUSY']["Run"] = "False" outjson['Codes'].pop('FlexibleSUSY') # delete! #if args.HiggsBounds or args.HiggsSignals or args.All: if includecodes['HiggsBounds'] or includecodes['HiggsSignals']: if 'Hneutral' not in bsmart_dict or 'Hcharged' not in bsmart_dict: includecodes['HiggsBounds']=False includecodes['HiggsSignals']=False else: HBdata=str(bsmart_dict['Hneutral'])+' '+str(bsmart_dict['Hcharged']) if includecodes['MicrOMEGAs']: targetmodir=os.path.join(paths_dict["MicrOMEGAs"],'SARAH_'+modelname) #MOexec=os.path.join(targetmodir,'MicrOmegas_v5.3_BSMArt') if 'MicrOMEGAs executable' in bsmart_dict: MOexec=bsmart_dict['MicrOMEGAs executable'] else: #print('Missing MO exec!') #if not os.path.exists(MOexec): includecodes['MicrOMEGAs'] = False ## Move vevacious files and create the init files #if args.VevaciousPlusPlus or args.All: if includecodes['VevaciousPlusPlus']: sarahVVdir=os.path.join(paths_dict["SARAH"],'Output',modelname,'Vevacious') if not os.path.exists(sarahVVdir): includecodes['VevaciousPlusPlus'] = False if includecodes['VevaciousPlusPlus']: sarahVVdir=os.path.join(paths_dict["SARAH"],'Output',modelname,'Vevacious') BSMVevaciousdir=os.path.join(BSMArtScanDir,'Vevacious') if os.path.exists(BSMVevaciousdir): shutil.rmtree(BSMVevaciousdir) os.makedirs(BSMVevaciousdir) shutil.copy(os.path.join(sarahVVdir,internalmodelname+'.vin'),BSMVevaciousdir) shutil.copy(os.path.join(sarahVVdir,'ScaleAndBlock.xml'),os.path.join(BSMVevaciousdir,internalmodelname+'.xml')) #shutil.copy(os.path.join(BSMVevaciousdir,'ScaleAndBlock.xml'),BSMVevaciousdir) #for ff in [internalmodelname+'.vin','ScaleAndBlock.xml']: # shutil.copy(os.path.join(BSMVevaciousdir,ff),BSMArtScanDir) VVPotentialFile=os.path.join(BSMVevaciousdir,'PotentialFunctionInitialization.xml') with open(VVPotentialFile,'w') as VVP: VVP.write('<VevaciousPlusPlusPotentialFunctionInitialization>\n') VVP.write('<LagrangianParameterManagerClass>\n') VVP.write('<ClassType>\n SlhaCompatibleWithSarahManager\n </ClassType>\n') VVP.write('<ConstructorArguments>\n <ScaleAndBlockFile>\n') VVP.write(os.path.join(BSMVevaciousdir,internalmodelname+'.xml')) #VVP.write(os.path.join(BSMVevaciousdir,'ScaleAndBlock.xml')) VVP.write(' </ScaleAndBlockFile></ConstructorArguments>\n') VVP.write('</LagrangianParameterManagerClass>\n') VVP.write('<PotentialFunctionClass>\n<ClassType> \n FixedScaleOneLoopPotential \n </ClassType>\n <ConstructorArguments>\n') VVP.write('<ModelFile>\n') VVP.write(os.path.join(BSMVevaciousdir,internalmodelname+'.vin')) VVP.write('</ModelFile>\n') VVP.write('<AssumedPositiveOrNegativeTolerance>\n 0.5 \n </AssumedPositiveOrNegativeTolerance> \n </ConstructorArguments>\n </PotentialFunctionClass>\n') VVP.write('</VevaciousPlusPlusPotentialFunctionInitialization>\n') ### NEW: Copy over the initialisation files instead of using the THDM ones VVPotentialInitFile=os.path.join(BSMVevaciousdir,'PotentialMinimizerInitialization.xml') shutil.copy(os.path.join(paths_dict['Vevacious++'],'InitializationFiles','THDMInitializationFiles','PotentialMinimizerInitialization.xml'),VVPotentialInitFile) ## edit the line to use VVTunnelingFile=os.path.join(BSMVevaciousdir,'TunnelingCalculatorInitialization.xml') shutil.copy(os.path.join(paths_dict['Vevacious++'],'InitializationFiles','THDMInitializationFiles','TunnelingCalculatorInitialization.xml'),VVTunnelingFile) VVinitfile=os.path.join(BSMVevaciousdir,internalmodelname+'Initialization.xml') with open(VVinitfile,'w') as VVF: VVF.write('<VevaciousPlusPlusObjectInitialization>\n') VVF.write(' <PotentialFunctionInitializationFile>\n') VVF.write(VVPotentialFile+'\n') VVF.write(' </PotentialFunctionInitializationFile>\n') VVF.write(' <PotentialMinimizerInitializationFile>\n') ## Use THDM VVF.write(VVPotentialInitFile+'\n') #VVF.write(os.path.join(paths_dict['Vevacious++'],'InitializationFiles','THDMInitializationFiles','PotentialMinimizerInitialization.xml')+'\n') #/ada1/lpthe/goodsell/Scratch/SPheno/Vevacious++/VevaciousPlusPlus/InitializationFiles/MSSMInitialization/PotentialMinimizerInitialization.xml VVF.write(' </PotentialMinimizerInitializationFile>\n') VVF.write(' <TunnelingCalculatorInitializationFile>\n') VVF.write(VVTunnelingFile+'\n') ## Use THDM #VVF.write(os.path.join(paths_dict['Vevacious++'],'InitializationFiles','THDMInitializationFiles','TunnelingCalculatorInitialization.xml')+'\n') #/ada1/lpthe/goodsell/Scratch/SPheno/Vevacious++/VevaciousPlusPlus/InitializationFiles/MSSMInitialization/TunnelingCalculatorInitialization.xml VVF.write(' </TunnelingCalculatorInitializationFile>\n') VVF.write(' </VevaciousPlusPlusObjectInitialization>\n') #OF2=open(os.path.join(BSMArtScanDir,'Template_'+modelname+'.json'),'w') #if args.HiggsBounds or args.All: if 'HiggsBounds' in template_dict['Codes']: if includecodes['HiggsBounds'] and 'HiggsBounds' in paths_dict: outjson['Codes']['HiggsBounds']['Command'] = os.path.join(paths_dict['HiggsBounds'],'HiggsBounds') if 'Neutral Higgs' not in template_dict['Codes']['HiggsBounds'] or template_dict['Codes']['HiggsBounds']['Neutral Higgs'] is None: outjson['Codes']['HiggsBounds']["Neutral Higgs"] = bsmart_dict['Hneutral'] outjson['Codes']['HiggsBounds']["Charged Higgs"]= bsmart_dict['Hcharged'] else: #outjson['Codes']['HiggsBounds']["Run"] = "False" outjson['Codes'].pop('HiggsBounds') #if args.HiggsSignals or args.All: if 'HiggsSignals' in template_dict['Codes']: if includecodes['HiggsSignals'] and 'HiggsSignals' in paths_dict: outjson['Codes']['HiggsSignals']['Command'] = os.path.join(paths_dict['HiggsSignals'],'HiggsSignals') if 'Neutral Higgs' not in template_dict['Codes']['HiggsSignals'] or template_dict['Codes']['HiggsSignals']['Neutral Higgs'] is None or template_dict['Codes']['HiggsTools']['Neutral Higgs'] == []: outjson['Codes']['HiggsSignals']["Neutral Higgs"] = bsmart_dict['Hneutral'] outjson['Codes']['HiggsSignals']["Charged Higgs"]= bsmart_dict['Hcharged'] outjson['Codes']['HiggsSignals']["Options"] = 'latestresults 2 effC '+HBdata else: #outjson['Codes']['HiggsSignals']["Run"] = "False" outjson['Codes'].pop('HiggsSignals') if 'Neutral Higgs' not in bsmart_dict or "Charged Higgs" not in bsmart_dict or 'HiggsBoundsRepo' not in paths_dict or 'HiggsSignalsRepo' not in paths_dict: includecodes['HiggsTools'] = False if 'HiggsTools' in template_dict['Codes']: if includecodes['HiggsTools']: outjson['Codes']['HiggsTools']["HiggsBounds Dataset"] = paths_dict['HiggsBoundsRepo'] outjson['Codes']['HiggsTools']["HiggsSignals Dataset"] = paths_dict['HiggsSignalsRepo'] if 'Neutral Higgs' not in template_dict['Codes']['HiggsTools'] or template_dict['Codes']['HiggsTools']['Neutral Higgs'] is None or template_dict['Codes']['HiggsTools']['Neutral Higgs'] == []: outjson['Codes']['HiggsTools']["Neutral Higgs"] = bsmart_dict['Neutral Higgs'] outjson['Codes']['HiggsTools']["Charged Higgs"] = bsmart_dict['Charged Higgs'] else: #outjson['Codes']['HiggsTools']["Run"] = "False" outjson['Codes'].pop('HiggsTools') if 'MicrOmegas' in template_dict['Codes']: if includecodes['MicrOMEGAs']: outjson['Codes']['MicrOmegas']['Command'] = MOexec if "InputFile" not in outjson['Codes']['MicrOmegas'] or outjson['Codes']['MicrOmegas']['InputFile'] is None or outjson['Codes']['MicrOmegas']['InputFile'] == '': outjson['Codes']['MicrOmegas']["InputFile"] = "SPheno.spc."+internalmodelname else: #outjson['Codes']['MicrOmegas']['Run'] = "False" outjson['Codes'].pop('MicrOmegas') if 'flavio' in template_dict['Codes']: outjson['Codes']['flavio']['InputFile']= "WCXF.SMEFT."+internalmodelname #if args.VevaciousPlusPlus or args.All: if 'VevaciousPlusPlus' in template_dict['Codes']: if includecodes['VevaciousPlusPlus']: outjson['Codes']['VevaciousPlusPlus']['Command'] = os.path.join(paths_dict['Vevacious++'],'bin','VevaciousPlusPlus') outjson['Codes']['VevaciousPlusPlus']["Initialization File"] = VVinitfile else: #outjson['Codes']['VevaciousPlusPlus']["Run"] = "False" outjson['Codes'].pop('VevaciousPlusPlus') if 'Vevacious++' in outjson['Codes']: outjson['Codes'].pop('Vevacious++') if 'HackAnalysis_LO' in template_dict['Codes']: if 'hackanalysis' in paths_dict: outjson['Codes']['HackAnalysis_LO']["Command"] = os.path.join(paths_dict['hackanalysis'],'analysePYTHIA.exe') if "YAML file" not in outjson['Codes']['HackAnalysis_LO'] or outjson['Codes']['HackAnalysis_LO']['YAML file'] is None or outjson['Codes']['HackAnalysis_LO']['YAML file'] == '': outjson['Codes']['HackAnalysis_LO']["YAML file"] = "LOpythia.yaml" outjson['Codes']['HackAnalysis_LO']["Config file"]= "LO.cfg" if "Efficiency Filename" not in outjson['Codes']['HackAnalysis_LO'] or outjson['Codes']['HackAnalysis_LO']['Efficiency Filename'] is None or outjson['Codes']['HackAnalysis_LO']['Efficiency Filename'] == '': outjson['Codes']['HackAnalysis_LO']["Efficiency Filename"] = internalmodelname+".eff" outjson['Codes']['HackAnalysis_LO']["Cutflow Filename"] = internalmodelname+".cutflow" outjson['Codes']['HackAnalysis_LO']["Histogram Filename"] = internalmodelname+".yoda" else: #outjson['Codes']['HackAnalysis_LO']["Run"] = "False" outjson['Codes'].pop('HackAnalysis_LO') if 'MadGraphHackAnalysis' in template_dict['Codes']: if 'hackanalysis' in paths_dict and 'madgraph' in paths_dict: outjson['Codes']['MadGraphHackAnalysis']["HackAnalysis"] = os.path.join(paths_dict['hackanalysis'],'analysePYTHIA_LHE.exe') outjson['Codes']['MadGraphHackAnalysis']["MadGraph"] =os.path.join(paths_dict['madgraph'],internalmodelname,'bin','generate_events') if "YAML file" not in outjson['Codes']['MadGraphHackAnalysis'] or outjson['Codes']['MadGraphHackAnalysis']['YAML file'] is None or outjson['Codes']['MadGraphHackAnalysis']['YAML file'] == '': outjson['Codes']['MadGraphHackAnalysis']["YAML file"] = "LOpythia.yaml" outjson['Codes']['MadGraphHackAnalysis']["Config file"]= "LO.cfg" if "Efficiency Filename" not in outjson['Codes']['MadGraphHackAnalysis'] or outjson['Codes']['MadGraphHackAnalysis']['Efficiency Filename'] is None or outjson['Codes']['MadGraphHackAnalysis']['Efficiency Filename'] == '': outjson['Codes']['MadGraphHackAnalysis']["Efficiency Filename"] = internalmodelname+".eff" outjson['Codes']['MadGraphHackAnalysis']["Cutflow Filename"] = internalmodelname+".cutflow" outjson['Codes']['MadGraphHackAnalysis']["Histogram Filename"] = internalmodelname+".yoda" else: #outjson['Codes']['MadGraphHackAnalysis']["Run"] = "False" outjson['Codes'].pop('MadGraphHackAnalysis') if 'ZPEED' in template_dict['Codes']: if 'ZPEED' in paths_dict and includecodes['MicrOMEGAs']: outjson['Codes']['ZPEED']["Path"] = paths_dict['ZPEED'] else: #outjson['Codes']['ZPEED']["Run"] = "False" outjson['Codes'].pop('ZPEED') includecodes['ZPEED'] = False if 'Zprime' in template_dict['Codes']: if not includecodes['MicrOMEGAs']: outjson['Codes']['Zprime']['Run'] = "False" outjson['Codes'].pop('Zprime') if 'SModelS' in template_dict['Codes']: if includecodes['SModelS'] and 'SModelS' in paths_dict: Defaultsmodelsinifile=os.path.join(paths_dict['SModelS'],'parameters.ini') templatesmodelsinifile="" if 'Parameter file' in template_dict['Codes']['SModelS']: templatesmodelsinifile=template_dict['Codes']['SModelS']['Parameter file'] #else: # templatesmodelsinifile=Defaultsmodelsinifile #else: # templatesmodelsinifile="" # base template contains it but defines it to be "" if templatesmodelsinifile != "" and os.path.exists(templatesmodelsinifile): # For the case where the parameters.ini is provided as a template! Just need to copy it #smodelsinifile=os.path.join(BSMArtScanDir,templatesmodelsinifile)# smodelsinifile=os.path.join(BSMArtScanDir,os.path.basename(templatesmodelsinifile)) #smodelsinifile=os.path.join(BSMArtScanDir,'smodels_parameters.ini') outjson['Codes']['SModelS']['Parameter file'] = smodelsinifile # will always rename it to smodels_parameters.ini try: shutil.copy(templatesmodelsinifile,smodelsinifile) except: # probably target already exists! pass else: if templatesmodelsinifile != "": # have named the file, but it's not present smodelsinifile=os.path.join(BSMArtScanDir,os.path.basename(templatesmodelsinifile)) else: smodelsinifile=os.path.join(BSMArtScanDir,'smodels_parameters.ini') outjson['Codes']['SModelS']['Parameter file'] = smodelsinifile if os.path.exists(Defaultsmodelsinifile): IF=open(Defaultsmodelsinifile,'r') OFS=open(smodelsinifile,'w') for line in IF: if line.startswith('model=share.models.mssm'): OFS.write('; '+line) OFS.write('model='+os.path.join(BSMArtScanDir,QNUMBERS_slha)+'\n') else: OFS.write(line) OFS.close() IF.close() outjson['Codes']['SModelS']['Path'] = paths_dict['SModelS'] outjson['Codes']['SModelS']['Cache'] = paths_dict['SModelS Cache'] #outjson['Codes']['SModelS']["QNUMBERS file"] = QNUMBERS_slha outjson['Codes']['SModelS']["QNUMBERS file"] = os.path.join(BSMArtScanDir,QNUMBERS_slha) else: #outjson["Codes"]["SModelS"]["Run"] = "False" outjson['Codes'].pop('SModelS') if 'MultiNest' in paths_dict and 'MultiNestLib' in template_dict['Setup']: outjson['Setup']['MultiNestLib']=paths_dict['MultiNest'] if 'Diver' in paths_dict and 'DiverLib' in template_dict['Setup']: outjson['Setup']['DiverLib']=paths_dict['Diver'] with open(os.path.join(BSMArtScanDir,template_name),'w') as OF2: json.dump(outjson, OF2, cls=CompactJSONEncoder, indent=4) #json.dump(outjson, OF2, indent=4) if 'BSMArt' in paths_dict: bsmartpath=paths_dict['BSMArt'] else: ## find BSMArt run path from where the script is located # bsmartpath = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0] # In package mode, we don't rely on this path for the executable. bsmartpath = None if template_name[-5:] == '.json': runname='_'+template_name[:-5] else: runname='' # BSMArtexec=os.path.join(bsmartpath,'bin','BSMArt') BSMArtexec = 'BSMArt' # Assume it is in PATH if bsmartpath and os.path.exists(os.path.join(bsmartpath, 'bin', 'BSMArt')): BSMArtexec=os.path.join(bsmartpath,'bin','BSMArt') shellscript=os.path.join(BSMArtScanDir,'runBSMArt'+runname+'.sh') OF3=open(shellscript,'w') OF3.write('#!/usr/bin/env bash\n\n') # OF3.write('python3 '+BSMArtexec + ' --debug '+template_name+' \n') if BSMArtexec == 'BSMArt': OF3.write(BSMArtexec + ' --debug '+template_name+' \n') else: OF3.write('python3 '+BSMArtexec + ' --debug '+template_name+' \n') OF3.close() os.system('chmod u+x '+shellscript)
##########################################################################################################
[docs] def makeBSMArtTemplates(modelname,bsmart_dict,paths_dict,includecodes): basetemplate=collections.OrderedDict() jsonbasefile='BSMArt_basetemplate.json' # Check current directory if os.path.exists(jsonbasefile): template_path = jsonbasefile else: # Check explicit BSMArt path if 'BSMArt' in paths_dict and os.path.exists(os.path.join(paths_dict['BSMArt'],'AuxFiles',jsonbasefile)): template_path = os.path.join(paths_dict['BSMArt'],'AuxFiles',jsonbasefile) else: # Check package resources try: import importlib.resources # Assume AuxFiles were moved to bsmart.data.AuxFiles or bsmart.data? # I moved AuxFiles to src/bsmart/data. So the file is at bsmart.data.BSMArt_basetemplate.json (if I flat moved it?) # Wait, I did `git mv AuxFiles src/bsmart/data/`. So it is `src/bsmart/data/AuxFiles/BSMArt_basetemplate.json`. # So resource is `bsmart.data.AuxFiles` # Python < 3.9 resources might be tricky with subdirectories. # Let's try files() interface. from importlib.resources import files template_path = files('bsmart.data').joinpath('AuxFiles', jsonbasefile) if not template_path.is_file(): # Maybe I moved it differently? # I did `git mv AuxFiles src/bsmart/data/` -> `src/bsmart/data/AuxFiles` pass except ImportError: # Fallback for older python? pass except Exception as e: pass # Actually resolving the file path for updateBSMArtTemplate which expects a path string if not os.path.exists(str(template_path)): # Last ditch: try finding it relative to this script if user is running from source structure # But we are installed. raise NameError('Could not find BSMArt_basetemplate.json, essential for constructing the templates') # updateBSMArtTemplate(modelname,bsmart_dict,paths_dict,includecodes,jsonbasefile,'BSMArt_'+modelname+'.json') # We pass the full path updateBSMArtTemplate(modelname,bsmart_dict,paths_dict,includecodes,str(template_path),'BSMArt_'+modelname+'.json')
[docs] def main(): info_message='Script to just set up a BSMArt directory and templates for an existing model. Will not generate any code. Just supply the Model Name.' parser = argparse.ArgumentParser( description=info_message) parser.add_argument('ModelName', metavar='<Model Name>', type=str, help='Input Model name') parser.add_argument('--template', type=str,help='Read and modify an example template instead of creating a new one',default=None) parser.add_argument('--scriptdir', type=str,help='Directory where the BSMArt data file for the model has been stored. By default, the script assumes the subdirectory ScriptsAndLogs of the current directory.',default=None) try: args = parser.parse_args() except Exception as e: print(str(e)) parser.print_help() #print(info_message +str(e)) raise SystemExit ## Set up directories cwd = os.getcwd() if args.scriptdir is not None and os.path.isdir(args.scriptdir): scriptdir = args.scriptdir else: scriptdir=os.path.join(cwd,'ScriptsAndLogs') bsmartdatafile=os.path.join(scriptdir,'BSMArt_data_'+modelname+'.json') if not os.path.exists(bsmartdatafile): from bsmart import get_bsmart_config_dir global_config_dir = get_bsmart_config_dir() if os.path.isdir(global_config_dir): bsmartdatafile=os.path.join(global_config_dir,'BSMArt_data_'+modelname+'.json') #if not os.path.isdir(scriptdir): # scriptdir=cwd model=args.ModelName modelname=str(args.ModelName).replace('/','-') #scriptname=os.path.join(scriptdir,'init'+modelname+'.m') jsonFILE='HEPtoolpaths.json' if not os.path.exists(jsonFILE): try: from bsmart import get_heptools_path_file jsonFILE = get_heptools_path_file() except ImportError: pass if os.path.exists(jsonFILE): try: with open(jsonFILE) as json_data: paths_dict = json.load(json_data, object_pairs_hook=collections.OrderedDict) except Exception as e: #log.error('Failed to load json file '+file) print('Failed to load json file '+jsonFILE) print('Json exception given as ' +str(e)) raise SystemExit else: print('Failed to load json file '+jsonFILE) print('Please run BSMArt-InstallHEPTools first or ensure HEPtoolpaths.json is in the current directory or configuration folder.') raise SystemExit includecodes={ 'SPheno':True, 'FlexibleSUSY': True, 'MicrOMEGAs':True, 'Vevacious++':True, 'HiggsSignals':True, 'HiggsBounds':True, 'HiggsTools':True, 'SModelS': True} for code in includecodes: if code not in paths_dict: includecodes[code] = False includecodes['flavio'] = True if 'SARAH' not in paths_dict: includecodes['Vevacious++'] = False #bsmartdatafile=os.path.join(scriptdir,'BSMArt_data_'+modelname+'.json') try: with open(bsmartdatafile) as bsmart_json_data: bsmart_dict = json.load(bsmart_json_data, object_pairs_hook=collections.OrderedDict) if 'Hneutral' not in bsmart_dict or 'Hcharged' not in bsmart_dict: includecodes['HiggsBounds'] = False includecodes['HiggsSignals'] = False if 'Neutral Higgs' not in bsmart_dict or 'Charged Higgs' not in bsmart_dict: includecodes['HiggsTools'] = False except Exception as e: #log.error('Failed to load json file '+file) print('Failed to load json file '+bsmartdatafile) print('Json exception given as ' +str(e)) print('Data for SPheno/HiggsTools will not be updated') bsmart_dict={} includecodes['SPheno'] = False includecodes['HiggsBounds'] = False includecodes['HiggsSignals'] = False includecodes['HiggsTools'] = False if args.template is None: makeBSMArtTemplates(modelname,bsmart_dict,paths_dict,includecodes) else: updateBSMArtTemplate(modelname,bsmart_dict,paths_dict,includecodes,args.template)
if __name__ == "__main__": main()