1- import os
21from collections import defaultdict
32from functools import wraps
43from typing import Any , Callable , Optional
76from addict import Dict
87from matplotlib .axes import Axes
98
10- from CADETProcess import CADETProcessError , plotting , settings
9+ from CADETProcess import CADETProcessError , plotting
1110from CADETProcess .dataStructure import String
1211from CADETProcess .dynamicEvents import Event , EventHandler
1312from CADETProcess .fractionation .fractions import Fraction , FractionPool
1413from CADETProcess .performance import Performance
15- from CADETProcess .processModel import ComponentSystem , Process
16- from CADETProcess .simulationResults import SimulationResults
14+ from CADETProcess .processModel import ComponentSystem , ProcessMetaInformation
1715from CADETProcess .solution import SolutionIO , slice_solution
1816
1917__all__ = ["Fractionator" ]
2018
2119
2220class Fractionator (EventHandler ):
2321 """
24- Class for Chromatogram Fractionation .
22+ Class for fractionation of Chromatograms .
2523
2624 This class is responsible for setting events for starting and ending fractionation,
2725 handling multiple chromatograms, and calculating various performance metrics.
@@ -33,6 +31,7 @@ class Fractionator(EventHandler):
3331 performance_keys : list
3432 Keys for performance metrics including mass, concentration, purity, recovery,
3533 productivity, and eluent consumption.
34+
3635 """
3736
3837 name = String (default = "Fractionator" )
@@ -47,9 +46,10 @@ class Fractionator(EventHandler):
4746
4847 def __init__ (
4948 self ,
50- simulation_results : SimulationResults ,
49+ chromatograms : SolutionIO | list [SolutionIO ],
50+ process_meta_information : ProcessMetaInformation ,
5151 components : Optional [list [str ]] = None ,
52- use_total_concentration_components : bool = True ,
52+ use_total_concentration_components : Optional [ bool ] = True ,
5353 * args : Any ,
5454 ** kwargs : Any ,
5555 ) -> None :
@@ -58,83 +58,75 @@ def __init__(
5858
5959 Parameters
6060 ----------
61- simulation_results : SimulationResults
62- Simulation results containing chromatograms.
63- components : list, optional
64- List of components to be fractionated. Default is None.
65- use_total_concentration_components : bool, optional
66- Use total concentration components. Default is True.
61+ chromatograms : SolutionIO | list[SolutionIO]
62+ Chromatograms to be fractionated.
63+ process_meta_information: ProcessMetaInformation
64+ Process meta information.
65+ components : Optional[list[str]]
66+ List of components to be fractionated. If None, all components are
67+ considered. The default is None.
68+ use_total_concentration_components : Optional[bool]
69+ If True, use the total concentration of components, i.e. the sum of all
70+ subspecies of each component. The default is True.
6771 *args
6872 Variable length argument list.
6973 **kwargs
7074 Arbitrary keyword arguments.
71- """
72- self .components : Optional [list [str ]] = components
73- self .use_total_concentration_components : bool = use_total_concentration_components
74- self .simulation_results = simulation_results
75-
76- super ().__init__ (* args , ** kwargs )
7775
78- @property
79- def simulation_results (self ) -> SimulationResults :
80- """SimulationResults: The simulation results containing the chromatograms."""
81- return self ._simulation_results
82-
83- @simulation_results .setter
84- def simulation_results (self , simulation_results : SimulationResults ) -> None :
8576 """
86- Set the simulation results.
77+ if not isinstance (chromatograms , list ):
78+ chromatograms = [chromatograms ]
8779
88- Parameters
89- ----------
90- simulation_results : SimulationResults
91- Simulation results containing chromatograms.
80+ self .process_meta_information = process_meta_information
9281
93- Raises
94- ------
95- TypeError
96- If simulation_results is not of type SimulationResults.
97- CADETProcessError
98- If the simulation results do not contain any chromatograms.
99- """
100- if not isinstance (simulation_results , SimulationResults ):
101- raise TypeError ("Expected SimulationResults" )
82+ for chrom in chromatograms :
83+ if chrom .component_system is not self .component_system :
84+ raise CADETProcessError ("Component systems do not match." )
10285
103- if len (simulation_results .chromatograms ) == 0 :
104- raise CADETProcessError ("Simulation results do not contain chromatogram" )
86+ component_system = chromatograms [0 ].component_system
10587
106- self ._simulation_results = simulation_results
88+ if components is not None :
89+ for comp in components :
90+ if comp not in component_system :
91+ raise CADETProcessError (
92+ f"Could not find component { comp } in component system."
93+ )
94+
95+ self .components = components
96+ self .use_total_concentration_components = use_total_concentration_components
10797
10898 self ._chromatograms = [
10999 slice_solution (
110100 chrom ,
111101 components = self .components ,
112102 use_total_concentration_components = self .use_total_concentration_components ,
113103 )
114- for chrom in simulation_results . chromatograms
104+ for chrom in chromatograms
115105 ]
116106
117107 m_feed = np .zeros ((self .component_system .n_comp ,))
118108 counter = 0
119- for comp , indices in simulation_results .component_system .indices .items ():
109+ for comp , indices in self .component_system .indices .items ():
120110 if comp in self .component_system .names :
121- m_feed_comp = simulation_results . process .m_feed [indices ]
111+ m_feed_comp = process_meta_information .m_feed [indices ]
122112 if self .use_total_concentration_components :
123113 m_feed [counter ] = np .sum (m_feed_comp )
124114 counter += 1
125115 else :
126116 n_species = len (indices )
127117 m_feed [counter : counter + n_species ] = m_feed_comp
128118 counter += n_species
129- self .m_feed : np . ndarray = m_feed
119+ self .m_feed = m_feed
130120
131121 self ._fractionation_states = Dict ({chrom : [] for chrom in self .chromatograms })
132122 self ._chromatogram_events = Dict ({chrom : [] for chrom in self .chromatograms })
133123
134- self ._cycle_time = self .process .cycle_time
124+ self ._cycle_time = self .process_meta_information .cycle_time
135125
136126 self .reset ()
137127
128+ super ().__init__ (* args , ** kwargs )
129+
138130 @property
139131 def component_system (self ) -> ComponentSystem :
140132 """ComponentSystem: The component system of the chromatograms."""
@@ -196,13 +188,23 @@ def chromatogram_events(self) -> dict[SolutionIO, list[Event]]:
196188 return chrom_events
197189
198190 @property
199- def process (self ) -> Process :
200- """Process: The process from the simulation results."""
201- return self .simulation_results .process
191+ def process_meta_information (self ) -> ProcessMetaInformation :
192+ """Process: from the simulation results."""
193+ return self ._process_meta_information
194+
195+ @process_meta_information .setter
196+ def process_meta_information (
197+ self ,
198+ process_meta_information : ProcessMetaInformation
199+ ) -> None :
200+ if not isinstance (process_meta_information , ProcessMetaInformation ):
201+ raise TypeError ("Expected ProcessMetaInformation." )
202+
203+ self ._process_meta_information = process_meta_information
202204
203205 @property
204206 def n_comp (self ) -> int :
205- """int: Number of components to be fractionized ."""
207+ """int: Number of components to be fractionated ."""
206208 return self .chromatograms [0 ].n_comp
207209
208210 @property
@@ -745,41 +747,6 @@ def section_dependent_parameters(self) -> Dict:
745747 """dict: Section dependent parameters of the fractionator."""
746748 return self .parameters
747749
748- def save (
749- self ,
750- case_dir : str ,
751- start : float = 0 ,
752- end : Optional [float ] = None ,
753- ) -> None :
754- """
755- Save chromatogram and purity plots to a specified directory.
756-
757- Parameters
758- ----------
759- case_dir : str
760- Directory name within the working directory to save plots.
761- start : float, optional
762- Start time for plotting purity, default is 0.
763- end : Optional[float]
764- End time for plotting purity. If None, includes all data.
765- """
766- path = os .path .join (settings .working_directory , case_dir )
767-
768- for index , chrom in enumerate (self .chromatograms ):
769- chrom .plot (save_path = path + f"/chrom_{ index } .png" )
770- chrom .plot_purity (
771- start = start , end = end , save_path = path + "/chrom_purity.png"
772- )
773-
774- for chrom in enumerate (self .chromatograms ):
775- self .plot_fraction_signal (
776- chromatogram = chrom ,
777- start = start ,
778- end = end ,
779- save_path = path + f"/fractionation_signal_{ index } .png" ,
780- index = index ,
781- )
782-
783750 def __str__ (self ) -> str :
784751 """str: String representation of the fractionator."""
785752 return self .__class__ .__name__
0 commit comments