Merge lp:~maddm/maddm/no_numpy_scipy into lp:maddm

Proposed by Olivier Mattelaer
Status: Superseded
Proposed branch: lp:~maddm/maddm/no_numpy_scipy
Merge into: lp:maddm
Diff against target: 255 lines (+87/-24)
3 files modified
__init__.py (+1/-1)
maddm_interface.py (+5/-0)
maddm_run_interface.py (+81/-23)
To merge this branch: bzr merge lp:~maddm/maddm/no_numpy_scipy
Reviewer Review Type Date Requested Status
Federico Ambrogi Pending
Review via email: mp+345140@code.launchpad.net

Commit message

Avoid direct crash if numpy/scipy are not present on the system.
-> forbids indirect detection but allows relic density computation and direct detection.

This allows to have maddm v2 options still working in version 3 even if numpy/scipy are not available.

To post a comment you must log in.
lp:~maddm/maddm/no_numpy_scipy updated
18. By olivier-mattelaer

some issue created by the change

19. By olivier-mattelaer

additional fix

20. By Federico Ambrogi <email address hidden>

Formatted string as as python 2.6

21. By olivier-mattelaer

change according to federico review

22. By olivier-mattelaer

remove some printout

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '__init__.py'
--- __init__.py 2018-03-30 22:19:49 +0000
+++ __init__.py 2018-05-06 15:24:43 +0000
@@ -16,6 +16,6 @@
16new_reweight = {'indirect': MGoutput.Indirect_Reweight}16new_reweight = {'indirect': MGoutput.Indirect_Reweight}
1717
18## The test/code have been validated up to this version18## The test/code have been validated up to this version
19latest_validated_version = (2,6,2)19latest_validated_version = (2,6,3)
20minimal_mg5amcnlo_version = (2,6,2)20minimal_mg5amcnlo_version = (2,6,2)
21maximal_mg5amcnlo_version = (1000,1000,1000)21maximal_mg5amcnlo_version = (1000,1000,1000)
2222
=== modified file 'maddm_interface.py'
--- maddm_interface.py 2018-04-29 20:55:19 +0000
+++ maddm_interface.py 2018-05-06 15:24:43 +0000
@@ -115,6 +115,11 @@
115 def post_install_PPPC4DMID(self):115 def post_install_PPPC4DMID(self):
116 if os.path.exists(pjoin(MG5DIR, 'PPPC4DMID')):116 if os.path.exists(pjoin(MG5DIR, 'PPPC4DMID')):
117 self.options['pppc4dmid_path'] = pjoin(MG5DIR, 'PPPC4DMID')117 self.options['pppc4dmid_path'] = pjoin(MG5DIR, 'PPPC4DMID')
118
119 if not maddm_run_interface.HAS_SCIPY:
120 logger.critical("PPC4DMID module requires scipy to be working. Please install those python module. (they are not present)")
121 logger.info("you can try to use \"pip install scipy\"")
122
118 return123 return
119 124
120 def set_configuration(self, config_path=None, final=True, **opts):125 def set_configuration(self, config_path=None, final=True, **opts):
121126
=== modified file 'maddm_run_interface.py'
--- maddm_run_interface.py 2018-04-29 20:53:38 +0000
+++ maddm_run_interface.py 2018-05-06 15:24:43 +0000
@@ -10,12 +10,7 @@
10import stat10import stat
11import shutil11import shutil
1212
13from scipy.interpolate import interp1d13
14from scipy.integrate import quad
15from scipy.optimize import minimize_scalar
16from scipy.optimize import brute
17from scipy.optimize import fmin
18from scipy.special import gammainc
1914
20import MGoutput15import MGoutput
21from madgraph import MadGraph5Error16from madgraph import MadGraph5Error
@@ -34,18 +29,36 @@
34 29
35#import darkmatter as darkmatter30#import darkmatter as darkmatter
3631
37import numpy as np32logger = logging.getLogger('madgraph.plugin.maddm')
3833
39try:34try:
40 import pymultinest35 import pymultinest
41except:36except ImportError:
42 print('WARNING: Multinest module not found! All multinest parameter scanning features will be disabled.')37 pass
4338
4439try:
45#import types40 from scipy.interpolate import interp1d
41 from scipy.integrate import quad
42 from scipy.special import gammainc
43except ImportError, error:
44 print error
45 logger.warning('scipy module not found! Some Indirect detection features will be disabled.')
46 HAS_SCIPY = False
47else:
48 HAS_SCIPY = True
49
50try:
51 import numpy as np
52except ImportError:
53 logger.warning('numpy module not found! Indirect detection features will be disabled.')
54 HAS_NUMPY = False
55else:
56 HAS_NUMPY = True
57
58class ModuleMissing(Exception): pass
4659
47pjoin = os.path.join60pjoin = os.path.join
48logger = logging.getLogger('madgraph.plugin.maddm')61
49logger_tuto = logging.getLogger('tutorial_plugin')62logger_tuto = logging.getLogger('tutorial_plugin')
50#logger.setLevel(10) #level 20 = INFO63#logger.setLevel(10) #level 20 = INFO
5164
@@ -111,14 +124,18 @@
111 self._sigma_ID[item] = -1.0124 self._sigma_ID[item] = -1.0
112 self._sigma_ID_width[item] = -1.0125 self._sigma_ID_width[item] = -1.0
113126
114 self.load_constraints()127 if HAS_NUMPY:
128 self.load_constraints()
129
115130
116 logger.info('Loaded experimental constraints. To change, use the set command')131 logger.info('Loaded experimental constraints. To change, use the set command')
117 logger.info('Omega h^2 = %.4e +- %.4e' %(self._oh2_planck, self._oh2_planck_width))132 logger.info('Omega h^2 = %.4e +- %.4e' %(self._oh2_planck, self._oh2_planck_width))
118 logger.info('Spin Independent cross section: %s' % self._dd_si_limit_file)133 if HAS_NUMPY:
119 logger.info('Spin Dependent cross section (p): %s' % self._dd_sd_proton_limit_file)134 logger.info('Spin Independent cross section: %s' % self._dd_si_limit_file)
120 logger.info('Spin Dependent cross section (n): %s' % self._dd_sd_neutron_limit_file)135 logger.info('Spin Dependent cross section (p): %s' % self._dd_sd_proton_limit_file)
121136 logger.info('Spin Dependent cross section (n): %s' % self._dd_sd_neutron_limit_file)
137 else:
138 logger.info('Spin (in)dependent not available due to the missing python module: numpy')
122# for chan in self._allowed_final_states:139# for chan in self._allowed_final_states:
123# logger.info('Indirect Detection cross section for final state %s at velocity %.2e: %s'\140# logger.info('Indirect Detection cross section for final state %s at velocity %.2e: %s'\
124# % (chan, self._id_limit_vel[chan] ,self._id_limit_file[chan]))141# % (chan, self._id_limit_vel[chan] ,self._id_limit_file[chan]))
@@ -146,6 +163,10 @@
146163
147 #Returns a value in cm^2164 #Returns a value in cm^2
148 def SI_max(self, mdm):165 def SI_max(self, mdm):
166 if not HAS_NUMPY:
167 logger.warning("missing numpy module for SI limit")
168 return __infty__
169
149 if (mdm < np.min(self._dd_si_limit_mDM) or mdm > np.max(self._dd_si_limit_mDM)):170 if (mdm < np.min(self._dd_si_limit_mDM) or mdm > np.max(self._dd_si_limit_mDM)):
150 logger.warning('Dark matter mass value '+str(mdm)+' is outside the range of SI limit')171 logger.warning('Dark matter mass value '+str(mdm)+' is outside the range of SI limit')
151 return __infty__172 return __infty__
@@ -154,6 +175,10 @@
154175
155 #Returns a value in cm^2176 #Returns a value in cm^2
156 def SD_max(self,mdm, nucleon):177 def SD_max(self,mdm, nucleon):
178 if not HAS_NUMPY:
179 logger.warning("missing numpy module for SD limit")
180 return __infty__
181
157 if nucleon not in ['n','p']:182 if nucleon not in ['n','p']:
158 logger.error('nucleon can only be p or n')183 logger.error('nucleon can only be p or n')
159 return __infty__184 return __infty__
@@ -173,6 +198,9 @@
173198
174 #Returns a value in cm^3/s199 #Returns a value in cm^3/s
175 def ID_max(self,mdm, channel):200 def ID_max(self,mdm, channel):
201 if not HAS_NUMPY:
202 logger.warning("missing numpy module for ID limit")
203 return __infty__
176 if (mdm < np.min(self._id_limit_mdm[channel]) or mdm > np.max(self._id_limit_mdm[channel])):204 if (mdm < np.min(self._id_limit_mdm[channel]) or mdm > np.max(self._id_limit_mdm[channel])):
177 logger.warning('Dark matter mass value %.2e for channel %s is outside the range of ID limit' % (mdm, channel))205 logger.warning('Dark matter mass value %.2e for channel %s is outside the range of ID limit' % (mdm, channel))
178 return __infty__206 return __infty__
@@ -267,6 +295,10 @@
267 # this function extracts the values of the spectra interpolated linearly between two values mdm_1 and mdm_2 295 # this function extracts the values of the spectra interpolated linearly between two values mdm_1 and mdm_2
268 # mdm is the DM candidate mass, spectrum is gammas, positron etc, channel is the SM annihilation e.g. bbar, hh etc. 296 # mdm is the DM candidate mass, spectrum is gammas, positron etc, channel is the SM annihilation e.g. bbar, hh etc.
269 def interpolate_spectra(self, sp_dic, mdm = '', spectrum = '' , channel = '' , earth = False , prof = 'Ein' , prop = 'MED' , halo_func = 'MF1'):297 def interpolate_spectra(self, sp_dic, mdm = '', spectrum = '' , channel = '' , earth = False , prof = 'Ein' , prop = 'MED' , halo_func = 'MF1'):
298
299 if not HAS_SCIPY:
300 raise ModuleMissing('scipy module is required for this functionality.')
301
270 M = sp_dic['Masses']302 M = sp_dic['Masses']
271 dm_min = max([m for m in M if m <= mdm]) # extracting lower mass limit to interpolate from 303 dm_min = max([m for m in M if m <= mdm]) # extracting lower mass limit to interpolate from
272 dm_max = min([m for m in M if m >= mdm]) # extracting upper mass limit to interpolate from 304 dm_max = min([m for m in M if m >= mdm]) # extracting upper mass limit to interpolate from
@@ -306,7 +338,8 @@
306 self.dSph_ll_files_path = pjoin(MDMDIR, 'Fermi_Data', 'likelihoods')338 self.dSph_ll_files_path = pjoin(MDMDIR, 'Fermi_Data', 'likelihoods')
307 self.dwarves_list = ['coma_berenices', 'draco', 'segue_1', 'ursa_major_II', 'ursa_minor', 'reticulum_II' ] # dSphs with the 6 highest Jfactors339 self.dwarves_list = ['coma_berenices', 'draco', 'segue_1', 'ursa_major_II', 'ursa_minor', 'reticulum_II' ] # dSphs with the 6 highest Jfactors
308 self.dwarveslist_all = self.extract_dwarveslist() 340 self.dwarveslist_all = self.extract_dwarveslist()
309 self.dw_in = self.dw_dic()341 if HAS_NUMPY:
342 self.dw_in = self.dw_dic()
310 self.ll_tot = ''343 self.ll_tot = ''
311344
312 # This function reads the list of dwarves from the Jfactor.dat file345 # This function reads the list of dwarves from the Jfactor.dat file
@@ -363,6 +396,10 @@
363 def eflux(self,spectrum, emin=1e2, emax=1e5, quiet=False):396 def eflux(self,spectrum, emin=1e2, emax=1e5, quiet=False):
364 """ Integrate a generic spectrum, multiplied by E, to get the energy flux. 397 """ Integrate a generic spectrum, multiplied by E, to get the energy flux.
365 """398 """
399
400 if not HAS_SCIPY:
401 raise ModuleMissing('scipy module is required for this functionality.')
402
366 espectrum = lambda e: spectrum(e)*e403 espectrum = lambda e: spectrum(e)*e
367 tol = min(espectrum(emin),espectrum(emax))*1e-10404 tol = min(espectrum(emin),espectrum(emax))*1e-10
368 try:405 try:
@@ -373,6 +410,9 @@
373410
374 def marg_like_dw(self,dw_in_i,pred,marginalize):411 def marg_like_dw(self,dw_in_i,pred,marginalize):
375 412
413 if not HAS_SCIPY:
414 raise ModuleMissing('scipy module is required for this functionality.')
415
376 j0, nBin = self.j0 , self.nBin416 j0, nBin = self.j0 , self.nBin
377417
378 j,jerr,like_inter = dw_in_i['Jfac'], dw_in_i['Jfac_err'], dw_in_i['likelihood']418 j,jerr,like_inter = dw_in_i['Jfac'], dw_in_i['Jfac_err'], dw_in_i['likelihood']
@@ -403,6 +443,9 @@
403443
404 def res_tot_dw(self,pred,marginalize):444 def res_tot_dw(self,pred,marginalize):
405445
446 if not HAS_SCIPY:
447 raise ModuleMissing('scipy module is required for this functionality.')
448
406 dw_in = self.dw_in449 dw_in = self.dw_in
407 ll_tot = 0.0450 ll_tot = 0.0
408 ll_null = 0.0451 ll_null = 0.0
@@ -437,6 +480,13 @@
437 def Fermi_sigmav_lim(self, mDM, x = '' , dndlogx = '' , marginalize = True, sigmav_th = False , maj_dirac='', \480 def Fermi_sigmav_lim(self, mDM, x = '' , dndlogx = '' , marginalize = True, sigmav_th = False , maj_dirac='', \
438 sigmavmin=1e-35, sigmavmax=1e-15, step_size_scaling=1.0, cl_val = 0.95):481 sigmavmin=1e-35, sigmavmax=1e-15, step_size_scaling=1.0, cl_val = 0.95):
439482
483 if not HAS_NUMPY:
484 logger.warning("Fermi limit ignored due to missing numpy module")
485 return -1
486 if not HAS_SCIPY:
487 logger.warning("Fermi limit ignored due to missing scipy module")
488 return -1
489
440 np.seterr(divide='ignore', invalid='ignore') # Keep numpy from complaining about dN/dE = 0... 490 np.seterr(divide='ignore', invalid='ignore') # Keep numpy from complaining about dN/dE = 0...
441 j0 , nBin = self.j0 , self.nBin491 j0 , nBin = self.j0 , self.nBin
442 492
@@ -1226,8 +1276,8 @@
1226 sp_name = sp + '_spectrum_pythia8.dat'1276 sp_name = sp + '_spectrum_pythia8.dat'
1227 out_dir = pjoin(self.dir_path,'Indirect', 'Events', run_name, sp_name )1277 out_dir = pjoin(self.dir_path,'Indirect', 'Events', run_name, sp_name )
1228 if sp == 'gammas': # x values are the same for all the spectra1278 if sp == 'gammas': # x values are the same for all the spectra
1229 x = np.loadtxt(out_dir , unpack = True )[0]1279 x = np.loadtxt(out_dir , unpack = True )[0]
1230 self.Spectra.spectra['x'] = [ np.power(10,num) for num in x] # from log[10,x] to x1280 self.Spectra.spectra['x'] = [ np.power(10,num) for num in x] # from log[10,x] to x
1231 self.Spectra.spectra[sp] = np.loadtxt(out_dir , unpack = True )[1].tolist() 1281 self.Spectra.spectra[sp] = np.loadtxt(out_dir , unpack = True )[1].tolist()
1232 1282
12331283
@@ -1239,6 +1289,10 @@
1239 logger.error('PPPC4DMID not installed. Please install by typing "install PPPC4DMID".')1289 logger.error('PPPC4DMID not installed. Please install by typing "install PPPC4DMID".')
1240 return1290 return
12411291
1292 if not HAS_SCIPY:
1293 logger.error('using PPPC4DMID requires scipy module. Please install it (for example with "pip install scipy")')
1294 return
1295
1242 if 'PPPC4DMID' in self.maddm_card['indirect_flux_source_method'] or 'inclusive' in self.maddm_card['sigmav_method']:1296 if 'PPPC4DMID' in self.maddm_card['indirect_flux_source_method'] or 'inclusive' in self.maddm_card['sigmav_method']:
1243 if self.Spectra.check_mass(mdm):1297 if self.Spectra.check_mass(mdm):
1244 if '_ew' in self.maddm_card['indirect_flux_source_method']:1298 if '_ew' in self.maddm_card['indirect_flux_source_method']:
@@ -2356,7 +2410,9 @@
2356 def set_default_indirect(self):2410 def set_default_indirect(self):
2357 """set the default value for relic="""2411 """set the default value for relic="""
2358 2412
2359 if self.availmode['has_indirect_detection']:2413 if not HAS_NUMPY:
2414 self.switch['indirect'] = 'Not Avail. (numpy missing)'
2415 elif self.availmode['has_indirect_detection']:
2360 self.switch['indirect'] = 'sigmav' 2416 self.switch['indirect'] = 'sigmav'
2361 else:2417 else:
2362 self.switch['indirect'] = 'Not Avail.'2418 self.switch['indirect'] = 'Not Avail.'
@@ -2368,7 +2424,9 @@
2368 if hasattr(self, 'allowed_indirect'):2424 if hasattr(self, 'allowed_indirect'):
2369 return getattr(self, 'allowed_indirect')2425 return getattr(self, 'allowed_indirect')
23702426
2371 if self.availmode['has_indirect_detection']:2427 if not HAS_NUMPY:
2428 self.allowed_indirect = ['OFF']
2429 elif self.availmode['has_indirect_detection']:
2372 self.allowed_indirect = ['OFF', 'sigmav', 'flux_source', 'flux_earth']2430 self.allowed_indirect = ['OFF', 'sigmav', 'flux_source', 'flux_earth']
2373 else:2431 else:
2374 return []2432 return []

Subscribers

People subscribed via source and target branches

to all changes: