Esempio n. 1
0
    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
Esempio n. 2
0
 def save(self, resave=False):
     """Save the precomputation to disk, and overwrite existing file in case
     *resave* is true.
     """
     if (not os.path.exists(self._filename)) or resave:
         LOG.info("Saving projection to " +
                  self._filename)
         np.savez(self._filename, **self._cache)
Esempio n. 3
0
    def _set_reader(self, pformat):
        """Gets the reader for *pformat* format, and puts it in the `reader`
        attribute.
        """
       
        elements = pformat.split(".")
        if len(elements) == 1:
            reader_module = pformat
            reader = "mpop.satin."+reader_module

            # Loading old style plugins
            reader_module = pformat
            LOG.info("old style plugin: " + pformat)
            try:
                # Look for builtin reader
                loader = __import__(reader, globals(),
                                    locals(), ['load'])
            except ImportError:
                # Look for custom reader
                loader = __import__(reader_module, globals(),
                                    locals(), ['load'])

            # Build a custom Reader plugin on the fly...
            from mpop.plugin_base import Reader
            reader_class = type(elements[-1].capitalize() + "Reader",
                                (Reader,),
                                {"pformat": elements[-1]})

            reader_instance = reader_class(self)

            # ... and set its "load" attribute with the "load" function of the
            # loader module
            loader = getattr(loader, "load")
            setattr(reader_instance, "load", loader)

            setattr(self, elements[-1] + "_reader", reader_instance)


        else:
            reader_module = ".".join(elements[:-1])
            reader_class = elements[-1]
        
            reader = "mpop.satin."+reader_module
            try:
                # Look for builtin reader
                loader = __import__(reader, globals(),
                                    locals(), [reader_class])
            except ImportError:
                # Look for custom reader
                loader = __import__(reader_module, globals(),
                                    locals(), [reader_class])
            loader = getattr(loader, reader_class)
            reader_instance = loader(self)
            setattr(self, loader.pformat + "_reader", reader_instance)

        return reader_instance
Esempio n. 4
0
File: scene.py Progetto: 3Geo/mpop
 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))
Esempio n. 5
0
File: channel.py Progetto: 3Geo/mpop
    def project(self, coverage_instance):
        """Make a projected copy of the current channel using the given
        *coverage_instance*.

        See also the :mod:`mpop.projector` module.
        """
        res = copy.copy(self)
        res.area = coverage_instance.out_area
        res.data = None
        if self.is_loaded():
            LOG.info("Projecting channel %s (%fμm)..."
                     %(self.name, self.wavelength_range[1]))
            data = coverage_instance.project_array(self._data)
            res.data = data
            return res
        else:
            raise NotLoadedError("Can't project, channel %s (%fμm) not loaded."
                                 %(self.name, self.wavelength_range[1]))
Esempio n. 6
0
File: scene.py Progetto: 3Geo/mpop
    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
Esempio n. 7
0
File: scene.py Progetto: 3Geo/mpop
    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()
Esempio n. 8
0
File: scene.py Progetto: 3Geo/mpop
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 ""
Esempio n. 9
0
    def __init__(self, in_area, out_area,
                 in_latlons=None, mode=None,
                 radius=10000):

        # TODO:
        # - Rework so that in_area and out_area can be lonlats.
        # - Add a recompute flag ?

        # Setting up the input area
        try:
            self.in_area = get_area_def(in_area)
            in_id = in_area
        except (utils.AreaNotFound, AttributeError):
            if isinstance(in_area, geometry.AreaDefinition):
                self.in_area = in_area
                in_id = in_area.area_id
            elif isinstance(in_area, geometry.SwathDefinition):
                self.in_area = in_area
                in_id = in_area.area_id
            elif in_latlons is not None:
                self.in_area = geometry.SwathDefinition(lons=in_latlons[0],
                                                        lats=in_latlons[1])
                in_id = in_area
            else:
                raise utils.AreaNotFound("Input area " +
                                         str(in_area) +
                                         " must be defined in " +
                                         AREA_FILE + ", be an area object"
                                         " or longitudes/latitudes must be "
                                         "provided.")


        # Setting up the output area
        try:
            self.out_area = get_area_def(out_area)
            out_id = out_area
        except (utils.AreaNotFound, AttributeError):
            if isinstance(out_area, (geometry.AreaDefinition,
                                     geometry.SwathDefinition)):
                self.out_area = out_area
                out_id = out_area.area_id
            else:
                raise utils.AreaNotFound("Output area " +
                                         str(out_area) +
                                         " must be defined in " +
                                         AREA_FILE + " or "
                                         "be an area object.")

        if self.in_area == self.out_area:
            return

        # choosing the right mode if necessary
        if(mode is None):
            if (isinstance(in_area, geometry.AreaDefinition) and
                isinstance(out_area, geometry.AreaDefinition)):
                self.mode = "quick"
            else:
                self.mode = "nearest"
        else:
            self.mode = mode



        filename = (in_id + "2" + out_id + "_" + self.mode + ".npz")

        projections_directory = "/var/tmp"
        try:
            projections_directory = CONF.get("projector",
                                             "projections_directory")
        except ConfigParser.NoSectionError:
            pass
        
        self._filename = os.path.join(projections_directory, filename)

        if(not os.path.exists(self._filename)):
            LOG.info("Computing projection from %s to %s..."
                     %(in_id, out_id))


            if self.mode == "nearest":
                valid_index, valid_output_index, index_array, distance_array = \
                             kd_tree.get_neighbour_info(self.in_area,
                                                        self.out_area,
                                                        radius,
                                                        neighbours=1)
                del distance_array
                self._cache = {}
                self._cache['valid_index'] = valid_index
                self._cache['valid_output_index'] = valid_output_index
                self._cache['index_array'] = index_array

            elif self.mode == "quick":
                ridx, cidx = \
                      utils.generate_quick_linesample_arrays(self.in_area,
                                                             self.out_area)
                                                    
                self._cache = {}
                self._cache['row_idx'] = ridx
                self._cache['col_idx'] = cidx

            else:
                raise ValueError("Unrecognised mode " + str(self.mode) + ".") 
            
        else:
            self._cache = {}
            self._file_cache = np.load(self._filename)
Esempio n. 10
0
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*,
Esempio n. 11
0
File: sarx.py Progetto: Pelgrum/mpop
    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')