Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Mario Gennaro committed Jun 2, 2016
0 parents commit 28cf4b7
Show file tree
Hide file tree
Showing 21 changed files with 303 additions and 0 deletions.
Empty file added __init__.py
Empty file.
Binary file added __pycache__/__init__.cpython-35.pyc
Binary file not shown.
1 change: 1 addition & 0 deletions auxfunc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__all__=["findNN_arr"]
Binary file added auxfunc/__pycache__/__init__.cpython-35.pyc
Binary file not shown.
Binary file added auxfunc/__pycache__/findNN_arr.cpython-35.pyc
Binary file not shown.
Binary file added auxfunc/__pycache__/photband.cpython-35.pyc
Binary file not shown.
14 changes: 14 additions & 0 deletions auxfunc/findNN_arr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import numpy as np
from numba import jit

@jit
def find_nearest(array,value):
"""Find the nearest element in an array"""
idx = (np.abs(array-value)).argmin()
return array[idx]

@jit
def find_nearest_idx(array,value):
"""Find the index of the nearest element in an array"""
idx = (np.abs(array-value)).argmin()
return idx
58 changes: 58 additions & 0 deletions auxfunc/photband.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import numpy as np

class photband(object):
'''
The Photometric band object
'''
def __init__(self):
'''
Initialize object
'''
self._name = 'empty'
self._upcut = -np.inf
self._lowcut = np.inf
self._xmagerr = None
self._ymagerr = None

@property
def name(self):
return self._name

@name.setter
def name(self, new_name):
self._name = new_name

@property
def upcut(self):
return self._upcut

@upcut.setter
def upcut(self, new_upcut):
self._upcut = new_upcut

@property
def lowcut(self):
return self._lowcut

@lowcut.setter
def lowcut(self, new_lowcut):
self._lowcut = new_lowcut

@property
def xmagerr(self):
return self._xmagerr

@xmagerr.setter
def xmagerr(self, new_xmagerr):
self._xmagerr = new_xmagerr

@property
def ymagerr(self):
return self._ymagerr

@ymagerr.setter
def ymagerr(self, new_ymagerr):
self._ymagerr = new_ymagerr



Binary file added generators/._ParlistException.py
Binary file not shown.
74 changes: 74 additions & 0 deletions generators/GeneralRandom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import matplotlib.pyplot as plt
import numpy as np
from numba import jit

class GeneralRandom:
"""This class enables us to generate random numbers with an arbitrary
distribution."""

def __init__(self, x, p, Nrl):
"""Initialize the lookup table (with default values if necessary)
Inputs:
x = random number values
p = probability density profile at that point
Nrl = number of reverse look up values between 0 and 1"""
self.set_pdf(x, p, Nrl)
@jit
def set_pdf(self, x, p, Nrl):
"""Generate the lookup tables.
x is the value of the random variate
pdf is its probability density
cdf is the cumulative pdf
inversecdf is the inverse look up table
"""

self.x = x
self.pdf = p/p.sum() #normalize it
self.cdf = self.pdf.cumsum()
self.inversecdfbins = Nrl
self.Nrl = Nrl
y = np.arange(Nrl)/float(Nrl)
delta = 1.0/Nrl
self.inversecdf = np.zeros(Nrl)
self.inversecdf[0] = self.x[0]
cdf_idx = 0
for n in range(1,self.inversecdfbins):
while self.cdf[cdf_idx] < y[n] and cdf_idx < Nrl:
cdf_idx += 1
self.inversecdf[n] = self.x[cdf_idx-1] + (self.x[cdf_idx] - self.x[cdf_idx-1]) * (y[n] - self.cdf[cdf_idx-1])/(self.cdf[cdf_idx] - self.cdf[cdf_idx-1])
if cdf_idx >= Nrl:
break
self.delta_inversecdf = np.concatenate((np.diff(self.inversecdf), [0]))

@jit
def random(self, N = 1):
"""Give us N random numbers with the requested distribution"""

idx_f = np.random.uniform(size = N, high = self.Nrl-1)
idx = np.array([idx_f],'i')
y = self.inversecdf[idx] + (idx_f - idx)*self.delta_inversecdf[idx]

return y.T

def plot_pdf(self):
plt.plot(self.x, self.pdf)

def self_test(self, N = 1000):
plt.figure()
#The cdf
plt.subplot(2,2,1)
plt.plot(self.x, self.cdf)
#The inverse cdf
plt.subplot(2,2,2)
y = np.arange(self.Nrl)/float(self.Nrl)
plt.plot(y, self.inversecdf)

#The actual generated numbers
plt.subplot(2,2,3)
y = self.random(N)
plt.hist(y, bins = 50,
range = (self.x.min(), self.x.max()),
normed = True)
# plt.plot(self.x, self.pdf/self.pdf.max())
plt.plot(self.x-(0.5*(self.x[1]-self.x[0])), self.pdf/np.trapz(self.pdf,self.x))
9 changes: 9 additions & 0 deletions generators/ParlistException.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class PE(Exception):
'''
Custom exception class to raise exceptions in the
parameters generators for the synthetic CMD module
'''

def __init__(self, msg, val):
self.msg = msg
self.val = val
1 change: 1 addition & 0 deletions generators/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__all__=["ParlistException","extract_age","extract_mass","extract_binq","GeneralRandom"]
Binary file not shown.
Binary file not shown.
Binary file added generators/__pycache__/__init__.cpython-35.pyc
Binary file not shown.
Binary file added generators/__pycache__/extract_age.cpython-35.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
58 changes: 58 additions & 0 deletions generators/extract_age.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import numpy as np
import scipy.stats as ss
from . import ParlistException
from numba import jit

@jit
def getage(sampsize,distr_name,parlist):

'''
Extract a number "sampsize" of ages
from a distribution selected among several available.
When a certain "distr_name" is passed, the paramters
for that distribution are passed in the list "parlist"
'''

#Uniform Distribution
if (distr_name == 'uniform'):
if (len(parlist) != 2): raise ParlistException.PE(
"The uniform distribution parlist must have 2 parameters: min_range and max_range",parlist)
if (parlist[1] <= parlist[0]): raise ParlistException.PE(
"parlist[0] must be <= parlist[1]",parlist)
return np.random.uniform(low=parlist[0],high=parlist[1],size=sampsize)

#Truncated exponential
elif(distr_name == 'Trunc_exp'):
if (len(parlist) != 3): raise ParlistException.PE(
"The Trunc_exp distribution parlist must have 3 parameters: min_range, max_range, lambda",parlist)
if (parlist[2] >= 0):
rnd_cdf = np.random.uniform(ss.expon.cdf(x=parlist[0], scale=parlist[2]),
ss.expon.cdf(x=parlist[1], scale=parlist[2]),size=sampsize)
return ss.expon.ppf(q=rnd_cdf, scale=parlist[2])
else:
rnd_cdf = np.random.uniform(ss.expon.cdf(x=parlist[0], scale=-1.*parlist[2]),
ss.expon.cdf(x=parlist[1], scale=-1.*parlist[2]),size=sampsize)

draws = ss.expon.ppf(q=rnd_cdf, scale=-1.*parlist[2])
return -1.*draws+parlist[0]+parlist[1]

#Bursts
elif(distr_name == 'Bursts'):
pk = []
for idx,burst in enumerate(parlist):
if (len(burst) != 3): raise ParlistException.PE(
"Each burst in the Bursts distribution must have 3 parameters: min_range, max_range, intensity ",[idx,burst])
else:
pk.append(burst[2])

xk = np.arange(len(pk))
pkv = np.asarray(pk)
pkv = pkv/np.sum(pkv)
custm = ss.rv_discrete(name='custm', values=(xk, pkv))
rndm_idx = custm.rvs(size=sampsize)
return parlist[rndm_idx][0]+(parlist[rndm_idx][1]-parlist[rndm_idx][0])*np.random.uniform(low=0., high=1.,size=sampsize)

else:
raise ParlistException.PE("This distribution is not supported:",distr_name)

38 changes: 38 additions & 0 deletions generators/extract_binq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import numpy as np
import scipy.stats as ss
from . import ParlistException
from numba import jit

@jit
def getbinq(sampsize,distr_name,parlist):

'''
Extract a number "sampsize" of masses
from a distribution selected among several available.
When a certain "distr_name" is passed, the paramters
for that distribution are passed in the list "parlist"
'''

#Uniform Distribution
if (distr_name == 'uniform'):
if (len(parlist) != 2): raise ParlistException.PE(
"The uniform distribution parlist must have 2 parameters: min_range and max_range",parlist)
if (parlist[1] <= parlist[0]): raise ParlistException.PE(
"parlist[0] must be <= parlist[1]",parlist)
return np.random.uniform(low=parlist[0],high=parlist[1],size=sampsize)

elif (distr_name == 'Trunc_normal'):
if (len(parlist) != 4): raise ParlistException.PE(
"The Truncated normal distribution parlist must have 4 elements: min_range, max_range, mu and sigma",parlist)

cdfh = ss.norm.cdf(parlist[1],loc=parlist[2],scale=parlist[3])
cdfl = ss.norm.cdf(parlist[0],loc=parlist[2],scale=parlist[3])
nrm = cdfh - cdfl
#sample using the inverse cdf
yr = np.random.uniform(low=0,high=1.,size=sampsize)*(nrm)+cdfl
return ss.norm.ppf(yr,loc=parlist[2],scale=parlist[3])

else:
raise ParlistException.PE("This distribution is not supported:",distr_name)

50 changes: 50 additions & 0 deletions generators/extract_mass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import numpy as np
import scipy.stats as ss
from . import ParlistException
from numba import jit

@jit
def getmass(sampsize,distr_name,parlist):

'''
Extract a number "sampsize" of masses
from a distribution selected among several available.
When a certain "distr_name" is passed, the paramters
for that distribution are passed in the list "parlist"
'''

#Uniform Distribution
if (distr_name == 'uniform'):
if (len(parlist) != 2): raise ParlistException.PE("The uniform distribution parlist must have 2 parameters: min_range and max_range",parlist)
if (parlist[1] <= parlist[0]): raise ParlistException.PE("parlist[0] must be <= parlist[1]",parlist)
return np.random.uniform(low=parlist[0],high=parlist[1],size=sampsize)

#Single power law
if (distr_name == 'SPL'):
if (len(parlist) != 3): raise ParlistException.PE("The SPL distribution parlist must have 3 parameters: min_range, max_range and slope",parlist)

#Convert limits from M to logM
log_x_Min = np.log(parlist[0])
log_x_Max = np.log(parlist[1])
max_p = np.power(parlist[0], 1.0 + parlist[2])

# Prepare output array
Y = np.zeros(sampsize)
i = 0
# Fill in array.
while (i < sampsize):
# Draw candidate from logM interval.
logx = np.random.uniform(low=log_x_Min,high=log_x_Max,size=1)
x = np.exp(logx)
# Compute likelihood of candidate from Salpeter SMF.
likelihood = np.power(x, 1.0 + parlist[2])
# Accept randomly.
u = np.random.uniform(low=0.0,high=max_p,size=1)
if (u < likelihood):
Y[i] = x
i+=1
return Y
else:
raise ParlistException.PE("This distribution is not supported:",distr_name)

0 comments on commit 28cf4b7

Please sign in to comment.