def __validateTimeValues(time_list): """ Since the time argument is string, additional controls are required for consistency :param time_list: List representing time e.g 8:30 is ["8", "30"] :return: """ if len(time_list) > 2: raise FormatError("__validTimeValues", "Time", "HH:MM") try: if int(time_list[0]) < 0 or int(time_list[0]) > 23: raise InputError("__validTimeValues", "Time must follow the 24-hour convention") if int(time_list[1]) < 0 or int(time_list[1]) > 59: raise InputError("__validTimeValues", "Minutes should be between 0 and 59") except ValueError: raise ValueError("Argument should be an integer")
def validateDay(day): """ This method validates that the day belongs to a correct weekday digit representation :param day: integer between 1 and 7 """ ValidTypes.validateInteger(day) if day < 1 or day > 7: raise InputError("ValidDates", "Day should be between 1 and 7")
def add_ron(self, std): """ Add read out noise :param std: expected read out nosie per pixel :return: """ if self._lock: raise InputError('Oi! This image has been locked.') else: self._realima += numpy.random.poisson(std, size=self._size) self._history.append('RON added std = %s' % std)
def add_shot(self, scale): """ Add shot (Poisson) noise :param scale: scaling applied before calculating shot noise :return: """ if self._lock: raise InputError('Oi! This image has been locked.') else: self._realima = numpy.random.poisson(self._ima * scale) self._history.append('Shot noise added scale = %s' % scale)
def add_bg(self, level): """ Add a background level :param level: background level in cts/pixel :return: """ if self._lock: raise InputError('Oi! This image has been locked.') else: self._ima += level self._history.append('Background added level = %s' % level)
def reset(self): """ Reset the image :return: """ if self._lock: raise InputError('Oi! This image has been locked.') else: self._ima = numpy.zeros(self._size) self._realima = numpy.zeros(self._size) self._history = []
def thin_lightcurve(self, thinfactor): """ Regular thinning of lightcurve, only every nth datapoint is kept :param thinfactor: :return: """ if type(thinfactor) is not int: raise InputError() thint = self._t[::thinfactor] thinflux = self._flux[::thinfactor] thinerr = self._error[::thinfactor] return thint, thinflux, thinerr
def random_subsample(self, keepfrac): """ :param keepfrac: :return: """ if keepfrac <= 0 or keepfrac > 1: raise InputError('keepfrac must be between 0 and 1.') mask = numpy.random.choice(self._n, int(self._n * keepfrac), replace=False) randt = self._t[mask] randflux = self._flux[mask] randerr = self._error[mask] return randt, randflux, randerr
def validateDate(year, month, day): """ This method validates that all year, month and day values are consistent :param year: integer :param month: integer :param day: integer """ ValidDates.__validateDateValues(year, month, day) ValidDates.validateMonth(month) last_day = monthrange(year, month)[1] if day < 1 or day > last_day: message = "Day of month " + str(month) + \ ", should be between 1 and " + str(last_day) raise InputError("validateDay", message)
def addPSF(self, x, y, sigma, intflux=1.): """ Add a Gaussian PSF :param x: x position :param y: y position :param sigma: width of PSF (sigma), same in x and y :param intflux: integrated flux of psf :return: """ if self._lock: raise InputError('Oi! This image has been locked.') else: self._ima += (1/(2*numpy.pi*(sigma**2)))*\ numpy.exp(- ((self._x - x) ** 2 + (self._y - y) ** 2) / (2* (sigma ** 2)))\ * intflux self._history.append('PSF added x = %s y = %s sigma = %s intflux = %s' %(x, y, sigma, intflux))
def realistic_sampling(self, obslength=1. / 24, obspernight=1, missedfrac=0.5, nightfrac=0.5): """ Approximatelt simulates an actual observation. :param obslength: length of each individual observation :param obspernight: number of observations per night :param missed: chance an observation is missed :param nightfrac: fraction of the day useable as nighttime, default 50% :return: t, flux """ if self._tunit != 'Days': raise InputError('unit needs to be in days') firstsundown = numpy.random.uniform( min(self._t), min(self._t) + 1, 1) # this randomly sets the time of sundown n_obsnights = int( (max(self._t) - min(self._t)) - (firstsundown - min(self._t))) #number of nights in the lightcurve obs_t = [] #creating an empty list for output obs_flux = [] obs_error = [] for i in range(n_obsnights): sundown = ((i + 1) * (firstsundown - min(self._t))) + firstsundown obstime = numpy.random.uniform(sundown, sundown + nightfrac, obspernight) for obs in obstime: checkweather = numpy.random.uniform() if checkweather > missedfrac: currmask = (self._t > obs) & (self._t < obs + obslength) for t, f, e in zip(self._t[currmask], self._flux[currmask], self._error[currmask]): obs_t.append(t) obs_flux.append(f) obs_error.append(e) return obs_t, obs_flux, obs_error
def practiceima(self, npsf=2, psffluxrange=[500, 1000], bgrange=[2, 10], sigmarange=[3, 6], ronrange=[1, 10], shot=True, ron=True, edge=0.1): """ Create a random practice image. :param npsf: number of objects added :param psffluxrange: range in which psf flux will be randomly chosen :param bgrange: range for background :param sigmarange: range for FWHM, will be idential for all objects :param ronrange: range in which RON will be chosen :param shot: add shot noise? (Boolean) :param ron: add RON? (bolean) :param edge: edge of frame left out of placement of PSFs :return: """ #Need to add sanity checks for the inputs if type(npsf) is not int or npsf <= 0: raise InputError("npsf needs to be an integer >= 0") if len(psffluxrange) != 2: raise InputError('psffluxrange needs to be of length 2') if len(bgrange) != 2: raise InputError('bgrange needs to be of length 2') if len(sigmarange) != 2: raise InputError('sigmarange needs to be of length 2') if len(ronrange) != 2: raise InputError('ronrange needs to be of length 2') if type(shot) is not bool: raise InputError("shot needs to be boolean") if type(ron) is not bool: raise InputError("shot needs to be boolean") if edge < 0 or edge > 0.5: raise InputError("edge needs to be between 0 and 0.5") #Resets and unlocks the image self._lock = False self.reset() self._practicedict = {} #Add psf #add PSF info to dictionary self._practicedict['npsfs'] = npsf self._practicedict['psf_x'] = [] self._practicedict['psf_y'] = [] self._practicedict['psf_flux'] = [] #get FWHM value and store sigma = numpy.random.uniform(sigmarange[0], sigmarange[1], 1)[0] self._practicedict['sigma'] = sigma #add PSFs, looping for i in range(npsf): #create random values for instance of this PSF x = numpy.random.uniform(edge * self._size[0], (1 - edge) * self._size[0], 1)[0] y = numpy.random.uniform(edge * self._size[1], (1 - edge) * self._size[1], 1)[0] flux = numpy.random.uniform(psffluxrange[0], psffluxrange[1], 1)[0] #add PSF self.addPSF(x, y, sigma, flux) #store PSF self._practicedict['psf_x'].append(x) self._practicedict['psf_y'].append(y) self._practicedict['psf_flux'].append(flux) #add bg bg = numpy.random.uniform(bgrange[0], bgrange[1], 1)[0] self._practicedict['bg'] = bg self.add_bg(bg) #add noise #RON if ron: ron = numpy.random.uniform(ronrange[0], ronrange[1], 1)[0] self._practicedict['ron'] = ron self._practicedict['ronflag'] = ron self.add_ron(ron) else: self._practicedict['ronflag'] = ron #add shot noise, if requested if shot: self._practicedict['shotflag'] = shot self.add_shot(1) else: self._practicedict['shotflag'] = shot #locking the image self._practicemode = True self._lock = True #showing the image self.show_ima()
def validateMonth(month): ValidTypes.validateNumber(month) if month < 1 or month > 12: raise InputError("validateMonth", "Month should be between 1 and 12")