コード例 #1
0
    def __init__(self, magZ=23, magEZ=22, varEZ=0, cachedir=None, **specs):

        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        specs['cachedir'] = self.cachedir

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        self.magZ = float(magZ)  # 1 zodi brightness (per arcsec2)
        self.magEZ = float(magEZ)  # 1 exo-zodi brightness (per arcsec2)
        self.varEZ = float(
            varEZ)  # exo-zodi variation (variance of log-normal dist)
        self.fZ0 = 10**(-0.4 *
                        self.magZ) / u.arcsec**2  # default zodi brightness
        self.fEZ0 = 10**(
            -0.4 * self.magEZ) / u.arcsec**2  # default exo-zodi brightness

        assert self.varEZ >= 0, "Exozodi variation must be >= 0"

        # populate outspec
        for att in self.__dict__:
            if att not in ['vprint', '_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(
                    dat, u.Quantity) else dat
コード例 #2
0
    def __init__(self, cachedir=None, whichPlanetPhaseFunction='lambert', **specs):
        
        #start the outspec
        self._outspec = {}

        # cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        specs['cachedir'] = self.cachedir

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        #Select which Phase Function to use
        assert isinstance(whichPlanetPhaseFunction, str), "whichPlanetPhaseFunction is not a string"
        self.whichPlanetPhaseFunction = whichPlanetPhaseFunction
        if whichPlanetPhaseFunction == 'quasiLambertPhaseFunction':
            from EXOSIMS.util.phaseFunctions import quasiLambertPhaseFunction
            self.calc_Phi = quasiLambertPhaseFunction
        elif whichPlanetPhaseFunction == 'hyperbolicTangentPhaseFunc':
            from EXOSIMS.util.phaseFunctions import hyperbolicTangentPhaseFunc
            self.calc_Phi = hyperbolicTangentPhaseFunc
        #else: if whichPlanetPhaseFunction == 'lambert': Default, Do nothing
        self._outspec['whichPlanetPhaseFunction'] = whichPlanetPhaseFunction

        #Define Phase Function Inverse
        betas = np.linspace(start=0.,stop=np.pi,num=1000,endpoint=True)*u.rad
        Phis = self.calc_Phi(betas)
        self.betaFunction = PchipInterpolator(-Phis,betas) #the -Phis ensure the function monotonically increases
コード例 #3
0
ファイル: Completeness.py プロジェクト: semaphoreP/EXOSIMS
    def __init__(self, dMagLim=25, minComp=0.1, cachedir=None, **specs):
        
        #start the outspec
        self._outspec = {}
        
        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
       
        #if specs contains a completeness_spec then we are going to generate separate instances
        #of planet population and planet physical model for completeness and for the rest of the sim
        if 'completeness_specs' in specs:
            if not specs['completeness_specs'].has_key('modules'):
                specs['completeness_specs']['modules'] = {}
            if not specs['completeness_specs']['modules'].has_key('PlanetPhysicalModel'):
                specs['completeness_specs']['modules']['PlanetPhysicalModel'] = specs['modules']['PlanetPhysicalModel']
            if not specs['completeness_specs']['modules'].has_key('PlanetPopulation'):
                specs['completeness_specs']['modules']['PlanetPopulation'] = specs['modules']['PlanetPopulation']
            self.PlanetPopulation = get_module(specs['completeness_specs']['modules']['PlanetPopulation'],'PlanetPopulation')(**specs['completeness_specs'])
        else:
            self.PlanetPopulation = get_module(specs['modules']['PlanetPopulation'],'PlanetPopulation')(**specs)

        # copy phyiscal model object up to attribute
        self.PlanetPhysicalModel = self.PlanetPopulation.PlanetPhysicalModel
        
        # loading attributes
        self.dMagLim = float(dMagLim)
        self.minComp = float(minComp)
        # find the cache directory
        self.cachedir = get_cache_dir(cachedir)
        
        # populate outspec
        self._outspec['dMagLim'] = self.dMagLim
        self._outspec['minComp'] = self.minComp
        self._outspec['cachedir'] = self.cachedir
コード例 #4
0
    def __init__(self, fixedPlanPerStar=None, Min=None, cachedir=None, **specs):
        
        #start the outspec
        self._outspec = {}

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        # save fixed number of planets to generate
        self.fixedPlanPerStar = fixedPlanPerStar
        self._outspec['fixedPlanPerStar'] = fixedPlanPerStar

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        
        # check if KnownRVPlanetsUniverse has correct input modules
        if specs['modules']['SimulatedUniverse'] == 'KnownRVPlanetsUniverse':
            val = specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList' \
            and specs['modules']['PlanetPopulation'] == 'KnownRVPlanets'
            assert val == True, 'KnownRVPlanetsUniverse must use KnownRVPlanetsTargetList and KnownRVPlanets'
        else:
            val = specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList' \
            or specs['modules']['PlanetPopulation'] == 'KnownRVPlanets'
            assert val == False, 'KnownRVPlanetsTargetList or KnownRVPlanets should not be used with this SimulatedUniverse'
            
        # import TargetList class
        self.TargetList = get_module(specs['modules']['TargetList'],
                'TargetList')(**specs)
        
        # bring inherited class objects to top level of Simulated Universe
        TL = self.TargetList
        self.StarCatalog = TL.StarCatalog
        self.PlanetPopulation = TL.PlanetPopulation
        self.PlanetPhysicalModel = TL.PlanetPhysicalModel
        self.OpticalSystem = TL.OpticalSystem
        self.ZodiacalLight = TL.ZodiacalLight
        self.BackgroundSources = TL.BackgroundSources
        self.PostProcessing = TL.PostProcessing
        self.Completeness = TL.Completeness
        
        # initial constant mean anomaly
        assert type(Min) is int or type(Min) is float or Min is None, 'Min may be int, float, or None'
        if Min is not None:
            self.Min = float(Min)*u.deg
        else:
            self.Min = Min
        
        # list of possible planet attributes
        self.planet_atts = ['plan2star', 'a', 'e', 'I', 'O', 'w', 'M0', 'Min', 'Rp', 'Mp', 'p',
                'r', 'v', 'd', 's', 'phi', 'fEZ', 'dMag', 'WA']
        
        # generate orbital elements, albedos, radii, and masses
        self.gen_physical_properties(**specs)
        
        # find initial position-related parameters: position, velocity, planet-star 
        # distance, apparent separation, surface brightness of exo-zodiacal light
        self.init_systems()
コード例 #5
0
ファイル: SurveyEnsemble.py プロジェクト: dsavransky/EXOSIMS
    def __init__(self, cachedir=None, **specs):

        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        
        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
コード例 #6
0
    def __init__(self, cachedir=None, **specs):
        self._outspec = {}

        # cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        return
