aegis_sim.recording.recordingmanager
Data recorder
Records data generated by the simulation.
When thinking about recording additional data, consider that there are three recording methods: I. Snapshots (record data from the population at a specific step) II. Flushes (collect data over time then flush) III. One-time records IV. Other: TE records
1"""Data recorder 2 3Records data generated by the simulation. 4 5When thinking about recording additional data, consider that there are three recording methods: 6 I. Snapshots (record data from the population at a specific step) 7 II. Flushes (collect data over time then flush) 8 III. One-time records 9 IV. Other: TE records 10""" 11 12import pathlib 13import shutil 14import logging 15 16from aegis_sim import variables 17 18from .terecorder import TERecorder 19from .picklerecorder import PickleRecorder 20from .popgenstatsrecorder import PopgenStatsRecorder 21from .intervalrecorder import IntervalRecorder 22from .flushrecorder import FlushRecorder 23from .featherrecorder import FeatherRecorder 24from .phenomaprecorder import PhenomapRecorder 25from .summaryrecorder import SummaryRecorder 26from .progressrecorder import ProgressRecorder 27from .simpleprogressrecorder import SimpleProgressRecorder 28from .popsizerecorder import PopsizeRecorder 29from .resourcerecorder import ResourcesRecorder 30from .ticker import Ticker 31from .configrecorder import ConfigRecorder 32from .envdriftmaprecorder import Envdriftmaprecorder 33 34# TODO write tests 35 36 37class RecordingManager: 38 """ 39 Container class for various recorders. 40 Each recorder records a certain type of data. 41 Most recorders record data as tables, except SummaryRecorder and PickleRecorder which record JSON files and pickles (a binary python format). 42 Headers and indexes of all tabular files are explicitly recorded. 43 44 ----- 45 GUI 46 AEGIS records a lot of different data. 47 In brief, AEGIS records 48 genomic data (population-level allele frequencies and individual-level binary sequences) and 49 phenotypic data (observed population-level phenotypes and intrinsic individual-level phenotypes), 50 as well as 51 derived demographic data (life, death and birth tables), 52 population genetic data (e.g. effective population size, theta), and 53 survival analysis data (TE / time-event tables). 54 Furthermore, it records metadata (e.g. simulation log, processed configuration files) and python pickle files. 55 56 Recorded data is distributed in multiple files. 57 Almost all data are tabular, so each file is a table to which rows are appended as the simulation is running. 58 The recording rates are frequencies at which rows are added; they are expressed in simulation steps. 59 """ 60 61 def init(self, custom_config_path, overwrite): 62 self.odir = self.make_odir(custom_config_path=custom_config_path, overwrite=overwrite) 63 # TODO make subfolders 64 65 def initialize_recorders(self, TICKER_RATE): 66 self.terecorder = TERecorder(odir=self.odir) 67 self.picklerecorder = PickleRecorder(odir=self.odir) 68 self.popgenstatsrecorder = PopgenStatsRecorder(odir=self.odir) 69 self.guirecorder = IntervalRecorder(odir=self.odir) 70 self.flushrecorder = FlushRecorder(odir=self.odir) 71 self.featherrecorder = FeatherRecorder(odir=self.odir) 72 self.phenomaprecorder = PhenomapRecorder(odir=self.odir) 73 self.summaryrecorder = SummaryRecorder(odir=self.odir) 74 self.progressrecorder = ProgressRecorder(odir=self.odir) 75 self.simpleprogressrecorder = SimpleProgressRecorder(odir=self.odir) 76 self.ticker = Ticker(odir=self.odir, TICKER_RATE=TICKER_RATE) 77 self.popsizerecorder = PopsizeRecorder(odir=self.odir) 78 self.resourcerecorder = ResourcesRecorder(odir=self.odir) 79 self.configrecorder = ConfigRecorder(odir=self.odir) 80 self.envdriftmaprecorder = Envdriftmaprecorder(odir=self.odir) 81 82 ############# 83 # UTILITIES # 84 ############# 85 86 @staticmethod 87 def make_odir(custom_config_path, overwrite) -> pathlib.Path: 88 output_path = custom_config_path.parent / custom_config_path.stem # remove .yml 89 is_occupied = output_path.exists() and output_path.is_dir() 90 if is_occupied: 91 if overwrite: 92 shutil.rmtree(output_path) 93 else: 94 raise Exception(f"{output_path} already exists. To overwrite, add flag --overwrite or -o.") 95 return output_path 96 97 @staticmethod 98 def make_subfolders(paths): 99 # TODO relink paths that are now in classes 100 for path in paths: 101 path.mkdir(exist_ok=True, parents=True) 102 103 def is_extinct(self) -> bool: 104 if self.summaryrecorder.extinct: 105 logging.info(f"Population went extinct (at step {variables.steps}).") 106 return True 107 return False
38class RecordingManager: 39 """ 40 Container class for various recorders. 41 Each recorder records a certain type of data. 42 Most recorders record data as tables, except SummaryRecorder and PickleRecorder which record JSON files and pickles (a binary python format). 43 Headers and indexes of all tabular files are explicitly recorded. 44 45 ----- 46 GUI 47 AEGIS records a lot of different data. 48 In brief, AEGIS records 49 genomic data (population-level allele frequencies and individual-level binary sequences) and 50 phenotypic data (observed population-level phenotypes and intrinsic individual-level phenotypes), 51 as well as 52 derived demographic data (life, death and birth tables), 53 population genetic data (e.g. effective population size, theta), and 54 survival analysis data (TE / time-event tables). 55 Furthermore, it records metadata (e.g. simulation log, processed configuration files) and python pickle files. 56 57 Recorded data is distributed in multiple files. 58 Almost all data are tabular, so each file is a table to which rows are appended as the simulation is running. 59 The recording rates are frequencies at which rows are added; they are expressed in simulation steps. 60 """ 61 62 def init(self, custom_config_path, overwrite): 63 self.odir = self.make_odir(custom_config_path=custom_config_path, overwrite=overwrite) 64 # TODO make subfolders 65 66 def initialize_recorders(self, TICKER_RATE): 67 self.terecorder = TERecorder(odir=self.odir) 68 self.picklerecorder = PickleRecorder(odir=self.odir) 69 self.popgenstatsrecorder = PopgenStatsRecorder(odir=self.odir) 70 self.guirecorder = IntervalRecorder(odir=self.odir) 71 self.flushrecorder = FlushRecorder(odir=self.odir) 72 self.featherrecorder = FeatherRecorder(odir=self.odir) 73 self.phenomaprecorder = PhenomapRecorder(odir=self.odir) 74 self.summaryrecorder = SummaryRecorder(odir=self.odir) 75 self.progressrecorder = ProgressRecorder(odir=self.odir) 76 self.simpleprogressrecorder = SimpleProgressRecorder(odir=self.odir) 77 self.ticker = Ticker(odir=self.odir, TICKER_RATE=TICKER_RATE) 78 self.popsizerecorder = PopsizeRecorder(odir=self.odir) 79 self.resourcerecorder = ResourcesRecorder(odir=self.odir) 80 self.configrecorder = ConfigRecorder(odir=self.odir) 81 self.envdriftmaprecorder = Envdriftmaprecorder(odir=self.odir) 82 83 ############# 84 # UTILITIES # 85 ############# 86 87 @staticmethod 88 def make_odir(custom_config_path, overwrite) -> pathlib.Path: 89 output_path = custom_config_path.parent / custom_config_path.stem # remove .yml 90 is_occupied = output_path.exists() and output_path.is_dir() 91 if is_occupied: 92 if overwrite: 93 shutil.rmtree(output_path) 94 else: 95 raise Exception(f"{output_path} already exists. To overwrite, add flag --overwrite or -o.") 96 return output_path 97 98 @staticmethod 99 def make_subfolders(paths): 100 # TODO relink paths that are now in classes 101 for path in paths: 102 path.mkdir(exist_ok=True, parents=True) 103 104 def is_extinct(self) -> bool: 105 if self.summaryrecorder.extinct: 106 logging.info(f"Population went extinct (at step {variables.steps}).") 107 return True 108 return False
Container class for various recorders. Each recorder records a certain type of data. Most recorders record data as tables, except SummaryRecorder and PickleRecorder which record JSON files and pickles (a binary python format). Headers and indexes of all tabular files are explicitly recorded.
GUI AEGIS records a lot of different data. In brief, AEGIS records genomic data (population-level allele frequencies and individual-level binary sequences) and phenotypic data (observed population-level phenotypes and intrinsic individual-level phenotypes), as well as derived demographic data (life, death and birth tables), population genetic data (e.g. effective population size, theta), and survival analysis data (TE / time-event tables). Furthermore, it records metadata (e.g. simulation log, processed configuration files) and python pickle files.
Recorded data is distributed in multiple files. Almost all data are tabular, so each file is a table to which rows are appended as the simulation is running. The recording rates are frequencies at which rows are added; they are expressed in simulation steps.
66 def initialize_recorders(self, TICKER_RATE): 67 self.terecorder = TERecorder(odir=self.odir) 68 self.picklerecorder = PickleRecorder(odir=self.odir) 69 self.popgenstatsrecorder = PopgenStatsRecorder(odir=self.odir) 70 self.guirecorder = IntervalRecorder(odir=self.odir) 71 self.flushrecorder = FlushRecorder(odir=self.odir) 72 self.featherrecorder = FeatherRecorder(odir=self.odir) 73 self.phenomaprecorder = PhenomapRecorder(odir=self.odir) 74 self.summaryrecorder = SummaryRecorder(odir=self.odir) 75 self.progressrecorder = ProgressRecorder(odir=self.odir) 76 self.simpleprogressrecorder = SimpleProgressRecorder(odir=self.odir) 77 self.ticker = Ticker(odir=self.odir, TICKER_RATE=TICKER_RATE) 78 self.popsizerecorder = PopsizeRecorder(odir=self.odir) 79 self.resourcerecorder = ResourcesRecorder(odir=self.odir) 80 self.configrecorder = ConfigRecorder(odir=self.odir) 81 self.envdriftmaprecorder = Envdriftmaprecorder(odir=self.odir)
87 @staticmethod 88 def make_odir(custom_config_path, overwrite) -> pathlib.Path: 89 output_path = custom_config_path.parent / custom_config_path.stem # remove .yml 90 is_occupied = output_path.exists() and output_path.is_dir() 91 if is_occupied: 92 if overwrite: 93 shutil.rmtree(output_path) 94 else: 95 raise Exception(f"{output_path} already exists. To overwrite, add flag --overwrite or -o.") 96 return output_path