def 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(0.635, 0.85, 1.63) ch1 = self[1.63].check_range() ch2 = self[0.85].check_range() ch3 = self[0.635].check_range() img = geo_image.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) return img
def snow(self): """Make a 'Snow' RGB as suggested in the MSG interpretation guide (rgbpart04.ppt). It is kind of special as it requires the derivation of the daytime component of the mixed Terrestrial/Solar 3.9 micron channel. Furthermore the sun zenith angle is used. """ self.refl39_chan() self.check_channels("_IR39Refl", 0.8, 1.63, 3.75) # We calculate the sun zenith angle again. Should be reused if already # calculated/available... # FIXME! lonlats = self[3.9].area.get_lonlats() sunz = sza(self.time_slot, lonlats[0], lonlats[1]) sunz = np.ma.masked_outside(sunz, 0.0, 88.0) sunzmask = sunz.mask sunz = sunz.filled(88.) costheta = np.cos(np.deg2rad(sunz)) red = np.ma.masked_where(sunzmask, self[0.8].data / costheta) green = np.ma.masked_where(sunzmask, self[1.6].data / costheta) img = geo_image.GeoImage((red, green, self['_IR39Refl'].data), self.area, self.time_slot, crange=((0, 100), (0, 70), (0, 30)), fill_value=None, mode="RGB") img.gamma((1.7, 1.7, 1.7)) return img
def chlorophyll(self, stretch=None): """ From http://oceancolor.gsfc.nasa.gov/REPROCESSING/R2009/ocv6/ * Rrs1 = blue wavelength Rrs (e.g., 443, 490, or 510-nm) * Rrs2 = green wavelength Rrs (e.g., 547, 555, or 565-nm) * X = log10(Rrs1 / Rrs2) * chlor_a = 10^(a0 + a1*X + a2*X^2 + a3*X^3 + a4*X^4) sensor default * blue green a0 a1 a2 a3 a4 OC3V VIIRS Y 443>486 550 0.2228 -2.4683 1.5867 -0.4275 -0.7768 blue: M02(445)>M03(488) green: M04(555) * X = log10(max(M2, M3)/M4) """ self.check_channels("M02", "M03", "M04") a0, a1, a2, a3, a4 = (0.2228, -2.4683, 1.5867, -0.4275, -0.7768) #X = np.maximum(self["M02"].data, self["M03"].data)/self["M04"].data X = self["M02"].data / self["M04"].data X = np.log10(X) chlor_a = 10**(a0 + a1 * X + a2 * (X**2) + a3 * (X**3) + a4 * (X**4)) print 'chlor_a:', chlor_a.min(), chlor_a.mean(), chlor_a.max() img = geo_image.GeoImage(chlor_a, self.area, self.time_slot, fill_value=0, mode="L") if stretch: img.enhance(stretch=stretch) return img
def red_snow(self): """Make a Red Snow RGB image composite. +--------------------+--------------------+ | Channels | Gamma | +====================+====================+ | VIS0.6 | gamma 1.6 | +--------------------+--------------------+ | IR1.6 | gamma 1.6 | +--------------------+--------------------+ | IR10.8 (inverted) | gamma 1.6 | +--------------------+--------------------+ Linear stretch without clipping. """ self.check_channels(0.635, 1.63, 10.8) ch1 = self[0.635].check_range() ch2 = self[1.63].check_range() ch3 = -self[10.8].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") img.enhance(stretch="crude") return img
def overview_sun(self, stretch='crude', gamma=1.6): """Make an overview RGB image composite normalising with cosine to the sun zenith angle. """ self.check_channels(0.635, 0.85, 10.8) lonlats = self[10.8].area.get_lonlats() sunz = sza(self.time_slot, lonlats[0], lonlats[1]) sunz = np.ma.masked_outside(sunz, 0.0, 88.0) sunzmask = sunz.mask sunz = sunz.filled(88.) costheta = np.cos(np.deg2rad(sunz)) red = np.ma.masked_where(sunzmask, self[0.635].data / costheta) green = np.ma.masked_where(sunzmask, self[0.85].data / costheta) blue = -self[10.8].data img = geo_image.GeoImage((red, green, blue), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") if stretch: img.enhance(stretch=stretch) if gamma: img.enhance(gamma=gamma) return img
def dust(self): """Make a Dust RGB image composite. +--------------------+--------------------+--------------------+ | Channels | Temp | Gamma | +====================+====================+====================+ | IR12.0 - IR10.8 | -4 to 2 K | gamma 1 | +--------------------+--------------------+--------------------+ | IR10.8 - IR8.7 | 0 to 15 K | gamma 2.5 | +--------------------+--------------------+--------------------+ | IR10.8 | 261 to 289 K | gamma 1 | +--------------------+--------------------+--------------------+ """ self.check_channels(8.7, 10.8, 12.0) ch1 = self[12.0].data - self[10.8].data ch2 = self[10.8].data - self[8.7].data ch3 = self[10.8].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-4, 2), (0, 15), (261, 289))) img.enhance(gamma=(1.0, 2.5, 1.0)) return img
def convection(self): """Make a Severe Convection RGB image composite. +--------------------+--------------------+--------------------+ | Channels | Span | Gamma | +====================+====================+====================+ | WV6.2 - WV7.3 | -30 to 0 K | gamma 1 | +--------------------+--------------------+--------------------+ | IR3.9 - IR10.8 | 0 to 55 K | gamma 1 | +--------------------+--------------------+--------------------+ | IR1.6 - VIS0.6 | -70 to 20 % | gamma 1 | +--------------------+--------------------+--------------------+ """ self.check_channels(0.635, 1.63, 3.75, 6.7, 7.3, 10.8) ch1 = self[6.7].data - self[7.3].data ch2 = self[3.75].data - self[10.8].data ch3 = self[1.63].check_range() - self[0.635].check_range() img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-30, 0), (0, 55), (-70, 20))) return img
def ash(self): """Make a Ash RGB image composite. +--------------------+--------------------+--------------------+ | Channels | Temp | Gamma | +====================+====================+====================+ | IR12.0 - IR10.8 | -4 to 2 K | gamma 1 | +--------------------+--------------------+--------------------+ | IR10.8 - IR8.7 | -4 to 5 K | gamma 1 | +--------------------+--------------------+--------------------+ | IR10.8 | 243 to 303 K | gamma 1 | +--------------------+--------------------+--------------------+ """ self.check_channels(8.7, 10.8, 12.0) ch1 = self[12.0].data - self[10.8].data ch2 = self[10.8].data - self[8.7].data ch3 = self[10.8].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-4, 2), (-4, 5), (243, 303))) return img
def night_fog(self): """Make a Night Fog RGB image composite. +--------------------+--------------------+--------------------+ | Channels | Temp | Gamma | +====================+====================+====================+ | IR12.0 - IR10.8 | -4 to 2 K | gamma 1 | +--------------------+--------------------+--------------------+ | IR10.8 - IR3.9 | 0 to 6 K | gamma 2.0 | +--------------------+--------------------+--------------------+ | IR10.8 | 243 to 293 K | gamma 1 | +--------------------+--------------------+--------------------+ """ self.check_channels(3.75, 10.8, 12.0) ch1 = self[12.0].data - self[10.8].data ch2 = self[10.8].data - self[3.75].data ch3 = self[10.8].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-4, 2), (0, 6), (243, 293))) img.enhance(gamma=(1.0, 2.0, 1.0)) return img
def cloudtop(self, stretch=(0.005, 0.005), gamma=None): """Make a Cloudtop RGB image composite. +--------------------+--------------------+ | Channels | Gamma | +====================+====================+ | IR3.9 (inverted) | gamma 1 | +--------------------+--------------------+ | IR10.8 (inverted) | gamma 1 | +--------------------+--------------------+ | IR12.0 (inverted) | gamma 1 | +--------------------+--------------------+ Linear stretch with 0.5 % clipping at both ends. """ self.check_channels(3.75, 10.8, 12.0) ch1 = -self[3.75].data ch2 = -self[10.8].data ch3 = -self[12.0].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") if stretch: img.enhance(stretch=stretch) if gamma: img.enhance(gamma=gamma) return img
def overview(self, stretch='crude', gamma=1.6): """Make an overview RGB image composite. +--------------------+--------------------+ | Channels | Gamma (default) | +====================+====================+ | VIS0.6 | gamma 1.6 | +--------------------+--------------------+ | VIS0.8 | gamma 1.6 | +--------------------+--------------------+ | IR10.8 (inverted) | gamma 1.6 | +--------------------+--------------------+ Linear stretch without clipping is applied. """ self.check_channels(0.635, 0.85, 10.8) ch1 = self[0.635].check_range() ch2 = self[0.85].check_range() ch3 = -self[10.8].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") if stretch: img.enhance(stretch=stretch) if gamma: img.enhance(gamma=gamma) return img
def 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(6.7, 7.3, 9.7, 10.8) ch1 = self[6.7].data - self[7.3].data ch2 = self[9.7].data - self[10.8].data ch3 = self[6.7].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-25, 0), (-40, 5), (243, 208))) return img
def setUp(self): """Setup the test. """ self.time_slot = datetime.datetime(2009, 10, 8, 14, 30) self.data = np.zeros((512, 512), dtype=np.uint8) self.img = geo_image.GeoImage(self.data, area="euro", start_time=self.time_slot)
def dnb(self, stretch="histogram"): """Make a black and white image of the Day-Night band.""" self.check_channels('DNB') img = geo_image.GeoImage(self['DNB'].data, self.area, self.time_slot, fill_value=0, mode="L") if stretch: img.enhance(stretch=stretch) return img
def hr_ir108(self): """Make a black and white image of the IR 10.8um channel (320m). """ self.check_channels("I05") img = geo_image.GeoImage(self["I05"].data, self.area, self.time_slot, fill_value=0, mode="L", crange=(-70 + 273.15, 57.5 + 273.15)) img.enhance(inverse=True) return img
def channel_image(self, channel, fill_value=0): """Make a black and white image of the *channel*. Linear stretch without clipping is applied by default. """ self.check_channels(channel) img = geo_image.GeoImage(self[channel].data, self[channel].area, self.time_slot, fill_value=fill_value, mode="L") img.enhance(stretch="crude") return img
def __call__(self, *channels, **keys): """Build a geoimage. e.g.: img = l.image(0.6, 0.8, -10.8, mode="RGB") """ data = [] area = None inv = [] new_channels = [] for channel in channels: if isinstance(channel, str): if channel.startswith("-"): inv.append(True) channel = channel[1:] else: inv.append(False) else: if channel < 0: inv.append(True) channel = -channel else: inv.append(False) new_channels.append(channel) data.append(self[channel].data) new_area = self[channel].area if area and (new_area != area): raise ValueError("Channels should have the same area") else: area = new_area self.check_channels(*new_channels) img = geo_image.GeoImage(data, area=area, start_time=self.time_slot, fill_value=keys.get("fill_value", None), crange=keys.get("crange", None), mode=keys.get("mode", None)) img.enhance(inverse=inv, gamma=keys.get("gamma", 1.0), stretch=keys.get("stretch", "no")) return img
def dnb_rgb(self, stretch="linear"): """Make a RGB Day-Night band using M15 as blue.""" self.check_channels('DNB', 'M15') ch1 = self['DNB'].data ch2 = self['DNB'].data ch3 = -self['M15'].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") if stretch: img.enhance(stretch=stretch) return img
def wv_low(self): """Make a black and white image of the IR 7.3um channel. Channel data inverted and a linear stretch is applied with 0.5 % clipping at both ends. """ self.check_channels(7.3) img = geo_image.GeoImage(self[7.3].data, self.area, self.time_slot, fill_value=0, mode="L") img.enhance(inverse=True, stretch="linear") return img
def ir108(self): """Make a black and white image of the IR 10.8um channel. Channel is inverted. Temperature range from -70 °C (white) to +57.5 °C (black) is shown. """ self.check_channels(10.8) img = geo_image.GeoImage(self[10.8].data, self.area, self.time_slot, fill_value=0, mode="L", crange=(-70 + 273.15, 57.5 + 273.15)) img.enhance(inverse=True) return img
def ash(self): """Make a Ash RGB image composite. """ self.check_channels('M14', 'M15', 'M16') ch1 = self['M16'].data - self['M15'].data ch2 = self['M15'].data - self['M14'].data ch3 = self['M15'].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-4, 2), (-4, 5), (243, 303))) return img
def fog(self): """Make a Fog RGB image composite. """ self.check_channels('M14', 'M15', 'M16') ch1 = self['M16'].data - self['M15'].data ch2 = self['M15'].data - self['M14'].data ch3 = self['M15'].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-4, 2), (0, 6), (243, 283))) img.enhance(gamma=(1.0, 2.0, 1.0)) return img
def red_snow(self): """Make a Red Snow RGB image composite. """ self.check_channels('M05', 'M10', 'M15') ch1 = self['M05'].check_range() ch2 = self['M10'].check_range() ch3 = -self['M15'].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") img.enhance(stretch="crude") return img
def hr_cloudtop(self): """Make a Night Fog RGB image composite. """ self.check_channels('I04', 'I05') ch1 = -self['I04'].data ch2 = self['I05'].data ch3 = self['I05'].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") img.enhance(stretch=(0.005, 0.005)) return img
def hr_green_snow(self): """Make a Green Snow RGB image composite. """ self.check_channels('I01', 'I03', 'I05') ch1 = self['I03'].check_range() ch2 = self['I01'].check_range() ch3 = -self['I05'].data img = geo_image.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) return img
def night_microphysics(self): """Make a Night Microphysics RGB image composite from Seviri channels. This is a Eumetsat variant of night_fog. See e.g http://oiswww.eumetsat.int/~idds/html/doc/best_practices.pdf """ self.check_channels(3.9, 10.8, 12.0) ch1 = self[12.0].data - self[10.8].data ch2 = self[10.8].data - self[3.9].data ch3 = self[10.8].data img = geo_image.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
def truecolor(self): """Make a daytime true color RGB composite from Modis channels. """ self.check_channels(0.645, 0.555, 0.469) ch1 = self[0.645].data / 100. ch2 = self[0.555].data / 100. ch3 = self[0.469].data / 100. img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=None, mode="RGB") img.enhance(stretch="histogram") return img
def hr_red_snow(self): """Make a high resolution Red Snow RGB image composite from the I-bands only. """ self.check_channels('I01', 'I03', 'I05') ch1 = self['I01'].check_range() ch2 = self['I03'].check_range() ch3 = -self['I05'].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB") img.enhance(stretch="crude") return img
def dnb_overview(self): """Make an Overview RGB image composite from VIIRS channels. """ self.check_channels('DNB', 'M15') ch1 = self['DNB'].data ch2 = self['DNB'].data ch3 = -self['M15'].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=None, mode="RGB") img.enhance(stretch="linear") return img
def night_fog(self): """Make a Night Fog RGB image composite from Seviri channels. """ self.co2corr_chan() self.check_channels("_IR39Corr", 10.8, 12.0) ch1 = self[12.0].data - self[10.8].data ch2 = self[10.8].data - self["_IR39Corr"].data ch3 = self[10.8].data img = geo_image.GeoImage((ch1, ch2, ch3), self.area, self.time_slot, fill_value=(0, 0, 0), mode="RGB", crange=((-4, 2), (0, 6), (243, 293))) img.enhance(gamma=(1.0, 2.0, 1.0)) return img