Ejemplo n.º 1
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
Ejemplo n.º 2
0
    def __init__(self, **specs):

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

        # 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

        # list of possible planet attributes
        self.planet_atts = [
            'plan2star', 'a', 'e', 'I', 'O', 'w', 'M0', '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()
Ejemplo n.º 3
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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
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()
Ejemplo n.º 6
0
    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))
Ejemplo n.º 7
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
Ejemplo n.º 8
0
    def singleRunPostProcessing(self, PPoutpath, folder):
        """Generates a single yield histogram for the run_type
        Args:
            PPoutpath (string) - output path to place data in
            folder (string) - full filepath to folder containing runs
        """
        #Get name of pkl file
        if not os.path.exists(folder):
            raise ValueError('%s not found'%folder)
        outspecPath = os.path.join(folder,'outspec.json')
        try:
            with open(outspecPath, 'rb') as g:
                outspec = json.load(g)
        except:
            vprint('Failed to open outspecfile %s'%outspecPath)
            pass

        #Create Simulation Object
        sim = EXOSIMS.MissionSim.MissionSim(scriptfile=None, nopar=True, **outspec)

        self.plotJointPDF(sim,PPoutpath,folder)
Ejemplo n.º 9
0
    def __init__(self, scriptfile, outspec):
        """
        Args:
            scriptfile (string):
            outspec (dictionary):

        """
        self.outspec = outspec
        if scriptfile is not None:
            assert os.path.isfile(scriptfile), "%s is not a file."%scriptfile
            try:
                script = open(scriptfile).read()
                self.specs_from_file = json.loads(script)
            except ValueError as err:
                vprint("Error: %s: Input file `%s' improperly formatted."%(self._modtype,
                        scriptfile))
                vprint("Error: JSON error was: ", err)
                # re-raise here to suppress the rest of the backtrace.
                # it is only confusing details about the bowels of json.loads()
                raise ValueError(err)
            except:
                vprint("Error: %s: %s", (self._modtype, sys.exc_info()[0]))
                raise
        else:
            self.specs_from_file = {}
Ejemplo n.º 10
0
    def __init__(self, scriptfile, outspec):
        """
        Args:
            scriptfile (string):
            outspec (dictionary):

        """
        self.outspec = outspec
        if scriptfile is not None:
            assert os.path.isfile(scriptfile), "%s is not a file." % scriptfile
            try:
                script = open(scriptfile).read()
                self.specs_from_file = json.loads(script)
            except ValueError as err:
                vprint("Error: %s: Input file `%s' improperly formatted." %
                       (self._modtype, scriptfile))
                vprint("Error: JSON error was: ", err)
                # re-raise here to suppress the rest of the backtrace.
                # it is only confusing details about the bowels of json.loads()
                raise ValueError(err)
            except:
                vprint("Error: %s: %s", (self._modtype, sys.exc_info()[0]))
                raise
        else:
            self.specs_from_file = {}
Ejemplo n.º 11
0
 def loadAliasFile(self):
     """
     Args:
     Returns:
         alias ():
             list 
     """
     #OLD aliasname = 'alias_4_11_2019.pkl'
     aliasname = 'alias_10_07_2019.pkl'
     tmp1 = inspect.getfile(self.__class__).split('/')[:-2]
     tmp1.append('util')
     self.classpath = '/'.join(tmp1)
     #self.classpath = os.path.split(inspect.getfile(self.__class__))[0]
     #vprint(inspect.getfile(self.__class__))
     self.alias_datapath = os.path.join(self.classpath, aliasname)
     #Load pkl and outspec files
     try:
         with open(self.alias_datapath, 'rb') as f:  #load from cache
             alias = pickle.load(f, encoding='latin1')
     except:
         vprint('Failed to open fullPathPKL %s' % self.alias_datapath)
         pass
     return alias
Ejemplo n.º 12
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
Ejemplo n.º 13
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__:
            if att not in ['vprint','_outspec']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(dat,(u.Quantity,Time)) else dat
Ejemplo n.º 14
0
    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
Ejemplo n.º 15
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
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
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)
        
        # 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
Ejemplo n.º 18
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)
Ejemplo n.º 19
0
 def __init__(self, args=None):
     vprint(args)
     vprint('fakeMultiRunAnalysis done')
     pass
 def __init__(self, args=None):
     vprint(args)
     vprint('plotConvergencevsNumberofRuns done')
     pass
Ejemplo n.º 21
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
Ejemplo n.º 22
0
 def __init__(self, args=None):
     vprint(args)
     self.args = args
     vprint('plotTimeline Initialization done')
     pass
Ejemplo n.º 23
0
 def __init__(self, args=None):
     vprint(args)
     vprint('plotCompletenessJointPDFs done')
     pass
