def model_background_state(self): """ Make some sort of realistic dynamics for the background state of reflectance """ if self.surface_rho == None: self.make_stack() # load spectra vegetation_rho, ash_rho = generate_spectra() # select some bands... vegetation_rho = vegetation_rho[::25] ash_rho = ash_rho[::25] # keep these for later... self.ash_rho = ash_rho self.vegetation_rho = vegetation_rho # first fill the dataset with just normal leaf reflectance across all timesteps self.surface_rho = (self.surface_rho[:].T*vegetation_rho[None, :].T).T # now make a mean state... mean_state = make_noises(1, self.xSize) mean_state *= 0.3 mean_state = np.tile(mean_state, (self.bands,self.timesteps,1,1),) mean_state = np.swapaxes(mean_state, 0,1) # alternative with more spatial features -- less like a cloud land_cover = make_landscape(self.xSize) # for each catergory in the land_cover assign a mean variation on # the spectra lc_spe_multiple = np.linspace(0.85, 1.15, len(np.unique(land_cover))) # associate these values with land_cover for i,j in enumerate(np.unique(land_cover)): land_cover[np.where(land_cover==j)] = lc_spe_multiple[i] #import pdb; pdb.set_trace() # multiply this with spectra lc_effect = np.tile(land_cover, (self.timesteps,self.bands,1,1),) #mean_state = np.swapaxes(mean_state, 0,1) self.surface_rho *= lc_effect return None # now generate temporal variability temporal = make_noises(self.timesteps, self.xSize) temporal *= 0.2 # now add to the surface reflectance # need same dimensions temporal = np.tile(temporal, (self.bands,1,1,1),) # switch dimensions temporal = np.swapaxes(temporal, 0,1) self.surface_rho += temporal
def model_cloud_cover(self): """ Add clouds to remove some pixels run after fires has been modelled into scene... """ """ idea for now is to re-use perlin noise generator With a threshold for how many clouds there should be: -- could be semi-seasonal + random element """ # model of cloud cover across timesteps # maximum seasonal component 20% random weather cloud = (0.2 * np.sin(np.linspace(0,np.pi,self.timesteps)) + np.random.normal(0.2, 0.1, self.timesteps)) # make sure max is one cloud[cloud > 1] = 1 # and min is 0 cloud[cloud < 0] = 0 # generate some new perlin noise the_noise = make_noises(self.timesteps, self.xSize, time_multiple=200) """ idea is to threshold the perlin noise by the percentile of cloud_cover this produces a binary mask that should produce realistic looking clouds """ percentiles = np.array([np.percentile(no, cl*100) for no, cl in zip(the_noise, cloud)]) # now threshold the noise below these values for day in xrange(self.timesteps): # mask in cloud the_noise[day][the_noise[day] < percentiles[day]] = True # is cloud # make into a binary the_noise[day][the_noise[day] != True] = False # convert all to a boolean the_noise = the_noise.astype(np.bool) # apply cloud mask to data self.cloud_mask = ~the_noise self.surface_rho = (self.surface_rho[:].T * self.cloud_mask[:,None].T).T # make it into a masked array for clarity #import pdb; pdb.set_trace() self.surface_rho = np.ma.array(self.surface_rho, mask=self.surface_rho==0) return 0