Exemple #1
0
    def __init__(self, config):

        self.statevec = []
        self.bounds = s.array([])
        self.scale = s.array([])
        self.init = s.array([])
        self.bvec = []
        self.bval = s.array([])
        self.emissive = False
        self.reconfigure(config)
        if 'reflectance_file' in config:
            self.rfl, self.wl = load_spectrum(config['reflectance_file'])
            self.n_wl = len(self.wl)
        elif 'wavelength_file' in config:
            self.wl, self.fwhm = load_wavelen(config['wavelength_file'])
            self.n_wl = len(self.wl)
Exemple #2
0
    def __init__(self,
                 fname,
                 write=False,
                 n_rows=None,
                 n_cols=None,
                 n_bands=None,
                 interleave=None,
                 dtype=s.float32,
                 wavelengths=None,
                 fwhm=None,
                 band_names=None,
                 bad_bands=[],
                 zrange='{0.0, 1.0}',
                 ztitles='{Wavelength (nm), Magnitude}',
                 map_info='{}'):

        self.frames = OrderedDict()
        self.write = write
        self.fname = fname
        self.wl = wavelengths
        self.band_names = band_names
        self.fwhm = fwhm
        self.n_rows = n_rows
        self.n_cols = n_cols
        self.n_bands = n_bands

        if self.fname.endswith('.txt'):

            # The .txt suffix implies a space-separated ASCII text file of
            # one or more data columns.  This is cheap to load and store, so
            # we do not defer read/write operations.
            logging.debug('Inferred ASCII file format for %s' % self.fname)
            self.format = 'ASCII'
            if not self.write:
                self.data, self.wl = load_spectrum(self.fname)
                self.n_rows, self.n_cols, self.map_info = 1, 1, '{}'
                if self.wl is not None:
                    self.n_bands = len(self.wl)
                else:
                    self.n_bands = None
                self.meta = {}

        elif self.fname.endswith('.mat'):

            # The .mat suffix implies a matlab-style file, i.e. a dictionary
            # of 2D arrays and other matlab-like objects. This is typically
            # only used for specific output products associated with single
            # spectrum retrievals; there is no read option.
            logging.debug('Inferred MATLAB file format for %s' % self.fname)
            self.format = 'MATLAB'
            if not self.write:
                logging.error('Unsupported MATLAB file in input block')
                raise IOError('MATLAB format in input block not supported')

        else:

            # Otherwise we assume it is an ENVI-format file, which is
            # basically just a binary data cube with a detached human-
            # readable ASCII header describing dimensions, interleave, and
            # metadata.  We buffer this data in self.frames, reading and
            # writing individual rows of the cube on-demand.
            logging.debug('Inferred ENVI file format for %s' % self.fname)
            self.format = 'ENVI'

            if not self.write:

                # If we are an input file, the header must preexist.
                if not os.path.exists(self.fname + '.hdr'):
                    logging.error('Could not find %s' % (self.fname + '.hdr'))
                    raise IOError('Could not find %s' % (self.fname + '.hdr'))

                # open file and copy metadata, checking interleave format
                self.file = envi.open(self.fname + '.hdr', fname)
                self.meta = self.file.metadata.copy()
                if self.meta['interleave'] not in ['bil', 'bip']:
                    logging.error('Unsupported interleave format.')
                    raise IOError('Unsupported interleave format.')

                self.n_rows = int(self.meta['lines'])
                self.n_cols = int(self.meta['samples'])
                self.n_bands = int(self.meta['bands'])

            else:

                # If we are an output file, we may have to build the header
                # from scratch.  Hopefully the caller has supplied the
                # necessary metadata details.
                meta = {
                    'lines': n_rows,
                    'samples': n_cols,
                    'bands': n_bands,
                    'byte order': 0,
                    'header offset': 0,
                    'map info': map_info,
                    'file_type': 'ENVI Standard',
                    'sensor type': 'unknown',
                    'interleave': interleave,
                    'data type': typemap[dtype],
                    'wavelength units': 'nm',
                    'z plot range': zrange,
                    'z plot titles': ztitles,
                    'fwhm': fwhm,
                    'bbl': bad_bands,
                    'band names': band_names,
                    'wavelength': self.wl
                }
                for k, v in meta.items():
                    if v is None:
                        logging.error('Must specify %s' % (k))
                        raise IOError('Must specify %s' % (k))

                self.file = envi.create_image(fname + '.hdr',
                                              meta,
                                              ext='',
                                              force=True)

            self.open_map_with_retries()