コード例 #7
0
ファイル: TimeKeeping.py プロジェクト: dsavransky/EXOSIMS
    def __init__(self, missionStart=60634, missionLife=0.1, 
        missionPortion=1, OBduration=np.inf, missionSchedule=None,
        cachedir=None, **specs):

        _outspec = {}
   
        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        # illegal value checks
        assert missionLife >= 0, "Need missionLife >= 0, got %f"%missionLife
        # arithmetic on missionPortion fails if it is outside the legal range
        assert missionPortion > 0 and missionPortion <= 1, \
                "Require missionPortion in the interval [0,1], got %f"%missionPortion
        # OBduration must be positive nonzero
        assert OBduration*u.d > 0*u.d, "Required OBduration positive nonzero, got %f"%OBduration
        
        # set up state variables
        # tai scale specified because the default, utc, requires accounting for leap
        # seconds, causing warnings from astropy.time when time-deltas are added
        self.missionStart = Time(float(missionStart), format='mjd', scale='tai')#the absolute date of mission start must have scale tai
        self.missionPortion = float(missionPortion)#the portion of missionFinishNorm the instrument can observe for
        
        # set values derived from quantities above
        self.missionLife = float(missionLife)*u.year#the total amount of time since mission start that can elapse MUST BE IN YEAR HERE FOR OUTSPEC
        self.missionFinishAbs = self.missionStart + self.missionLife.to('day')#the absolute time the mission can possibly end
        
        # initialize values updated by functions
        self.currentTimeNorm = 0.*u.day#the current amount of time since mission start that has elapsed
        self.currentTimeAbs = self.missionStart#the absolute mission time
        
        # initialize observing block times arrays. #An Observing Block is a segment of time over which observations may take place
        self.init_OB(str(missionSchedule), OBduration*u.d)
        
        # initialize time spend using instrument
        self.exoplanetObsTime = 0*u.day
        
        # populate outspec
        for att in self.__dict__:
            if att not in ['vprint','_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(dat,(u.Quantity,Time)) else dat
コード例 #8
0
    def __init__(self, missionStart=60634, missionLife=0.1, 
        missionPortion=1, OBduration=np.inf, missionSchedule=None,
        cachedir=None, **specs):

        _outspec = {}
   
        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        # illegal value checks
        assert missionLife >= 0, "Need missionLife >= 0, got %f"%missionLife
        # arithmetic on missionPortion fails if it is outside the legal range
        assert missionPortion > 0 and missionPortion <= 1, \
                "Require missionPortion in the interval [0,1], got %f"%missionPortion
        # OBduration must be positive nonzero
        assert OBduration*u.d > 0*u.d, "Required OBduration positive nonzero, got %f"%OBduration
        
        # set up state variables
        # tai scale specified because the default, utc, requires accounting for leap
        # seconds, causing warnings from astropy.time when time-deltas are added
        self.missionStart = Time(float(missionStart), format='mjd', scale='tai')#the absolute date of mission start must have scale tai
        self.missionPortion = float(missionPortion)#the portion of missionFinishNorm the instrument can observe for
        
        # set values derived from quantities above
        self.missionLife = float(missionLife)*u.year#the total amount of time since mission start that can elapse MUST BE IN YEAR HERE FOR OUTSPEC
        self.missionFinishAbs = self.missionStart + self.missionLife.to('day')#the absolute time the mission can possibly end
        
        # initialize values updated by functions
        self.currentTimeNorm = 0.*u.day#the current amount of time since mission start that has elapsed
        self.currentTimeAbs = self.missionStart#the absolute mission time
        
        # initialize observing block times arrays. #An Observing Block is a segment of time over which observations may take place
        self.init_OB(str(missionSchedule), OBduration*u.d)
        
        # initialize time spend using instrument
        self.exoplanetObsTime = 0*u.day
        
        # populate outspec
        for att in self.__dict__.keys():
            if att not in ['vprint','_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(dat,(u.Quantity,Time)) else dat
コード例 #9
0
ファイル: StarCatalog.py プロジェクト: walker-dula/EXOSIMS
    def __init__(self, ntargs=1, cachedir=None, **specs):

        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        specs['cachedir'] = self.cachedir

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        # ntargs must be an integer >= 1
        self.ntargs = max(int(ntargs), 1)

        # list of astropy attributes
        self.dist = np.ones(ntargs) * u.pc  # distance
        self.parx = self.dist.to('mas', equivalencies=u.parallax())  # parallax
        self.coords = SkyCoord(ra=np.zeros(ntargs) * u.deg,
                               dec=np.zeros(ntargs) * u.deg,
                               distance=self.dist)  # ICRS coordinates
        self.pmra = np.zeros(ntargs) * u.mas / u.yr  # proper motion in RA
        self.pmdec = np.zeros(ntargs) * u.mas / u.yr  # proper motion in DEC
        self.rv = np.zeros(ntargs) * u.km / u.s  # radial velocity

        # list of non-astropy attributes
        self.Name = np.array(['Prototype'] * ntargs)  # star names
        self.Spec = np.array(['G'] * ntargs)  # spectral types
        self.Umag = np.zeros(ntargs)  # U magnitude
        self.Bmag = np.zeros(ntargs)  # B magnitude
        self.Vmag = np.zeros(ntargs)  # V magnitude
        self.Rmag = np.zeros(ntargs)  # R magnitude
        self.Imag = np.zeros(ntargs)  # I magnitude
        self.Jmag = np.zeros(ntargs)  # J magnitude
        self.Hmag = np.zeros(ntargs)  # H magnitude
        self.Kmag = np.zeros(ntargs)  # K magnitude
        self.BV = np.zeros(ntargs)  # B-V Johnson magnitude
        self.MV = np.zeros(ntargs)  # absolute V magnitude
        self.BC = np.zeros(ntargs)  # bolometric correction
        self.L = np.ones(ntargs)  # stellar luminosity in ln(SolLum)
        self.Binary_Cut = np.zeros(ntargs,
                                   dtype=bool)  # binary closer than 10 arcsec

        # populate outspecs
        self._outspec['ntargs'] = self.ntargs
コード例 #10
0
    def __init__(self, cachedir=None, **specs):
        
        #start the outspec
        self._outspec = {}

        # cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        specs['cachedir'] = self.cachedir

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        #Define Phase Function Inverse
        betas = np.linspace(start=0.,stop=np.pi,num=1000,endpoint=True)*u.rad
        Phis = self.calc_Phi(betas)
        self.betaFunction = PchipInterpolator(-Phis,betas) #the -Phis ensure the function monotonically increases

        return
コード例 #11
0
 def __init__(self, cachedir=None, **specs):
     self.cachedir = get_cache_dir(cachedir)
     classpath = os.path.split(inspect.getfile(self.__class__))[0]
     filename = 'SIMBAD300'
     pklpath = os.path.join(self.cachedir, filename + '.pkl')
     matpath = os.path.join(classpath, filename + '.mat')
     
     # check if given filename exists as .pkl file already
     if os.path.exists(pklpath):
         self.populatepkl(pklpath, **specs)
         self.vprint('Loaded %s.pkl star catalog'%filename)
     # check if given filename exists as a .mat file but not .pkl file
     elif os.path.exists(matpath):
         self.SIMBAD_mat2pkl(matpath, pklpath)
         self.populatepkl(pklpath, **specs)
         self.vprint('Loaded %s.mat star catalog'%filename)
     # otherwise print error
     else:
         self.vprint('Could not load SIMBAD300 star catalog')
コード例 #12
0
    def __init__(self, cachedir=None, **specs):
        self.cachedir = get_cache_dir(cachedir)
        classpath = os.path.split(inspect.getfile(self.__class__))[0]
        filename = 'SIMBAD300'
        pklpath = os.path.join(self.cachedir, filename + '.pkl')
        matpath = os.path.join(classpath, filename + '.mat')

        # check if given filename exists as .pkl file already
        if os.path.exists(pklpath):
            self.populatepkl(pklpath, **specs)
            print('Loaded %s.pkl star catalog' % filename)
        # check if given filename exists as a .mat file but not .pkl file
        elif os.path.exists(matpath):
            self.SIMBAD_mat2pkl(matpath, pklpath)
            self.populatepkl(pklpath, **specs)
            print('Loaded %s.mat star catalog' % filename)
        # otherwise print error
        else:
            print('Could not load SIMBAD300 star catalog')
コード例 #13
0
ファイル: Completeness.py プロジェクト: dsavransky/EXOSIMS
    def __init__(self, dMagLim=25, minComp=0.1, cachedir=None, **specs):
        
        #start the outspec
        self._outspec = {}
        
        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
       
        #if specs contains a completeness_spec then we are going to generate separate instances
        #of planet population and planet physical model for completeness and for the rest of the sim
        if 'completeness_specs' in specs:
            if specs['completeness_specs'] == None:
                specs['completeness_specs'] = {}
                specs['completeness_specs']['modules'] = {}
            if not 'modules' in specs['completeness_specs']:
                specs['completeness_specs']['modules'] = {}
            if not 'PlanetPhysicalModel' in specs['completeness_specs']['modules']:
                specs['completeness_specs']['modules']['PlanetPhysicalModel'] = specs['modules']['PlanetPhysicalModel']
            if not 'PlanetPopulation' in specs['completeness_specs']['modules']:
                specs['completeness_specs']['modules']['PlanetPopulation'] = specs['modules']['PlanetPopulation']
            self.PlanetPopulation = get_module(specs['completeness_specs']['modules']['PlanetPopulation'],'PlanetPopulation')(**specs['completeness_specs'])
        else:
            self.PlanetPopulation = get_module(specs['modules']['PlanetPopulation'],'PlanetPopulation')(**specs)

        # copy phyiscal model object up to attribute
        self.PlanetPhysicalModel = self.PlanetPopulation.PlanetPhysicalModel
        
        # loading attributes
        self.dMagLim = float(dMagLim)
        self.minComp = float(minComp)
        # find the cache directory
        self.cachedir = get_cache_dir(cachedir)
        
        # populate outspec
        self._outspec['dMagLim'] = self.dMagLim
        self._outspec['minComp'] = self.minComp
        self._outspec['completeness_specs'] = specs.get('completeness_specs')
        self._outspec['cachedir'] = self.cachedir
コード例 #14
0
ファイル: ZodiacalLight.py プロジェクト: dsavransky/EXOSIMS
    def __init__(self, magZ=23, magEZ=22, varEZ=0, cachedir=None, **specs):

        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        
        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        self.magZ = float(magZ)         # 1 zodi brightness (per arcsec2)
        self.magEZ = float(magEZ)       # 1 exo-zodi brightness (per arcsec2)
        self.varEZ = float(varEZ)       # exo-zodi variation (variance of log-normal dist)
        self.fZ0 = 10**(-0.4*self.magZ)/u.arcsec**2   # default zodi brightness
        self.fEZ0 = 10**(-0.4*self.magEZ)/u.arcsec**2 # default exo-zodi brightness
        
        assert self.varEZ >= 0, "Exozodi variation must be >= 0"
        
        # populate outspec
        for att in self.__dict__:
            if att not in ['vprint','_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(dat, u.Quantity) else dat
コード例 #15
0
    def __init__(self,
                 arange=[0.1, 100.],
                 erange=[0.01, 0.99],
                 Irange=[0., 180.],
                 Orange=[0., 360.],
                 wrange=[0., 360.],
                 prange=[0.1, 0.6],
                 Rprange=[1., 30.],
                 Mprange=[1., 4131.],
                 scaleOrbits=False,
                 constrainOrbits=False,
                 eta=0.1,
                 cachedir=None,
                 **specs):

        #start the outspec
        self._outspec = {}

        # get the cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        specs['cachedir'] = self.cachedir

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        # check range of parameters
        self.arange = self.checkranges(arange, 'arange') * u.AU
        self.erange = self.checkranges(erange, 'erange')
        self.Irange = self.checkranges(Irange, 'Irange') * u.deg
        self.Orange = self.checkranges(Orange, 'Orange') * u.deg
        self.wrange = self.checkranges(wrange, 'wrange') * u.deg
        self.prange = self.checkranges(prange, 'prange')
        self.Rprange = self.checkranges(Rprange, 'Rprange') * u.earthRad
        self.Mprange = self.checkranges(Mprange, 'Mprange') * u.earthMass

        assert isinstance(scaleOrbits, bool), "scaleOrbits must be boolean"
        # scale planetary orbits by sqrt(L)
        self.scaleOrbits = scaleOrbits

        assert isinstance(constrainOrbits,
                          bool), "constrainOrbits must be boolean"
        # constrain planetary orbital radii to sma range
        self.constrainOrbits = constrainOrbits
        # derive orbital radius range from quantities above
        ar = self.arange.to('AU').value
        er = self.erange
        if self.constrainOrbits:
            self.rrange = [ar[0], ar[1]] * u.AU
        else:
            self.rrange = [ar[0] * (1. - er[1]), ar[1] * (1. + er[1])] * u.AU
        assert isinstance(eta, numbers.Number) and (eta > 0),\
                "eta must be strictly positive"
        # global occurrence rate defined as expected number of planets per
        # star in a given universe
        self.eta = eta

        # albedo is constant for planetary radius range
        self.pfromRp = False

        # populate all attributes to outspec
        for att in self.__dict__:
            if att not in ['vprint', '_outspec']:
                dat = copy.copy(self.__dict__[att])
                self._outspec[att] = dat.value if isinstance(
                    dat, u.Quantity) else dat

        # define prototype distributions of parameters (uniform and log-uniform)
        self.uniform = lambda x, v: np.array(
            (np.array(x) >= v[0]) & (np.array(x) <= v[1]),
            dtype=float,
            ndmin=1) / (v[1] - v[0])
        self.logunif = lambda x, v: np.array(
            (np.array(x) >= v[0]) & (np.array(x) <= v[1]),
            dtype=float,
            ndmin=1) / (x * np.log(v[1] / v[0]))

        # import PlanetPhysicalModel
        self.PlanetPhysicalModel = get_module(
            specs['modules']['PlanetPhysicalModel'],
            'PlanetPhysicalModel')(**specs)
コード例 #16
0
    def __init__(self,
                 fixedPlanPerStar=None,
                 Min=None,
                 cachedir=None,
                 lucky_planets=False,
                 commonSystemInclinations=None,
                 **specs):

        #start the outspec
        self._outspec = {}

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        self.lucky_planets = lucky_planets
        self._outspec['lucky_planets'] = lucky_planets
        self.commonSystemInclinations = commonSystemInclinations
        self._outspec['commonSystemInclinations'] = commonSystemInclinations

        # save fixed number of planets to generate
        self.fixedPlanPerStar = fixedPlanPerStar
        self._outspec['fixedPlanPerStar'] = fixedPlanPerStar

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        specs['cachedir'] = self.cachedir

        # check if KnownRVPlanetsUniverse has correct input modules
        if specs['modules']['SimulatedUniverse'] == 'KnownRVPlanetsUniverse':
            val = specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList' \
            and specs['modules']['PlanetPopulation'] == 'KnownRVPlanets'
            assert val == True, 'KnownRVPlanetsUniverse must use KnownRVPlanetsTargetList and KnownRVPlanets'
        else:
            val = specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList' \
            or specs['modules']['PlanetPopulation'] == 'KnownRVPlanets'
            assert val == False, 'KnownRVPlanetsTargetList or KnownRVPlanets should not be used with this SimulatedUniverse'

        # import TargetList class
        self.TargetList = get_module(specs['modules']['TargetList'],
                                     'TargetList')(**specs)

        # bring inherited class objects to top level of Simulated Universe
        TL = self.TargetList
        self.StarCatalog = TL.StarCatalog
        self.PlanetPopulation = TL.PlanetPopulation
        self.PlanetPhysicalModel = TL.PlanetPhysicalModel
        self.OpticalSystem = TL.OpticalSystem
        self.ZodiacalLight = TL.ZodiacalLight
        self.BackgroundSources = TL.BackgroundSources
        self.PostProcessing = TL.PostProcessing
        self.Completeness = TL.Completeness

        # initial constant mean anomaly
        assert type(Min) is int or type(
            Min) is float or Min is None, 'Min may be int, float, or None'
        if Min is not None:
            self.Min = float(Min) * u.deg
        else:
            self.Min = Min

        # list of possible planet attributes
        self.planet_atts = [
            'plan2star', 'a', 'e', 'I', 'O', 'w', 'M0', 'Min', 'Rp', 'Mp', 'p',
            'r', 'v', 'd', 's', 'phi', 'fEZ', 'dMag', 'WA'
        ]

        # generate orbital elements, albedos, radii, and masses
        self.gen_physical_properties(**specs)

        # find initial position-related parameters: position, velocity, planet-star
        # distance, apparent separation, surface brightness of exo-zodiacal light
        self.init_systems()
コード例 #17
0
ファイル: PostProcessing.py プロジェクト: semaphoreP/EXOSIMS
    def __init__(self,
                 FAP=3e-7,
                 MDP=1e-3,
                 ppFact=1.0,
                 FAdMag0=15,
                 cachedir=None,
                 **specs):

        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        self.FAP = float(FAP)  # false alarm probability
        self.MDP = float(MDP)  # missed detection probability

        # check for post-processing factor, function of the working angle
        if isinstance(ppFact, str):
            pth = os.path.normpath(os.path.expandvars(ppFact))
            assert os.path.isfile(pth), "%s is not a valid file." % pth
            dat = fits.open(pth)[0].data
            assert len(dat.shape) == 2 and 2 in dat.shape, \
                    "Wrong post-processing gain data shape."
            WA, G = (dat[0], dat[1]) if dat.shape[0] == 2 else (dat[:,
                                                                    0], dat[:,
                                                                            1])
            assert np.all(G > 0) and np.all(G <= 1), \
                    "Post-processing gain must be positive and smaller than 1."
            # gain outside of WA values defaults to 1
            Ginterp = scipy.interpolate.interp1d(WA,
                                                 G,
                                                 kind='cubic',
                                                 fill_value=1.,
                                                 bounds_error=False)
            self.ppFact = lambda s: np.array(Ginterp(s.to('arcsec').value),
                                             ndmin=1)
        elif isinstance(ppFact, numbers.Number):
            assert ppFact > 0 and ppFact <= 1, \
                    "Post-processing gain must be positive and smaller than 1."
            self.ppFact = lambda s, G=float(ppFact): G

        # check for minimum FA delta magnitude, function of the working angle
        if isinstance(FAdMag0, str):
            pth = os.path.normpath(os.path.expandvars(FAdMag0))
            assert os.path.isfile(pth), "%s is not a valid file." % pth
            dat = fits.open(pth)[0].data
            assert len(dat.shape) == 2 and 2 in dat.shape, \
                    "Wrong FAdMag0 data shape."
            WA, G = (dat[0], dat[1]) if dat.shape[0] == 2 else (dat[:,
                                                                    0], dat[:,
                                                                            1])
            # gain outside of WA values defaults to 25
            Ginterp = scipy.interpolate.interp1d(WA,
                                                 G,
                                                 kind='cubic',
                                                 fill_value=25.,
                                                 bounds_error=False)
            self.FAdMag0 = lambda s: np.array(Ginterp(s.to('arcsec').value),
                                              ndmin=1)
        elif isinstance(FAdMag0, numbers.Number):
            self.FAdMag0 = lambda s, G=float(FAdMag0): G

        # populate outspec
        for att in self.__dict__.keys():
            if att not in ['vprint', 'ppFact', 'FAdMag0', '_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(
                    dat, u.Quantity) else dat
        # populate with values which may be interpolants
        self._outspec['ppFact'] = ppFact
        self._outspec['FAdMag0'] = FAdMag0

        # instantiate background sources object
        self.BackgroundSources = get_module(
            specs['modules']['BackgroundSources'],
            'BackgroundSources')(**specs)
コード例 #18
0
    def __init__(self,
                 obscurFac=0.1,
                 shapeFac=np.pi / 4,
                 pupilDiam=4,
                 intCutoff=50,
                 dMag0=15,
                 WA0=None,
                 scienceInstruments=None,
                 QE=0.9,
                 optics=0.5,
                 FoV=10,
                 pixelNumber=1000,
                 pixelSize=1e-5,
                 sread=1e-6,
                 idark=1e-4,
                 CIC=1e-3,
                 texp=100,
                 radDos=0,
                 PCeff=0.8,
                 ENF=1,
                 Rs=50,
                 lenslSamp=2,
                 starlightSuppressionSystems=None,
                 lam=500,
                 BW=0.2,
                 occ_trans=0.2,
                 core_thruput=0.1,
                 core_contrast=1e-10,
                 core_platescale=None,
                 PSF=np.ones((3, 3)),
                 ohTime=1,
                 observingModes=None,
                 SNR=5,
                 timeMultiplier=1.,
                 IWA=None,
                 OWA=None,
                 ref_dMag=3,
                 ref_Time=0,
                 cachedir=None,
                 use_char_minintTime=False,
                 **specs):

        #start the outspec
        self._outspec = {}

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        # load all values with defaults
        self.obscurFac = float(
            obscurFac)  # obscuration factor (fraction of PM area)
        self.shapeFac = float(shapeFac)  # shape factor
        self.pupilDiam = float(pupilDiam) * u.m  # entrance pupil diameter
        self.intCutoff = float(intCutoff) * u.d  # integration time cutoff
        self.dMag0 = float(dMag0)  # favorable dMag for calc_minintTime
        self.ref_dMag = float(ref_dMag)  # reference star dMag for RDI
        self.ref_Time = float(
            ref_Time)  # fraction of time spent on ref star for RDI

        self.use_char_minintTime = use_char_minintTime

        # pupil collecting area (obscured PM)
        self.pupilArea = (1 -
                          self.obscurFac) * self.shapeFac * self.pupilDiam**2

        # spectral flux density ~9.5e7 [ph/s/m2/nm] @ 500nm
        # F0(lambda) function of wavelength, based on Traub et al. 2016 (JATIS):
        self.F0 = lambda l: 1e4*10**(4.01 - (l.to('nm').value - 550)/770) \
                *u.ph/u.s/u.m**2/u.nm

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)

        # loop through all science Instruments (must have one defined)
        assert scienceInstruments, "No science instrument defined."
        self.scienceInstruments = scienceInstruments
        self._outspec['scienceInstruments'] = []
        for ninst, inst in enumerate(self.scienceInstruments):
            assert isinstance(
                inst, dict), "Science instruments must be defined as dicts."
            assert 'name' in inst and isinstance(inst['name'], basestring), \
                    "All science instruments must have key name."
            # populate with values that may be filenames (interpolants)
            inst['QE'] = inst.get('QE', QE)
            self._outspec['scienceInstruments'].append(inst.copy())

            # quantum efficiency
            if isinstance(inst['QE'], basestring):
                pth = os.path.normpath(os.path.expandvars(inst['QE']))
                assert os.path.isfile(pth), "%s is not a valid file." % pth
                dat = fits.open(pth)[0].data
                assert len(dat.shape) == 2 and 2 in dat.shape, \
                        param_name + " wrong data shape."
                lam, D = (dat[0], dat[1]) if dat.shape[0] == 2 else (dat[:, 0],
                                                                     dat[:, 1])
                assert np.all(D >= 0) and np.all(D <= 1), \
                        "QE must be positive and smaller than 1."
                # parameter values outside of lam
                Dinterp = scipy.interpolate.interp1d(lam.astype(float),
                                                     D.astype(float),
                                                     kind='cubic',
                                                     fill_value=0.,
                                                     bounds_error=False)
                inst['QE'] = lambda l: np.array(Dinterp(l.to('nm').value),
                                                ndmin=1) / u.photon
            elif isinstance(inst['QE'], numbers.Number):
                assert inst['QE'] >= 0 and inst['QE'] <= 1, \
                        "QE must be positive and smaller than 1."
                inst['QE'] = lambda l, QE=float(inst['QE']): np.array(
                    [QE] * l.size, ndmin=1) / u.photon

            # load detector specifications
            inst['optics'] = float(inst.get(
                'optics', optics))  # attenuation due to optics
            inst['FoV'] = float(inst.get('FoV',
                                         FoV)) * u.arcsec  # field of view
            inst['pixelNumber'] = int(inst.get('pixelNumber',
                                               pixelNumber))  # array format
            inst['pixelSize'] = float(inst.get('pixelSize',
                                               pixelSize)) * u.m  # pixel pitch
            inst['pixelScale'] = inst.get(
                'pixelScale', 2 * inst['FoV'].value /
                inst['pixelNumber']) * u.arcsec  # pixel pitch
            inst['idark'] = float(inst.get('idark',
                                           idark)) / u.s  # dark-current rate
            inst['CIC'] = float(inst.get('CIC', CIC))  # clock-induced-charge
            inst['sread'] = float(inst.get('sread',
                                           sread))  # effective readout noise
            inst['texp'] = float(inst.get(
                'texp', texp)) * u.s  # exposure time per frame
            inst['ENF'] = float(inst.get('ENF', ENF))  # excess noise factor
            inst['PCeff'] = float(inst.get(
                'PCeff', PCeff))  # photon counting efficiency

            # parameters specific to spectrograph
            if 'spec' in inst['name'].lower():
                # spectral resolving power
                inst['Rs'] = float(inst.get('Rs', Rs))
                # lenslet sampling, number of pixel per lenslet rows or cols
                inst['lenslSamp'] = float(inst.get('lenslSamp', lenslSamp))
            else:
                inst['Rs'] = 1.
                inst['lenslSamp'] = 1.

            # calculate focal and f-number
            inst['focal'] = inst['pixelSize'].to('m') / inst['pixelScale'].to(
                'rad').value
            inst['fnumber'] = float(inst['focal'] / self.pupilDiam)

            # populate detector specifications to outspec
            for att in inst:
                if att not in ['QE']:
                    dat = inst[att]
                    self._outspec['scienceInstruments'][ninst][att] = dat.value \
                            if isinstance(dat, u.Quantity) else dat

        # loop through all starlight suppression systems (must have one defined)
        assert starlightSuppressionSystems, "No starlight suppression systems defined."
        self.starlightSuppressionSystems = starlightSuppressionSystems
        self.haveOcculter = False
        self._outspec['starlightSuppressionSystems'] = []
        for nsyst, syst in enumerate(self.starlightSuppressionSystems):
            assert isinstance(syst,dict),\
                    "Starlight suppression systems must be defined as dicts."
            assert 'name' in syst and isinstance(syst['name'],basestring),\
                    "All starlight suppression systems must have key name."
            # populate with values that may be filenames (interpolants)
            syst['occ_trans'] = syst.get('occ_trans', occ_trans)
            syst['core_thruput'] = syst.get('core_thruput', core_thruput)
            syst['core_contrast'] = syst.get('core_contrast', core_contrast)
            syst['core_mean_intensity'] = syst.get(
                'core_mean_intensity')  # no default
            syst['core_area'] = syst.get('core_area',
                                         0.)  # if zero, will get from lam/D
            syst['PSF'] = syst.get('PSF', PSF)
            self._outspec['starlightSuppressionSystems'].append(syst.copy())

            # attenuation due to optics specific to the coronagraph (defaults to 1)
            # e.g. polarizer, Lyot stop, extra flat mirror
            syst['optics'] = float(syst.get('optics', 1.))

            # set an occulter, for an external or hybrid system
            syst['occulter'] = syst.get('occulter', False)
            if syst['occulter'] == True:
                self.haveOcculter = True

            # handle inf OWA
            if syst.get('OWA') == 0:
                syst['OWA'] = np.Inf

            # when provided, always use deltaLam instead of BW (bandwidth fraction)
            syst['lam'] = float(syst.get(
                'lam', lam)) * u.nm  # central wavelength (nm)
            syst['deltaLam'] = float(
                syst.get('deltaLam', syst['lam'].to('nm').value *
                         syst.get('BW', BW))) * u.nm  # bandwidth (nm)
            syst['BW'] = float(syst['deltaLam'] /
                               syst['lam'])  # bandwidth fraction
            # default lam and BW updated with values from first instrument
            if nsyst == 0:
                lam, BW = syst.get('lam').value, syst.get('BW')

            # get coronagraph input parameters
            syst = self.get_coro_param(syst, 'occ_trans')
            syst = self.get_coro_param(syst, 'core_thruput')
            syst = self.get_coro_param(syst, 'core_contrast', fill=1.)
            syst = self.get_coro_param(syst, 'core_mean_intensity')
            syst = self.get_coro_param(syst, 'core_area')
            syst['core_platescale'] = syst.get('core_platescale',
                                               core_platescale)

            # get PSF
            if isinstance(syst['PSF'], basestring):
                pth = os.path.normpath(os.path.expandvars(syst['PSF']))
                assert os.path.isfile(pth), "%s is not a valid file." % pth
                hdr = fits.open(pth)[0].header
                dat = fits.open(pth)[0].data
                assert len(dat.shape) == 2, "Wrong PSF data shape."
                assert np.any(dat), "PSF must be != 0"
                syst['PSF'] = lambda l, s, P=dat: P
            else:
                assert np.any(syst['PSF']), "PSF must be != 0"
                syst['PSF'] = lambda l, s, P=np.array(syst['PSF']).astype(float
                                                                          ): P

            # loading system specifications
            syst['IWA'] = syst.get(
                'IWA', 0.1 if IWA is None else IWA) * u.arcsec  # inner WA
            syst['OWA'] = syst.get(
                'OWA', np.Inf if OWA is None else OWA) * u.arcsec  # outer WA
            syst['ohTime'] = float(syst.get('ohTime',
                                            ohTime)) * u.d  # overhead time

            # populate system specifications to outspec
            for att in syst:
                if att not in [
                        'occ_trans', 'core_thruput', 'core_contrast',
                        'core_mean_intensity', 'core_area', 'PSF'
                ]:
                    dat = syst[att]
                    self._outspec['starlightSuppressionSystems'][nsyst][att] \
                            = dat.value if isinstance(dat, u.Quantity) else dat

        # loop through all observing modes
        # if no observing mode defined, create a default mode
        if observingModes == None:
            inst = self.scienceInstruments[0]
            syst = self.starlightSuppressionSystems[0]
            observingModes = [{
                'detectionMode': True,
                'instName': inst['name'],
                'systName': syst['name']
            }]
        self.observingModes = observingModes
        self._outspec['observingModes'] = []
        for nmode, mode in enumerate(self.observingModes):
            assert isinstance(
                mode, dict), "Observing modes must be defined as dicts."
            assert 'instName' in mode and 'systName' in mode, \
                    "All observing modes must have key instName and systName."
            assert np.any([mode['instName'] == inst['name'] for inst in \
                    self.scienceInstruments]), "The mode's instrument name " \
                    + mode['instName'] + " does not exist."
            assert np.any([mode['systName'] == syst['name'] for syst in \
                    self.starlightSuppressionSystems]), "The mode's system name " \
                    + mode['systName'] + " does not exist."
            self._outspec['observingModes'].append(mode.copy())

            # loading mode specifications
            mode['SNR'] = float(mode.get('SNR', SNR))
            mode['timeMultiplier'] = float(
                mode.get('timeMultiplier', timeMultiplier))
            mode['detectionMode'] = mode.get('detectionMode', False)
            mode['inst'] = [inst for inst in self.scienceInstruments \
                    if inst['name'] == mode['instName']][0]
            mode['syst'] = [syst for syst in self.starlightSuppressionSystems \
                    if syst['name'] == mode['systName']][0]
            # get mode wavelength and bandwidth (get system's values by default)
            # when provided, always use deltaLam instead of BW (bandwidth fraction)
            syst_lam = mode['syst']['lam'].to('nm').value
            syst_BW = mode['syst']['BW']
            mode['lam'] = float(mode.get('lam', syst_lam)) * u.nm
            mode['deltaLam'] = float(mode.get('deltaLam', mode['lam'].value \
                    *mode.get('BW',syst_BW)))*u.nm
            mode['BW'] = float(mode['deltaLam'] / mode['lam'])
            # get mode IWA and OWA: rescale if the mode wavelength is different than
            # the wavelength at which the system is defined
            mode['IWA'] = mode['syst']['IWA']
            mode['OWA'] = mode['syst']['OWA']
            if mode['lam'] != mode['syst']['lam']:
                mode['IWA'] = mode['IWA'] * mode['lam'] / mode['syst']['lam']
                mode['OWA'] = mode['OWA'] * mode['lam'] / mode['syst']['lam']
            # radiation dosage, goes from 0 (beginning of mission) to 1 (end of mission)
            mode['radDos'] = float(mode.get('radDos', radDos))

        # check for only one detection mode
        allModes = self.observingModes
        detModes = list(
            filter(lambda mode: mode['detectionMode'] == True, allModes))
        assert len(detModes) <= 1, "More than one detection mode specified."
        # if not specified, default detection mode is first imager mode
        if len(detModes) == 0:
            imagerModes = list(
                filter(lambda mode: 'imag' in mode['inst']['name'], allModes))
            if imagerModes:
                imagerModes[0]['detectionMode'] = True
            # if no imager mode, default detection mode is first observing mode
            else:
                allModes[0]['detectionMode'] = True

        # load favorable working angle (WA0) for calc_minintTime,
        # or calculate it from detection IWA-OWA midpoint value
        try:
            self.WA0 = float(WA0) * u.arcsec
        except TypeError:
            mode = list(
                filter(lambda mode: mode['detectionMode'] == True,
                       self.observingModes))[0]
            self.WA0 = 2. * mode['IWA'] if np.isinf(
                mode['OWA']) else (mode['IWA'] + mode['OWA']) / 2.

        # populate fundamental IWA and OWA as required
        IWAs = [
            x.get('IWA') for x in self.observingModes
            if x.get('IWA') is not None
        ]
        if IWA is not None:
            self.IWA = float(IWA) * u.arcsec
        elif IWAs:
            self.IWA = min(IWAs)
        else:
            raise ValueError("Could not determine fundamental IWA.")

        OWAs = [
            x.get('OWA') for x in self.observingModes
            if x.get('OWA') is not None
        ]
        if OWA is not None:
            self.OWA = float(OWA) * u.arcsec if OWA != 0 else np.inf * u.arcsec
        elif OWAs:
            self.OWA = max(OWAs)
        else:
            raise ValueError("Could not determine fundamental OWA.")

        assert self.IWA < self.OWA, "Fundamental IWA must be smaller that the OWA."

        # populate outspec with all OpticalSystem scalar attributes
        for att in self.__dict__:
            if att not in [
                    'vprint', 'F0', 'scienceInstruments',
                    'starlightSuppressionSystems', 'observingModes', '_outspec'
            ]:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(
                    dat, u.Quantity) else dat
コード例 #19
0
ファイル: TargetList.py プロジェクト: dsavransky/EXOSIMS
    def __init__(self, missionStart=60634, staticStars=True, 
        keepStarCatalog=False, fillPhotometry=False, explainFiltering=False, 
        filterBinaries=True, filterSubM=False, cachedir=None, **specs):
       
        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        # validate TargetList inputs
        assert isinstance(staticStars, bool), "staticStars must be a boolean."
        assert isinstance(keepStarCatalog, bool), "keepStarCatalog must be a boolean."
        assert isinstance(fillPhotometry, bool), "fillPhotometry must be a boolean."
        assert isinstance(explainFiltering, bool), "explainFiltering must be a boolean."
        assert isinstance(filterBinaries, bool), "filterBinaries must be a boolean."
        assert isinstance(filterSubM, bool), "filterSubM must be a boolean."
        self.staticStars = bool(staticStars)
        self.keepStarCatalog = bool(keepStarCatalog)
        self.fillPhotometry = bool(fillPhotometry)
        self.explainFiltering = bool(explainFiltering)
        self.filterBinaries = bool(filterBinaries)
        self.filterSubM = bool(filterSubM)
        
        # check if KnownRVPlanetsTargetList is using KnownRVPlanets
        if specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList':
            assert specs['modules']['PlanetPopulation'] == 'KnownRVPlanets', \
            'KnownRVPlanetsTargetList must use KnownRVPlanets'
        else:
            assert specs['modules']['PlanetPopulation'] != 'KnownRVPlanets', \
            'This TargetList cannot use KnownRVPlanets'
        
        # check if KnownRVPlanetsTargetList is using KnownRVPlanets
        if specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList':
            assert specs['modules']['PlanetPopulation'] == 'KnownRVPlanets', \
            'KnownRVPlanetsTargetList must use KnownRVPlanets'
        else:
            assert specs['modules']['PlanetPopulation'] != 'KnownRVPlanets', \
            'This TargetList cannot use KnownRVPlanets'
        
        # populate outspec
        for att in self.__dict__:
            if att not in ['vprint','_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(dat, u.Quantity) else dat

        # get desired module names (specific or prototype) and instantiate objects
        self.StarCatalog = get_module(specs['modules']['StarCatalog'],
                'StarCatalog')(**specs)
        self.OpticalSystem = get_module(specs['modules']['OpticalSystem'],
                'OpticalSystem')(**specs)
        self.ZodiacalLight = get_module(specs['modules']['ZodiacalLight'],
                'ZodiacalLight')(**specs)
        self.PostProcessing = get_module(specs['modules']['PostProcessing'],
                'PostProcessing')(**specs)
        self.Completeness = get_module(specs['modules']['Completeness'],
                'Completeness')(**specs)
        
        # bring inherited class objects to top level of Simulated Universe
        self.BackgroundSources = self.PostProcessing.BackgroundSources

        #if specs contains a completeness_spec then we are going to generate separate instances
        #of planet population and planet physical model for completeness and for the rest of the sim
        if 'completeness_specs' in specs:
            self.PlanetPopulation = get_module(specs['modules']['PlanetPopulation'],'PlanetPopulation')(**specs)
            self.PlanetPhysicalModel = self.PlanetPopulation.PlanetPhysicalModel
        else:
            self.PlanetPopulation = self.Completeness.PlanetPopulation
            self.PlanetPhysicalModel = self.Completeness.PlanetPhysicalModel
        
        # list of possible Star Catalog attributes
        self.catalog_atts = ['Name', 'Spec', 'parx', 'Umag', 'Bmag', 'Vmag', 'Rmag', 
                'Imag', 'Jmag', 'Hmag', 'Kmag', 'dist', 'BV', 'MV', 'BC', 'L', 
                'coords', 'pmra', 'pmdec', 'rv', 'Binary_Cut']
        
        # now populate and filter the list
        self.populate_target_list(**specs)
        # generate any completeness update data needed
        self.Completeness.gen_update(self)
        self.filter_target_list(**specs)

        # have target list, no need for catalog now (unless asked to retain)
        if not self.keepStarCatalog:
            self.StarCatalog = specs['modules']['StarCatalog']

        # add nStars to outspec
        self._outspec['nStars'] = self.nStars
        
        # if staticStars is True, the star coordinates are taken at mission start, 
        # and are not propagated during the mission
        self.starprop_static = None
        if self.staticStars is True:
            allInds = np.arange(self.nStars,dtype=int)
            missionStart = Time(float(missionStart), format='mjd', scale='tai')
            self.starprop_static = lambda sInds, currentTime, eclip=False, \
                    c1=self.starprop(allInds, missionStart, eclip=False), \
                    c2=self.starprop(allInds, missionStart, eclip=True): \
                    c1[sInds] if eclip==False else c2[sInds]
コード例 #20
0
    def __init__(self, arange=[0.1,100.], erange=[0.01,0.99], Irange=[0.,180.],
        Orange=[0.,360.], wrange=[0.,360.], prange=[0.1,0.6], Rprange=[1.,30.],
        Mprange=[1.,4131.], scaleOrbits=False, constrainOrbits=False, eta=0.1,
        cachedir=None, **specs):
       
        #start the outspec
        self._outspec = {}

        # get the cache directory
        self.cachedir = get_cache_dir(cachedir)

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        # check range of parameters
        self.arange = self.checkranges(arange,'arange')*u.AU
        self.erange = self.checkranges(erange,'erange')
        self.Irange = self.checkranges(Irange,'Irange')*u.deg
        self.Orange = self.checkranges(Orange,'Orange')*u.deg
        self.wrange = self.checkranges(wrange,'wrange')*u.deg
        self.prange = self.checkranges(prange,'prange')
        self.Rprange = self.checkranges(Rprange,'Rprange')*u.earthRad
        self.Mprange = self.checkranges(Mprange,'Mprange')*u.earthMass
        
        assert isinstance(scaleOrbits, bool), "scaleOrbits must be boolean"
        # scale planetary orbits by sqrt(L)
        self.scaleOrbits = scaleOrbits
        
        assert isinstance(constrainOrbits,bool), "constrainOrbits must be boolean"
        # constrain planetary orbital radii to sma range
        self.constrainOrbits = constrainOrbits
        # derive orbital radius range from quantities above
        ar = self.arange.to('AU').value
        er = self.erange
        if self.constrainOrbits:
            self.rrange = [ar[0], ar[1]]*u.AU
        else:
            self.rrange = [ar[0]*(1. - er[1]), ar[1]*(1. + er[1])]*u.AU
        assert isinstance(eta, numbers.Number) and (eta > 0),\
                "eta must be strictly positive"
        # global occurrence rate defined as expected number of planets per 
        # star in a given universe
        self.eta = eta
        
        # albedo is constant for planetary radius range
        self.pfromRp = False
        
        # populate all attributes to outspec
        for att in self.__dict__:
            if att not in ['vprint','_outspec']:
                dat = copy.copy(self.__dict__[att])
                self._outspec[att] = dat.value if isinstance(dat, u.Quantity) else dat
                
        # define prototype distributions of parameters (uniform and log-uniform)
        self.uniform = lambda x,v: np.array((np.array(x) >=v [0]) & 
                (np.array(x) <= v[1]), dtype=float, ndmin=1) / (v[1] - v[0])
        self.logunif = lambda x,v: np.array((np.array(x) >= v[0]) &
                (np.array(x) <= v[1]), dtype=float, ndmin=1) / (x*np.log(v[1]/v[0]))
        
        # import PlanetPhysicalModel
        self.PlanetPhysicalModel = get_module(specs['modules']['PlanetPhysicalModel'],
                'PlanetPhysicalModel')(**specs)
コード例 #21
0
    def __init__(self,
                 missionStart=60634,
                 staticStars=True,
                 keepStarCatalog=False,
                 fillPhotometry=False,
                 explainFiltering=False,
                 filterBinaries=True,
                 filterSubM=False,
                 cachedir=None,
                 filter_for_char=False,
                 earths_only=False,
                 **specs):

        #start the outspec
        self._outspec = {}

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        self._outspec['cachedir'] = self.cachedir
        specs['cachedir'] = self.cachedir

        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        # validate TargetList inputs
        assert isinstance(staticStars, bool), "staticStars must be a boolean."
        assert isinstance(keepStarCatalog,
                          bool), "keepStarCatalog must be a boolean."
        assert isinstance(fillPhotometry,
                          bool), "fillPhotometry must be a boolean."
        assert isinstance(explainFiltering,
                          bool), "explainFiltering must be a boolean."
        assert isinstance(filterBinaries,
                          bool), "filterBinaries must be a boolean."
        assert isinstance(filterSubM, bool), "filterSubM must be a boolean."
        self.staticStars = bool(staticStars)
        self.keepStarCatalog = bool(keepStarCatalog)
        self.fillPhotometry = bool(fillPhotometry)
        self.explainFiltering = bool(explainFiltering)
        self.filterBinaries = bool(filterBinaries)
        self.filterSubM = bool(filterSubM)
        self.filter_for_char = bool(filter_for_char)
        self.earths_only = bool(earths_only)

        # check if KnownRVPlanetsTargetList is using KnownRVPlanets
        if specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList':
            assert specs['modules']['PlanetPopulation'] == 'KnownRVPlanets', \
            'KnownRVPlanetsTargetList must use KnownRVPlanets'
        else:
            assert specs['modules']['PlanetPopulation'] != 'KnownRVPlanets', \
            'This TargetList cannot use KnownRVPlanets'

        # check if KnownRVPlanetsTargetList is using KnownRVPlanets
        if specs['modules']['TargetList'] == 'KnownRVPlanetsTargetList':
            assert specs['modules']['PlanetPopulation'] == 'KnownRVPlanets', \
            'KnownRVPlanetsTargetList must use KnownRVPlanets'
        else:
            assert specs['modules']['PlanetPopulation'] != 'KnownRVPlanets', \
            'This TargetList cannot use KnownRVPlanets'

        # populate outspec
        for att in self.__dict__:
            if att not in ['vprint', '_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(
                    dat, u.Quantity) else dat

        # get desired module names (specific or prototype) and instantiate objects
        self.StarCatalog = get_module(specs['modules']['StarCatalog'],
                                      'StarCatalog')(**specs)
        self.OpticalSystem = get_module(specs['modules']['OpticalSystem'],
                                        'OpticalSystem')(**specs)
        self.ZodiacalLight = get_module(specs['modules']['ZodiacalLight'],
                                        'ZodiacalLight')(**specs)
        self.PostProcessing = get_module(specs['modules']['PostProcessing'],
                                         'PostProcessing')(**specs)
        self.Completeness = get_module(specs['modules']['Completeness'],
                                       'Completeness')(**specs)

        # bring inherited class objects to top level of Simulated Universe
        self.BackgroundSources = self.PostProcessing.BackgroundSources

        #if specs contains a completeness_spec then we are going to generate separate instances
        #of planet population and planet physical model for completeness and for the rest of the sim
        if 'completeness_specs' in specs:
            self.PlanetPopulation = get_module(
                specs['modules']['PlanetPopulation'],
                'PlanetPopulation')(**specs)
            self.PlanetPhysicalModel = self.PlanetPopulation.PlanetPhysicalModel
        else:
            self.PlanetPopulation = self.Completeness.PlanetPopulation
            self.PlanetPhysicalModel = self.Completeness.PlanetPhysicalModel

        # list of possible Star Catalog attributes
        self.catalog_atts = [
            'Name', 'Spec', 'parx', 'Umag', 'Bmag', 'Vmag', 'Rmag', 'Imag',
            'Jmag', 'Hmag', 'Kmag', 'dist', 'BV', 'MV', 'BC', 'L', 'coords',
            'pmra', 'pmdec', 'rv', 'Binary_Cut', 'closesep', 'closedm',
            'brightsep', 'brightdm'
        ]

        # now populate and filter the list
        self.populate_target_list(**specs)
        # generate any completeness update data needed
        self.Completeness.gen_update(self)
        self.filter_target_list(**specs)

        # have target list, no need for catalog now (unless asked to retain)
        if not self.keepStarCatalog:
            self.StarCatalog = specs['modules']['StarCatalog']

        # add nStars to outspec
        self._outspec['nStars'] = self.nStars

        # if staticStars is True, the star coordinates are taken at mission start,
        # and are not propagated during the mission
        self.starprop_static = None
        if self.staticStars is True:
            allInds = np.arange(self.nStars, dtype=int)
            missionStart = Time(float(missionStart), format='mjd', scale='tai')
            self.starprop_static = lambda sInds, currentTime, eclip=False, \
                    c1=self.starprop(allInds, missionStart, eclip=False), \
                    c2=self.starprop(allInds, missionStart, eclip=True): \
                    c1[sInds] if eclip==False else c2[sInds]
コード例 #22
0
ファイル: OpticalSystem.py プロジェクト: dsavransky/EXOSIMS
    def __init__(self, obscurFac=0.1, shapeFac=np.pi/4, pupilDiam=4, intCutoff=50, 
            dMag0=15, WA0=None, scienceInstruments=None, QE=0.9, optics=0.5, FoV=10,
            pixelNumber=1000, pixelSize=1e-5, sread=1e-6, idark=1e-4, CIC=1e-3, 
            texp=100, radDos=0, PCeff=0.8, ENF=1, Rs=50, lenslSamp=2, 
            starlightSuppressionSystems=None, lam=500, BW=0.2, occ_trans=0.2,
            core_thruput=0.1, core_contrast=1e-10, core_platescale=None, 
            PSF=np.ones((3,3)), ohTime=1, observingModes=None, SNR=5, timeMultiplier=1., 
            IWA=None, OWA=None, ref_dMag=3, ref_Time=0, cachedir=None,
            use_char_minintTime=False, **specs):

        #start the outspec
        self._outspec = {}
        
        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))
        
        # load all values with defaults
        self.obscurFac = float(obscurFac)       # obscuration factor (fraction of PM area)
        self.shapeFac = float(shapeFac)         # shape factor
        self.pupilDiam = float(pupilDiam)*u.m   # entrance pupil diameter
        self.intCutoff = float(intCutoff)*u.d   # integration time cutoff
        self.dMag0 = float(dMag0)               # favorable dMag for calc_minintTime
        self.ref_dMag = float(ref_dMag)         # reference star dMag for RDI
        self.ref_Time = float(ref_Time)         # fraction of time spent on ref star for RDI

        self.use_char_minintTime = use_char_minintTime
        
        # pupil collecting area (obscured PM)
        self.pupilArea = (1 - self.obscurFac)*self.shapeFac*self.pupilDiam**2
        
        # spectral flux density ~9.5e7 [ph/s/m2/nm] @ 500nm
        # F0(lambda) function of wavelength, based on Traub et al. 2016 (JATIS):
        self.F0 = lambda l: 1e4*10**(4.01 - (l.to('nm').value - 550)/770) \
                *u.ph/u.s/u.m**2/u.nm

        # get cache directory
        self.cachedir = get_cache_dir(cachedir)
        
        # loop through all science Instruments (must have one defined)
        assert scienceInstruments, "No science instrument defined."
        self.scienceInstruments = scienceInstruments
        self._outspec['scienceInstruments'] = []
        for ninst, inst in enumerate(self.scienceInstruments):
            assert isinstance(inst, dict), "Science instruments must be defined as dicts."
            assert 'name' in inst and isinstance(inst['name'], basestring), \
                    "All science instruments must have key name."
            # populate with values that may be filenames (interpolants)
            inst['QE'] = inst.get('QE', QE)
            self._outspec['scienceInstruments'].append(inst.copy())
            
            # quantum efficiency
            if isinstance(inst['QE'], basestring):
                pth = os.path.normpath(os.path.expandvars(inst['QE']))
                assert os.path.isfile(pth), "%s is not a valid file."%pth
                dat = fits.open(pth)[0].data
                assert len(dat.shape) == 2 and 2 in dat.shape, \
                        param_name + " wrong data shape."
                lam, D = (dat[0], dat[1]) if dat.shape[0] == 2 else (dat[:,0], dat[:,1])
                assert np.all(D >= 0) and np.all(D <= 1), \
                        "QE must be positive and smaller than 1."
                # parameter values outside of lam
                Dinterp = scipy.interpolate.interp1d(lam.astype(float), D.astype(float),
                        kind='cubic', fill_value=0., bounds_error=False)
                inst['QE'] = lambda l: np.array(Dinterp(l.to('nm').value), 
                        ndmin=1)/u.photon
            elif isinstance(inst['QE'], numbers.Number):
                assert inst['QE'] >= 0 and inst['QE'] <= 1, \
                        "QE must be positive and smaller than 1."
                inst['QE'] = lambda l, QE=float(inst['QE']): np.array([QE]*l.size,
                        ndmin=1)/u.photon
            
            # load detector specifications
            inst['optics'] = float(inst.get('optics', optics))  # attenuation due to optics
            inst['FoV'] = float(inst.get('FoV', FoV))*u.arcsec  # field of view
            inst['pixelNumber'] = int(inst.get('pixelNumber', pixelNumber)) # array format
            inst['pixelSize'] = float(inst.get('pixelSize', pixelSize))*u.m # pixel pitch
            inst['pixelScale'] = inst.get('pixelScale', 2*inst['FoV'].value/inst['pixelNumber'])*u.arcsec # pixel pitch
            inst['idark'] = float(inst.get('idark', idark))/u.s # dark-current rate
            inst['CIC'] = float(inst.get('CIC', CIC))           # clock-induced-charge
            inst['sread'] = float(inst.get('sread', sread))     # effective readout noise
            inst['texp'] = float(inst.get('texp', texp))*u.s    # exposure time per frame
            inst['ENF'] = float(inst.get('ENF', ENF))           # excess noise factor
            inst['PCeff'] = float(inst.get('PCeff', PCeff))     # photon counting efficiency
            
            # parameters specific to spectrograph
            if 'spec' in inst['name'].lower():
                # spectral resolving power
                inst['Rs'] = float(inst.get('Rs', Rs))
                # lenslet sampling, number of pixel per lenslet rows or cols
                inst['lenslSamp'] = float(inst.get('lenslSamp', lenslSamp))
            else:
                inst['Rs'] = 1.
                inst['lenslSamp'] = 1.
            
            # calculate focal and f-number
            inst['focal'] = inst['pixelSize'].to('m')/inst['pixelScale'].to('rad').value
            inst['fnumber'] = float(inst['focal']/self.pupilDiam)
            
            # populate detector specifications to outspec
            for att in inst:
                if att not in ['QE']:
                    dat = inst[att]
                    self._outspec['scienceInstruments'][ninst][att] = dat.value \
                            if isinstance(dat, u.Quantity) else dat
        
        # loop through all starlight suppression systems (must have one defined)
        assert starlightSuppressionSystems, "No starlight suppression systems defined."
        self.starlightSuppressionSystems = starlightSuppressionSystems
        self.haveOcculter = False
        self._outspec['starlightSuppressionSystems'] = []
        for nsyst,syst in enumerate(self.starlightSuppressionSystems):
            assert isinstance(syst,dict),\
                    "Starlight suppression systems must be defined as dicts."
            assert 'name' in syst and isinstance(syst['name'],basestring),\
                    "All starlight suppression systems must have key name."
            # populate with values that may be filenames (interpolants)
            syst['occ_trans'] = syst.get('occ_trans', occ_trans)
            syst['core_thruput'] = syst.get('core_thruput', core_thruput)
            syst['core_contrast'] = syst.get('core_contrast', core_contrast)
            syst['core_mean_intensity'] = syst.get('core_mean_intensity') # no default
            syst['core_area'] = syst.get('core_area', 0.) # if zero, will get from lam/D
            syst['PSF'] = syst.get('PSF', PSF)
            self._outspec['starlightSuppressionSystems'].append(syst.copy())
            
            # attenuation due to optics specific to the coronagraph (defaults to 1)
            # e.g. polarizer, Lyot stop, extra flat mirror
            syst['optics'] = float(syst.get('optics', 1.))
            
            # set an occulter, for an external or hybrid system
            syst['occulter'] = syst.get('occulter', False)
            if syst['occulter'] == True:
                self.haveOcculter = True
            
            # handle inf OWA
            if syst.get('OWA') == 0:
                syst['OWA'] = np.Inf
            
            # when provided, always use deltaLam instead of BW (bandwidth fraction)
            syst['lam'] = float(syst.get('lam', lam))*u.nm      # central wavelength (nm)
            syst['deltaLam'] = float(syst.get('deltaLam', syst['lam'].to('nm').value*
                    syst.get('BW', BW)))*u.nm                   # bandwidth (nm)
            syst['BW'] = float(syst['deltaLam']/syst['lam'])    # bandwidth fraction
            # default lam and BW updated with values from first instrument
            if nsyst == 0:
                lam, BW = syst.get('lam').value, syst.get('BW')
            
            # get coronagraph input parameters
            syst = self.get_coro_param(syst, 'occ_trans')
            syst = self.get_coro_param(syst, 'core_thruput')
            syst = self.get_coro_param(syst, 'core_contrast', fill=1.)
            syst = self.get_coro_param(syst, 'core_mean_intensity')
            syst = self.get_coro_param(syst, 'core_area')
            syst['core_platescale'] = syst.get('core_platescale', core_platescale)
            
            # get PSF
            if isinstance(syst['PSF'], basestring):
                pth = os.path.normpath(os.path.expandvars(syst['PSF']))
                assert os.path.isfile(pth), "%s is not a valid file."%pth
                hdr = fits.open(pth)[0].header
                dat = fits.open(pth)[0].data
                assert len(dat.shape) == 2, "Wrong PSF data shape."
                assert np.any(dat), "PSF must be != 0"
                syst['PSF'] = lambda l, s, P=dat: P
            else:
                assert np.any(syst['PSF']), "PSF must be != 0"
                syst['PSF'] = lambda l, s, P=np.array(syst['PSF']).astype(float): P
            
            # loading system specifications
            syst['IWA'] = syst.get('IWA', 0.1 if IWA is None else IWA)*u.arcsec    # inner WA
            syst['OWA'] = syst.get('OWA', np.Inf if OWA is None else OWA)*u.arcsec# outer WA
            syst['ohTime'] = float(syst.get('ohTime', ohTime))*u.d  # overhead time
            
            # populate system specifications to outspec
            for att in syst:
                if att not in ['occ_trans', 'core_thruput', 'core_contrast',
                        'core_mean_intensity', 'core_area', 'PSF']:
                    dat = syst[att]
                    self._outspec['starlightSuppressionSystems'][nsyst][att] \
                            = dat.value if isinstance(dat, u.Quantity) else dat
        
        # loop through all observing modes
        # if no observing mode defined, create a default mode
        if observingModes == None:
            inst = self.scienceInstruments[0]
            syst = self.starlightSuppressionSystems[0]
            observingModes = [{'detectionMode': True,
                               'instName': inst['name'],
                               'systName': syst['name']}]
        self.observingModes = observingModes
        self._outspec['observingModes'] = []
        for nmode, mode in enumerate(self.observingModes):
            assert isinstance(mode, dict), "Observing modes must be defined as dicts."
            assert 'instName' in mode and 'systName' in mode, \
                    "All observing modes must have key instName and systName."
            assert np.any([mode['instName'] == inst['name'] for inst in \
                    self.scienceInstruments]), "The mode's instrument name " \
                    + mode['instName'] + " does not exist."
            assert np.any([mode['systName'] == syst['name'] for syst in \
                    self.starlightSuppressionSystems]), "The mode's system name " \
                    + mode['systName'] + " does not exist."
            self._outspec['observingModes'].append(mode.copy())
            
            # loading mode specifications
            mode['SNR'] = float(mode.get('SNR', SNR))
            mode['timeMultiplier'] = float(mode.get('timeMultiplier', timeMultiplier))
            mode['detectionMode'] = mode.get('detectionMode', False)
            mode['inst'] = [inst for inst in self.scienceInstruments \
                    if inst['name'] == mode['instName']][0]
            mode['syst'] = [syst for syst in self.starlightSuppressionSystems \
                    if syst['name'] == mode['systName']][0]
            # get mode wavelength and bandwidth (get system's values by default)
            # when provided, always use deltaLam instead of BW (bandwidth fraction)
            syst_lam = mode['syst']['lam'].to('nm').value
            syst_BW = mode['syst']['BW']
            mode['lam'] = float(mode.get('lam', syst_lam))*u.nm
            mode['deltaLam'] = float(mode.get('deltaLam', mode['lam'].value \
                    *mode.get('BW',syst_BW)))*u.nm
            mode['BW'] = float(mode['deltaLam']/mode['lam'])
            # get mode IWA and OWA: rescale if the mode wavelength is different than 
            # the wavelength at which the system is defined
            mode['IWA'] = mode['syst']['IWA']
            mode['OWA'] = mode['syst']['OWA']
            if mode['lam'] != mode['syst']['lam']:
                mode['IWA'] = mode['IWA']*mode['lam']/mode['syst']['lam']
                mode['OWA'] = mode['OWA']*mode['lam']/mode['syst']['lam']
            # radiation dosage, goes from 0 (beginning of mission) to 1 (end of mission)
            mode['radDos'] = float(mode.get('radDos', radDos))
        
        # check for only one detection mode
        allModes = self.observingModes
        detModes = list(filter(lambda mode: mode['detectionMode'] == True, allModes))
        assert len(detModes) <= 1, "More than one detection mode specified."
        # if not specified, default detection mode is first imager mode
        if len(detModes) == 0:
            imagerModes = list(filter(lambda mode: 'imag' in mode['inst']['name'], allModes))
            if imagerModes:
                imagerModes[0]['detectionMode'] = True
            # if no imager mode, default detection mode is first observing mode
            else:
                allModes[0]['detectionMode'] = True
        
        # load favorable working angle (WA0) for calc_minintTime,
        # or calculate it from detection IWA-OWA midpoint value
        try:
            self.WA0 = float(WA0)*u.arcsec
        except TypeError:
            mode = list(filter(lambda mode: mode['detectionMode'] == True, self.observingModes))[0]
            self.WA0 = 2.*mode['IWA'] if np.isinf(mode['OWA']) else (mode['IWA'] + mode['OWA'])/2.
        
        # populate fundamental IWA and OWA as required
        IWAs = [x.get('IWA') for x in self.observingModes if x.get('IWA') is not None]
        if IWA is not None:
            self.IWA = float(IWA)*u.arcsec
        elif IWAs:
            self.IWA = min(IWAs)
        else:
            raise ValueError("Could not determine fundamental IWA.")
        
        OWAs = [x.get('OWA') for x in self.observingModes if x.get('OWA') is not None]
        if OWA is not None:
            self.OWA = float(OWA)*u.arcsec if OWA != 0 else np.inf*u.arcsec
        elif OWAs:
            self.OWA = max(OWAs)
        else:
            raise ValueError("Could not determine fundamental OWA.")
        
        assert self.IWA < self.OWA, "Fundamental IWA must be smaller that the OWA."
        
        # populate outspec with all OpticalSystem scalar attributes
        for att in self.__dict__:
            if att not in ['vprint', 'F0', 'scienceInstruments', 
                    'starlightSuppressionSystems', 'observingModes','_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(dat, u.Quantity) else dat