def main(argv): path = os.path.expanduser('~/Documents/data_old/OPD40cm/20130809/') airmasstables = ['G9348/timeairmass.dat', 'SA111773/timeairmass.dat', 'SA114750/timeairmass.dat'] #airmasstables = ['SA114750/timeairmass.dat'] targetRa = [21.8736111111111,19.6211111111111,22.6958333333333] targetDec = [2.38888888888889,0.183055555555556,1.21055555555556] sitelat =-25.3416666667 sitelong = 3.21148148148 #airmasstables = np.loadtxt(os.path.join(path,airmasstableslis),dtype='S',ndmin=1) T0 = 2456514. nightstart = 2456514.4 nightend = 2456514.85 timeStamp = np.linspace(nightstart,nightend,1e3) lstStamp = [_skysub.lst(time,sitelong) for time in timeStamp] ax = py.subplot(111) ylim = [0,0.5] color = ['b','r','g','y','c','m', 'k'] for i in range(len(airmasstables)): data = np.loadtxt(os.path.join(path,airmasstables[i]),unpack=True,converters={0:datestr2JD}) secz = np.array([_skysub.true_airmass(_skysub.secant_z(_skysub.altit(targetDec[i],lst - targetRa[i],sitelat)[0])) for lst in lstStamp]) data[1] = np.array([_skysub.true_airmass(_skysub.secant_z(_skysub.altit(targetDec[i],_skysub.lst(time,sitelong) - targetRa[i],sitelat)[0])) for time in data[0]]) mm = np.bitwise_and(data[1] > 0, data[1] < 3) py.plot(data[0][mm]-T0,np.log10(data[1][mm]),color[i]+'o') py.plot(data[0][mm]-T0,np.log10(data[1][mm]),color[i]+'o') mm = np.bitwise_and(secz > 0, secz < 3) py.plot(timeStamp[mm]-T0,np.log10(secz[mm]),color[i]+'-') py.plot([nightstart-T0,nightstart-T0],ylim,'k--',lw=1.1,alpha=1.0) py.plot([nightend-T0,nightend-T0],ylim,'k--',lw=1.1,alpha=1.0) py.ylim(ylim[1],ylim[0]) a=ax.get_yticks().tolist() print a newyticks = ['%.2f'%(10**(val)) for val in a] print newyticks ax.set_yticklabels(newyticks) py.ylabel('airmass',size=18) py.xlabel('JD - %.0f'%T0,size=18) py.savefig(os.path.expanduser('~/Develop/SMAPs/Figures/plot_airmasses_obs.pdf')) py.show() return 0
def getTargets(T0,T1,RA,DEC,mask,texp,sitelat,sitelong): obsmask = mask tbin = 0 ra = RA[obsmask] dec = DEC[obsmask] mm = obsmask[obsmask] targets = np.zeros(len(np.arange(T0,T1,texp))) xaxis = np.arange(len(RA))[obsmask] # Rejecting objects that are close to the moon for time in np.arange(T0,T1,texp): ra = RA[obsmask] dec = DEC[obsmask] xaxis = np.arange(len(RA))[obsmask] lst = _skysub.lst(time,sitelong) #*360./24. ha = lst - ra alt = np.array([_skysub.altit(dec[i],ha[i],sitelat)[0] for i in range(len(ha))]) stg = alt.argmax() mm = obsmask[obsmask] mm[stg] = False obsmask[obsmask] = mm targets[tbin] = xaxis[stg] tbin+=1 #print i return targets
def airmass(ra,dec,time,sitelat,sitelong): lst = _skysub.lst(time,sitelong) #*360./24. ha = lst - ra alt = _skysub.altit(dec,ha,sitelat)[0] return alt
def computesky(self): # computes many quantities so they're self-consistent sidtemp = _skysub.lst(self.jd, self.longit) self.sidereal = ra(sidtemp) # it behaves like an RA self.decimalyr = self.julian_epoch() self.CoordsOfDate = self.precess(self.julian_epoch()) self.hanow = ha(self.sidereal.val - self.CoordsOfDate.ra.val) [self.altit,self.az,self.parang] = \ _skysub.altit(self.CoordsOfDate.dec.val,self.hanow.val, \ self.lat) self.secz = _skysub.secant_z(self.altit) self.airmass = _skysub.true_airmass(self.secz)
def computesky(self) : # computes many quantities so they're self-consistent sidtemp = _skysub.lst(self.jd,self.longit) self.sidereal = ra(sidtemp) # it behaves like an RA self.decimalyr = self.julian_epoch() self.CoordsOfDate = self.precess(self.julian_epoch()) self.hanow = ha(self.sidereal.val - self.CoordsOfDate.ra.val) [self.altit,self.az,self.parang] = \ _skysub.altit(self.CoordsOfDate.dec.val,self.hanow.val, \ self.lat) self.secz = _skysub.secant_z(self.altit) self.airmass = _skysub.true_airmass(self.secz)
def selectScienceTargets(self): ''' Based on configuration parameters select a good set of targets to run scheduler on a specified Julian Day. ''' session = Session() # [To be done] Reject objects that are close to the moon for tbin, time in enumerate(self.obsTimeBins): if self.obsTimeMask[tbin] < 1.0: # Select objects from database that where not observed and where not scheduled yet # In the future may include targets that where observed a number of nights ago. # This is still incomplete. We should also consider the distance from the previous pointing to the next! # Since a target can have a higher airmass but be farther away from a neaby target that will take less time # to point. # one way of selecting targets that are close together and have good airmass is to select regions that are close # to the current location. it can start as searching an area with r1 ~ 10 x the FoV and, if there are no regions # to to x2 that and then x4 that. If still there are no targets, than search for the higher in the sky. targets = session.query(Targets).filter( Targets.observed == False).filter( Targets.scheduled == False).filter( Targets.type == self.sciFlag) lst = _skysub.lst(time, self.sitelong) #*360./24. alt = np.array([ _skysub.altit(target.targetDec, lst - target.targetRa, self.sitelat)[0] for target in targets ]) stg = alt.argmax() log.info('Selecting %s' % (targets[stg])) # Marking target as schedule tst = session.query(Targets).filter( Targets.id == targets[stg].id) for t in tst: t.scheduled = True session.commit() self.addObservation(t, time) self.obsTimeMask[tbin] = 1.0 else: log.debug( 'Bin %3i @mjd=%.3f already filled up with observations. Skipping...' % (tbin, time - 2400000.5)) #print i return 0 #targets
def __init__(self,ra,dec,ii,jj,ntrays,exptime): # Default observatory information self.sitelat = -30.228 self.sitelong = 4.715 # Default sun Max Alt (defines star/end of night) self.sunMaxAlt = -18. self.fullmoon = 0.95 self.vfac = 0.65 self.rvfac = 0.5 # Store tiles coordinate information self._ii = np.array(ii) self._jj = np.array(jj) self._ra = np.array(ra) self._dec = np.array(dec) # Store maximum altitude of tiles self.maxAltit = [] for i in range(ntrays): self.maxAltit.append(np.array([_skysub.altit(self._dec[i][j],0.,self.sitelat)[0] for j in range(len(ra[i]))])) if len(exptime) != ntrays: raise IOError('Number of trays/filters must match number of exposure times. ') self.ntrays = ntrays # Number of trays/filters self.exptime = np.array(exptime) # Store which observation where performed or not self.obs = [] for i in range(ntrays): self.obs.append(np.zeros(len(ii[i]))==0) # Store tiles to be repeated # tile - tile index # day - day to be repeated # nrepeat - number of times to repeat # nobs - number of times tile was observed self.repeatInfo = { 'tile' : np.arange(len(self._ra)), 'day' : np.zeros(len(self._ra)), 'nobs' : np.zeros(len(self._ra),dtype=int)} self._repeatTray = 0 self.rexptime = 0 self._nrepeat = 0 self._dTime = 0
def selectScienceTargets(self): ''' Based on configuration parameters select a good set of targets to run scheduler on a specified Julian Day. ''' session = Session() # [To be done] Reject objects that are close to the moon for tbin,time in enumerate(self.obsTimeBins): if self.obsTimeMask[tbin] < 1.0: # Select objects from database that where not observed and where not scheduled yet # In the future may include targets that where observed a number of nights ago. # This is still incomplete. We should also consider the distance from the previous pointing to the next! # Since a target can have a higher airmass but be farther away from a neaby target that will take less time # to point. # one way of selecting targets that are close together and have good airmass is to select regions that are close # to the current location. it can start as searching an area with r1 ~ 10 x the FoV and, if there are no regions # to to x2 that and then x4 that. If still there are no targets, than search for the higher in the sky. targets = session.query(Targets).filter(Targets.observed == False).filter(Targets.scheduled == False).filter(Targets.type == self.sciFlag) lst = _skysub.lst(time,self.sitelong) #*360./24. alt = np.array([_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0] for target in targets]) stg = alt.argmax() self.log.info('Selecting %s'%(targets[stg])) # Marking target as schedule tst = session.query(Targets).filter(Targets.id == targets[stg].id) for t in tst: t.scheduled = True session.commit() self.addObservation(t,time) self.obsTimeMask[tbin] = 1.0 else: self.log.debug('Bin %3i @mjd=%.3f already filled up with observations. Skipping...'%(tbin,time-2400000.5)) #print i return 0 #targets
def make_obs(T0,T1,RA,DEC,mask,texp): obsmask = np.bitwise_and(np.zeros(len(RA),dtype=int)==0,mask) i = 0 for time in np.arange(T0,T1,texp): lst = _skysub.lst(time,sitelong)*360./24. #lst = _skysub.lst(time,sitelong) #*360./24. ha = lst - RA[obsmask] alt = np.array([_skysub.altit(DEC[obsmask][i],ha[i],sitelat)[0] for i in range(len(ha))]) stg = alt.argmax() #print time,lst,np.sqrt(dist1[stg]),np.sqrt(dist2[stg]),dist[stg],RA[obsmask][stg],DEC[obsmask][stg],stg mm = obsmask[obsmask] mm[stg] = False obsmask[obsmask] = mm i+=1 #print i return obsmask
def selectStandardTargets(self,nstars=3,nairmass=3): ''' Based on configuration parameters, select 'nstars' standard stars to run scheduler on a specified Julian Day. Ideally you will select standard stars before your science targets so not to have a full queue. Usually standard stars are observed more than once a night at different airmasses. The user can control this parameter with nairmass and the script will try to take care of the rest. ''' session = Session() # First of all, standard stars can be obsered multiple times in sucessive nights. I will mark all # stars an unscheduled. targets = session.query(Targets).filter(Targets.scheduled == True).filter(Targets.type == self.stdFlag) for target in targets: target.scheduled = False session.commit() # [To be done] Reject objects that are close to the moon # Selecting standard stars is not only searching for the higher in that time but select stars than can be observed at 3 # or more (nairmass) different airmasses. It is also important to select stars with different colors (but this will be # taken care in the future). if nairmass*nstars > len(self.obsTimeBins): self.log.warning('Requesting more stars/observations than it will be possible to schedule. Decreasing number of requests to fit in the night.') nstars = len(self.obsTimeBins)/nairmass obsStandars = np.zeros(len(self.obsTimeBins))-1 # first selection of observable standards for tbin,time in enumerate(self.obsTimeBins): if self.obsTimeMask[tbin] < 1.0: # 1 - Select objects from database that where not scheduled yet (standard stars may be repited) # that fits our observing night targets = session.query(Targets).filter(Targets.scheduled == 0).filter(Targets.type == self.stdFlag) lst = _skysub.lst(time,self.sitelong) #*360./24. alt = np.array([_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0] for target in targets]) stg = alt.argmax() self.log.info('Selecting %s'%(targets[stg])) # Marking target as schedule tst = session.query(Targets).filter(Targets.id == targets[stg].id) for t in tst: t.scheduled = True session.commit() obsStandars[tbin] = t.id else: self.log.info('Bin already filled up with observations. Skipping...') if len(obsStandars[obsStandars >= 0]) < nstars: self.log.warning('Could not find %i suitable standard stars in catalog. Only %i where found.'%(nstars,len(obsStandars[obsStandars >= 0]))) # # Unmarking potential targets as scheduled # for id in obsStandars[obsStandars >= 0]: target = session.query(Targets).filter(Targets.id == id) for t in target: t.scheduled = False session.commit() tbin+=1 # # Preparing a grid of altitudes for each target for each observing window # amGrid = np.zeros(len(obsStandars)*len(obsStandars)).reshape(len(obsStandars),len(obsStandars)) for i in np.arange(len(obsStandars))[obsStandars >= 0]: target = session.query(Targets).filter(Targets.id == obsStandars[i])[0] for j in range(len(obsStandars)): lst = _skysub.lst(self.obsTimeBins[j],self.sitelong) amGrid[i][j] = _skysub.true_airmass(_skysub.secant_z(_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0])) if amGrid[i][j] < 0: amGrid [i][j] = 99. # # Build a grid mask that specifies the position in time each target should be observed. This means that, when # selecting a single target we ocuppy more than one, non consecutive, position in the night. This grid shows where are these # positions. # obsMask = np.zeros(len(obsStandars)*len(obsStandars),dtype=np.bool).reshape(len(obsStandars),len(obsStandars)) for i in np.arange(len(obsStandars))[obsStandars >= 0]: amObs = np.linspace(amGrid[i].min(),self.stdMaxAirmass,nairmass) # requested aimasses dam = np.mean(np.abs(amGrid[i][amGrid[i]<self.stdMaxAirmass][1:] - amGrid[i][amGrid[i]<self.stdMaxAirmass][:-1])) # how much airmass changes in average for j,am in enumerate(amObs): # Mark positions where target is at specified airmass if j == 0: obsMask[i] = np.bitwise_or(obsMask[i],amGrid[i] == am) else: obsMask[i] = np.bitwise_or(obsMask[i],np.bitwise_and(amGrid[i]>am-dam,amGrid[i]<am+dam)) #print amGrid[i][np.where(obsMask[i])] # # Now it is time to actually select the targets. It will start with the first target and then try the others # until it find enough standard stars, as specified by the user. # # Para cada bin em tempo, varro o bin em massa de ar por coisas observaveis. Se acho um, vejo se posso agendar # os outros bins. Se sim, marco o alvo para observacao, se nao, passo para o proximo. Repito ate completar a # lista de alvos # obsMaskTimeGrid = np.zeros(len(obsStandars),dtype=np.bool) nrequests = 0 reqId = np.zeros(nstars,dtype=np.int)-1 for tbin,time in enumerate(self.obsTimeBins[:-1]): # Evaluates if time slots are all available. If yes, mark orbservation and ocuppy slots. if ( (not obsMaskTimeGrid[obsMask[tbin]].any()) and (len(amGrid[tbin][obsMask[tbin]])>=nairmass) ): obsMaskTimeGrid = np.bitwise_or(obsMaskTimeGrid,obsMask[tbin]) reqId[nrequests] = tbin nrequests += 1 if nrequests >= nstars: break # Finally, requesting observations for id in reqId[reqId >= 0]: target = session.query(Targets).filter(Targets.id == obsStandars[id])[0] secz = amGrid[id][obsMask[id]] seczreq = np.zeros(nairmass,dtype=np.bool) amObs = np.linspace(amGrid[id].min(),self.stdMaxAirmass,nairmass) # requested aimasses for i,obstime in enumerate(self.obsTimeBins[obsMask[id]]): sindex = np.abs(amObs-secz[i]).argmin() if not seczreq[sindex]: self.log.info('Requesting observations of %s @airmass=%4.2f @mjd=%.3f...'%(target.name,secz[i],obstime-2400000.5)) seczreq[sindex] = True target.scheduled = True session.commit() self.addObservation(target,obstime) self.obsTimeMask[obsMask[id]] = 1.0 #print self.obsTimeBins[obsMask[id]] #print #print i return 0 #targets
def makeObs(self,T0,T1): time = T0 hd = 1./24 maskRep = [] if self._nrepeat > 0: maskRep = np.bitwise_and(self.repeatInfo['day'] > 0,self.repeatInfo['nobs'] < self._nrepeat) else: maskRep = self.repeatInfo['day'] > 0 info = ['Observations start @ JD = %12.2f'%T0, 'Observations end @ JD = %12.2f'%T1, 'Total number of tiles: %5i'%self.nTiles(), 'Tiles to observe: %5i'%(self.obsTiles()), 'Tiles to repeate: %5i'%(len(maskRep[maskRep])) ] # count time spent observing each tray obsTime = np.zeros(self.ntrays+1) # Calculate moon for this night queue = [] ramoon = 0. decmoon = 0. distmoon = 0. rasun = 0. decsun = 0. ramoon,decmoon,distmoon = _skysub.lpmoon(T0,self.sitelat,_skysub.lst(T0,self.sitelong)) ill_frac=0.5*(1.-np.cos(_skysub.subtend(ramoon,decmoon,rasun,decsun))) fullmoon = False if ill_frac >= self.fullmoon: fullmoon = True info.append('Full moon (%5.1f)'%(ill_frac*100)) obsTime[-1] = (T1-T0) else: info.append('Moon %5.1f '%(ill_frac*100.)) cra = -99 cdec = -99 while time < T1 and not fullmoon: obsDone = False tray = 0 obsTile = -1 # Trying the first tray while ( (not obsDone) and (0 <= tray < self.ntrays) ): # Local Sidereal time at start -2hours and end +2hours lst_start = _skysub.lst(time-2.*hd,self.sitelong) lst_end = _skysub.lst(time+self.exptime[tray]+2.*hd,self.sitelong) # Check if there is observation to be repeated this night. if self._nrepeat > 0: maskRep = np.bitwise_and(np.bitwise_and(self.repeatInfo['day'] > 0, self.repeatInfo['day'] <= time),self.repeatInfo['nobs'] < self._nrepeat) else: maskRep = np.bitwise_and(self.repeatInfo['day'] > 0, self.repeatInfo['day'] <= time) ra_mask = self.raMask(self._repeatTray,lst_start,lst_end) repeated = False if len(maskRep[maskRep]) > 0: ra_tmpmask = np.bitwise_and(ra_mask,maskRep) if ra_tmpmask.any(): # make repeate observation index = np.arange(len(self._ra[self._repeatTray]))[ra_tmpmask] # Selecting highest in the sky at the center of the observation lst = _skysub.lst(time+self.exptime[self._repeatTray]/2.,self.sitelong)*360./24. ha = (lst - self._ra[self._repeatTray][ra_tmpmask])*24./360. alt = np.array([_skysub.altit(self._dec[self._repeatTray][j],ha[i],self.sitelat)[0] for i,j in enumerate(index)]) if len(alt) == 0: info.append('[R] No observable tiles available...') else: stg = alt.argmax() if alt[stg] > self.maxAltit[self._repeatTray][index[stg]]*self.rvfac: info.append('[R] Observation complete... ') self.repeatInfo['nobs'][index[stg]] += 1 self.repeatInfo['day'][index[stg]] += self._dTime obsDone = True repeated = True tray = self._repeatTray else: info.append('[R] Object too low. Alt = %7.2f, Max Alt = %7.2f... '%(alt[stg],self.maxAltit[self._repeatTray][index[stg]])) ra_mask = self.raMask(tray,lst_start,lst_end) # Check if makes sense to continue if ra_mask.any() and not obsDone: info.append('Number of observable tiles %4i'%len(ra_mask[ra_mask])) index = np.arange(len(self._ra[tray]))[np.bitwise_and(ra_mask,self.obs[tray])] # Selecting highest in the sky at the center of the observation lst = _skysub.lst(time+self.exptime[tray]/2.,self.sitelong)*360./24. #lst = _skysub.lst(time,sitelong) #*360./24. ha = (lst - self._ra[tray][ra_mask])*24./360. alt = np.array([_skysub.altit(self._dec[tray][j],ha[i],self.sitelat)[0] for i,j in enumerate(index)]) if len(alt) == 0: info.append('No observable tiles available...') # Go to next tray tray+=1 else: #info.append(['Suitable tile available...']) stg = alt.argmax() if alt[stg] > self.maxAltit[tray][index[stg]]*self.vfac: info.append('Observation complete... ') obsTile = index[stg] obsDone = True # check if needs to be repeated if tray == self._repeatTray and self.repeatInfo['nobs'][index[stg]] < self._nrepeat and self.repeatInfo['day'][index[stg]] < time: self.repeatInfo['day'][index[stg]] = time+self._dTime elif tray == self._repeatTray and self.repeatInfo['day'][index[stg]] < time and self._nrepeat < 0: self.repeatInfo['day'][index[stg]] = time+self._dTime else: obsDone = False info.append('Object too low. Alt = %7.2f, Max Alt = %7.2f... '%(alt[stg],self.maxAltit[tray][index[stg]]*self.vfac)) # Go to next tray tray+=1 elif repeated: tray = -self._repeatTray else: tray = -1 info.append('No tiles available...') tray = np.abs(tray) # Check if observation was performed and in which tray if obsDone: if repeated: obsTime[tray]+=self.rexptime time+=self.rexptime else: obsTime[tray]+=self.exptime[tray] time+=self.exptime[tray] self.obs[tray][obsTile] = False queue.append('TILE%05i %6.2f %+7.2f %16.6f %2i %8.3f'%(obsTile,self._ra[tray][obsTile],self._dec[tray][obsTile],time,tray,self.exptime[tray])) else: # Try one more time # See if there is any field to be repeated in the sky maskRep = self.repeatInfo['day'] > 0 lst_start = _skysub.lst(time-3.*hd,self.sitelong) lst_end = _skysub.lst(time+self.rexptime+3.*hd,self.sitelong) ra_mask = self.raMask(self._repeatTray,lst_start,lst_end) repeated = False idx = 0 if len(maskRep[maskRep]) > 0: ra_tmpmask = np.bitwise_and(ra_mask,maskRep) if ra_tmpmask.any(): # make repeate observation index = np.arange(len(self._ra[self._repeatTray]))[ra_tmpmask] # Selecting highest in the sky at the center of the observation lst = _skysub.lst(time+self.exptime[self._repeatTray]/2.,self.sitelong)*360./24. ha = (lst - self._ra[self._repeatTray][ra_tmpmask])*24./360. alt = np.array([_skysub.altit(self._dec[self._repeatTray][j],ha[i],self.sitelat)[0] for i,j in enumerate(index)]) if len(alt) == 0: info.append('[R] No observable tiles available...') else: stg = alt.argmax() if alt[stg] > self.maxAltit[self._repeatTray][index[stg]]*self.rvfac: info.append('[R] Observation complete... ') self.repeatInfo['nobs'][index[stg]] += 1 self.repeatInfo['day'][index[stg]] += self._dTime obsDone = True repeated = True tray = -self._repeatTray idx = index[stg] else: obsDone = False info.append('[R] Object too low. Alt = %7.2f, Max Alt = %7.2f [RR]... '%(alt[stg],self.maxAltit[self._repeatTray][index[stg]]*self.rvfac)) if obsDone: obsTime[self._repeatTray] += self.rexptime time+=self.rexptime else: obsTime[-1] += self.exptime.max() time+=self.exptime.max() queueInfo = '%16.6f %6.3f '%(T0,(T1-T0)*24.) for tray in range(len(obsTime)): queueInfo += '%10.7f '%(obsTime[tray]*24.) return info,queue,queueInfo
def selectStandardTargets(self, nstars=3, nairmass=3): ''' Based on configuration parameters, select 'nstars' standard stars to run scheduler on a specified Julian Day. Ideally you will select standard stars before your science targets so not to have a full queue. Usually standard stars are observed more than once a night at different airmasses. The user can control this parameter with nairmass and the script will try to take care of the rest. ''' session = Session() # First of all, standard stars can be obsered multiple times in sucessive nights. I will mark all # stars an unscheduled. targets = session.query(Targets).filter( Targets.scheduled == True).filter(Targets.type == self.stdFlag) for target in targets: target.scheduled = False session.commit() # [To be done] Reject objects that are close to the moon # Selecting standard stars is not only searching for the higher in that time but select stars than can be observed at 3 # or more (nairmass) different airmasses. It is also important to select stars with different colors (but this will be # taken care in the future). if nairmass * nstars > len(self.obsTimeBins): log.warning( 'Requesting more stars/observations than it will be possible to schedule. Decreasing number of requests to fit in the night.' ) nstars = len(self.obsTimeBins) / nairmass obsStandars = np.zeros(len( self.obsTimeBins)) - 1 # first selection of observable standards for tbin, time in enumerate(self.obsTimeBins): if self.obsTimeMask[tbin] < 1.0: # 1 - Select objects from database that where not scheduled yet (standard stars may be repited) # that fits our observing night targets = session.query(Targets).filter( Targets.scheduled == 0).filter( Targets.type == self.stdFlag) lst = _skysub.lst(time, self.sitelong) #*360./24. alt = np.array([ _skysub.altit(target.targetDec, lst - target.targetRa, self.sitelat)[0] for target in targets ]) stg = alt.argmax() log.info('Selecting %s' % (targets[stg])) # Marking target as schedule tst = session.query(Targets).filter( Targets.id == targets[stg].id) for t in tst: t.scheduled = True session.commit() obsStandars[tbin] = t.id else: log.info( 'Bin already filled up with observations. Skipping...') if len(obsStandars[obsStandars >= 0]) < nstars: log.warning( 'Could not find %i suitable standard stars in catalog. Only %i where found.' % (nstars, len(obsStandars[obsStandars >= 0]))) # # Unmarking potential targets as scheduled # for id in obsStandars[obsStandars >= 0]: target = session.query(Targets).filter(Targets.id == id) for t in target: t.scheduled = False session.commit() tbin += 1 # # Preparing a grid of altitudes for each target for each observing window # amGrid = np.zeros(len(obsStandars) * len(obsStandars)).reshape( len(obsStandars), len(obsStandars)) for i in np.arange(len(obsStandars))[obsStandars >= 0]: target = session.query(Targets).filter( Targets.id == obsStandars[i])[0] for j in range(len(obsStandars)): lst = _skysub.lst(self.obsTimeBins[j], self.sitelong) amGrid[i][j] = _skysub.true_airmass( _skysub.secant_z( _skysub.altit(target.targetDec, lst - target.targetRa, self.sitelat)[0])) if amGrid[i][j] < 0: amGrid[i][j] = 99. # # Build a grid mask that specifies the position in time each target should be observed. This means that, when # selecting a single target we ocuppy more than one, non consecutive, position in the night. This grid shows where are these # positions. # obsMask = np.zeros(len(obsStandars) * len(obsStandars), dtype=np.bool).reshape(len(obsStandars), len(obsStandars)) for i in np.arange(len(obsStandars))[obsStandars >= 0]: amObs = np.linspace(amGrid[i].min(), self.stdMaxAirmass, nairmass) # requested aimasses dam = np.mean( np.abs(amGrid[i][amGrid[i] < self.stdMaxAirmass][1:] - amGrid[i][amGrid[i] < self.stdMaxAirmass][:-1]) ) # how much airmass changes in average for j, am in enumerate(amObs): # Mark positions where target is at specified airmass if j == 0: obsMask[i] = np.bitwise_or(obsMask[i], amGrid[i] == am) else: obsMask[i] = np.bitwise_or( obsMask[i], np.bitwise_and(amGrid[i] > am - dam, amGrid[i] < am + dam)) #print amGrid[i][np.where(obsMask[i])] # # Now it is time to actually select the targets. It will start with the first target and then try the others # until it find enough standard stars, as specified by the user. # # Para cada bin em tempo, varro o bin em massa de ar por coisas observaveis. Se acho um, vejo se posso agendar # os outros bins. Se sim, marco o alvo para observacao, se nao, passo para o proximo. Repito ate completar a # lista de alvos # obsMaskTimeGrid = np.zeros(len(obsStandars), dtype=np.bool) nrequests = 0 reqId = np.zeros(nstars, dtype=np.int) - 1 for tbin, time in enumerate(self.obsTimeBins[:-1]): # Evaluates if time slots are all available. If yes, mark orbservation and ocuppy slots. if ((not obsMaskTimeGrid[obsMask[tbin]].any()) and (len(amGrid[tbin][obsMask[tbin]]) >= nairmass)): obsMaskTimeGrid = np.bitwise_or(obsMaskTimeGrid, obsMask[tbin]) reqId[nrequests] = tbin nrequests += 1 if nrequests >= nstars: break # Finally, requesting observations for id in reqId[reqId >= 0]: target = session.query(Targets).filter( Targets.id == obsStandars[id])[0] secz = amGrid[id][obsMask[id]] seczreq = np.zeros(nairmass, dtype=np.bool) amObs = np.linspace(amGrid[id].min(), self.stdMaxAirmass, nairmass) # requested aimasses for i, obstime in enumerate(self.obsTimeBins[obsMask[id]]): sindex = np.abs(amObs - secz[i]).argmin() if not seczreq[sindex]: log.info( 'Requesting observations of %s @airmass=%4.2f @mjd=%.3f...' % (target.name, secz[i], obstime - 2400000.5)) seczreq[sindex] = True target.scheduled = True session.commit() self.addObservation(target, obstime) self.obsTimeMask[obsMask[id]] = 1.0 #print self.obsTimeBins[obsMask[id]] #print #print i return 0 #targets
def computesunmoon(self): [ras,decs,dists,toporas,topodecs,xs,ys,zs] = \ _skysub.accusun(self.jd, self.sidereal.val,self.lat) self.SunCoords = celest([ras, decs, self.julian_epoch()]) self.hasun = ha(self.sidereal.val - self.SunCoords.ra.val) [self.altsun,self.azsun,parangsun] = \ _skysub.altit(self.SunCoords.dec.val,self.hasun.val,\ self.lat) self.ztwilight = _skysub.ztwilight(self.altsun) [georam,geodm,geodism,toporam,topodecm,topodistm] = \ _skysub.accumoon(self.jd,self.lat,self.sidereal.val, self.elevsea) self.MoonCoords = celest([toporam, topodecm, self.julian_epoch()]) self.hamoon = ha(self.sidereal.val - self.MoonCoords.ra.val) [self.altmoon,self.azmoon,parangmoon] = \ _skysub.altit(self.MoonCoords.dec.val,self.hamoon.val,\ self.lat) self.sun_moon = _skysub.subtend(self.MoonCoords.ra.val, self.MoonCoords.dec.val, self.SunCoords.ra.val, self.SunCoords.dec.val) # radians self.moonillfrac = 0.5 * (1. - math.cos(self.sun_moon)) self.sun_moon = self.sun_moon * _skysub.DEG_IN_RADIAN self.obj_moon = _skysub.subtend( self.MoonCoords.ra.val, self.MoonCoords.dec.val, self.CoordsOfDate.ra.val, self.CoordsOfDate.dec.val) * _skysub.DEG_IN_RADIAN self.lunsky = _skysub.lunskybright(self.sun_moon, self.obj_moon, 0.17, self.altmoon, self.altit, topodistm) [self.barytcor, self.baryvcor] = _skysub.helcor(self.jd, self.CoordsOfDate.ra.val, self.CoordsOfDate.dec.val, self.hanow.val, self.lat, self.elevsea) self.baryjd = self.jd + self.barytcor / _skysub.SEC_IN_DAY # find the jd at the nearest clock-time midnight ... localtimestr = self.calstring(stdz=self.stdz, use_dst=self.use_dst) x = string.split(localtimestr) ymd = x[0] + " " + x[1] + " " + x[2] if float(x[3]) >= 12.: midnstring = ymd + " 23 59 59.99" else: midnstring = ymd + " 0 0 0 " self.jdmid = time_to_jd(midnstring, stdz = self.stdz, \ use_dst = self.use_dst) self.stmid = ra(_skysub.lst(self.jdmid, self.longit)) # elevation correction (in degrees) for horizon depression horiz = math.sqrt(2. * self.elevhoriz / _skysub.EQUAT_RAD) \ * _skysub.DEG_IN_RADIAN setelev = -1. * (0.83 + horiz) hasunset = _skysub.ha_alt(self.SunCoords.dec.val, self.lat, setelev) if hasunset > 900.: self.jdsunset = 1000. # never sets self.jdsunrise = 1000. self.jdcent = 1000. elif hasunset < -900.: self.jdsunset = -1000. # never rises self.jdsunrise = -1000. self.jdcent = -1000. else: self.jdsunset = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ + hasunset - self.stmid.val)/24. # initial guess # print "entering jdsunset - self.jdsunset = ",self.jdsunset, self.jdsunset = _skysub.jd_sun_alt(setelev,self.jdsunset,self.lat, \ self.longit) self.jdsunrise = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ - hasunset - self.stmid.val)/24. # initial guess self.jdsunrise = _skysub.jd_sun_alt(setelev,self.jdsunrise,self.lat, \ self.longit) self.jdcent = (self.jdsunset + self.jdsunrise) / 2. hatwilight = _skysub.ha_alt(self.SunCoords.dec.val, self.lat, -18.) if hatwilight > 900.: self.jdevetwi = 1000. # never gets dark self.jdmorntwi = 1000. elif hatwilight < -900.: self.jdevetwi = -1000. # never gets light self.jdmorntwi = -1000. else: self.jdevetwi = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ + hatwilight - self.stmid.val)/24. # initial guess self.jdevetwi = _skysub.jd_sun_alt(-18.,self.jdevetwi,self.lat, \ self.longit) self.jdmorntwi = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ - hatwilight - self.stmid.val)/24. # initial guess self.jdmorntwi = _skysub.jd_sun_alt(-18.,self.jdmorntwi,self.lat, \ self.longit) [ramoonmid,decmoonmid,distmoonmid] = \ _skysub.lpmoon(self.jdmid,self.lat,self.sidereal.val) [minmoonalt, maxmoonalt] = _skysub.min_max_alt(self.lat, decmoonmid) # rough (close enough) check to see if moonrise or moonset occur ... if maxmoonalt < setelev: self.jdmoonrise = -100. # never rises # -1000. is used later to signal non-convergence self.jdmoonset = -100. if minmoonalt > setelev: self.jdmoonrise = 100. # never sets self.jdmoonset = 100. else: hamoonset = _skysub.ha_alt(decmoonmid, self.lat, setelev) tmoonrise = _skysub.adj_time(ramoonmid - hamoonset - self.stmid.val) tmoonset = _skysub.adj_time(ramoonmid + hamoonset - self.stmid.val) self.jdmoonrise = self.jdmid + tmoonrise / 24. self.jdmoonrise = _skysub.jd_moon_alt(setelev,self.jdmoonrise, \ self.lat,self.longit,self.elevsea) self.jdmoonset = self.jdmid + tmoonset / 24. self.jdmoonset = _skysub.jd_moon_alt(setelev,self.jdmoonset,self.lat, \ self.longit,self.elevsea) [self.par_dra,self.par_ddec,self.aber_dra,self.aber_ddec] = \ _skysub.parellipse(self.jd,self.ra.val,self.dec.val,self.equinox, self.lat,self.longit)
def main(argv): ''' Main function. Reads input parameters, run scheduler and stores results. ''' from optparse import OptionParser parser = OptionParser() parser.add_option("-s",'--south_pt', help=''' Input file. This file contains the ra dec for all the tiles. The format is the same as the output of tiler.''' ,type="string") parser.add_option("-n",'--north_pt', help=''' Input file. This file contains the ra dec for all the tiles. The format is the same as the output of tiler.''' ,type="string") parser.add_option("-m",'--meteorology', help=''' Input file. This file contains weather information. Only clouded nights need be specified. Format is MJD FLAG, where FLAG is 0 - Good night. Less than 0.5 mag extinction (may be skipped) 1 - Thin Cirrus. Between 0.5 and 2 mag extinction. 2 - Cloudy. Between 2 and 4 mag extinction. 3 - Closed.''' ,type="string") parser.add_option("-v", '--verbose',action="store_true", dest="verbose", default=False, help="Don't print status messages to stdout") opt,arg = parser.parse_args(argv) # # Reading input files # _path = os.path.expanduser('~/Develop/SMAPs/coordinatesystemandtiling/') sna_file = os.path.join(_path,'smaps_pointT80norte.dat') ssa_file = os.path.join(_path,'smaps_pointsulT80.dat') iis,jjs,ras,decs,rots = np.loadtxt(sna_file,unpack=True,usecols=(0,1,4,5,6)) iin,jjn,ran,decn,rotn = np.loadtxt(ssa_file,unpack=True,usecols=(0,1,4,5,6)) ii = np.array(np.append(iis,iin+iis.max()+10),dtype=int) jj = np.array(np.append(jjs,jjn),dtype=int) ra = np.append(ras,ran) dec = np.append(decs,decn) # Store maximum altitude of tiles maxAltit = np.array([_skysub.altit(dec[j],0.,sitelat)[0] for j in range(len(ra))]) iciclo = 0 ncycle = 2 xcycle = 0 ntryes = 400 tryes = 0 obs = np.array([np.zeros(len(ii))==0,np.zeros(len(ii))==0,np.zeros(len(ii))==0,np.zeros(len(ii))==0]) MJD_dstart = aux.mjd(2014,01,01) # 01/jan/2014 exptime = [0.003,0.024] xx = ii.max()+1 yy = jj.max()+1 map = np.zeros(xx*yy).reshape(yy,xx) for i in range(len(ii)): map[jj[i]][ii[i]] = 1.0 xmap = np.array([map,map,map]) cmap = colors.ListedColormap(['black', 'gray', 'red','white','white']) bounds=[0,1,2,3,4] norm = colors.BoundaryNorm(bounds, cmap.N) #plt.plot(ii,jj,'.') fig = plt.figure() ax = fig.add_subplot(1,1,1) #[fig.add_subplot(2,2,0),fig.add_subplot(2,2,1),fig.add_subplot(2,2,2),fig.add_subplot(2,2,3)] ax = fig.add_axes([0,0,1,1]) ax.axis("off") #for i in range(len(obs)): ax.imshow(map,aspect='auto',interpolation='nearest',cmap=cmap, norm=norm) fig.savefig('xmap_%04i.png'%0) nmap = 1 no_obsTray = np.zeros(len(obs)) == 1 fp = open('surveysim_02.dat','w') for MJD in np.arange(MJD_dstart,MJD_dstart+365.*2): nightStart = _skysub.jd_sun_alt(sunMaxAlt,2400000.5+MJD+1.0, sitelat, sitelong) nightEnd = _skysub.jd_sun_alt(sunMaxAlt,2400000.5+MJD+1.5, sitelat, sitelong) ramoon = 0. decmoon = 0. distmoon = 0. rasun = 0. decsun = 0. ramoon,decmoon,distmoon = _skysub.lpmoon(nightStart,sitelat,_skysub.lst(nightStart,sitelong)) ill_frac=0.5*(1.-np.cos(_skysub.subtend(ramoon,decmoon,rasun,decsun))) stdscr.addstr(7, 0, 'Moon illum: %.3f '%(ill_frac)) stdscr.clrtoeol() if ill_frac < 0.95: iciclo = 0 else: iciclo = -1 stdscr.addstr(0,0,'Observations start at JD = %12.2f'%nightStart) stdscr.addstr(1,0,'Observations end at JD = %12.2f'%nightEnd) xnobs=0 if iciclo >= 0: nobs = len(obs[iciclo][obs[iciclo]]) try: obs[iciclo],xnobs,tnobs,emptyObsSlots = make_obs(nightStart,nightEnd,ra,dec,obs[iciclo],exptime[iciclo],maxAltit) fp.write('%10.2f %6.3f %4i %4i '%(nightStart,nightEnd-nightStart,xnobs,tnobs)) xnobs = 0 tnobs = len(emptyObsSlots) if len(emptyObsSlots) > 0: obs[iciclo+1],xnobs,tnobs,emptyObsSlots = make_obs(nightStart,nightEnd,ra,dec,obs[iciclo+1],exptime[iciclo+1],maxAltit) fp.write('%4i %4i\n'%(xnobs,tnobs)) except: #stdscr.addstr(8,0,sys.exc_info()[0]) errinfo = traceback.format_exc(sys.exc_info()[2]).split('\n') for ierr in range(len(errinfo)): stdscr.addstr(11+ierr,0,errinfo[ierr]) pass if nobs == len(obs[iciclo][obs[iciclo]]): no_obsTray[iciclo] = True else: no_obsTray[iciclo] = False if no_obsTray.all(): if tryes > ntryes: break else: tryes+=1 else: fp.write('%10.2f %6.3f %4i %4i 0 0\n'%(nightStart,nightEnd-nightStart,0.,len(np.arange(nightStart,nightEnd,exptime[iciclo])))) stdscr.addstr(7, 20, ' - No observations this night') stdscr.addstr(2, 0, ' Observed %i '%(xnobs)) xjj = jj[np.bitwise_not(obs[iciclo])] xii = ii[np.bitwise_not(obs[iciclo])] for i in range(len(xii)): xmap[iciclo][xjj[i]][xii[i]] = 2.0 xjj = jj[np.bitwise_not(obs[iciclo+1])] xii = ii[np.bitwise_not(obs[iciclo+1])] for i in range(len(xii)): xmap[iciclo+1][xjj[i]][xii[i]] = 2.0 xcycle+=1 #stdscr.addstr(0, 0, "Moving file: {0}".format(filename)) #stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress)) alldone = np.zeros(ncycle) == 1 for i in range(ncycle): if i == iciclo: start = '--> ' else: start = '--- ' stdscr.addstr(i+3, 0, start+'[Tray: %i] - %4i/%i areas observed'%(i,len(obs[i])-len(obs[i][obs[i]]),len(obs[i]))) alldone[i] = len(obs[i][obs[i]]) == 0 stdscr.refresh() #print '[Ciclo: %i] - %i/%i areas observed'%(i,len(obs[i])-len(obs[i][obs[i]]),len(obs[i])) #for i in range(len(obs)): # ax[i].cla() # ax[i].imshow(xmap[i],aspect='auto',interpolation='nearest',cmap=cmap, norm=norm) ax.cla() ax.imshow(xmap[0]+xmap[1]-1,aspect='auto',interpolation='nearest',cmap=cmap, norm=norm) fig.canvas.draw() if not no_obsTray.all(): fig.savefig('ymap_%04i.png'%nmap) nmap += 1 #plt.plot(ii,jj,'.') if alldone.all(): break fp.close() print 'Observations started in ',MJD_dstart print 'Observations ended in ',MJD print 'Survey took %i days'%(MJD-MJD_dstart) return 0
def computesunmoon(self) : [ras,decs,dists,toporas,topodecs,xs,ys,zs] = \ _skysub.accusun(self.jd, self.sidereal.val,self.lat) self.SunCoords = celest([ras,decs,self.julian_epoch()]) self.hasun = ha(self.sidereal.val - self.SunCoords.ra.val) [self.altsun,self.azsun,parangsun] = \ _skysub.altit(self.SunCoords.dec.val,self.hasun.val,\ self.lat) self.ztwilight = _skysub.ztwilight(self.altsun) [georam,geodm,geodism,toporam,topodecm,topodistm] = \ _skysub.accumoon(self.jd,self.lat,self.sidereal.val, self.elevsea) self.MoonCoords = celest([toporam,topodecm,self.julian_epoch()]) self.hamoon = ha(self.sidereal.val - self.MoonCoords.ra.val) [self.altmoon,self.azmoon,parangmoon] = \ _skysub.altit(self.MoonCoords.dec.val,self.hamoon.val,\ self.lat) self.sun_moon = _skysub.subtend(self.MoonCoords.ra.val, self.MoonCoords.dec.val,self.SunCoords.ra.val, self.SunCoords.dec.val) # radians self.moonillfrac = 0.5 * (1. - math.cos(self.sun_moon)) self.sun_moon = self.sun_moon * _skysub.DEG_IN_RADIAN self.obj_moon = _skysub.subtend(self.MoonCoords.ra.val, self.MoonCoords.dec.val,self.CoordsOfDate.ra.val, self.CoordsOfDate.dec.val) * _skysub.DEG_IN_RADIAN self.lunsky = _skysub.lunskybright(self.sun_moon, self.obj_moon,0.17,self.altmoon,self.altit,topodistm) [self.barytcor, self.baryvcor] = _skysub.helcor(self.jd,self.CoordsOfDate.ra.val, self.CoordsOfDate.dec.val,self.hanow.val,self.lat,self.elevsea) self.baryjd = self.jd + self.barytcor / _skysub.SEC_IN_DAY # find the jd at the nearest clock-time midnight ... localtimestr = self.calstring(stdz = self.stdz, use_dst = self.use_dst) x = string.split(localtimestr) ymd = x[0] + " " + x[1] + " " + x[2] if float(x[3]) >= 12. : midnstring = ymd + " 23 59 59.99" else : midnstring = ymd + " 0 0 0 " self.jdmid = time_to_jd(midnstring, stdz = self.stdz, \ use_dst = self.use_dst) self.stmid = ra( _skysub.lst(self.jdmid,self.longit)) # elevation correction (in degrees) for horizon depression horiz = math.sqrt(2. * self.elevhoriz / _skysub.EQUAT_RAD) \ * _skysub.DEG_IN_RADIAN setelev = -1. * (0.83 + horiz) hasunset = _skysub.ha_alt(self.SunCoords.dec.val,self.lat,setelev) if hasunset > 900. : self.jdsunset = 1000. # never sets self.jdsunrise = 1000. self.jdcent = 1000. elif hasunset < -900. : self.jdsunset = -1000. # never rises self.jdsunrise = -1000. self.jdcent = -1000. else : self.jdsunset = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ + hasunset - self.stmid.val)/24. # initial guess # print "entering jdsunset - self.jdsunset = ",self.jdsunset, self.jdsunset = _skysub.jd_sun_alt(setelev,self.jdsunset,self.lat, \ self.longit) self.jdsunrise = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ - hasunset - self.stmid.val)/24. # initial guess self.jdsunrise = _skysub.jd_sun_alt(setelev,self.jdsunrise,self.lat, \ self.longit) self.jdcent = (self.jdsunset + self.jdsunrise) / 2. hatwilight = _skysub.ha_alt(self.SunCoords.dec.val, self.lat, -18.) if hatwilight > 900. : self.jdevetwi = 1000. # never gets dark self.jdmorntwi = 1000. elif hatwilight < -900. : self.jdevetwi = -1000. # never gets light self.jdmorntwi = -1000. else : self.jdevetwi = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ + hatwilight - self.stmid.val)/24. # initial guess self.jdevetwi = _skysub.jd_sun_alt(-18.,self.jdevetwi,self.lat, \ self.longit) self.jdmorntwi = self.jdmid + _skysub.adj_time(self.SunCoords.ra.val \ - hatwilight - self.stmid.val)/24. # initial guess self.jdmorntwi = _skysub.jd_sun_alt(-18.,self.jdmorntwi,self.lat, \ self.longit) [ramoonmid,decmoonmid,distmoonmid] = \ _skysub.lpmoon(self.jdmid,self.lat,self.sidereal.val) [minmoonalt,maxmoonalt] = _skysub.min_max_alt(self.lat,decmoonmid) # rough (close enough) check to see if moonrise or moonset occur ... if maxmoonalt < setelev : self.jdmoonrise = -100. # never rises # -1000. is used later to signal non-convergence self.jdmoonset = -100. if minmoonalt > setelev : self.jdmoonrise = 100. # never sets self.jdmoonset = 100. else : hamoonset = _skysub.ha_alt(decmoonmid,self.lat,setelev) tmoonrise = _skysub.adj_time(ramoonmid - hamoonset - self.stmid.val) tmoonset = _skysub.adj_time(ramoonmid + hamoonset - self.stmid.val) self.jdmoonrise = self.jdmid + tmoonrise / 24. self.jdmoonrise = _skysub.jd_moon_alt(setelev,self.jdmoonrise, \ self.lat,self.longit,self.elevsea) self.jdmoonset = self.jdmid + tmoonset / 24. self.jdmoonset = _skysub.jd_moon_alt(setelev,self.jdmoonset,self.lat, \ self.longit,self.elevsea) [self.par_dra,self.par_ddec,self.aber_dra,self.aber_ddec] = \ _skysub.parellipse(self.jd,self.ra.val,self.dec.val,self.equinox, self.lat,self.longit)
def make_obs(T0,T1,RA,DEC,mask,texp,MaxAltit,obsTimes=[]): #obsmask = np.array(mask) i = 0 lst_start = _skysub.lst(T0,sitelong) lst_end = _skysub.lst(T1,sitelong) ra_mask = [] if lst_start < lst_end: ra_mask = np.bitwise_and(RA > lst_start*360./24., RA < lst_end*360./24.) stdscr.addstr(8,0,'[%5i] >> lst_start < lst_end <<'%(len(ra_mask[ra_mask]))) stdscr.addstr(9,0,' ') else: obsmask1 = RA > lst_start*360./24. obsmask2 = np.bitwise_and(RA > 0.,RA < lst_end*360./24.) ra_mask = np.bitwise_or(obsmask1,obsmask2) stdscr.addstr(8,0,' ') stdscr.addstr(9,0,'[%5i] << lst_start > lst_end >>'%(len(ra_mask[ra_mask]))) stdscr.refresh() obsmask = np.bitwise_and(mask,ra_mask) xindex = np.arange(len(RA)) #stdscr.addstr(5,0,'%i %i'%(len(index[obsmask]),len(index[ra_mask]))) stdscr.addstr(5,0,'Initial size of array %i'%(len(xindex))) ondex = [] index = list(np.array(xindex)[obsmask]) if len(obsTimes) == 0: _obsTimes = np.arange(T0,T1,texp) else: _obsTimes = obsTimes obsSlot = np.zeros_like(_obsTimes) == 1 if len(index)>len(xindex[ra_mask]): stdscr.addstr(6,0,'[WARNING] More tiles available than it is possible!') stdscr.refresh() return mask,0,len(np.arange(T0,T1,texp)),_obsTimes if len(index) < 1: stdscr.addstr(6,0,'Nothing to observe... ') stdscr.refresh() return mask,0,len(np.arange(T0,T1,texp)),_obsTimes __strlen = len('Running size of array %4i'%(len(index))) stdscr.addstr(6,0,'Running size of array %4i'%(len(index))) stdscr.refresh() #obsmask[ra_mask] = True #return obsmask,i #fp = open('queue_%05.0f.txt'%(T0-2400000.5),'w') for line in range(10): stdscr.addstr(10+line,0,' ') line = 0 for itr,time in enumerate(_obsTimes): lst = _skysub.lst(time,sitelong)*360./24. #lst = _skysub.lst(time,sitelong) #*360./24. ha = (lst - RA)*24./360. alt = np.array([_skysub.altit(DEC[j],ha[j],sitelat)[0] for j in index]) if len(alt) == 0: stdscr.addstr(6,0,'Nothing to observe... ') stdscr.refresh() else: stg = alt.argmax() i+=1 #stdscr.addstr(8,0,'%i %i %i'%(obsmask[index[stg]],index[stg],stg)) if alt[stg] > MaxAltit[index[stg]]*0.6: ondex.append(index[stg]) index.pop(stg) obsSlot[itr] = True else: stdscr.addstr(10+line,0,'Object too low. Alt = %7.2f, Max Alt = %7.2f... '%(alt[stg],MaxAltit[index[stg]])) if line < 9: line+=1 stdscr.refresh() #stg = ha.argmin() #fp.write('tile%05i %f %f\n'%( index[stg], # RA[index[stg]], # DEC[index[stg]])) # #xtime.sleep(1.0) #fp.close() obsmask = np.array(mask) for idx in ondex: if obsmask[idx] == False: stdscr.addstr(10,0,'[WARINING] - Tile repeated!') stdscr.refresh() obsmask[idx] = False #stdscr.addstr(8,0,'%i'%(len(xindex[mask])-len(xindex[obsmask]))) stdscr.refresh() #print i return obsmask,len(ondex),len(_obsTimes),_obsTimes[obsSlot]
def selectStandardTargets(self,flag,nstars=3,nairmass=3): ''' Based on configuration parameters, select 'nstars' standard stars to run scheduler on a specified Julian Day. Ideally you will select standard stars before your science targets so not to have a full queue. Usually standard stars are observed more than once a night at different airmasses. The user can control this parameter with nairmass and the script will try to take care of the rest. ''' session = Session() # query project information projQuery = session.query(Projects).filter(Projects.flag == flag) totobstime = 0. # Calculate total observation time for block in projQuery: totobstime += block.exptime totobstime /= 86400.0 # First of all, standard stars can be observed multiple times in sucessive nights. I will mark all # stars as unscheduled. targets = session.query(Targets).filter(Targets.scheduled == True).filter(Targets.type == flag) for target in targets: target.scheduled = False session.commit() # [To be done] Reject objects that are close to the moon # [To be done] Apply all sorts of rejections # Selecting standard stars is not only searching for the higher in that time but select stars than can be observed at 3 # or more (nairmass) different airmasses. It is also important to select stars with different colors (but this will be # taken care in the future). if nairmass*nstars > len(self.obsTimeBins): self.log.warning('Requesting more stars/observations than it will be possible to schedule. Decreasing number of requests to fit in the night.') nstars = len(self.obsTimeBins)/nairmass # Build a grid of desired times for higher airmass observation of each standard star. stdObsTimeBin = np.arange(10,len(self.obsTimeBins)-10,(len(self.obsTimeBins)-10)/nstars) obsStandars = np.zeros(nstars) print stdObsTimeBin # selecting the closest bin without observation stdObsTimeBin,status = self.findSuitableTimeBin(stdObsTimeBin) if status != 0: raise Exception('Could not find suitable time to start observations! Try cleaning queue.') print stdObsTimeBin site = Site() calclst = lambda time: np.sum(np.array([float(tt) / 60.**i for i,tt in enumerate(str(site._getEphem(datetimeFromJD(time)).sidereal_time()).split(':'))])) nightlst = np.array([calclst(obstime) for obstime in self.obsTimeBins]) for i,tbin in enumerate(stdObsTimeBin): # selecting the closest bin without observation closestcleanbin = tbin while self.obsTimeMask[closestcleanbin] > 0.0: closestcleanbin += 1 if i+1 < len(stdObsTimeBin): if closestcleanbin > stdObsTimeBin[i+1]: raise Exception('Could not find suitable place to start observations of standard star. Try cleaning queue.') time = self.obsTimeBins[closestcleanbin] # 1 - Select objects from database that where not scheduled yet (standard stars may be repited) # that fits our observing night #targetSched = False # Will try until a good match is obtained #while( not targetSched ): targets = session.query(Targets).filter(Targets.scheduled == 0).filter(Targets.type == flag) if len(targets[:]) > 0: #ephem = site._getEphem(datetimeFromJD(time)) lst = calclst(time) #np.sum(np.array([float(tt) / 60.**i for i,tt in enumerate(str(ephem.sidereal_time()).split(':'))])) sitelat = np.sum(np.array([float(tt) / 60.**i for i,tt in enumerate(str(site['latitude']).split(':'))])) alt = np.array([_skysub.altit(target.targetDec,lst - target.targetRa,sitelat)[0] for target in targets]) stg = alt.argmax() print('Selecting %s'%(targets[stg])) # Marking target as schedule tst = session.query(Targets).filter(Targets.id == targets[stg].id) # Build airmass table for object objsecz = np.array([_skysub.true_airmass(_skysub.secant_z(_skysub.altit(targets[stg].targetDec,nlst - targets[stg].targetRa,sitelat)[0])) for nlst in nightlst]) # Build desired airmass table #obsairmass = np.linspace(_skysub.true_airmass(_skysub.secant_z(alt[stg])),projQuery[0].maxairmass,nairmass) obsairmass = np.logspace(np.log10(np.min(objsecz[objsecz > 0])),np.log10(projQuery[0].maxairmass),nairmass) np.savetxt('airmass_%04i.dat'%(stg),X=zip(self.obsTimeBins,objsecz)) # Build mask with scheduled airmasses #mask = np.zeros(len(objsecz),dtype=bool) == 1 pltobstime,pltobsairmass = np.array([]),np.array([]) # Try scheduling observations on all airmasses for airmass in obsairmass: # Get times where the object is close to the desired airmass and there are no observations scheduled timeobsmask = np.bitwise_and(self.obsTimeMask < 1.0,np.abs(objsecz - airmass) < self.tolairmass) # Check that there are times available if not timeobsmask.any(): #raise Exception('No time available for scheduling observations of standard star %s at airmass %.3f'%(targets[stg],airmass)) self.log.warning('No time available for scheduling observations of standard star %s at airmass %.3f'%(targets[stg],airmass)) # Start trying to schedule observations indexes = np.arange(len(self.obsTimeMask))[timeobsmask] #np.bitwise_and(self.obsTimeMask, timeobsmask) obsSched = False for index in indexes: print('[%.3f] - Time bin available for observation of standard star at airmass %.3f'%(self.obsTimeBins[index], airmass)) print '- Require %i extra time bins'%(totobstime/self.tbin) if (self.obsTimeMask[index:index+totobstime/self.tbin] < 1.0).all(): print 'Observation fit in this block.' self.obsTimeMask[index:index+totobstime/self.tbin] = 1.0 self.log.info('Requesting observations of %s @airmass=%4.2f @mjd=%.3f...'%(target.name,airmass,self.obsTimeBins[index]-2400000.5)) pltobstime = np.append(pltobstime,self.obsTimeBins[index:index+totobstime/self.tbin]) pltobsairmass = np.append(pltobsairmass, objsecz[index:index+totobstime/self.tbin]) #for nblock,ii in enumerate(range(index,int(index+totobstime/self.tbin),1)): self.addObservation(targets[stg],self.obsTimeBins[index],projQuery) break np.savetxt('obsairmass_%04i.dat'%stg,X = zip(pltobstime,pltobsairmass)) #self.obsTimeMask[index] = 1.0 #for iobsbins in range(index+1,index+int(totobstime/self.tbin)): #print '[%i] - require extra time bin'%(iobsbins) #if self.obsTimeMask[iobsbins] < 1.0: # self.obsTimeMask[iobsbins] = 1.0 #else: # raise Exception('Time bin [%i/%i] not available for observation of standard star at airmass %.3f'%(iobsbins,len(self.obsTimeMask),airmass)) #else: #raise Exception('Time bin not available for observation of standard star at airmass %.3f'%(airmass)) for t in tst: t.scheduled = True session.commit() obsStandars[i] = t.id else: self.log.warning('No suitable standard star for jd:%.3f in database...'%(time)) return 0 return 0 if len(obsStandars[obsStandars >= 0]) < nstars: self.log.warning('Could not find %i suitable standard stars in catalog. Only %i where found.'%(nstars,len(obsStandars[obsStandars >= 0]))) obsStandars = np.zeros(len(self.obsTimeBins))-1 # first selection of observable standards for tbin,time in enumerate(self.obsTimeBins): if self.obsTimeMask[tbin] < 1.0: # 1 - Select objects from database that where not scheduled yet (standard stars may be repited) # that fits our observing night targets = session.query(Targets).filter(Targets.scheduled == 0).filter(Targets.type == flag) if len(targets[:]) > 0: ephem = site._getEphem(datetimeFromJD(time)) lst = np.sum(np.array([float(tt) / 60.**i for i,tt in enumerate(str(ephem.sidereal_time()).split(':'))])) sitelat = np.sum(np.array([float(tt) / 60.**i for i,tt in enumerate(str(site['latitude']).split(':'))])) secz = np.array([_skysub.secant_z(_skysub.altit(target.targetDec,lst - target.targetRa,sitelat)[0]) for target in targets]) stg = secz.argmax() self.log.info('Selecting %s'%(targets[stg])) # Marking target as schedule tst = session.query(Targets).filter(Targets.id == targets[stg].id) for t in tst: t.scheduled = True session.commit() obsStandars[tbin] = t.id else: print('No suitable target for jd:%.3f in database...'%(time)) break else: self.log.info('Bin already filled up with observations. Skipping...') if len(obsStandars[obsStandars >= 0]) < nstars: self.log.warning('Could not find %i suitable standard stars in catalog. Only %i where found.'%(nstars,len(obsStandars[obsStandars >= 0]))) # # Unmarking potential targets as scheduled # for id in obsStandars[obsStandars >= 0]: target = session.query(Targets).filter(Targets.id == id) for t in target: t.scheduled = False session.commit() tbin+=1 # # Preparing a grid of altitudes for each target for each observing window # amGrid = np.zeros(len(obsStandars)*len(obsStandars)).reshape(len(obsStandars),len(obsStandars)) for i in np.arange(len(obsStandars))[obsStandars >= 0]: target = session.query(Targets).filter(Targets.id == obsStandars[i])[0] for j in range(len(obsStandars)): lst = _skysub.lst(self.obsTimeBins[j],self.sitelong) amGrid[i][j] = _skysub.true_airmass(_skysub.secant_z(_skysub.altit(target.targetDec,lst - target.targetRa,self.sitelat)[0])) if amGrid[i][j] < 0: amGrid [i][j] = 99. # # Build a grid mask that specifies the position in time each target should be observed. This means that, when # selecting a single target we ocuppy more than one, non consecutive, position in the night. This grid shows where are these # positions. # obsMask = np.zeros(len(obsStandars)*len(obsStandars),dtype=np.bool).reshape(len(obsStandars),len(obsStandars)) for i in np.arange(len(obsStandars))[obsStandars >= 0]: amObs = np.linspace(amGrid[i].min(),self.stdMaxAirmass,nairmass) # requested aimasses dam = np.mean(np.abs(amGrid[i][amGrid[i]<self.stdMaxAirmass][1:] - amGrid[i][amGrid[i]<self.stdMaxAirmass][:-1])) # how much airmass changes in average for j,am in enumerate(amObs): # Mark positions where target is at specified airmass if j == 0: obsMask[i] = np.bitwise_or(obsMask[i],amGrid[i] == am) else: obsMask[i] = np.bitwise_or(obsMask[i],np.bitwise_and(amGrid[i]>am-dam,amGrid[i]<am+dam)) #print amGrid[i][np.where(obsMask[i])] # # Now it is time to actually select the targets. It will start with the first target and then try the others # until it find enough standard stars, as specified by the user. # # Para cada bin em tempo, varro o bin em massa de ar por coisas observaveis. Se acho um, vejo se posso agendar # os outros bins. Se sim, marco o alvo para observacao, se nao, passo para o proximo. Repito ate completar a # lista de alvos # obsMaskTimeGrid = np.zeros(len(obsStandars),dtype=np.bool) nrequests = 0 reqId = np.zeros(nstars,dtype=np.int)-1 for tbin,time in enumerate(self.obsTimeBins[:-1]): # Evaluates if time slots are all available. If yes, mark orbservation and ocuppy slots. if ( (not obsMaskTimeGrid[obsMask[tbin]].any()) and (len(amGrid[tbin][obsMask[tbin]])>=nairmass) ): obsMaskTimeGrid = np.bitwise_or(obsMaskTimeGrid,obsMask[tbin]) reqId[nrequests] = tbin nrequests += 1 if nrequests >= nstars: break # Finally, requesting observations for id in reqId[reqId >= 0]: target = session.query(Targets).filter(Targets.id == obsStandars[id])[0] secz = amGrid[id][obsMask[id]] seczreq = np.zeros(nairmass,dtype=np.bool) amObs = np.linspace(amGrid[id].min(),self.stdMaxAirmass,nairmass) # requested aimasses for i,obstime in enumerate(self.obsTimeBins[obsMask[id]]): sindex = np.abs(amObs-secz[i]).argmin() if not seczreq[sindex]: self.log.info('Requesting observations of %s @airmass=%4.2f @mjd=%.3f...'%(target.name,secz[i],obstime-2400000.5)) seczreq[sindex] = True target.scheduled = True session.commit() self.addObservation(target,obstime) self.obsTimeMask[obsMask[id]] = 1.0 #print self.obsTimeBins[obsMask[id]] #print #print i return 0 #targets