Spectra
def Spectra(
wavenumbers:numpy.ndarray, spectra:numpy.ndarray, measurement_type:str, sample_ids:numpy.ndarray,
source:object=None
)->None:Spectra of several samples, measured at the same wavenumbers
Spectra of several samples, measured at the same wavenumbers
@dataclass
class Spectra:
"Spectra of several samples, measured at the same wavenumbers"
wavenumbers:np.ndarray # Wavenumbers in cm⁻¹, in increasing order
spectra:np.ndarray # One row per sample, one column per wavenumber
measurement_type:str # `abs` (absorbance) or `ref` (reflectance)
sample_ids:np.ndarray # Sample ID of each row of `spectra`
source:object=field(default=None, repr=False, compare=False) # Object holding the sample properties, such as an `OSSL`
def __str__(self):
'Pretty print the Spectra object'
sections = [
("Spectra attributes", f"Available attributes: {', '.join(f.name for f in fields(self) if f.repr)}"),
("Wavenumbers",
f"{np.array2string(self.wavenumbers[:10], precision=2, separator=', ')}\n"
f"Shape: {self.wavenumbers.shape}"),
("Spectra",
f"{np.array2string(self.spectra[:5,:5], precision=4, separator=', ')}\n"
f"Shape: {self.spectra.shape}"),
("Measurement type (Reflectance or Absorbance)", self.measurement_type),
("Sample IDs",
f"{np.array2string(self.sample_ids[:10], separator=', ')}\n"
f"Total samples: {len(self.sample_ids)}")]
return '\n\n'.join(f"{title}:\n{'-'*len(title)}\n{content}"
for title, content in sections)OSSL.mir, OSSL.visnir and load_spa return a Spectra. Row i of spectra is the spectrum of sample sample_ids[i], measured at wavenumbers. Printing a Spectra shows the start of each field and its shape. Two MIR spectra at three wavenumbers:
Spectra attributes:
------------------
Available attributes: wavenumbers, spectra, measurement_type, sample_ids
Wavenumbers:
-----------
[600, 602, 604]
Shape: (3,)
Spectra:
-------
[[0.11, 0.12, 0.13],
[0.21, 0.22, 0.23]]
Shape: (2, 3)
Measurement type (Reflectance or Absorbance):
--------------------------------------------
abs
Sample IDs:
----------
['s1', 's2']
Total samples: 2
Spectra and targets of the samples that have both, for machine learning
@patch
def xy(
self:Spectra,
target_cols:Union[str, List] # Target column name or names
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: # Spectra, targets and sample IDs, row by row
"Spectra and targets of the samples that have both, for machine learning"
targets = self.source[listify(target_cols)].dropna()
aligned = pd.DataFrame(self.spectra, index=self.sample_ids).join(targets, how='inner')
n = self.spectra.shape[1]
return aligned.iloc[:, :n].to_numpy(copy=True), aligned.iloc[:, n:].to_numpy(copy=True), aligned.index.to_numpy()xy reads the targets from source, which returns a DataFrame indexed by sample ID when indexed with a list of column names. An OSSL and a pd.DataFrame both work. xy keeps the samples that have a value for every target. It returns the spectra X, the targets y and the sample IDs ids, in the same row order. Sample s2 has no clay value: