def __init__(self, potential: Potential, dipole_separation: float, prefactor: float = 1.5, empirical_bound: float = float('inf'), number_trials: int = 10000, dipole_charge: float = 1.0, periodic_boundaries: bool = True) -> None: """ The constructor of the InnerPointEstimator class. Parameters ---------- potential : potential.Potential Potential whose derivative is to be bounded. dipole_separation : float Separation of the two point masses within the constructed dipole. prefactor : float, optional A constant which gets multiplied to the bounds. empirical_bound : float, optional If a bound exceeds this value, this value will be returned instead. number_trials : int, optional The number of separation samples taken. dipole_charge : float, optional The absolute value of the charges in the dipole. periodic_boundaries : bool Whether the separations in the given region should be corrected for periodic boundaries. Raises ------ base.exceptions.ConfigurationError If the potential derivative method does not expect exactly one separation. If the potential derivative method does not expect exactly two charges. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, potential=potential.__class__.__name__, dipole_separation=dipole_separation, prefactor=prefactor, empirical_bound=empirical_bound, number_trials=number_trials, dipole_charge=dipole_charge, periodic_boundaries=periodic_boundaries) super().__init__(potential=potential, prefactor=prefactor, empirical_bound=empirical_bound) self._number_trials = number_trials self._dipole_separation = dipole_separation self._dipole_separation_over_two = dipole_separation / 2 self._dipole_charge = dipole_charge if self._potential.number_separation_arguments != 1: raise ConfigurationError( "The estimator {0} expects a potential " "which handles exactly one separation!".format( self.__class__.__name__)) if self._potential.number_charge_arguments != 2: raise ConfigurationError( "The estimator {0} expects a potential " "which handles exactly two charges!".format( self.__class__.__name__))
def __init__(self, charge_values: Sequence[ChargeValues] = ()) -> None: """ The constructor of the RandomNodeCreator class. Parameters ---------- charge_values : Sequence[input_output_handler.input_handler.charge_values.ChargeValues], optional The sequence of charge values. Raises ------ base.exceptions.ConfigurationError If the charge values does not contain a charge for each child node within a root node. base.exceptions.ConfigurationError: If in the sequence of charge values a charge name appears more than once. """ # Check that per charge value there is a charge given for every particle for charge_value in charge_values: if not len(charge_value) == self.number_of_nodes_per_root_node: raise ConfigurationError( "Charge {0} is not given for every child of a composite point object." .format(charge_value.charge_name)) # Check that each charge value has a different name if not len( set(charge_value.charge_name for charge_value in charge_values)) == len(charge_values): raise ConfigurationError( "Please choose a unique charge name for all the charges used.") self._charge_values = charge_values
def __init__(self, prefactor: float = 1.5837) -> None: """ The constructor of the InversePowerCoulombBoundingPotential class. Parameters ---------- prefactor : float, optional The prefactor k of the potential. Raises ------ base.exceptions.ConfigurationError If the hypercubic setting is not initialized. base.exceptions.ConfigurationError If the dimension does not equal three. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, prefactor=prefactor) if not setting.initialized(): raise ConfigurationError( "Potential {0} can only be used in a hypercubic setting.". format(self.__class__.__name__)) if not setting.dimension == 3: raise ConfigurationError( "The potential {0} can only be used in 3 dimensions.".format( self.__class__.__name__)) super().__init__(prefactor=prefactor)
def __init__(self, minimum_separation: float, maximum_separation: float) -> None: """ The constructor of the HardDipolePotential class. Parameters ---------- minimum_separation : float The minimum separation r. maximum_separation : float The maximum separation R. Raises ------ base.exceptions.ConfigurationError If the minimum separation r is not larger than 0. If the maximum separation R is not larger than 0. If the minimum separation r is not smaller than the maximum separation R. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, minimum_separation=minimum_separation, maximum_separation=maximum_separation) if not minimum_separation > 0.0: raise ConfigurationError("The class {0} can only be used with a minimum separation bigger than 0.0." .format(self.__class__.__name__)) if not maximum_separation: raise ConfigurationError("The class {0} can only be used with a maximum separation bigger than 0.0." .format(self.__class__.__name__)) if not minimum_separation < maximum_separation: raise ConfigurationError("The class {0} can only be used with a minimum separation that is smaller than the" "maximum separation.".format(self.__class__.__name__)) super().__init__() self._minimum_separation_squared = minimum_separation * minimum_separation self._maximum_separation_squared = maximum_separation * maximum_separation
def __init__(self, chain_time: float, delta_phi_degree: float) -> None: """ The constructor of the SingleIndependentActiveSequentialDirectionEndOfChainEventHandler class. The rotation angle in degrees by which the two-dimensional velocity vector is rotated on each end-of-chain event should be greater than 0.0 and smaller than 360.0. Moreover, 180.0 degrees is excluded to assure irreducibility of the Markov chain. Parameters ---------- chain_time : float The time interval after which a new end-of-chain event occurs. delta_phi_degree : float The rotation angle in degrees by which the two-dimensional velocity vector is rotated on each end-of-chain event. Raises ------ base.exceptions.ConfigurationError: If the rotation angle in degrees is not in the interval (0, 360.0) or equal to 180.0. If the dimension in the setting package is not set to two. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, chain_time=chain_time, delta_phi_degree=delta_phi_degree) super().__init__(chain_time=chain_time) if not 0.0 < delta_phi_degree < 360.0 or delta_phi_degree == 180.0: raise ConfigurationError("The rotation angle of the velocity after an end-of-chain event in the event " "handler {0} has to be larger than 0.0 and smaller than 360.0, and is further not " "allowed to be exactly 180.0.".format(self.__class__.__name__)) if not setting.dimension == 2: raise ConfigurationError("The event handler {0} can only be used in two dimensions." .format(self.__class__.__name__)) delta_phi = delta_phi_degree * math.pi / 180.0 self._cos_delta_phi = math.cos(delta_phi) self._sin_delta_phi = math.sin(delta_phi)
def __init__(self, potential: Potential, bounding_potential: CellBoundingPotential, charge: str = None) -> None: """ The constructor of the TwoLeafUnitCellBoundingPotentialEventHandler class. Parameters ---------- potential : potential.Potential The potential between the leaf units. bounding_potential : potential.cell_bounding_potential.CellBoundingPotential The invertible cell bounding potential between the leaf units. charge : str or None, optional The relevant charge for this event handler. Raises ------ base.exceptions.ConfigurationError: If the cell bounding potential does not expect exactly one separation. base.exceptions.ConfigurationError: If the charge is not None but the potential or the cell bounding potential expects more than two charges. """ log_init_arguments( logging.getLogger(__name__).debug, self.__class__.__name__, potential=potential.__class__.__name__, bounding_potential=bounding_potential.__class__.__name__, charge=charge) super().__init__(potential=potential, bounding_potential=bounding_potential) self._charge = charge if self._bounding_potential.number_separation_arguments != 1: raise ConfigurationError( "The event handler {0} expects a cell bounding potential " "which handles exactly one separation!".format( self.__class__.__name__)) if charge is None: self._potential_charges = (lambda unit_one, unit_two: tuple( 1.0 for _ in range(self._potential.number_charge_arguments))) self._bounding_potential_charges = ( lambda unit_one, unit_two: tuple(1.0 for _ in range( self._bounding_potential.number_charge_arguments))) else: if self._potential.number_charge_arguments == 2 and self._bounding_potential.number_charge_arguments == 2: self._potential_charges = lambda unit_one, unit_two: ( unit_one.charge[charge], unit_two.charge[charge]) self._bounding_potential_charges = self._potential_charges else: raise ConfigurationError( "The event handler {0} was initialized with a charge which is not None," " but its potential {1} and/or its bounding potential {2}" "expects not exactly 2 charges.".format( self.__class__.__name__, self._potential.__class__.__name__, self._bounding_potential.__class__.__name__))
def initialize(self, extracted_global_state: Any) -> None: """ Initialize all the taggers based on the internal states. Extends the initialize method of the abstract Activator class. This method is called once in the beginning of the run by the mediator. Only after a call of this method, other public methods of this class can be called without raising an error. The internal states get initialized in the super().initialize(extracted_global_state) using the extracted global state from the state handler. The precise format of the extracted_active_global_state is specified by the used state handler. Since it is just passed through to the internal states, only their initialize methods needs to be implemented for different versions of state handlers. Since taggers might only be able to provide a full list of their event handlers after a call to their initialize method (because, e.g., the tagger wants to first initialize a single event handler with information about an internal state, and then copy the initialized event handler), attributes of this class that rely on all event handlers are constructed here and not in the __init__ method. Parameters ---------- extracted_global_state : Any The full extracted global state from the state handler. """ super().initialize(extracted_global_state) for tagger in self._taggers: tagger.initialize_with_internal_states(self._internal_states) tagger.initialize() self._event_handlers = sum( (tagger.get_event_handlers() for tagger in self._taggers), []) self._event_handler_tagger_dictionary = { event_handler: tagger for tagger in self._taggers for event_handler in tagger.get_event_handlers() } self._running_event_handlers = {tagger: [] for tagger in self._taggers} self._not_running_event_handlers = { tagger: copy.copy(tagger.get_event_handlers()) for tagger in self._taggers } # Search the one and only instance of StartOfRunEventHandler self._start_of_run_event_handler = None for event_handler in self._event_handlers: if isinstance(event_handler, StartOfRunEventHandler): if self._start_of_run_event_handler is None: self._start_of_run_event_handler = event_handler else: raise ConfigurationError( "Please provide only one StartOfRunEventHandler!") if self._start_of_run_event_handler is None: raise ConfigurationError( "An StartOfRunEventHandler is required to run the program!")
def __init__(self, potential: Potential, offset: float, max_displacement: float, charge: str = None) -> None: """ The constructor of the TwoLeafUnitEventHandlerWithPiecewiseConstantBoundingPotential class. Parameters ---------- potential : potential.Potential The potential between the leaf units. offset : float The offset used to create piecewise constant bounding potential. max_displacement : The maximum time displacement used to create piecewise constant bounding potential. charge : str or None, optional The relevant charge for this event handler. Raises ------ base.exceptions.ConfigurationError: If the potential does not expect exactly one separation. base.exceptions.ConfigurationError: If the charge is not None but the potential expects more than two charges. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, potential=potential.__class__.__name__, offset=offset, max_displacement=max_displacement, charge=charge) super().__init__(potential=potential, offset=offset, max_displacement=max_displacement) if self._potential.number_separation_arguments != 1: raise ConfigurationError( "The event handler {0} expects a potential " "which handles exactly one separation!".format( self.__class__.__name__)) if charge is None: self._charges = lambda unit_one, unit_two: tuple( 1.0 for _ in range(self._potential.number_charge_arguments)) else: if self._potential.number_charge_arguments == 2: self._charges = lambda unit_one, unit_two: (unit_one.charge[ charge], unit_two.charge[charge]) else: raise ConfigurationError( "The event handler {0} was initialized with a charge which is not None," " but its potential {1} expects not exactly 2 charges.". format(self.__class__.__name__, self._potential.__class__.__name__))
def __init__(self, potential: InvertiblePotential, charge: str = None) -> None: """ The constructor of the TwoLeafUnitEventHandler class. Parameters ---------- potential : potential.InvertiblePotential The invertible potential. charge : str or None, optional The relevant charge for this event handler. Raises ------ base.exceptions.ConfigurationError: If the potential does not expect exactly one separation. base.exceptions.ConfigurationError: If the charge is not None but the potential expects more than two charges. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, potential=potential.__class__.__name__, charge=charge) super().__init__() self._potential = potential if self._potential.number_separation_arguments != 1: raise ConfigurationError( "The event handler {0} expects a potential " "which handles exactly one separation!".format( self.__class__.__name__)) if charge is None: self._charges = lambda unit_one, unit_two: tuple( 1.0 for _ in range(self._potential.number_charge_arguments)) else: if self._potential.number_charge_arguments == 2: self._charges = lambda unit_one, unit_two: (unit_one.charge[ charge], unit_two.charge[charge]) else: raise ConfigurationError( "The event handler {0} was initialized with a charge which is not None," " but its potential {1} expects not exactly 2 charges.". format(self.__class__.__name__, self._potential.__class__.__name__)) if self._potential.potential_change_required: self._potential_displacement = ( lambda *args, **kwargs: self._potential.displacement( *args, **kwargs, potential_change=random.expovariate(setting.beta))) else: self._potential_displacement = self._potential.displacement
def __init__(self, potential: Potential, **kwargs: Any): """ The constructor of the EventHandlerWithBoundingPotential class. This class is designed for cooperative inheritance, meaning that it passes through all unused kwargs in the init to the next class in the MRO via super. Parameters ---------- potential : potential.Potential The potential between the active and target leaf unit. kwargs : Any Additional kwargs which are passed to the __init__ method of the next class in the MRO. Raises ------ base.exceptions.ConfigurationError If the potential expects more than one separation. """ super().__init__(**kwargs) self._bounding_event_rate = None self._potential = potential if self._potential.number_separation_arguments != 1: raise ConfigurationError("The event handler {0} expects a potential " "which handles exactly one separation!".format(self.__class__.__name__))
def __init__(self, filename: str, charge: str) -> None: """ The constructor of the PolarizationOutputHandler class. This class uses a HardBufferedTextWriter to first write the polarization to a temporary file. Parameters ---------- filename : str The filename of the file this output handler is connected to. charge : str The charge used to calculate the polarization. Raises ------ base.exceptions.ConfigurationError If the number of node levels is not two or the number of nodes per root node is not three. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, filename=filename, charge=charge) super().__init__(filename) self._file = HardBufferedTextWriter(filename) self._charge = charge if setting.number_of_node_levels != 2 or setting.number_of_nodes_per_root_node == 1: raise ConfigurationError("The output handler {0} can only be used with charge neutral composite point" " objects.".format(self.__class__.__name__)) print("# Polarization Vector", file=self._file)
def initialize(self, cells: PeriodicCells, calculate_lower_bound: bool) -> None: """ Initialize the cell bounding potential. This is done by handing the cells to the cell bounding potential, and by telling it whether it needs to determine a lower bound on the derivatives for all not excluded cell separations, or not. Since in this version of JeLLyFysh, cell separations are only defined for periodic cell systems (i.e., with taking periodic boundary conditions into account), a cell bounding potential can only be initialized with an instance of the 'PeriodicCells' class. The same restriction thus holds for this event handler. Extends the initialize method of the abstract Initializer class. This method is called once in the beginning of the run by the activator. Only after a call of this method, other public methods of this class can be called without raising an error. Parameters ---------- cells : activator.internal_state.cell_occupancy.cells.Cells The cell system. calculate_lower_bound : bool Whether the cell bounding potential needs to compute a lower bound or not. Raises ------ base.exceptions.ConfigurationError If the cell system is not an instance of a periodic cell system. """ super().initialize() if not isinstance(cells, PeriodicCells): raise ConfigurationError( "The event handler {0} can only be initialized with an instance of the " "'PeriodicCells' class.".format(self.__class__.__name__)) self._cells = cells self._bounding_potential.initialize(cells, calculate_lower_bound)
def __init__(self, cells: Cells, cell_level: int, maximum_number_occupants: int = 1, charge: str = None) -> None: """ The constructor of the SingleActiveCellOccupancy class. Parameters ---------- cells : activator.internal_state.cell_occupancy.cells.Cells The underlying cell system. cell_level : int The length of the global state identifiers which should be stored in this internal state. maximum_number_occupants : int, optional The maximum number of allowed occupants per cell. If this number is smaller than or equal to zero, this class allows for an infinite number of occupants per cell. charge : str or None, optional The charge of the unit that must be unequal zero in order for the corresponding identifier to be stored. If the charge is None, all global state identifiers with the correct length are stored. Raises ------ base.exceptions.ConfigurationError If the cell_level corresponds to composite point objects which cannot have a charge but the charge is set. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, cells=cells.__class__.__name__, cell_level=cell_level, maximum_number_occupants=maximum_number_occupants, charge=charge) super().__init__(cells, cell_level, maximum_number_occupants) if cell_level < setting.number_of_node_levels and charge is not None: raise ConfigurationError("Chosen cell level stores composite point objects which cannot have a charge!") self._surplus = {} self._occupants = {cell: [] for cell in self._cells.yield_cells()} self._active_unit_identifier = None self._is_relevant_unit = (lambda unit: unit.charge[charge] != 0) if charge is not None else lambda unit: True self._active_cell = None
def __init__(self, end_of_run_time: float, output_handler: str = None) -> None: """ The constructor of the FinalTimeEndOfRunEventHandler class. Parameters ---------- end_of_run_time : float The event time at which the run is ended. output_handler : str or None, optional The name of the output handler. Raises ------ base.exceptions.ConfigurationError If the end of run time is not greater than or equal to zero (the latter case logs a warning). """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, end_of_run_time=end_of_run_time, output_handler=output_handler) super().__init__(output_handler=output_handler) if not end_of_run_time >= 0.0: raise ConfigurationError("The end_of_run_time in the event handler {0} has to be >= 0.0." .format(self.__class__.__name__)) if end_of_run_time == 0.0: logging.getLogger(__name__).warning("The end_of_run_time in the event handler {0} is equal to 0.0. The " "simulation will stop immediately once the run is started." .format(self.__class__.__name__)) self._event_time = Time.from_float(end_of_run_time)
def initialize_with_internal_states(self, internal_states: Sequence[InternalState]) -> None: """ Initialize the tagger based on the initialized internal states. Extends the initialize_with_internal_states method of the base TaggerWithInternal class. This method is a second initialize method relevant to the base Initializer class. It is called once in the beginning of the run by the tag activator. However, this method does not call the initialize method of the Initializer class. Therefore, other public methods of this class can still not be called without raising an error after this method has been used. To finalize the initialization of this class, use the initialize method (which should be called after this method). This method checks if the internal state of this label is a cell-occupancy system. Parameters ---------- internal_states : Sequence[activator.internal_state.InternalState] Sequence of all initialized internal states in the activator. Raises ------ base.exceptions.ConfigurationError If the internal state is not an instance of CellOccupancy. """ super().initialize_with_internal_states(internal_states) if not isinstance(self._internal_state, CellOccupancy): raise ConfigurationError("The tagger {0} can only be used with an instance of the CellOccupancy class as " "the internal state.".format(self.__class__.__name__))
def __init__(self, filename: str) -> None: """ The constructor of the DumpingOutputHandler class. Parameters ---------- filename : str The filename of the file this output handler is connected to. Raises ------ AssertionError If the filename does not contain a file format. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, filename=filename) split_filename = filename.split(".") if len(split_filename) != 2: raise ConfigurationError( "The given filename {0} contains more than one '.'.".format( filename)) # Include python implementation and version (implementation_major_minor_macro in filename) dumping_filename = ( split_filename[0] + "_" + sys.implementation.name + "_" + "_".join([str(sys.version_info[i]) for i in range(3)]) + "." + split_filename[1]) super().__init__(dumping_filename)
def __init__(self, power: float, prefactor: float) -> None: """ The constructor of the InversePowerPotential. Parameters ---------- power : float The power p of the potential. prefactor : float The prefactor k of the potential. Raises ------ base.exceptions.ConfigurationError If the power p is not larger than 0. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, power=power, prefactor=prefactor) super().__init__(prefactor=prefactor) if not power > 0.0: raise ConfigurationError("Give a power > 0.0 as the power for the potential {0}." .format(self.__class__.__name__)) self._power = power self._two_over_power = 2.0 / self._power self._power_over_two = self._power / 2.0 self._power_plus_two = self._power + 2 self._infinity = float('inf')
def __init__(self, potential: Potential, offset: float, max_displacement: float, **kwargs: Any): """ The constructor of the EventHandlerWithPiecewiseConstantBoundingPotential class. This class is designed for cooperative inheritance, meaning that it passes through all unused kwargs in the init to the next class in the MRO via super. Parameters ---------- potential : potential.Potential The potential between the leaf units. offset : float The offset. max_displacement : float The maximum time displacement by which the active unit is displaced to determine the bounding event rate. kwargs : Any Additional kwargs which are passed to the __init__ method of the next class in the MRO. Raises ------ base.exceptions.ConfigurationError If the maximum time displacement is not larger than zero. """ super().__init__(**kwargs) self._potential = potential self._offset = offset if not max_displacement > 0.0: raise ConfigurationError("Please use a value for max_displacement > 0.0 in the class {0}." .format(self.__class__.__name__)) self._max_displacement = max_displacement self._bounding_event_rate = None
def __init__( self, create: Sequence[str], trash: Sequence[str], event_handler: EventHandler, number_event_handlers: int = 1, tag: str = None, activate: Sequence[str] = (), deactivate: Sequence[str] = () ) -> None: """ The constructor of the ActiveRootUnitInStateTagger class. Parameters ---------- create : Sequence[str] Sequence of tags to create after an event handler of this tagger has committed an event to the global state. trash : Sequence[str] Sequence of tags to trash after an event handler of this tagger has committed an event to the global state. event_handler : event_handler.EventHandler A single event handler instance. number_event_handlers : int, optional Number of event handlers to prepare. The tagger will deepcopy the given event handler instance to create this number of event handlers. tag : str or None, optional Tag used in all four lists (also of other taggers). If None, the class name (or the alias set in the factory) will be used as the tag. activate : Sequence[str], optional Sequence of tags to activate after an event handler of this tagger has committed an event to the global state. deactivate : Sequence[str], optional Sequence of tags to deactivate after an event handler of this tagger has committed an event to the global state. Raises ------ base.exceptions.ConfigurationError If no composite point objects are involved in the run (setting.number_of_node_levels not > 1). """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, event_handler=event_handler.__class__.__name__, number_event_handlers=number_event_handlers, create=create, trash=trash, activate=activate, deactivate=deactivate, tag=tag) super().__init__(create, trash, event_handler, number_event_handlers=number_event_handlers, tag=tag, activate=activate, deactivate=deactivate) if not setting.number_of_node_levels > 1: raise ConfigurationError( "The tagger {0} can only be used when composite point objects are involved in the" "simulation (setting.number_of_node_levels > 1).".format( self.__class__.__name__))
def initialize(self, cells: PeriodicCells, cell_level: int) -> None: """ Initialize the cell boundary event handler. Here, the event handler gets access to the relevant periodic cell system and the cell level of the corresponding cell-occupancy system. This cell boundary event handler requires a periodic cell system (and not a simple cell system) so that each cell always has a neighbor cell. Extends the initialize method of the abstract Initializer class. This method is called once in the beginning of the run by the activator. Only after a call of this method, other public methods of this class can be called without raising an error. Parameters ---------- cells : activator.internal_state.cell_occupancy.cells.PeriodicCells The periodic cell system. cell_level : int The cell level. Raises ------ base.exceptions.ConfigurationError If the cell system is not an instance of the PeriodicCells class. """ super().initialize() if not isinstance(cells, PeriodicCells): raise ConfigurationError("The event handler {0} can only be initialized with an instance of the " "PeriodicCells class.".format(self.__class__.__name__)) self._cells = cells self._cell_level = cell_level
def __init__(self, equilibrium_separation: float, power: int, prefactor: float = 1.0) -> None: """ The constructor of the DisplacedEvenPowerPotential class. Parameters ---------- equilibrium_separation : float The absolute value r_0 of the equilibrium separation of the potential. power : int The power p of the potential. prefactor : float, optional The prefactor k of the potential. Raises ------ base.exceptions.ConfigurationError If the power p is not larger than 0 or if p is odd. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, equilibrium_separation=equilibrium_separation, power=power, prefactor=prefactor) super().__init__(prefactor=prefactor, equilibrium_separation=equilibrium_separation) if not (power > 0 and power % 2 == 0): raise ConfigurationError("The potential {0} can only be used with " "a power > 0 divisible by 2!".format(self.__class__.__name__)) self._equilibrium_separation = equilibrium_separation self._equilibrium_separation_squared = equilibrium_separation * equilibrium_separation self._power = power self._inverse_power = 1.0 / power
def __init__(self, dumping_interval: float, output_handler: str) -> None: """ The constructor of the FixedIntervalDumpingEventHandler class. Parameters ---------- dumping_interval : float The time interval of the dumping. output_handler : The name of the output handler. Raises ------ base.exceptions.ConfigurationError: If the dumping interval is not greater than zero. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, dumping_interval=dumping_interval, output_handler=output_handler) super().__init__(output_handler=output_handler) if not dumping_interval > 0.0: raise ConfigurationError( "The dumping_interval in the event handler {0} has to be > 0.0." .format(self.__class__.__name__)) self._dumping_interval = dumping_interval self._event_time = Time(0.0, 0.0)
def __init__(self, filename: str): """ The constructor of the BondLengthAndAngleOutputHandler class. This class uses a HardBufferedTextWriter to first write the bond lengths and angles to temporary files. Parameters ---------- filename : str The filename of the file this output handler is connected to. Raises ------ base.exceptions.ConfigurationError If the number of node levels is not two or the number of nodes per root node is not three. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, filename=filename) super().__init__(filename) filename_dot_position = self._output_filename.rfind('.') bond_length_filename = (self._output_filename[:filename_dot_position] + '_Length' + self._output_filename[filename_dot_position:]) bond_angle_filename = (self._output_filename[:filename_dot_position] + '_Angle' + self._output_filename[filename_dot_position:]) self._file_bond_lengths = HardBufferedTextWriter(bond_length_filename) self._file_bond_angles = HardBufferedTextWriter(bond_angle_filename) if setting.number_of_node_levels != 2 or setting.number_of_nodes_per_root_node != 3: raise ConfigurationError("The output handler {0} can only be used if each root node has 3 child nodes." .format(self.__class__.__name__))
def __init__(self, bounding_potential: CellBoundingPotential, **kwargs: Any) -> None: """ The constructor of the CellBoundingPotentialEventHandler class. This class is designed for cooperative inheritance, meaning that it passes through all unused kwargs in the init to the next class in the MRO via super. Parameters ---------- bounding_potential : potential.cell_bounding_potential.CellBoundingPotential The cell bounding potential. kwargs : Any Additional kwargs which are passed to the __init__ method of the next class in the MRO. Raises ------ base.exceptions.ConfigurationError If the bounding potential is not an instance of a cell bounding potential. """ super().__init__(**kwargs) self._cells = None self._active_cell = None self._relative_cell = None self._bounding_potential = bounding_potential if not isinstance(self._bounding_potential, CellBoundingPotential): raise ConfigurationError( "The event handler {0} can only be used " "with the class CellBoundingPotential!".format( self.__class__.__name__))
def write(self, output_handler: str, *args: Any) -> None: """ Pass the arguments to the output handler. The arguments could be for example the full global state so that the output handler can start its sampling. This method is called in the mediating methods of event handlers in the mediator. There, each event handler defines itself, which methods should be passed to its output handler. When the output handlers were built using the JF factory, their names can include an alias. Then the output handler name should be this alias. Parameters ---------- output_handler : str The name of the output handler which should receive the arguments. args : Any The arguments passed to output handler. Raises ------ base.exceptions.ConfigurationError If no output handler with the given name exists. """ try: self._output_handlers_dictionary[output_handler].write(*args) except KeyError: raise ConfigurationError("The given output handler {0} does not exist.".format(output_handler))
def __init__(self, sampling_interval: float, output_handler: str, first_event_time_zero: bool = False) -> None: """ The constructor of the FixedIntervalSamplingEventHandler class. Parameters ---------- sampling_interval : float The time interval of the sampling. output_handler : str The name of the output handler. first_event_time_zero : bool, optional If the first returned candidate event time is zero. Raises ------ base.exceptions.ConfigurationError: If the sampling interval is not greater than zero. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, sampling_interval=sampling_interval, output_handler=output_handler) super().__init__(output_handler=output_handler) if not sampling_interval > 0.0: raise ConfigurationError("The sampling_interval in the event handler {0} has to be > 0.0." .format(self.__class__.__name__)) self._sampling_interval = sampling_interval self._event_time = Time(0.0, 0.0) if not first_event_time_zero else Time.from_float(-sampling_interval)
def initialize_with_internal_states(self, internal_states: Sequence[InternalState]) -> None: """ Initialize the tagger based on the initialized internal states. Extends the initialize_with_internal_states method of the base TaggerWithInternal class. This method is a second initialize method relevant to the base Initializer class. It is called once in the beginning of the run by the tag activator. However, this method does not call the initialize method of the Initializer class. Therefore, other public methods of this class can still not be called without raising an error after this method has been used. To finalize the initialization of this class, use the initialize method (which should be called after this method). This method checks if the internal state of this tagger is a cell-occupancy system. Also, the cell bounding potential event handler in the self._event_handler_to_copy attribute gets knowledge about the cell system, and is initialized itself. This event handler is deepcopied in the subsequent call of the initialize method to create the desired number of (initialized) event handlers for this tagger (see Tagger base class). Parameters ---------- internal_states : Sequence[activator.internal_state.InternalState] Sequence of all initialized internal states in the activator. Raises ------ base.exceptions.ConfigurationError If the internal state is not an instance of CellOccupancy. """ super().initialize_with_internal_states(internal_states) if not isinstance(self._internal_state, CellOccupancy): raise ConfigurationError("The tagger {0} can only be used with an instance of the CellOccupancy class as " "the internal state.".format(self.__class__.__name__)) # noinspection PyUnresolvedReferences self._event_handler_to_copy.initialize(self._internal_state.cells)
def __init__(self, create: Sequence[str], trash: Sequence[str], event_handler: EventHandler, internal_state_label: str, number_event_handlers: int = 1, tag: str = None) -> None: """ The constructor of the CellVetoTagger class. This class uses an internal state and therefore inherits from the TaggerWithInternalState class. The internal_state_label should refer to a cell-occupancy system. Note that the activate and deactivate sequences are always empty for a tagger of this kind. The event handler should be an instance of a CellVetoEventHandler. The number of event handlers should be set to the number of active units that are relevant to the cell-occupancy system. Parameters ---------- create : Sequence[str] Sequence of tags to create after an event handler of this tagger has committed an event to the global state. trash : Sequence[str] Sequence of tags to trash after an event handler of this tagger has committed an event to the global state. event_handler : event_handler.cell_boundary_event_handler.CellBoundaryEventHandler A single event handler instance. internal_state_label : str The label of the internal state this tagger wants to use. number_event_handlers : int, optional Number of event handlers to prepare. The tagger will deepcopy the given event handler instance to create this number of event handlers. tag : str or None, optional Tag used in all four lists (also of other taggers). If None, the class name (or the alias set in the factory) will be used as the tag. Raises ------ base.exceptions.ConfigurationError If the event handler is not an instance of a CellVetoEventHandler. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, event_handler=event_handler.__class__.__name__, number_event_handlers=number_event_handlers, internal_state_label=internal_state_label, create=create, trash=trash, tag=tag) if not isinstance(event_handler, CellVetoEventHandler): raise ConfigurationError( "The class {0} can only be used with an instance of the class " "CellVetoEventHandler as the event handler".format( self.__class__.__name__)) super().__init__(create, trash, event_handler, number_event_handlers=number_event_handlers, internal_state_label=internal_state_label, tag=tag)
def __init__(self, potential: Potential, lifting: Lifting, charge: str = None, **kwargs: Any) -> None: """ The constructor of the TwoCompositeObjectBoundingPotentialEventHandler class. This class is designed for cooperative inheritance, meaning that it passes through all unused kwargs in the init to the next class in the MRO via super. Parameters ---------- potential : potential.Potential The potential between all pairs of units in different composite objects. lifting : lifting.Lifting The lifting scheme. charge : str or None, optional The charge this event handler passes to the potential. If None, the potential just gets one as the charges. kwargs : Any Additional kwargs which are passed to the __init__ method of the next class in the MRO. Raises ------ base.exceptions.ConfigurationError If the number of nodes per root node is one and therefore no composite objects are present in the run. base.exceptions.ConfigurationError If the potential expects more than one separation. base.exceptions.ConfigurationError If the charge is not None but the potential expects more than two charges. """ super().__init__(potential=potential, **kwargs) self._lifting = lifting if not setting.number_of_nodes_per_root_node > 1: raise ConfigurationError("Class {0} can only be used when composite point objects are present!" .format(self.__class__.__name__)) if self._potential.number_separation_arguments != 1: raise ConfigurationError("The event handler {0} expects a potential " "which handles exactly one separation!".format(self.__class__.__name__)) if charge is None: self._potential_charges = (lambda unit_one, unit_two: tuple(1.0 for _ in range(self._potential.number_charge_arguments))) else: if self._potential.number_charge_arguments == 2: self._potential_charges = lambda unit_one, unit_two: (unit_one.charge[charge], unit_two.charge[charge]) else: raise ConfigurationError("The event handler {0} was initialized with a charge which is not None," " but its potential {1} " "expects not exactly 2 charges." .format(self.__class__.__name__, self._potential.__class__.__name__))
def __init__(self, potential: Potential, lifting: Lifting, offset: float, max_displacement: float, separations: Sequence[int]) -> None: """ The constructor of the FixedSeparationsEventHandlerWithPiecewiseConstantBoundingPotential class. Parameters ---------- potential : potential.Potential The potential between the leaf units. lifting : lifting.Lifting The lifting scheme. offset : float The offset used to create piecewise constant bounding potential. max_displacement : float The maximum time displacement used to create piecewise constant bounding potential. separations : Sequence[int] A sequence of integers in the format [i1, j1, i2, j2...in, jn]. The separations passed to the potential will be [r_j1 - r_i1, r_j2 - r_i2, ..., r_jn - r_in]. Raises ------ base.exceptions.ConfigurationError: If the separations sequence is not divisible by two. base.exceptions.ConfigurationError: If the number of separations which can be constructed from the separations sequence does not equal the number of separation arguments of the potential. """ log_init_arguments(logging.getLogger(__name__).debug, self.__class__.__name__, potential=potential.__class__.__name__, lifting=lifting.__class__.__name__, offset=offset, max_displacement=max_displacement, separations=separations) super().__init__(potential=potential, offset=offset, max_displacement=max_displacement) self._lifting = lifting self._separations = separations if len(self._separations) % 2 != 0: raise ConfigurationError("The given array of indices {0} which should be used to calculate the separations" " handed over to the potential is not divisible by two!".format(separations)) if self._potential.number_separation_arguments != len(self._separations) // 2: raise ConfigurationError("The event handler {0} expects a potential " "which handles exactly the number of separations specified" " by the list of identifiers {1} used to calculate these separations" " (length of the list divided by 2)!" .format(self.__class__.__name__, self._separations)) # The charges the potential expects will always be set to 1.0 self._number_charges = self._potential.number_charge_arguments