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
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()
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
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
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()
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))
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
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)
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 = {}
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 = {}
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
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
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
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
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
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
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
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)
def __init__(self, args=None): vprint(args) vprint('fakeMultiRunAnalysis done') pass
def __init__(self, args=None): vprint(args) vprint('plotConvergencevsNumberofRuns done') pass
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
def __init__(self, args=None): vprint(args) self.args = args vprint('plotTimeline Initialization done') pass
def __init__(self, args=None): vprint(args) vprint('plotCompletenessJointPDFs done') pass
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))
def __init__(self, args=None): vprint(args) vprint('initialize plotKeepoutMap done') pass
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'))
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
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))
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
def __init__(self, **specs): # load the vprint function (same line in all prototype module constructors) self.vprint = vprint(specs.get('verbose', True)) return
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]
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
def __init__(self, args=None): vprint(args) self.args = args vprint('plotTimeline Initialization done') pass
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))
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)
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]
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
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'))
def __init__(self, args=None): vprint(args) vprint('initialize plotKeepoutMap done') pass
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)
def __init__(self, args=None): vprint(args) vprint('plotConvergencevsNumberofRuns done') pass
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
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)
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()
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
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)
def __init__(self, args=None): vprint(args) vprint('fakeMultiRunAnalysis done') pass