Source code for darsia.manager.traceranalysis

"""Module providing structures for tracer analysis.

The resulting class is abstract and needs to be tailored to the specific situation by
inheritance.
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from pathlib import Path
from typing import Union

import darsia


[docs] class TracerAnalysis(ABC, darsia.ConcentrationAnalysisBase): def __init__( self, baseline: Union[str, Path, list[str], list[Path]], config: Union[str, Path], update_setup: bool = False, ) -> None: """ Constructor for TracerAnalysis. Args: baseline (str, Path or list of such): see darsia.AnalysisBase. config_source (str or Path): see darsia.AnalysisBase. update_setup (bool): see darsia.AnalysisBase. """ # Call constructor of AnalysisBase super().__init__(baseline, config, update_setup) # Define tracer analysis. if "tracer" in self.config.keys(): self.tracer_analysis = self.define_tracer_analysis() # Safety check if not isinstance(self.tracer_analysis, darsia.ConcentrationAnalysis): raise ValueError("tracer_analysis has wrong type.") # Setup standard data including the cleaning filter tracer_config = self.config.get("tracer", {}) tracer_cleaning_filter = tracer_config.get( "cleaning_filter", "cache/cleaning_filter_tracer.npy" ) self._setup_concentration_analysis( self.tracer_analysis, tracer_cleaning_filter, baseline, update_setup, ) else: raise ValueError("Tracer analysis not well defined.")
[docs] @abstractmethod def define_tracer_analysis(self) -> darsia.ConcentrationAnalysis: """ The main purpose of this routine is to define self.tracer_analysis, which lies at the heart of this class. It is supposed to determine tracers from image differences. Since the choice of a suitable color channel etc. may heavily depend on the situation, this method is abstract and has to be overwritten in each specific situation. """ pass
[docs] def determine_tracer( self, return_volume: bool = False ) -> Union[darsia.Image, tuple[darsia.Image, float]]: """Extract tracer from currently loaded image, based on a reference image. Args: return_volume (bool): flag controlling whether the volume of the fluid in the porous geometry is returned. Returns: darsia.Image: image array of spatial concentration map float, optional: occupied volume by the fluid in porous geometry """ # Make a copy of the current image img = self.img.copy() # Extract tracer map - includes rescaling tracer = self.tracer_analysis(img) # Integrate concentration over porous domain and/or return concentration if return_volume: volume = self.geometry.integrate(tracer.img) return tracer, volume else: return tracer