Skip to content

Controller

rionid.gui.controller

display_nions(nions, yield_data, nuclei_names, simulated_data_dict, ref_ion, harmonics)

Filters the simulated data to retain only the top N ions based on yield.

This function modifies the simulated_data_dict in-place. It ensures that the Reference Ion is always included in the list, even if its yield is low.

Parameters:

Name Type Description Default
nions int

The number of ions to keep.

required
yield_data array - like

Array of yield values for all simulated ions.

required
nuclei_names array - like

Array of ion names corresponding to the yield data.

required
simulated_data_dict dict

Dictionary mapping harmonic numbers to simulation arrays.

required
ref_ion str

The name of the reference ion (e.g., '72Ge+35').

required
harmonics list of float

The list of harmonics being simulated.

required
Source code in src/rionid/gui/controller.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def display_nions(nions, yield_data, nuclei_names, simulated_data_dict, ref_ion, harmonics):
    """
    Filters the simulated data to retain only the top N ions based on yield.

    This function modifies the `simulated_data_dict` in-place. It ensures that
    the Reference Ion is always included in the list, even if its yield is low.

    Parameters
    ----------
    nions : int
        The number of ions to keep.
    yield_data : array-like
        Array of yield values for all simulated ions.
    nuclei_names : array-like
        Array of ion names corresponding to the yield data.
    simulated_data_dict : dict
        Dictionary mapping harmonic numbers to simulation arrays.
    ref_ion : str
        The name of the reference ion (e.g., '72Ge+35').
    harmonics : list of float
        The list of harmonics being simulated.
    """
    # 1. Get indices of the top N ions
    sorted_indices = argsort(yield_data)[::-1][:nions]

    # 2. Find the index of the reference ion
    ref_index = where(nuclei_names == ref_ion)[0]

    # 3. FIX: Check if ref_index is not empty AND if the scalar index is missing
    if ref_index.size > 0 and ref_index[0] not in sorted_indices:
        sorted_indices = append(sorted_indices, ref_index[0])

    # 4. Filter the names
    nuclei_names = nuclei_names[sorted_indices]

    # 5. Filter the simulated data for each harmonic
    for harmonic in harmonics:
        name = f"{harmonic}"
        if name in simulated_data_dict:
            simulated_data_dict[name] = simulated_data_dict[name][sorted_indices]

import_controller(datafile=None, filep=None, alphap=None, refion=None, harmonics=None, nions=None, amplitude=None, circumference=None, mode=None, value=None, reload_data=None, highlight_ions=None, io_params=None, sim_scalingfactor=None, correct=None)

Main orchestration function for the RionID simulation workflow.

This function acts as the bridge between the GUI/CLI inputs and the physics core. It initializes the ImportData model, loads experimental data, performs the physics calculations (mass-to-charge, revolution frequencies), runs the simulation, and saves the results to disk.

Parameters:

Name Type Description Default
datafile str

Path to the experimental data file (.npz, .csv, .root, etc.).

None
filep str

Path to the particle list file (e.g., LISE++ .lpp output).

None
alphap float

Momentum compaction factor of the ring. If the value provided is > 1, it is treated as Gamma Transition (gamma_t) and converted automatically via alphap = 1 / gamma_t^2.

None
refion str

The reference ion string in the format 'AAEl+QQ' (e.g., '72Ge+35').

None
harmonics str or list of float

Harmonic numbers to simulate. Can be a list or a space/comma-separated string.

None
nions int

If provided, filters the output to show only the top nions species sorted by yield (plus the reference ion).

None
amplitude int

Display option for spectral lines (0 for constant height, 1 for scaled).

None
circumference float

Ring circumference in meters.

None
mode str

The operation mode. Options: 'Frequency', 'Brho', 'Kinetic Energy', 'Gamma'.

None
value float

The numerical value corresponding to the selected mode (e.g., the reference frequency in Hz if mode is 'Frequency').

None
reload_data bool

If True, reloads experimental data from the raw file; otherwise loads from the cached .npz.

None
highlight_ions str

Comma-separated string of ion names to highlight in the plot (e.g., '72Ge+35, 74Se+34').

None
io_params dict

Dictionary containing specific I/O parameters (e.g., keys for NPZ files, histogram names for ROOT files).

None
sim_scalingfactor float

Factor to scale the simulated yield/amplitude.

None
correct list of float

Coefficients [a0, a1, a2] for a second-order polynomial correction applied to the simulated frequencies.

None

Returns:

Type Description
ImportData

The populated data model object containing simulation results and experimental data.

Exception

Returns the exception object if an error occurs during processing.

Source code in src/rionid/gui/controller.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def import_controller(
    datafile=None,
    filep=None,
    alphap=None,
    refion=None,
    harmonics=None,
    nions=None,
    amplitude=None,
    circumference=None,
    mode=None,
    value=None,
    reload_data=None,
    highlight_ions=None,
    io_params=None,
    sim_scalingfactor=None,
    correct=None,
):
    """
    Main orchestration function for the RionID simulation workflow.

    This function acts as the bridge between the GUI/CLI inputs and the physics core.
    It initializes the `ImportData` model, loads experimental data, performs the
    physics calculations (mass-to-charge, revolution frequencies), runs the
    simulation, and saves the results to disk.

    Parameters
    ----------
    datafile : str, optional
        Path to the experimental data file (.npz, .csv, .root, etc.).
    filep : str, optional
        Path to the particle list file (e.g., LISE++ .lpp output).
    alphap : float, optional
        Momentum compaction factor of the ring. If the value provided is > 1,
        it is treated as Gamma Transition (gamma_t) and converted automatically
        via `alphap = 1 / gamma_t^2`.
    refion : str, optional
        The reference ion string in the format 'AAEl+QQ' (e.g., '72Ge+35').
    harmonics : str or list of float, optional
        Harmonic numbers to simulate. Can be a list or a space/comma-separated string.
    nions : int, optional
        If provided, filters the output to show only the top `nions` species
        sorted by yield (plus the reference ion).
    amplitude : int, optional
        Display option for spectral lines (0 for constant height, 1 for scaled).
    circumference : float, optional
        Ring circumference in meters.
    mode : str, optional
        The operation mode. Options: 'Frequency', 'Brho', 'Kinetic Energy', 'Gamma'.
    value : float, optional
        The numerical value corresponding to the selected `mode` (e.g., the
        reference frequency in Hz if mode is 'Frequency').
    reload_data : bool, optional
        If True, reloads experimental data from the raw file; otherwise loads
        from the cached .npz.
    highlight_ions : str, optional
        Comma-separated string of ion names to highlight in the plot (e.g., '72Ge+35, 74Se+34').
    io_params : dict, optional
        Dictionary containing specific I/O parameters (e.g., keys for NPZ files,
        histogram names for ROOT files).
    sim_scalingfactor : float, optional
        Factor to scale the simulated yield/amplitude.
    correct : list of float, optional
        Coefficients [a0, a1, a2] for a second-order polynomial correction
        applied to the simulated frequencies.

    Returns
    -------
    ImportData
        The populated data model object containing simulation results and
        experimental data.
    Exception
        Returns the exception object if an error occurs during processing.
    """
    try:
        # initializations
        if float(alphap) > 1:
            alphap = 1 / float(alphap) ** 2  # handling alphap and gammat
        fref = brho = ke = gam = None
        if mode == "Frequency":
            fref = float(value)
        elif mode == "Brho":
            brho = float(value)
        elif mode == "Kinetic Energy":
            ke = float(value)
        elif mode == "Gamma":
            gam = float(value)
        # Calculations
        mydata = ImportData(
            refion,
            float(alphap),
            filename=datafile,
            reload_data=reload_data,
            circumference=circumference,
            highlight_ions=highlight_ions,
            io_params=io_params,
        )

        mydata._set_particles_to_simulate_from_file(filep)
        mydata._calculate_moqs()
        mydata._calculate_srrf(fref=fref, brho=brho, ke=ke, gam=gam, correct=correct)

        if isinstance(harmonics, str):
            harmonics = [float(h.strip()) for h in harmonics.replace(",", " ").split()]
        elif not isinstance(harmonics, list):
            harmonics = [float(harmonics)]

        mydata._simulated_data(
            brho=brho,
            harmonics=harmonics,
            mode=mode,
            sim_scalingfactor=sim_scalingfactor,
            nions=nions,
        )
        # "Outputs"
        if nions:
            display_nions(
                int(nions),
                mydata.yield_data,
                mydata.nuclei_names,
                mydata.simulated_data_dict,
                refion,
                harmonics,
            )

        logger.info(
            "Simulation results (ordered by frequency) will be saved to simulation_result.out"
        )
        sort_index = argsort(mydata.srrf)
        # Save the results to a file with the specified format
        save_simulation_results(mydata, mode, harmonics, sort_index)
        logger.info("Succesfully saved!")

        return mydata  # Returns the simulated spectrum data

    except Exception as e:
        print(f"Error during calculations: {str(e)}")
        raise e

