Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F92836866
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Nov 24, 02:34
Size
87 KB
Mime Type
application/octet-stream
Expires
Tue, Nov 26, 02:34 (1 d, 21 h)
Engine
blob
Format
Raw Data
Handle
22525448
Attached To
rARRAKIHS ARRAKIHS
View Options
diff --git a/ParticlesToSurfaceBrightness/ARRAKIHS.py b/ParticlesToSurfaceBrightness/ARRAKIHS.py
new file mode 100644
index 0000000..026b907
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/ARRAKIHS.py
@@ -0,0 +1,621 @@
+#!/usr/bin/env python3
+###########################################################################################
+# package: pNbody
+# file: __init__.py
+# brief: init file
+# copyright: GPLv3
+# Copyright (C) 2019 EPFL (Ecole Polytechnique Federale de Lausanne)
+# LASTRO - Laboratory of Astrophysics of EPFL
+# author: Yves Revaz <yves.revaz@epfl.ch>
+#
+# This file is part of pNbody.
+###########################################################################################
+
+
+import numpy as np
+
+from astropy import constants as cte
+from astropy import units as u
+
+from pNbody import *
+from pNbody import ic
+from pNbody import mapping
+from pNbody import geometry
+
+import argparse
+
+import matplotlib.pyplot as plt
+import matplotlib.colors as mcolors
+
+from scipy import signal
+
+import stars_class
+
+
+def SetTelecope(opt):
+
+
+ ##################
+ # set telescope
+
+ if opt.telescope=='arrakihs_vis':
+
+ opt.ccd_shape=[4096,4096]
+ opt.ccd_size=[1.5,1.5]
+
+ if opt.filter is None:
+ opt.filter = "VIS"
+
+ elif opt.telescope=='arrakihs_nir':
+
+ opt.ccd_shape=[2048,2048]
+ opt.ccd_size=[1.3,1.3]
+
+ if opt.filter is None:
+ opt.filter = "UKIRT_J"
+
+
+ elif opt.telescope=='euclid_vis':
+
+ opt.ccd_shape=[24576,24576]
+ opt.ccd_size=[0.787,0.787]
+
+
+ ##################
+ # set filters
+
+ if opt.filter=='F475X':
+ opt.mlim = 30.12
+ opt.mlmin = 29.50
+ opt.mlmax = opt.mlim
+
+ elif opt.filter=='VISeuclid':
+ opt.mlim = 33 #30.23
+ opt.mlmin = 29.5 #29.50 # Euclid preparation: XVI. Borlaff 2021
+ opt.mlmax = opt.mlim
+
+ elif opt.filter=='Yeuclid':
+ opt.mlim = 29.59
+ opt.mlmin = 29.50
+ opt.mlmax = opt.mlim
+
+ elif opt.filter=='Jeuclid':
+ opt.mlim = 31.37
+ opt.mlmin = 29.50
+ opt.mlmax = opt.mlim
+
+
+
+
+
+
+ ##################################
+ # ccd size
+ ##################################
+
+ # degree to arcsec
+ opt.ccd_size = [opt.ccd_size[0]*3600,opt.ccd_size[1]*3600]
+ opt.ccd_pixel_size = [opt.ccd_size[0]/opt.ccd_shape[0],opt.ccd_size[1]/opt.ccd_shape[1]]
+ opt.ccd_pixel_area = opt.ccd_pixel_size[0]*opt.ccd_pixel_size[1]
+
+
+
+
+def GenerateDwarf(opt):
+ '''
+ Generate a dwarf model based on a plummer sphere.
+ Note that the plummer scaling length is equivalent to
+ the projected half light radius.
+ '''
+
+ # set maximal radius
+ rmax = opt.e * opt.rmax_e_ratio
+
+ # convert to int
+ opt.N = int(opt.N)
+
+ # generate the model
+ nb = ic.plummer(opt.N,1,1,1,opt.e,rmax,M=opt.M,irand=1,vel='no',name=opt.outputfilename,ftype='swift')
+
+ if opt.outputfilename is not None:
+ nb.write()
+
+ return nb
+
+
+
+def gaussian_filter(kernel_size, sigma=1, muu=0):
+
+ # Initializing value of x,y as grid of kernel size
+ # in the range of kernel size
+
+ x, y = np.meshgrid(np.linspace(-kernel_size, kernel_size, kernel_size),np.linspace(-kernel_size, kernel_size, kernel_size))
+ dst = np.sqrt(x**2+y**2)
+
+
+ # lower normal part of gaussian
+ #normal = 1/np.sqrt(2 * np.pi * sigma**2)
+
+ # Calculating Gaussian filter
+ gauss = np.exp(-((dst-muu)**2 / (2.0 * sigma**2)))
+ gauss = gauss/gauss.sum()
+
+ return gauss
+
+
+
+def Project(opt):
+ '''
+ Project a stellar model
+ '''
+
+
+ ##################################
+ # factor conversion kpc to arcsec
+ ##################################
+
+ # Mpc to kpc
+ distance = opt.distance * 1000
+
+ # define a conversion function : kpc -> arcsec
+ fct_kpc2arcsec = np.vectorize(lambda x: 3600*180/np.pi* np.arctan(x/distance) )
+ opt.fct_kpc2arcsec = lambda x: 3600*180/np.pi* np.arctan(x/distance)
+
+ # define a conversion function : arcsec -> kpc
+ fct_arcsec2kpc = np.vectorize(lambda x: distance*np.tan(x*np.pi/3600/180) )
+ opt.fct_arcsec2kpc = lambda x: distance*np.tan(x*np.pi/3600/180)
+
+
+ # image properties
+ if opt.fov is not None:
+ xmin = -opt.fov/2.
+ xmax = +opt.fov/2.
+ ymin = -opt.fov/2.
+ ymax = +opt.fov/2.
+
+ nx = int(opt.fov/opt.ccd_pixel_size[0])+1
+ ny = int(opt.fov/opt.ccd_pixel_size[1])+1
+
+
+ elif opt.size is not None:
+ nx = opt.size[0] + 1 # +1 as the resulting matrix will be -1
+ ny = opt.size[1] + 1 # +1 as the resulting matrix will be -1
+
+ xmin = -nx*opt.ccd_pixel_size[0] /2.
+ xmax = +nx*opt.ccd_pixel_size[0] /2.
+ ymin = -ny*opt.ccd_pixel_size[1] /2.
+ ymax = +ny*opt.ccd_pixel_size[1] /2.
+
+ else:
+ nx = int(opt.ccd_shape[0] *opt.ccd_field_fraction)
+ ny = int(opt.ccd_shape[1] *opt.ccd_field_fraction)
+
+ xmin = -opt.ccd_size[0]/2 *opt.ccd_field_fraction
+ xmax = +opt.ccd_size[0]/2 *opt.ccd_field_fraction
+ ymin = -opt.ccd_size[1]/2 *opt.ccd_field_fraction
+ ymax = +opt.ccd_size[1]/2 *opt.ccd_field_fraction
+
+
+
+ # extension in kpc
+ opt.xmin_kpc = fct_arcsec2kpc(xmin)
+ opt.xmax_kpc = fct_arcsec2kpc(xmax)
+ opt.ymin_kpc = fct_arcsec2kpc(ymin)
+ opt.ymax_kpc = fct_arcsec2kpc(ymax)
+
+
+
+ ##################################
+ # open the model
+ ##################################
+
+ if opt.file is None:
+ nb = opt.nb
+ else:
+ nb = Nbody(opt.file)
+ nb.mass = nb.mass*opt.toMsol
+
+ # remove doublets
+ u,idx = np.unique(nb.rxyz(),return_index=True)
+ nb = nb.selectp(lst=nb.num[idx])
+
+ if not nb.has_array("rsp"):
+ # compute Hsml
+ #nb.set_tpe(0)
+ #nb.InitSphParameters(DesNumNgb=32, MaxNumNgbDeviation=2)
+ #nb.getTree()
+ #nb.rsp = nb.get_rsp_approximation()
+ nb.ComputeRsp(5)
+
+ if not nb.has_array("age"):
+ # compute Age [in Gyr]
+ print("Compute ages...")
+ nb.age = nb.StellarAge(units="Gyr")
+ print("done.")
+
+ # rotate
+ if opt.los is not None:
+ nb.align(opt.los)
+
+
+ # compute mass
+ mass = nb.mass
+
+
+
+
+ # scale the model : kpc -> arcsec
+ x = fct_kpc2arcsec(nb.x())
+ y = fct_kpc2arcsec(nb.y())
+ z = fct_kpc2arcsec(nb.z())
+
+ nb.pos = np.transpose((x,y,z))
+ nb.pos = nb.pos.astype(np.float32)
+
+
+ binsx = np.linspace(xmin,xmax,nx)
+ binsy = np.linspace(ymin,ymax,ny)
+
+
+
+
+ # get the luminosity:
+ if opt.filter=="V" or opt.filter=="VIS" or opt.filter=="UKIRT_J" :
+
+ # here we assume the mass of the particle to contain its luminosity
+
+ # luminosity (L_sun)
+ #L = nb.mass.sum()
+
+ # map from numpy
+ #L_map,xe,ye = np.histogram2d(x, y,bins=[binsx,binsy],weights=nb.mass)
+ #L_map = np.rot90(L_map)
+
+ # map from pnbody
+ params = {}
+ params['size'] = (xmax,ymax)
+ params['shape'] = (nx,ny)
+ params['rendering'] = 'map'
+ params['obs'] = None
+ params['xp'] = None
+ params['view'] = opt.view
+ params['mode'] = 'm'
+ params['exec'] = None
+ params['macro'] = None
+ params['frsp'] = opt.frsp
+ params['filter_name'] = None
+
+ L_map = nb.CombiMap(params)
+ L_map = np.rot90(L_map)
+ L_map = np.flipud(L_map)
+
+ # psf convolution
+ if opt.convolve:
+ psf = opt.psf/opt.ccd_pixel_size[0]
+ # gaussian filter
+ psf_map = gaussian_filter(L_map.shape[0],psf)
+ # convolve
+ L_map = signal.convolve2d(L_map, psf_map, mode='same', boundary='fill', fillvalue=0)
+
+
+ # compute the absolute magnitude in each pixel (vband)
+ Mvega = 4.81
+ M_map = Mvega - 2.5*np.log10(L_map)
+
+ # filter stuffs
+ M_V = M_map
+ L_V = L_map
+
+ M_R = M_V -0.45
+ M_I = M_R -0.5
+ M_J = M_I -0.6
+ L_R = np.log10( (M_R-4.43)/(-2.5) )
+ L_I = np.log10( (M_R-4.10)/(-2.5) )
+ L_J = np.log10( (M_J-3.65)/(-2.5) )
+
+ L_VIS = L_V + L_R + L_I
+ M_VIS = 3.216 - 2.5*np.log10(L_VIS)
+
+ if opt.filter=="V":
+ M_map = M_V
+ elif opt.filter=="VIS":
+ M_map = M_VIS
+ elif opt.filter=="UKIRT_J":
+ M_map = M_J
+
+
+ # compute the apparent magnitude in each pixel
+ d = distance*100 # kpc -> 10pc
+ m_map = M_map + 5*np.log10(d)
+
+ # compute the surface brightness in each pixel
+ S_map = m_map + 2.5*np.log10(opt.ccd_pixel_area)
+
+
+ #S_map = L_map
+
+
+
+ elif opt.filter=="F475X" or opt.filter=="VISeuclid" or opt.filter=="Yeuclid" or opt.filter=="Jeuclid":
+
+ if not nb.has_array("MagF475X") or not nb.has_array("MagVISeuclid") or not nb.has_array("MagYeuclid") or not nb.has_array("MagJeuclid"):
+
+
+ # compute a magnitude for the filter in each mass bin
+ print("Compute magnitudes...")
+
+ if opt.filter=="F475X":
+ M = stars_class.HST475X_fun(None,nb.age,nb.MH())
+
+ elif opt.filter=="VISeuclid":
+ M = stars_class.VISeuclid_fun(None,nb.age,nb.MH())
+
+ elif opt.filter=="Yeuclid":
+ M = stars_class.Yeuclid_fun(None,nb.age,nb.MH())
+
+ elif opt.filter=="Jeuclid":
+ M = stars_class.Jeuclid_fun(None,nb.age,nb.MH())
+
+ # convert to flux (ignore the zero point)
+ # to get the correct flux, see notes in Garrotxa
+ F = 10**(-M/2.5)
+
+ # get the number of stars in each mass bin
+ Nstars = stars_class.Stars_fun(mass,None,None, 'normed_3slope')
+
+ # sum the contribution of the mass bins
+ F = np.sum(F*Nstars, axis=0)
+
+ # compute the absolute magnitude in each pixel (as before we ignore the zero point)
+ M = - 2.5*np.log10(F)
+
+ print("done.")
+
+ else:
+
+ if opt.filter=="F475X":
+ M = nb.MagF475X
+
+ elif opt.filter=="VISeuclid":
+ M = nb.MagVISeuclid
+
+ elif opt.filter=="Yeuclid":
+ M = nb.MagYeuclid
+
+ elif opt.filter=="Jeuclid":
+ M = nb.MagJeuclid
+
+
+
+
+ # convert to flux (ignore the zero point)
+ F = 10**(-M/2.5)
+
+ # store in the mass field
+ nb.mass = F.astype(np.float32)
+
+ # map from numpy
+ #L_map,xe,ye = np.histogram2d(x, y,bins=[binsx,binsy],weights=nb.mass)
+ #L_map = np.rot90(L_map)
+
+ # map from pnbody
+ params = {}
+ params['size'] = (xmax,ymax)
+ params['shape'] = (nx,ny)
+ params['rendering'] = 'map'
+ params['obs'] = None
+ params['xp'] = None
+ params['view'] = opt.view
+ params['mode'] = 'm'
+ params['exec'] = None
+ params['macro'] = None
+ params['frsp'] = opt.frsp
+ params['filter_name'] = None
+
+ L_map = nb.CombiMap(params)
+ L_map = np.rot90(L_map)
+ L_map = np.flipud(L_map)
+
+ # psf convolution
+ if opt.convolve:
+ psf = opt.psf/opt.ccd_pixel_size[0]
+ # gaussian filter
+ psf_map = gaussian_filter(L_map.shape[0],psf)
+ # convolve
+ L_map = signal.convolve2d(L_map, psf_map, mode='same', boundary='fill', fillvalue=0)
+
+
+ # compute the absolute magnitude in each pixel (as before we ignore the zero point)
+ M_map = - 2.5*np.log10(L_map)
+
+ # compute the apparent magnitude in each pixel
+ d = distance*100 # kpc -> 10pc
+ m_map = M_map + 5*np.log10(d)
+
+ # compute the surface brightness in each pixel
+ S_map = m_map + 2.5*np.log10(opt.ccd_pixel_area)
+
+
+
+
+
+
+
+
+
+
+ return S_map,xmin,xmax,ymin,ymax
+
+
+
+
+def SkySurfaceBrightness(opt,shape):
+ '''
+ Generate a sky surface brightness
+
+ sky background on earth : 21.8 mag/arcsec2 in V
+ '''
+
+ mean = opt.sky_mean
+ std = (mean - opt.mlim)/3.
+ sky_image = np.random.normal(mean,std,shape)
+
+ print(" mean :",sky_image.mean())
+ print(" 3*std :",3*sky_image.std())
+ print(" mean-3*std :",sky_image.mean()-3*sky_image.std())
+
+ return sky_image
+
+
+
+
+
+def AddSkyBackground(opt,image):
+ """
+ !!! this must be corrected !!! the filter is bad
+ """
+
+ if opt.sky_background:
+ sky = SkySurfaceBrightness(opt,image.shape)
+
+
+ M0 = 4.81
+ Fg = 10**((-image+M0)/2.5)
+ Fs = 10**((-sky +M0)/2.5)
+
+ image = -2.5*np.log10(Fg + Fs) + M0
+
+ plt.imshow(image)
+ plt.show()
+
+
+
+ return image
+
+
+def Display(opt,ax,image,xmin,xmax,ymin,ymax):
+
+
+ mmin = 25 # min magnitude
+ mmax = 36 # max magnitude
+
+
+ if opt.split_colorbar:
+ mlim = opt.mlim # limit magnitude
+
+ n1 = int(256* (mlim-mmin)/(mmax-mmin))
+ n2 = 256-n1
+
+ colors1 = plt.cm.gist_heat_r(np.linspace(0.75, 0.25, n1))
+ #colors2 = plt.cm.binary(np.linspace(0.25, 0.0, n2))
+ colors2 = plt.cm.binary(np.linspace(0.25, 0.0, n2))
+
+ # combine them and build a new colormap
+ colors = np.vstack((colors1, colors2))
+ mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
+
+ else:
+ mymap = plt.cm.Greys_r
+
+ # use kpc units
+ xmin=opt.xmin_kpc
+ xmax=opt.xmax_kpc
+ ymin=opt.ymin_kpc
+ ymax=opt.ymax_kpc
+
+ im = ax.imshow(image,aspect='equal',extent=(xmin,xmax,ymin,ymax),cmap=mymap,interpolation=None,vmin=mmin,vmax=mmax)
+
+
+ return im
+
+
+
+
+def DisplayDiff(opt,ax,image,xmin,xmax,ymin,ymax):
+
+
+ mmin = 25 # min magnitude
+ mmax = 36 # max magnitude
+
+
+ if opt.split_colorbar:
+ mlim = opt.mlim # limit magnitude
+
+ mlmin = opt.mlmin
+ mlmax = opt.mlmax
+
+ n1 = int(256* (mlmin-mmin)/(mmax-mmin))
+ n2 = int(256* (mlmax-mmin)/(mmax-mmin)) - n1
+ n3 = 256 - int(256* (mlmax-mmin)/(mmax-mmin))
+
+
+ colors1 = plt.cm.binary(np.linspace(0.0, 0.0, n1))
+ colors2 = plt.cm.gist_heat_r(np.linspace(0.7, 0.3, n2))
+ colors3 = plt.cm.binary(np.linspace(0.0, 0.0, n3))
+
+
+ # combine them and build a new colormap
+ colors = np.vstack((colors1,colors2,colors3))
+ mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
+
+ else:
+ mymap = plt.cm.Greys_r
+
+ # use kpc units
+ xmin=opt.xmin_kpc
+ xmax=opt.xmax_kpc
+ ymin=opt.ymin_kpc
+ ymax=opt.ymax_kpc
+
+ im = ax.imshow(image,aspect='equal',extent=(xmin,xmax,ymin,ymax),cmap=mymap,interpolation=None,vmin=mmin,vmax=mmax)
+
+
+ return im
+
+
+
+
+def DisplaySingle(opt,ax,image,xmin,xmax,ymin,ymax):
+
+
+
+ mmin = opt.mlmin
+ mmax = opt.mlmax
+
+ opt.split_colorbar=False
+
+ if opt.split_colorbar:
+ #mlim = opt.mlim # limit magnitude
+
+ #mlmin = opt.mlmin
+ #mlmax = opt.mlmax
+
+ #n1 = int(256* (mlmin-mmin)/(mmax-mmin))
+ #n2 = int(256* (mlmax-mmin)/(mmax-mmin)) - n1
+ #n3 = 256 - int(256* (mlmax-mmin)/(mmax-mmin))
+
+
+ #colors1 = plt.cm.binary(np.linspace(0.0, 0.0, n1))
+ colors2 = plt.cm.gist_heat(np.linspace(0.3, 1.0, 255))
+ #colors3 = plt.cm.binary(np.linspace(0.0, 0.0, n3))
+
+
+ # combine them and build a new colormap
+ #colors = np.vstack((colors1,colors2,colors3))
+ mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors2)
+
+ #mymap = plt.cm.gist_heat
+
+ else:
+ mymap = plt.cm.gist_heat
+
+ # use kpc units
+ xmin=opt.xmin_kpc
+ xmax=opt.xmax_kpc
+ ymin=opt.ymin_kpc
+ ymax=opt.ymax_kpc
+
+ im = ax.imshow(image,aspect='equal',extent=(xmin,xmax,ymin,ymax),cmap=mymap,interpolation=None,vmin=mmin,vmax=mmax)
+
+
+ return im
diff --git a/ParticlesToSurfaceBrightness/IMF.py b/ParticlesToSurfaceBrightness/IMF.py
new file mode 100644
index 0000000..f82e34d
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/IMF.py
@@ -0,0 +1,232 @@
+import numpy as np
+
+####################
+ ## IMF subroutines
+####################
+
+def slope_imf(x,p1,p2,p3,kn1,kn2):
+
+#Is calculating a three slope IMF
+#INPUT:
+# x = An array of masses for which the IMF should be calculated
+# p1..p3 = the slopes of the power law
+# kn1, kn2 = Where the breaks of the power law are
+#OUTPUT:
+# An array of frequencies matching the mass base array x
+ if(x > kn2):
+ t = (pow(kn2,p2)/pow(kn2,p3))*pow(x,p3+1)
+ elif (x < kn1):
+ t = (pow(kn1,p2)/pow(kn1,p1))*pow(x,p1+1)
+ else:
+ t = pow(x,p2+1)
+ return t
+
+
+def lifetime(m,Z):
+
+#here we will calculate the MS lifetime of the star after Argast et al., 2000, A&A, 356, 873
+#INPUT:¡
+# m = mass in Msun
+# Z = metallicity in Zsun
+
+#OUTPUT:
+# returns the lifetime of the star in Gyrs
+
+ lm = np.log10(m)
+ a0 = 3.79 + 0.24*Z
+ a1 = -3.10 - 0.35*Z
+ a2 = 0.74 + 0.11*Z
+ tmp = a0 + a1*lm + a2*lm*lm
+ return np.divide(np.power(10,tmp),1000)
+
+
+class IMF(object):
+
+#This class represents the IMF normed to 1 in units of M_sun.
+#Input for initialisation:
+
+# mmin = minimal mass of the IMF
+
+# mmax = maximal mass of the IMF
+
+# intervals = how many steps inbetween mmin and mmax should be given
+
+#Then one of the IMF functions can be used
+
+# self.x = mass base
+
+# self.dn = the number of stars at x
+
+# self.dm = the masses for each mass interval x
+
+ def __init__(self, mmin = 0.08 , mmax = 100., intervals = 5000):
+ self.mmin = mmin
+ self.mmax = mmax
+ self.intervals = intervals
+ self.x = np.linspace(mmin,mmax,intervals)
+ self.dx = self.x[1]-self.x[0]
+
+ def normed_3slope(self,paramet = (-1.3,-2.2,-2.7,0.5,1.0)):
+
+# Three slope IMF, Kroupa 1993 as a default
+
+ s1,s2,s3,k1,k2 = paramet
+ u = np.zeros_like(self.x)
+ v = np.zeros_like(self.x)
+ for i in range(len(self.x)):
+ u[i] = slope_imf(self.x[i],s1,s2,s3,k1,k2)
+ v = np.divide(u,self.x)
+ self.dm = np.divide(u,sum(u))
+ self.dn = np.divide(self.dm,self.x)
+ return(self.dm,self.dn)
+
+
+ def Chabrier_1(self, paramet = (0.69, 0.079, -2.3)):
+
+# Chabrier IMF from Chabrier 2003 equation 17 field IMF with variable high mass slope and automatic normalisation
+
+ sigma, m_c, expo = paramet
+ dn = np.zeros_like(self.x)
+ for i in range(len(self.x)):
+ if self.x[i] <= 1:
+ index_with_mass_1 = i
+ dn[i] = (1. / float(self.x[i])) * np.exp(-1*(((np.log10(self.x[i] / m_c))**2)/(2*sigma**2)))
+ else:
+ dn[i] = (pow(self.x[i],expo))
+ # Need to 'attach' the upper to the lower branch
+ derivative_at_1 = dn[index_with_mass_1] - dn[index_with_mass_1 - 1]
+ target_y_for_m_plus_1 = dn[index_with_mass_1] + derivative_at_1
+ rescale = target_y_for_m_plus_1 / dn[index_with_mass_1 + 1]
+ dn[np.where(self.x>1.)] *= rescale
+ # Normalizing to 1 in mass space
+ self.dn = np.divide(dn,sum(dn))
+ dm = dn*self.x
+ self.dm = np.divide(dm,sum(dm))
+ self.dn = np.divide(self.dm,self.x)
+ return(self.dm,self.dn)
+
+
+ def Chabrier_2(self,paramet = (22.8978, 716.4, 0.25,-2.3)):
+
+# Chabrier IMF from Chabrier 2001, IMF 3 = equation 8 parameters from table 1
+
+
+ A,B,sigma,expo = paramet
+ expo -= 1. ## in order to get an alpha index normalisation
+ dn = np.zeros_like(self.x)
+ for i in range(len(self.x)):
+ dn[i] = A*(np.exp(-pow((B/self.x[i]),sigma)))*pow(self.x[i],expo)
+ self.dn = np.divide(dn,sum(dn))
+ dm = dn*self.x
+ self.dm = np.divide(dm,sum(dm))
+ self.dn = np.divide(self.dm,self.x)
+ return(self.dm,self.dn)
+
+
+ def salpeter(self, alpha = (2.35)):
+
+# Salpeter IMF
+
+# Input the slope of the IMF
+
+ self.alpha = alpha
+ temp = np.power(self.x,-self.alpha)
+ norm = sum(temp)
+ self.dn = np.divide(temp,norm)
+ u = self.dn*self.x
+ self.dm = np.divide(u,sum(u))
+ self.dn = np.divide(self.dm,self.x)
+ return (self.dm,self.dn)
+
+
+ def BrokenPowerLaw(self, paramet):
+ breaks,slopes = paramet
+ if len(breaks) != len(slopes)-1:
+ print("error in the precription of the power law. It needs one more slope than break value")
+ else:
+ dn = np.zeros_like(self.x)
+ self.breaks = breaks
+ self.slopes = slopes
+ self.mass_range = np.hstack((self.mmin,breaks,self.mmax))
+ for i,item in enumerate(self.slopes):
+ cut = np.where(np.logical_and(self.x>=self.mass_range[i],self.x<self.mass_range[i+1]))
+ dn[cut] = np.power(self.x[cut],item)
+ if i != 0:
+ renorm = np.divide(last_dn,dn[cut][0])
+ dn[cut] = dn[cut]*renorm
+ last_dn = dn[cut][-1]
+ last_x = self.x[cut][-1]
+ self.dn = np.divide(dn,sum(dn))
+ u = self.dn*self.x
+ self.dm = np.divide(u,sum(u))
+ self.dn = np.divide(self.dm,self.x)
+ return (self.dm,self.dn)
+
+
+ def imf_mass_fraction(self,mlow,mup):
+
+# Calculates the mass fraction of the IMF sitting between mlow and mup
+
+ norm = sum(self.dm)
+ cut = np.where(np.logical_and(self.x>=mlow,self.x<mup))
+ fraction = np.divide(sum(self.dm[cut]),norm)
+ return(fraction)
+
+ def imf_number_fraction(self,mlow,mup):
+
+# Calculating the number fraction of stars of the IMF sitting between mlow and mup
+
+ norm = sum(self.dn)
+ cut = np.where(np.logical_and(self.x>=mlow,self.x<mup))
+ fraction = np.divide(sum(self.dn[cut]),norm)
+ return(fraction)
+
+ def imf_number_stars(self,mlow,mup):
+ cut = np.where(np.logical_and(self.x>=mlow,self.x<mup))
+ number = sum(self.dn[cut])
+ return(number)
+
+ def stochastic_sampling(self, mass):
+
+# The analytic IMF will be resampled according to the mass of the SSP.
+# The IMF will still be normalised to 1
+
+# Stochastic sampling is realised by fixing the number of expected stars and then drawing from the probability distribution of the number density
+# Statistical properties are tested for this sampling and are safe: number of stars and masses converge.
+
+ number_of_stars = int(round(sum(self.dn) * mass))
+ self.dm_copy = np.copy(self.dm)
+ self.dn_copy = np.copy(self.dn)
+
+ #self.dn_copy = np.divide(self.dn_copy,sum(self.dn_copy))
+ random_number = np.random.uniform(low = 0.0, high = sum(self.dn_copy), size = number_of_stars)
+ self.dm = np.zeros_like(self.dm)
+ self.dn = np.zeros_like(self.dn)
+
+ ### This could be favourable if the number of stars drawn is low compared to the imf resolution
+# for i in range(number_of_stars):
+ ### the next line randomly draws a mass according to the number distribution of stars
+# cut = np.where(np.abs(np.cumsum(self.dn_copy)-random_number[i])== np.min(np.abs(np.cumsum(self.dn_copy)-random_number[i])))
+# x1 = self.x[cut][0]
+ #self.dn[cut] += 0.5
+# self.dn[cut[0]] += 1
+# self.dm[cut[0]] += x1 + self.dx/2.
+# t.append(x1 + self.dx/2.)
+
+ counting = np.cumsum(self.dn_copy)
+ for i in range(len(counting)-1):
+ if i == 0:
+ cut = np.where(np.logical_and(random_number>0.,random_number<=counting[i]))
+ else:
+ cut = np.where(np.logical_and(random_number>counting[i-1],random_number<=counting[i]))
+ number_of_stars_in_mass_bin = len(random_number[cut])
+ self.dm[i] = number_of_stars_in_mass_bin * self.x[i]
+ if number_of_stars:
+ self.dm = np.divide(self.dm,sum(self.dm))
+ else:
+ self.dm = np.divide(self.dm, 1)
+ self.dn = np.divide(self.dm,self.x)
+ return (self.dm,self.dn)
+########
+ ## End IMF subroutines
+########
diff --git a/ParticlesToSurfaceBrightness/Readme b/ParticlesToSurfaceBrightness/Readme
new file mode 100644
index 0000000..223cea5
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/Readme
@@ -0,0 +1,48 @@
+# requirement : pNbody https://lastro.epfl.ch/projects/pNbody/
+
+
+#################################################
+# download snapshots containing only stars
+# we need to find another repo for big data
+
+stars_1keV_1000kpc.hdf5
+stars_3keV_1000kpc.hdf5
+stars_10keV_1000kpc.hdf5
+stars_30keV_1000kpc.hdf5
+
+#################################################
+# add additional information (age, magnitudes, html)
+
+./arrakihs_addfields.py -o stars_1keV_1000kpc.hdf5 stars_1keV_1000kpc.hdf5
+./arrakihs_addfields.py -o stars_3keV_1000kpc.hdf5 stars_3keV_1000kpc.hdf5
+./arrakihs_addfields.py -o stars_10keV_1000kpc.hdf5 stars_10keV_1000kpc.hdf5
+./arrakihs_addfields.py -o stars_30keV_1000kpc.hdf5 stars_30keV_1000kpc.hdf5
+
+
+################################################
+# compute a set of images
+
+./arrakihs_compute_images.py --telescope arrakihs_vis --filter F475X --fov 5000 --distance 25 --frsp 0.25 --nlos 16 -o F475X_1keV.pkl stars_1keV_1000kpc.hdf5
+./arrakihs_compute_images.py --telescope arrakihs_vis --filter VISeuclid --fov 5000 --distance 25 --frsp 0.25 --nlos 16 -o VISeuclid_3keV.pkl stars_3keV_1000kpc.hdf5
+./arrakihs_compute_images.py --telescope arrakihs_vis --filter Yeuclid --fov 5000 --distance 25 --frsp 0.25 --nlos 16 -o Yeuclid_1keV.pkl stars_1keV_1000kpc.hdf5
+./arrakihs_compute_images.py --telescope arrakihs_vis --filter Jeuclid --fov 5000 --distance 25 --frsp 0.25 --nlos 16 -o Jeuclid_1keV.pkl stars_1keV_1000kpc.hdf5
+
+################################################
+# display or save images in the pkl file
+
+./arrakihs_show_images.py F475X_1keV.pkl -o F475X_1keV.png
+./arrakihs_show_images.py VISeuclid_3keV.pkl -o VISeuclid_3keV.png
+./arrakihs_show_images.py Yeuclid_1keV.pkl -o Yeuclid_1keV.png
+./arrakihs_show_images.py Jeuclid_1keV.pkl -o Jeuclid_1keV.png
+
+###############################################
+# compute and compare the fraction of illuminated pixels
+
+./arrakihs_compute_illuminated.py -o F475X_coverage_fraction.png F475X_1keV.pkl F475X_3keV.pkl F475X_10keV.pkl F475X_30keV.pkl
+./arrakihs_compute_illuminated.py -o VISeuclid_coverage_fraction.png VISeuclid_1keV.pkl VISeuclid_3keV.pkl VISeuclid_10keV.pkl VISeuclid_30keV.pkl
+./arrakihs_compute_illuminated.py -o Yeuclid_coverage_fraction.png Yeuclid_1keV.pkl Yeuclid_3keV.pkl Yeuclid_10keV.pkl Yeuclid_30keV.pkl
+./arrakihs_compute_illuminated.py -o Jeuclid_coverage_fraction.png Jeuclid_1keV.pkl Jeuclid_3keV.pkl Jeuclid_10keV.pkl Jeuclid_30keV.pkl
+
+
+
+
diff --git a/ParticlesToSurfaceBrightness/arrakihs_addfields.py b/ParticlesToSurfaceBrightness/arrakihs_addfields.py
new file mode 100755
index 0000000..102dfe5
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/arrakihs_addfields.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python3
+
+import argparse
+import numpy as np
+from pNbody import *
+
+import stars_class
+
+
+####################################################################
+# option parser
+####################################################################
+
+description=""
+epilog =""""""
+
+parser = argparse.ArgumentParser(description=description,epilog=epilog,formatter_class=argparse.RawDescriptionHelpFormatter)
+
+
+parser.add_argument(action="store",
+ dest="files",
+ metavar='FILE',
+ type=str,
+ default=None,
+ nargs='*',
+ help='a file name')
+
+parser.add_argument("-o",
+ action="store",
+ type=str,
+ dest="outputfilename",
+ default=None,
+ help="Name of the output file")
+
+####################################################################
+# main
+####################################################################
+
+
+if __name__ == '__main__':
+
+ opt = parser.parse_args()
+
+ for f in opt.files:
+ nb = Nbody(f,ftype="arepo")
+
+
+ # remove doublets
+ u,idx = np.unique(nb.rxyz(),return_index=True)
+ nb = nb.selectp(lst=nb.num[idx])
+
+
+ ###################################
+ # Stellar ages
+ ###################################
+ print("Compute ages...")
+ nb.age = nb.StellarAge(units="Gyr")
+ print("done.")
+
+ ###################################
+ # compute Hsml
+ ###################################
+ print("Compute Rsp...")
+ #nb.set_tpe(0)
+ #nb.InitSphParameters(DesNumNgb=32, MaxNumNgbDeviation=2)
+ #nb.getTree()
+ #nb.rsp = nb.get_rsp_approximation()
+ #nb.set_tpe(4)
+ nb.ComputeRsp(5)
+ print("done.")
+
+ ###################################
+ # compute Magnitudes
+ ###################################
+ print("Compute magnitudes...")
+ MH = nb.MH()
+
+ # mass in Msol
+ mass = nb.mass * 1e10
+
+ # get the number of stars in each mass bin
+ Nstars = stars_class.Stars_fun(mass,None,None, 'normed_3slope')
+
+ ##############################
+ # F475X magnitude
+
+ M = stars_class.HST475X_fun(None,nb.age,MH)
+ # convert to flux (ignore the zero point)
+ F = 10**(-M/2.5)
+ # sum the contribution of the mass bins
+ F = np.sum(F*Nstars, axis=0)
+ # compute the absolute magnitude in each pixel (as before we ignore the zero point)
+ M = - 2.5*np.log10(F)
+ nb.MagF475X = M
+
+ ##############################
+ # VIS Euclid magnitude
+
+ M = stars_class.VISeuclid_fun(None,nb.age,MH)
+ # convert to flux (ignore the zero point)
+ F = 10**(-M/2.5)
+ # sum the contribution of the mass bins
+ F = np.sum(F*Nstars, axis=0)
+ # compute the absolute magnitude in each pixel (as before we ignore the zero point)
+ M = - 2.5*np.log10(F)
+ nb.MagVISeuclid = M
+
+ ##############################
+ # Y Euclid magnitude
+
+ M = stars_class.Yeuclid_fun(None,nb.age,MH)
+ # convert to flux (ignore the zero point)
+ F = 10**(-M/2.5)
+ # sum the contribution of the mass bins
+ F = np.sum(F*Nstars, axis=0)
+ # compute the absolute magnitude in each pixel (as before we ignore the zero point)
+ M = - 2.5*np.log10(F)
+ nb.MagYeuclid = M
+
+ ##############################
+ # J Euclid magnitude
+
+ M = stars_class.Jeuclid_fun(None,nb.age,MH)
+ # convert to flux (ignore the zero point)
+ F = 10**(-M/2.5)
+ # sum the contribution of the mass bins
+ F = np.sum(F*Nstars, axis=0)
+ # compute the absolute magnitude in each pixel (as before we ignore the zero point)
+ M = - 2.5*np.log10(F)
+ nb.MagJeuclid = M
+
+
+ print("done.")
+
+
+ if opt.outputfilename:
+ nb.rename(opt.outputfilename)
+ nb.write()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ParticlesToSurfaceBrightness/arrakihs_compute_illuminated.py b/ParticlesToSurfaceBrightness/arrakihs_compute_illuminated.py
new file mode 100755
index 0000000..45c31d6
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/arrakihs_compute_illuminated.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+
+import numpy as np
+
+from astropy import constants as cte
+from astropy import units as u
+
+import argparse
+
+import matplotlib.pyplot as plt
+import matplotlib.colors as mcolors
+
+from pNbody import *
+from pNbody import ic
+import ARRAKIHS
+
+import pickle
+
+
+####################################################################
+# option parser
+####################################################################
+
+description=""
+epilog =""""""
+
+parser = argparse.ArgumentParser(description=description,epilog=epilog,formatter_class=argparse.RawDescriptionHelpFormatter)
+
+
+
+
+
+parser.add_argument(action="store",
+ dest="files",
+ metavar='FILE',
+ type=str,
+ default=None,
+ nargs='*',
+ help='a file name')
+
+parser.add_argument("-o",
+ action="store",
+ type=str,
+ dest="outputfilename",
+ default=None,
+ help="Name of the output file")
+
+
+
+parser.add_argument('--mlim',
+ action="store",
+ dest="mlim",
+ metavar='FLOAT',
+ type=float,
+ default=31,
+ help='magnitude limit')
+
+
+
+
+
+parser.add_argument("--mlmin",
+ action="store",
+ dest="mlmin",
+ metavar='FLOAT',
+ type=float,
+ default=None,
+ help='mag lim min')
+
+parser.add_argument("--mlmax",
+ action="store",
+ dest="mlmax",
+ metavar='FLOAT',
+ type=float,
+ default=None,
+ help='mag lim max')
+
+parser.add_argument("--nlos",
+ action="store",
+ dest="nlos",
+ metavar='INT',
+ type=int,
+ default=1,
+ help='number of los')
+
+
+
+
+####################################################################
+# main
+####################################################################
+
+cs = ['r','g','b','y']
+nmagbins = 50
+mag0 = 33
+magmax = mag0
+
+if __name__ == '__main__':
+
+ opt = parser.parse_args()
+
+
+ for j,f in enumerate(opt.files):
+
+ print(f)
+
+ fd = open(f,"rb")
+ images = pickle.load(fd)
+ fd.close()
+
+ # loop over images of the same model
+
+ Npixs = np.zeros((len(images),nmagbins))
+
+
+ for k in range(len(images)):
+
+ image,xmin,xmax,ymin,ymax = images[k]
+
+
+ Npixtot = image.shape[0]*image.shape[1]
+
+ # clean
+ image = np.where(np.isinf(image),100,image)
+
+
+
+ magbins = np.linspace(26,magmax,nmagbins)
+ Npix = np.zeros(nmagbins)
+
+ for i in tqdm(range(nmagbins)):
+ img1 = np.where(image<magbins[i],1,0)
+ Npix[i] = np.ravel(img1).sum()
+
+ # normalize
+ #Npix = Npix/Npixtot
+ #idx = np.argmin(np.fabs(magbins - mag0))
+ #Npix = Npix/Npix[idx]
+ Npix = Npix/Npixtot
+
+
+
+ #plt.plot(magbins,Npix,color=cs[j])
+
+
+ # sum
+ Npixs[k] = Npix
+
+
+
+ mean = Npixs.mean(axis=0)
+ std = Npixs.std(axis=0)
+
+ label = os.path.basename(f)
+ label = label[label.find("_")+1:]
+ label = label[:-4]
+
+
+ plt.plot(magbins,mean,color=cs[j],label=r"$%s$"%label,lw=2)
+ #plt.plot(magbins,mean+1*std,color=cs[j],lw=5)
+ #plt.plot(magbins,mean-1*std,color=cs[j],lw=5)
+
+ ax = plt.gca()
+ ax.fill_between(magbins,mean+1*std,mean-1*std,facecolor=cs[j],alpha=0.1)
+
+
+
+ plt.legend()
+ plt.xlabel(r"$\rm{VIS}\,\,\rm{magnitude}$")
+ plt.ylabel(r"$\rm{coverage\,\,fraction}$")
+
+ if opt.outputfilename is None:
+ plt.show()
+ else:
+ plt.savefig(opt.outputfilename)
+
+
+
+
+
diff --git a/ParticlesToSurfaceBrightness/arrakihs_compute_images.py b/ParticlesToSurfaceBrightness/arrakihs_compute_images.py
new file mode 100755
index 0000000..e8a3055
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/arrakihs_compute_images.py
@@ -0,0 +1,294 @@
+#!/usr/bin/env python3
+
+import numpy as np
+
+from astropy import constants as cte
+from astropy import units as u
+
+import argparse
+
+import matplotlib.pyplot as plt
+import matplotlib.colors as mcolors
+
+from pNbody import *
+from pNbody import ic
+import ARRAKIHS
+
+import pickle
+
+
+####################################################################
+# option parser
+####################################################################
+
+description=""
+epilog =""""""
+
+parser = argparse.ArgumentParser(description=description,epilog=epilog,formatter_class=argparse.RawDescriptionHelpFormatter)
+
+
+
+
+
+parser.add_argument(action="store",
+ dest="file",
+ metavar='FILE',
+ type=str,
+ default=None,
+ nargs='*',
+ help='a file name')
+
+parser.add_argument("-o",
+ action="store",
+ type=str,
+ dest="outputfilename",
+ default=None,
+ help="Name of the output file")
+
+
+parser.add_argument("--ccd_shape",
+ action="store",
+ dest="ccd_shape",
+ metavar='INT INT',
+ type=int,
+ default=[4096,4096],
+ nargs=2,
+ help='ccd shape')
+
+parser.add_argument("--size",
+ action="store",
+ dest="size",
+ metavar='INT INT',
+ type=int,
+ default=None,
+ nargs=2,
+ help='image size')
+
+
+
+parser.add_argument("--ccd_size",
+ action="store",
+ dest="ccd_size",
+ metavar='FLOAT FLOAT',
+ type=float,
+ default=[1.5,1.5],
+ nargs=2,
+ help='ccd size in degree')
+
+
+parser.add_argument("--ccd_field_fraction",
+ action="store",
+ dest="ccd_field_fraction",
+ metavar='FLOAT',
+ type=float,
+ default=1,
+ help='fraction of the field displayed')
+
+
+parser.add_argument("--fov",
+ action="store",
+ dest="fov",
+ metavar='FLOAT',
+ type=float,
+ default=None,
+ help='field of view in arcsec')
+
+
+
+parser.add_argument("--psf",
+ action="store",
+ dest="psf",
+ metavar='FLOAT',
+ type=float,
+ default=0.8,
+ help='psf in arcsec')
+
+
+parser.add_argument("--convolve",
+ action="store_true",
+ dest="convolve",
+ default=False,
+ help='convolve with the pdf')
+
+
+parser.add_argument('--distance',
+ action="store",
+ dest="distance",
+ metavar='FLOAT',
+ type=float,
+ default=20,
+ help='distance of the object in Mpc')
+
+
+
+parser.add_argument('--mlim',
+ action="store",
+ dest="mlim",
+ metavar='FLOAT',
+ type=float,
+ default=31,
+ help='magnitude limit')
+
+
+parser.add_argument("--sky_background",
+ action="store_true",
+ dest="sky_background",
+ default=False,
+ help='add sky background')
+
+
+parser.add_argument("--sky_N",
+ action="store",
+ dest="sky_N",
+ metavar='FLOAT',
+ type=float,
+ default=1e6,
+ help='number of particles in the sky')
+
+parser.add_argument("--sky_M",
+ action="store",
+ dest="sky_M",
+ metavar='FLOAT',
+ type=float,
+ default=3.4e5,
+ help='total sky mass [Msol]')
+
+parser.add_argument("--sky_e",
+ action="store",
+ dest="sky_e",
+ metavar='FLOAT',
+ type=float,
+ default=3,
+ help='sky size [kpc]')
+
+parser.add_argument("--sky_mean",
+ action="store",
+ dest="sky_mean",
+ metavar='FLOAT',
+ type=float,
+ default=34,
+ help='sky mean surface brighness')
+
+
+
+parser.add_argument("--telescope",
+ action="store",
+ dest="telescope",
+ metavar='STR',
+ type=str,
+ default='arrakihs_vis',
+ help='telescope name')
+
+parser.add_argument("--filter",
+ action="store",
+ dest="filter",
+ metavar='STR',
+ type=str,
+ default=None,
+ help='filter name')
+
+
+parser.add_argument("--toMsol",
+ action="store",
+ dest="toMsol",
+ metavar='FLOAT',
+ type=float,
+ default=1e10,
+ help='mass convertion to solar mass')
+
+parser.add_argument("--frsp",
+ action="store",
+ dest="frsp",
+ metavar='FLOAT',
+ type=float,
+ default=0,
+ help='factor for the image smoothing')
+
+
+parser.add_argument("--view",
+ action="store",
+ dest="view",
+ metavar='STR',
+ type=str,
+ default='xy',
+ help='view xy, yz, zx')
+
+parser.add_argument("--mlmin",
+ action="store",
+ dest="mlmin",
+ metavar='FLOAT',
+ type=float,
+ default=None,
+ help='mag lim min')
+
+parser.add_argument("--mlmax",
+ action="store",
+ dest="mlmax",
+ metavar='FLOAT',
+ type=float,
+ default=None,
+ help='mag lim max')
+
+parser.add_argument("--nlos",
+ action="store",
+ dest="nlos",
+ metavar='INT',
+ type=int,
+ default=1,
+ help='number of los')
+
+
+
+
+####################################################################
+# main
+####################################################################
+
+def get_axes(n=7,irand=0):
+
+ np.random.seed(irand)
+ random2 = np.random.random(n)
+ random3 = np.random.random(n)
+
+ phi = random2 * np.pi * 2.
+ costh = 1. - 2. * random3
+
+ sinth = np.sqrt(1. - costh**2)
+
+ x = sinth * np.cos(phi)
+ y = sinth * np.sin(phi)
+ z = costh
+
+ pos = np.transpose(np.array([x, y, z]))
+
+ return pos
+
+
+
+
+if __name__ == '__main__':
+
+ opt = parser.parse_args()
+
+ naxes = opt.nlos
+ axes = get_axes(naxes)
+
+
+ ARRAKIHS.SetTelecope(opt)
+
+ images = []
+
+ # loop over axes
+ for i in range(naxes):
+ opt.los=axes[i]
+ image = ARRAKIHS.Project(opt) # here we get: image,xmin,xmax,ymin,ymax
+ images.append(image)
+
+
+ if opt.outputfilename is not None:
+
+ f = open(opt.outputfilename,'wb')
+ pickle.dump(images,f)
+ f.close()
+
+
diff --git a/ParticlesToSurfaceBrightness/arrakihs_show_images.py b/ParticlesToSurfaceBrightness/arrakihs_show_images.py
new file mode 100755
index 0000000..1ef266a
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/arrakihs_show_images.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python3
+
+import numpy as np
+
+from astropy import constants as cte
+from astropy import units as u
+
+import argparse
+
+import matplotlib.pyplot as plt
+import matplotlib.colors as mcolors
+
+from pNbody import *
+from pNbody import ic
+import ARRAKIHS
+
+import pickle
+import os
+
+####################################################################
+# option parser
+####################################################################
+
+description=""
+epilog =""""""
+
+parser = argparse.ArgumentParser(description=description,epilog=epilog,formatter_class=argparse.RawDescriptionHelpFormatter)
+
+
+
+
+
+parser.add_argument(action="store",
+ dest="file",
+ metavar='FILE',
+ type=str,
+ default=None,
+ nargs='*',
+ help='a file name')
+
+parser.add_argument("-o",
+ action="store",
+ type=str,
+ dest="outputfilename",
+ default=None,
+ help="Name of the output file")
+
+
+
+
+
+
+parser.add_argument('--mlim',
+ action="store",
+ dest="mlim",
+ metavar='FLOAT',
+ type=float,
+ default=31,
+ help='magnitude limit')
+
+
+
+
+
+parser.add_argument("--mlmin",
+ action="store",
+ dest="mlmin",
+ metavar='FLOAT',
+ type=float,
+ default=None,
+ help='mag lim min')
+
+parser.add_argument("--mlmax",
+ action="store",
+ dest="mlmax",
+ metavar='FLOAT',
+ type=float,
+ default=None,
+ help='mag lim max')
+
+parser.add_argument("--nlos",
+ action="store",
+ dest="nlos",
+ metavar='INT',
+ type=int,
+ default=1,
+ help='number of los')
+
+
+parser.add_argument("--filter",
+ action="store",
+ dest="filter",
+ metavar='STR',
+ type=str,
+ default=None,
+ help='filter name')
+
+
+parser.add_argument("--MDM",
+ action="store",
+ dest="MDM",
+ metavar='FLOAT',
+ type=float,
+ default=1,
+ help='dark mattermass')
+
+
+
+####################################################################
+# main
+####################################################################
+
+
+if __name__ == '__main__':
+
+ opt = parser.parse_args()
+
+
+ if len(opt.file)==0:
+ print("need to provie one file")
+ exit()
+
+
+ f = open(opt.file[0],"rb")
+ images = pickle.load(f)
+ f.close()
+
+ nx = int(np.sqrt(len(images)))
+ ny = nx
+
+
+ fig, ax = plt.subplots(nx,ny)
+
+ # plot
+ fig = plt.gcf()
+ fig.set_size_inches(12*1.15, 12)
+
+ fig.subplots_adjust(left=0.1)
+ fig.subplots_adjust(right=1)
+ fig.subplots_adjust(bottom=0.05)
+ fig.subplots_adjust(top=0.95)
+ fig.subplots_adjust(wspace=0.02)
+ fig.subplots_adjust(hspace=0.02)
+
+
+ colors2 = plt.cm.gist_heat(np.linspace(0.3, 1.0, 255))
+ mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors2)
+
+ for i in range(len(images)):
+
+ image,xmin,xmax,ymin,ymax = images[i]
+
+ #image = np.where(image>26,34,image)
+
+
+ ix = i//nx
+ iy = i- (ix*nx)
+
+
+ #ax[i] = plt.gca()
+ ax[ix,iy].set_aspect('equal')
+
+ mmin = 24
+ mmax = 33
+
+ im = ax[ix,iy].imshow(image,aspect='equal',extent=(xmin,xmax,ymin,ymax),interpolation=None,vmin=mmin,vmax=mmax,cmap=mymap)
+ #ax[ix,iy].contour(image,levels=[26],colors='r')
+
+
+ ax[ix,iy].set_xlabel(r"$x\,[\rm{kpc}]$")
+ ax[ix,iy].set_ylabel(r"$y\,[\rm{kpc}]$")
+
+
+ if i != nx*(ny-1):
+ ax[ix,iy].get_xaxis().set_visible(False)
+ ax[ix,iy].get_yaxis().set_visible(False)
+ ax[ix,iy].get_xaxis().set_ticks([])
+ ax[ix,iy].get_yaxis().set_ticks([])
+
+
+ plt.colorbar(im,label="surface brightness [mag/arcsec]",ax=ax)
+
+ basename = os.path.basename(opt.file[0])
+ opt.filter = basename.split("_")[0]
+ opt.MDM = basename.split("_")[1].split("keV")[0]
+
+ txt = r"$\rm{%s}\,\,:\,\,%s\,\rm{keV}$"%(opt.filter,opt.MDM)
+ fig.suptitle(txt,fontsize=20)
+
+
+
+
+ if opt.outputfilename:
+ plt.savefig(opt.outputfilename)
+ else:
+ plt.show()
+
+
+
+
+
+
+
diff --git a/ParticlesToSurfaceBrightness/stars_class.py b/ParticlesToSurfaceBrightness/stars_class.py
new file mode 100644
index 0000000..811eda3
--- /dev/null
+++ b/ParticlesToSurfaceBrightness/stars_class.py
@@ -0,0 +1,1449 @@
+import numpy as np
+from IMF import *
+
+
+
+def Stars_fun(mass, age, metals, imf = 'normed_3slope'):
+ """
+ This function calculates the number of stars for a given stellar mass particle, for different IMFs:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ Metallicity of the particle [M/H]
+ imf: str.
+ Initial Mass Function. Eligible: 'normed_3slope', 'Chabier_1', 'Chabier_2', 'sapeter' or 'BrokenPowerLaw'. By default: 'normed_3slope'.
+
+ """
+ init_imf=IMF(mmin=0.05, mmax=100.0, intervals=5000)
+ if imf=='Chabrier_1':
+ IMF_type=init_imf.Chabrier_1() # Chabrier_1() # Chabrier_2(), salpeter(), BrokenPowerLaw(),
+ # normed_3slope() that is Kroupa.
+ if imf=='Chabrier_2':
+ IMF_type=init_imf.Chabrier_2()
+
+ if imf=='salpeter':
+ IMF_type=init_imf.salpeter()
+
+ if imf=='normed_3slope':
+ IMF_type=init_imf.normed_3slope()
+
+
+ M1=init_imf.imf_mass_fraction(0.0,0.1)
+ M2=init_imf.imf_mass_fraction(0.1,0.2)
+ M3=init_imf.imf_mass_fraction(0.2,0.3)
+ M4=init_imf.imf_mass_fraction(0.3,0.4)
+ M5=init_imf.imf_mass_fraction(0.4,0.5)
+ M6=init_imf.imf_mass_fraction(0.5,0.6)
+ M7=init_imf.imf_mass_fraction(0.6,0.7)
+ M8=init_imf.imf_mass_fraction(0.7,0.8)
+ M9=init_imf.imf_mass_fraction(0.8,0.9)
+ M10=init_imf.imf_mass_fraction(0.9,1)
+ M11=init_imf.imf_mass_fraction(1,2)
+ M12=init_imf.imf_mass_fraction(2,3)
+ M13=init_imf.imf_mass_fraction(3,4)
+ M14=init_imf.imf_mass_fraction(4,5)
+ M15=init_imf.imf_mass_fraction(5,6)
+ M16=init_imf.imf_mass_fraction(6,7)
+ M17=init_imf.imf_mass_fraction(7,8)
+ M18=init_imf.imf_mass_fraction(8,101.)
+
+
+
+ n_1=[M1*i/0.1 for i in mass]
+ n_2=[M2*i/0.2 for i in mass]
+ n_3=[M3*i/0.3 for i in mass]
+ n_4=[M4*i/0.4 for i in mass]
+ n_5=[M5*i/0.5 for i in mass]
+ n_6=[M6*i/0.6 for i in mass]
+ n_7=[M7*i/0.7 for i in mass]
+ n_8=[M8*i/0.8 for i in mass]
+ n_9=[M9*i/0.9 for i in mass]
+ n_10=[M10*i/1 for i in mass]
+ n_11=[M11*i/2 for i in mass]
+ n_12=[M12*i/3 for i in mass]
+ n_13=[M13*i/4 for i in mass]
+ n_14=[M14*i/5 for i in mass]
+ n_15=[M15*i/6 for i in mass]
+ n_16=[M16*i/7 for i in mass]
+ n_17=[M17*i/8 for i in mass]
+ n_18=[M18*i/100 for i in mass]
+
+
+ return np.array([n_1,n_2, n_3,n_4,n_5,n_6, n_7,n_8,n_9,n_10, n_11, n_12,n_13, n_14, n_15,n_16,n_17,n_18])
+
+
+def Temp_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the temperature of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_euclid.txt',comments='#')
+ MH,logAge,Mini,Te,logL=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4]
+ # Difererentes edades de las estrellas del cmd
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+ t1=Te[k+1]
+ t2=Te[k+2]
+ t3=Te[k+3]
+ t4=Te[k+4]
+ t5=Te[k+5]
+ t6=Te[k+6]
+ t7=Te[k+7]
+ t8=Te[k+8]
+ t9=Te[k+9]
+ t10=Te[k+10]
+ t11=Te[k+11]
+ t12=Te[k+12]
+ t13=Te[k+13]
+ t14=Te[k+14]
+ t15=Te[k+15]
+ t16=Te[k+16]
+ t17=Te[k+17]
+ t18=Te[k+18]
+
+
+ return t1,t2,t3,t4,t5,t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18
+
+
+
+def Luminosity_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the intrinsic luminosity of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_euclid.txt',comments='#')
+ MH,logAge,Mini,Te,logL=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1=10**logL[k+1]
+ l2=10**logL[k+2]
+ l3=10**logL[k+3]
+ l4=10**logL[k+4]
+ l5=10**logL[k+5]
+ l6=10**logL[k+6]
+ l7=10**logL[k+7]
+ l8=10**logL[k+8]
+ l9=10**logL[k+9]
+ l10=10**logL[k+10]
+ l11=10**logL[k+11]
+ l12=10**logL[k+12]
+ l13=10**logL[k+13]
+ l14=10**logL[k+14]
+ l15=10**logL[k+15]
+ l16=10**logL[k+16]
+ l17=10**logL[k+17]
+ l18=10**logL[k+18]
+
+
+ return l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18
+
+
+#####################################
+########## HST FUNCTIONS
+#####################################
+
+
+
+
+def HST475X_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on HST-F475X from WFC3 of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_hst_wfc3.txt',comments='#')
+ MH,logAge,Mini,Te,logL, HST475Xmag=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,5]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+ # yr: the following lines gives the wrong results !!!
+ '''
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+ '''
+
+ # yr
+ get_age_idx = np.vectorize(lambda x:np.argmin( np.fabs( x*1e9 -10**age_l )))
+ get_met_idx = np.vectorize(lambda x:np.argmin( np.fabs( x -met_l )))
+
+ idx_age = get_age_idx(age)
+ idx_met = get_met_idx(metals)
+
+ k=(idx_met*(age_len+1)*(mass_len+1)+idx_age*(mass_len+1))
+ k = k-1 # really ???
+
+
+
+ l1 = HST475Xmag[k+1]
+ l2 = HST475Xmag[k+2]
+ l3 = HST475Xmag[k+3]
+ l4 = HST475Xmag[k+4]
+ l5 = HST475Xmag[k+5]
+ l6 = HST475Xmag[k+6]
+ l7 = HST475Xmag[k+7]
+ l8 = HST475Xmag[k+8]
+ l9 = HST475Xmag[k+9]
+ l10 = HST475Xmag[k+10]
+ l11 = HST475Xmag[k+11]
+ l12 = HST475Xmag[k+12]
+ l13 = HST475Xmag[k+13]
+ l14 = HST475Xmag[k+14]
+ l15 = HST475Xmag[k+15]
+ l16 = HST475Xmag[k+16]
+ l17 = HST475Xmag[k+17]
+ l18 = HST475Xmag[k+18]
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
+#####################################
+########## EUCLID FUNCTIONS
+#####################################
+
+def VISeuclid_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on Euclid-VIS of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_euclid.txt',comments='#')
+ MH,logAge,Mini,Te,logL, VISmag = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,5]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+ # yr: the following lines gives the wrong results !!!
+ '''
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+ '''
+
+ # yr
+ get_age_idx = np.vectorize(lambda x:np.argmin( np.fabs( x*1e9 -10**age_l )))
+ get_met_idx = np.vectorize(lambda x:np.argmin( np.fabs( x -met_l )))
+
+ idx_age = get_age_idx(age)
+ idx_met = get_met_idx(metals)
+
+ k=(idx_met*(age_len+1)*(mass_len+1)+idx_age*(mass_len+1))
+ k = k-1 # really ???
+
+
+
+ l1 = VISmag[k+1]
+ l2 = VISmag[k+2]
+ l3 = VISmag[k+3]
+ l4 = VISmag[k+4]
+ l5 = VISmag[k+5]
+ l6 = VISmag[k+6]
+ l7 = VISmag[k+7]
+ l8 = VISmag[k+8]
+ l9 = VISmag[k+9]
+ l10 = VISmag[k+10]
+ l11 = VISmag[k+11]
+ l12 = VISmag[k+12]
+ l13 = VISmag[k+13]
+ l14 = VISmag[k+14]
+ l15 = VISmag[k+15]
+ l16 = VISmag[k+16]
+ l17 = VISmag[k+17]
+ l18 = VISmag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
+def Yeuclid_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on Euclid-Y of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_euclid.txt',comments='#')
+ MH,logAge,Mini,Te,logL, Ymag = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,7]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+ # yr: the following lines gives the wrong results !!!
+ '''
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+ '''
+
+ # yr
+ get_age_idx = np.vectorize(lambda x:np.argmin( np.fabs( x*1e9 -10**age_l )))
+ get_met_idx = np.vectorize(lambda x:np.argmin( np.fabs( x -met_l )))
+
+ idx_age = get_age_idx(age)
+ idx_met = get_met_idx(metals)
+
+ k=(idx_met*(age_len+1)*(mass_len+1)+idx_age*(mass_len+1))
+ k = k-1 # really ???
+
+
+ l1 = Ymag[k+1]
+ l2 = Ymag[k+2]
+ l3 = Ymag[k+3]
+ l4 = Ymag[k+4]
+ l5 = Ymag[k+5]
+ l6 = Ymag[k+6]
+ l7 = Ymag[k+7]
+ l8 = Ymag[k+8]
+ l9 = Ymag[k+9]
+ l10 = Ymag[k+10]
+ l11 = Ymag[k+11]
+ l12 = Ymag[k+12]
+ l13 = Ymag[k+13]
+ l14 = Ymag[k+14]
+ l15 = Ymag[k+15]
+ l16 = Ymag[k+16]
+ l17 = Ymag[k+17]
+ l18 = Ymag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+def Jeuclid_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on Euclid-J of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_euclid.txt',comments='#')
+ MH,logAge,Mini,Te,logL, Jmag = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,6]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+ # yr: the following lines gives the wrong results !!!
+ '''
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+ '''
+
+ # yr
+ get_age_idx = np.vectorize(lambda x:np.argmin( np.fabs( x*1e9 -10**age_l )))
+ get_met_idx = np.vectorize(lambda x:np.argmin( np.fabs( x -met_l )))
+
+ idx_age = get_age_idx(age)
+ idx_met = get_met_idx(metals)
+
+ k=(idx_met*(age_len+1)*(mass_len+1)+idx_age*(mass_len+1))
+ k = k-1 # really ???
+
+
+ l1 = Jmag[k+1]
+ l2 = Jmag[k+2]
+ l3 = Jmag[k+3]
+ l4 = Jmag[k+4]
+ l5 = Jmag[k+5]
+ l6 = Jmag[k+6]
+ l7 = Jmag[k+7]
+ l8 = Jmag[k+8]
+ l9 = Jmag[k+9]
+ l10 = Jmag[k+10]
+ l11 = Jmag[k+11]
+ l12 = Jmag[k+12]
+ l13 = Jmag[k+13]
+ l14 = Jmag[k+14]
+ l15 = Jmag[k+15]
+ l16 = Jmag[k+16]
+ l17 = Jmag[k+17]
+ l18 = Jmag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
+
+
+
+#####################################
+########## SLOAN FUNCTIONS
+#####################################
+
+
+def rsloan_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on sloan r of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_sloan.txt',comments='#')
+ MH,logAge,Mini,Te,logL, rmag=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,5]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1 = rmag[k+1]
+ l2 = rmag[k+2]
+ l3 = rmag[k+3]
+ l4 = rmag[k+4]
+ l5 = rmag[k+5]
+ l6 = rmag[k+6]
+ l7 = rmag[k+7]
+ l8 = rmag[k+8]
+ l9 = rmag[k+9]
+ l10 = rmag[k+10]
+ l11 = rmag[k+11]
+ l12 = rmag[k+12]
+ l13 = rmag[k+13]
+ l14 = rmag[k+14]
+ l15 = rmag[k+15]
+ l16 = rmag[k+16]
+ l17 = rmag[k+17]
+ l18 = rmag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+def gsloan_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on sloan g of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_sloan.txt',comments='#')
+ MH,logAge,Mini,Te,logL, gmag=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,6]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1 = gmag[k+1]
+ l2 = gmag[k+2]
+ l3 = gmag[k+3]
+ l4 = gmag[k+4]
+ l5 = gmag[k+5]
+ l6 = gmag[k+6]
+ l7 = gmag[k+7]
+ l8 = gmag[k+8]
+ l9 = gmag[k+9]
+ l10 = gmag[k+10]
+ l11 = gmag[k+11]
+ l12 = gmag[k+12]
+ l13 = gmag[k+13]
+ l14 = gmag[k+14]
+ l15 = gmag[k+15]
+ l16 = gmag[k+16]
+ l17 = gmag[k+17]
+ l18 = gmag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+def isloan_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on sloan g of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_sloan.txt',comments='#')
+ MH,logAge,Mini,Te,logL, imag=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,7]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1 = imag[k+1]
+ l2 = imag[k+2]
+ l3 = imag[k+3]
+ l4 = imag[k+4]
+ l5 = imag[k+5]
+ l6 = imag[k+6]
+ l7 = imag[k+7]
+ l8 = imag[k+8]
+ l9 = imag[k+9]
+ l10 = imag[k+10]
+ l11 = imag[k+11]
+ l12 = imag[k+12]
+ l13 = imag[k+13]
+ l14 = imag[k+14]
+ l15 = imag[k+15]
+ l16 = imag[k+16]
+ l17 = imag[k+17]
+ l18 = imag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+#####################################
+########## GALEX FUNCTIONS
+#####################################
+
+def NUVmags_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on GALEX NUV of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_galex.txt',comments='#')
+ MH,logAge,Mini,Te,logL, NUVmag = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,7]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+ l1 = NUVmag[k+1]
+ l2 = NUVmag[k+2]
+ l3 = NUVmag[k+3]
+ l4 = NUVmag[k+4]
+ l5 = NUVmag[k+5]
+ l6 = NUVmag[k+6]
+ l7 = NUVmag[k+7]
+ l8 = NUVmag[k+8]
+ l9 = NUVmag[k+9]
+ l10 = NUVmag[k+10]
+ l11 = NUVmag[k+11]
+ l12 = NUVmag[k+12]
+ l13 = NUVmag[k+13]
+ l14 = NUVmag[k+14]
+ l15 = NUVmag[k+15]
+ l16 = NUVmag[k+16]
+ l17 = NUVmag[k+17]
+ l18 = NUVmag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
+def FUVmags_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on GALEX FUV of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_galex.txt',comments='#')
+ MH,logAge,Mini,Te,logL, FUVmag=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,6]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+ l1 = FUVmag[k+1]
+ l2 = FUVmag[k+2]
+ l3 = FUVmag[k+3]
+ l4 = FUVmag[k+4]
+ l5 = FUVmag[k+5]
+ l6 = FUVmag[k+6]
+ l7 = FUVmag[k+7]
+ l8 = FUVmag[k+8]
+ l9 = FUVmag[k+9]
+ l10 = FUVmag[k+10]
+ l11 = FUVmag[k+11]
+ l12 = FUVmag[k+12]
+ l13 = FUVmag[k+13]
+ l14 = FUVmag[k+14]
+ l15 = FUVmag[k+15]
+ l16 = FUVmag[k+16]
+ l17 = FUVmag[k+17]
+ l18 = FUVmag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
+#####################################
+########## LSST FUNCTIONS
+#####################################
+
+def ulsst_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on LSST-U of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_lsst.txt',comments='#')
+ MH,logAge,Mini,Te,logL, umag=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,5]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+ l1 = umag[k+1]
+ l2 = umag[k+2]
+ l3 = umag[k+3]
+ l4 = umag[k+4]
+ l5 = umag[k+5]
+ l6 = umag[k+6]
+ l7 = umag[k+7]
+ l8 = umag[k+8]
+ l9 = umag[k+9]
+ l10 = umag[k+10]
+ l11 = umag[k+11]
+ l12 = umag[k+12]
+ l13 = umag[k+13]
+ l14 = umag[k+14]
+ l15 = umag[k+15]
+ l16 = umag[k+16]
+ l17 = umag[k+17]
+ l18 = umag[k+18]
+
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+def glsst_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on LSST-G of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_lsst.txt',comments='#')
+ MH,logAge,Mini,Te,logL, gmag=Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,6]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+ l1 = gmag[k+1]
+ l2 = gmag[k+2]
+ l3 = gmag[k+3]
+ l4 = gmag[k+4]
+ l5 = gmag[k+5]
+ l6 = gmag[k+6]
+ l7 = gmag[k+7]
+ l8 = gmag[k+8]
+ l9 = gmag[k+9]
+ l10 = gmag[k+10]
+ l11 = gmag[k+11]
+ l12 = gmag[k+12]
+ l13 = gmag[k+13]
+ l14 = gmag[k+14]
+ l15 = gmag[k+15]
+ l16 = gmag[k+16]
+ l17 = gmag[k+17]
+ l18 = gmag[k+18]
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
+
+
+
+#####################################
+########## DECAM FUNCTIONS
+#####################################
+
+
+
+
+def g_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on DECAM-g of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_decam.txt',comments='#')
+ MH,logAge,Mini,Te,logL, gmag = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,5]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1 = gmag[k+1]
+ l2 = gmag[k+2]
+ l3 = gmag[k+3]
+ l4 = gmag[k+4]
+ l5 = gmag[k+5]
+ l6 = gmag[k+6]
+ l7 = gmag[k+7]
+ l8 = gmag[k+8]
+ l9 = gmag[k+9]
+ l10 = gmag[k+10]
+ l11 = gmag[k+11]
+ l12 = gmag[k+12]
+ l13 = gmag[k+13]
+ l14 = gmag[k+14]
+ l15 = gmag[k+15]
+ l16 = gmag[k+16]
+ l17 = gmag[k+17]
+ l18 = gmag[k+18]
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+def r_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on DECAM-r of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_decam.txt',comments='#')
+ MH,logAge,Mini,Te,logL, rmags = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,7]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1 = rmags[k+1]
+ l2 = rmags[k+2]
+ l3 = rmags[k+3]
+ l4 = rmags[k+4]
+ l5 = rmags[k+5]
+ l6 = rmags[k+6]
+ l7 = rmags[k+7]
+ l8 = rmags[k+8]
+ l9 = rmags[k+9]
+ l10 = rmags[k+10]
+ l11 = rmags[k+11]
+ l12 = rmags[k+12]
+ l13 = rmags[k+13]
+ l14 = rmags[k+14]
+ l15 = rmags[k+15]
+ l16 = rmags[k+16]
+ l17 = rmags[k+17]
+ l18 = rmags[k+18]
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
+def z_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on DECAM-z of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_decam.txt',comments='#')
+ MH,logAge,Mini,Te,logL, zmag = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,6]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1 = zmag[k+1]
+ l2 = zmag[k+2]
+ l3 = zmag[k+3]
+ l4 = zmag[k+4]
+ l5 = zmag[k+5]
+ l6 = zmag[k+6]
+ l7 = zmag[k+7]
+ l8 = zmag[k+8]
+ l9 = zmag[k+9]
+ l10 = zmag[k+10]
+ l11 = zmag[k+11]
+ l12 = zmag[k+12]
+ l13 = zmag[k+13]
+ l14 = zmag[k+14]
+ l15 = zmag[k+15]
+ l16 = zmag[k+16]
+ l17 = zmag[k+17]
+ l18 = zmag[k+18]
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+def i_fun(mass, age, metals):
+ '''''''''''''''
+ This function calculates the magnitude on DECAM-i of stars from the synthetic CMD:
+ Parameters
+ -------
+ mass: numpy array.
+ Mass of the particle.
+ age: numpy array.
+ Age of the particle
+ metals: numpy array.
+ '''''''''''''''
+ Isoc=np.genfromtxt('./Isochrones/new_CMDs/Isoc_new_decam.txt',comments='#')
+ MH,logAge,Mini,Te,logL, imag = Isoc[:,0],Isoc[:,1],Isoc[:,2],Isoc[:,3],Isoc[:,4], Isoc[:,8]
+ # Difererentes edades de las estrellas del cmd
+
+ logAge_iter=[0]
+ logAge_iter[0]=logAge[0]
+ j=0
+ for i in range(0,len(logAge)-1):
+ if (logAge_iter[j] != logAge[i]) & (logAge_iter[j] <= logAge[i]):
+ j=j+1
+ logAge_iter.append(logAge[i])
+
+ # Difererentes metalicidades de las estrellas del cmd
+ MH_iter=[0]
+ MH_iter[0]=MH[0]
+ j=0
+ for i in range(0,len(MH)-1):
+ if MH_iter[j] != MH[i]:
+ j=j+1
+ MH_iter.append(MH[i])
+
+ met_l = np.unique(MH)
+ age_l = np.unique(logAge)
+ Mass_l = np.unique(Mini)
+ met_len=len(met_l)-1
+ age_len=len(age_l)-1
+ mass_len=len(Mass_l)-1
+
+
+ m=((age_len)*((age*1e9-10**np.min(age_l))/(10**np.max(age_l)-10**np.min(age_l)))).round(0).astype(int)
+ m[m<0]=0
+ m[m>=age_len]=age_len
+
+
+ j=((met_len)*(metals-np.min(met_l))/(np.max(met_l)-np.min(met_l))).astype(int)
+
+ j[j<0]=0
+ j[j>=met_len]=met_len
+
+ k=(j*(age_len+1)*(mass_len+1)+m*(mass_len+1))
+
+
+ l1 = imag[k+1]
+ l2 = imag[k+2]
+ l3 = imag[k+3]
+ l4 = imag[k+4]
+ l5 = imag[k+5]
+ l6 = imag[k+6]
+ l7 = imag[k+7]
+ l8 = imag[k+8]
+ l9 = imag[k+9]
+ l10 = imag[k+10]
+ l11 = imag[k+11]
+ l12 = imag[k+12]
+ l13 = imag[k+13]
+ l14 = imag[k+14]
+ l15 = imag[k+15]
+ l16 = imag[k+16]
+ l17 = imag[k+17]
+ l18 = imag[k+18]
+
+ return np.array([l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12, l13,l14,l15,l16,l17,l18])
+
+
+
Event Timeline
Log In to Comment