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
1=== modified file '__init__.py'
2--- __init__.py 2018-03-30 22:19:49 +0000
3+++ __init__.py 2018-05-06 15:24:43 +0000
4@@ -16,6 +16,6 @@
5 new_reweight = {'indirect': MGoutput.Indirect_Reweight}
6
7 ## The test/code have been validated up to this version
8-latest_validated_version = (2,6,2)
9+latest_validated_version = (2,6,3)
10 minimal_mg5amcnlo_version = (2,6,2)
11 maximal_mg5amcnlo_version = (1000,1000,1000)
12
13=== modified file 'maddm_interface.py'
14--- maddm_interface.py 2018-04-29 20:55:19 +0000
15+++ maddm_interface.py 2018-05-06 15:24:43 +0000
16@@ -115,6 +115,11 @@
17 def post_install_PPPC4DMID(self):
18 if os.path.exists(pjoin(MG5DIR, 'PPPC4DMID')):
19 self.options['pppc4dmid_path'] = pjoin(MG5DIR, 'PPPC4DMID')
20+
21+ if not maddm_run_interface.HAS_SCIPY:
22+ logger.critical("PPC4DMID module requires scipy to be working. Please install those python module. (they are not present)")
23+ logger.info("you can try to use \"pip install scipy\"")
24+
25 return
26
27 def set_configuration(self, config_path=None, final=True, **opts):
28
29=== modified file 'maddm_run_interface.py'
30--- maddm_run_interface.py 2018-04-29 20:53:38 +0000
31+++ maddm_run_interface.py 2018-05-06 15:24:43 +0000
32@@ -10,12 +10,7 @@
33 import stat
34 import shutil
35
36-from scipy.interpolate import interp1d
37-from scipy.integrate import quad
38-from scipy.optimize import minimize_scalar
39-from scipy.optimize import brute
40-from scipy.optimize import fmin
41-from scipy.special import gammainc
42+
43
44 import MGoutput
45 from madgraph import MadGraph5Error
46@@ -34,18 +29,36 @@
47
48 #import darkmatter as darkmatter
49
50-import numpy as np
51+logger = logging.getLogger('madgraph.plugin.maddm')
52
53 try:
54 import pymultinest
55-except:
56- print('WARNING: Multinest module not found! All multinest parameter scanning features will be disabled.')
57-
58-
59-#import types
60+except ImportError:
61+ pass
62+
63+try:
64+ from scipy.interpolate import interp1d
65+ from scipy.integrate import quad
66+ from scipy.special import gammainc
67+except ImportError, error:
68+ print error
69+ logger.warning('scipy module not found! Some Indirect detection features will be disabled.')
70+ HAS_SCIPY = False
71+else:
72+ HAS_SCIPY = True
73+
74+try:
75+ import numpy as np
76+except ImportError:
77+ logger.warning('numpy module not found! Indirect detection features will be disabled.')
78+ HAS_NUMPY = False
79+else:
80+ HAS_NUMPY = True
81+
82+class ModuleMissing(Exception): pass
83
84 pjoin = os.path.join
85-logger = logging.getLogger('madgraph.plugin.maddm')
86+
87 logger_tuto = logging.getLogger('tutorial_plugin')
88 #logger.setLevel(10) #level 20 = INFO
89
90@@ -111,14 +124,18 @@
91 self._sigma_ID[item] = -1.0
92 self._sigma_ID_width[item] = -1.0
93
94- self.load_constraints()
95+ if HAS_NUMPY:
96+ self.load_constraints()
97+
98
99 logger.info('Loaded experimental constraints. To change, use the set command')
100 logger.info('Omega h^2 = %.4e +- %.4e' %(self._oh2_planck, self._oh2_planck_width))
101- logger.info('Spin Independent cross section: %s' % self._dd_si_limit_file)
102- logger.info('Spin Dependent cross section (p): %s' % self._dd_sd_proton_limit_file)
103- logger.info('Spin Dependent cross section (n): %s' % self._dd_sd_neutron_limit_file)
104-
105+ if HAS_NUMPY:
106+ logger.info('Spin Independent cross section: %s' % self._dd_si_limit_file)
107+ logger.info('Spin Dependent cross section (p): %s' % self._dd_sd_proton_limit_file)
108+ logger.info('Spin Dependent cross section (n): %s' % self._dd_sd_neutron_limit_file)
109+ else:
110+ logger.info('Spin (in)dependent not available due to the missing python module: numpy')
111 # for chan in self._allowed_final_states:
112 # logger.info('Indirect Detection cross section for final state %s at velocity %.2e: %s'\
113 # % (chan, self._id_limit_vel[chan] ,self._id_limit_file[chan]))
114@@ -146,6 +163,10 @@
115
116 #Returns a value in cm^2
117 def SI_max(self, mdm):
118+ if not HAS_NUMPY:
119+ logger.warning("missing numpy module for SI limit")
120+ return __infty__
121+
122 if (mdm < np.min(self._dd_si_limit_mDM) or mdm > np.max(self._dd_si_limit_mDM)):
123 logger.warning('Dark matter mass value '+str(mdm)+' is outside the range of SI limit')
124 return __infty__
125@@ -154,6 +175,10 @@
126
127 #Returns a value in cm^2
128 def SD_max(self,mdm, nucleon):
129+ if not HAS_NUMPY:
130+ logger.warning("missing numpy module for SD limit")
131+ return __infty__
132+
133 if nucleon not in ['n','p']:
134 logger.error('nucleon can only be p or n')
135 return __infty__
136@@ -173,6 +198,9 @@
137
138 #Returns a value in cm^3/s
139 def ID_max(self,mdm, channel):
140+ if not HAS_NUMPY:
141+ logger.warning("missing numpy module for ID limit")
142+ return __infty__
143 if (mdm < np.min(self._id_limit_mdm[channel]) or mdm > np.max(self._id_limit_mdm[channel])):
144 logger.warning('Dark matter mass value %.2e for channel %s is outside the range of ID limit' % (mdm, channel))
145 return __infty__
146@@ -267,6 +295,10 @@
147 # this function extracts the values of the spectra interpolated linearly between two values mdm_1 and mdm_2
148 # mdm is the DM candidate mass, spectrum is gammas, positron etc, channel is the SM annihilation e.g. bbar, hh etc.
149 def interpolate_spectra(self, sp_dic, mdm = '', spectrum = '' , channel = '' , earth = False , prof = 'Ein' , prop = 'MED' , halo_func = 'MF1'):
150+
151+ if not HAS_SCIPY:
152+ raise ModuleMissing('scipy module is required for this functionality.')
153+
154 M = sp_dic['Masses']
155 dm_min = max([m for m in M if m <= mdm]) # extracting lower mass limit to interpolate from
156 dm_max = min([m for m in M if m >= mdm]) # extracting upper mass limit to interpolate from
157@@ -306,7 +338,8 @@
158 self.dSph_ll_files_path = pjoin(MDMDIR, 'Fermi_Data', 'likelihoods')
159 self.dwarves_list = ['coma_berenices', 'draco', 'segue_1', 'ursa_major_II', 'ursa_minor', 'reticulum_II' ] # dSphs with the 6 highest Jfactors
160 self.dwarveslist_all = self.extract_dwarveslist()
161- self.dw_in = self.dw_dic()
162+ if HAS_NUMPY:
163+ self.dw_in = self.dw_dic()
164 self.ll_tot = ''
165
166 # This function reads the list of dwarves from the Jfactor.dat file
167@@ -363,6 +396,10 @@
168 def eflux(self,spectrum, emin=1e2, emax=1e5, quiet=False):
169 """ Integrate a generic spectrum, multiplied by E, to get the energy flux.
170 """
171+
172+ if not HAS_SCIPY:
173+ raise ModuleMissing('scipy module is required for this functionality.')
174+
175 espectrum = lambda e: spectrum(e)*e
176 tol = min(espectrum(emin),espectrum(emax))*1e-10
177 try:
178@@ -373,6 +410,9 @@
179
180 def marg_like_dw(self,dw_in_i,pred,marginalize):
181
182+ if not HAS_SCIPY:
183+ raise ModuleMissing('scipy module is required for this functionality.')
184+
185 j0, nBin = self.j0 , self.nBin
186
187 j,jerr,like_inter = dw_in_i['Jfac'], dw_in_i['Jfac_err'], dw_in_i['likelihood']
188@@ -403,6 +443,9 @@
189
190 def res_tot_dw(self,pred,marginalize):
191
192+ if not HAS_SCIPY:
193+ raise ModuleMissing('scipy module is required for this functionality.')
194+
195 dw_in = self.dw_in
196 ll_tot = 0.0
197 ll_null = 0.0
198@@ -437,6 +480,13 @@
199 def Fermi_sigmav_lim(self, mDM, x = '' , dndlogx = '' , marginalize = True, sigmav_th = False , maj_dirac='', \
200 sigmavmin=1e-35, sigmavmax=1e-15, step_size_scaling=1.0, cl_val = 0.95):
201
202+ if not HAS_NUMPY:
203+ logger.warning("Fermi limit ignored due to missing numpy module")
204+ return -1
205+ if not HAS_SCIPY:
206+ logger.warning("Fermi limit ignored due to missing scipy module")
207+ return -1
208+
209 np.seterr(divide='ignore', invalid='ignore') # Keep numpy from complaining about dN/dE = 0...
210 j0 , nBin = self.j0 , self.nBin
211
212@@ -1226,8 +1276,8 @@
213 sp_name = sp + '_spectrum_pythia8.dat'
214 out_dir = pjoin(self.dir_path,'Indirect', 'Events', run_name, sp_name )
215 if sp == 'gammas': # x values are the same for all the spectra
216- x = np.loadtxt(out_dir , unpack = True )[0]
217- self.Spectra.spectra['x'] = [ np.power(10,num) for num in x] # from log[10,x] to x
218+ x = np.loadtxt(out_dir , unpack = True )[0]
219+ self.Spectra.spectra['x'] = [ np.power(10,num) for num in x] # from log[10,x] to x
220 self.Spectra.spectra[sp] = np.loadtxt(out_dir , unpack = True )[1].tolist()
221
222
223@@ -1239,6 +1289,10 @@
224 logger.error('PPPC4DMID not installed. Please install by typing "install PPPC4DMID".')
225 return
226
227+ if not HAS_SCIPY:
228+ logger.error('using PPPC4DMID requires scipy module. Please install it (for example with "pip install scipy")')
229+ return
230+
231 if 'PPPC4DMID' in self.maddm_card['indirect_flux_source_method'] or 'inclusive' in self.maddm_card['sigmav_method']:
232 if self.Spectra.check_mass(mdm):
233 if '_ew' in self.maddm_card['indirect_flux_source_method']:
234@@ -2356,7 +2410,9 @@
235 def set_default_indirect(self):
236 """set the default value for relic="""
237
238- if self.availmode['has_indirect_detection']:
239+ if not HAS_NUMPY:
240+ self.switch['indirect'] = 'Not Avail. (numpy missing)'
241+ elif self.availmode['has_indirect_detection']:
242 self.switch['indirect'] = 'sigmav'
243 else:
244 self.switch['indirect'] = 'Not Avail.'
245@@ -2368,7 +2424,9 @@
246 if hasattr(self, 'allowed_indirect'):
247 return getattr(self, 'allowed_indirect')
248
249- if self.availmode['has_indirect_detection']:
250+ if not HAS_NUMPY:
251+ self.allowed_indirect = ['OFF']
252+ elif self.availmode['has_indirect_detection']:
253 self.allowed_indirect = ['OFF', 'sigmav', 'flux_source', 'flux_earth']
254 else:
255 return []

Subscribers

People subscribed via source and target branches

to all changes: