particle_monitor module

Define ParticleMonitor.

This dictionary-based object holds Particle objects. Keys of the dictionary are the particle id of the Particle.

Todo

Raise error when folder is not found.

_load_particle_monitor_file(filepath, delimiter=None)[source]

Load a single Particle Monitor file.

A Particle Monitor file holds the ID, position, momentum of every particle alive at a specific time.

Todo

Type hints could be cleaner.

Parameters:
  • filepath (Path)

  • delimiter (str | None, default: None)

Return type:

tuple[tuple[str, str, str, str, str, str, str, str, str, str, str, str], ...]

class ParticleMonitor(dict_of_parts, max_time, stl_path=None, stl_alpha=None, plotter=None, **kwargs)[source]

Bases: dict

Holds all Particle objects as values, particle id as keys.

max_time

Time at which the simulation ended.

Parameters:
FILTERS: dict[str, Callable[[Particle], bool]] = {   '_default': <function ParticleMonitor.<lambda> at 0x756088fa9ee0>,     'collision': <function ParticleMonitor.<lambda> at 0x75608892e8e0>,     'emitted': <function ParticleMonitor.<lambda> at 0x75608892e840>,     'no collision': <function ParticleMonitor.<lambda> at 0x75608892e980>,     'seed': <function ParticleMonitor.<lambda> at 0x75608892e7a0>}
__init__(dict_of_parts, max_time, stl_path=None, stl_alpha=None, plotter=None, **kwargs)[source]

Create the object, ordered list of filepaths beeing provided.

Also handle mesh related operations: collision/emission angles calculation.

Parameters:
  • dict_of_parts (dict[int, Particle]) – Dictionary which values are Particle instances and keys are the associated unique ID.

  • max_time (float) – Simulation end time. Used to determine which particles were alive at the end of the simulation.

  • stl_path (str | Path | None, default: None) – Path to the structure mesh. In particular, used to compute the collision and emission angles.

  • stl_alpha (float | None, default: None) – Mesh transparency setting.

  • plotter (Plotter | None, default: None) – Object to create the plots.

classmethod from_folder(folder, delimiter=None, stl_path=None, stl_alpha=None, plotter=None, load_first_n_particles=None, particle_monitor_ignore=('.swp',), **kwargs)[source]

Load all the particle monitor files and create object.

Parameters:
  • folder (str | Path) – Where all the CST particle monitor files are stored.

  • delimiter (str | None, default: None) – Delimiter between columns.

  • stl_path (str | Path | None, default: None) – Path to the mesh file, saved as STL.

  • stl_alpha (float | None, default: None) – Transparency for the 3D mesh.

  • plotter (Plotter | None, default: None) – Object realizing the plots.

  • load_first_n_particles (int | None, default: None) – To only load the first particles that are found in the folder.

  • particle_monitor_ignore (Collection[str], default: ('.swp',)) – File extensions to skip when exploring the particle monitor folder.

Returns:

particle_monitor – Instantiated object.

Return type:

ParticleMonitor

property seed_electrons: dict[int, Particle]

Return only seed electrons.

property emitted_electrons: dict[int, Particle]

Return only emitted electrons.

__str__()[source]

Resume information on the simulation.

Return type:

str

emission_energies(source_id=None)[source]

Get emission energies of all or only a subset of particles.

Parameters:

source_id (int | None, default: None)

Return type:

ndarray[tuple[Any, ...], dtype[float64]]

collision_energies(source_id=None, extrapolation=True, remove_alive_at_end=True)[source]

Get all collision energies in \(\mathrm{eV}\).

Parameters:
  • source_id (int | None, optional) – If set, we only take particles which source_id is source_id. The default is None.

  • extrapolation (bool, optional) – If True, we extrapolate over the last time steps to refine the collision energy. Otherwise, we simply take the last known energy of the particle. The default is True.

  • remove_alive_at_end (bool, optional) – To remove particles alive at the end of the simulation (did not impact a wall). The default is True.

Return type:

ndarray[tuple[Any, ...], dtype[float64]]

emission_angles(source_id=None, extrapolation=True)[source]

Get all emission angles in \(\mathrm{deg}\).

Parameters:
  • source_id (int | None, optional) – If set, we only take particles which source_id is source_id. The default is None.

  • extrapolation (bool, optional) – If True, we extrapolate over the last time steps to refine the collision energy. Otherwise, we simply take the last known energy of the particle. The default is True.

  • remove_alive_at_end (bool, optional) – To remove particles alive at the end of the simulation (did not impact a wall). The default is True.

Returns:

out – Emission angles in degrees.

Return type:

NDArray[np.float64]

collision_angles(source_id=None, remove_alive_at_end=True)[source]

Get all collision angles in \(\mathrm{deg}\).

Parameters:
  • source_id (int | None, default: None) – If set, we only take particles which source_id is source_id. The default is None.

  • remove_alive_at_end (bool, default: True) – To remove particles alive at the end of the simulation (did not impact a wall). The default is True.

Return type:

ndarray[tuple[Any, ...], dtype[float64]]

last_known_position(source_id=None, remove_alive_at_end=True)[source]

Get the last recorded position of every particle.

Parameters:
  • source_id (int | None, optional) – If set, we only take particles which source_id is source_id. The default is None.

  • to_numpy (bool, optional) – If True, output list is transformed to an array. The default is True.

  • remove_alive_at_end (bool, optional) – To remove particles alive at the end of the simulation (did not impact a wall). The default is True.

Returns:

out – Last known position in \(\mathrm{mm}\) of every particle.

Return type:

NDArray[np.float64]

last_known_direction(source_id=None, normalize=True, remove_alive_at_end=True)[source]

Get the last recorded direction of every particle.

Todo

Why did I choose to compute position difference rather than just taking the momentum array when not normalizing???

Parameters:
  • source_id (int | None, optional) – If set, we only take particles which source_id is source_id. The default is None.

  • normalize (bool, optional) – To normalize the direction vector. The default is True.

  • remove_alive_at_end (bool, optional) – To remove particles alive at the end of the simulation (did not impact a wall). The default is True.

Returns:

out – Last known moment vector of every particle.

Return type:

NDArray[np.float64]

compute_collision_angles(mesh, **kwargs)[source]

Find all collisions.

Parameters:

mesh (Mesh)

Return type:

None

hist(x, bins=200, hist_range=None, plotter=None, filter=None, title=None, **kwargs)[source]

Create a histogram.

Parameters:
  • x (Literal['emission_energy', 'collision_energy', 'collision_angle']) – Name of the data to plot.

  • bins (int, default: 200) – Number of histogram bins.

  • hist_range (tuple[float, float] | None, default: None) – Lower and upper value for the histogram.

  • plotter (Plotter | None, default: None) – Object creating the plots.

  • filter (Union[Literal['seed', 'emitted', 'collision', 'no collision'], Callable[[Particle], bool], None], default: None) – To plot only some of the particles.

  • title (str | None, default: None) – Figure title. If not provided, we take a default according to the value of filter.

Return type:

Any

plot_mesh(plotter=None, *args, **kwargs)[source]

Plot the stored mesh.

Parameters:

plotter (Plotter | None, default: None)

Return type:

Any

plot_trajectories(emission_color=None, collision_color=None, lw=7, r=8, plotter=None, filter=None, **kwargs)[source]

Plot trajectories in 3D.

Parameters:
  • emission_color (str | None, default: None) – If provided, the first known position is colored with this color.

  • collision_color (str | None, default: None) – If provided, the last known position is colored with this color.

  • collision_point – If provided and collision_color is not None, we plot this point instead of the last of points. This is useful when the extrapolated time is large, and actuel collision point may differ significantly from last position points.

  • lw (int, default: 7) – Trajectory line width.

  • r (int, default: 8) – Size of the emission/collision points.

  • plotter (Plotter | None, default: None) – An object allowing to plot data.

  • filter (Union[Literal['seed', 'emitted', 'collision', 'no collision'], Callable[[Particle], bool], None], default: None) – To select the particles to be plotted.

Return type:

Any

property to_list: list[Particle]

Return stored Particle as a list.

to_pandas(*args, filter=None)[source]
Parameters:
  • args (Literal['emission_energy', 'collision_energy', 'collision_angle'])

  • filter (Union[Literal['seed', 'emitted', 'collision', 'no collision'], Callable[[Particle], bool], None], default: None)

Return type:

DataFrame

filter_particles(filter)[source]

Return a list of particles that match the given criterion.

Parameters:

filter (Union[Literal['seed', 'emitted', 'collision', 'no collision'], Callable[[Particle], bool], None])

Return type:

list[Particle]

_load_mesh(stl_path, stl_alpha=None, **kwargs)[source]

Load the STL file with self._plotter.load_mesh().

Parameters:
Return type:

Mesh

_absolute_file_paths(directory, particle_monitor_ignore=('.swp',))[source]

Get all filepaths in absolute from dir, remove unwanted files.

Parameters:
  • directory (Path) – Folder to explore.

  • particle_monitor_ignore (Collection[str], default: ('.swp',)) – Extensions to skip.

Return type:

Generator[Path, Path, None]

_get_float_from_filename(filename)[source]

Extract the float value from the filename.

Parameters:

filename (Path) – Filename, looking like position  monitor 1_0.117175810039043.txt

Return type:

float

_sorted_particle_monitor_files(directory, particle_monitor_ignore=('.swp',))[source]

Recursively get and sort all particle monitor files.

Typical structure is:

directory
├──'position  monitor 1_0.117175810039043.txt'
├──'position  monitor 1_0.156234413385391.txt'
├──'position  monitor 1_0.19529302418232.txt'
├──'position  monitor 1_0.232905015349388.txt'
├──'position  monitor 1_0.271963626146317.txt'
├──...
└──'position  monitor 1_7.81172066926956E-02.txt'
Parameters:
  • directory (Path) – Folder to explore.

  • particle_monitor_ignore (Collection[str], default: ('.swp',)) – Extensions to skip.

Return type:

tuple[list[Path], float]

Returns:

  • files (list[Path]) – The sorted filepaths.

  • max_time (float) – Highest time among provided files.

_filter_source_id(input_dict, wanted_id)[source]

Filter Particles against the sourceID field.

Parameters:
Return type:

dict[int, Particle]

_filter_out_dead_at_end(input_dict)[source]

Filter out Particles that collisioned during simulation.

Parameters:

input_dict (dict[int, Particle])

Return type:

dict[int, Particle]

_filter_out_alive_at_end(input_dict)[source]

Filter out Particles that were alive at the end of simulation.

Parameters:

input_dict (dict[int, Particle])

Return type:

dict[int, Particle]

_filter_out_part_with_one_time_step(input_dict)[source]

Remove particle with only one known position.

This is useful when the time resolution is low.

Parameters:

input_dict (dict[int, Particle])

Return type:

dict[int, Particle]