def sza(self): #self.check_channels("VIS006", "HRV", "IR_108") import numpy as np # calculate longitude/latitude and solar zenith angle from pyorbital.astronomy import sun_zenith_angle lonlats = self.area.get_lonlats() #lonlats = self["IR_108"].area.get_lonlats() sza = sun_zenith_angle(self.time_slot, lonlats[0], lonlats[1]) ### stupid numbers for outside disk!!! #import numpy.ma as ma #sza=ma.masked_equal(sza, 8.24905797976) #sza=ma.masked_equal(sza, 8.25871138053) img = GeoImage(sza, self.area, self.time_slot, fill_value=(0, 0, 0), mode="L") from trollimage.colormap import rainbow cm = deepcopy(rainbow) cm.set_range(0, 90) img.colorize(cm) return img
def IR_039c_CO2(self): """ IR_039 channel, but compensated for the CO2 absorption """ from trollimage.image import Image as trollimage self.co2corr_chan() self.check_channels("_IR39Corr") img = GeoImage(self["_IR39Corr"].data, self.area, self.time_slot, fill_value=(0, 0, 0), mode="L") #min_data = prop.min() #max_data = prop.max() min_data = 210 # same as for IR_039 in get_input_msg.py max_data = 340 # same as for IR_039 in get_input_msg.py colorize = True if colorize: # use trollimage to create a color map cm = deepcopy(rainbow) cm.set_range(min_data, max_data) # colorize the image img.colorize(cm) return img
def sandwich(self): """Make a colored 10.8 RGB image with HRV resolution enhacement from Seviri channels. """ from trollimage.image import Image as trollimage self.check_channels('IR_108', "HRV") ## use trollimage to create black white image #img = trollimage(self['IR_108'].data, mode="L") img = GeoImage(self["IR_108"].data, self.area, self.time_slot, mode="L") #, fill_value=0 # use trollimage to create a color map greys.set_range(-30 + 273.15, 30 + 273.15) cm2 = deepcopy(rainbow) cm2.set_range(-73 + 273.15, -30.00001 + 273.15) cm2.reverse() my_cm = cm2 + greys #luminance = GeoImage((self["HRV"].data), self.area, self.time_slot, # crange=(0, 100), mode="L") #luminance.enhance(gamma=2.0) #img.replace_luminance(luminance.channels[0]) ## colorize the image img.colorize(my_cm) return img
def ndvi(self): """Make a normalized vegitation index image from Seviri channels. """ from trollimage.image import Image as trollimage from trollimage.colormap import rdylgn self.check_channels('VIS006', 'VIS008') colorize = True ndvi = (self['VIS008'] - self['VIS006']) / (self['VIS008'] + self['VIS006']) ## use trollimage to create black white image ## black and white version img = GeoImage(ndvi.data, self.area, self.time_slot, fill_value=(0, 0, 0), mode="L") if colorize: # use trollimage to create a color map rdylgn.set_range(-1., +1.) # colorize the image img.colorize(rdylgn) return img
def panSharpen(image, data, band): from mpop.imageo.geo_image import GeoImage pan_data = data[band].data pan = GeoImage((pan_data), data.area, data.time_slot, crange=(0,100) , mode="L") pan.enhance(gamma=2.0) sharp_image = image sharp_image.replace_luminance(pan.channels[0]) return sharp_image
def as_image(self, stretched=True): """Return the channel as a :class:`mpop.imageo.geo_image.GeoImage` object. The *stretched* argument set to False allows the data to remain untouched (as opposed to crude stretched by default to obtain the same output as :meth:`show`). """ from mpop.imageo.geo_image import GeoImage img = GeoImage(self._data, self.area, None) if stretched: img.stretch("crude") return img
def pilimage2geoimage(pimage, area, timeslot): if pimage.mode == 'RGB': (r,g,b) = _image2array(pimage) gi = GeoImage((r,g,b), area, timeslot, mode=pimage.mode) elif pimage.mode == 'RGBA': (r,g,b,a) = _image2array(pimage) gi = GeoImage((r,g,b,a), area, timeslot, mode=pimage.mode) else: "*** Error in pilimage2geoimage (ninjotiff_example)" " unknown PIL_image mode: ", pimage.mode quit return gi
def hr_visual(self): """Make a High Resolution visual BW image composite from Seviri channel. """ self.check_channels("HRV") img = GeoImage(self["HRV"].data, self.area, self.time_slot, fill_value=0, mode="L") img.enhance(stretch="crude") return img
def average(self, downscaling_factor=2, average_window=None): """ Makes a mean convolution of an image. :Parameters: `downscaling_factor` : int image downscaling factor, default is a factor 2. `average_window` : int window size for calculating mean values, default is the same as downscaling_factor. :Returns: `image` : GeoImage mean convoluted image. """ from mpop.imageo.geo_image import GeoImage from pyresample import geometry import scipy.ndimage as ndi self.check_channels(9.65) if average_window == None: average_window = downscaling_factor LOG.info("Downsampling a factor %d and averaging " % downscaling_factor + "in a window of %dx%d" % (average_window, average_window)) ch = self[9.65] # If average window and downscale factor is the same # the following could be used: # # data = data.reshape([shight, hight/shight, # swidth, width/swidth]).mean(3).mean(1) # avg kernel kernel = (np.ones((average_window, average_window), dtype=np.float) / (average_window * average_window)) # do convolution data = ndi.filters.correlate(ch.data.astype(np.float), kernel, mode='nearest') # downscale data = data[1::downscaling_factor, 1::downscaling_factor] # New area, and correct for integer truncation. p_size_x, p_size_y = (ch.area.pixel_size_x * downscaling_factor, ch.area.pixel_size_y * downscaling_factor) area_extent = (ch.area.area_extent[0], ch.area.area_extent[1], ch.area.area_extent[0] + data.shape[1] * p_size_x, ch.area.area_extent[1] + data.shape[0] * p_size_y) area = geometry.AreaDefinition( self._data_holder.satname + self._data_holder.instrument_name + str(area_extent) + str(data.shape), "On-the-fly area", ch.area.proj_id, ch.area.proj_dict, data.shape[1], data.shape[0], area_extent) return GeoImage(data, area, self.time_slot, fill_value=(0, ), mode='L')
def s2_truecolor(self): self.check_channels('B02','B03','B04') ch1 = self['B04'].data ch2 = self['B03'].data ch3 = self['B02'].data img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=None, mode="RGB") img.enhance(stretch="linear") #img.enhance(stretch="histogram") img.enhance(gamma=2.0) return img
def fls_day_modis(self, elevation, cot, reff): """ This method defines a composite for fog and low stratus detection and forecasting at daytime. Required additional inputs: elevation Ditital elevation model as array cot Cloud optical thickness(depth) as array reff cloud particle effective radius as array """ logger.debug("Creating fog composite for {} instrument" .format(self.fullname)) self.check_channels(0.635, 0.86, 1.64, 3.959, 8.7, 10.8, 12.0) chn108 = self[10.8].data chn39 = self[3.959].data chn08 = self[0.86].data chn16 = self[1.64].data chn06 = self[0.635].data chn87 = self[8.7].data chn120 = self[12.0].data time = self.time_slot # Get central lon/lat coordinates for the image area = self[10.8].area lon, lat = area.get_lonlats() # Compute fog mask fogmask = fogpy(chn108, chn39, chn08, chn16, chn06, chn87, chn120, time, lat, lon, elevation, cot, reff) # Apply fog mask to 10.8 channel out = np.ones(fogmask.shape) out_ma = np.ma.masked_where(fogmask, out) # Plot infrared 10.8 um channel with fog mask as image img = GeoImage(out_ma, self.area, self.time_slot, fill_value=0, mode="L") img.enhance(stretch="crude") return(img)
def fls_night(self, sza): """This method defines a composite for fog and low stratus detection and forecasting at night. The fog algorithm is optimized for the Meteosat Second Generation - SERVIRI instrument. Args: | sza (:obj:`ndarray`): Satellite zenith angle as array. Returns: Infrared image with colorized fog areas and the calculated fog mask """ logger.debug("Creating fog composite for {} instrument scene {}" .format(self.fullname, self.time_slot)) self.check_channels(3.92, 10.8) # Get central lon/lat coordinates for the image area = self[10.8].area lon, lat = area.get_lonlats() flsinput = {'ir108': self[10.8].data, 'ir039': self[3.92].data, 'sza': sza, 'lat': lat, 'lon': lon, 'time': self.time_slot, 'plot': True, 'save': True, 'dir': '/tmp', 'resize': '5'} # Compute fog mask flsalgo = NightFogLowStratusAlgorithm(**flsinput) fls, mask = flsalgo.run() # Create geoimage object from algorithm result flsimg = GeoImage(fls, area, self.time_slot, fill_value=0, mode="L") flsimg.enhance(stretch="crude") maskimg = GeoImage(~mask, area, self.time_slot, fill_value=0, mode="L") maskimg.enhance(stretch="crude") return flsimg, maskimg
def HRVFog(self, downscale=False, return_data=False): """Make an HRV RGB image composite. +--------------------+--------------------+--------------------+ | Channels | Temp | Gamma | +====================+====================+====================+ | NIR1.6 | 0 - 70 | gamma 1 | +--------------------+--------------------+--------------------+ | HRV | 0 - 100 | gamma 1 | +--------------------+--------------------+--------------------+ | HRV | 0 - 100 | gamma 1 | +--------------------+--------------------+--------------------+ """ self.check_channels(1.6, "HRV") from pyorbital.astronomy import sun_zenith_angle lonlats = self["HRV"].area.get_lonlats() sza = sun_zenith_angle(self.time_slot, lonlats[0], lonlats[1]) cos_sza = np.cos(np.radians(sza)) + 0.05 ch1 = self[1.6].data / cos_sza ch2 = self["HRV"].data / cos_sza ch3 = self["HRV"].data / cos_sza # this area exception is not nice! if downscale or (self["HRV"].area.name == 'ccs4' or self["HRV"].area.name == 'Switzerland_stereographic_500m'): print('... downscale NIR1.6') from plot_coalition2 import downscale_array ch1 = downscale_array(ch1) if return_data: return ch1, ch2, ch3 img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((0, 70), (0, 100), (0, 100))) return img
def hr_airmass(self): """Make an airmass RGB image composite. +--------------------+--------------------+--------------------+ | Channels | Temp | Gamma | +====================+====================+====================+ | WV6.2 - WV7.3 | -25 to 0 K | gamma 1 | +--------------------+--------------------+--------------------+ | IR9.7 - IR10.8 | -40 to 5 K | gamma 1 | +--------------------+--------------------+--------------------+ | WV6.2 | 243 to 208 K | gamma 1 | +--------------------+--------------------+--------------------+ """ self.check_channels('WV_062', 'WV_073', 'IR_097', 'IR_108') ch1 = self['WV_062'].data - self['WV_073'].data ch2 = self['IR_097'].data - self['IR_108'].data ch3 = self['WV_062'].data img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-25, 0), (-40, 5), (243, 208))) luminance = GeoImage((self["HRV"].data), self.area, self.time_slot, crange=(0, 100), mode="L") luminance.enhance(gamma=2.0) img.replace_luminance(luminance.channels[0]) return img
def s2_truecolor(self): self.check_channels('B02', 'B03', 'B04') ch1 = self['B04'].data ch2 = self['B03'].data ch3 = self['B02'].data img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=None, mode="RGB") img.enhance(stretch="linear") #img.enhance(stretch="histogram") img.enhance(gamma=2.0) return img
def fls_day(self, elevation, cot, reff, lwp=None): """ This method defines a composite for fog and low stratus detection and forecasting at daytime. Required additional inputs: elevation Ditital elevation model as array cot Cloud optical thickness(depth) as array reff Cloud particle effective radius as array lwp Liquid water path as array """ logger.debug("Creating fog composite for {} instrument" .format(self.fullname)) self.check_channels(0.635, 0.81, 1.64, 3.92, 8.7, 10.8, 12.0) chn108 = self[10.8].data chn39 = self[3.92].data chn08 = self[0.81].data chn16 = self[1.64].data chn06 = self[0.635].data chn87 = self[8.7].data chn120 = self[12.0].data time = self.time_slot # Get central lon/lat coordinates for the image area = self[10.8].area lon, lat = area.get_lonlats() # Compute fog mask fogmask, lcth = fogpy(chn108, chn39, chn08, chn16, chn06, chn87, chn120, time, lat, lon, elevation, cot, reff) print(np.sum(fogmask)) print(lcth.iteritems()) #img = GeoImage(lcth, self.area, self.time_slot, # fill_value=0, mode="L") #img.enhance(stretch="crude") #img.show() if lwp is not None: # Calculate cloud top height cth = estimate_cth(chn108, 'midlatitude winter') cth = np.ma.filled(cth, np.nan) # Apply low cloud mask cth_ma = np.ma.array(cth, mask=fogmask) # Convert lwp from kg m-2 to g m-2 lwp_ma = np.ma.array(lwp * 1000, mask=fogmask) ctt_ma = np.ma.array(chn108, mask=fogmask) print(cth_ma.count()) # Calibrate cloud base height v_get_cloud_base_height = np.vectorize(get_cloud_base_height) cbh = v_get_cloud_base_height(lwp_ma.compressed(), cth_ma.compressed(), ctt_ma.compressed()) # Apply fog mask to 10.8 channel out = np.ones(fogmask.shape) out_ma = np.ma.masked_where(fogmask, out) # Plot infrared 10.8 um channel with fog mask as image img = GeoImage(out_ma, self.area, self.time_slot, fill_value=0, mode="L") img.enhance(stretch="crude") return(img, fogmask)
def DayNightFog(self, downscale=False, sza_max=88): """Make an RGB image composite. during day: HRVFog during night: night microphysics """ self.check_channels("IR_016", "IR_039", "IR_108", "IR_120", "HRV") # HRVFog recipe # -------------- from pyorbital.astronomy import sun_zenith_angle lonlats = self["HRV"].area.get_lonlats() sza = sun_zenith_angle(self.time_slot, lonlats[0], lonlats[1]) import numpy as np cos_sza = np.cos(np.radians(sza)) + 0.05 ch1a = self["IR_016"].data / cos_sza ch2a = self["HRV"].data / cos_sza ch3a = self["HRV"].data / cos_sza # this area exception is not nice! if downscale or (self["HRV"].area.name == 'ccs4' or self["HRV"].area.name == 'Switzerland_stereographic_500m'): print('... downscale NIR1.6') from plot_coalition2 import downscale_array ch1a = downscale_array(ch1a) # night microphysics recipe # -------------------------- ch1b = self["IR_120"].data - self["IR_108"].data ch2b = self["IR_108"].data - self["IR_039"].data ch3b = self["IR_108"].data # this area exception is not nice! if downscale or (self["HRV"].area.name == 'ccs4' or self["HRV"].area.name == 'Switzerland_stereographic_500m'): print('... downscale night microphysics - red/green/blue') ch1b = downscale_array(ch1b) ch2b = downscale_array(ch2b) ch3b = downscale_array(ch3b) # re-adjust range so that both are in in the same range # ch1b [-4,2] -> [0,70] ch1b = (ch1b + 4.) * 70. / 6. # ch2b [0,10] -> [0,100] ch2b = (ch2b) * 10. # ch3b [243, 293] -> [0,100] ch3b = (ch3b - 243.0) * 100.0 / (293.0 - 243.0) mask = np.array(sza > sza_max) # add two images: ch1 = (1 - mask) * ch1a + mask * ch1b ch2 = (1 - mask) * ch2a + mask * ch2b ch3 = (1 - mask) * ch3a + mask * ch3b img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((0, 70), (0, 100), (0, 100))) #img = GeoImage((ch1, ch2, ch3), # self.area, # self.time_slot, # fill_value=(0, 0, 0), # mode="RGB", # crange=((-4, 2), # (0, 10), # (243, 293))) return img
sflux = solar_irr.inband_solarflux(seviri.rsr['IR3.9']) ch39 = local_data['IR_039'] ch11 = local_data['IR_108'] ch13 = local_data['IR_134'] lonlats = ch39.area.get_lonlats() from pyorbital.astronomy import sun_zenith_angle sunz = sun_zenith_angle(tslot, lonlats[0], lonlats[1]) print("... create look-up-table") #refl37 = Calculator(rsr) refl37 = Calculator('Meteosat-9', 'seviri', 'IR3.9', solar_flux=sflux) #refl37.make_tb2rad_lut('/tmp/seviri_37_tb2rad_lut.npz') # new syntax -> #refl37.make_tb2rad_lut('IR3.9','/data/COALITION2/database/meteosat/SEVIRI/seviri_tb2rad_lut/') print("... calculate reflectance") r39 = refl37.reflectance_from_tbs(sunz, ch39.data, ch11.data, ch13.data) # , lookuptable='/tmp/seviri_37_tb2rad_lut.npz' import numpy as np r39 = np.ma.masked_array(r39, mask = np.logical_or(np.less(r39, -0.1), np.greater(r39, 3.0))) print("... show new RGB image") from mpop.imageo.geo_image import GeoImage img = GeoImage((local_data[0.8].data, local_data[1.6].data, r39 * 100), area, tslot, crange=((0, 100), (0, 70), (0, 30)), fill_value=(0, 0, 0), mode="RGB") img.enhance(gamma=1.7) img.show()
def hr_natural(self, stretch=None, gamma=1.8): """Make a Natural Colors RGB image composite. +--------------------+--------------------+--------------------+ | Channels | Range (reflectance)| Gamma (default) | +====================+====================+====================+ | IR1.6 | 0 - 90 | gamma 1.8 | +--------------------+--------------------+--------------------+ | VIS0.8 | 0 - 90 | gamma 1.8 | +--------------------+--------------------+--------------------+ | VIS0.6 | 0 - 90 | gamma 1.8 | +--------------------+--------------------+--------------------+ """ self.check_channels('VIS006', 'VIS008', 'IR_016') ch1 = self['IR_016'].check_range() ch2 = self['VIS008'].check_range() ch3 = self['VIS006'].check_range() img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((0, 90), (0, 90), (0, 90))) if stretch: img.enhance(stretch=stretch) if gamma: img.enhance(gamma=gamma) luminance = GeoImage((self["HRV"].data), self.area, self.time_slot, crange=(0, 100), mode="L") luminance.enhance(gamma=2.0) img.replace_luminance(luminance.channels[0]) return img
def fls_day(self, elevation, cot, reff, lwp=None, cth=None, validate=False, plot=False, plotdir='/tmp', single=False): """This method defines a composite for fog and low stratus detection and forecasting at daytime. The fog algorithm is optimized for the Meteosat Second Generation - SERVIRI instrument. Args: | elevation (:obj:`ndarray`): Ditital elevation model as array. | cot (:obj:`ndarray`): Cloud optical thickness(depth) as array. | reff (:obj:`ndarray`): Cloud particle effective radius as array. | lwp (:obj:`ndarray`): Liquid water path as array. | cth (:obj:`ndarray`): Cloud top height as array, optional. | validate (:obj:`bool`): Additional cloud mask output, optional. | plot (:obj:`bool`): Save filter and algorithm results as png images. | plotdir (:obj:`str`): Path to plotting directory as string. | single (:obj:`bool`): Compute lowcloud model single pixelwise. Default is False. Returns: Infrared image with colorized fog areas and the calculated fog mask. """ logger.debug("Creating fog composite for {} instrument scene {}" .format(self.fullname, self.time_slot)) self.check_channels(0.635, 0.81, 1.64, 3.92, 8.7, 10.8, 12.0) # Get central lon/lat coordinates for the image area = self[10.8].area lon, lat = area.get_lonlats() flsinput = {'vis006': self[0.635].data, 'vis008': self[0.81].data, 'ir108': self[10.8].data, 'nir016': self[1.64].data, 'ir039': self[3.92].data, 'ir120': self[12.0].data, 'ir087': self[8.7].data, 'lat': lat, 'lon': lon, 'time': self.time_slot, 'elev': elevation, 'cot': cot, 'reff': reff, 'lwp': lwp, 'cth': cth, 'plot': plot, 'save': plot, 'dir': plotdir, 'single': single, 'resize': '1'} # Compute fog mask flsalgo = DayFogLowStratusAlgorithm(**flsinput) fls, mask = flsalgo.run() # Create geoimage object from algorithm result flsimg = GeoImage(fls, area, self.time_slot, fill_value=0, mode="L") flsimg.enhance(stretch="crude") maskimg = GeoImage(~mask, area, self.time_slot, fill_value=0, mode="L") maskimg.enhance(stretch="crude") if validate: # Get cloud mask image vmaskimg = GeoImage(flsalgo.vcloudmask, area, self.time_slot, fill_value=0, mode="L") vmaskimg.enhance(stretch="crude") # Get cloud base height image cbhimg = GeoImage(flsalgo.cbh, area, self.time_slot, fill_value=9999, mode="L") # Get fog base height image fbhimg = GeoImage(flsalgo.fbh, area, self.time_slot, fill_value=9999, mode="L") # Get low cloud top height image lcthimg = GeoImage(flsalgo.lcth, area, self.time_slot, fill_value=9999, mode="L") return [flsimg, maskimg, vmaskimg, cbhimg, fbhimg, lcthimg] else: return flsimg, maskimg
def create_PIL_image(rgb, data, in_msg): if in_msg.verbose: print("*** make image for: ", rgb) # get the data array that you want to plot if rgb in products.MSG: prop = data[rgb].data plot_type = 'channel_image' elif rgb in products.MSG_color: prop = data[rgb.replace("c", "")].data plot_type = 'trollimage' elif rgb in products.CTTH: prop = data[rgb].data prop.mask = (prop == 0) if rgb == 'CTH': prop /= 1000. # 1000. == m -> km plot_type = 'trollimage' elif rgb in products.CT: prop = data[rgb].data plot_type = 'palette' if rgb == 'CT_QUALITY': plot_type = 'trollimage' elif rgb in products.CMa or rgb in products.SPhR: prop = data[rgb].data if hasattr(data[rgb], 'palette') and in_msg.nwcsaf_calibrate == False: plot_type = 'palette' else: plot_type = 'trollimage' elif rgb in products.HSAF: prop = data[rgb].data plot_type = 'trollimage' else: # includes products.RGBs_buildin prop = ma.asarray([-999., -999.]) plot_type = 'user_defined' #from numpy import log10 #prop=log10(prop) # search minimum and maximum # (default) min_data = prop.min() max_data = prop.max() # replace default with fixed min/max if specified if in_msg.fixed_minmax: if rgb in list(in_msg.rad_min.keys()): min_data = in_msg.rad_min[rgb] else: if rgb not in products.RGBs_buildin: print( "*** Warning, no specified minimum for plotting in get_input_msg.py or input file" ) if rgb in list(in_msg.rad_max.keys()): max_data = in_msg.rad_max[rgb] else: if rgb not in products.RGBs_buildin: print( "*** Warning, no specified maximum for plotting in get_input_msg.py or input file" ) if in_msg.verbose and rgb not in products.RGBs_buildin: print('... set value range from min_data (', min_data, ') to max_data (', max_data, ')') # specifies if a colorbar does make sense at all in_msg.colormap = {} # make the image if plot_type == 'channel_image': if in_msg.verbose: print( " use data.image.channel_image for black and white pictures" ) img = data.image.channel_image(rgb) in_msg.colormap[rgb] = None elif plot_type == 'trollimage': if in_msg.verbose: print( " use trollimage.image.image for colorized pictures (min=" + str(min_data) + ", max=" + str(max_data) + ")") img = trollimage(prop, mode="L", fill_value=in_msg.fill_value) rainbow.set_range(min_data, max_data) img.colorize(rainbow) rainbow_r.set_range( min_data, max_data ) # attention set_range does modify the colormap, but does not have a return values ! in_msg.colormap[rgb] = rainbow.reverse() # print "in_msg.colormap[rgb]", rgb, in_msg.colormap[rgb] elif plot_type == 'palette': min_data = 0. max_data = float(len(data[rgb].palette) - 1) if in_msg.verbose: print(" use GeoImage and colorize with a palette (min=" + str(min_data) + ", max=" + str(max_data) + ")") img = GeoImage(prop, data.area, data.time_slot, mode="P", palette=data[rgb].palette, fill_value=in_msg.fill_value) colormap = convert_palette2colormap(data[rgb].palette) colormap.set_range(min_data, max_data) # no return value! in_msg.colormap[rgb] = colormap elif plot_type == 'user_defined': obj_image = get_image(data, rgb) if in_msg.verbose: print(" use image function defined by my_msg_module.py") img = obj_image() in_msg.colormap[rgb] = None #if rgb == 'ndvi': # in_msg.colormap[rgb] = rdylgn_r else: print("*** Error in create_PIL_image (" + inspect.getfile(inspect.currentframe()) + ")") print(" unknown plot_type ", plot_type) quit() if in_msg.HRV_enhancement: if in_msg.verbose: print("enhance the image with the HRV channel") luminance = GeoImage((data["HRV"].data), data.area, data.time_slot, crange=(0, 100), mode="L") luminance.enhance(gamma=2.0) img.replace_luminance(luminance.channels[0]) rgb = 'HR' + rgb ## alternative: for geoimages is possible to add coasts and borders, but not for trollimage #if hasattr(img, 'add_overlay'): # if in_msg.verbose: # print " add coastlines to image by add_averlay" # img.add_overlay(color=(0, 0, 0), width=0.5, resolution=None) # convert image to PIL image if hasattr(img, 'pil_image'): if in_msg.verbose: print(" convert to PIL_image by pil_image function") PIL_image = img.pil_image() else: if in_msg.verbose: print(" convert to PIL_image by saving and reading") tmp_file = outputDir + satS + '_' + dateS + '_' + timeS + '__' + area + '_' + rgb.replace( "_", "-") + '_tmp.png' # in_msg. img.save(tmp_file) PIL_image = Image.open(tmp_file) subprocess.call("rm " + tmp_file, shell=True) return PIL_image
area_extent=ger_extent) #germ_scene.project('euro4', mode="nearest") #germ_scene.image[0.6].show() germ_area = germ_scene[10.8].area_def # Resample fls input elevation_ger = elevation.resample(germ_area) cot_ger = cot_fd.resample(germ_area) reff_ger = reff_fd.resample(germ_area) cwp_ger = cwp_fd.resample(germ_area) ele_img = GeoImage(elevation_ger.image_data, germ_area, time, fill_value=0, mode="L") ele_img.enhance(stretch="crude") cwp_img = GeoImage(cwp_ger.image_data, germ_area, time, fill_value=0, mode="L") cwp_img.enhance(stretch="crude") reff_img = GeoImage(reff_ger.image_data, germ_area, time, fill_value=0, mode="L") reff_img.enhance(stretch="crude")
def daynight_background(self, cos_scaled=True, use_HRV=False, smooth=False, stretch=False, colorscale='greys', fixed_minmax=False, white_clouds=True): import numpy as np # threshold sza sza1 = 80. # calculate longitude/latitude and solar zenith angle from pyorbital.astronomy import sun_zenith_angle lonlats = self["IR_108"].area.get_lonlats() sza = sun_zenith_angle(self.time_slot, lonlats[0], lonlats[1]) if not smooth: mask = np.array(sza > sza1) else: mask = np.zeros(ir108.shape) mask[np.where(sza > sza1)] = 1 # select, if you want HRV or VIS006 if use_HRV: vis = self["HRV"].data # fill remaining area with VIS006 vis[vis.mask == True] = self["VIS006"].data[vis.mask == True] else: vis = self["VIS006"].data # sceen out data at night/day part of the disk ir108 = self["IR_108"].data * mask # ... and apply cos scaling to mitigate effect of solar zenith angle if not cos_scaled: vis = vis * (1 - mask) else: vis = vis * (1 - mask) / (np.cos(np.radians(sza)) + 0.05) # normilize vis reflectivity and ir brightness temperature # to comparable range between 0 and 1 if fixed_minmax: # minimum and maximum for ir108 ir1 = 190. ir2 = 290. # minimum and maximum for HRV (or VIS006) scale vis1 = 0. if not cos_scaled: vis2 = 75. #for pure vis/hrv else: vis2 = 110. #for scaling with cos(sza) else: # linear stretch from p1 percentile to p2 percentile #import matplotlib.pyplot as plt #plt.hist(ir108[np.where(ir108 > 100)], bins='auto') #plt.title("Histogram with 'auto' bins") #plt.show() #print " min/max(1) IR:", ir108.min(), ir108.max() #print " min/max(1) VIS:", vis.min(), vis.max() # percentile limits p1 = 5 p2 = 95 # ind_ir108 = np.where(ir108 > 100) if len(ind_ir108) > 5: ir1 = np.percentile(ir108[ind_ir108], p1) ir2 = np.percentile(ir108[ind_ir108], p2) else: ir1 = 190. ir2 = 290. ind_vis = np.where(vis > 0) if len(ind_vis) > 5: vis1 = np.percentile(vis[np.where(vis > 0)], p1) vis2 = np.percentile(vis[np.where(vis > 0)], p2) else: vis1 = 5. if not cos_scaled: vis2 = 75. else: vis2 = 110. #print " min/max(2) IR:", ir1, ir2 #print " min/max(2) VIS:", vis1, vis2 # scale the vis and ir channel to the range [0,1] # multiply with mask to keep the zeros for day/night area ir108 = (ir108 - ir1) / (ir2 - ir1) * mask vis = (vis - vis1) / (vis2 - vis1) * (1 - mask) #print " min/max scaled ir: ", ir108.min(), ir108.max() #print " min/max scaled vis:", vis.min(), vis.max() # invert ir108 ir108 = (1 - ir108) * mask img = GeoImage(vis + ir108, self.area, self.time_slot, fill_value=(0, 0, 0), mode="L") print(colorscale, white_clouds) if colorscale == 'rainbow': from trollimage.colormap import rainbow cm = deepcopy(rainbow) elif colorscale == 'greys': from trollimage.colormap import greys cm = deepcopy(greys) if white_clouds: #cm.reverse() # UH (my change in trollimage/colormap.py): color table is not any more changed, but changed one is returned. cm = cm.reverse() cm.set_range(0, 1) img.colorize(cm) if stretch: print("... use streching ", stretch) img.enhance(stretch=stretch) return img
def hr_overview(self): """Make a High Resolution Overview RGB image composite from Seviri channels. """ self.check_channels('VIS006', 'VIS008', 'IR_108', "HRV") ch1 = self['VIS006'].check_range() ch2 = self['VIS008'].check_range() ch3 = -self['IR_108'].data img = GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") img.enhance(stretch="crude") img.enhance(gamma=[1.6, 1.6, 1.1]) luminance = GeoImage((self["HRV"].data), self.area, self.time_slot, crange=(0, 100), mode="L") luminance.enhance(gamma=2.0) img.replace_luminance(luminance.channels[0]) return img