def __init__(self, coeffs=[1,1,1,1,2,1], revisit_wait=91.25, **specs):
        
        SurveySimulation.__init__(self, **specs)
        TL = self.TargetList
        
        #verify that coefficients input is iterable 6x1
        if not(isinstance(coeffs,(list,tuple,np.ndarray))) or (len(coeffs) != 6):
            raise TypeError("coeffs must be a 6 element iterable")

        #Add to outspec
        self._outspec['coeffs'] = coeffs
        self._outspec['revisit_wait'] = revisit_wait
        
        # normalize coefficients
        coeffs = np.array(coeffs)
        coeffs = coeffs/np.linalg.norm(coeffs, ord=1)
        
        self.coeffs = coeffs

        self.revisit_wait = revisit_wait*u.d

        self.earth_candidates = []   # list of detected earth-like planets aroung promoted stars
        self.no_dets = np.ones(self.TargetList.nStars, dtype=bool)
        self.known_stars, self.known_rocky = self.find_known_plans()
        TL.comp0[self.known_rocky] = 1.0
Exemple #2
0
    def __init__(self, **specs):

        SurveySimulation.__init__(self, **specs)

        OS = self.OpticalSystem
        SU = self.SimulatedUniverse

        allModes = OS.observingModes
        num_char_modes = len(list(filter(lambda mode: 'spec' in mode['inst']['name'], allModes)))
        self.fullSpectra = np.zeros((num_char_modes, SU.nPlans), dtype=int)
        self.partialSpectra = np.zeros((num_char_modes, SU.nPlans), dtype=int)
 def __init__(self, occHIPs=[], **specs):
     SurveySimulation.__init__(self, **specs)
     self._outspec['occHIPs'] = occHIPs
     
     if occHIPs != []:
         occHIPs_path = os.path.join(EXOSIMS.__path__[0],'Scripts',occHIPs)
         assert os.path.isfile(occHIPs_path), "%s is not a file."%occHIPs_path
         HIPsfile = open(occHIPs_path, 'r').read()
         self.occHIPs = HIPsfile.split(',')
         if len(self.occHIPs) <= 1:
             self.occHIPs = HIPsfile.split('\n')
     else:
         self.occHIPs = occHIPs
Exemple #4
0
 def __init__(self, coeffs=[1,0,0,0], **specs):
     
     SurveySimulation.__init__(self, **specs)
     
     #verify that coefficients input is iterable 6x1
     if not(isinstance(coeffs,(list,tuple,np.ndarray))) or (len(coeffs) != 4):
         raise TypeError("coeffs must be a 3 element iterable")
     
     #normalize coefficients
     coeffs = np.array(coeffs)
     coeffs = coeffs/np.linalg.norm(coeffs)
     
     self.coeffs = coeffs
Exemple #5
0
    def __init__(self, coeffs=[1, 1, 2, 1], revisit_wait=91.25, **specs):

        SurveySimulation.__init__(self, **specs)

        #verify that coefficients input is iterable 4x1
        if not (isinstance(coeffs,
                           (list, tuple, np.ndarray))) or (len(coeffs) != 4):
            raise TypeError("coeffs must be a 4 element iterable")

        #Add to outspec
        self._outspec['coeffs'] = coeffs
        self._outspec['revisit_wait'] = revisit_wait

        # normalize coefficients
        coeffs = np.array(coeffs)
        coeffs = coeffs / np.linalg.norm(coeffs)

        self.coeffs = coeffs

        self.revisit_wait = revisit_wait * u.d
        self.no_dets = np.ones(self.TargetList.nStars, dtype=bool)
    def __init__(self, coeffs=[1,1,2,1], revisit_wait=91.25, **specs):
        
        SurveySimulation.__init__(self, **specs)
        
        #verify that coefficients input is iterable 4x1
        if not(isinstance(coeffs,(list,tuple,np.ndarray))) or (len(coeffs) != 4):
            raise TypeError("coeffs must be a 4 element iterable")


        #Add to outspec
        self._outspec['coeffs'] = coeffs
        self._outspec['revisit_wait'] = revisit_wait
        
        # normalize coefficients
        coeffs = np.array(coeffs)
        coeffs = coeffs/np.linalg.norm(coeffs)
        
        self.coeffs = coeffs

        self.revisit_wait = revisit_wait*u.d
        self.no_dets = np.ones(self.TargetList.nStars, dtype=bool)
Exemple #7
0
 def __init__(self, **specs):
     
     # call prototype constructor
     SurveySimulation.__init__(self, **specs)
     
     TL = self.TargetList
     SU = self.SimulatedUniverse
     
     # reinitialize working angles and delta magnitudes used for integration
     self.WAint = np.zeros(TL.nStars)*u.arcsec
     self.dMagint = np.zeros(TL.nStars)
     
     # calculate estimates of shortest WAint and largest dMagint for each target
     for sInd in range(TL.nStars):
         pInds = np.where(SU.plan2star == sInd)[0]
         self.WAint[sInd] = np.arctan(np.min(SU.a[pInds])/TL.dist[sInd]).to('arcsec')
         phis = np.array([np.pi/2]*pInds.size)
         dMags = deltaMag(SU.p[pInds], SU.Rp[pInds], SU.a[pInds], phis)
         self.dMagint[sInd] = np.min(dMags)
     
     # populate outspec with arrays
     self._outspec['WAint'] = self.WAint.value
     self._outspec['dMagint'] = self.dMagint