Exemple #3
0
    def __init__(self, config, forward, inverse, active_rows, active_cols):
        """Initialization specifies retrieval subwindows for calculating
        measurement cost distributions"""

        # Default IO configuration options
        self.input = {}
        self.output = {'plot_surface_components': False}

        self.iv = inverse
        self.fm = forward
        self.bbl = '[]'
        self.radiance_correction = None
        self.meas_wl = forward.instrument.wl_init
        self.meas_fwhm = forward.instrument.fwhm_init
        self.writes = 0
        self.n_rows = 1
        self.n_cols = 1
        self.n_sv = len(self.fm.statevec)
        self.n_chan = len(self.fm.instrument.wl_init)

        if 'input' in config:
            self.input.update(config['input'])
        if 'output' in config:
            self.output.update(config['output'])
        if 'logging' in config:
            logging.config.dictConfig(config)

        # A list of all possible input data sources
        self.possible_inputs = [
            "measured_radiance_file", "reference_reflectance_file",
            "reflectance_file", "obs_file", "glt_file", "loc_file",
            "surface_prior_mean_file", "surface_prior_variance_file",
            "rt_prior_mean_file", "rt_prior_variance_file",
            "instrument_prior_mean_file", "instrument_prior_variance_file",
            "radiometry_correction_file"
        ]

        # A list of all possible outputs.  There are several special cases
        # that we handle differently - the "plot_directory", "summary_file",
        # "Data dump file", etc.
        wl_names = [('Channel %i' % i) for i in range(self.n_chan)]
        sv_names = self.fm.statevec.copy()
        self.output_info = {
            "estimated_state_file": (sv_names, '{State Parameter, Value}',
                                     '{}'),
            "estimated_reflectance_file":
            (wl_names, '{Wavelength (nm), Lambertian Reflectance}',
             '{0.0,1.0}'),
            "estimated_emission_file":
            (wl_names,
             '{Wavelength (nm), Emitted Radiance (uW nm-1 cm-2 sr-1)}', '{}'),
            "modeled_radiance_file":
            (wl_names,
             '{Wavelength (nm), Modeled Radiance (uW nm-1 cm-2 sr-1)}', '{}'),
            "apparent_reflectance_file":
            (wl_names, '{Wavelength (nm), Apparent Surface Reflectance}',
             '{}'),
            "path_radiance_file":
            (wl_names, '{Wavelength (nm), Path Radiance (uW nm-1 cm-2 sr-1)}',
             '{}'),
            "simulated_measurement_file":
            (wl_names,
             '{Wavelength (nm), Simulated Radiance (uW nm-1 cm-2 sr-1)}',
             '{}'),
            "algebraic_inverse_file":
            (wl_names, '{Wavelength (nm), Apparent Surface Reflectance}',
             '{}'),
            "atmospheric_coefficients_file":
            (wl_names, '{Wavelength (nm), Atmospheric Optical Parameters}',
             '{}'),
            "radiometry_correction_file":
            (wl_names, '{Wavelength (nm), Radiometric Correction Factors}',
             '{}'),
            "spectral_calibration_file": (wl_names, '{}', '{}'),
            "posterior_uncertainty_file": (sv_names,
                                           '{State Parameter, Value}', '{}')
        }

        self.defined_outputs, self.defined_inputs = {}, {}
        self.infiles, self.outfiles, self.map_info = {}, {}, '{}'

        # Load input files and record relevant metadata
        for q in self.input:
            if q in self.possible_inputs:
                self.infiles[q] = SpectrumFile(self.input[q])

                if (self.infiles[q].n_rows > self.n_rows) or \
                   (self.infiles[q].n_cols > self.n_cols):
                    self.n_rows = self.infiles[q].n_rows
                    self.n_cols = self.infiles[q].n_cols

                for inherit in ['map info', 'bbl']:
                    if inherit in self.infiles[q].meta:
                        setattr(self, inherit.replace(' ', '_'),
                                self.infiles[q].meta[inherit])

        for q in self.output:
            if q in self.output_info:
                band_names, ztitle, zrange = self.output_info[q]
                n_bands = len(band_names)
                self.outfiles[q] = SpectrumFile(self.output[q],
                                                write=True,
                                                n_rows=self.n_rows,
                                                n_cols=self.n_cols,
                                                n_bands=n_bands,
                                                interleave='bip',
                                                dtype=s.float32,
                                                wavelengths=self.meas_wl,
                                                fwhm=self.meas_fwhm,
                                                band_names=band_names,
                                                bad_bands=self.bbl,
                                                map_info=self.map_info,
                                                zrange=zrange,
                                                ztitles=ztitle)

        # Do we apply a radiance correction?
        if 'radiometry_correction_file' in self.input:
            filename = self.input['radiometry_correction_file']
            self.radiance_correction, wl = load_spectrum(filename)

        # Last thing is to define the active image area
        if active_rows is None:
            active_rows = s.arange(self.n_rows)
        if active_cols is None:
            active_cols = s.arange(self.n_cols)
        self.iter_inds = []
        for row in active_rows:
            for col in active_cols:
                self.iter_inds.append([row, col])
        self.iter_inds = s.array(self.iter_inds)