示例#1
0
    def _watchProgramBegin(self, program):
        session = model.Session()
        rsession = RSession()
        try:
            program = session.merge(program)
            self._debuglog.debug('Program %s started' % program)
            site = self.getSite()

            log = ObservingLog(time=datetimeFromJD(site.MJD() + 2400000.5, ),
                               tid=program.tid,
                               name=program.name,
                               priority=program.priority,
                               action='ROBOBS: Program Started')
            rsession.add(log)
        finally:
            session.commit()
            rsession.commit()
示例#2
0
    def _watchProgramComplete(self, program, status, message=None):

        session = model.Session()
        rsession = RSession()
        try:
            program = session.merge(program)
            self._debuglog.debug('Program %s completed with status %s(%s)' %
                                 (program, status, message))
            site = self.getSite()

            log = ObservingLog(
                time=datetimeFromJD(site.MJD() + 2400000.5, ),
                tid=program.tid,
                name=program.name,
                priority=program.priority,
                action='ROBOBS: Program End with status %s(%s)' %
                (status, message))
            rsession.add(log)
            rsession.commit()

            if status == SchedulerStatus.OK and self._current_program is not None:

                cp = rsession.merge(self._current_program[0])
                cp.finished = True
                rsession.commit()

                block_config = rsession.merge(self._current_program[1])
                sched = schedAlgorithms[block_config.schedalgorith]
                sched.observed(site.MJD(), self._current_program, site)
                rsession.commit()

                rsession.commit()

                self._current_program = None
            elif status != SchedulerStatus.OK:
                self.stop()
        finally:
            session.commit()
            rsession.commit()
示例#3
0
    def _readout(self, request):
        self.readoutBegin(request)

        img = Dispatch("CCDSoft.Image")
        img.AttachToActiveImager()
        pix = np.transpose(np.array(img.DataArray))

        (mode, binning, top, left, width, height) = self._getReadoutModeInfo(request["binning"], request["window"])

        request.headers.append(('GAIN', str(mode.gain), 'Electronic gain in photoelectrons per ADU'))

        proxy = self._saveImage(request, pix, {
            "frame_start_time": datetimeFromJD(img.JulianDay),
            "frame_temperature": self.getTemperature(),
            "binning_factor": self._binning_factors[binning]})

        # [ABORT POINT]
        if self.abort.isSet():
            self.readoutComplete(None, CameraStatus.ABORTED)
            return None

        self.readoutComplete(proxy, CameraStatus.OK)
        return proxy
示例#4
0
    def _readout(self, request):
        self.readoutBegin(request)

        img = Dispatch("CCDSoft.Image")
        img.AttachToActiveImager()
        pix = np.transpose(np.array(img.DataArray))

        (mode, binning, top, left, width, height) = self._getReadoutModeInfo(request["binning"], request["window"])

        request.headers.append(('GAIN', str(mode.gain), 'Electronic gain in photoelectrons per ADU'))

        proxy = self._saveImage(request, pix, {
            "frame_start_time": datetimeFromJD(img.JulianDay),
            "frame_temperature": self.getTemperature(),
            "binning_factor": self._binning_factors[binning]})

        # [ABORT POINT]
        if self.abort.isSet():
            self.readoutComplete(None, CameraStatus.ABORTED)
            return None

        self.readoutComplete(proxy, CameraStatus.OK)
        return proxy