Exemple #8
0
 def __init__(self, **specs):
     
     # call prototype constructor
     SurveySimulation.__init__(self, **specs)
     
     TL = self.TargetList
     SU = self.SimulatedUniverse
     
     # reinitialize working angles and delta magnitudes used for integration
     self.WAint = np.zeros(TL.nStars)*u.arcsec
     self.dMagint = np.zeros(TL.nStars)
     
     # calculate estimates of shortest WAint and largest dMagint for each target
     for sInd in range(TL.nStars):
         pInds = np.where(SU.plan2star == sInd)[0]
         self.WAint[sInd] = np.arctan(np.min(SU.a[pInds])/TL.dist[sInd]).to('arcsec')
         phis = np.array([np.pi/2]*pInds.size)
         dMags = deltaMag(SU.p[pInds], SU.Rp[pInds], SU.a[pInds], phis)
         self.dMagint[sInd] = np.min(dMags)
     
     # populate outspec with arrays
     self._outspec['WAint'] = self.WAint.value
     self._outspec['dMagint'] = self.dMagint
    def __init__(self, cacheOptTimes=False, staticOptTimes=False, **specs):
        
        #initialize the prototype survey
        SurveySimulation.__init__(self, **specs)

        assert isinstance(staticOptTimes, bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes
        self._outspec['staticOptTimes'] = self.staticOptTimes

        assert isinstance(cacheOptTimes, bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes


        #some global defs
        self.detmode = filter(lambda mode: mode['detectionMode'] == True, self.OpticalSystem.observingModes)[0]
        self.ohTimeTot = self.Observatory.settlingTime + self.detmode['syst']['ohTime']
        self.maxTime = self.TimeKeeping.missionLife*self.TimeKeeping.missionPortion

        self.constraints = {'type':'ineq',
                            'fun': lambda x: self.maxTime.to(u.d).value - np.sum(x[x*u.d > 0.1*u.s]) - 
                                             np.sum(x*u.d > 0.1*u.s).astype(float)*self.ohTimeTot.to(u.d).value,
                            'jac':lambda x: np.ones(len(x))*-1.}

        self.t0 = None
        if cacheOptTimes:
            #Generate cache Name########################################################################
            cachefname = self.cachefname + 't0'
            
            if os.path.isfile(cachefname):
                self.vprint("Loading cached t0 from %s"%cachefname)
                with open(cachefname, 'rb') as f:
                    self.t0 = pickle.load(f)
                sInds = np.arange(self.TargetList.nStars)
                fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
                self.scomp0 = -self.objfun(self.t0.to(u.d).value,sInds,fZ)


        if self.t0 is None:
            #find nominal background counts for all targets in list
            _, Cbs, Csps = self.OpticalSystem.Cp_Cb_Csp(self.TargetList, range(self.TargetList.nStars),  
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, 25.0, self.WAint, self.detmode)

            #find baseline solution with dMagLim-based integration times
            self.vprint('Finding baseline fixed-time optimal target set.')
            t0 = self.OpticalSystem.calc_intTime(self.TargetList, range(self.TargetList.nStars),  
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.dMagint, self.WAint, self.detmode)
            comp0 = self.Completeness.comp_per_intTime(t0, self.TargetList, range(self.TargetList.nStars), 
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.WAint, self.detmode, C_b=Cbs, C_sp=Csps)

            
            solver = pywraplp.Solver('SolveIntegerProblem',pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
            xs = [ solver.IntVar(0.0,1.0, 'x'+str(j)) for j in range(len(comp0)) ]

            #constraint is x_i*t_i < maxtime
            constraint = solver.Constraint(-solver.infinity(),self.maxTime.to(u.day).value)
            for j,x in enumerate(xs):
                constraint.SetCoefficient(x, t0[j].to(u.day).value + self.ohTimeTot.to(u.day).value)

            #objective is max x_i*comp_i
            objective = solver.Objective()
            for j,x in enumerate(xs):
                objective.SetCoefficient(x, comp0[j])
            objective.SetMaximization()

            cpres = solver.Solve()
            x0 = np.array([x.solution_value() for x in xs])
            self.scomp0 = np.sum(comp0*x0)
            self.t0 = t0

            #now find the optimal eps baseline and use whichever gives you the highest starting completeness
            self.vprint('Finding baseline fixed-eps optimal target set.')
            def totCompfeps(eps):
                compstars,tstars,x = self.inttimesfeps(eps, Cbs.to('1/d').value, Csps.to('1/d').value)
                return -np.sum(compstars*x)
            epsres = minimize_scalar(totCompfeps,method='bounded',bounds = [0,1],options = {'disp':True})
            comp_epsmax,t_epsmax,x_epsmax = self.inttimesfeps(epsres['x'],Cbs.to('1/d').value, Csps.to('1/d').value)
            if np.sum(comp_epsmax*x_epsmax) > self.scomp0:
                x0 = x_epsmax
                self.scomp0 = np.sum(comp_epsmax*x_epsmax) 
                self.t0 = t_epsmax*u.day

            #now optimize the solution
            self.vprint('Optimizing baseline integration times.')
            sInds = np.arange(self.TargetList.nStars)
            fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
            bounds = [(0,self.maxTime.to(u.d).value) for i in range(len(sInds))]
            initguess = x0*self.t0.to(u.d).value
            ires = minimize(self.objfun, initguess, jac=self.objfun_deriv, args=(sInds,fZ), 
                    constraints=self.constraints, method='SLSQP', bounds=bounds, options={'maxiter':100,'ftol':1e-4})

            assert ires['success'], "Initial time optimization failed."

            self.t0 = ires['x']*u.d
            self.scomp0 = -ires['fun']

            if cacheOptTimes:
                with open(cachefname,'wb') as f:
                    pickle.dump(self.t0, f)
                self.vprint("Saved cached optimized t0 to %s"%cachefname)
Exemple #10
0
    def __init__(self, **specs):
        SurveySimulation.__init__(self, **specs)
        # bring inherited class objects to top level of Survey Simulation
        SU = self.SimulatedUniverse
        OS = SU.OpticalSystem
        ZL = SU.ZodiacalLight
        self.Completeness = SU.Completeness
        TL = SU.TargetList
        Obs = self.Observatory
        TK = self.TimeKeeping

        self.starVisits = np.zeros(TL.nStars, dtype=int)
        self.starRevisit = np.array([])

        detMode = filter(lambda mode: mode['detectionMode'] == True,
                         OS.observingModes)[0]
        spectroModes = filter(lambda mode: 'spec' in mode['inst']['name'],
                              OS.observingModes)
        self.mode = detMode

        #Create and start Schedule
        self.schedule = np.arange(
            TL.nStars)  #self.schedule is meant to be editable
        self.schedule_startSaved = np.arange(
            TL.nStars)  #preserves initial list of targets

        dMagLim = self.Completeness.dMagLim
        self.dmag_startSaved = np.linspace(1, dMagLim, num=1500, endpoint=True)

        sInds = self.schedule_startSaved
        dmag = self.dmag_startSaved
        WA = OS.WA0
        startTime = np.zeros(
            sInds.shape[0]) * u.d + self.TimeKeeping.currentTimeAbs

        tovisit = np.zeros(sInds.shape[0], dtype=bool)

        #Generate fZ
        #ZL.fZ_startSaved = self.generate_fZ(sInds)#Sept 21, 2017 execution time 0.725 sec

        #Estimate Yearly fZmin###########################################
        tmpfZ = np.asarray(ZL.fZ_startSaved)
        fZ_matrix = tmpfZ[
            sInds, :]  #Apply previous filters to fZ_startSaved[sInds, 1000]
        #Find minimum fZ of each star
        fZmin = np.zeros(sInds.shape[0])
        fZminInds = np.zeros(sInds.shape[0])
        for i in xrange(len(sInds)):
            fZmin[i] = min(fZ_matrix[i, :])
            fZminInds[i] = np.argmin(fZ_matrix[i, :])
        #################################################################

        #CACHE Cb Cp Csp################################################Sept 20, 2017 execution time 10.108 sec
        #fZ = np.zeros(sInds.shape[0]) + 0./u.arcsec**2
        #fEZ = 0./u.arcsec**2#
        #fZ = np.zeros(sInds.shape[0]) + ZL.fZ0
        fZ = fZmin / u.arcsec**2  #
        fEZ = ZL.fEZ0
        mode = self.mode  #resolve this mode is passed into next_target
        allModes = self.OpticalSystem.observingModes
        det_mode = filter(lambda mode: mode['detectionMode'] == True,
                          allModes)[0]
        #dmag = self.dmag_startSaved
        Cp = np.zeros([sInds.shape[0], dmag.shape[0]])
        Cb = np.zeros(sInds.shape[0])
        Csp = np.zeros(sInds.shape[0])
        for i in xrange(dmag.shape[0]):
            Cp[:, i], Cb[:], Csp[:] = OS.Cp_Cb_Csp(TL, sInds, fZ, fEZ, dmag[i],
                                                   WA, det_mode)
        self.Cb = Cb[:] / u.s  #Cb[:,0]/u.s#note all Cb are the same for different dmags. They are just star dependent
        self.Csp = Csp[:] / u.s  #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
        ################################################################

        #Solve Initial Integration Times###############################################
        def CbyTfunc(t_dets, self, TL, sInds, fZ, fEZ, WA, mode, Cb, Csp):
            CbyT = -self.Completeness.comp_per_intTime(t_dets * u.d, TL, sInds,
                                                       fZ, fEZ, WA, mode, Cb,
                                                       Csp) / t_dets * u.d
            return CbyT.value

        maxCbyTtime = np.zeros(
            sInds.shape[0])  #This contains the time maxCbyT occurs at
        maxCbyT = np.zeros(sInds.shape[0])  #this contains the value of maxCbyT

        dir_path = os.path.dirname(os.path.realpath(
            __file__))  #find current directory of survey Simualtion
        fname = '/cachedMaxCbyTtime.csv'
        #Check File Length
        fileLength = 0
        numcommas = 0
        try:
            with open(dir_path + fname, 'rb') as f:
                reader = csv.reader(f)
                your_list = list(reader)
                fileLength = len(your_list)
                numcommas = len(your_list[0])
                f.close()
        except:
            fileLength = 0
            numcommas = 0

        if (
                not os.path.isfile(dir_path + fname)
                or not (fileLength != sInds.shape[0]
                        or numcommas != sInds.shape[0])
        ):  #If the file does not exist or is not the proper size, Recalculate

            for i in xrange(sInds.shape[0]):
                x0 = 0.01
                maxCbyTtime[i] = fmin(CbyTfunc,
                                      x0,
                                      xtol=1e-8,
                                      args=(self, TL, sInds[i], fZ[i], fEZ, WA,
                                            mode, self.Cb[i], self.Csp[i]),
                                      disp=False)
            t_dets = maxCbyTtime
            #Sept 27, Execution time 101 seconds for 651 stars

            #Save maxCbyT to File######################################
            try:  #Here we delete the previous fZ file
                timeNow = datetime.datetime.now()
                timeString = str(timeNow.year) + '_' + str(
                    timeNow.month) + '_' + str(timeNow.day) + '_' + str(
                        timeNow.hour) + '_' + str(timeNow.minute) + '_'
                fnameNew = '/' + timeString + 'moved_maxCbyTtime.csv'
                os.rename(dir_path + fname, dir_path + fnameNew)
            except OSError:
                pass
            with open(dir_path + fname, "wb") as fo:
                wr = csv.writer(fo, quoting=csv.QUOTE_ALL)
                wr.writerow(maxCbyTtime)  #Write the fZ to file
                fo.close()

        #Load maxCbyTtime for Each Star From File###### Sept 28, 2017 execution time is 0.00057 sec
        maxCbyTtimeList = list()
        with open(dir_path + fname, 'rb') as f:
            reader = csv.reader(f)
            your_list = list(reader)
            f.close()
        for i in range(len(your_list)):
            tmp = np.asarray(your_list[i]).astype(np.float)
            maxCbyTtimeList.append(tmp)
        maxCbyTtime = np.asarray(maxCbyTtimeList, dtype=np.float64)
        t_dets = maxCbyTtime[0][sInds]
        #############################################################################

        #Distribute Excess Mission Time################################################Sept 28, 2017 execution time 19.0 sec
        missionLength = (
            TK.missionFinishAbs - TK.currentTimeAbs
        ).value * 12 / 12  #TK.missionLife.to(u.day).value#mission length in days
        overheadTime = self.Observatory.settlingTime.value + self.OpticalSystem.observingModes[
            0]['syst']['ohTime'].value  #OH time in days
        while (
            (sum(t_dets) + sInds.shape[0] * overheadTime) > missionLength
        ):  #the sum of star observation times is still larger than the mission length
            sInds, t_dets, sacrificedStarTime, fZ = self.sacrificeStarCbyT(
                sInds, t_dets, fZ, fEZ, WA, overheadTime)

        if (sum(t_dets + sInds.shape[0] * overheadTime) >
                missionLength):  #There is some excess time
            sacrificedStarTime = missionLength - (
                sum(t_dets) + sInds.shape[0] * overheadTime
            )  #The amount of time the list is under the total mission Time
            t_dets = self.distributedt(sInds, t_dets, sacrificedStarTime, fZ,
                                       fEZ, WA)
        ###############################################################################

        #STARK AYO LOOP################################################################
        savedSumComp00 = np.zeros(sInds.shape[0])
        firstIteration = 1  #checks if this is the first iteration.
        numits = 0  #ensure an infinite loop does not occur. Should be depricated
        lastIterationSumComp = -10000000  #this is some ludacrisly negative number to ensure sumcomp runs. All sumcomps should be positive
        while numits < 100000 and sInds is not None:
            numits = numits + 1  #we increment numits each loop iteration

            #Sacrifice Lowest Performing Star################################################Sept 28, 2017 execution time 0.0744 0.032 at smallest list size
            sInds, t_dets, sacrificedStarTime, fZ = self.sacrificeStarCbyT(
                sInds, t_dets, fZ, fEZ, WA, overheadTime)

            #Distribute Sacrificed Time to new star observations############################# Sept 28, 2017 execution time 0.715, 0.64 at smallest (depends on # stars)
            t_dets = self.distributedt(sInds, t_dets, sacrificedStarTime, fZ,
                                       fEZ, WA)

            #AYO Termination Conditions###############################Sept 28, 2017 execution time 0.033 sec
            Comp00 = self.Completeness.comp_per_intTime(
                t_dets * u.d, TL, sInds, fZ, fEZ, WA, mode, self.Cb, self.Csp)

            #change this to an assert
            if 1 >= len(sInds):  #if this is the last ement in the list
                #print('sInds maximally sorted (This probably indicates an error)')
                #print(saltyburrito)
                break
            savedSumComp00[numits - 1] = sum(Comp00)
            # # #If the total sum of completeness at this moment is less than the last sum, then exit
            if (
                    sum(Comp00) < lastIterationSumComp
            ):  #If sacrificing the additional target reduced performance, then Define Output of AYO Process
                CbyT = self.Completeness.comp_per_intTime(
                    t_dets * u.d, self.TargetList, sInds, fZ, fEZ, WA,
                    self.mode, self.Cb, self.Csp
                ) / t_dets  #takes 5 seconds to do 1 time for all stars
                sortIndex = np.argsort(CbyT, axis=-1)[::-1]

                #This is the static optimal schedule
                self.schedule = sInds[sortIndex]
                self.t_dets = t_dets[sortIndex]
                self.CbyT = CbyT[sortIndex]
                self.fZ = fZ[sortIndex]
                self.Comp00 = Comp00[sortIndex]

                break
            else:  #else set lastIterationSumComp to current sum Comp00
                lastIterationSumComp = sum(Comp00)
                print(
                    str(numits) + ' SumComp ' + str(sum(Comp00)) +
                    ' Sum(t_dets) ' + str(sum(t_dets)) + ' sInds ' +
                    str(sInds.shape[0] * float(1)) + ' TimeConservation ' +
                    str(sum(t_dets) + sInds.shape[0] * float(1))
                )  # + ' Avg C/T ' + str(np.average(CbyT)))
Exemple #11
0
    def __init__(self, **specs):

        SurveySimulation.__init__(self, **specs)
    def __init__(self, cacheOptTimes=False, staticOptTimes=False, **specs):
        SurveySimulation.__init__(self, **specs)

        assert isinstance(staticOptTimes, bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes
        self._outspec['staticOptTimes'] = self.staticOptTimes

        assert isinstance(cacheOptTimes, bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes


        # bring inherited class objects to top level of Survey Simulation
        OS = self.OpticalSystem
        ZL = self.ZodiacalLight
        TL = self.TargetList
        Obs = self.Observatory
        TK = self.TimeKeeping
        
        #Create and start Schedule
        self.schedule = np.arange(TL.nStars)#self.schedule is meant to be editable
        self.schedule_startSaved = np.arange(TL.nStars)#preserves initial list of targets
          
        dMagLim = self.Completeness.dMagLim
        self.dmag_startSaved = np.linspace(1, dMagLim, num=1500,endpoint=True)

        sInds = self.schedule_startSaved.copy()
        dmag = self.dmag_startSaved
        WA = OS.WA0
        startTime = np.zeros(sInds.shape[0])*u.d + TK.currentTimeAbs

        #Generate fZ #no longer necessary because called by calcfZmin
        #Estimate Yearly fZmin###########################################
        self.fZmin, self.abdTimefZmin = ZL.calcfZmin(sInds, Obs, TL, TK, self.mode, self.cachefname)
        #Estimate Yearly fZmax###########################################
        self.fZmax, self.abdTimefZmax = ZL.calcfZmax(sInds, Obs, TL, TK, self.mode, self.cachefname)
        #################################################################

        #CACHE Cb Cp Csp################################################Sept 20, 2017 execution time 10.108 sec
        #WE DO NOT NEED TO CALCULATE OVER EVERY DMAG
        Cp = np.zeros([sInds.shape[0],dmag.shape[0]])
        Cb = np.zeros(sInds.shape[0])
        Csp = np.zeros(sInds.shape[0])
        for i in xrange(dmag.shape[0]):
            Cp[:,i], Cb[:], Csp[:] = OS.Cp_Cb_Csp(TL, sInds, self.fZmin, ZL.fEZ0, dmag[i], WA, self.mode)
        self.Cb = Cb[:]/u.s#Cb[:,0]/u.s#note all Cb are the same for different dmags. They are just star dependent
        self.Csp = Csp[:]/u.s#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
        ################################################################


        #Load cached Observation Times
        cachefname = self.cachefname + 'starkcache'  # Generate cache Name
        if cacheOptTimes and os.path.isfile(cachefname):#Checks if flag to load cached optimal times exists
            self.vprint("Loading starkcache from %s"%cachefname)
            try:
                with open(cachefname, "rb") as ff:
                    tmpDat = pickle.load(ff)
            except UnicodeDecodeError:
                with open(cachefname, "rb") as ff:
                    tmpDat = pickle.load(ff,encoding='latin1')
            self.schedule = tmpDat[0,:].astype(int)
            self.t_dets = tmpDat[1,:]
            self.CbyT = tmpDat[2,:]
            self.Comp00 = tmpDat[3,:]
        else:#create cachedOptTimes
            self.altruisticYieldOptimization(sInds)
    def __init__(self, cacheOptTimes=False, staticOptTimes=False, **specs):
        SurveySimulation.__init__(self, **specs)

        assert isinstance(staticOptTimes, bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes
        self._outspec['staticOptTimes'] = self.staticOptTimes
        
        assert isinstance(cacheOptTimes, bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes


        # bring inherited class objects to top level of Survey Simulation
        SU = self.SimulatedUniverse
        OS = self.OpticalSystem
        ZL = self.ZodiacalLight
        #self.Completeness = SU.Completeness
        TL = self.TargetList
        Obs = self.Observatory
        TK = self.TimeKeeping
        
        #Create and start Schedule
        self.schedule = np.arange(TL.nStars)#self.schedule is meant to be editable
        self.schedule_startSaved = np.arange(TL.nStars)#preserves initial list of targets
          
        dMagLim = self.Completeness.dMagLim
        self.dmag_startSaved = np.linspace(1, dMagLim, num=1500,endpoint=True)

        sInds = self.schedule_startSaved.copy()
        dmag = self.dmag_startSaved
        WA = OS.WA0
        startTime = np.zeros(sInds.shape[0])*u.d + TK.currentTimeAbs

        #Generate fZ #no longer necessary because called by calcfZmin
        #Estimate Yearly fZmin###########################################
        self.fZmin, self.abdTimefZmin = ZL.calcfZmin(sInds, Obs, TL, TK, self.mode, self.cachefname)
        #Estimate Yearly fZmax###########################################
        self.fZmax, self.abdTimefZmax = ZL.calcfZmax(sInds, Obs, TL, TK, self.mode, self.cachefname)
        #################################################################

        #CACHE Cb Cp Csp################################################Sept 20, 2017 execution time 10.108 sec
        #WE DO NOT NEED TO CALCULATE OVER EVERY DMAG
        Cp = np.zeros([sInds.shape[0],dmag.shape[0]])
        Cb = np.zeros(sInds.shape[0])
        Csp = np.zeros(sInds.shape[0])
        for i in xrange(dmag.shape[0]):
            Cp[:,i], Cb[:], Csp[:] = OS.Cp_Cb_Csp(TL, sInds, self.fZmin, ZL.fEZ0, dmag[i], WA, self.mode)
        self.Cb = Cb[:]/u.s#Cb[:,0]/u.s#note all Cb are the same for different dmags. They are just star dependent
        self.Csp = Csp[:]/u.s#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
        ################################################################


        #Load cached Observation Times
        cachefname = self.cachefname + 'starkcache'  # Generate cache Name
        if cacheOptTimes and os.path.isfile(cachefname):#Checks if flag to load cached optimal times exists
            self.vprint("Loading starkcache from %s"%cachefname)
            with open(cachefname, 'rb') as f:#load from cache
                tmpDat = pickle.load(f)
                self.schedule = tmpDat[0,:].astype(int)
                self.t_dets = tmpDat[1,:]
                self.CbyT = tmpDat[2,:]
                self.Comp00 = tmpDat[3,:]
            sInds = np.arange(self.TargetList.nStars)
        else:#create cachedOptTimes
            #Calculate Initial Integration Times###########################################
            maxCbyTtime = self.calcTinit(sInds, TL, self.fZmin, ZL.fEZ0, WA, self.mode)
            t_dets = maxCbyTtime#[sInds] #t_dets has length TL.nStars

            #Sacrifice Stars and then Distribute Excess Mission Time################################################Sept 28, 2017 execution time 19.0 sec
            overheadTime = Obs.settlingTime.value + OS.observingModes[0]['syst']['ohTime'].value#OH time in days
            while((sum(t_dets) + sInds.shape[0]*overheadTime) > (TK.missionLife*TK.missionPortion).to('day').value):#the sum of star observation times is still larger than the mission length
                sInds, t_dets, sacrificedStarTime= self.sacrificeStarCbyT(sInds, t_dets, self.fZmin[sInds], ZL.fEZ0, WA, overheadTime)
            self.vprint('Started with ' + str(TL.nStars) + ' sacrificed down to ' + str(sInds.shape[0]))

            if(sum(t_dets + sInds.shape[0]*overheadTime) > (TK.missionLife*TK.missionPortion).to('day').value):#There is some excess time
                sacrificedStarTime = (TK.missionLife*TK.missionPortion).to('day').value - (sum(t_dets) + sInds.shape[0]*overheadTime)#The amount of time the list is under the total mission Time
                t_dets = self.distributedt(sInds, t_dets, sacrificedStarTime, self.fZmin[sInds], ZL.fEZ0, WA)
            ###############################################################################

            #STARK AYO LOOP################################################################
            numits = 0#ensure an infinite loop does not occur. Should be depricated
            lastIterationSumComp  = -10000000 #this is some ludacrisly negative number to ensure sumcomp runs. All sumcomps should be positive
            while numits < 100000 and sInds is not None:
                numits = numits+1#we increment numits each loop iteration

                #Sacrifice Lowest Performing Star################################################Sept 28, 2017 execution time 0.0744 0.032 at smallest list size
                sInds, t_dets, sacrificedStarTime = self.sacrificeStarCbyT(sInds, t_dets, self.fZmin[sInds], ZL.fEZ0, WA, overheadTime)

                #Distribute Sacrificed Time to new star observations############################# Sept 28, 2017 execution time 0.715, 0.64 at smallest (depends on # stars)
                t_dets = self.distributedt(sInds, t_dets, sacrificedStarTime, self.fZmin[sInds], ZL.fEZ0, WA)

                #AYO Termination Conditions###############################Sept 28, 2017 execution time 0.033 sec
                Comp00 = self.Completeness.comp_per_intTime(t_dets*u.d, TL, sInds, self.fZmin[sInds], ZL.fEZ0, WA, self.mode, self.Cb[sInds], self.Csp[sInds])

                #change this to an assert
                if 1 >= len(sInds):#if this is the last ement in the list
                    break
                #If the total sum of completeness at this moment is less than the last sum, then exit
                if(sum(Comp00) < lastIterationSumComp):#If sacrificing the additional target reduced performance, then Define Output of AYO Process
                    CbyT = self.Completeness.comp_per_intTime(t_dets*u.d, self.TargetList, sInds, self.fZmin[sInds], ZL.fEZ0, WA, self.mode, self.Cb[sInds], self.Csp[sInds])/t_dets#takes 5 seconds to do 1 time for all stars
                    sortIndex = np.argsort(CbyT,axis=-1)[::-1]

                    #This is the static optimal schedule
                    self.schedule = sInds[sortIndex]
                    self.t_dets = t_dets[sortIndex]
                    self.CbyT = CbyT[sortIndex]
                    #self.fZ = fZ[sortIndex]
                    self.Comp00 = Comp00[sortIndex]

                    cachefname = self.cachefname + 'starkcache'  # Generate cache Name
                    tmpDat = np.zeros([4,self.schedule.shape[0]])
                    tmpDat[0,:] = self.schedule
                    tmpDat[1,:] = self.t_dets
                    tmpDat[2,:] = self.CbyT
                    tmpDat[3,:] = self.Comp00
                    self.vprint("Saving starkcache to %s"%cachefname)
                    with open(cachefname, 'wb') as f:#save to cache
                        pickle.dump(tmpDat,f)
                    break
                else:#else set lastIterationSumComp to current sum Comp00
                    lastIterationSumComp = sum(Comp00)
                    self.vprint("%d SumComp %.2f Sum(t_dets) %.2f sInds %d Time Conservation %.2f" \
                        %(numits, sum(Comp00), sum(t_dets), sInds.shape[0], sum(t_dets)+sInds.shape[0]*overheadTime))
Exemple #14
0
    def __init__(self, cacheOptTimes=False, **specs):
        SurveySimulation.__init__(self, **specs)

        assert isinstance(cacheOptTimes,
                          bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes

        #Load cached Observation Times
        self.starkt0 = None
        if cacheOptTimes:  #Checks if flag exists
            cachefname = ''  #declares cachefname
            mods = [
                'PlanetPopulation', 'PlanetPhysicalModel', 'Completeness',
                'TargetList', 'OpticalSystem'
            ]  #modules to look at
            for mod in mods:
                cachefname += self.modules[mod].__module__.split(".")[
                    -1]  #add module name to end of cachefname?
            cachefname += hashlib.md5(
                str(self.TargetList.Name) +
                str(self.TargetList.tint0.to(u.d).value)).hexdigest(
                )  #turn cachefname into hashlib
            cachefname = os.path.join(
                os.path.split(inspect.getfile(self.__class__))[0], cachefname +
                os.extsep + 'starkt0')  #'t0')#join into filepath and fname

            if os.path.isfile(cachefname):  #check if file exists
                self.vprint("Loading cached t0 from %s" % cachefname)
                with open(cachefname, 'rb') as f:  #load from cache
                    self.starkt0 = pickle.load(f)
                sInds = np.arange(self.TargetList.nStars)

        # bring inherited class objects to top level of Survey Simulation
        SU = self.SimulatedUniverse
        OS = SU.OpticalSystem
        ZL = SU.ZodiacalLight
        self.Completeness = SU.Completeness
        TL = SU.TargetList
        Obs = self.Observatory
        TK = self.TimeKeeping

        self.starVisits = np.zeros(TL.nStars, dtype=int)
        self.starRevisit = np.array([])

        detMode = filter(lambda mode: mode['detectionMode'] == True,
                         OS.observingModes)[0]
        spectroModes = filter(lambda mode: 'spec' in mode['inst']['name'],
                              OS.observingModes)
        self.mode = detMode

        #Create and start Schedule
        self.schedule = np.arange(
            TL.nStars)  #self.schedule is meant to be editable
        self.schedule_startSaved = np.arange(
            TL.nStars)  #preserves initial list of targets

        dMagLim = self.Completeness.dMagLim
        self.dmag_startSaved = np.linspace(1, dMagLim, num=1500, endpoint=True)

        sInds = self.schedule_startSaved
        dmag = self.dmag_startSaved
        WA = OS.WA0
        startTime = np.zeros(
            sInds.shape[0]) * u.d + self.TimeKeeping.currentTimeAbs

        tovisit = np.zeros(sInds.shape[0], dtype=bool)

        #Generate fZ
        self.fZ_startSaved = self.generate_fZ(sInds)  #

        #Estimate Yearly fZmin###########################################
        fZmin, fZminInds = self.calcfZmin(sInds, self.fZ_startSaved)
        #Estimate Yearly fZmin###########################################
        # tmpfZ = np.asarray(self.fZ_startSaved)
        # fZ_matrix = tmpfZ[sInds,:]#Apply previous filters to fZ_startSaved[sInds, 1000]
        # #Find minimum fZ of each star
        # fZmin = np.zeros(sInds.shape[0])
        # fZminInds = np.zeros(sInds.shape[0])
        # for i in xrange(len(sInds)):
        #     fZmin[i] = min(fZ_matrix[i,:])
        #     fZminInds[i] = np.argmin(fZ_matrix[i,:])
        #################################################################

        #CACHE Cb Cp Csp################################################Sept 20, 2017 execution time 10.108 sec
        fZ = fZmin / u.arcsec**2  #
        fEZ = ZL.fEZ0
        mode = self.mode  #resolve this mode is passed into next_target
        allModes = self.OpticalSystem.observingModes
        det_mode = filter(lambda mode: mode['detectionMode'] == True,
                          allModes)[0]
        Cp = np.zeros([sInds.shape[0], dmag.shape[0]])
        Cb = np.zeros(sInds.shape[0])
        Csp = np.zeros(sInds.shape[0])
        for i in xrange(dmag.shape[0]):
            Cp[:, i], Cb[:], Csp[:] = OS.Cp_Cb_Csp(TL, sInds, fZ, fEZ, dmag[i],
                                                   WA, det_mode)
        self.Cb = Cb[:] / u.s  #Cb[:,0]/u.s#note all Cb are the same for different dmags. They are just star dependent
        self.Csp = Csp[:] / u.s  #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
        ################################################################

        #Calculate Initial Integration Times###########################################
        maxCbyTtime = self.calcTinit(sInds, TL, fZ, fEZ, WA, mode, self.Cb,
                                     self.Csp)
        t_dets = maxCbyTtime[sInds]

        #Sacrifice Stars and then Distribute Excess Mission Time################################################Sept 28, 2017 execution time 19.0 sec
        missionLength = (
            TK.missionLife.to(u.d) * TK.missionPortion
        ).value * 12 / 12  #TK.missionLife.to(u.day).value#mission length in days
        overheadTime = self.Observatory.settlingTime.value + self.OpticalSystem.observingModes[
            0]['syst']['ohTime'].value  #OH time in days
        while (
            (sum(t_dets) + sInds.shape[0] * overheadTime) > missionLength
        ):  #the sum of star observation times is still larger than the mission length
            sInds, t_dets, sacrificedStarTime, fZ = self.sacrificeStarCbyT(
                sInds, t_dets, fZ, fEZ, WA, overheadTime)

        if (sum(t_dets + sInds.shape[0] * overheadTime) >
                missionLength):  #There is some excess time
            sacrificedStarTime = missionLength - (
                sum(t_dets) + sInds.shape[0] * overheadTime
            )  #The amount of time the list is under the total mission Time
            t_dets = self.distributedt(sInds, t_dets, sacrificedStarTime, fZ,
                                       fEZ, WA)
        ###############################################################################

        #STARK AYO LOOP################################################################
        savedSumComp00 = np.zeros(sInds.shape[0])
        firstIteration = 1  #checks if this is the first iteration.
        numits = 0  #ensure an infinite loop does not occur. Should be depricated
        lastIterationSumComp = -10000000  #this is some ludacrisly negative number to ensure sumcomp runs. All sumcomps should be positive
        while numits < 100000 and sInds is not None:
            numits = numits + 1  #we increment numits each loop iteration

            #Sacrifice Lowest Performing Star################################################Sept 28, 2017 execution time 0.0744 0.032 at smallest list size
            sInds, t_dets, sacrificedStarTime, fZ = self.sacrificeStarCbyT(
                sInds, t_dets, fZ, fEZ, WA, overheadTime)

            #Distribute Sacrificed Time to new star observations############################# Sept 28, 2017 execution time 0.715, 0.64 at smallest (depends on # stars)
            t_dets = self.distributedt(sInds, t_dets, sacrificedStarTime, fZ,
                                       fEZ, WA)

            #AYO Termination Conditions###############################Sept 28, 2017 execution time 0.033 sec
            Comp00 = self.Completeness.comp_per_intTime(
                t_dets * u.d, TL, sInds, fZ, fEZ, WA, mode, self.Cb, self.Csp)

            #change this to an assert
            if 1 >= len(sInds):  #if this is the last ement in the list
                break
            savedSumComp00[numits - 1] = sum(Comp00)
            #If the total sum of completeness at this moment is less than the last sum, then exit
            if (
                    sum(Comp00) < lastIterationSumComp
            ):  #If sacrificing the additional target reduced performance, then Define Output of AYO Process
                CbyT = self.Completeness.comp_per_intTime(
                    t_dets * u.d, self.TargetList, sInds, fZ, fEZ, WA,
                    self.mode, self.Cb, self.Csp
                ) / t_dets  #takes 5 seconds to do 1 time for all stars
                sortIndex = np.argsort(CbyT, axis=-1)[::-1]

                #This is the static optimal schedule
                self.schedule = sInds[sortIndex]
                self.t_dets = t_dets[sortIndex]
                self.CbyT = CbyT[sortIndex]
                self.fZ = fZ[sortIndex]
                self.Comp00 = Comp00[sortIndex]
                break
            else:  #else set lastIterationSumComp to current sum Comp00
                lastIterationSumComp = sum(Comp00)
                self.vprint(
                    str(numits) + ' SumComp ' + str(sum(Comp00)) +
                    ' Sum(t_dets) ' + str(sum(t_dets)) + ' sInds ' +
                    str(sInds.shape[0] * float(1)) + ' TimeConservation ' +
                    str(sum(t_dets) + sInds.shape[0] * float(1))
                )  # + ' Avg C/T ' + str(np.average(CbyT)))
Exemple #15
0
    def __init__(self, cacheOptTimes=False, staticOptTimes=False, **specs):
        SurveySimulation.__init__(self, **specs)

        assert isinstance(staticOptTimes,
                          bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes
        self._outspec['staticOptTimes'] = self.staticOptTimes

        assert isinstance(cacheOptTimes,
                          bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes

        # bring inherited class objects to top level of Survey Simulation
        OS = self.OpticalSystem
        ZL = self.ZodiacalLight
        TL = self.TargetList
        Obs = self.Observatory
        TK = self.TimeKeeping

        #Create and start Schedule
        self.schedule = np.arange(
            TL.nStars)  #self.schedule is meant to be editable
        self.schedule_startSaved = np.arange(
            TL.nStars)  #preserves initial list of targets

        dMagLim = self.Completeness.dMagLim
        self.dmag_startSaved = np.linspace(1, dMagLim, num=1500, endpoint=True)

        sInds = self.schedule_startSaved.copy()
        dmag = self.dmag_startSaved
        WA = OS.WA0
        startTime = np.zeros(sInds.shape[0]) * u.d + TK.currentTimeAbs

        #Generate fZ #no longer necessary because called by calcfZmin
        #Estimate Yearly fZmin###########################################
        self.fZmin, self.abdTimefZmin = ZL.calcfZmin(sInds, Obs, TL, TK,
                                                     self.mode,
                                                     self.cachefname)
        #Estimate Yearly fZmax###########################################
        self.fZmax, self.abdTimefZmax = ZL.calcfZmax(sInds, Obs, TL, TK,
                                                     self.mode,
                                                     self.cachefname)
        #################################################################

        #CACHE Cb Cp Csp################################################Sept 20, 2017 execution time 10.108 sec
        #WE DO NOT NEED TO CALCULATE OVER EVERY DMAG
        Cp = np.zeros([sInds.shape[0], dmag.shape[0]])
        Cb = np.zeros(sInds.shape[0])
        Csp = np.zeros(sInds.shape[0])
        for i in xrange(dmag.shape[0]):
            Cp[:,
               i], Cb[:], Csp[:] = OS.Cp_Cb_Csp(TL, sInds, self.fZmin, ZL.fEZ0,
                                                dmag[i], WA, self.mode)
        self.Cb = Cb[:] / u.s  #Cb[:,0]/u.s#note all Cb are the same for different dmags. They are just star dependent
        self.Csp = Csp[:] / u.s  #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
        ################################################################

        #Load cached Observation Times
        cachefname = self.cachefname + 'starkcache'  # Generate cache Name
        if cacheOptTimes and os.path.isfile(
                cachefname
        ):  #Checks if flag to load cached optimal times exists
            self.vprint("Loading starkcache from %s" % cachefname)
            with open(cachefname, 'rb') as f:  #load from cache
                tmpDat = pickle.load(f)
                self.schedule = tmpDat[0, :].astype(int)
                self.t_dets = tmpDat[1, :]
                self.CbyT = tmpDat[2, :]
                self.Comp00 = tmpDat[3, :]
        else:  #create cachedOptTimes
            self.altruisticYieldOptimization(sInds)
Exemple #16
0
    def __init__(self, cacheOptTimes=False, staticOptTimes=False, selectionMetric='maxC', Izod='current',
        maxiter=60, ftol=1e-3, **specs): #fZminObs=False,
        
        #initialize the prototype survey
        SurveySimulation.__init__(self, **specs)

        #Calculate fZmax
        self.valfZmax, self.absTimefZmax = self.ZodiacalLight.calcfZmax(np.arange(self.TargetList.nStars), self.Observatory, self.TargetList,
            self.TimeKeeping, list(filter(lambda mode: mode['detectionMode'] == True, self.OpticalSystem.observingModes))[0], self.cachefname)

        assert isinstance(staticOptTimes, bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes
        self._outspec['staticOptTimes'] = self.staticOptTimes

        assert isinstance(cacheOptTimes, bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes

        assert selectionMetric in ['maxC','Izod-Izodmin','Izod-Izodmax',
            '(Izod-Izodmin)/(Izodmax-Izodmin)',
            '(Izod-Izodmin)/(Izodmax-Izodmin)/CIzod', #(Izod-Izodmin)/(Izodmax-Izodmin)/CIzodmin is simply this but with Izod='fZmin'
            'TauIzod/CIzod', #TauIzodmin/CIzodmin is simply this but with Izod='fZmin'
            'random',
            'priorityObs'], 'selectionMetric not valid input' # Informs what selection metric to use
        self.selectionMetric = selectionMetric
        self._outspec['selectionMetric'] = self.selectionMetric

        assert Izod in ['fZmin','fZ0','fZmax','current'], 'Izod not valid input' # Informs what Izod to optimize integration times for [fZmin, fZmin+45d, fZ0, fZmax, current]
        self.Izod = Izod
        self._outspec['Izod'] = self.Izod

        assert isinstance(maxiter, int), 'maxiter is not an int' # maximum number of iterations to optimize integration times for
        assert maxiter >= 1, 'maxiter must be positive real'
        self.maxiter = maxiter
        self._outspec['maxiter'] = self.maxiter

        assert isinstance(ftol, float), 'ftol must be boolean' # tolerance to place on optimization
        assert ftol > 0, 'ftol must be positive real'
        self.ftol = ftol
        self._outspec['ftol'] = self.ftol


        #some global defs
        self.detmode = list(filter(lambda mode: mode['detectionMode'] == True, self.OpticalSystem.observingModes))[0]
        self.ohTimeTot = self.Observatory.settlingTime + self.detmode['syst']['ohTime'] # total overhead time per observation
        self.maxTime = self.TimeKeeping.missionLife*self.TimeKeeping.missionPortion # total mission time

        self.constraints = {'type':'ineq',
                            'fun': lambda x: self.maxTime.to(u.d).value - np.sum(x[x*u.d > 0.1*u.s]) - #maxTime less sum of intTimes
                                             np.sum(x*u.d > 0.1*u.s).astype(float)*self.ohTimeTot.to(u.d).value, # sum of True -> goes to 1 x OHTime
                            'jac':lambda x: np.ones(len(x))*-1.}

        self.t0 = None
        if cacheOptTimes:
            #Generate cache Name########################################################################
            cachefname = self.cachefname + 't0'
            
            if os.path.isfile(cachefname):
                self.vprint("Loading cached t0 from %s"%cachefname)
                with open(cachefname, 'rb') as f:
                    self.t0 = pickle.load(f)
                sInds = np.arange(self.TargetList.nStars)
                fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
                self.scomp0 = -self.objfun(self.t0.to('day').value,sInds,fZ)


        if self.t0 is None:
            #1. find nominal background counts for all targets in list
            dMagint = 25.0 # this works fine for WFIRST
            _, Cbs, Csps = self.OpticalSystem.Cp_Cb_Csp(self.TargetList, np.arange(self.TargetList.nStars),  
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, dMagint, self.WAint, self.detmode)

            #find baseline solution with dMagLim-based integration times
            #3.
            self.vprint('Finding baseline fixed-time optimal target set.')
            t0 = self.OpticalSystem.calc_intTime(self.TargetList, np.arange(self.TargetList.nStars),  
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.dMagint, self.WAint, self.detmode)
            #4.
            comp0 = self.Completeness.comp_per_intTime(t0, self.TargetList, np.arange(self.TargetList.nStars), 
                    self.ZodiacalLight.fZ0, self.ZodiacalLight.fEZ0, self.WAint, self.detmode, C_b=Cbs, C_sp=Csps)
            
            #### 5. Formulating MIP to filter out stars we can't or don't want to reasonably observe
            solver = pywraplp.Solver('SolveIntegerProblem',pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING) # create solver instance
            xs = [ solver.IntVar(0.0,1.0, 'x'+str(j)) for j in np.arange(len(comp0)) ] # define x_i variables for each star either 0 or 1

            #constraint is x_i*t_i < maxtime
            constraint = solver.Constraint(-solver.infinity(),self.maxTime.to(u.day).value)
            for j,x in enumerate(xs):
                constraint.SetCoefficient(x, t0[j].to('day').value + self.ohTimeTot.to(u.day).value) # this forms x_i*(t_0i+OH) for all i

            #objective is max x_i*comp_i
            objective = solver.Objective()
            for j,x in enumerate(xs):
                objective.SetCoefficient(x, comp0[j])
            objective.SetMaximization()

            #solver.EnableOutput()# this line enables output of the CBC MIXED INTEGER PROGRAM (Was hard to find don't delete)
            solver.SetTimeLimit(5*60*1000)#time limit for solver in milliseconds
            cpres = solver.Solve() # actually solve MIP
            x0 = np.array([x.solution_value() for x in xs]) # convert output solutions

            self.scomp0 = np.sum(comp0*x0) # calculate sum Comp from MIP
            self.t0 = t0 # assign calculated t0

            #Observation num x0=0 @ dMagint=25 is 1501
            #Observation num x0=0 @ dMagint=30 is 1501...

            #now find the optimal eps baseline and use whichever gives you the highest starting completeness
            self.vprint('Finding baseline fixed-eps optimal target set.')
            def totCompfeps(eps):
                compstars,tstars,x = self.inttimesfeps(eps, Cbs.to('1/d').value, Csps.to('1/d').value)
                return -np.sum(compstars*x)
            #Note: There is no way to seed an initial solution to minimize scalar 
            #0 and 1 are supposed to be the bounds on epsres. I could define upper bound to be 0.01, However defining the bounds to be 5 lets the solver converge
            epsres = minimize_scalar(totCompfeps,method='bounded',bounds=[0,7], options={'disp': 3, 'xatol':self.ftol, 'maxiter': self.maxiter})  #adding ftol for initial seed. could be different ftol
                #https://docs.scipy.org/doc/scipy/reference/optimize.minimize_scalar-bounded.html#optimize-minimize-scalar-bounded
            comp_epsmax,t_epsmax,x_epsmax = self.inttimesfeps(epsres['x'],Cbs.to('1/d').value, Csps.to('1/d').value)
            if np.sum(comp_epsmax*x_epsmax) > self.scomp0:
                x0 = x_epsmax
                self.scomp0 = np.sum(comp_epsmax*x_epsmax) 
                self.t0 = t_epsmax*x_epsmax*u.day

            ##### Optimize the baseline solution
            self.vprint('Optimizing baseline integration times.')
            sInds = np.arange(self.TargetList.nStars)
            if self.Izod == 'fZ0': # Use fZ0 to calculate integration times
                fZ = np.array([self.ZodiacalLight.fZ0.value]*len(sInds))*self.ZodiacalLight.fZ0.unit
            elif self.Izod == 'fZmin': # Use fZmin to calculate integration times
                fZ = self.valfZmin
            elif self.Izod == 'fZmax': # Use fZmax to calculate integration times
                fZ = self.valfZmax
            elif self.Izod == 'current': # Use current fZ to calculate integration times
                fZ = self.ZodiacalLight.fZ(self.Observatory, self.TargetList, sInds, self.TimeKeeping.currentTimeAbs.copy()+np.zeros(self.TargetList.nStars)*u.d, self.detmode)

            maxIntTimeOBendTime, maxIntTimeExoplanetObsTime, maxIntTimeMissionLife = self.TimeKeeping.get_ObsDetectionMaxIntTime(self.Observatory, self.detmode, self.TimeKeeping.currentTimeNorm.copy())
            maxIntTime   = min(maxIntTimeOBendTime, maxIntTimeExoplanetObsTime, maxIntTimeMissionLife) # Maximum intTime allowed
            bounds = [(0,maxIntTime.to(u.d).value) for i in np.arange(len(sInds))]
            initguess = x0*self.t0.to(u.d).value
            self.save_initguess = initguess


            #While we use all sInds as input, theoretically, this can be solved faster if we use the following lines:
            #sInds = np.asarray([sInd for sInd in sInds if np.bool(x0[sInd])])
            #bounds = [(0,maxIntTime.to(u.d).value) for i in np.arange(len(sInds))]
            #and use initguess[sInds], fZ[sInds], and self.t0[sInds].
            #There was no noticable performance improvement
            ires = minimize(self.objfun, initguess, jac=self.objfun_deriv, args=(sInds,fZ), 
                    constraints=self.constraints, method='SLSQP', bounds=bounds, options={'maxiter':self.maxiter, 'ftol':self.ftol, 'disp': True}) #original method

            assert ires['success'], "Initial time optimization failed."

            self.t0 = ires['x']*u.d
            self.scomp0 = -ires['fun']

            if cacheOptTimes:
                with open(cachefname,'wb') as f:
                    pickle.dump(self.t0, f)
                self.vprint("Saved cached optimized t0 to %s"%cachefname)

        #Redefine filter inds
        self.intTimeFilterInds = np.where((self.t0 > 0.)*(self.t0 <= self.OpticalSystem.intCutoff) > 0.)[0] # These indices are acceptable for use simulating    
Exemple #17
0
    def __init__(self,
                 cacheOptTimes=False,
                 staticOptTimes=False,
                 selectionMetric='maxC',
                 Izod='current',
                 maxiter=60,
                 ftol=1e-3,
                 **specs):  #fZminObs=False,

        #initialize the prototype survey
        SurveySimulation.__init__(self, **specs)

        #Calculate fZmax
        self.valfZmax, self.absTimefZmax = self.ZodiacalLight.calcfZmax(
            np.arange(self.TargetList.nStars), self.Observatory,
            self.TargetList, self.TimeKeeping,
            list(
                filter(lambda mode: mode['detectionMode'] == True,
                       self.OpticalSystem.observingModes))[0], self.cachefname)

        assert isinstance(staticOptTimes,
                          bool), 'staticOptTimes must be boolean.'
        self.staticOptTimes = staticOptTimes
        self._outspec['staticOptTimes'] = self.staticOptTimes

        assert isinstance(cacheOptTimes,
                          bool), 'cacheOptTimes must be boolean.'
        self._outspec['cacheOptTimes'] = cacheOptTimes

        assert selectionMetric in [
            'maxC',
            'Izod-Izodmin',
            'Izod-Izodmax',
            '(Izod-Izodmin)/(Izodmax-Izodmin)',
            '(Izod-Izodmin)/(Izodmax-Izodmin)/CIzod',  #(Izod-Izodmin)/(Izodmax-Izodmin)/CIzodmin is simply this but with Izod='fZmin'
            'TauIzod/CIzod',  #TauIzodmin/CIzodmin is simply this but with Izod='fZmin'
            'random',
            'priorityObs'
        ], 'selectionMetric not valid input'  # Informs what selection metric to use
        self.selectionMetric = selectionMetric
        self._outspec['selectionMetric'] = self.selectionMetric

        assert Izod in [
            'fZmin', 'fZ0', 'fZmax', 'current'
        ], 'Izod not valid input'  # Informs what Izod to optimize integration times for [fZmin, fZmin+45d, fZ0, fZmax, current]
        self.Izod = Izod
        self._outspec['Izod'] = self.Izod

        assert isinstance(
            maxiter, int
        ), 'maxiter is not an int'  # maximum number of iterations to optimize integration times for
        assert maxiter >= 1, 'maxiter must be positive real'
        self.maxiter = maxiter
        self._outspec['maxiter'] = self.maxiter

        assert isinstance(
            ftol, float
        ), 'ftol must be boolean'  # tolerance to place on optimization
        assert ftol > 0, 'ftol must be positive real'
        self.ftol = ftol
        self._outspec['ftol'] = self.ftol

        #some global defs
        self.detmode = list(
            filter(lambda mode: mode['detectionMode'] == True,
                   self.OpticalSystem.observingModes))[0]
        self.ohTimeTot = self.Observatory.settlingTime + self.detmode['syst'][
            'ohTime']  # total overhead time per observation
        self.maxTime = self.TimeKeeping.missionLife * self.TimeKeeping.missionPortion  # total mission time

        self.constraints = {
            'type':
            'ineq',
            'fun':
            lambda x: self.maxTime.to(u.d).value - np.sum(x[
                x * u.d > 0.1 * u.s]) -  #maxTime less sum of intTimes
            np.sum(x * u.d > 0.1 * u.s).astype(float) * self.ohTimeTot.to(u.d).
            value,  # sum of True -> goes to 1 x OHTime
            'jac':
            lambda x: np.ones(len(x)) * -1.
        }

        self.t0 = None
        if cacheOptTimes:
            #Generate cache Name########################################################################
            cachefname = self.cachefname + 't0'

            if os.path.isfile(cachefname):
                self.vprint("Loading cached t0 from %s" % cachefname)
                with open(cachefname, 'rb') as f:
                    self.t0 = pickle.load(f)
                sInds = np.arange(self.TargetList.nStars)
                fZ = np.array([self.ZodiacalLight.fZ0.value] *
                              len(sInds)) * self.ZodiacalLight.fZ0.unit
                self.scomp0 = -self.objfun(self.t0.to('day').value, sInds, fZ)

        if self.t0 is None:
            #1. find nominal background counts for all targets in list
            dMagint = 25.0  # this works fine for WFIRST
            _, Cbs, Csps = self.OpticalSystem.Cp_Cb_Csp(
                self.TargetList,
                np.arange(self.TargetList.nStars),
                self.ZodiacalLight.fZ0,
                self.ZodiacalLight.fEZ0,
                dMagint,
                self.WAint,
                self.detmode,
                TK=self.TimeKeeping)

            #find baseline solution with dMagLim-based integration times
            #3.
            self.vprint('Finding baseline fixed-time optimal target set.')
            t0 = self.OpticalSystem.calc_intTime(self.TargetList,
                                                 np.arange(
                                                     self.TargetList.nStars),
                                                 self.ZodiacalLight.fZ0,
                                                 self.ZodiacalLight.fEZ0,
                                                 self.dMagint,
                                                 self.WAint,
                                                 self.detmode,
                                                 TK=self.TimeKeeping)
            #4.
            comp0 = self.Completeness.comp_per_intTime(
                t0,
                self.TargetList,
                np.arange(self.TargetList.nStars),
                self.ZodiacalLight.fZ0,
                self.ZodiacalLight.fEZ0,
                self.WAint,
                self.detmode,
                C_b=Cbs,
                C_sp=Csps,
                TK=self.TimeKeeping)

            #### 5. Formulating MIP to filter out stars we can't or don't want to reasonably observe
            solver = pywraplp.Solver(
                'SolveIntegerProblem', pywraplp.Solver.
                CBC_MIXED_INTEGER_PROGRAMMING)  # create solver instance
            xs = [
                solver.IntVar(0.0, 1.0, 'x' + str(j))
                for j in np.arange(len(comp0))
            ]  # define x_i variables for each star either 0 or 1

            #constraint is x_i*t_i < maxtime
            constraint = solver.Constraint(-solver.infinity(),
                                           self.maxTime.to(u.day).value)
            for j, x in enumerate(xs):
                constraint.SetCoefficient(
                    x, t0[j].to('day').value + self.ohTimeTot.to(
                        u.day).value)  # this forms x_i*(t_0i+OH) for all i

            #objective is max x_i*comp_i
            objective = solver.Objective()
            for j, x in enumerate(xs):
                objective.SetCoefficient(x, comp0[j])
            objective.SetMaximization()

            #solver.EnableOutput()# this line enables output of the CBC MIXED INTEGER PROGRAM (Was hard to find don't delete)
            solver.SetTimeLimit(5 * 60 *
                                1000)  #time limit for solver in milliseconds
            cpres = solver.Solve()  # actually solve MIP
            x0 = np.array([x.solution_value()
                           for x in xs])  # convert output solutions

            self.scomp0 = np.sum(comp0 * x0)  # calculate sum Comp from MIP
            self.t0 = t0  # assign calculated t0

            #Observation num x0=0 @ dMagint=25 is 1501
            #Observation num x0=0 @ dMagint=30 is 1501...

            #now find the optimal eps baseline and use whichever gives you the highest starting completeness
            self.vprint('Finding baseline fixed-eps optimal target set.')

            def totCompfeps(eps):
                compstars, tstars, x = self.inttimesfeps(
                    eps,
                    Cbs.to('1/d').value,
                    Csps.to('1/d').value)
                return -np.sum(compstars * x)

            #Note: There is no way to seed an initial solution to minimize scalar
            #0 and 1 are supposed to be the bounds on epsres. I could define upper bound to be 0.01, However defining the bounds to be 5 lets the solver converge
            epsres = minimize_scalar(
                totCompfeps,
                method='bounded',
                bounds=[0, 7],
                options={
                    'disp': 3,
                    'xatol': self.ftol,
                    'maxiter': self.maxiter
                })  #adding ftol for initial seed. could be different ftol
            #https://docs.scipy.org/doc/scipy/reference/optimize.minimize_scalar-bounded.html#optimize-minimize-scalar-bounded
            comp_epsmax, t_epsmax, x_epsmax = self.inttimesfeps(
                epsres['x'],
                Cbs.to('1/d').value,
                Csps.to('1/d').value)
            if np.sum(comp_epsmax * x_epsmax) > self.scomp0:
                x0 = x_epsmax
                self.scomp0 = np.sum(comp_epsmax * x_epsmax)
                self.t0 = t_epsmax * x_epsmax * u.day

            ##### Optimize the baseline solution
            self.vprint('Optimizing baseline integration times.')
            sInds = np.arange(self.TargetList.nStars)
            if self.Izod == 'fZ0':  # Use fZ0 to calculate integration times
                fZ = np.array([self.ZodiacalLight.fZ0.value] *
                              len(sInds)) * self.ZodiacalLight.fZ0.unit
            elif self.Izod == 'fZmin':  # Use fZmin to calculate integration times
                fZ = self.valfZmin
            elif self.Izod == 'fZmax':  # Use fZmax to calculate integration times
                fZ = self.valfZmax
            elif self.Izod == 'current':  # Use current fZ to calculate integration times
                fZ = self.ZodiacalLight.fZ(
                    self.Observatory, self.TargetList, sInds,
                    self.TimeKeeping.currentTimeAbs.copy() +
                    np.zeros(self.TargetList.nStars) * u.d, self.detmode)

            maxIntTimeOBendTime, maxIntTimeExoplanetObsTime, maxIntTimeMissionLife = self.TimeKeeping.get_ObsDetectionMaxIntTime(
                self.Observatory, self.detmode,
                self.TimeKeeping.currentTimeNorm.copy())
            maxIntTime = min(maxIntTimeOBendTime, maxIntTimeExoplanetObsTime,
                             maxIntTimeMissionLife)  # Maximum intTime allowed
            bounds = [(0, maxIntTime.to(u.d).value)
                      for i in np.arange(len(sInds))]
            initguess = x0 * self.t0.to(u.d).value
            self.save_initguess = initguess

            #While we use all sInds as input, theoretically, this can be solved faster if we use the following lines:
            #sInds = np.asarray([sInd for sInd in sInds if np.bool(x0[sInd])])
            #bounds = [(0,maxIntTime.to(u.d).value) for i in np.arange(len(sInds))]
            #and use initguess[sInds], fZ[sInds], and self.t0[sInds].
            #There was no noticable performance improvement
            ires = minimize(self.objfun,
                            initguess,
                            jac=self.objfun_deriv,
                            args=(sInds, fZ),
                            constraints=self.constraints,
                            method='SLSQP',
                            bounds=bounds,
                            options={
                                'maxiter': self.maxiter,
                                'ftol': self.ftol,
                                'disp': True
                            })  #original method

            assert ires['success'], "Initial time optimization failed."

            self.t0 = ires['x'] * u.d
            self.scomp0 = -ires['fun']

            if cacheOptTimes:
                with open(cachefname, 'wb') as f:
                    pickle.dump(self.t0, f)
                self.vprint("Saved cached optimized t0 to %s" % cachefname)

        #Redefine filter inds
        self.intTimeFilterInds = np.where(
            (self.t0 > 0.) * (self.t0 <= self.OpticalSystem.intCutoff) > 0.)[
                0]  # These indices are acceptable for use simulating
Exemple #18
0
 def __init__(self, **specs):
     
     SurveySimulation.__init__(self, **specs)