save_simulation_results(mydata, mode, harmonics, sort_index, filename='simulation_result.out')

Saves the simulation results to a formatted text file.

Writes a table containing Ion Name, Frequency, Yield, m/q, and Mass for every simulated ion, sorted according to sort_index.

Parameters:

Name Type Description Default
mydata ImportData

The data object containing the calculated physics results (srrf, moq, etc.).

required
mode str

The simulation mode ('Frequency', 'Brho', etc.) used to determine how absolute frequencies are calculated.

required
harmonics list of float

The list of harmonics used in the simulation.

required
sort_index array - like

Indices used to sort the output (typically sorted by frequency).

required
filename str

The output filename. Default is 'simulation_result.out'.

'simulation_result.out'
Source code in src/rionid/gui/controller.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
def save_simulation_results(mydata, mode, harmonics, sort_index, filename="simulation_result.out"):
    """
    Saves the simulation results to a formatted text file.

    Writes a table containing Ion Name, Frequency, Yield, m/q, and Mass for
    every simulated ion, sorted according to `sort_index`.

    Parameters
    ----------
    mydata : ImportData
        The data object containing the calculated physics results (srrf, moq, etc.).
    mode : str
        The simulation mode ('Frequency', 'Brho', etc.) used to determine how
        absolute frequencies are calculated.
    harmonics : list of float
        The list of harmonics used in the simulation.
    sort_index : array-like
        Indices used to sort the output (typically sorted by frequency).
    filename : str, optional
        The output filename. Default is 'simulation_result.out'.
    """
    with open(filename, "w") as file:
        # Writing harmonics and brho information
        brho = mydata.brho
        for harmonic in harmonics:
            header0 = f"Harmonic: {harmonic} , Bp: {brho:.6f} [Tm]"
            logger.info(header0)
            file.write(header0 + "\n")

        # Writing the header for the data table
        header1 = f"{'ion':<15}{'fre[Hz]':<30}{'yield [pps]':<15}{'m/q [u]':<15}{'m [eV]':<15}"
        file.write(header1 + "\n")
        file.write("-" * len(header1) + "\n")
        logger.info(header1)

        # Writing the sorted simulation results
        for i in sort_index:
            ion = mydata.nuclei_names[i]
            if mode == "Frequency":
                fre = mydata.srrf[i] * mydata.ref_frequency
            elif mode == "Brho":
                fre = mydata.srrf[i] * mydata.ref_frequency * harmonic  # pyright: ignore[reportPossiblyUnboundVariable]
            yield_ = mydata.yield_data[i]
            moq = mydata.moq[ion]
            mass_u = mydata.total_mass[ion]
            mass = AMEData.to_mev(mass_u) * 1e6
            result_line = f"{ion:<15}{fre:<30.10f}{yield_:<15.4e}{moq:<15.12f}{mass:<15.3f}"  # pyright: ignore[reportPossiblyUnboundVariable]
            logger.info(result_line)
            file.write(result_line + "\n")