示例#5
0
    def checkConditions(self,
                        program,
                        time,
                        program_length=0.,
                        external_checker=None):
        '''
        Check if a program can be executed given all restrictions imposed by airmass, moon distance,
         seeing, cloud cover, etc...

        [comment] There must be a good way of letting the user rewrite this easily. I can only
         think about a decorator but I am not sure how to implement it.

        :param program:
        :return: True (Program can be executed) | False (Program cannot be executed)
        '''

        site = self.getSite()
        # 1) check airmass
        session = RSession()
        # program = session.merge(prg)
        target = session.merge(program[3])
        # obsblock = session.merge(program[2])
        blockpar = session.merge(program[1])

        raDec = Position.fromRaDec(target.targetRa, target.targetDec)

        dateTime = datetimeFromJD(time + 2400000.5)
        lst = site.LST_inRads(dateTime)  # in radians

        alt = float(site.raDecToAltAz(raDec, lst).alt)
        airmass = 1. / np.cos(np.pi / 2. - alt * np.pi / 180.)

        if blockpar.minairmass < airmass < blockpar.maxairmass:
            self._debuglog.debug('\tairmass:%.3f' % airmass)
            pass
        else:
            self._debuglog.warning(
                'Target %s out of airmass range @ %.3f... (%f < %f < %f)' %
                (target, time, blockpar.minairmass, airmass,
                 blockpar.maxairmass))
            return False

        if program_length > 0.:
            observation_end = datetimeFromJD((time + program_length / 86.4e3) +
                                             2400000.5).replace(tzinfo=None)
            # lst = site.LST_inRads(dateTime)  # in radians
            night_end = site.sunrise_twilight_begin(dateTime).replace(
                tzinfo=None)
            if observation_end > night_end:
                self._debuglog.warning(
                    'Block finish @ %s. Night end is @ %s!' %
                    (observation_end, night_end))
                return False
            else:
                self._debuglog.debug('Block finish @ %s. Night end is @ %s!' %
                                     (observation_end, night_end))

            alt = float(site.raDecToAltAz(raDec, lst).alt)
            airmass = 1. / np.cos(np.pi / 2. - alt * np.pi / 180.)

            if blockpar.minairmass < airmass < blockpar.maxairmass:
                self._debuglog.debug('\tairmass:%.3f' % airmass)
                pass
            else:
                self._debuglog.warning(
                    'Target %s out of airmass range @ %.3f... (%f < %f < %f)' %
                    (target, time, blockpar.minairmass, airmass,
                     blockpar.maxairmass))
                # return False
                # FIXME
                pass

        # 2) check moon Brightness
        moonPos = site.moonpos(dateTime)
        moonBrightness = site.moonphase(dateTime) * 100.
        if blockpar.minmoonBright < moonBrightness < blockpar.maxmoonBright:
            self._debuglog.debug('\tMoon brightness:%.2f' % moonBrightness)
            pass
        elif moonPos.alt < 0.:
            self._debuglog.warning(
                '\tMoon bellow horizon. Moon brightness:%.2f' % moonBrightness)
        else:
            self._debuglog.warning('Wrong Moon Brightness... (%f < %f < %f)' %
                                   (blockpar.minmoonBright, moonBrightness,
                                    blockpar.maxmoonBright))
            return False

        # 3) check moon distance
        moonRaDec = site.altAzToRaDec(moonPos, lst)

        moonDist = raDec.angsep(moonRaDec)

        if moonDist < blockpar.minmoonDist:
            self._debuglog.warning(
                'Object to close to the moon... '
                'Target@ %s / Moon@ %s (moonDist = %f | minmoonDist = %f)' %
                (raDec, moonRaDec, moonDist, blockpar.minmoonDist))
            return False
        else:
            self._debuglog.debug('\tMoon distance:%.3f' % moonDist)
        # 4) check seeing

        if self["seeingmonitors"] is not None:

            seeing = self.getSM().seeing()

            if seeing > blockpar.maxseeing:
                self._debuglog.warning(
                    'Seeing higher than specified... sm = %f | max = %f' %
                    (seeing, blockpar.maxseeing))
                return False
            elif seeing < 0.:
                self._debuglog.warning('No seeing measurement...')
            else:
                self._debuglog.debug('Seeing %.3f' % seeing)
        # 5) check cloud cover
        if self["cloudsensors"] is not None:
            pass

        if self["weatherstations"] is not None:
            pass

        if external_checker is not None:
            # Todo: add a 3rd option which is a function to check if program is ok from the algorithm itself.
            pass

        self._debuglog.debug('Target OK!')

        return True
示例#6
0
文件: tao.py 项目: tribeiro/SMAPS
	def targets(self):
		'''
		After selecting targets, you can generate a list of potential targets to run the scheduler.
		'''
		
		session = Session()

		fp1 = open(os.path.join(self.PATH,'Fixed.txt'),'w')
		fp2 = open(os.path.join(self.PATH,'request.stg'),'w')

		# Write header
		fp1.write('''P|Designation |    RA     |    dec    |mag.
-|------------|hh mm ss.ss|sdd mm ss.s|nn.n
''')

		config = {	'name' : '',
					'user' : '',
					'nimages' : 1,
					'expt' : 0,
					'filter' : '',
					'time' : ''}


		for obstype in [self.stdFlag,self.sciFlag]:
		
			targets = session.query(Targets,Program).join((Program,Targets.id==Program.tid)).filter(Targets.type == obstype).order_by(Targets.name)
			tobs = []
			
			tname = ''
			FlagFilterClear = True
			for target,program in targets:

				p = Position.fromRaDec(target.targetRa,target.targetDec)
				ra = p.ra.HMS
				dec = p.dec.DMS

				#
				# Write Fixed.txt
				#
				objname = '%12s'%(target.name).replace(' ','_')
				objname = objname.replace(' ','_')
				fp1.write('%1s %s %02.0f %02.0f %05.2f %+03.0f %02.0f %04.1f %04.1f\n'%(	target.type,
																			objname,
																			ra[1],
																			ra[2],
																			ra[3],
																			dec[0]*dec[1],
																			dec[2],
																			dec[3],target.targetMag))

				#
				# Write stg file with observation requests
				#
				config['name'] = objname
				config['user'] = self.stdUser
				filterExpt = self.stdExpTime
				if target.type == self.sciFlag:
					config['user'] = self.sciUser
					filterExpt = self.sciExpTime
					config['time'] = ''
				dt = np.max(filterExpt)*self.nfilters/60./60./24.
				if target.type ==self.stdFlag:
					FlagFilterClear = True
					tname = target.name
					tstart = datetimeFromJD(program.slewAt + 2400000.5)
					tend = datetimeFromJD(program.slewAt+dt + 2400000.5)
					config['time'] = 't>%s t<%s'%(tstart.strftime('%y%m%d-%H:%M'),tend.strftime('%y%m%d-%H:%M'))

				for i in range(self.nfilters):
					config['expt'] = filterExpt[i]
					config['filter'] = self.filters[i]
					tstart = datetimeFromJD(program.slewAt + 2400000.5)
					tend = datetimeFromJD(program.slewAt+dt*1.1 + 2400000.5)
					
					fp2.write('%(name)12s; %(user)s %(nimages)ii exp=%(expt).2f opt filter=%(filter)s %(time)s\n'%config)

		fp1.close()
		fp2.close()
		
		return 0
示例#7
0
    def targets(self):
        '''
		After selecting targets, you can generate a list of potential targets to run the scheduler.
		'''

        import subprocess

        session = Session()

        request = os.path.join(self.PATH, 'targets/request.stg')

        fp1 = open(os.path.join(self.PATH, 'targets/Fixed.txt'), 'w')
        fp2 = open(request, 'w')

        # Write header
        fp1.write('''P|Designation |    RA     |    dec    |mag.
-|------------|hh mm ss.ss|sdd mm ss.s|nn.n
''')

        config = {
            'name': '',
            'user': '',
            'nimages': 1,
            'expt': 0,
            'filter': '',
            'time': ''
        }

        for obstype in [self.stdFlag, self.sciFlag]:

            targets = session.query(Targets, Program).join(
                (Program, Targets.id == Program.tid)).filter(
                    Targets.type == obstype).order_by(Targets.name)
            tobs = []

            tname = ''
            FlagFilterClear = True
            for target, program in targets:

                p = Position.fromRaDec(target.targetRa, target.targetDec)
                ra = p.ra.HMS
                dec = p.dec.DMS

                #
                # Write Fixed.txt
                #
                objname = '%12s' % (target.name).replace(' ', '_')
                objname = objname.replace(' ', '_')
                fp1.write(
                    '%1s %s %02.0f %02.0f %05.2f %+03.0f %02.0f %04.1f %04.1f\n'
                    % (target.type, objname, ra[1], ra[2], ra[3],
                       dec[0] * dec[1], dec[2], dec[3], target.targetMag))

                #
                # Write stg file with observation requests
                #
                config['name'] = objname
                config['user'] = self.stdUser
                filterExpt = self.stdExpTime
                if target.type == self.sciFlag:
                    config['user'] = self.sciUser
                    filterExpt = self.sciExpTime
                    config['time'] = ''
                dt = np.max(filterExpt) * self.nfilters / 60. / 60. / 24.
                if target.type == self.stdFlag:
                    FlagFilterClear = True
                    tname = target.name
                    tstart = datetimeFromJD(program.slewAt + 2400000.5)
                    tend = datetimeFromJD(program.slewAt + dt + 2400000.5)
                    config['time'] = 't>%s t<%s' % (tstart.strftime(
                        '%y%m%d-%H:%M'), tend.strftime('%y%m%d-%H:%M'))

                for i in range(self.nfilters):
                    config['expt'] = filterExpt[i]
                    config['filter'] = self.filters[i]
                    tstart = datetimeFromJD(program.slewAt + 2400000.5)
                    tend = datetimeFromJD(program.slewAt + dt * 1.1 +
                                          2400000.5)

                    fp2.write(
                        '%(name)12s; %(user)s %(nimages)ii exp=%(expt).2f opt filter=%(filter)s %(time)s\n'
                        % config)

        fp1.close()
        fp2.close()

        #
        # Calling targets from TAO to generate targets list.
        #
        fp1 = open(os.path.join(self.PATH, 'targets/targets.log'), 'w')
        bin = os.path.expanduser(os.path.join(self.PATH, 'targets/targets'))
        runTargets = subprocess.Popen([bin, '-s', request],
                                      stdout=fp1,
                                      stderr=fp1)

        runTargets.wait()
        fp1.close()

        return 0
示例#8
0
文件: mkqueue.py 项目: tribeiro/SMAPS
	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