class SimConfExportVisual(YamlABC): ''' **Visual export subconfiguration** (i.e., YAML-backed wrapper exposing settings globally applicable to all visual exports). Attributes (Cell: Indices) ---------- is_show_cell_indices : bool ``True`` only if the 0-based indices of all cells are to be displayed over all cell cluster visuals (e.g., as integers situated at cell centres). single_cell_index : int 0-based index of the cell to be visualized for all single cell visuals. Defaults to 0, the index assigned to the first cell guaranteed to exist. Note that cell indices are seed-specific and may be visualized by enabling the :attr:`is_show_cell_indices` boolean. ''' # ..................{ ALIASES ~ cell : index }.................. is_show_cell_indices = yaml_alias( "['results options']['visuals']['cell indices']['show']", bool) #FIXME, Consider generalizing this into a list. single_cell_index = yaml_alias( "['results options']['visuals']['cell indices']['single cell']", int)
class SimConfExportCSVs(YamlABC): ''' YAML-backed subconfiguration for exporting *all* comma-separated value (CSV) files enabled by the current YAML-formatted simulation configuration file. Attributes (After Solving) ---------- is_after_sim_save : bool ``True`` only if this configuration saves post-simulation CSV files. anims_after_sim : YamlList YAML-backed list of all post-simulation CSV files to be animated. Ignored if :attr:`is_after_sim_save` is ``False``. Attributes (Save) ---------- csv_filetype : str Filetype of all CSV files saved by this configuration. Ignored if :attr:`is_after_sim_save` is ``False``. ''' # ..................{ ALIASES ~ after }.................. is_after_sim_save = yaml_alias( "['results options']['after solving']['csvs']['save']", bool) # ..................{ ALIASES ~ save }.................. filetype = yaml_alias("['results options']['save']['csvs']['filetype']", str) # ..................{ INITIALIZERS }.................. def __init__(self, *args, **kwargs) -> None: # Initialize our superclass with all passed parameters. super().__init__(*args, **kwargs) # Encapsulate low-level lists of dictionaries with high-level wrappers. self.csvs_after_sim = SimConfExportCSV.make_list() # ..................{ LOADERS }.................. def load(self, *args, **kwargs) -> None: # Load our superclass with all passed arguments. super().load(*args, **kwargs) # Load all subconfigurations of this configuration. self.csvs_after_sim.load(conf=self._conf['results options'] ['after solving']['csvs']['pipeline']) def unload(self) -> None: # Unload our superclass. super().unload() # Unload all subconfigurations of this configuration. self.csvs_after_sim.unload()
class SimConfVisualCellsYAMLMixin(SimConfVisualCellsABC): ''' Mixin of all **YAML-backed cell cluster visual subconfiguration** (i.e., configuration of a single visual export parsed from the current YAML-formatted simulation configuration file) subclasses. ''' # ..................{ ALIASES ~ colorbar }.................. is_color_autoscaled = yaml_alias("['colorbar']['autoscale']", bool) color_min = yaml_alias("['colorbar']['minimum']", NumericSimpleTypes) color_max = yaml_alias("['colorbar']['maximum']", NumericSimpleTypes)
class SimConfVisualCellsYAMLMixin(SimConfVisualCellsABC): ''' Abstract mixin generalizing implementation common to all YAML-backed cell cluster visual subconfiguration subclasses. This mixin encapsulates configuration of a single visual (either in- or post-simulation plot or animation) parsed from the current YAML-formatted simulation configuration file. For generality, this mixin provides no support for a YAML ``type`` key or corresponding :attr:`name` property. ''' # ..................{ ALIASES ~ colorbar }.................. is_color_autoscaled = yaml_alias("['colorbar']['autoscale']", bool) color_min = yaml_alias("['colorbar']['minimum']", NumericSimpleTypes) color_max = yaml_alias("['colorbar']['maximum']", NumericSimpleTypes)
class SimConfCutListItem(YamlNamedMixin, YamlListItemABC): ''' YAML-backed cut profile list item subconfiguration, encapsulating the configuration of a single cut profile parsed from a list of these profiles in the current YAML-formatted simulation configuration file. Attributes ---------- picker_image_filename : str Absolute or relative filename of the image mask whose pure-black pixels define the region of the cell cluster whose cells are all to be removed by this cut profile. See the :attr:`SimConfTissueListItem.picker_image_filename` variable for details. ''' # ..................{ ALIASES }.................. picker_image_filename = yaml_alias("['image']", str) # ..................{ SUPERCLASS }.................. @classmethod @type_check def make_default(cls, yaml_list: YamlList) -> YamlListItemABC: # Duplicate the first tissue profile in our default configuration file. return cls._make_loaded( conf={ 'name': yaml_list.get_item_name_uniquified('Cut ({})'), 'image': 'geo/circle/wedge.png', })
class YamlBooledMixin(object): ''' Mixin of all **YAML-backed booled configuration** (i.e., backed by a YAML dictionary with top-level key ``enabled`` whose value is a boolean specifying whether this configuration is enabled or disabled) subclasses. This class is suitable for use as a multiple-inheritance mixin. To preserve the expected method resolution order (MRO) semantics, this class should typically be inherited *first* rather than *last* in subclasses. Attributes ---------- is_enabled : bool ``True`` only if this list item is enabled. ''' # ..................{ ALIASES }.................. is_enabled = yaml_alias("['enabled']", bool)
class SimConfPhase(YamlABC): ''' YAML-backed simulation phase subconfiguration, encapsulating the configuration of a single phase (e.g., seed, initialization, simulation) parsed from the current YAML-formatted simulation configuration file. Attributes (Path) ---------- . : . . Attributes (Time) ---------- . : . . ''' # ..................{ ALIASES ~ wut }.................. wut = yaml_alias("['wut']['wut']", int)
class SimConfTissueDefault(SimConfTissueABC, YamlABC): ''' YAML-backed **default tissue profile** (i.e., profile applied to all cells *not* already targeted by another tissue profile) subconfiguration, encapsulating the configuration of a single tissue profile unconditionally applicable to all cells parsed from a dictionary configuring at least this profile in the current YAML-formatted simulation configuration file. Attributes (Cell Picker) ---------- picker_image_filename : str Absolute or relative filename of the image mask whose pure-black pixels define the shape of the cell cluster to be populated with cells. See the :attr:`SimConfTissueListItem.picker_image_filename` variable for details. ''' # ..................{ ALIASES ~ picker }.................. picker_image_filename = yaml_alias("['image']", str)
class YamlNamedMixin(object): ''' Mixin of all **YAML-backed named configuration** (i.e., backed by a YAML dictionary with top-level key ``name`` whose value is a human- and/or machine-readable string identifying this configuration's presumably unique name) subclasses. This class is suitable for use as a multiple-inheritance mixin. To preserve the expected method resolution order (MRO) semantics, this class should typically be inherited *first* rather than *last* in subclasses. Attributes ---------- name : str Arbitrary string typically uniquely identifying this configuration (e.g., ``spot``, naming a spatially isolated tissue profile). ''' # ..................{ ALIASES }.................. name = yaml_alias("['name']", str)
class YamlTypedMixin(object): ''' Mixin of all **YAML-backed typed configuration** (i.e., backed by a YAML dictionary with top-level key ``type`` whose value is a machine-readable string identifying this configuration's type) subclasses. This class is suitable for use as a multiple-inheritance mixin. To preserve the expected method resolution order (MRO) semantics, this class should typically be inherited *first* rather than *last* in subclasses. Attributes ---------- kind : str Lowercase alphanumeric string uniquely identifying the type of this configuration (e.g., ``voltage_membrane``, identifying a transmembrane voltage). See each ``type`` key of the corresponding list in the default simulation configuration file for real-world examples. ''' # ..................{ ALIASES }.................. kind = yaml_alias("['type']", str)
class SimConfPlotAll(YamlABC): ''' YAML-backed subconfiguration for exporting *all* plots (both in- and post-simulation) enabled by the current YAML-formatted simulation configuration file. This subconfiguration saves (i.e., writes, serializes) in-memory plots to on-disk cache, image, and/or video files configured by this configuration. Attributes (After Solving) ---------- is_after_sim : bool ``True`` only if this configuration displays and/or saves post-simulation plots. is_after_sim_show : bool ``True`` only if this configuration displays post-simulation plots. is_after_sim_save : bool ``True`` only if this configuration saves post-simulation plots. Attributes (After Solving: Single-cell) ---------- plots_cell_after_sim : YamlList YAML-backed list of all post-simulation single-cell plots to be animated. Ignored if :attr:``is_after_sim`` is ``False``. plots_cells_after_sim : YamlList YAML-backed list of all post-simulation cell cluster plots to be animated. Ignored if :attr:``is_after_sim`` is ``False``. Attributes (Image) ---------- image_filetype : str Filetype of all image files saved by this configuration. Ignored if :attr:`is_after_sim_save` is ``False``. image_dpi : int Dots per inch (DPI) of all image files saved by this configuration. Ignored if :attr:`is_after_sim_save` is ``False``. ''' # ..................{ ALIASES ~ after }.................. is_after_sim_save = yaml_alias( "['results options']['after solving']['plots']['save']", bool) is_after_sim_show = yaml_alias( "['results options']['after solving']['plots']['show']", bool) # ..................{ ALIASES ~ save }.................. image_filetype = yaml_alias( "['results options']['save']['plots']['filetype']", str) image_dpi = yaml_alias_int_positive( "['results options']['save']['plots']['dpi']") # ..................{ INITIALIZERS }.................. def __init__(self, *args, **kwargs) -> None: # Initialize our superclass with all passed parameters. super().__init__(*args, **kwargs) # Encapsulate low-level lists of dictionaries with high-level wrappers. self.plots_cell_after_sim = SimConfVisualCellListItem.make_list() self.plots_cells_after_sim = SimConfVisualCellsListItem.make_list() # ..................{ LOADERS }.................. def load(self, *args, **kwargs) -> None: # Load our superclass with all passed arguments. super().load(*args, **kwargs) # Load all subconfigurations of this configuration. self.plots_cell_after_sim.load(conf=self._conf[ 'results options']['after solving'][ 'plots']['single cell pipeline']) self.plots_cells_after_sim.load(conf=self._conf[ 'results options']['after solving'][ 'plots']['cell cluster pipeline']) def unload(self) -> None: # Unload our superclass. super().unload() # Unload all subconfigurations of this configuration. self.plots_cell_after_sim.unload() self.plots_cells_after_sim.unload() # ..................{ PROPERTIES ~ after }.................. @property def is_after_sim(self) -> bool: return self.is_after_sim_save or self.is_after_sim_show @is_after_sim.setter @type_check def is_after_sim(self, is_after_sim: bool) -> None: self.is_after_sim_save = is_after_sim self.is_after_sim_show = is_after_sim
class SimConfAnimAll(YamlABC): ''' YAML-backed subconfiguration for exporting *all* animations (both in- and post-simulation) enabled by the current YAML-formatted simulation configuration file. Attributes (General) ---------- is_overlay_current : bool ``True`` only if this configuration overlays streamlines (e.g., electric current, concentration flux) onto appropriate animations. Attributes (While Solving) ---------- is_while_sim : bool ``True`` only if this configuration displays and/or saves in-simulation animations. is_while_sim_save : bool ``True`` only if this configuration saves in-simulation animations. is_while_sim_show : bool ``True`` only if this configuration displays in-simulation animations. anim_while_sim : SimConfVisualCellsEmbedded Generic configuration applicable to all in-simulation animations. Ignored if :attr:``is_while_sim`` is ``False``. Attributes (After Solving) ---------- is_after_sim : bool ``True`` only if this configuration displays and/or saves post-simulation animations. is_after_sim_save : bool ``True`` only if this configuration saves post-simulation animations. is_after_sim_show : bool ``True`` only if this configuration displays post-simulation animations. anims_after_sim : YamlList YAML-backed list of all post-simulation animations to be animated. Ignored if :attr:`is_after_sim` is ``False``. Attributes (Images) ---------- is_images_save : bool ``True`` only if this configuration saves animation frames as images. image_filetype : str Filetype of all image files saved by this configuration. Ignored if :attr:`is_images_save` is ``False``. image_dpi : int Dots per inch (DPI) of all image files saved by this configuration. Ignored if :attr:`is_images_save` is ``False``. Attributes (Video) ---------- is_video_save : bool ``True`` only if this configuration saves animation frames as video. video_bitrate : int Bitrate in bits per second of all video files saved by this configuration. Ignored if :attr:`is_video_save` is `False`. video_codec_names : SequenceTypes List of the names of all encoder-specific codecs with which to encode animations (in descending order of preference), automatically: * Selecting the first codec supported by the selected writer. * Replacing any codec named `auto` by the name of a recommended codec specific to the selected writer and filetype. For details, see the `betse.lib.matplotlib.writer.mplvideo.get_first_codec_name()` function. Ignored if :attr:`is_video_save` is `False`. video_dpi : int Dots per inch (DPI) of all frames of all video files saved by this configuration. Ignored if :attr:`is_images_save` is `False`. video_filetype : str Filetype of all video files saved by this configuration. Supported filetypes include: * `mkv` (Matroska), an open-standard audio and video container supporting all relevant codecs and hence the default. * `avi`, Microsoft's obsolete proprietary audio and video container. * `gif`, a proprietary image format supporting video animations. * `ogv` (Theora), Xiph's open-standard audio and video container. * `mov` (QuickTime), Apple's proprietary audio and video container. * `mp4` (MPEG-4 Part 14), an open-standard audio and video container. * `webm` (WebM), Google's proprietary audio and video container. Ignored if :attr:`is_video_save` is `False`. video_framerate : int Framerate in frames per second of all video files saved by this configuration. Ignored if :attr:`is_video_save` is `False`. video_metadata : MappingType Dictionary mapping from the alphabetic lowercase name of video metadata supported by the active video encoder to that metadata's human-readable string to be embedded in all video files saved by this configuration. Supported names include: `title`, `artist`, `genre`, `subject`, `copyright`, `srcform`, and `comment`. If this dictionary does *not* contain a `copyright` key, such a key will be automatically synthesized from the current year. Ignored if :attr:`is_video_save` is `False`. video_writer_names : SequenceTypes List of the names of all matplotlib animation writers with which to encode animations (in order of descending preference), automatically selecting the first writer installed on the current system. Supported names include: * ``ffmpeg``, an open-source cross-platform audio and video encoder. * ``avconv``, an open-source cross-platform audio and video encoder forked from (and largely interchangeable with) `ffmpeg`. * ``mencoder``, an open-source cross-platform audio and video encoder associated with MPlayer, a popular media player. * ``imagemagick``, an open-source cross-platform image manipulation suite supporting *only* creation of animated GIFs. Ignored if :attr:`is_video_save` is ``False``. ''' # ..................{ ALIASES }.................. is_overlay_current = yaml_alias( "['results options']['overlay currents']", bool) # ..................{ ALIASES ~ while }.................. is_while_sim_save = yaml_alias( "['results options']['while solving']['animations']['save']", bool) is_while_sim_show = yaml_alias( "['results options']['while solving']['animations']['show']", bool) # ..................{ ALIASES ~ after }.................. is_after_sim_save = yaml_alias( "['results options']['after solving']['animations']['save']", bool) is_after_sim_show = yaml_alias( "['results options']['after solving']['animations']['show']", bool) # ..................{ ALIASES ~ save : images }.................. is_images_save = yaml_alias( "['results options']['save']['animations']['images']['enabled']", bool) image_filetype = yaml_alias( "['results options']['save']['animations']['images']['filetype']", str) image_dpi = yaml_alias_int_positive( "['results options']['save']['animations']['images']['dpi']") # ..................{ ALIASES ~ save : video }.................. is_video_save = yaml_alias( "['results options']['save']['animations']['video']['enabled']", bool) video_bitrate = yaml_alias_int_positive( "['results options']['save']['animations']['video']['bitrate']") video_dpi = yaml_alias_int_positive( "['results options']['save']['animations']['video']['dpi']") video_filetype = yaml_alias( "['results options']['save']['animations']['video']['filetype']", str) video_framerate = yaml_alias_int_positive( "['results options']['save']['animations']['video']['framerate']") video_metadata = yaml_alias( "['results options']['save']['animations']['video']['metadata']", MappingType) video_writer_names = yaml_alias( "['results options']['save']['animations']['video']['writers']", SequenceTypes) video_codec_names = yaml_alias( "['results options']['save']['animations']['video']['codecs']", SequenceTypes) # ..................{ INITIALIZERS }.................. def __init__(self, *args, **kwargs) -> None: # Initialize our superclass with all passed parameters. super().__init__(*args, **kwargs) # Encapsulate low-level dictionaries with high-level wrappers. self.anim_while_sim = SimConfVisualCellsEmbedded() # Encapsulate low-level lists of dictionaries with high-level wrappers. self.anims_after_sim = SimConfVisualCellsListItem.make_list() # ..................{ LOADERS }.................. #FIXME: Default the "copyright" entry of video metadata to #"@ {}".format(current_year)". def load(self, *args, **kwargs) -> None: # Load our superclass with all passed arguments. super().load(*args, **kwargs) # Load all subconfigurations of this configuration. self.anim_while_sim.load(conf=self._conf[ 'results options']['while solving']['animations']) self.anims_after_sim.load(conf=self._conf[ 'results options']['after solving']['animations']['pipeline']) def unload(self) -> None: # Unload our superclass. super().unload() # Unload all subconfigurations of this configuration. self.anim_while_sim.unload() self.anims_after_sim.unload() # ..................{ PROPERTIES ~ while }.................. @property def is_while_sim(self) -> bool: return self.is_while_sim_save or self.is_while_sim_show @is_while_sim.setter @type_check def is_while_sim(self, is_while_sim: bool) -> None: self.is_while_sim_save = is_while_sim self.is_while_sim_show = is_while_sim # ..................{ PROPERTIES ~ after }.................. @property def is_after_sim(self) -> bool: return self.is_after_sim_save or self.is_after_sim_show @is_after_sim.setter @type_check def is_after_sim(self, is_after_sim: bool) -> None: self.is_after_sim_save = is_after_sim self.is_after_sim_show = is_after_sim
class SimConfTissueListItem(SimConfTissueABC, YamlListItemABC): ''' YAML-backed tissue profile list item subconfiguration, encapsulating the configuration of a single tissue profile parsed from a list of these profiles in the current YAML-formatted simulation configuration file. Attributes ---------- is_gj_insular : bool ``True`` only if gap junctions originating at cells in this tissue are **insular** (i.e., prevented from connecting to cells in other tissues), implying these gap junctions to be strictly intra-tissue. Attributes (Cell Picker) ---------- picker_type : CellsPickerType Type of **tissue profile picker** (i.e., object assigning a subset of all cells matching some criteria to this tissue profile). picker_cells_color : str **Hexadecimal-formatted color** (i.e., string of six hexadecimal digits specifying this color's red, green, and blue components) of all circles within the vector image (defined by the ``cells from svg`` setting in the current simulation configuration) to be assigned to this tissue. Ignored unless :attr:`picker_type` is :attr:`CellsPickerType.COLOR`. picker_cells_index : SequenceTypes Sequence of the indices of all cells to be assigned to this tissue. Ignored unless :attr:`picker_type` is :attr:`CellsPickerType.INDICES`. picker_cells_percent : float **Percentage** (i.e., floating point number in the range ``[0.0, 100.0]``) of the total cell population to be randomly assigned to this tissue. Ignored unless :attr:`picker_type` is :attr:`CellsPickerType.PERCENT`. picker_image_filename : str Absolute or relative filename of the image mask whose pure-black pixels (i.e., pixels whose red, green, and blue color components are all 0) define the region of the cell cluster whose cells are all to be assigned to this tissue. This image *must*: * Be square (i.e., have equal width and height). * Contain no alpha transparency layer. Ignored unless :attr:`picker_type` is :attr:`CellsPickerType.IMAGE`. ''' # ..................{ ALIASES }.................. is_gj_insular = yaml_alias("['insular']", bool) # ..................{ ALIASES ~ picker }.................. picker_type = yaml_enum_alias("['cell targets']['type']", CellsPickerType) #FIXME: Create a new yaml_alias_color() data descriptor validating this #string to be a valid hexadecimal-formatted color. #FIXME: In the YAML, if color specifications don't have quotations around #them (e.g. '808080') the yaml sometimes thinks all numerical hex codes are #strings (e.g. 008080), and sometimes integers (e.g. 800080), in which case #the whole thing crashed with a type error! I'm not quite sure how to force #it to read in a string... For now, I've put quotes around the hex code #numeral... picker_cells_color = yaml_alias("['cell targets']['color']", str) picker_cells_index = yaml_alias("['cell targets']['indices']", SequenceTypes) picker_cells_percent = yaml_alias_float_percent( "['cell targets']['percent']") picker_image_filename = yaml_alias("['cell targets']['image']", str) # ..................{ SUPERCLASS }.................. @classmethod @type_check def make_default(cls, yaml_list: YamlList) -> YamlListItemABC: # Duplicate the first tissue profile in our default configuration file. return cls._make_loaded( conf={ 'name': yaml_list.get_item_name_uniquified('Tissue ({})'), 'insular': True, 'diffusion constants': { 'Dm_Na': 1.0e-18, 'Dm_K': 15.0e-18, 'Dm_Cl': 2.0e-18, 'Dm_Ca': 1.0e-18, 'Dm_M': 1.0e-18, 'Dm_P': 0.0, }, 'cell targets': { 'type': 'all', 'color': 'ff0000', 'image': 'geo/circle/circle_base.png', 'indices': [3, 14, 15, 9, 265], 'percent': 50, }, })