Ejemplo n.º 24
0
    def singleRunPostProcessing(self, PPoutpath, folder):
        """Generates a single yield histogram for the run_type
        Args:
            PPoutpath (string) - output path to place data in
            folder (string) - full filepath to folder containing runs
        """
        if not os.path.exists(folder):  #Folder must exist
            raise ValueError('%s not found' % folder)
        if not os.path.exists(PPoutpath):  #PPoutpath must exist
            raise ValueError('%s not found' % PPoutpath)
        outspecfile = os.path.join(folder, 'outspec.json')
        if not os.path.exists(outspecfile):  #outspec file not found
            raise ValueError('%s not found' % outspecfile)

        #Get name of pkl file
        if isinstance(self.args, dict):
            if 'file' in self.args.keys():
                file = self.args['file']
            else:
                file = self.pickPKL(folder)
        else:
            file = self.pickPKL(folder)
        fullPathPKL = os.path.join(folder, file)  # create full file path
        if not os.path.exists(fullPathPKL):
            raise ValueError('%s not found' % fullPathPKL)

        #Load pkl and outspec files
        try:
            with open(fullPathPKL, 'rb') as f:  #load from cache
                DRM = pickle.load(f, encoding='latin1')
        except:
            vprint('Failed to open fullPathPKL %s' % fullPathPKL)
            pass
        outspecPath = os.path.join(folder, 'outspec.json')
        try:
            with open(outspecPath, 'rb') as g:
                outspec = json.load(g)
        except:
            vprint('Failed to open outspecfile %s' % outspecPath)
            pass

        #Create Simulation Object
        sim = EXOSIMS.MissionSim.MissionSim(scriptfile=None,
                                            nopar=True,
                                            **outspec)
        SS = sim.SurveySimulation
        ZL = SS.ZodiacalLight
        COMP = SS.Completeness
        OS = SS.OpticalSystem
        Obs = SS.Observatory
        TL = SS.TargetList
        TK = SS.TimeKeeping

        plt.close('all')
        plt.figure(2, figsize=(8.5, 6))
        gs = gridspec.GridSpec(2, 2, width_ratios=[6, 1],
                               height_ratios=[1, 4])  #DELETE ,0.3,6,1.25
        gs.update(wspace=0.06, hspace=0.06)  # set the spacing between axes.

        plt.rc('axes', linewidth=2)
        plt.rc('lines', linewidth=2)
        plt.rcParams['axes.linewidth'] = 2
        plt.rc('font', weight='bold')

        #What the plot layout looks like
        ###---------------
        # | gs[0]  gs[1] |
        # | gs[2]  gs[3] |
        ###---------------
        ax0 = plt.subplot(gs[0])  #1D histogram of intTimes
        ax1 = plt.subplot(gs[1])  #BLANK
        ax2 = plt.subplot(gs[2])  #CvsT lines
        ax3 = plt.subplot(gs[3])  #1D histogram of Completeness

        ax1 = plt.subplot(gs[1])  #BLANK
        ax1.xaxis.set_visible(False)
        ax1.yaxis.set_visible(False)

        #IF SurveySimulation module is SLSQPScheduler
        initt0 = None
        comp0 = None
        numObs0 = 0
        fZ = ZL.fZ0
        if 'SLSQPScheduler' in outspec['modules']['SurveySimulation']:
            #Extract Initial det_time and scomp0
            initt0 = sim.SurveySimulation.t0  #These are the optmial times generated by SLSQP
            numObs0 = initt0[initt0.value > 1e-10].shape[0]
            timeConservationCheck = numObs0 * (
                outspec['settlingTime'] +
                outspec['starlightSuppressionSystems'][0]['ohTime'].value
            ) + sum(
                initt0).value  # This assumes a specific instrument for ohTime
            #assert abs(timeConservationCheck-outspec['missionLife']*outspec['missionPortion']*365.25) < 0.1, 'total instrument time not consistent with initial calculation'
            if not abs(timeConservationCheck - outspec['missionLife'] *
                       outspec['missionPortion'] * 365.25) < 0.1:
                vprint(
                    'total instrument time used is not within total allowed time with 0.1d'
                )
            assert abs(
                timeConservationCheck -
                outspec['missionLife'] * outspec['missionPortion'] * 365.25
            ) < 0.5, 'total instrument time not consistent with initial calculation'
            #THIS IS JUST SUMCOMP initscomp0 = sim.SurveySimulation.scomp0

            if 'Izod' in outspec.keys():
                if outspec[
                        'Izod'] == 'fZ0':  # Use fZ0 to calculate integration times
                    vprint('fZ0 in Izod of outspec')
                    pass  # Keep ZL.fZ0... fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
                elif outspec[
                        'Izod'] == 'fZmin':  # Use fZmin to calculate integration times
                    vprint('fZmin in Izod of outspec')
                    fZ = SS.valfZmin
                elif outspec[
                        'Izod'] == 'fZmax':  # Use fZmax to calculate integration times
                    vprint('fZmax in Izod of outspec')
                    fZ = SS.valfZmax
                elif self.Izod == 'current':  # Use current fZ to calculate integration times
                    vprint('current in Izod of outspec')
                    pass  # keep ZL.fZ0.... fZ = self.ZodiacalLight.fZ(self.Observatory, self.TargetList, sInds, self.TimeKeeping.currentTimeAbs.copy()+np.zeros(self.TargetList.nStars)*u.d, self.detmode)

            WA = SS.WAint
            _, Cbs, Csps = OS.Cp_Cb_Csp(TL, np.arange(TL.nStars), fZ, ZL.fEZ0,
                                        25.0, WA, SS.detmode)

            #find baseline solution with dMagLim-based integration times
            #self.vprint('Finding baseline fixed-time optimal target set.')
            # t0 = OS.calc_intTime(TL, range(TL.nStars),
            #         ZL.fZ0, ZL.fEZ0, SS.dMagint, SS.WAint, SS.detmode)
            comp0 = COMP.comp_per_intTime(
                initt0,
                TL,
                np.arange(TL.nStars),
                fZ,
                ZL.fEZ0,
                SS.WAint,
                SS.detmode,
                C_b=Cbs,
                C_sp=Csps)  #Integration time at the initially calculated t0
            sumComp0 = sum(comp0)

            #Plot t0 vs c0
            #scatter(initt0.value, comp0, label='SLSQP $C_0$ ALL')
            ax2.scatter(initt0[initt0.value > 1e-10].value,
                        comp0[initt0.value > 1e-10],
                        label=r'$c_{3,i}$,' + '' + r'$\sum c_{3,i}$' +
                        "=%0.2f" % sumComp0,
                        alpha=0.5,
                        color='red',
                        zorder=2,
                        s=45,
                        marker='s')

            #This is a calculation check to ensure the targets at less than 1e-10 d are trash
            sIndsLT1us = np.arange(TL.nStars)[initt0.value < 1e-10]
            t0LT1us = initt0[initt0.value < 1e-10].value + 0.1
            if len(fZ) == 1:
                tmpfZ = fZ
            else:
                tmpfZ = fZ[sIndsLT1us]
            comp02 = COMP.comp_per_intTime(t0LT1us * u.d,
                                           TL,
                                           sIndsLT1us.tolist(),
                                           tmpfZ,
                                           ZL.fEZ0,
                                           SS.WAint[sIndsLT1us],
                                           SS.detmode,
                                           C_b=Cbs[sIndsLT1us],
                                           C_sp=Csps[sIndsLT1us])

            #Overwrite DRM with DRM just calculated
            res = sim.run_sim()
            DRM['DRM'] = sim.SurveySimulation.DRM
        elif 'starkAYO' in outspec['modules']['SurveySimulation']:
            #TODO
            initt0 = np.zeros(sim.SurveySimulation.TargetList.nStars)
            initt0[sim.SurveySimulation.schedule] = sim.SurveySimulation.t_dets

        #extract mission information from DRM
        arrival_times = [
            DRM['DRM'][i]['arrival_time'].value
            for i in np.arange(len(DRM['DRM']))
        ]
        star_inds = [
            DRM['DRM'][i]['star_ind'] for i in np.arange(len(DRM['DRM']))
        ]
        sumOHTIME = outspec['settlingTime'] + outspec[
            'starlightSuppressionSystems'][0]['ohTime'].value
        raw_det_time = [
            DRM['DRM'][i]['det_time'].value for i in np.arange(len(DRM['DRM']))
        ]  #DOES NOT INCLUDE overhead time
        det_times = [
            DRM['DRM'][i]['det_time'].value + sumOHTIME
            for i in np.arange(len(DRM['DRM']))
        ]  #includes overhead time
        det_timesROUNDED = [
            round(DRM['DRM'][i]['det_time'].value + sumOHTIME, 1)
            for i in np.arange(len(DRM['DRM']))
        ]
        ObsNums = [DRM['DRM'][i]['ObsNum'] for i in np.arange(len(DRM['DRM']))]
        y_vals = np.zeros(len(det_times)).tolist()
        char_times = [
            DRM['DRM'][i]['char_time'].value * (1. + outspec['charMargin']) +
            sumOHTIME for i in np.arange(len(DRM['DRM']))
        ]
        OBdurations = np.asarray(outspec['OBendTimes']) - np.asarray(
            outspec['OBstartTimes'])
        #sumOHTIME = [1 for i in np.arange(len(DRM['DRM']))]
        vprint(sum(det_times))
        vprint(sum(char_times))

        #DIRECT COMPARISON BETWEEN RAW_DET_TIME and initt0
        # print(sum(initt0[initt0.value>0].value))
        # print(sum(np.asarray(raw_det_time)))
        # print(initt0[initt0.value>0].value - np.asarray(raw_det_time))
        # print(np.mean(initt0[initt0.value>0].value - np.asarray(raw_det_time)))

        #Display Text
        #Observations
        #Planned: num
        #Actual: num
        ax1.text(0.1,
                 0.4,
                 'Observations\nPlanned:%s\nActual:%s' %
                 ("{:,}".format(numObs0), "{:,}".format(len(raw_det_time))),
                 weight='bold',
                 horizontalalignment='left',
                 fontsize=8)
        #TXT1.text(0.5, 0.4, '# Universe\nPlanets:\n%s'%("{:,}".format(len(x))), weight='bold', horizontalalignment='center', fontsize=8)
        #TXT1.text(0.5, -0.1, '# Sims\n%s'%("{:,}".format(len(out['Rps']))), weight='bold', horizontalalignment='center', fontsize=8)

        #calculate completeness at the time of each star observation
        slewTimes = np.zeros(len(star_inds))
        fZ_obs = ZL.fZ(Obs, TL, star_inds,
                       TK.missionStart + (arrival_times + slewTimes) * u.d,
                       SS.detmode)
        _, Cb, Csp = OS.Cp_Cb_Csp(TL, star_inds, fZ_obs, ZL.fEZ0, 25.0,
                                  SS.WAint[star_inds], SS.detmode)

        comps = COMP.comp_per_intTime(raw_det_time * u.d,
                                      TL,
                                      star_inds,
                                      fZ_obs,
                                      ZL.fEZ0,
                                      SS.WAint[star_inds],
                                      SS.detmode,
                                      C_b=Cb,
                                      C_sp=Csp)
        sumComps = sum(comps)

        xlims = [10.**-6, 1.1 * max(raw_det_time)]
        ylims = [10.**-6, 1.1 * max(comps)]
        #if not plt.get_fignums(): # there is no figure open
        #    plt.figure()
        ax2.scatter(raw_det_time,
                    comps,
                    label=r'$c_{t_{Obs},i}$,' + '' + r'$\sum c_{t_{Obs},i}$' +
                    "=%0.2f" % sumComps,
                    alpha=0.5,
                    color='blue',
                    zorder=2)
        ax2.set_xlim(xlims)
        ax2.set_ylim(ylims)
        ax2.set_xlabel(r'Integration Time, $t_i$, in (days)', weight='bold')
        ax2.set_ylabel(r'Target Completeness, $c_i$', weight='bold')
        legend_properties = {'weight': 'bold'}
        ax2.legend(prop=legend_properties)
        ax0.set_xlim(xlims)
        ax3.set_ylim(ylims)
        #ax2.set_xscale('log')
        ax0.set_xscale('log')
        ax0.set_xticks([])
        ax3.set_yticks([])
        nullfmt = NullFormatter()
        ax0.xaxis.set_major_formatter(nullfmt)
        ax1.xaxis.set_major_formatter(nullfmt)
        ax1.yaxis.set_major_formatter(nullfmt)
        ax3.yaxis.set_major_formatter(nullfmt)
        ax0.axis('off')
        ax1.axis('off')
        ax3.axis('off')

        #Done plotting Comp vs intTime of Observations
        date = str(datetime.datetime.now())
        date = ''.join(
            c + '_'
            for c in re.split('-|:| ', date)[0:-1])  #Removes seconds from date
        fname = 'C0vsT0andCvsT_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'))
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'))

        #plt.show(block=False)

        ax0.set_ylabel(r'$\frac{{t_i\ Freq.}}{{{}\ Targets}}$'.format(numObs0),
                       weight='bold',
                       multialignment='center')
        ax3.set_xlabel(r'$\frac{{c_i\ Freq.}}{{{}\ Targets}}$'.format(numObs0),
                       weight='bold',
                       multialignment='center')

        #Manually Calculate the difference to veryify all det_times are the same
        tmpdiff = np.asarray(initt0[star_inds]) - np.asarray(raw_det_time)
        vprint(max(tmpdiff))

        vprint(-2.5 * np.log10(ZL.fZ0.value))  # This is 23
        vprint(-2.5 * np.log10(np.mean(fZ).value))

        ###### Plot C vs T Lines
        #self.plotCvsTlines(TL, Obs, TK, OS, SS, ZL, sim, COMP, PPoutpath, folder, date, ax2)
        """ Plots CvsT with Lines
        #From starkAYO_staticSchedule_withPlotting_copy_Feb6_2018.py
        #Lines 1246-1313, 1490-1502
        """
        ax2.set_xscale('log')
        sInds = np.arange(TL.nStars)
        #DELETE mode = filter(lambda mode: mode['detectionMode'] == True, OS.observingModes)[0]
        mode = [
            mode for mode in OS.observingModes if mode['detectionMode'] == True
        ][0]  #assuming first detection mode
        #fZ, fZabsTime = ZL.calcfZmin(sInds, Obs, TL, TK, mode, SS.cachefname)
        fEZ = ZL.fEZ0
        #WA = OS.WA0
        WA = SS.WAint
        dmag = np.linspace(1, COMP.dMagLim, num=1500, endpoint=True)
        Cp = np.zeros([sInds.shape[0], dmag.shape[0]])
        Cb = np.zeros(sInds.shape[0])
        Csp = np.zeros(sInds.shape[0])
        for i in np.arange(dmag.shape[0]):
            Cp[:, i], Cb[:], Csp[:] = OS.Cp_Cb_Csp(TL, sInds, fZ, fEZ, dmag[i],
                                                   WA, mode)
        Cb = Cb[:]  #Cb[:,0]/u.s#note all Cb are the same for different dmags. They are just star dependent
        Csp = Csp[:]  #Csp[:,0]/u.s#note all Csp are the same for different dmags. They are just star dependent
        #self.Cp = Cp[:,:] #This one is dependent upon dmag and each star

        cmap = plt.cm.get_cmap('autumn_r')
        intTimes = np.logspace(
            -6, 3, num=400,
            base=10.0)  #define integration times we will evaluate at
        actualComp = np.zeros([sInds.shape[0], intTimes.shape[0]])
        for j in np.arange(intTimes.shape[0]):
            actualComp[:, j] = COMP.comp_per_intTime(
                (intTimes[j] + np.zeros([sInds.shape[0]])) * u.d, TL, sInds,
                fZ, fEZ, WA, mode, Cb / u.s, Csp / u.s)

        #Plot Top 10 black Lines
        compObs = COMP.comp_per_intTime(initt0, TL, sInds, fZ, fEZ, WA, mode,
                                        Cb / u.s,
                                        Csp / u.s)  #integration time at t0
        compObs2 = np.asarray([gg for gg in compObs if gg > 0.])
        tmpI = np.asarray([gg for gg in sInds if compObs[gg] > 0.
                           ])  #Inds of sInds with positive Complateness
        maxCI = np.argmax(compObs)  # should return ind of max C0
        minCI = tmpI[np.argmin(compObs2)]  # should return ind of min C0
        tmpI2 = np.argsort(compObs)[-10:]
        middleCI = compObs.tolist().index(
            np.percentile(compObs2, 50, interpolation='nearest'))

        for l in np.arange(10):
            ax2.plot(intTimes, actualComp[tmpI2[l], :], color='k', zorder=1)
        ax2.plot(intTimes, actualComp[middleCI, :], color='k', zorder=1)
        ax2.plot(intTimes, actualComp[minCI, :], color='k', zorder=1)
        #plt.show(block=False)
        ###############################

        #ax2.set_xscale('log')
        #plt.rcParams['axes.linewidth']=2
        #plt.rc('font',weight='bold')
        #plt.title('Generic Title I Forgot to Update',weight='bold')
        #plt.xlabel(r'Integration Time, $\tau$ (days)',weight='bold',fontsize=14)
        #plt.ylabel('Completeness',weight='bold',fontsize=14)
        #plt.rc('axes',linewidth=2)
        #plt.rc('lines',linewidth=2)
        #Plot Colorbar
        cmap = plt.cm.get_cmap('autumn_r')

        compatt0 = np.zeros([sInds.shape[0]])
        for j in np.arange(sInds.shape[0]):
            if len(fZ) == 1:
                tmpfZ = fZ
            else:
                tmpfZ = fZ[j]
            compatt0[j] = COMP.comp_per_intTime(initt0[j], TL, sInds[j], tmpfZ,
                                                fEZ, WA[j], mode, Cb[j] / u.s,
                                                Csp[j] / u.s)
        #ax2.scatter(initt0,compatt0,color='k',marker='o',zorder=3,label=r'$C_{i}(\tau_{0})$')
        #plt.show(block=False)

        def plotSpecialPoints(ind, TL, OS, fZ, fEZ, COMP, WA, mode, sim):
            #### Plot Top Performer at dMagLim, max(C/t)
            if not len(fZ) == 1:
                fZ = fZ[ind]
            if not len(WA) == 1:
                WA = WA[ind]
            tCp, tCb, tCsp = OS.Cp_Cb_Csp(TL, ind, fZ, fEZ, COMP.dMagLim, WA,
                                          mode)
            tdMaglim = OS.calc_intTime(TL, ind, fZ, fEZ, COMP.dMagLim, WA,
                                       mode)
            Cdmaglim = COMP.comp_per_intTime(tdMaglim, TL, ind, fZ, fEZ, WA,
                                             mode, tCb[0], tCsp[0])

            #ax2.scatter(tdMaglim,Cdmaglim,marker='x',color='red',zorder=3)
            def objfun(t, TL, tmpI, fZ, fEZ, WA, mode, OS):
                dmag = OS.calc_dMag_per_intTime(
                    t * u.d, TL, tmpI, fZ, fEZ, WA, mode
                )  #We must calculate a different dmag for each integraiton time
                Cp, Cb, Csp = OS.Cp_Cb_Csp(
                    TL, tmpI, fZ, fEZ, dmag, WA,
                    mode)  #We must recalculate Cb and Csp at each dmag
                return -COMP.comp_per_intTime(t * u.d, TL, tmpI, fZ, fEZ, WA,
                                              mode, Cb, Csp) / t

            out = minimize_scalar(
                objfun,
                method='bounded',
                bounds=[0, 10**3.],
                args=(TL, ind, fZ, fEZ, WA, mode, OS)
            )  #, options={'disp': 3, 'xatol':self.ftol, 'maxiter': self.maxiter})
            tMaxCbyT = out['x']
            CtMaxCbyT = COMP.comp_per_intTime(tMaxCbyT * u.d, TL, ind, fZ, fEZ,
                                              WA, mode, tCb[0], tCsp[0])
            #ax2.scatter(tMaxCbyT,CtMaxCbyT,marker='D',color='blue',zorder=3)
            return tdMaglim, Cdmaglim, tMaxCbyT, CtMaxCbyT

        ax2.scatter(10**0.,
                    -1.,
                    marker='o',
                    facecolors='white',
                    edgecolors='black',
                    zorder=3,
                    label=r'$c_{\Delta mag_{lim}}$')
        ax2.scatter(10**0.,
                    -1.,
                    marker='D',
                    color='blue',
                    zorder=3,
                    label=r'Max $c_i/t_i$')
        #plt.show(block=False)

        #tdMaglim, Cdmaglim, tMaxCbyT, CtMaxCbyT = plotSpecialPoints(maxCI, TL, OS, fZ, fEZ, COMP, WA, mode, sim)
        #ax2.scatter(tdMaglim,Cdmaglim,marker='o',facecolors='white', edgecolors='black',zorder=3)
        #ax2.scatter(tMaxCbyT,CtMaxCbyT,marker='D',color='blue',zorder=3)
        for l in np.arange(10):
            tmptdMaglim, tmpCdmaglim, tmptMaxCbyT, tmpCtMaxCbyT = plotSpecialPoints(
                tmpI2[l], TL, OS, fZ, fEZ, COMP, WA, mode, sim)
            ax2.scatter(tmptdMaglim,
                        tmpCdmaglim,
                        marker='o',
                        facecolors='white',
                        edgecolors='black',
                        zorder=3)
            ax2.scatter(tmptMaxCbyT,
                        tmpCtMaxCbyT,
                        marker='D',
                        color='blue',
                        zorder=3)
        tdMaglim, Cdmaglim, tMaxCbyT, CtMaxCbyT = plotSpecialPoints(
            middleCI, TL, OS, fZ, fEZ, COMP, WA, mode, sim)
        ax2.scatter(tdMaglim,
                    Cdmaglim,
                    marker='o',
                    facecolors='white',
                    edgecolors='black',
                    zorder=3)
        ax2.scatter(tMaxCbyT, CtMaxCbyT, marker='D', color='blue', zorder=3)
        tdMaglim, Cdmaglim, tMaxCbyT, CtMaxCbyT = plotSpecialPoints(
            minCI, TL, OS, fZ, fEZ, COMP, WA, mode, sim)
        ax2.scatter(tdMaglim,
                    Cdmaglim,
                    marker='o',
                    facecolors='white',
                    edgecolors='black',
                    zorder=3)
        ax2.scatter(tMaxCbyT, CtMaxCbyT, marker='D', color='blue', zorder=3)
        #plt.show(block=False)

        ax2.plot([1e-5, 1e-5], [0, 0],
                 color='k',
                 label=r'Numerical $c_{i}(t)$',
                 zorder=1)
        ax2.legend(loc=2)
        ax2.set_xlim([1e-6, 10. * max(initt0.value)])
        ax0.set_xlim([1e-6, 10. * max(initt0.value)])
        ax2.set_ylim([1e-6, 1.1 * max(compatt0)])
        ax3.set_ylim([1e-6, 1.1 * max(compatt0)])

        #plt.show(block=False)
        fname = 'CvsTlines_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'))
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'))
        ##################

        #### Plot Axis Histograms
        ax0.axis('on')
        ax3.axis('on')
        #ax0.set_xlim(xlims)
        #ax3.set_ylim(ylims)
        ax0.set_xlim([1e-6, 10. * max(initt0.value)])
        ax3.set_ylim([1e-6, 1.1 * max(compatt0)])
        ax0.set_xscale('log')
        #ax3.set_yscale('log')
        ax0.set_xticks([])
        ax3.set_yticks([])
        nullfmt = NullFormatter()
        ax0.xaxis.set_major_formatter(nullfmt)
        ax1.xaxis.set_major_formatter(nullfmt)
        ax1.yaxis.set_major_formatter(nullfmt)
        ax3.yaxis.set_major_formatter(nullfmt)

        xmin = xlims[0]
        xmax = xlims[1]
        ymin = ylims[0]
        ymax = ylims[1]
        # Make the 'main' temperature plot
        # Define the number of bins
        #Base on number of targets???
        nxbins = 50  # a bins
        nybins = 50  # Rp bins
        nbins = 100
        xbins = np.logspace(start=np.log10(xmin),
                            stop=np.log10(xmax),
                            num=nxbins)
        ybins = np.linspace(start=ymin, stop=ymax, num=nybins)
        xcenter = (xbins[0:-1] + xbins[1:]) / 2.0
        ycenter = (ybins[0:-1] + ybins[1:]) / 2.0
        aspectratio = 1.0 * (xmax - 0) / (1.0 * ymax - 0)

        x = np.asarray(raw_det_time)
        y = comps
        H, xedges, yedges = np.histogram2d(x, y,
                                           bins=(xbins, ybins))  #,normed=True)
        X = xcenter
        Y = ycenter
        Z = H

        n0, bins0, patches0 = plt.subplot(gs[1]).hist(
            x,
            bins=xbins,
            color='black',
            alpha=0.,
            fill='black',
            histtype='step'
        )  #,normed=True)#, hatch='-/')#1D histogram of universe a
        center0 = (bins0[:-1] + bins0[1:]) / 2.
        width0 = np.diff(bins0)
        ax0.bar(center0,
                n0 / float(numObs0),
                align='center',
                width=width0,
                color='black',
                fill='black')

        n3, bins3, patches3 = plt.subplot(gs[1]).hist(
            y,
            bins=ybins,
            color='black',
            alpha=0.,
            fill='black',
            histtype='step'
        )  #,normed=True)#, hatch='-/')#1D histogram of universe a
        center3 = (bins3[:-1] + bins3[1:]) / 2.
        width3 = np.diff(bins3)
        ax3.barh(center3,
                 np.asarray(n3 / float(numObs0)),
                 align='center',
                 height=width3,
                 color='black',
                 fill='black')
        plt.show(block=False)

        fname = 'CvsTlinesAndHists_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'))
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'))

        #self.plotTauHist()
        #self.plotCompHist()
        plt.close('all')  #required before next plotting utility runs

        #### Loading ALIAS FILE ##################################
        #OLD aliasname = 'alias_4_11_2019.pkl'
        aliasname = 'alias_10_07_2019.pkl'
        self.classpath = os.path.split(inspect.getfile(self.__class__))[0]
        vprint(inspect.getfile(self.__class__))
        self.alias_datapath = os.path.join(self.classpath, aliasname)
        #Load pkl and outspec files
        try:
            with open(self.alias_datapath, 'rb') as f:  #load from cache
                alias = pickle.load(f, encoding='latin1')
        except:
            vprint('Failed to open fullPathPKL %s' % self.alias_datapath)
            pass
        ##########################################################

        #TODO DOWNLOAD LIST OF STARS WITH DETECTED EXOPLANETS
        data = self.constructIPACurl()
        starsWithPlanets = self.setOfStarsWithKnownPlanets(data)

        outspec = sim.SurveySimulation.genOutSpec()

        OBdurations = np.asarray(outspec['OBendTimes']) - np.asarray(
            outspec['OBstartTimes'])
        lines = self.writeDATAtoLines(initt0, numObs0, sumOHTIME, raw_det_time, PPoutpath, folder, date, outspec, sim,\
            tmpI, maxCI, minCI, tmpI2, middleCI, comp0, DRM, star_inds, intTimes, actualComp, comps, alias, data, starsWithPlanets)
        self.lines = lines

        #print(saltyburrito)

        #### Save Data File
        fname = 'C0vsT0andCvsTDATA_' + folder.split('/')[-1] + '_' + date
        with open(os.path.join(PPoutpath, fname + '.txt'), 'w') as g:
            g.write("\n".join(lines))
Ejemplo n.º 25
0
 def __init__(self, args=None):
     vprint(args)
     vprint('initialize plotKeepoutMap done')
     pass
Ejemplo n.º 26
0
    def plotTimelineWithOB(self, pklfile='./', outspecfile='./', PPoutpath='./', folder='./'):
        """
        Args:
            pklfile (string) - full path to pkl file
            outspecfile (string) - full path to outspec file
            PPoutpath (string) - full path to output directory of file
        Return:
        """
        #Error check to ensure provided pkl file exists
        assert os.path.isfile(pklfile), '%s not found' %pklfile
        assert os.path.isfile(outspecfile), '%s not found' %outspecfile
        
        pkldir = [pklfile.split('/')[-2]]
        pklfname = pklfile.split('/')[-1].split('.')[0]

        DRM, outspec = self.loadFiles(pklfile, outspecfile)

        arrival_times = [DRM['DRM'][i]['arrival_time'].value for i in np.arange(len(DRM['DRM']))]
        sumOHTIME = outspec['settlingTime'] + outspec['starlightSuppressionSystems'][0]['ohTime']
        det_times = [DRM['DRM'][i]['det_time'].value+sumOHTIME for i in np.arange(len(DRM['DRM']))]
        det_timesROUNDED = [round(DRM['DRM'][i]['det_time'].value+sumOHTIME,1) for i in np.arange(len(DRM['DRM']))]
        ObsNums = [DRM['DRM'][i]['ObsNum'] for i in np.arange(len(DRM['DRM']))]
        y_vals = np.zeros(len(det_times)).tolist()
        char_times = [DRM['DRM'][i]['char_time'].value*(1+outspec['charMargin'])+sumOHTIME*(DRM['DRM'][i]['char_time'].value > 0.) for i in np.arange(len(DRM['DRM']))]
        OBdurations = np.asarray(outspec['OBendTimes'])-np.asarray(outspec['OBstartTimes'])
        #sumOHTIME = [1 for i in np.arange(len(DRM['DRM']))]
        vprint(sum(det_times))
        vprint(sum(char_times))


        #Check if plotting font #########################################################
        tmpfig = plt.figure(figsize=(30,3.5),num=0)
        ax = tmpfig.add_subplot(111)
        t = ax.text(0, 0, "Obs#   ,  d", ha='center',va='center',rotation='vertical', fontsize=8)
        r = tmpfig.canvas.get_renderer()
        bb = t.get_window_extent(renderer=r)
        Obstxtwidth = bb.width#Width of text
        Obstxtheight = bb.height#height of text
        FIGwidth, FIGheight = tmpfig.get_size_inches()*tmpfig.dpi
        plt.show(block=False)
        plt.close()
        daysperpixelapprox = max(arrival_times)/FIGwidth#approximate #days per pixel
        if mean(det_times)*0.8/daysperpixelapprox > Obstxtwidth:
            ObstextBool = True
        else:
            ObstextBool = False

        tmpfig = plt.figure(figsize=(30,3.5),num=0)
        ax = tmpfig.add_subplot(111)
        t = ax.text(0, 0, "OB#  , dur.=    d", ha='center',va='center',rotation='horizontal', fontsize=12)
        r = tmpfig.canvas.get_renderer()
        bb = t.get_window_extent(renderer=r)
        OBtxtwidth = bb.width#Width of text
        OBtxtheight = bb.height#height of text
        FIGwidth, FIGheight = tmpfig.get_size_inches()*tmpfig.dpi
        plt.show(block=False)
        plt.close()
        if mean(OBdurations)*0.8/daysperpixelapprox > OBtxtwidth:
            OBtextBool = True
        else:
            OBtextBool = False
        #################################################################################



        colors = 'rb'#'rgbwmc'
        patch_handles = []
        fig = plt.figure(figsize=(30,3.5),num=0)
        ax = fig.add_subplot(111)

        # Plot All Detection Observations
        ind = 0
        obs = 0
        for (det_time, l, char_time) in zip(det_times, ObsNums, char_times):
            #print det_time, l
            patch_handles.append(ax.barh(0, det_time, align='center', left=arrival_times[ind],
                color=colors[int(obs) % len(colors)]))
            if not char_time == 0.:
                ax.barh(0, char_time, align='center', left=arrival_times[ind]+det_time,color=(0./255.,128/255.,0/255.))
            ind += 1
            obs += 1
            patch = patch_handles[-1][0] 
            bl = patch.get_xy()
            x = 0.5*patch.get_width() + bl[0]
            y = 0.5*patch.get_height() + bl[1]
            self.prettyPlot()
            if ObstextBool: 
                ax.text(x, y, "Obs#%d, %dd" % (l,det_time), ha='center',va='center',rotation='vertical', fontsize=8)

        # Plot Observation Blocks
        patch_handles2 = []
        for (OBnum, OBdur, OBstart) in zip(xrange(len(outspec['OBendTimes'])), OBdurations, np.asarray(outspec['OBstartTimes'])):
            patch_handles2.append(ax.barh(1, OBdur, align='center', left=OBstart, hatch='//',linewidth=2.0, edgecolor='black'))
            patch = patch_handles2[-1][0] 
            bl = patch.get_xy()
            x = 0.5*patch.get_width() + bl[0]
            y = 0.5*patch.get_height() + bl[1]
            if OBtextBool:
                ax.text(x, y, "OB#%d, dur.= %dd" % (OBnum,OBdur), ha='center',va='center',rotation='horizontal',fontsize=12)

        #Set Plot Xlimit so the end of the timeline is at the end of the figure box
        ax.set_xlim([None, outspec['missionLife']*365.25])


        # Plot Asthetics
        y_pos = np.arange(2)#Number of xticks to have

        self.prettyPlot()
        ax.set_yticks(y_pos)
        ax.set_yticklabels(('Obs','OB'),fontsize=12)
        ax.set_xlabel('Current Normalized Time (days)', weight='bold',fontsize=12)
        title('Mission Timeline for runName: ' + pkldir[0] + '\nand pkl file: ' + pklfname, weight='bold',fontsize=12)
        plt.tight_layout()
        plt.show(block=False)

        date = unicode(datetime.datetime.now())
        date = ''.join(c + '_' for c in re.split('-|:| ',date)[0:-1])#Removes seconds from date
        fname = 'Timeline_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath,fname+'.png'))
        plt.savefig(os.path.join(PPoutpath,fname+'.svg'))
        plt.savefig(os.path.join(PPoutpath,fname+'.eps'))
        plt.savefig(os.path.join(PPoutpath,fname+'.pdf'))
Ejemplo n.º 27
0
    def gen_summary_kopparapu(self, folder):
        """
        """
        pklfiles = glob.glob(os.path.join(folder, '*.pkl'))

        out = {
            'fname': [],
            'detected': [],
            #'fullspectra':[],
            #'partspectra':[],
            'Rps': [],
            #'Mps':[],
            #'tottime':[],
            'starinds': [],
            'smas': [],
            #'ps':[],
            'es': [],
            #'WAs':[],
            #'SNRs':[],
            #'fZs':[],
            #'fEZs':[],
            #'allsmas':[],
            #'allRps':[],
            #'allps':[],
            #'alles':[],
            #'allMps':[],
            #'dMags':[],
            #'rs':[]}
        }

        for counter, f in enumerate(pklfiles):
            vprint("%d/%d" % (counter, len(pklfiles)))
            with open(f, 'rb') as g:
                res = pickle.load(g, encoding='latin1')

            out['fname'].append(f)
            dets = np.hstack([
                row['plan_inds'][row['det_status'] == 1] for row in res['DRM']
            ])
            out['detected'].append(dets)  # planet inds

            #out['WAs'].append(np.hstack([row['det_params']['WA'][row['det_status'] == 1].to('arcsec').value for row in res['DRM']]))
            #out['dMags'].append(np.hstack([row['det_params']['dMag'][row['det_status'] == 1] for row in res['DRM']]))
            #out['rs'].append(np.hstack([row['det_params']['d'][row['det_status'] == 1].to('AU').value for row in res['DRM']]))
            #out['fEZs'].append(np.hstack([row['det_params']['fEZ'][row['det_status'] == 1].value for row in res['DRM']]))
            #out['fZs'].append(np.hstack([[row['det_fZ'].value]*len(np.where(row['det_status'] == 1)[0]) for row in res['DRM']]))
            #out['fullspectra'].append(np.hstack([row['plan_inds'][row['char_status'] == 1]  for row in res['DRM']]))
            #out['partspectra'].append(np.hstack([row['plan_inds'][row['char_status'] == -1]  for row in res['DRM']]))
            #out['tottime'].append(np.sum([row['det_time'].value+row['char_time'].value for row in res['DRM']]))
            #out['SNRs'].append(np.hstack([row['det_SNR'][row['det_status'] == 1]  for row in res['DRM']]))
            out['Rps'].append(
                (res['systems']['Rp'][dets] / u.R_earth).decompose().value)
            out['smas'].append(res['systems']['a'][dets].to(u.AU).value)
            #out['ps'].append(res['systems']['p'][dets])
            out['es'].append(res['systems']['e'][dets])
            #out['Mps'].append((res['systems']['Mp'][dets]/u.M_earth).decompose())
            out['starinds'].append(
                np.hstack([[row['star_ind']] *
                           len(np.where(row['det_status'] == 1)[0])
                           for row in res['DRM']]))
            #DELETE out['starinds'].append(np.hstack([row['star_ind'][row['det_status'] == 1] for row in res['DRM']]))

            #if includeUniversePlanetPop == True:
            #  out['allRps'].append((res['systems']['Rp']/u.R_earth).decompose().value)
            #  out['allMps'].append((res['systems']['Mp']/u.M_earth).decompose())
            #  out['allsmas'].append(res['systems']['a'].to(u.AU).value)
            #  out['allps'].append(res['systems']['p'])
            #  out['alles'].append(res['systems']['e'])
            del res

        return out
Ejemplo n.º 28
0
    def singleRunPostProcessing(self, PPoutpath, folder):
        """Generates a single yield histogram for the run_type
        Args:
            PPoutpath (string) - output path to place data in
            folder (string) - full filepath to folder containing runs
        """
        #Get name of pkl file
        if not os.path.exists(folder):
            raise ValueError('%s not found' % folder)
        outspecPath = os.path.join(folder, 'outspec.json')
        try:
            with open(outspecPath, 'rb') as g:
                outspec = json.load(g)
        except:
            vprint('Failed to open outspecfile %s' % outspecPath)
            pass

        #Create Simulation Object
        sim = EXOSIMS.MissionSim.MissionSim(scriptfile=None,
                                            nopar=True,
                                            **outspec)
        SS = sim.SurveySimulation
        ZL = SS.ZodiacalLight
        COMP = SS.Completeness
        OS = SS.OpticalSystem
        Obs = SS.Observatory
        TL = SS.TargetList
        TK = SS.TimeKeeping

        out = self.gen_summary_kopparapu(
            folder)  #out contains information on the detected planets
        self.out = out

        # Put Planets into appropriate bins
        aggbins, earthLikeBins = self.putPlanetsInBoxes(out, TL)
        self.aggbins = aggbins
        self.earthLikeBins = earthLikeBins

        # Plot Data
        figVio = plt.figure(figsize=(8.5, 4.5))
        plt.rc('axes', linewidth=2)
        plt.rc('lines', linewidth=2)
        plt.rcParams['axes.linewidth'] = 2
        plt.rc('font', weight='bold')
        gs1 = gridspec.GridSpec(3, 16, height_ratios=[8, 1,
                                                      1])  #, width_ratios=[1]
        gs1.update(wspace=0.06, hspace=0.2)  # set the spacing between axes.
        ax1 = plt.subplot(gs1[:-2, :])
        figBar = plt.figure(figsize=(8.5, 4.5))
        plt.rc('axes', linewidth=2)
        plt.rc('lines', linewidth=2)
        plt.rcParams['axes.linewidth'] = 2
        plt.rc('font', weight='bold')
        gs2 = gridspec.GridSpec(3, 16, height_ratios=[8, 1,
                                                      1])  #, width_ratios=[1]
        gs2.update(wspace=0.06, hspace=0.2)  # set the spacing between axes.
        ax2 = plt.subplot(gs2[:-2, :])
        ymaxVio = 0
        ymaxBar = 0

        #INSERT VIOLIN PLOT STUFF HERE
        plt.figure(figVio.number)
        parts = ax1.violinplot(dataset=np.transpose(np.asarray(earthLikeBins)),
                               positions=[0],
                               showmeans=False,
                               showmedians=False,
                               showextrema=False,
                               widths=0.75)
        parts['bodies'][0].set_facecolor('green')
        parts['bodies'][0].set_edgecolor('black')
        parts['bodies'][0].set_alpha(1.0)
        ymaxVio = max([ymaxVio, max(earthLikeBins)])
        ax1.scatter([0],
                    np.mean(earthLikeBins),
                    marker='o',
                    color='k',
                    s=30,
                    zorder=3)
        ax1.vlines([0],
                   min(earthLikeBins),
                   max(earthLikeBins),
                   color='k',
                   linestyle='-',
                   lw=2)
        ax1.vlines([0],
                   np.mean(earthLikeBins) - np.std(earthLikeBins),
                   np.mean(earthLikeBins) + np.std(earthLikeBins),
                   color='purple',
                   linestyle='-',
                   lw=5)
        #### Plot Kopparapu Bar Chart
        plt.figure(figBar.number)
        ax2.bar(0, np.mean(earthLikeBins), width=0.8, color='green')
        ax2.scatter([0],
                    np.mean(earthLikeBins),
                    marker='o',
                    color='k',
                    s=30,
                    zorder=3)
        ax2.vlines([0],
                   min(earthLikeBins),
                   max(earthLikeBins),
                   color='k',
                   linestyle='-',
                   lw=2)
        ax2.vlines([0],
                   np.mean(earthLikeBins) - np.std(earthLikeBins),
                   np.mean(earthLikeBins) + np.std(earthLikeBins),
                   color='purple',
                   linestyle='-',
                   lw=5)
        ymaxBar = max([ymaxBar, max(earthLikeBins)])

        ### Calculate Stats of Bins
        binMeans = np.zeros((5, 3))  # planet type, planet temperature
        binUpperQ = np.zeros((5, 3))  # planet type, planet temperature
        binLowerQ = np.zeros((5, 3))  # planet type, planet temperature
        fifthPercentile = np.zeros((5, 3))  # planet type, planet temperature
        twentyfifthPercentile = np.zeros(
            (5, 3))  # planet type, planet temperature
        fiftiethPercentile = np.zeros(
            (5, 3))  # planet type, planet temperature
        seventyfifthPercentile = np.zeros(
            (5, 3))  # planet type, planet temperature
        ninetiethPercentile = np.zeros(
            (5, 3))  # planet type, planet temperature
        nintyfifthPercentile = np.zeros(
            (5, 3))  # planet type, planet temperature
        minNumDetected = np.zeros((5, 3))  # planet type, planet temperature
        percentAtMinimum = np.zeros((5, 3))  # planet type, planet temperature
        maxNumDetected = np.zeros((5, 3))  # planet type, planet temperature
        #                HOT,  WARM,        COLD
        colorViolins = ['red', 'royalblue', 'skyblue']
        for i in np.arange(len(self.Rp_hi)):  # iterate over Rp sizes
            for j in np.arange(len(self.L_hi[0])):  # iterate over Luminosities
                # Create array of bin counts for this specific bin type
                counts = np.asarray([
                    aggbins[k][i][j] for k in np.arange(len(out['detected']))
                ])  # create array of counts
                binMeans[i][j] = np.mean(counts)
                binUpperQ[i][j] = np.mean(counts) + np.std(counts)
                binLowerQ[i][j] = np.mean(counts) - np.std(counts)
                #stdUniqueDetections[i][j].append(np.std(el))
                fifthPercentile[i][j] = np.percentile(counts, 5)
                twentyfifthPercentile[i][j] = np.percentile(counts, 25)
                fiftiethPercentile[i][j] = np.percentile(counts, 50)
                seventyfifthPercentile[i][j] = np.percentile(counts, 75)
                ninetiethPercentile[i][j] = np.percentile(counts, 90)
                nintyfifthPercentile[i][j] = np.percentile(counts, 95)
                minNumDetected[i][j] = min(counts)
                percentAtMinimum[i][j] = float(counts.tolist().count(
                    min(counts))) / len(counts)
                maxNumDetected[i][j] = max(counts)
                fiftiethPercentile[i][j] = np.percentile(counts, 50)
                seventyfifthPercentile[i][j] = np.percentile(counts, 75)

                #INSERT VIOLIN PLOT STUFF HERE
                plt.figure(figVio.number)
                parts = ax1.violinplot(dataset=np.transpose(
                    np.asarray(counts)),
                                       positions=[3 * i + j + 1],
                                       showmeans=False,
                                       showmedians=False,
                                       showextrema=False,
                                       widths=0.75)
                parts['bodies'][0].set_facecolor(colorViolins[j])
                parts['bodies'][0].set_edgecolor('black')
                parts['bodies'][0].set_alpha(1.0)
                ymaxVio = max([ymaxVio, max(counts)])
                ax1.scatter([3 * i + j + 1],
                            binMeans[i][j],
                            marker='o',
                            color='k',
                            s=30,
                            zorder=3)
                ax1.vlines([3 * i + j + 1],
                           min(counts),
                           max(counts),
                           color='k',
                           linestyle='-',
                           lw=2)
                ax1.vlines([3 * i + j + 1],
                           twentyfifthPercentile[i][j],
                           seventyfifthPercentile[i][j],
                           color='purple',
                           linestyle='-',
                           lw=5)
                #### Plot Kopparapu Bar Chart
                plt.figure(figBar.number)
                ax2.bar(3 * i + j + 1,
                        binMeans[i][j],
                        width=0.8,
                        color=colorViolins[j])
                ymaxBar = max([ymaxBar, max(counts)])
                ax2.scatter([3 * i + j + 1],
                            binMeans[i][j],
                            marker='o',
                            color='k',
                            s=30,
                            zorder=3)
                ax2.vlines([3 * i + j + 1],
                           min(counts),
                           max(counts),
                           color='k',
                           linestyle='-',
                           lw=2)
                ax2.vlines([3 * i + j + 1],
                           twentyfifthPercentile[i][j],
                           seventyfifthPercentile[i][j],
                           color='purple',
                           linestyle='-',
                           lw=5)

        #Limits Touch Up and Labels
        plt.figure(figVio.number)
        #axes = ax1.gca()
        ax1.set_ylim([0, 1.05 * np.amax(ymaxVio)])
        ax1.set_xticks(
            ticks=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
        ax1.set_xticklabels(
            ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''))
        #ax1.set_xticklabels(('','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold'))
        #ax1.tick_params(axis='x',labelrotation=60)
        ax1.set_ylabel('Unique Detection Yield', weight='bold', fontsize=12)
        plt.figure(figBar.number)
        #axes2 = ax2.gca()
        ax2.set_ylim([0, 1.05 * np.amax(ymaxBar)])
        ax2.set_xticks(
            ticks=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
        ax2.set_xticklabels(
            ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''))
        #ax2.set_xticklabels(('','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold'))
        #ax2.tick_params(axis='x',labelrotation=60)
        ax2.set_ylabel('Unique Detection Yield', weight='bold', fontsize=12)

        #Add Hot Warm Cold Labels
        plt.figure(figVio.number)
        axHC = plt.subplot(
            gs1[-2, :])  # subplot for Plant classification Labels
        ht = 0.9
        xstart = 0.1
        Labels = ['Hot', 'Warm', 'Cold']
        for i in np.arange(5):
            axHC.text(xstart + np.float(i) * 0.175 + 0.,
                      ht,
                      'Hot',
                      weight='bold',
                      rotation=60,
                      fontsize=12,
                      color=colorViolins[0])
            axHC.text(xstart + np.float(i) * 0.175 + 0.04,
                      ht,
                      'Warm',
                      weight='bold',
                      rotation=60,
                      fontsize=12,
                      color=colorViolins[1])
            axHC.text(xstart + np.float(i) * 0.175 + 0.11,
                      ht,
                      'Cold',
                      weight='bold',
                      rotation=60,
                      fontsize=12,
                      color=colorViolins[2])
        axHC.axis('off')
        plt.figure(figBar.number)
        axHC2 = plt.subplot(
            gs2[-2, :])  # subplot for Plant classification Labels
        for i in np.arange(5):
            axHC2.text(xstart + np.float(i) * 0.175 + 0.,
                       ht,
                       'Hot',
                       weight='bold',
                       rotation=60,
                       fontsize=12,
                       color=colorViolins[0])
            axHC2.text(xstart + np.float(i) * 0.175 + 0.04,
                       ht,
                       'Warm',
                       weight='bold',
                       rotation=60,
                       fontsize=12,
                       color=colorViolins[1])
            axHC2.text(xstart + np.float(i) * 0.175 + 0.11,
                       ht,
                       'Cold',
                       weight='bold',
                       rotation=60,
                       fontsize=12,
                       color=colorViolins[2])
        axHC2.axis('off')

        #Add Planet Type Labels
        #ax1
        plt.figure(figVio.number)
        axEarthLike = plt.subplot(
            gs1[-1, 0])  # subplot for Plant classification Labels
        axEarthLike.text(0.8,
                         0.3,
                         'Earth-\nLike',
                         weight='bold',
                         horizontalalignment='center',
                         fontsize=12)
        axEarthLike.axis('off')
        axRocky = plt.subplot(
            gs1[-1, 1:3])  # subplot for Plant classification Labels
        axRocky.text(0.9,
                     0.2,
                     'Rocky',
                     weight='bold',
                     horizontalalignment='center',
                     fontsize=12)
        axRocky.axis('off')
        axSEarth = plt.subplot(
            gs1[-1, 4:6])  # subplot for Plant classification Labels
        axSEarth.text(0.7,
                      0.1,
                      'Super\nEarth',
                      weight='bold',
                      horizontalalignment='center',
                      fontsize=12)
        axSEarth.axis('off')
        axSNept = plt.subplot(
            gs1[-1, 7:9])  # subplot for Plant classification Labels
        axSNept.text(0.85,
                     0.1,
                     'Sub-\nNeptune',
                     weight='bold',
                     horizontalalignment='center',
                     fontsize=12)
        axSNept.axis('off')
        axSJov = plt.subplot(
            gs1[-1, 10:12])  # subplot for Plant classification Labels
        axSJov.text(0.7,
                    0.1,
                    'Sub-\nJovian',
                    weight='bold',
                    horizontalalignment='center',
                    fontsize=12)
        axSJov.axis('off')
        axJov = plt.subplot(
            gs1[-1, 13:15])  # subplot for Plant classification Labels
        axJov.text(0.5,
                   0.3,
                   'Jovian',
                   weight='bold',
                   horizontalalignment='center',
                   fontsize=12)
        axJov.axis('off')
        #ax2
        plt.figure(figBar.number)
        axEarthLike = plt.subplot(
            gs2[-1, 0])  # subplot for Plant classification Labels
        axEarthLike.text(0.8,
                         0.3,
                         'Earth-\nLike',
                         weight='bold',
                         horizontalalignment='center',
                         fontsize=12)
        axEarthLike.axis('off')
        axRocky = plt.subplot(
            gs2[-1, 1:3])  # subplot for Plant classification Labels
        axRocky.text(0.9,
                     0.2,
                     'Rocky',
                     weight='bold',
                     horizontalalignment='center',
                     fontsize=12)
        axRocky.axis('off')
        axSEarth = plt.subplot(
            gs2[-1, 4:6])  # subplot for Plant classification Labels
        axSEarth.text(0.7,
                      0.1,
                      'Super\nEarth',
                      weight='bold',
                      horizontalalignment='center',
                      fontsize=12)
        axSEarth.axis('off')
        axSNept = plt.subplot(
            gs2[-1, 7:9])  # subplot for Plant classification Labels
        axSNept.text(0.85,
                     0.1,
                     'Sub-\nNeptune',
                     weight='bold',
                     horizontalalignment='center',
                     fontsize=12)
        axSNept.axis('off')
        axSJov = plt.subplot(
            gs2[-1, 10:12])  # subplot for Plant classification Labels
        axSJov.text(0.7,
                    0.1,
                    'Sub-\nJovian',
                    weight='bold',
                    horizontalalignment='center',
                    fontsize=12)
        axSJov.axis('off')
        axJov = plt.subplot(
            gs2[-1, 13:15])  # subplot for Plant classification Labels
        axJov.text(0.5,
                   0.3,
                   'Jovian',
                   weight='bold',
                   horizontalalignment='center',
                   fontsize=12)
        axJov.axis('off')

        plt.show(block=False)
        self.aggbins = aggbins

        #Save Plots
        # Save to a File
        date = str(datetime.datetime.now())
        date = ''.join(
            c + '_'
            for c in re.split('-|:| ', date)[0:-1])  #Removes seconds from date

        plt.figure(figBar.number)
        fname = 'KopparapuBar_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'),
                    format='png',
                    dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.eps'),
                    format='eps',
                    dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'),
                    format='pdf',
                    dpi=500)
        plt.figure(figVio.number)
        fname = 'KopparapuVio_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'),
                    format='png',
                    dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.eps'),
                    format='eps',
                    dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'),
                    format='pdf',
                    dpi=500)

        ###########################################################################
        #### Save Bins to File
        lines = []
        lines.append(
            '#################################################################################'
        )
        lines.append(
            'Rp_Lo: 0.90 , Rp_hi: 1.4 , L_lo: 0.3586 , L_hi: 1.1080 , Planet Type: EarthLike'
        )
        #planet type, planet temperature
        lines.append('   mean: ' + str(np.mean(earthLikeBins)))
        lines.append('   upper STD: ' +
                     str(np.mean(earthLikeBins) + np.std(earthLikeBins)))
        lines.append('   lower STD: ' +
                     str(np.mean(earthLikeBins) - np.std(earthLikeBins)))
        lines.append('   5th percentile: ' +
                     str(np.percentile(earthLikeBins, 5)))
        lines.append('   25th percentile: ' +
                     str(np.percentile(earthLikeBins, 25)))
        lines.append('   50th percentile: ' +
                     str(np.percentile(earthLikeBins, 50)))
        lines.append('   75th percentile: ' +
                     str(np.percentile(earthLikeBins, 75)))
        lines.append('   90th percentile: ' +
                     str(np.percentile(earthLikeBins, 90)))
        lines.append('   95th percentile: ' +
                     str(np.percentile(earthLikeBins, 95)))
        lines.append('   min #: ' + str(min(earthLikeBins)))
        lines.append('   \% at min percentile: ' + str(
            float(earthLikeBins.count(min(earthLikeBins))) /
            len(earthLikeBins)))
        lines.append('   max #: ' + str(max(earthLikeBins)))
        lines.append('   50th percentile: ' +
                     str(np.percentile(earthLikeBins, 50)))
        lines.append('   75th percentile: ' +
                     str(np.percentile(earthLikeBins, 75)))

        #### Plotting Types
        pTypesLabels = [
            'Rocky', 'Super Earth', 'Sub-Neptune', 'Sub-Jovian', 'Jovian'
        ]
        for i in np.arange(len(self.Rp_hi)):  # iterate over Rp sizes
            for j in np.arange(len(self.L_hi[0])):  # iterate over Luminosities
                lines.append(
                    '#################################################################################'
                )
                lines.append('Rp_Lo: ' + str(self.Rp_lo[i]) + ' , Rp_hi: ' + str(self.Rp_hi[i]) + \
                        ' , L_lo: ' + str(self.L_lo[i][j]) + ' , L_hi: ' + str(self.L_hi[i][j]) + \
                        ' , Planet Type: ' + pTypesLabels[i] + ' , Temperatures: ' + Labels[j])
                #planet type, planet temperature
                lines.append('   mean: ' + str(binMeans[i][j]))
                lines.append('   upper STD: ' + str(binUpperQ[i][j]))
                lines.append('   lower STD: ' + str(binLowerQ[i][j]))
                lines.append('   5th percentile: ' +
                             str(fifthPercentile[i][j]))
                lines.append('   25th percentile: ' +
                             str(twentyfifthPercentile[i][j]))
                lines.append('   50th percentile: ' +
                             str(fiftiethPercentile[i][j]))
                lines.append('   75th percentile: ' +
                             str(seventyfifthPercentile[i][j]))
                lines.append('   90th percentile: ' +
                             str(ninetiethPercentile[i][j]))
                lines.append('   95th percentile: ' +
                             str(nintyfifthPercentile[i][j]))
                lines.append('   min #: ' + str(minNumDetected[i][j]))
                lines.append('   \% at min percentile: ' +
                             str(percentAtMinimum[i][j]))
                lines.append('   max #: ' + str(maxNumDetected[i][j]))
                lines.append('   50th percentile: ' +
                             str(fiftiethPercentile[i][j]))
                lines.append('   75th percentile: ' +
                             str(seventyfifthPercentile[i][j]))

        fname = 'KopparapuDATA_' + folder.split('/')[-1] + '_' + date
        with open(os.path.join(PPoutpath, fname + '.txt'), 'w') as g:
            g.write("\n".join(lines))
Ejemplo n.º 29
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
Ejemplo n.º 30
0
    def __init__(self, **specs):

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

        return
Ejemplo n.º 31
0
    def __init__(self,
                 missionStart=60634,
                 staticStars=True,
                 keepStarCatalog=False,
                 fillPhotometry=False,
                 explainFiltering=False,
                 **specs):

        # 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."
        self.staticStars = bool(staticStars)
        self.keepStarCatalog = bool(keepStarCatalog)
        self.fillPhotometry = bool(fillPhotometry)
        self.explainFiltering = bool(explainFiltering)

        # populate outspec
        for att in self.__dict__.keys():
            if att not in ['vprint']:
                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 specs.has_key('completeness_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
        if not 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)
            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]
Ejemplo n.º 32
0
    def gen_summary_kopparapu(self,folder):
        """
        """
        pklfiles = glob.glob(os.path.join(folder,'*.pkl'))

        out = {'fname':[],
               'detected':[],
               #'fullspectra':[],
               #'partspectra':[],
               'Rps':[],
               #'Mps':[],
               #'tottime':[],
               'starinds':[],
               'smas':[],
               #'ps':[],
               #'es':[],
               #'WAs':[],
               #'SNRs':[],
               #'fZs':[],
               #'fEZs':[],
               #'allsmas':[],
               #'allRps':[],
               #'allps':[],
               #'alles':[],
               #'allMps':[],
               #'dMags':[],
               #'rs':[]}
               }

        for counter,f in enumerate(pklfiles):
            vprint("%d/%d"%(counter,len(pklfiles)))
            with open(f, 'rb') as g:
                res = pickle.load(g)

            out['fname'].append(f)
            dets = np.hstack([row['plan_inds'][row['det_status'] == 1]  for row in res['DRM']])
            out['detected'].append(dets) # planet inds

            #out['WAs'].append(np.hstack([row['det_params']['WA'][row['det_status'] == 1].to('arcsec').value for row in res['DRM']]))
            #out['dMags'].append(np.hstack([row['det_params']['dMag'][row['det_status'] == 1] for row in res['DRM']]))
            #out['rs'].append(np.hstack([row['det_params']['d'][row['det_status'] == 1].to('AU').value for row in res['DRM']]))
            #out['fEZs'].append(np.hstack([row['det_params']['fEZ'][row['det_status'] == 1].value for row in res['DRM']]))
            #out['fZs'].append(np.hstack([[row['det_fZ'].value]*len(np.where(row['det_status'] == 1)[0]) for row in res['DRM']]))
            #out['fullspectra'].append(np.hstack([row['plan_inds'][row['char_status'] == 1]  for row in res['DRM']]))
            #out['partspectra'].append(np.hstack([row['plan_inds'][row['char_status'] == -1]  for row in res['DRM']]))
            #out['tottime'].append(np.sum([row['det_time'].value+row['char_time'].value for row in res['DRM']]))
            #out['SNRs'].append(np.hstack([row['det_SNR'][row['det_status'] == 1]  for row in res['DRM']]))
            out['Rps'].append((res['systems']['Rp'][dets]/u.R_earth).decompose().value)
            out['smas'].append(res['systems']['a'][dets].to(u.AU).value)
            #out['ps'].append(res['systems']['p'][dets])
            #out['es'].append(res['systems']['e'][dets])
            #out['Mps'].append((res['systems']['Mp'][dets]/u.M_earth).decompose())
            out['starinds'].append(np.hstack([[row['star_ind']]*len(np.where(row['det_status'] == 1)[0]) for row in res['DRM']]))
            #DELETE out['starinds'].append(np.hstack([row['star_ind'][row['det_status'] == 1] for row in res['DRM']]))

            #if includeUniversePlanetPop == True:
            #  out['allRps'].append((res['systems']['Rp']/u.R_earth).decompose().value)
            #  out['allMps'].append((res['systems']['Mp']/u.M_earth).decompose())
            #  out['allsmas'].append(res['systems']['a'].to(u.AU).value)
            #  out['allps'].append(res['systems']['p'])
            #  out['alles'].append(res['systems']['e'])
            del res
            
        return out
Ejemplo n.º 33
0
 def __init__(self, args=None):
     vprint(args)
     self.args = args
     vprint('plotTimeline Initialization done')
     pass
Ejemplo n.º 34
0
    def singleRunPostProcessing(self, PPoutpath, folder):
        """Generates a single yield histogram for the run_type
        Args:
            PPoutpath (string) - output path to place data in
            folder (string) - full filepath to folder containing runs
        """
        #Get name of pkl file
        if not os.path.exists(folder):
            raise ValueError('%s not found'%folder)
        outspecPath = os.path.join(folder,'outspec.json')
        try:
            with open(outspecPath, 'rb') as g:
                outspec = json.load(g)
        except:
            vprint('Failed to open outspecfile %s'%outspecPath)
            pass

        #Create Simulation Object
        sim = EXOSIMS.MissionSim.MissionSim(scriptfile=None, nopar=True, **outspec)
        SS = sim.SurveySimulation
        ZL = SS.ZodiacalLight
        COMP = SS.Completeness
        OS = SS.OpticalSystem
        Obs = SS.Observatory
        TL = SS.TargetList
        TK = SS.TimeKeeping

        out = self.gen_summary_kopparapu(folder)#out contains information on the detected planets
        self.out = out

        # Put Planets into appropriate bins
        aggbins, earthLikeBins = self.putPlanetsInBoxes(out,TL)
        self.aggbins = aggbins
        self.earthLikeBins = earthLikeBins

        # Plot Data
        figVio = plt.figure(figsize=(8.5,4.5))
        plt.rc('axes',linewidth=2)
        plt.rc('lines',linewidth=2)
        plt.rcParams['axes.linewidth']=2
        plt.rc('font',weight='bold')
        gs1 = gridspec.GridSpec(3,16, height_ratios=[8,1,1])#, width_ratios=[1]
        gs1.update(wspace=0.06, hspace=0.2) # set the spacing between axes. 
        ax1 = plt.subplot(gs1[:-2,:])
        figBar = plt.figure(figsize=(8.5,4.5))
        plt.rc('axes',linewidth=2)
        plt.rc('lines',linewidth=2)
        plt.rcParams['axes.linewidth']=2
        plt.rc('font',weight='bold')
        gs2 = gridspec.GridSpec(3,16, height_ratios=[8,1,1])#, width_ratios=[1]
        gs2.update(wspace=0.06, hspace=0.2) # set the spacing between axes. 
        ax2 = plt.subplot(gs2[:-2,:])
        ymaxVio = 0
        ymaxBar = 0

        #INSERT VIOLIN PLOT STUFF HERE
        plt.figure(figVio.number)
        parts = ax1.violinplot(dataset=np.transpose(np.asarray(earthLikeBins)), positions=[0], showmeans=False, showmedians=False, showextrema=False, widths=0.75)
        parts['bodies'][0].set_facecolor('green')
        parts['bodies'][0].set_edgecolor('black')
        parts['bodies'][0].set_alpha(1.0)
        ymaxVio = max([ymaxVio,max(earthLikeBins)])
        ax1.scatter([0], np.mean(earthLikeBins), marker='o', color='k', s=30, zorder=3)
        ax1.vlines([0], min(earthLikeBins), max(earthLikeBins), color='k', linestyle='-', lw=2)
        ax1.vlines([0], np.mean(earthLikeBins)-np.std(earthLikeBins), np.mean(earthLikeBins)+np.std(earthLikeBins), color='purple', linestyle='-', lw=5)
        #### Plot Kopparapu Bar Chart
        plt.figure(figBar.number)
        ax2.bar(0,np.mean(earthLikeBins),width=0.8,color='green')
        ax2.scatter([0], np.mean(earthLikeBins), marker='o', color='k', s=30, zorder=3)
        ax2.vlines([0], min(earthLikeBins), max(earthLikeBins), color='k', linestyle='-', lw=2)
        ax2.vlines([0], np.mean(earthLikeBins)-np.std(earthLikeBins), np.mean(earthLikeBins)+np.std(earthLikeBins), color='purple', linestyle='-', lw=5)
        ymaxBar = max([ymaxBar,max(earthLikeBins)])


        ### Calculate Stats of Bins
        binMeans = np.zeros((5,3)) # planet type, planet temperature
        binUpperQ = np.zeros((5,3)) # planet type, planet temperature
        binLowerQ = np.zeros((5,3)) # planet type, planet temperature
        fifthPercentile = np.zeros((5,3)) # planet type, planet temperature
        twentyfifthPercentile = np.zeros((5,3)) # planet type, planet temperature
        fiftiethPercentile = np.zeros((5,3)) # planet type, planet temperature
        seventyfifthPercentile = np.zeros((5,3)) # planet type, planet temperature
        ninetiethPercentile = np.zeros((5,3)) # planet type, planet temperature
        nintyfifthPercentile = np.zeros((5,3)) # planet type, planet temperature
        minNumDetected = np.zeros((5,3)) # planet type, planet temperature
        percentAtMinimum = np.zeros((5,3)) # planet type, planet temperature
        maxNumDetected = np.zeros((5,3)) # planet type, planet temperature
        #                HOT,  WARM,        COLD
        colorViolins = ['red','royalblue','skyblue']
        for i in np.arange(len(self.Rp_hi)): # iterate over Rp sizes
            for j in np.arange(len(self.L_hi[0])): # iterate over Luminosities
                # Create array of bin counts for this specific bin type
                counts = np.asarray([aggbins[k][i][j] for k in np.arange(len(out['detected']))]) # create array of counts
                binMeans[i][j] = np.mean(counts)
                binUpperQ[i][j] = np.mean(counts) + np.std(counts)
                binLowerQ[i][j] = np.mean(counts) - np.std(counts)
                #stdUniqueDetections[i][j].append(np.std(el))
                fifthPercentile[i][j] = np.percentile(counts,5)
                twentyfifthPercentile[i][j] = np.percentile(counts,25)
                fiftiethPercentile[i][j] = np.percentile(counts,50)
                seventyfifthPercentile[i][j] = np.percentile(counts,75)
                ninetiethPercentile[i][j] = np.percentile(counts,90)
                nintyfifthPercentile[i][j] = np.percentile(counts,95)
                minNumDetected[i][j] = min(counts)
                percentAtMinimum[i][j] = float(counts.tolist().count(min(counts)))/len(counts)
                maxNumDetected[i][j] = max(counts)
                fiftiethPercentile[i][j] = np.percentile(counts,50)
                seventyfifthPercentile[i][j] = np.percentile(counts,75)


                #INSERT VIOLIN PLOT STUFF HERE
                plt.figure(figVio.number)
                parts = ax1.violinplot(dataset=np.transpose(np.asarray(counts)), positions=[3*i+j+1], showmeans=False, showmedians=False, showextrema=False, widths=0.75)
                parts['bodies'][0].set_facecolor(colorViolins[j])
                parts['bodies'][0].set_edgecolor('black')
                parts['bodies'][0].set_alpha(1.0)
                ymaxVio = max([ymaxVio,max(counts)])
                ax1.scatter([3*i+j+1], binMeans[i][j], marker='o', color='k', s=30, zorder=3)
                ax1.vlines([3*i+j+1], min(counts), max(counts), color='k', linestyle='-', lw=2)
                ax1.vlines([3*i+j+1], twentyfifthPercentile[i][j], seventyfifthPercentile[i][j], color='purple', linestyle='-', lw=5)
                #### Plot Kopparapu Bar Chart
                plt.figure(figBar.number)
                ax2.bar(3*i+j+1,binMeans[i][j],width=0.8,color=colorViolins[j])
                ymaxBar = max([ymaxBar,max(counts)])
                ax2.scatter([3*i+j+1], binMeans[i][j], marker='o', color='k', s=30, zorder=3)
                ax2.vlines([3*i+j+1], min(counts), max(counts), color='k', linestyle='-', lw=2)
                ax2.vlines([3*i+j+1], twentyfifthPercentile[i][j], seventyfifthPercentile[i][j], color='purple', linestyle='-', lw=5)

        #Limits Touch Up and Labels
        plt.figure(figVio.number)
        #axes = ax1.gca()
        ax1.set_ylim([0,1.05*np.amax(ymaxVio)])
        ax1.set_xticks(ticks=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
        ax1.set_xticklabels(('','','','','','','','','','','','','','','',''))
        #ax1.set_xticklabels(('','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold'))
        #ax1.tick_params(axis='x',labelrotation=60)
        ax1.set_ylabel('Unique Detection Yield',weight='bold',fontsize=12)
        plt.figure(figBar.number)
        #axes2 = ax2.gca()
        ax2.set_ylim([0,1.05*np.amax(ymaxBar)])
        ax2.set_xticks(ticks=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
        ax2.set_xticklabels(('','','','','','','','','','','','','','','',''))
        #ax2.set_xticklabels(('','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold','Hot','Warm','Cold'))
        #ax2.tick_params(axis='x',labelrotation=60)
        ax2.set_ylabel('Unique Detection Yield',weight='bold',fontsize=12)
        
        #Add Hot Warm Cold Labels
        plt.figure(figVio.number)
        axHC = plt.subplot(gs1[-2,:]) # subplot for Plant classification Labels
        ht = 0.9
        xstart = 0.1
        Labels = ['Hot','Warm','Cold']
        for i in np.arange(5):
            axHC.text(xstart+np.float(i)*0.175+0., ht, 'Hot', weight='bold', rotation=60, fontsize=12, color=colorViolins[0])
            axHC.text(xstart+np.float(i)*0.175+0.04, ht, 'Warm', weight='bold', rotation=60, fontsize=12, color=colorViolins[1])
            axHC.text(xstart+np.float(i)*0.175+0.11, ht, 'Cold', weight='bold', rotation=60, fontsize=12, color=colorViolins[2])
        axHC.axis('off')
        plt.figure(figBar.number)
        axHC2 = plt.subplot(gs2[-2,:]) # subplot for Plant classification Labels
        for i in np.arange(5):
            axHC2.text(xstart+np.float(i)*0.175+0., ht, 'Hot', weight='bold', rotation=60, fontsize=12, color=colorViolins[0])
            axHC2.text(xstart+np.float(i)*0.175+0.04, ht, 'Warm', weight='bold', rotation=60, fontsize=12, color=colorViolins[1])
            axHC2.text(xstart+np.float(i)*0.175+0.11, ht, 'Cold', weight='bold', rotation=60, fontsize=12, color=colorViolins[2])
        axHC2.axis('off')

        #Add Planet Type Labels
        #ax1
        plt.figure(figVio.number)
        axEarthLike = plt.subplot(gs1[-1,0]) # subplot for Plant classification Labels
        axEarthLike.text(0.8, 0.3, 'Earth-\nLike', weight='bold', horizontalalignment='center', fontsize=12)
        axEarthLike.axis('off')
        axRocky = plt.subplot(gs1[-1,1:3]) # subplot for Plant classification Labels
        axRocky.text(0.9, 0.2, 'Rocky', weight='bold', horizontalalignment='center', fontsize=12)
        axRocky.axis('off')
        axSEarth = plt.subplot(gs1[-1,4:6]) # subplot for Plant classification Labels
        axSEarth.text(0.7, 0.1, 'Super\nEarth', weight='bold', horizontalalignment='center', fontsize=12)
        axSEarth.axis('off')
        axSNept = plt.subplot(gs1[-1,7:9]) # subplot for Plant classification Labels
        axSNept.text(0.85, 0.1, 'Sub-\nNeptune', weight='bold', horizontalalignment='center', fontsize=12)
        axSNept.axis('off')
        axSJov = plt.subplot(gs1[-1,10:12]) # subplot for Plant classification Labels
        axSJov.text(0.7, 0.1, 'Sub-\nJovian', weight='bold', horizontalalignment='center', fontsize=12)
        axSJov.axis('off')
        axJov = plt.subplot(gs1[-1,13:15]) # subplot for Plant classification Labels
        axJov.text(0.5, 0.3, 'Jovian', weight='bold', horizontalalignment='center', fontsize=12)
        axJov.axis('off')
        #ax2
        plt.figure(figBar.number)
        axEarthLike = plt.subplot(gs2[-1,0]) # subplot for Plant classification Labels
        axEarthLike.text(0.8, 0.3, 'Earth-\nLike', weight='bold', horizontalalignment='center', fontsize=12)
        axEarthLike.axis('off')
        axRocky = plt.subplot(gs2[-1,1:3]) # subplot for Plant classification Labels
        axRocky.text(0.9, 0.2, 'Rocky', weight='bold', horizontalalignment='center', fontsize=12)
        axRocky.axis('off')
        axSEarth = plt.subplot(gs2[-1,4:6]) # subplot for Plant classification Labels
        axSEarth.text(0.7, 0.1, 'Super\nEarth', weight='bold', horizontalalignment='center', fontsize=12)
        axSEarth.axis('off')
        axSNept = plt.subplot(gs2[-1,7:9]) # subplot for Plant classification Labels
        axSNept.text(0.85, 0.1, 'Sub-\nNeptune', weight='bold', horizontalalignment='center', fontsize=12)
        axSNept.axis('off')
        axSJov = plt.subplot(gs2[-1,10:12]) # subplot for Plant classification Labels
        axSJov.text(0.7, 0.1, 'Sub-\nJovian', weight='bold', horizontalalignment='center', fontsize=12)
        axSJov.axis('off')
        axJov = plt.subplot(gs2[-1,13:15]) # subplot for Plant classification Labels
        axJov.text(0.5, 0.3, 'Jovian', weight='bold', horizontalalignment='center', fontsize=12)
        axJov.axis('off')


        plt.show(block=False)
        self.aggbins = aggbins

        #Save Plots
        # Save to a File
        date = unicode(datetime.datetime.now())
        date = ''.join(c + '_' for c in re.split('-|:| ',date)[0:-1])#Removes seconds from date

        plt.figure(figBar.number)
        fname = 'KopparapuBar_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'), format='png', dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.eps'), format='eps', dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'), format='pdf', dpi=500)
        plt.figure(figVio.number)
        fname = 'KopparapuVio_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'), format='png', dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.eps'), format='eps', dpi=500)
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'), format='pdf', dpi=500)

        ###########################################################################
        #### Save Bins to File
        lines = []
        lines.append('#################################################################################')
        lines.append('Rp_Lo: 0.90 , Rp_hi: 1.4 , L_lo: 0.3586 , L_hi: 1.1080 , Planet Type: EarthLike')
        #planet type, planet temperature
        lines.append('   mean: ' + str(np.mean(earthLikeBins)))
        lines.append('   upper STD: ' + str(np.mean(earthLikeBins)+np.std(earthLikeBins)))
        lines.append('   lower STD: ' + str(np.mean(earthLikeBins)-np.std(earthLikeBins)))
        lines.append('   5th percentile: ' + str(np.percentile(earthLikeBins,5)))
        lines.append('   25th percentile: ' + str(np.percentile(earthLikeBins,25)))
        lines.append('   50th percentile: ' + str(np.percentile(earthLikeBins,50)))
        lines.append('   75th percentile: ' + str(np.percentile(earthLikeBins,75)))
        lines.append('   90th percentile: ' + str(np.percentile(earthLikeBins,90)))
        lines.append('   95th percentile: ' + str(np.percentile(earthLikeBins,95)))
        lines.append('   min #: ' + str(min(earthLikeBins)))
        lines.append('   \% at min percentile: ' + str(float(earthLikeBins.count(min(earthLikeBins)))/len(earthLikeBins)))
        lines.append('   max #: ' + str(max(earthLikeBins)))
        lines.append('   50th percentile: ' + str(np.percentile(earthLikeBins,50)))
        lines.append('   75th percentile: ' + str(np.percentile(earthLikeBins,75)))

        #### Plotting Types
        pTypesLabels = ['Rocky','Super Earth','Sub-Neptune','Sub-Jovian','Jovian']
        for i in np.arange(len(self.Rp_hi)): # iterate over Rp sizes
            for j in np.arange(len(self.L_hi[0])): # iterate over Luminosities
                lines.append('#################################################################################')
                lines.append('Rp_Lo: ' + str(self.Rp_lo[i]) + ' , Rp_hi: ' + str(self.Rp_hi[i]) + \
                        ' , L_lo: ' + str(self.L_lo[i][j]) + ' , L_hi: ' + str(self.L_hi[i][j]) + \
                        ' , Planet Type: ' + pTypesLabels[i] + ' , Temperatures: ' + Labels[j])
                #planet type, planet temperature
                lines.append('   mean: ' + str(binMeans[i][j]))
                lines.append('   upper STD: ' + str(binUpperQ[i][j]))
                lines.append('   lower STD: ' + str(binLowerQ[i][j]))
                lines.append('   5th percentile: ' + str(fifthPercentile[i][j]))
                lines.append('   25th percentile: ' + str(twentyfifthPercentile[i][j]))
                lines.append('   50th percentile: ' + str(fiftiethPercentile[i][j]))
                lines.append('   75th percentile: ' + str(seventyfifthPercentile[i][j]))
                lines.append('   90th percentile: ' + str(ninetiethPercentile[i][j]))
                lines.append('   95th percentile: ' + str(nintyfifthPercentile[i][j]))
                lines.append('   min #: ' + str(minNumDetected[i][j]))
                lines.append('   \% at min percentile: ' + str(percentAtMinimum[i][j]))
                lines.append('   max #: ' + str(maxNumDetected[i][j]))
                lines.append('   50th percentile: ' + str(fiftiethPercentile[i][j]))
                lines.append('   75th percentile: ' + str(seventyfifthPercentile[i][j]))

        fname = 'KopparapuDATA_' + folder.split('/')[-1] + '_' + date
        with open(os.path.join(PPoutpath, fname + '.txt'), 'w') as g:
            g.write("\n".join(lines))
Ejemplo n.º 35
0
    def recurse(self,
                json1,
                json2,
                pretty_print=False,
                recurse_level=0,
                outtext=""):
        """
        This function iterates recursively through the JSON structures of the script file
        and the simulation outspec, checking them against one another. Outputs the following 
        warnings:

        WARNING 1: Catches parameters that are never used in the sim or are not in the outspec
        WARNING 2: Catches parameters that are unspecified in the script file and notes default value used
        WARNING 3: Catches mismatches in the modules being imported
        WARNING 4: Catches cases where the value in the script file does not match the value in the outspec

        Args:
            json1 (dict):
                The scriptfile json input.
            json2 (dict):
                The outspec json input
            pretty_print (boolean):
                Write output to a single return string rather than sequentially
            recurse_level (int):
                The current level of recursion
            outtext (string):
                The concatinated output text
        Returns:
            outtext (string):
                The concatinated output text
        """

        unused = np.setdiff1d(list(json1), list(json2))
        unspecified = np.setdiff1d(list(json2), list(json1))
        both_use = np.intersect1d(list(json1), list(json2))
        text_buffer = "  " * recurse_level

        # Check for unused fields
        for spec in unused:
            out = text_buffer + "WARNING 1: {} is not used in simulation".format(
                spec)
            if pretty_print:
                vprint(out)
            outtext += out + '\n'

        # Check for unspecified specs
        for spec in unspecified:
            out = text_buffer + "WARNING 2: {} is unspecified in script, using default value: {}".format(
                spec, json2[spec])
            if pretty_print:
                vprint(out)
            outtext += out + '\n'

        # Loop through full json structure
        for jkey in both_use:
            items = json1[jkey]
            # Check if there is more depth to JSON
            if jkey == 'modules':
                out = "NOTE: Moving down a level from key: {}".format(jkey)
                if pretty_print:
                    vprint(out)
                outtext += out + '\n'
                for mkey in json2[jkey]:
                    if json1[jkey][mkey] != json2[jkey][mkey] and json1[jkey][
                            mkey] != " " and json1[jkey][mkey] != "":
                        out = "  WARNING 3: module {} from script file does not match module {} "\
                              "from simulation".format([json1[jkey][mkey]], [json2[jkey][mkey]])
                        if pretty_print:
                            vprint(out)
                        outtext += out + '\n'
                    elif json1[jkey][mkey] == " " or json1[jkey][mkey] == "":
                        out = "  NOTE: Script file does not specify module, using default: {}".format(
                            [json2[jkey][mkey]])
                        if pretty_print:
                            vprint(out)
                        outtext += out + '\n'
            elif type(json1[jkey]) == type({}) and type(json2[jkey]) == type(
                {}):
                if "name" in json1[jkey]:
                    out = "NOTE: Moving down a level from key: {} to ".format(
                        jkey, json1[jkey]["name"])
                else:
                    out = "NOTE: Moving down a level from key: {}".format(jkey)
                if pretty_print:
                    vprint(out)
                outtext += out + '\n'
                outtext = self.recurse(json1[jkey],
                                       json2[jkey],
                                       pretty_print=pretty_print,
                                       recurse_level=recurse_level + 1,
                                       outtext=outtext)
            else:
                try:
                    for i in range(len(items)):
                        if json1[jkey][i] != json2[jkey][i]:
                            if type(json1[jkey][i]) == type({}) and type(
                                    json2[jkey][i]) == type({}):
                                if "name" in json1[jkey][i]:
                                    out = "NOTE: Moving down a level from key: {} to {}".format(
                                        jkey, json1[jkey][i]["name"])
                                else:
                                    out = "NOTE: Moving down a level from key: {}".format(
                                        jkey)
                                if pretty_print:
                                    vprint(out)
                                outtext += out + '\n'
                                outtext = self.recurse(
                                    json1[jkey][i],
                                    json2[jkey][i],
                                    pretty_print=pretty_print,
                                    recurse_level=recurse_level + 1,
                                    outtext=outtext)
                            else:
                                out = text_buffer + "WARNING 4: {} in script file does not match spec in simulation:"\
                                      " (Script {}:{}, Simulation {}:{})".format(jkey, jkey, json1[jkey], jkey, json2[jkey])
                                if pretty_print:
                                    vprint(out)
                                outtext += out + '\n'
                # Make sure script file matches with sim
                except TypeError:
                    if json1[jkey] != json2[jkey]:
                        out = text_buffer + "WARNING 4: {} in script file does not match spec in simulation: "\
                              "(Script {}:{}, Simulation {}:{})".format(jkey, jkey, json1[jkey], jkey, json2[jkey])
                        if pretty_print:
                            vprint(out)
                        outtext += out + '\n'
        return (outtext)
Ejemplo n.º 36
0
    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]
Ejemplo n.º 37
0
if not os.path.exists(folder):  #Folder must exist
    raise ValueError('%s not found' % folder)
allres = read_all(
    folder
)  # contains all drm from all missions in folder. Length of number of pkl files in folder

#### Generate Ensemble Wide Properties
# For each parameter P, gather min, mean, and max
P = ['']

outspecPath = os.path.join(folder, 'outspec.json')
try:
    with open(outspecPath, 'rb') as g:
        outspec = json.load(g)
except:
    vprint('Failed to open outspecfile %s' % outspecPath)
    pass
#Create Simulation Object
sim = EXOSIMS.MissionSim.MissionSim(scriptfile=None, nopar=True, **outspec)
SS = sim.SurveySimulation
ZL = SS.ZodiacalLight
COMP = SS.Completeness
OS = SS.OpticalSystem
Obs = SS.Observatory
TL = SS.TargetList
TK = SS.TimeKeeping
totOH = Obs.settlingTime.value + OS.observingModes[0]['syst']['ohTime'].value

data = list()
for i in [0]:  #np.arange(len(allres)):
    #allres[i]['systems'] # contains all information relating to planets and stars
Ejemplo n.º 38
0
    def plotTimelineWithOB(self,
                           pklfile='./',
                           outspecfile='./',
                           PPoutpath='./',
                           folder='./'):
        """
        Args:
            pklfile (string) - full path to pkl file
            outspecfile (string) - full path to outspec file
            PPoutpath (string) - full path to output directory of file
        Return:
        """
        #Error check to ensure provided pkl file exists
        assert os.path.isfile(pklfile), '%s not found' % pklfile
        assert os.path.isfile(outspecfile), '%s not found' % outspecfile

        pkldir = [pklfile.split('/')[-2]]
        pklfname = pklfile.split('/')[-1].split('.')[0]

        DRM, outspec = self.loadFiles(pklfile, outspecfile)

        arrival_times = [
            DRM['DRM'][i]['arrival_time'].value
            for i in np.arange(len(DRM['DRM']))
        ]
        sumOHTIME = outspec['settlingTime'] + outspec[
            'starlightSuppressionSystems'][0]['ohTime']
        det_times = [
            DRM['DRM'][i]['det_time'].value + sumOHTIME
            for i in np.arange(len(DRM['DRM']))
        ]
        det_timesROUNDED = [
            round(DRM['DRM'][i]['det_time'].value + sumOHTIME, 1)
            for i in np.arange(len(DRM['DRM']))
        ]
        ObsNums = [DRM['DRM'][i]['ObsNum'] for i in np.arange(len(DRM['DRM']))]
        y_vals = np.zeros(len(det_times)).tolist()
        char_times = [
            DRM['DRM'][i]['char_time'].value * (1 + outspec['charMargin']) +
            sumOHTIME * (DRM['DRM'][i]['char_time'].value > 0.)
            for i in np.arange(len(DRM['DRM']))
        ]
        OBdurations = np.asarray(outspec['OBendTimes']) - np.asarray(
            outspec['OBstartTimes'])
        #sumOHTIME = [1 for i in np.arange(len(DRM['DRM']))]
        vprint(sum(det_times))
        vprint(sum(char_times))

        #Check if plotting font #########################################################
        tmpfig = plt.figure(figsize=(30, 3.5), num=0)
        ax = tmpfig.add_subplot(111)
        t = ax.text(0,
                    0,
                    "Obs#   ,  d",
                    ha='center',
                    va='center',
                    rotation='vertical',
                    fontsize=8)
        r = tmpfig.canvas.get_renderer()
        bb = t.get_window_extent(renderer=r)
        Obstxtwidth = bb.width  #Width of text
        Obstxtheight = bb.height  #height of text
        FIGwidth, FIGheight = tmpfig.get_size_inches() * tmpfig.dpi
        plt.show(block=False)
        plt.close()
        daysperpixelapprox = max(
            arrival_times) / FIGwidth  #approximate #days per pixel
        if mean(det_times) * 0.8 / daysperpixelapprox > Obstxtwidth:
            ObstextBool = True
        else:
            ObstextBool = False

        tmpfig = plt.figure(figsize=(30, 3.5), num=0)
        ax = tmpfig.add_subplot(111)
        t = ax.text(0,
                    0,
                    "OB#  , dur.=    d",
                    ha='center',
                    va='center',
                    rotation='horizontal',
                    fontsize=12)
        r = tmpfig.canvas.get_renderer()
        bb = t.get_window_extent(renderer=r)
        OBtxtwidth = bb.width  #Width of text
        OBtxtheight = bb.height  #height of text
        FIGwidth, FIGheight = tmpfig.get_size_inches() * tmpfig.dpi
        plt.show(block=False)
        plt.close()
        if mean(OBdurations) * 0.8 / daysperpixelapprox > OBtxtwidth:
            OBtextBool = True
        else:
            OBtextBool = False
        #################################################################################

        colors = 'rb'  #'rgbwmc'
        patch_handles = []
        fig = plt.figure(figsize=(30, 3.5), num=0)
        ax = fig.add_subplot(111)

        # Plot All Detection Observations
        ind = 0
        obs = 0
        for (det_time, l, char_time) in zip(det_times, ObsNums, char_times):
            #print det_time, l
            patch_handles.append(
                ax.barh(0,
                        det_time,
                        align='center',
                        left=arrival_times[ind],
                        color=colors[int(obs) % len(colors)]))
            if not char_time == 0.:
                ax.barh(0,
                        char_time,
                        align='center',
                        left=arrival_times[ind] + det_time,
                        color=(0. / 255., 128 / 255., 0 / 255.))
            ind += 1
            obs += 1
            patch = patch_handles[-1][0]
            bl = patch.get_xy()
            x = 0.5 * patch.get_width() + bl[0]
            y = 0.5 * patch.get_height() + bl[1]
            self.prettyPlot()
            if ObstextBool:
                ax.text(x,
                        y,
                        "Obs#%d, %dd" % (l, det_time),
                        ha='center',
                        va='center',
                        rotation='vertical',
                        fontsize=8)

        # Plot Observation Blocks
        patch_handles2 = []
        for (OBnum, OBdur,
             OBstart) in zip(xrange(len(outspec['OBendTimes'])), OBdurations,
                             np.asarray(outspec['OBstartTimes'])):
            patch_handles2.append(
                ax.barh(1,
                        OBdur,
                        align='center',
                        left=OBstart,
                        hatch='//',
                        linewidth=2.0,
                        edgecolor='black'))
            patch = patch_handles2[-1][0]
            bl = patch.get_xy()
            x = 0.5 * patch.get_width() + bl[0]
            y = 0.5 * patch.get_height() + bl[1]
            if OBtextBool:
                ax.text(x,
                        y,
                        "OB#%d, dur.= %dd" % (OBnum, OBdur),
                        ha='center',
                        va='center',
                        rotation='horizontal',
                        fontsize=12)

        #Set Plot Xlimit so the end of the timeline is at the end of the figure box
        ax.set_xlim([None, outspec['missionLife'] * 365.25])

        # Plot Asthetics
        y_pos = np.arange(2)  #Number of xticks to have

        self.prettyPlot()
        ax.set_yticks(y_pos)
        ax.set_yticklabels(('Obs', 'OB'), fontsize=12)
        ax.set_xlabel('Current Normalized Time (days)',
                      weight='bold',
                      fontsize=12)
        title('Mission Timeline for runName: ' + pkldir[0] +
              '\nand pkl file: ' + pklfname,
              weight='bold',
              fontsize=12)
        plt.tight_layout()
        plt.show(block=False)

        date = unicode(datetime.datetime.now())
        date = ''.join(
            c + '_'
            for c in re.split('-|:| ', date)[0:-1])  #Removes seconds from date
        fname = 'Timeline_' + folder.split('/')[-1] + '_' + date
        plt.savefig(os.path.join(PPoutpath, fname + '.png'))
        plt.savefig(os.path.join(PPoutpath, fname + '.svg'))
        plt.savefig(os.path.join(PPoutpath, fname + '.eps'))
        plt.savefig(os.path.join(PPoutpath, fname + '.pdf'))
Ejemplo n.º 39
0
 def __init__(self, args=None):
     vprint(args)
     vprint('initialize plotKeepoutMap done')
     pass
Ejemplo n.º 40
0
    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)
Ejemplo n.º 41
0
 def __init__(self, args=None):
     vprint(args)
     vprint('plotConvergencevsNumberofRuns done')
     pass
Ejemplo n.º 42
0
    def __init__(self, scriptfile=None, nopar=False, verbose=True, **specs):
        """Initializes all modules from a given script file or specs dictionary.
        
        Args: 
            scriptfile (string):
                Path to JSON script file. If not set, assumes that 
                dictionary has been passed through specs.
            specs (dictionary):
                Dictionary containing additional user specification values and 
                desired module names.
            nopar (boolean):
                If True, ignore any provided ensemble module in the script or specs
                and force the prototype ensemble.
            verbose (boolean):
                Boolean used to create the vprint function, equivalent to the 
                python print function with an extra verbose toggle parameter.
            
        """
        
        # extend given specs with (JSON) script file
        if scriptfile is not None:
            assert os.path.isfile(scriptfile), "%s is not a file."%scriptfile
            try:
                with open(scriptfile ,'r') as ff:
                    script = ff.read()
                specs_from_file = json.loads(script)
                specs_from_file.update(specs)
            except ValueError as err:
                print("Error: %s: Input file `%s' improperly formatted."%(self._modtype,
                        scriptfile))
                print("Error: JSON error was: %s"%err)
                # re-raise here to suppress the rest of the backtrace.
                # it is only confusing details about the bowels of json.loads()
                raise ValueError(err)
            except:
                print("Error: %s: %s"%(self._modtype, sys.exc_info()[0]))
                raise
        else:
            specs_from_file = {}
        specs.update(specs_from_file)
        
        if 'modules' not in specs:
            raise ValueError("No modules field found in script.")
        
        # set up the verbose level
        self.verbose = bool(verbose)
        specs['verbose'] = self.verbose
        # load the vprint function (same line in all prototype module constructors)
        self.vprint = vprint(specs.get('verbose', True))

        # overwrite any ensemble setting if nopar is set
        if nopar:
            self.vprint('No-parallel: resetting SurveyEnsemble to Prototype')
            specs['modules']['SurveyEnsemble'] = ' '

        #save a copy of specs up to this point to use with the survey ensemble later
        specs0 = copy.deepcopy(specs)

        # start logging, with log file and logging level (default: INFO)
        self.logfile = specs.get('logfile', None)
        self.loglevel = specs.get('loglevel', 'INFO').upper()
        specs['logger'] = self.get_logger(self.logfile, self.loglevel)
        specs['logger'].info('Start Logging: loglevel = %s'%specs['logger'].level \
                + ' (%s)'%self.loglevel)
        
        # populate outspec
        for att in self.__dict__:
            if att not in ['vprint']:
                self._outspec[att] = self.__dict__[att]

        #create a surveysimulation object (triggering init of everything else)
        self.SurveySimulation = get_module(specs['modules']['SurveySimulation'],
                'SurveySimulation')(**specs)
        
        # collect sub-initializations
        SS = self.SurveySimulation
        self.StarCatalog = SS.StarCatalog
        self.PlanetPopulation = SS.PlanetPopulation
        self.PlanetPhysicalModel = SS.PlanetPhysicalModel
        self.OpticalSystem = SS.OpticalSystem
        self.ZodiacalLight = SS.ZodiacalLight
        self.BackgroundSources = SS.BackgroundSources
        self.PostProcessing = SS.PostProcessing
        self.Completeness = SS.Completeness
        self.TargetList = SS.TargetList
        self.SimulatedUniverse = SS.SimulatedUniverse
        self.Observatory = SS.Observatory
        self.TimeKeeping = SS.TimeKeeping
        
        #now that everything has successfully built, you can create the ensemble
        self.SurveyEnsemble = get_module(specs['modules']['SurveyEnsemble'],
                'SurveyEnsemble')(**specs0)

        # create a dictionary of all modules, except StarCatalog
        self.modules = SS.modules
        self.modules['SurveyEnsemble'] = self.SurveyEnsemble

        # alias SurveySimulation random seed to attribute for easier access
        self.seed = self.SurveySimulation.seed        
Ejemplo n.º 43
0
    def recurse(self, json1, json2, pretty_print=False, recurse_level=0, outtext=""):
        """
        This function iterates recursively through the JSON structures of the script file
        and the simulation outspec, checking them against one another. Outputs the following 
        warnings:

        WARNING 1: Catches parameters that are never used in the sim or are not in the outspec
        WARNING 2: Catches parameters that are unspecified in the script file and notes default value used
        WARNING 3: Catches mismatches in the modules being imported
        WARNING 4: Catches cases where the value in the script file does not match the value in the outspec

        Args:
            json1 (dict):
                The scriptfile json input.
            json2 (dict):
                The outspec json input
            pretty_print (boolean):
                Write output to a single return string rather than sequentially
            recurse_level (int):
                The current level of recursion
            outtext (string):
                The concatinated output text
        Returns:
            outtext (string):
                The concatinated output text
        """

        unused = np.setdiff1d(list(json1), list(json2))
        unspecified = np.setdiff1d(list(json2), list(json1))
        both_use = np.intersect1d(list(json1), list(json2))
        text_buffer = "  " * recurse_level

        # Check for unused fields
        for spec in unused:
            out = text_buffer + "WARNING 1: {} is not used in simulation".format(spec)
            if pretty_print:
                vprint(out)
            outtext += out + '\n'

        # Check for unspecified specs
        for spec in unspecified:
            out = text_buffer + "WARNING 2: {} is unspecified in script, using default value: {}".format(spec, json2[spec])
            if pretty_print:
                vprint(out)
            outtext += out + '\n'

        # Loop through full json structure
        for jkey in both_use:
            items = json1[jkey]
            # Check if there is more depth to JSON
            if jkey == 'modules':
                out = "NOTE: Moving down a level from key: {}".format(jkey)
                if pretty_print:
                    vprint(out)
                outtext += out + '\n'
                for mkey in json2[jkey]:
                    if json1[jkey][mkey] != json2[jkey][mkey] and json1[jkey][mkey] != " " and json1[jkey][mkey] != "":
                        out = "  WARNING 3: module {} from script file does not match module {} "\
                              "from simulation".format([json1[jkey][mkey]], [json2[jkey][mkey]])
                        if pretty_print:
                            vprint(out)
                        outtext += out + '\n'
                    elif json1[jkey][mkey] == " " or json1[jkey][mkey] == "":
                        out = "  NOTE: Script file does not specify module, using default: {}".format([json2[jkey][mkey]])
                        if pretty_print:
                            vprint(out)
                        outtext += out + '\n'
            elif type(json1[jkey]) == type({}) and type(json2[jkey]) == type({}):
                if "name" in json1[jkey]:
                    out = "NOTE: Moving down a level from key: {} to ".format(jkey, json1[jkey]["name"])
                else:
                    out = "NOTE: Moving down a level from key: {}".format(jkey)
                if pretty_print:
                    vprint(out)
                outtext += out + '\n'
                outtext = self.recurse(json1[jkey], json2[jkey], pretty_print=pretty_print, recurse_level=recurse_level + 1, outtext=outtext)
            else:
                try:
                    for i in range(len(items)):
                        if json1[jkey][i] != json2[jkey][i]:
                            if type(json1[jkey][i]) == type({}) and type(json2[jkey][i]) == type({}):
                                if "name" in json1[jkey][i]:
                                    out = "NOTE: Moving down a level from key: {} to {}".format(jkey, json1[jkey][i]["name"])
                                else:
                                    out = "NOTE: Moving down a level from key: {}".format(jkey)
                                if pretty_print:
                                    vprint(out)
                                outtext += out + '\n'
                                outtext = self.recurse(json1[jkey][i], json2[jkey][i], pretty_print=pretty_print, recurse_level=recurse_level + 1, outtext=outtext)
                            else:
                                out = text_buffer + "WARNING 4: {} in script file does not match spec in simulation:"\
                                      " (Script {}:{}, Simulation {}:{})".format(jkey, jkey, json1[jkey], jkey, json2[jkey])
                                if pretty_print:
                                    vprint(out)
                                outtext += out + '\n'
                # Make sure script file matches with sim
                except TypeError:
                    if json1[jkey] != json2[jkey]:
                        out = text_buffer + "WARNING 4: {} in script file does not match spec in simulation: "\
                              "(Script {}:{}, Simulation {}:{})".format(jkey, jkey, json1[jkey], jkey, json2[jkey])
                        if pretty_print:
                            vprint(out)
                        outtext += out + '\n'
        return(outtext)
Ejemplo n.º 44
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()
Ejemplo n.º 45
0
    def __init__(self,
                 missionStart=60634,
                 missionLife=0.1,
                 extendedLife=0,
                 missionPortion=1,
                 OBduration=np.inf,
                 waitTime=1,
                 waitMultiple=2,
                 **specs):

        # 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
        assert extendedLife >= 0, "Need extendedLife >= 0, got %f" % extendedLife
        # 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

        # 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')
        self.missionLife = float(missionLife) * u.year
        self.extendedLife = float(extendedLife) * u.year
        self.missionPortion = float(missionPortion)

        # set values derived from quantities above
        self.missionFinishNorm = self.missionLife.to(
            'day') + self.extendedLife.to('day')
        self.missionFinishAbs = self.missionStart + self.missionLife + self.extendedLife

        # initialize values updated by functions
        self.currentTimeNorm = 0. * u.day
        self.currentTimeAbs = self.missionStart

        # initialize observing block times arrays
        self.OBnumber = 0
        self.OBduration = float(OBduration) * u.day
        self.OBstartTimes = [0.] * u.day
        maxOBduration = self.missionFinishNorm * self.missionPortion
        self.OBendTimes = [
            min(self.OBduration, maxOBduration).to('day').value
        ] * u.day

        # initialize single observation START and END times
        self.obsStart = 0. * u.day
        self.obsEnd = 0. * u.day

        # initialize wait parameters
        self.waitTime = float(waitTime) * u.day
        self.waitMultiple = float(waitMultiple)

        # populate outspec
        for att in self.__dict__.keys():
            if att not in ['vprint']:
                dat = self.__dict__[att]
                self._outspec[att] = dat.value if isinstance(
                    dat, (u.Quantity, Time)) else dat
Ejemplo n.º 46
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)
Ejemplo n.º 47
0
 def __init__(self, args=None):
     vprint(args)
     vprint('fakeMultiRunAnalysis done')
     pass