def co2corr(self): """CO2 correction of the brightness temperature of the MSG 3.9um channel:: .. math:: T4_CO2corr = (BT(IR3.9)^4 + Rcorr)^0.25 Rcorr = BT(IR10.8)^4 - (BT(IR10.8)-dt_CO2)^4 dt_CO2 = (BT(IR10.8)-BT(IR13.4))/4.0 """ try: self.check_channels(3.75, 10.8, 13.4) except RuntimeError: LOG.warning("CO2 correction not performed, channel data missing.") return bt039 = self[3.9].data bt108 = self[10.8].data bt134 = self[13.4].data dt_co2 = (bt108-bt134)/4.0 rcorr = bt108 ** 4 - (bt108-dt_co2) ** 4 t4_co2corr = bt039 ** 4 + rcorr t4_co2corr = np.ma.where(t4_co2corr > 0.0, t4_co2corr, 0) t4_co2corr = t4_co2corr ** 0.25 return t4_co2corr
def unload(self, *channels): """Unloads *channels* from memory. :meth:`mpop.scene.SatelliteInstrumentScene.load` must be called again to reload the data. """ for chn in channels: try: self[chn].data = None except AttributeError: LOG.warning("Can't unload channel" + str(chn))
def project(self, dest_area, channels=None, precompute=False, mode=None, radius=None): """Make a copy of the current snapshot projected onto the *dest_area*. Available areas are defined in the region configuration file (ACPG). *channels* tells which channels are to be projected, and if None, all channels are projected and copied over to the return snapshot. If *precompute* is set to true, the projecting data is saved on disk for reusage. *mode* sets the mode to project in: 'quick' which works between cartographic projections, and, as its denomination indicates, is quick (but lower quality), and 'nearest' which uses nearest neighbour for best projection. A *mode* set to None uses 'quick' when possible, 'nearest' otherwise. *radius* defines the radius of influence for neighbour search in 'nearest' mode. Setting it to None, or omitting it will fallback to default values (5 times the channel resolution) or 10km if the resolution is not available. Note: channels have to be loaded to be projected, otherwise an exception is raised. """ if not is_pyresample_loaded: # Not much point in proceeding then return self _channels = set([]) if channels is None: for chn in self.loaded_channels(): _channels |= set([chn]) elif(isinstance(channels, (list, tuple, set))): for chn in channels: try: _channels |= set([self[chn]]) except KeyError: LOG.warning("Channel "+str(chn)+" not found," "thus not projected.") else: raise TypeError("Channels must be a list/" "tuple/set of channel keys!") res = copy.copy(self) if isinstance(dest_area, str): dest_area = mpop.projector.get_area_def(dest_area) res.area = dest_area res.channels = [] if not _channels <= self.loaded_channels(): LOG.warning("Cannot project nonloaded channels: %s." %(_channels - self.loaded_channels())) LOG.info("Will project the other channels though.") _channels = _channels and self.loaded_channels() cov = {} for chn in _channels: if chn.area is None: if self.area is None: area_name = ("swath_" + self.fullname + "_" + str(self.time_slot) + "_" + str(chn.shape)) chn.area = area_name else: if is_pyresample_loaded: try: chn.area = AreaDefinition( self.area.area_id + str(chn.shape), self.area.name, self.area.proj_id, self.area.proj_dict, chn.shape[1], chn.shape[0], self.area.area_extent, self.area.nprocs) except AttributeError: try: dummy = self.area.lons dummy = self.area.lats chn.area = self.area area_name = ("swath_" + self.fullname + "_" + str(self.time_slot) + "_" + str(chn.shape)) chn.area.area_id = area_name except AttributeError: chn.area = self.area + str(chn.shape) else: chn.area = self.area + str(chn.shape) else: #chn.area is not None if is_pyresample_loaded and isinstance(chn.area, SwathDefinition): area_name = ("swath_" + self.fullname + "_" + str(self.time_slot) + "_" + str(chn.shape) + "_" + str(chn.name)) chn.area.area_id = area_name if chn.area == dest_area: res.channels.append(chn) else: if isinstance(chn.area, str): area_id = chn.area else: area_id = chn.area_id or chn.area.area_id if area_id not in cov: if radius is None: if chn.resolution > 0: radius = 5 * chn.resolution else: radius = 10000 cov[area_id] = mpop.projector.Projector(chn.area, dest_area, mode=mode, radius=radius) if precompute: try: cov[area_id].save() except IOError: LOG.exception("Could not save projection.") try: res.channels.append(chn.project(cov[area_id])) except NotLoadedError: LOG.warning("Channel "+str(chn.name)+" not loaded, " "thus not projected.") # Compose with image object try: if res._CompositerClass is not None: # Pass weak ref to compositor to allow garbage collection res.image = res._CompositerClass(weakref.proxy(res)) except AttributeError: pass return res
def load(self, channels=None, load_again=False, area_extent=None, **kwargs): """Load instrument data into the *channels*. *Channels* is a list or a tuple containing channels we will load data into, designated by there center wavelength (float), resolution (integer) or name (string). If None, all channels are loaded. The *load_again* boolean flag allows to reload the channels even they have already been loaded, to mirror changes on disk for example. This is false by default. The *area_extent* keyword lets you specify which part of the data to load. Given as a 4-element sequence, it defines the area extent to load in satellite projection. The other keyword arguments are passed as is to the reader plugin. Check the corresponding documentation for more details. """ # Set up the list of channels to load. if channels is None: for chn in self.channels: self.channels_to_load |= set([chn.name]) elif(isinstance(channels, (list, tuple, set))): for chn in channels: try: self.channels_to_load |= set([self[chn].name]) except KeyError: self.channels_to_load |= set([chn]) else: raise TypeError("Channels must be a list/" "tuple/set of channel keys!") loaded_channels = [chn.name for chn in self.loaded_channels()] if load_again: for chn in self.channels_to_load: if chn in loaded_channels: self.unload(chn) loaded_channels = [] else: for chn in loaded_channels: self.channels_to_load -= set([chn]) # find the plugin to use from the config file conf = ConfigParser.ConfigParser() try: conf.read(os.path.join(CONFIG_PATH, self.fullname + ".cfg")) if len(conf.sections()) == 0: raise ConfigParser.NoSectionError(("Config file did " "not make sense")) levels = [section for section in conf.sections() if section.startswith(self.instrument_name+"-level")] except ConfigParser.NoSectionError: LOG.warning("Can't load data, no config file for " + self.fullname) self.channels_to_load = set() return levels.sort() if levels[0] == self.instrument_name+"-level1": levels = levels[1:] if len(levels) == 0: raise ConfigParser.NoSectionError( self.instrument_name+"-levelN (N>1) to tell me how to"+ " read data... Not reading anything.") for level in levels: if len(self.channels_to_load) == 0: return LOG.debug("Looking for sources in section "+level) reader_name = conf.get(level, 'format') try: reader_name = eval(reader_name) except NameError: reader_name = str(reader_name) LOG.debug("Using plugin mpop.satin."+reader_name) # read the data reader = "mpop.satin."+reader_name try: try: # Look for builtin reader reader_module = __import__(reader, globals(), locals(), ['load']) except ImportError: # Look for custom reader reader_module = __import__(reader_name, globals(), locals(), ['load']) if area_extent is not None: if(isinstance(area_extent, (tuple, list)) and len(area_extent) == 4): kwargs["area_extent"] = area_extent else: raise ValueError("Area extent must be a sequence of " "four numbers.") reader_module.load(self, **kwargs) except ImportError: LOG.exception("ImportError while loading "+reader+".") continue loaded_channels = [chn.name for chn in self.loaded_channels()] self.channels_to_load = set([chn for chn in self.channels_to_load if not chn in loaded_channels]) LOG.debug("Successfully loaded: "+str(loaded_channels)) if len(self.channels_to_load) > 0: LOG.warning("Unable to import channels " + str(self.channels_to_load)) self.channels_to_load = set()
from mpop import CONFIG_PATH from mpop.channel import Channel, NotLoadedError from mpop.logger import LOG from mpop.utils import OrderedConfigParser try: # Work around for on demand import of pyresample. pyresample depends # on scipy.spatial which memory leaks on multiple imports is_pyresample_loaded = False from pyresample.geometry import AreaDefinition, SwathDefinition import mpop.projector is_pyresample_loaded = True except ImportError: LOG.warning("pyresample missing. Can only work in satellite projection") class Satellite(object): """This is the satellite class. It contains information on the satellite. """ def __init__(self, (satname, number, variant)=(None, None, None)): try: self.satname = satname or "" or self.satname except AttributeError: self.satname = satname or "" try: self.number = number or "" or self.number except AttributeError: self.number = number or ""
import numpy as np from pyresample import image, utils, geometry, kd_tree from mpop import CONFIG_PATH from mpop.logger import LOG CONF = ConfigParser.ConfigParser() CONF.read(os.path.join(CONFIG_PATH, "mpop.cfg")) try: AREA_FILE = os.path.join(CONF.get("projector", "area_directory") or CONFIG_PATH, CONF.get("projector", "area_file")) except ConfigParser.NoSectionError: AREA_FILE = "" LOG.warning("Couldn't find the mpop.cfg file. " "Do you have one ? is it in $PPP_CONFIG_DIR ?") def get_area_def(area_name): """Get the definition of *area_name* from file. The file is defined to use is to be placed in the $PPP_CONFIG_DIR directory, and its name is defined in mpop's configuration file. """ return utils.parse_area_file(AREA_FILE, area_name)[0] class Projector(object): """This class define projector objects. They contain the mapping information necessary for projection purposes. For efficiency reasons, generated projectors can be saved to disk for later reuse. Use the :meth:`save` method for this. To define a projector object, on has to specify *in_area* and *out_area*,