Source code for cana.composition.mixtures

r"""Mixtures used in the Shkuratov model."""

import copy
import numpy as np

from .shkuratov import Shkuratov
from .. import interp_spec


[docs]def create_inclusion(constant1, constant2, concentration): r""" """ #interpolating second constant constant2_ = constant2.rebase(constant1.w) ime = (constant1.k * constant2_.n) - (constant1.n * constant2_.k) / \ (constant2_.n**2 + constant2_.k**2) # ime = ka = 1.5 * concentration * constant1.n * ime constant1_ = constant1.copy() constant1_.k += ka return constant1_
[docs]class IntimateMixture(object): r"""Mixture of samples.""" def __init__(self, samples, grainsizes=[30,50], proportions=[0.5, 0.5], porosity=0.5, model='shkuratov'): r"""Initialize the Initimate Mixture class. Parameters ---------- samples: list List containing the optical constants Sample proportions: list List of proportions in the same order of the samples List porosity: float The value for porosity model: string The name of the reflectance model to be used """ self.modelname = model.capitalize() self.samples = samples self.proportions = proportions self.porosity = porosity self.samples_ids = ','.join([sam.label for sam in self.samples]) self.grainsizes = grainsizes self.model = self.select_model() def __str__(self): r"""Representation of the IntimateMixture class.""" grains = ','.join([str(g) for g in self.grainsizes]) prop = ','.join([str(p) for p in self.proportions]) return '''IntimateMixture(samples:({0}), grainsizes:({1}), proportions=({2}), porosity:{3})'''.format(self.samples_ids, grains, prop, self.porosity) def __repr__(self): r"""Representation of the IntimateMixture class.""" return self.__str__()
[docs] def copy(self): r"""Return a copy of the object.""" return copy.copy(self)
[docs] def select_model(self): r"""Select the reflectance model that will be used.""" if self.modelname == 'Shkuratov': model = Shkuratov return model
[docs] def make(self, albedo_w=0.55, wavelengths=None, datatype=None): r"""Make the reflectance spectrum of the mixture. Parameters ---------- rebase: boolean True if you want to rebase the wavelength axis of the samples. If False, the provided samples should have equal wavelentghs. interpmethod: Method that will be used to rebase the samples. Default is 'interpolate'. baseaxis: None or array The wavelength array that will be used if rebase=True. If baseaxis=None and rebase=True, it will select the wavelength of the first sample as a reference. Not used if rebase=False. """ if wavelengths is None: wavelengths = self.samples[0].w # building coef structure coef = np.zeros(len(wavelengths), dtype=[('b', np.float64), ('f', np.float64)]) # calculating coeficients for s, sam in enumerate(self.samples): # no need to calculate coeficients if proportion is zero if self.proportions[s] != 0.: # print(sam,self.proportions[s],self.grainsizes[s]) sam = sam.rebase(baseaxis=wavelengths) model = self.model(sample=sam, grainsize=self.grainsizes[s], porosity=self.porosity) coef_aux = model.scattering_coef() # print(coef_aux) # summing coeficients coef['b'] += coef_aux['b']*self.proportions[s] coef['f'] += coef_aux['f']*self.proportions[s] spec, albedo = model.build_spec(coef=coef, albedo_w=albedo_w) spec = interp_spec(spec, baseaxis=wavelengths, datatype=datatype) return spec, albedo