Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

pmagpy.rockmag API Reference

ANOVA

ANOVA(xs, ys)

ANOVA statistics for linear regression

Parameters

Returns


Fabian_nonlinear_fit

Fabian_nonlinear_fit(H, chi_HF, Ms, alpha, beta)

function for calculating the Fabian non-linear fit

Parameters

Returns


IRM_nonlinear_fit

IRM_nonlinear_fit(H, chi_HF, Ms, a_1, a_2)

Calculate the non-linear fit for Isothermal Remanent Magnetization (IRM) as a function of applied field.

This function models the IRM signal as a sum of high-field linear susceptibility, saturation magnetization, and non-linear correction terms with inverse field dependence. The model is commonly used for fitting high-field IRM data, especially for extracting parameters such as high-field susceptibility (chi_HF) and saturation magnetization (Ms).

Parameters

Returns

Examples

>>> H = np.linspace(0.1, 3, 100)  # field in Tesla, avoid zero for stability
>>> fit = IRM_nonlinear_fit(H, chi_HF=0.02, Ms=1.2, a_1=-0.03, a_2=-0.01)
>>> import matplotlib.pyplot as plt
>>> plt.plot(H, fit)
>>> plt.xlabel('Field (T)')
>>> plt.ylabel('IRM fit')
>>> plt.show()

Langevin

Langevin(alpha)

Langevin function

Parameters

Returns


Me_drift_correction

Me_drift_correction(H, M, descending_first=True)

Perform default IRM drift correction for a hysteresis loop based on the Me method.

This function applies a drift correction algorithm to magnetization data (M) measured as a function of applied field (H), commonly used for IRM (Isothermal Remanent Magnetization) experiments. The correction is based on the Me signal, which is the sum of the upper and reversed lower branches of the hysteresis loop. The correction method adapts depending on whether significant drift is detected in the high-field region.

The drift estimate depends on measurement-time order, and the arrays are expected in canonical order (descending upper branch first, as produced by grid_hyst_loop). For a loop originally measured from negative saturation, pass descending_first=False (detected from the raw field values with measured_descending_first) so the correction is applied in true time order rather than with the opposite time sense.

Parameters

Returns

Examples

>>> H = np.linspace(-1, 1, 200)
>>> M = measure_hysteresis(H)
>>> M_cor = Me_drift_correction(H, M)
>>> plot(H, M, label='Original')
>>> plot(H, M_cor, label='Drift Corrected')

SD_MD_mixture

SD_MD_mixture(Mr_Ms_SD=0.5, Mr_Ms_MD=0.019, Bc_SD=400, Bc_MD=43, Bcr_SD=500, Bcr_MD=230, X_sd=0.6, X_MD=0.209, Xr_SD=0.48, Xr_MD=0.039)

function to calculate the SD/MD mixture curve according to Dunlop (2002)

Parameters

Returns


SP_SD_mixture

SP_SD_mixture(SP_size, SD_Mr_Ms=0.5, SD_Bcr_Bc=1.25, X_sd=3, T=300)

function to calculate the SP/SD mixture curve according to Dunlop (2002)

Parameters

Returns


SP_saturation_curve

SP_saturation_curve(SD_Mr_Ms=0.5, SD_Bcr_Bc=1.25)

function to calculate the SP saturation curve according to Dunlop (2002)

Parameters

Returns


add_Bcr_to_specimens_table

add_Bcr_to_specimens_table(specimens_df, experiment_name, Bcr)

Add the Bcr value to the MagIC specimens table the controled vocabulary for backfield derived Bcr is rem_bcr

Parameters


add_curie_estimates_to_specimens_table

add_curie_estimates_to_specimens_table(specimens_df, experiment_name, estimates, method='inflection', branch='heating', critical_temp_type='Curie')

Write a Curie temperature estimate to a MagIC specimens table.

Sets critical_temp (in Kelvin, per the MagIC data model) and critical_temp_type (controlled vocabulary; ‘Curie’ by default) for the rows whose experiments column matches experiment_name, and records the estimation method, branch, and uncertainty in the description column so the processing choice is archived with the result. Updates specimens_df in place.

Parameters


add_hyst_stats_to_specimens_table

add_hyst_stats_to_specimens_table(specimens_df, hyst_results, overwrite=True)

Return a copy of the specimens table with hysteresis results added.

The input DataFrame is not modified. Assign the return value to update your table, e.g.: specimens = add_hyst_stats_to_specimens_table(specimens, hyst_results)

Parameters

Returns


add_unmixing_to_specimens_table

add_unmixing_to_specimens_table(specimens_df, components_df, mode='rows')

Record coercivity unmixing results in a MagIC specimens table.

Two recording conventions are supported:

Parameters

Returns


aggregate_by_class

aggregate_by_class(components, boundaries_mT, class_names=None, coercivity_column='B_mean_mT', proportion_column='proportion', contribution_column='contribution', curve_factor=2.0, group_column='experiment', passthrough=('specimen', 'Bcr_mT', 'r_squared'))

Aggregate fitted unmixing components into coercivity classes.

Sums each component’s remanence proportion (and, if available, its contribution) into classes defined by one or more coercivity cut points, per experiment. This is the robust way to quantify a mineral assemblage from an unmixing fit: because it integrates the fitted distribution within coercivity bands, the result is insensitive to how many components the optimizer used or how it split a single mineral, so long as the mineral populations are separated by the cut points. Typical use is a magnetite/hematite split at a single boundary, but any number of classes is supported.

Parameters

Returns


build_symmetric_hyst_grid

build_symmetric_hyst_grid(upper_branch, lower_branch)

Build a symmetric field grid over the overlap shared by the two loop branches.


calc_Bc

calc_Bc(H, M)

function for calculating the coercivity of the ferromagnetic component of a hysteresis loop the final Bc value is calculated as the average of the positive and negative Bc values

Parameters

Returns


calc_Mr_Mrh_Mih_Brh

calc_Mr_Mrh_Mih_Brh(grid_field, grid_magnetization)

function to calculate the Mrh and Mih values from a hysteresis loop

Parameters

Returns


calc_Q

calc_Q(H, M, type='Q')

Calculate the quality factor (Q) for a magnetic hysteresis loop.

The Q factor is a logarithmic measure (base 10) of the signal-to-noise ratio for a hysteresis loop, following Jackson and Solheid (2010): the upper and inverted lower branches are treated as replicate measurements, so their mean squared moment relative to the mean squared mismatch between them (the err(H) curve) quantifies signal/noise. Q = log10(s/n); loops with Q >= 2 have small deviations from inversion symmetry while loops with Q below ~0.3 (s/n ~ 2) are too noisy for meaningful parameter estimation. The quality factor of the ferromagnetic component (Q_f of Jackson and Solheid, 2010) is obtained by calling this function on the slope-corrected loop.

The calculation can be performed in two modes: - ‘Q’: Uses the mean squared magnetization of both the upper and lower branches. - ‘Qf’: Uses only the upper branch.

Parameters

Returns

Notes

Examples

>>> H = np.linspace(-1, 1, 200)
>>> M = np.tanh(3 * H) + 0.05 * np.random.randn(200)
>>> M_sn, Q = calc_Q(H, M, type='Q')
>>> print(f"Signal-to-noise ratio: {M_sn:.3f}, Q: {Q:.2f}")

calc_verwey_estimate

calc_verwey_estimate(temps, mags, t_range_background_min=50, t_range_background_max=250, excluded_t_min=75, excluded_t_max=150, poly_deg=3)

Estimate the Verwey transition temperature and remanence loss of magnetite from MPMS data. Plots the magnetization data, background fit, and resulting magnetite curve, and optionally the zero-crossing.

Parameters


calc_zero_crossing

calc_zero_crossing(dM_dT_temps, dM_dT)

Calculate the temperature at which the second derivative of magnetization with respect to temperature crosses zero. This value provides an estimate of the peak of the derivative curve that is more precise than the maximum value.

The function computes the second derivative of magnetization (dM/dT) with respect to temperature, identifies the nearest points around the maximum value of the derivative, and then calculates the temperature at which this second derivative crosses zero using linear interpolation.

Parameters: dM_dT_temps (pd.Series): A pandas Series representing temperatures corresponding to the first derivation of magnetization with respect to temperature. dM_dT (pd.Series): A pandas Series representing the first derivative of magnetization with respect to temperature. Returns: float: The estimated temperature at which the second derivative of magnetization with respect to temperature crosses zero.

Note: The function assumes that the input series dM_dT_temps and dM_dT are related to each other and are of equal length.


chi_SP

chi_SP(SP_size, T)

SP size distribution function

Parameters

Returns


clean_out_na

clean_out_na(dataframe)

Cleans a DataFrame by removing columns and rows that contain only NaN values.

Args: dataframe (pd.DataFrame): The DataFrame to be cleaned. Returns: pd.DataFrame: A cleaned DataFrame with all-NaN columns and rows removed.


coercivity_curve_components

coercivity_curve_components(x, parameters, curve_type='backfield')

Evaluate each component in measurement space (cumulative curves).

For ‘backfield’ curves (processed so that magnetization decays from a maximum toward zero with increasing field magnitude) each component is contribution * (1 - CDF); for ‘acquisition’ curves each component is contribution * CDF.

Parameters

Returns


coercivity_curve_model

coercivity_curve_model(x, parameters, offset=0.0, curve_type='backfield')

Evaluate the summed unmixing model in measurement space.

Parameters

Returns


coercivity_prior_table

coercivity_prior_table(minerals=None)

Summarize the coercivity-component prior library as a table.

Parameters

Returns


coercivity_spectrum_components

coercivity_spectrum_components(x, parameters)

Evaluate each unmixing component in spectrum space (dM/dlog10 B).

Parameters

Returns


coercivity_spectrum_from_curve

coercivity_spectrum_from_curve(x, magnetization, curve_type='backfield')

Compute a finite-difference coercivity spectrum from a remanence curve.

Parameters

Returns


coercivity_spectrum_model

coercivity_spectrum_model(x, parameters)

Evaluate the summed unmixing model in spectrum space.

Parameters

Returns


coercivity_unmixing_interactive

coercivity_unmixing_interactive(x, magnetization, n_components=2, method='spectrum', curve_type='backfield', vary_skew=True, figsize=(9, 5))

Interactive widget for choosing initial unmixing parameters visually.

Initial parameter choices strongly influence nonlinear unmixing fits. This widget shows the coercivity spectrum with a live model built from per-component sliders (peak field in mT on a log scale, proportion of the total remanence, dispersion DP, and skew). Sliders are seeded from automatic peak detection. Pressing “Fit” runs the chosen optimizer (spectrum- or measurement-space) starting from the current slider values and overlays the optimized model.

Important: run %matplotlib widget in the notebook first so the figure updates live.

Parameters

Returns


collapse_hyst_field_plateaus

collapse_hyst_field_plateaus(field, magnetization)

Average consecutive repeated field steps into a single point.


compare_unmixing_models

compare_unmixing_models(results)

Compare unmixing fits with different numbers of components.

Builds a comparison table with information criteria and sequential F-tests. All results must be fits of the same data with the same method (‘spectrum’ or ‘curve’); AIC/BIC values are only meaningful relative to one another under that condition. The F-test compares each model to the previous (simpler) one; a small p-value indicates the additional component produces a statistically significant improvement. As emphasized by Maxbauer et al. (2016) and Egli (2003), statistical significance alone should not decide the number of components -- independent knowledge of the likely magnetic mineralogy should inform the choice.

Parameters

Returns


convert_temperature

convert_temperature(temp_array, input_unit, output_unit)

Convert temperatures between Kelvin and Celsius.

Parameters

Returns

Raises


curie_Ms_squared_extrapolation

curie_Ms_squared_extrapolation(T, M, fit_range=None, exponent=2.0, min_points=5, min_m=None)

Mean-field (Moskowitz, 1981) extrapolation of Ms**exponent to zero.

Fits M**exponent linearly in temperature over fit_range and returns the x-intercept (where M**exponent = 0) as the Curie temperature. This is the extrapolation method of Moskowitz (1981, doi:10.1016/0012-821X(81)90028-5) for saturation-magnetization (Ms-T) thermomagnetic curves whose signal terminates below Tc — e.g. titanomaghemites that chemically invert on heating before Ms reaches zero, so a direct Ms = 0 crossing is unavailable.

Near Tc a second-order (mean-field / Landau-Belov) treatment gives Js proportional to (Tc - T)(1/2), so Js2 is linear in T and extrapolates to zero at Tc (Moskowitz, 1981, eqs. 4-5). This is the magnetization-space analog of the Curie-Weiss inverse-susceptibility method: there 1/chi rises linearly to a zero at theta; here Ms**2 falls linearly to a zero at Tc, so curie_temp = -intercept/slope with the slope required to be negative. (Moskowitz normalizes by Js0 = Js(T0); the normalization does not change the x-intercept and is omitted here.)

The mean-field form is valid for T/Tc > 0.8 (roughly the uppermost ~100 C below Tc), so restrict fit_range to the steep descent below where the curve flattens out or the sample alters; report the window. Following Moskowitz, exponent=2 (critical exponent beta = 1/2) is the theoretically justified, best-conditioned choice and minimized his fit error (+/-5 C) on standards (Fe3O4 572 C, Ni 360 C, CrO2 133 C). For a mean-field curve exponent=2 is exact; any other exponent introduces curvature into the fitted data and moves the extrapolated Tc off the true value. Moskowitz reported that a smaller exponent shifted Tc lower for his irreversible titanomaghemite samples; on ideal and mean-field curves a smaller exponent instead biases Tc high, so the direction of the bias depends on the true curve shape. For a multiphase sample only the Curie temperature of the highest-Tc phase is recovered.

Parameters

Returns


curie_derivative_estimates

curie_derivative_estimates(T, y, t_range=None, smooth_window=0)

Derivative-based Curie temperature estimates from one thermomagnetic branch.

Two estimates are returned:

Non-finite temperature or magnetization values are dropped before differentiation, and the steepest descent is located over the interior of the branch (the one-sided derivatives at the first and last points are the most noise-prone). Both estimates are anchored to that steepest-descent point, so isolated noise or structure in the flat tails does not capture them.

Differentiation amplifies noise, so even a smoothed signal can yield a ragged first derivative whose global minimum is a noise spike within a broad, flat-bottomed transition rather than the true steepest descent. Set smooth_window to smooth the first and second derivatives on the same temperature scale used to smooth the signal (as the legacy ipmag.curie does), which locates the estimate at the center of the transition instead of an arbitrary spike; curie_temperature_estimates passes its smoothing window through automatically. For multi-phase curves, additionally use t_range to isolate the transition of interest, and check the estimate against first_derivative_min_temp and the diagnostics arrays.

Parameters

Returns


curie_inverse_susceptibility

curie_inverse_susceptibility(T, chi, fit_range=None, min_points=5, min_chi=None)

Curie-Weiss (inverse susceptibility) estimate of the ordering temperature.

Above the Curie temperature the susceptibility of the paramagnetic phase follows the Curie-Weiss law chi = C / (T - theta), so 1/chi is linear in T and extrapolates to zero at the paramagnetic Curie temperature theta. A straight line is fit to 1/chi within fit_range and curie_temp = -intercept/slope is returned.

This is the recommended quantitative approach for low-field susceptibility X(T) curves (Petrovsky & Kapicka, 2006, doi:10.1029/2006JB004507). Two caveats apply: (1) theta is an upper bound on the Curie temperature (theta >= Tc, with the difference depending on the strength of magnetic interactions); (2) the estimate is sensitive to the choice of fitting window — the fit must be restricted to temperatures where the signal is fully paramagnetic, above the steep decrease, and where the (holder-corrected) susceptibility is still resolved above the instrument’s measurement resolution. Well above the transition the paramagnetic signal commonly becomes so weak that successive readings repeat identical values and 1/chi shows flat plateaus; including such quantized points flattens the fitted slope and biases theta low — a theta below an independently estimated Tc (e.g., the inflection point) is a red flag for this. The function detects repeated quantized values in the fitting window and attaches a warning; use min_chi or tighten fit_range to exclude resolution-limited points. Report the fitting window with the estimate.

Parameters

Returns


curie_inverse_susceptibility_interactive

curie_inverse_susceptibility_interactive(experiment, temperature_column='meas_temp', magnetic_column='susc_chi_mass', temp_unit='C', input_unit='K', smooth_window=0, remove_holder=True, branch='heating', initial_fit_range=None, figsize=(6, 6))

Interactive (Bokeh) Curie-Weiss fit to inverse susceptibility.

Displays 1/chi versus temperature with a two-point fit line whose endpoints can be dragged (Bokeh PointDrawTool); the extrapolated temperature where 1/chi reaches zero — the paramagnetic Curie temperature theta (Petrovsky & Kapicka, 2006, doi:10.1029/2006JB004507) — updates live below the plot.

This tool is for exploration: it helps identify the temperature interval over which 1/chi is linear (fully paramagnetic). For reported values, use curie_inverse_susceptibility with the fit_range identified here, so that the fit is reproducible.

Parameters

Returns

Raises


curie_landau_fit

curie_landau_fit(T, M, fit_range=None, temp_unit='C', tc_bounds=None, n_grid=40)

Fit the in-field Landau equation of state to a magnetization curve M(T).

The model is M(T) = M0 * m(tau; h) where m is the physical root of the Landau equation of state m**3 + tau*m = h with tau = (T - Tc)/Tc in absolute temperature (Fabian et al., 2013, doi:10.1029/2012GC004440, eqs. 3-5). The reduced field h rounds the transition and produces the field-induced tail above Tc, so the fit uses the full curve without an ad-hoc baseline. In the h = 0 limit the model is M = M0*sqrt(1 - T/Tc) below Tc — the mean-field form underlying the extrapolation method of Moskowitz (1981, doi:10.1016/0012-821X(81)90028-5).

The fit provides the physically grounded Curie temperature (at the inflection point of the in-field curve), with a formal 1-sigma uncertainty. When fit_range excludes the transition (all data below Tc), the fit operates in Moskowitz-style extrapolation mode: this is the only option for runs that end below Tc, but the reliability of the extrapolated Tc decays rapidly with the distance between the highest measured temperature and Tc, and the formal uncertainty then underestimates the true (model-dependence dominated) uncertainty.

Caveats: the model describes a single ferromagnetic phase near its transition; admixed paramagnetic signal, multiple phases, or alteration during heating violate it — restrict fit_range to isolate one transition. Applied to low-field susceptibility the model does not describe the dominant susceptibility mechanisms (see Fabian et al., 2013) and results should be treated as qualitative.

Parameters

Returns


curie_temperature_estimates

curie_temperature_estimates(experiment, methods=None, temperature_column='meas_temp', magnetic_column='susc_chi_mass', temp_unit='C', input_unit='K', smooth_window=0, remove_holder=True, branches=('heating', 'cooling'), method_kwargs=None, print_estimates=False, data_type=None, branch_data=None, return_method_results=False)

Estimate the Curie temperature of a thermomagnetic experiment with multiple methods and return a tidy comparison table.

The experiment is preprocessed with prepare_thermomag_branches and each requested method is applied to each requested branch. Systematic differences between the estimates are expected and diagnostic: see the module notes above and Lattard et al. (2006, doi:10.1029/2006JB004591) for the magnitude of inter-method offsets on synthetic titanomagnetites.

The available methods are:

Parameters

Returns


curie_two_tangent

curie_two_tangent(T, y, lower_range=None, upper_range=None, min_points=3)

Two-tangent (intersecting tangents) Curie temperature estimate.

Straight lines are fit to a segment of the steeply descending limb below the Curie temperature and to the near-flat baseline above it; the temperature of their intersection is returned. The construction follows Gromme et al. (1969, doi:10.1029/JB074i022p05277), who applied it to strong-field J-T curves.

Applicability and bias: the method is intended for magnetization curves M(T). Even there it coincides with the maximum-curvature estimate and therefore lies systematically above the inflection-point Curie temperature (Fabian et al., 2013, doi:10.1029/2012GC004440). Applied to low-field susceptibility X(T) it lacks a rigorous physical basis and can overestimate Tc (Petrovsky & Kapicka, 2006, doi:10.1029/2006JB004507); it remains a robust, transition-based estimator useful for mineral identification and for comparison with legacy results.

Parameters

Returns


estimate_coercivity_components

estimate_coercivity_components(x, spectrum, n_components, smooth_window=None)

Automatic initial-guess estimation for unmixing components.

The spectrum is interpolated onto a uniform grid, lightly smoothed (Savitzky-Golay), and searched for peaks. The n_components most prominent peaks seed the component locations; widths at half maximum seed dp; peak heights seed the contributions. If fewer peaks than components are found, the remaining components are placed at evenly spaced quantiles of the cumulative spectrum.

Initial choices matter for nonlinear fitting: these automatic estimates are a starting point that can (and often should) be refined by the user, e.g. with coercivity_unmixing_interactive.

Parameters

Returns


estimate_measurement_noise

estimate_measurement_noise(x, magnetization, curve_type='backfield')

Robustly estimate the measurement noise of a remanence curve.

Suppresses the smooth signal and returns a robust standard deviation of the residual scatter, without any smoothing or model fitting. This provides the noise scale needed to judge when an unmixing model fits “to within the measurement noise” (see select_n_components).

For each interior point the smooth signal is removed by comparing the point to the value predicted for it by cubic interpolation through its four nearest neighbours (two on each side) at their actual field positions; the residual is scaled by the standard deviation that combination would have under white noise, and a robust (median-absolute) scale is taken. Because the interpolation is exact for any polynomial of degree <= 3, this removes not just the local slope but the curvature of the sigmoidal curve, so the estimator is little biased even on the coarse and non-uniform (typically log-spaced) field grids of backfield/IRM measurements -- unlike a plain second difference, which cancels only a linear trend and inflates the noise where the curve bends.

Parameters

Returns


experiment_selection

experiment_selection(measurements, experiment_name)

This function filters a measurements DataFrame to return only the rows that correspond to the specified experiment name.

Parameters

Returns


extract_hyst_data

extract_hyst_data(df, specimen_name)

Extracts hysteresis loop data for a specific specimen from a dataframe.

This function filters measurements for a given specimen and returns rows whose MagIC method codes contain ‘LP-HYS’ (hysteresis loop experiments).

Parameters: df (pandas.DataFrame): The dataframe containing MagIC measurement data. specimen_name (str): The name of the specimen to filter data for.

Returns: pandas.DataFrame: Measurements for the specimen with ‘LP-HYS’ in their method codes (empty if none are present).

Example: >>> hyst_data = extract_hyst_data(measurements_df, ‘Specimen_1’)


extract_mpms_data_dc

extract_mpms_data_dc(measurements, specimen_name)

Extracts and separates MPMS data for a specified specimen from a DataFrame.

This function filters data for the given specimen and separates it based on MagIC measurement method codes. It specifically extracts data corresponding to ‘LP-FC’ (Field Cooled), ‘LP-ZFC’ (Zero Field Cooled), ‘LP-CW-SIRM:LP-MC’ (Room Temperature SIRM measured upon cooling), and ‘LP-CW-SIRM:LP-MW’ (Room Temperature SIRM measured upon Warming). For each method code, if the data is not available, an empty DataFrame with the same columns as the specimen data is returned.

Parameters: measurements (pd.DataFrame): DataFrame containing MPMS measurement data. specimen_name (str): Name of the specimen to filter data for.

Returns: tuple: A tuple containing four DataFrames: - fc_data: Data filtered for ‘LP-FC’ method if available, otherwise an empty DataFrame. - zfc_data: Data filtered for ‘LP-ZFC’ method if available, otherwise an empty DataFrame. - rtsirm_cool_data: Data filtered for ‘LP-CW-SIRM:LP-MC’ method if available, otherwise an empty DataFrame. - rtsirm_warm_data: Data filtered for ‘LP-CW-SIRM:LP-MW’ method if available, otherwise an empty DataFrame.


find_hyst_turning_point

find_hyst_turning_point(field)

Find the single loop reversal, tolerating repeated plateaus and minor field glitches.

Returns the index of the last point of the first field sweep, such that field[:index+1] is the first branch and field[index+1:] is the second branch. Zero field steps (plateaus from repeated field values) are ignored when detecting the reversal, and if field glitches produce multiple sign changes, the reversal closest to the global field extremum opposite the initial sweep direction is chosen.


goethite_removal

goethite_removal(rtsirm_warm_data, rtsirm_cool_data, t_min=150, t_max=290, poly_deg=2, rtsirm_cool_color='#17becf', rtsirm_warm_color='#d62728', symbol_size=4, return_data=False)

Analyzes and visualizes the removal of goethite signal from Room Temperature Saturation Isothermal Remanent Magnetization (RTSIRM) warming and cooling data. The function fits a polynomial to the RTSRIM warming curve between specified temperature bounds to model the goethite contribution, then subtracts this fit from the original data. The corrected and uncorrected magnetizations are plotted, along with their derivatives, to assess the effect of goethite removal.

Parameters: rtsirm_warm_data (pd.DataFrame): DataFrame containing ‘meas_temp’ and ‘magn_mass’ columns for RTSIRM warming data. rtsirm_cool_data (pd.DataFrame): DataFrame containing ‘meas_temp’ and ‘magn_mass’ columns for RTSIRM cooling data. t_min (int, optional): Minimum temperature for polynomial fitting. Default is 150. t_max (int, optional): Maximum temperature for polynomial fitting. Default is 290. poly_deg (int, optional): Degree of the polynomial to fit. Default is 2. rtsirm_cool_color (str, optional): Color code for plotting cooling data. Default is ‘#17becf’. rtsirm_warm_color (str, optional): Color code for plotting warming data. Default is ‘#d62728’. symbol_size (int, optional): Size of the markers in the plots. Default is 4. return_data (bool, optional): If True, returns the corrected magnetization data for both warming and cooling. Default is False.

Returns: Tuple[pd.Series, pd.Series]: Only if return_data is True. Returns two pandas Series containing the corrected magnetization data for the warming and cooling sequences, respectively.


goethite_removal_interactive

goethite_removal_interactive(measurements, specimen)

Display an interactive widget for fitting and visualizing goethite removal from low temperature remanence data.

This function creates an interactive interface that allows the user to select a specimen and adjust parameters (temperature range and polynomial degree) for fitting the goethite component in RTSIRM (Room Temperature Saturation Isothermal Remanent Magnetization) warming and cooling curves. The user can visually explore the effect of these parameters on the fit and resulting goethite removal, with real-time updated plots.

Parameters

Notes

Returns

Examples

>>> goethite_removal_interactive(measurements_df, specimen_dropdown)
>>> goethite_removal_interactive(measurements_df, 'A73-7-1350-4B-01a')
Displays interactive sliders and plots for fitting goethite removal to the selected specimen's data.

grid_hyst_loop

grid_hyst_loop(field, magnetization)

function to grid a hysteresis loop into a regular grid with grid intervals equal to the average field step size calculated from the data

Parameters

Returns


hyst_HF_nonlinear_optimization

hyst_HF_nonlinear_optimization(H, M, HF_cutoff, fit_type, initial_guess=[1, 1, -0.1, -0.1], bounds=([0, 0, -np.inf, -np.inf], [np.inf, np.inf, 0, 0]))

Optimize a high-field nonlinear fit

Parameters

Returns


hyst_linearity_test

hyst_linearity_test(grid_field, grid_magnetization)

function for testing the linearity of a hysteresis loop

Parameters

Returns


hyst_loop_centering

hyst_loop_centering(grid_field, grid_magnetization)

function for finding the optimum applied field offset value for minimizing a linear fit through the Me based on the R2 value. The idea is maximizing the residual noise in the Me gives the best centered loop.

Parameters

Returns


hyst_loop_centering_iterative

hyst_loop_centering_iterative(grid_field, grid_magnetization, hf_cutoff=0.8, low_field_fraction=0.35, shift_bound_fraction=0.1, weight_power=4, max_iterations=5, field_tolerance=1e-05, moment_tolerance=1e-08)

Center a hysteresis loop by iterating between provisional slope removal and offset fitting.

The routine alternates between fitting a provisional high-field slope and optimizing horizontal and vertical offsets on the residual loop using a low-field-weighted inversion-symmetry metric. This is designed for weak ferromagnetic loops superimposed on a strong linear background.


hyst_loop_saturation_test

hyst_loop_saturation_test(grid_field, grid_magnetization, max_field_cutoff=0.97)

Assess the saturation state of a magnetic hysteresis loop based on linearity at high-field segments.

This function evaluates the degree of saturation in a hysteresis loop by calculating the F statistic for nonlinearity (FNL, the lack-of-fit F ratio of Jackson and Solheid, 2010) over high-field windows starting at 60%, 70%, and 80% of the maximum field (up to a specified cutoff). A significant FNL (above the 2.5 threshold) indicates reproducible curvature in that window, i.e. the ferromagnetic moment has not saturated and a linear high-field fit is inappropriate there.

Parameters

Returns

Notes

Examples

>>> results = hyst_loop_saturation_test(fields, magnetizations)
>>> print(results['saturation_cutoff'], results['loop_is_saturated'])
0.8 False

hyst_slope_correction

hyst_slope_correction(grid_field, grid_magnetization, chi_HF)

function for subtracting the paramagnetic/diamagnetic slope from a hysteresis loop the input should be gridded field and magnetization values

Parameters

Returns


landau_magnetization

landau_magnetization(tau, h)

Reduced magnetization from the Landau equation of state with field term.

Solves m**3 + tau*m = h for the physical (largest real) root, where tau = (T - Tc)/Tc is the reduced temperature and h is the reduced field (Fabian et al., 2013, doi:10.1029/2012GC004440, eqs. 3-5). For h = 0 this reduces to m = sqrt(-tau) below the Curie temperature and m = 0 above it; for h > 0 the transition is rounded and a field-induced tail persists above Tc.

Parameters

Returns


linear_HF_fit

linear_HF_fit(field, magnetization, HF_cutoff=0.8)

function to fit a linear function to the high field portion of a hysteresis loop

Parameters

Returns


loop_closure_test

loop_closure_test(H, Mrh, HF_cutoff=0.8, Me=None, max_field_cutoff=0.99)

function for testing whether a hysteresis loop is closed at high fields

Mrh should be an even function of field for a well-behaved loop (Mrh(-H) = Mrh(H)), so its field-reflection average (even part, with unphysical negative values set to zero) is taken as the signal. A loop that remains open at high fields (e.g. due to unsaturated high-coercivity phases such as hematite or goethite) retains a significant Mrh signal in the high-field window, giving a high signal-to-noise ratio (SNR) and a high ratio of high-field Mrh area to total Mrh area (HAR). The noise is estimated from the high-field portion of the err(H) curve when Me is provided (matching the HystLab implementation of this test; Paterson et al., 2018, section 4.5), or from the odd part of Mrh otherwise. Fields above max_field_cutoff (default 99%) of the maximum field are excluded from the high-field windows to avoid extreme-tip artifacts.

Parameters

Returns


loop_saturation_stats

loop_saturation_stats(field, magnetization, HF_cutoff=0.8, max_field_cutoff=0.97)

ANOVA statistics for the high field portion of a hysteresis loop

Parameters

Returns


magnetite_Ms

magnetite_Ms(T)

Magnetite saturation magnetization calculation

Parameters

Returns


make_experiment_df

make_experiment_df(measurements, exclude_method_codes=None)

Creates a DataFrame of unique experiments from the measurements DataFrame.

Parameters

Returns


measured_descending_first

measured_descending_first(field)

Whether the first-measured branch sweeps downward from positive field.

Gridding canonicalizes a loop to descending-upper-branch-first array order regardless of how it was measured, so the original sweep order must be detected from the raw field values before gridding and passed to the time-order-sensitive drift corrections.

Parameters

Returns


mineral_priors

mineral_priors(mineral_names, tighten=1.0, widen=1.0, field_max_mT=None, overrides=None)

Build a Bayesian-unmixing prior dictionary from named mineral components.

Converts a list of component names from COERCIVITY_COMPONENT_LIBRARY into the priors dictionary accepted by unmix_coercivity_bayes, with a mean-coercivity, dispersion, and skew window per component. The mean window constrains the component’s mean coercivity directly (the skew-normal location is derived from the sampled dp and skew), so the window is meaningful whatever the fitted skew. Components are sorted by their central coercivity so the returned order matches the (low-to-high coercivity) component ordering of the fit.

The library windows are broad starting points; real samples often need them adapted. Use tighten to narrow every window, widen to broaden every window, and overrides to replace specific windows outright when a mineral in your samples sits outside its library range (for example a harder, finer-grained magnetite, or a hematite whose low-coercivity shoulder starts below the library’s detrital-hematite window). A typical workflow is to fit unconstrained first, see where the components land, and then set the windows accordingly.

Because these are informative priors on an ill-posed decomposition, they should be treated as soft constraints; see the caveats in the COERCIVITY_COMPONENT_LIBRARY documentation.

Parameters

Returns


mpms_signal_blender

mpms_signal_blender(measurement_1, measurement_2, spec_1, spec_2, experiments=['LP-ZFC', 'LP-FC', 'LP-CW-SIRM:LP-MC', 'LP-CW-SIRM:LP-MW'], temp_col='meas_temp', moment_col='magn_mass', fraction=0.5)

function for simulating simple mixtures of MPMS dc remanence measurements using the Insitute for Rock Magnetism’s rock magnetism bestiary data

Parameters

Returns


mpms_signal_blender_interactive

mpms_signal_blender_interactive(measurement_1, measurement_2, experiments=['LP-ZFC', 'LP-FC', 'LP-CW-SIRM:LP-MC', 'LP-CW-SIRM:LP-MW'], temp_col='meas_temp', moment_col='magn_mass', figsize=(12, 6))

function for making interactive blender of MPMS dc remanence measurements using the Institute for Rock Magnetism’s rock magnetism bestiary data

Parameters


optimize_moving_average_window

optimize_moving_average_window(experiment, min_temp_window=0, max_temp_window=50, steps=50, colormapwarm='tab20b', colormapcool='tab20c')

Visualize and optimize the moving average window size for smoothing experimental temperature-dependent data.

This function evaluates the effect of different moving average window sizes on the smoothing of both the warm and cool cycles of an experiment (such as low temperature remanence or thermal demagnetization data). It iterates over a range of window sizes, applies smoothing, and computes the average variance and root mean square (RMS) for each window. These metrics are plotted to help the user visually identify the optimal window size for minimizing variance and RMS, balancing noise reduction and signal fidelity.

Parameters

Returns

Examples

>>> fig, axs = optimize_moving_average_window(my_experiment, min_temp_window=5, max_temp_window=30, steps=20)
>>> fig.show()

parse_specimen_description

parse_specimen_description(description)

Parse a MagIC specimens ‘description’ cell into (text, dict).

The description convention used here stores free text and a machine-readable JSON dictionary separated by ’ | '. Legacy cells that contain a Python dict repr (from older rockmagpy versions) are parsed with ast.literal_eval.

Parameters

Returns


plot_M_T

plot_M_T(data, temperature_column='meas_temp', magnetization_column='magn_mass', input_unit='K', plot_unit='K', interactive=False, return_figure=False, show_plot=True, size=(6, 3), legend_location='upper left')

Plot magnetization versus temperature in static or interactive mode.

Parameters

Returns


plot_backfield_data

plot_backfield_data(experiment, field='treat_dc_field', magnetization='magn_mass', Bcr=None, figsize=(5, 10), plot_raw=True, plot_processed=True, plot_spectrum=True, interactive=False, return_figure=False, show_plot=True, y_axis_units='Am²/kg', legend_location='upper left')

Plot backfield data: raw, processed, and coercivity spectrum.

Parameters

Returns


plot_chi_T

plot_chi_T(experiment, temperature_column='meas_temp', magnetic_column='susc_chi_mass', temp_unit='C', smooth_window=0, remove_holder=True, plot_derivative=True, plot_inverse=False, interactive=True, return_figure=False, figsize=(6, 6), window_type='hanning')

Plot the high-temperature susceptibility curve, and optionally its derivative and reciprocal using Bokeh or Matplotlib.

Parameters: experiment (pandas.DataFrame): MagIC-formatted experiment DataFrame. temperature_column (str): Name of temperature column. magnetic_column (str): Name of susceptibility column. temp_unit (str): “C” or “K” for the plotted temperatures (input temperatures are assumed to be in Kelvin, the MagIC convention). smooth_window (int): Window for smoothing, if 0, no smoothing is applied. remove_holder (bool): Subtract holder signal. plot_derivative (bool): Plot derivative. plot_inverse (bool): Plot inverse. interactive (bool): True for Bokeh, False for Matplotlib. return_figure (bool): Return figure objects if True. figsize (tuple): (width, height) in inches. window_type (str): Weighting function applied within each smoothing window, one of ‘flat’, ‘hanning’, ‘hamming’, ‘bartlett’, or ‘blackman’ (default ‘hanning’). Only used when smooth_window > 0. See prepare_thermomag_branches for a description of each option.

Returns: tuple or None: If return_figure is True, a tuple of the figure objects created (Matplotlib Figures when interactive is False, Bokeh figures when interactive is True). Otherwise the figures are displayed and None is returned.


plot_coercivity_prior_library

plot_coercivity_prior_library(minerals=None, field_range=(1.0, 5000.0), n_grid=400, figsize=None, ax=None)

Visualize the coercivity-component prior library.

Draws, for each named mineral component, the skew-normal coercivity distribution implied by the centre of its library windows (mean coercivity, dispersion, and skew) as a ridgeline over a shared log field axis, with the mean-coercivity window drawn as a bar at the baseline and a dot at its centre. Components are coloured by mineral family and ordered by central coercivity, so the coercivity ranges of the different minerals, their characteristic widths and skews, and -- importantly -- their overlaps (the reason a coercivity prior constrains a window rather than identifying a mineral) are all legible at a glance.

Parameters

Returns


plot_coercivity_unmixing

plot_coercivity_unmixing(result, show_components=True, show_bootstrap=True, show_initial=False, n_grid=300, figsize=None, title=None, color_by='component', class_boundaries=None, class_colors=None)

Plot an unmixing result in its fitted data space.

For spectrum-space fits a single panel shows the data, total model, and components. For measurement-space (curve) fits an upper panel shows the measured curve with the cumulative model and a lower panel shows the finite-difference spectrum of the data with the implied component density curves. Bootstrap 95% bands are drawn when present.

Parameters

Returns


plot_curie_estimates

plot_curie_estimates(experiment, methods=None, temperature_column='meas_temp', magnetic_column='susc_chi_mass', temp_unit='C', input_unit='K', smooth_window=0, remove_holder=True, branches=('heating', 'cooling'), method_kwargs=None, figsize=(10, 10), return_figure=False, save_path=None, data_type=None)

Plot a thermomagnetic curve with Curie temperature estimates from multiple methods overlain.

Produces a static matplotlib figure with up to three stacked panels: (a) the (holder-corrected) curve per branch with a vertical line at each method’s estimate, the two-tangent construction, and the Landau model curve where those methods are requested; (b) the first and second derivatives with the inflection point and curvature maximum marked; and (c) 1/chi with the Curie-Weiss fit when 'inverse_susceptibility' is requested. Method colors follow the colorblind-safe palette of Okabe & Ito (2008); heating estimates are drawn with solid lines and cooling estimates with dashed lines.

Parameters mirror curie_temperature_estimates; see that function for the estimation details and method caveats.

Parameters

Returns


plot_day

plot_day(Mr, Ms, Bcr, Bc, Mr_Ms_lower=0.05, Mr_Ms_upper=0.5, Bc_Bcr_lower=1.5, Bc_Bcr_upper=4, plot_day_lines=True, plot_MD_slope=True, plot_SP_SD_mixing=[10, 15, 25, 30], plot_SD_MD_mixing=True, color='black', marker='o', label='sample', alpha=1, lc='black', lw=0.5, legend=True, figsize=(8, 6), show_plot=True, return_figure=True)

function to plot given Ms, Mr, Bc, Bcr values either as single values or list/array of values plots Mr/Ms vs Bc/Bcr.

Parameters

Returns


plot_day_magic

plot_day_magic(specimen_data, by='specimen', Mr='hyst_mr_mass', Ms='hyst_ms_mass', Bcr='rem_bcr', Bc='hyst_bc', kwargs={})

Function to plot a Day plot from a MagIC specimens table.

Parameters

Returns


plot_hyst_loop

plot_hyst_loop(field, magnetization, specimen_name, p=None, interactive=True, show_plot=True, return_figure=False, line_color='grey', line_width=1, label='', legend_location='bottom_right')

function to plot a hysteresis loop

Parameters

Returns


plot_mpms_ac

plot_mpms_ac(experiment, frequency=None, phase='in', figsize=(6, 6), interactive=False, return_figure=False, show_plot=True, legend_location='upper left')

Plot AC susceptibility data from MPMS-X, optionally as interactive Bokeh.

Parameters

Returns


plot_mpms_dc

plot_mpms_dc(fc_data=None, zfc_data=None, rtsirm_cool_data=None, rtsirm_warm_data=None, fc_color='#1f77b4', zfc_color='#ff7f0e', rtsirm_cool_color='#17becf', rtsirm_warm_color='#d62728', fc_marker='d', zfc_marker='p', rtsirm_cool_marker='s', rtsirm_warm_marker='o', symbol_size=4, interactive=False, plot_derivative=False, return_figure=False, show_plot=True, drop_first=False, drop_last=False)

Plots MPMS DC data and optional derivatives, omitting empty panels.

Parameters: fc_data (DataFrame or None): Field-cooled data. zfc_data (DataFrame or None): Zero-field-cooled data. rtsirm_cool_data (DataFrame or None): RTSIRM cooling data. rtsirm_warm_data (DataFrame or None): RTSIRM warming data. fc_color, zfc_color, rtsirm_cool_color, rtsirm_warm_color (str): HEX color codes. fc_marker, zfc_marker, rtsirm_cool_marker, rtsirm_warm_marker (str): Matplotlib-style markers. symbol_size (int): Marker size. interactive (bool): If True, use Bokeh. plot_derivative (bool): If True, plot dM/dT curves. return_figure (bool): If True, return the figure/grid. show_plot (bool): If True, display the plot. drop_first (bool): If True, drop first row of each series. drop_last (bool): If True, drop last row of each series.

Returns: Bokeh grid or Matplotlib fig/axes tuple, or None.


plot_mpms_dc_interactive

plot_mpms_dc_interactive(measurements)

Create a UI to select specimen and plot MPMS data in Matplotlib or Bokeh.

Parameters: measurements (pandas.DataFrame): DataFrame with ‘specimen’ and ‘method_codes’.


plot_neel

plot_neel(Mr, Ms, Bc, color='black', marker='o', label='sample', alpha=1, lc='black', lw=0.5, legend=True, axis_scale='linear', figsize=(5, 5))

Generate a Néel plot (squareness-coercivity) of Mr/Ms versus Bc from hysteresis data.

This plot shows the ratio of remanent to saturation magnetization (Mr/Ms) plotted against the coercivity (Bc). It is useful for characterizing magnetic domain states in rock magnetic samples.

Parameters

Returns


plot_neel_magic

plot_neel_magic(specimen_data, by='specimen', Mr='hyst_mr_mass', Ms='hyst_ms_mass', Bcr='rem_bcr', Bc='hyst_bc', kwargs={})

Function to plot a Day plot from a MagIC specimens table.

Parameters

Returns


plot_unmixing_ensemble

plot_unmixing_ensemble(result, space='spectrum', n_draws=200, n_grid=300, show_components=True, figsize=(8, 5), title=None, colors=None, random_seed=None)

Overlay many draws of the model curves to visualize decomposition spread.

Rather than a single best fit with an error band, this draws the total model and (optionally) the individual components for many bootstrap or posterior samples, so the full range of decompositions consistent with the data is visible directly -- including cases where components exchange coercivity or amplitude between draws.

Parameters

Returns


plot_unmixing_multistart

plot_unmixing_multistart(result, max_solutions=6, space='spectrum', n_grid=300, figsize=None, colors=None, marker_scale='uniform')

Visualize the distinct solutions found by a multi-start analysis.

Produces a panel of small multiples, one per distinct solution (ordered best-fit first), each showing that solution’s decomposition against the data, plus a final parameter-space map that places every solution’s components on a coercivity-versus-proportion plot. Together these make the non-uniqueness of the decomposition concrete: how many genuinely different solutions the data admit and how each partitions the spectrum.

Parameters

Returns


plot_unmixing_posterior

plot_unmixing_posterior(result, quantity='B_mean_mT', bins=40, figsize=None, colors=None)

Plot marginal uncertainty distributions of a component quantity.

Draws one histogram per component of the requested derived quantity from the bootstrap or Bayesian draws, with the median and 95% interval marked. This visualizes how tightly each component parameter is constrained, including asymmetric and multimodal uncertainties that a single standard-error value cannot convey.

Parameters

Returns


plot_unmixing_tradeoff

plot_unmixing_tradeoff(result, x='B_mean_mT', y='proportion', component=None, figsize=(5, 5), colors=None)

Scatter two component quantities across draws to reveal parameter trade-offs.

Overlapping coercivity components trade parameters against one another; plotting one quantity against another across the bootstrap or posterior draws exposes these correlations (and any multimodality) that marginal intervals hide. By default every component is shown; pass a component index to isolate one.

Parameters

Returns


prepare_thermomag_branches

prepare_thermomag_branches(experiment, temperature_column='meas_temp', magnetic_column='susc_chi_mass', temp_unit='C', input_unit='K', smooth_window=0, remove_holder=True, window_type='hanning')

Preprocess a thermomagnetic experiment into clean heating/cooling branches.

This is the shared preprocessing step for the Curie temperature estimators and thermomagnetic plots. It splits the measurement sequence into heating and cooling branches (split_heating_cooling), converts temperatures to the requested unit, optionally subtracts the per-branch minimum as an estimate of the sample-holder background, sorts each branch by ascending temperature, and optionally smooths each branch with an x-space moving window (smooth_moving_average).

Subtracting the per-branch minimum assumes that the magnetic signal decays to the holder background at the highest temperatures (i.e., the experiment passes above the Curie temperature of all ferromagnetic phases). When that assumption does not hold (e.g., a run that ends below the Curie temperature), set remove_holder=False.

Parameters

Returns


process_backfield_data

process_backfield_data(experiment, field='treat_dc_field', magnetization='magn_mass', smooth_mode='lowess', smooth_frac=0.0, drop_first=False)

Function to process the backfield data including shifting the magnetic moment to be positive values taking the log base 10 of the magnetic field values and writing these new fields into the experiment attribute table

Parameters

Returns


process_hyst_loop

process_hyst_loop(field, magnetization, specimen_name='', show_results_table=True, show_plot=True, NL_fit=False, centering_protocol='legacy', fit_open_loop=False, fit_linear_loop=False)

Process a magnetic hysteresis loop using the IRM decision tree workflow.

This function performs a complete analysis of a hysteresis loop, including gridding, centering, drift correction, high-field correction, and extraction of key magnetic parameters. The workflow follows best practices in rock magnetism and outputs both a summary of results and a Bokeh plot visualizing the various processing steps.

The inputs need not come from a MagIC measurements table: any pair of field and magnetization sequences (lists, arrays, or dataframe columns) can be processed. Inputs are passed through sanitize_hyst_inputs, so non-finite measurement pairs are dropped with a report, numeric strings are converted, and either field sweep order (starting from positive or negative saturation) is accepted.

Two decision-tree exits terminate processing early, in both cases returning the full result key set with the undefined quantities reported as NaN/None so batch tables keep a stable schema:

Parameters

Returns


process_hyst_loops

process_hyst_loops(hyst_experiments, measurements, field_col='meas_field_dc', magn_col='magn_mass', show_results_table=True, show_plots=True, centering_protocol='legacy', fit_open_loop=False, fit_linear_loop=False)

Process multiple hysteresis loops in batch.

Parameters

Returns


prorated_drift_correction

prorated_drift_correction(field, magnetization, descending_first=True)

function to correct for the linear drift of a hysteresis loop take the difference between the magnetization measured at the maximum field on the upper and lower branches apply linearly prorated correction of M(H) this should be applied to the gridded data

The prorated ramp runs in measurement-time order, and the arrays are expected in canonical order (descending upper branch first, as produced by grid_hyst_loop). For a loop originally measured from negative saturation, pass descending_first=False (detected from the raw field values with measured_descending_first) so the ramp is applied in true time order rather than with the opposite time sense.

Parameters

Returns


register_unmixing_method

register_unmixing_method(name, function)

Register a custom coercivity unmixing method.

Registered methods become available through unmix_coercivity and unmix_backfield_experiments alongside the built-in ‘spectrum’, ‘curve’, and ‘maxunmix’ methods. The function must accept (x, magnetization, n_components=None, initial_parameters=None, curve_type=‘backfield’, vary_skew=True, **kwargs) and return the standardized result dictionary (see unmix_coercivity_spectrum); the component model helpers (skewnormal_pdf, coercivity_spectrum_model, coercivity_curve_model, ...) can be reused when implementing new methods.

Parameters

Returns


sanitize_hyst_inputs

sanitize_hyst_inputs(field, magnetization, drop_nonfinite=True)

Coerce hysteresis loop inputs into clean float arrays for processing.

This helper makes the processing functions usable with data from any source: MagIC measurement table columns (including ones read as text), plain Python lists, or arrays exported from instrument software.

Parameters

Returns


select_n_components

select_n_components(x, magnetization, method=DEFAULT_UNMIX_METHOD, min_components=1, max_components=4, criterion='parsimony', min_improvement=0.02, noise_level=None, reduced_chi2_target=1.0, curve_type='backfield', vary_skew=DEFAULT_UNMIX_VARY_SKEW, verbose=False, kwargs={})

Choose the number of coercivity components by a parsimony rule.

Fits models with a range of component counts and selects the simplest one that adequately describes the data. This is deliberately different from minimizing an information criterion or maximizing the Bayesian evidence: with high-resolution, low-noise curves those measures tend to keep favoring more components indefinitely, because a real coercivity distribution is never exactly log-Gaussian and each added component removes a little more systematic misfit. Following the parsimony principle emphasized by Egli (2003) and Heslop (2015), an extra component is accepted only when it produces a large enough improvement, so a simpler adequate model is preferred.

Two selection criteria are provided:

In all cases the returned table reports the fit statistics, the fractional RSS improvement per added component, and (when a noise level is available) the reduced chi-square, so the selection can be inspected and overridden.

Parameters

Returns


skewnormal_cdf

skewnormal_cdf(x, location, dp, skew=0.0)

Skew-normal cumulative distribution function.

Evaluated analytically as Phi(z) - 2*T(z, skew) where T is Owen’s T function (scipy.special.owens_t).

Parameters

Returns


skewnormal_pdf

skewnormal_pdf(x, location, dp, skew=0.0)

Skew-normal probability density function (unit area).

With skew = 0 this is a Gaussian with mean = location and standard deviation = dp; in log10(B) coordinates that Gaussian is the log-Gaussian coercivity distribution of Robertson & France (1994). Nonzero skew follows the Azzalini (1985) formulation: negative values skew the distribution toward low values (tail to the left).

Parameters

Returns


skewnormal_stats

skewnormal_stats(location, dp, skew=0.0)

Moments and characteristic points of a skew-normal distribution.

Parameters

Returns


smooth_moving_average

smooth_moving_average(x, y, x_window, window_type='hanning', pad_mode='edge', return_variance=False)

Smooth y vs x using an x-space moving window and numpy window functions.

Parameters: x (array-like): 1-D sequence of independent variable values. y (array-like): 1-D sequence of dependent variable values. x_window (float): Width of the x-window centered on each point; must be >= 0. If zero, no smoothing is applied. window_type (str, optional): One of [‘flat’, ‘hanning’, ‘hamming’, ‘bartlett’, ‘blackman’]. ‘flat’ is a simple running mean. Defaults to ‘hanning’. pad_mode (str, optional): Mode for numpy.pad to reduce edge artifacts (e.g., ‘edge’, ‘constant’, ‘nearest’). Defaults to ‘edge’. return_variance (bool, optional): If True, return weighted variances of x and y as well. Otherwise, only return smoothed x and y. Defaults to False.

Returns: tuple: (smoothed_x, smoothed_y) by default, or (smoothed_x, smoothed_y, x_var, y_var) when return_variance is True. smoothed_x and smoothed_y are the window-averaged arrays (same length as the inputs); x_var and y_var are the corresponding per-point weighted variances within each window (in the squared units of x and y), a measure of local spread. When x_window is 0 the inputs are returned unchanged and the variances are zero.


specimen_experiment_selection_interactive

specimen_experiment_selection_interactive(measurements)

Creates interactive dropdown widgets for selecting a specimen and its associated experiment from a measurements DataFrame.

Parameters

Returns


specimen_selection_interactive

specimen_selection_interactive(measurements)

Creates and displays a dropdown widget for selecting a specimen from a given DataFrame of measurements.

Parameters

Returns


split_heating_cooling

split_heating_cooling(experiment, temperature_column='meas_temp', magnetic_column='susc_chi_mass')

Split a thermomagnetic curve into heating and cooling portions.

The sequence is split at the temperature turning point (the global maximum): measurements up to and including the peak form the heating branch and the descending remainder forms the cooling branch. A run whose temperature never descends after its peak returns an empty cooling branch, and a run that descends from its first measurement returns an empty heating branch. Rows with non-finite temperature or magnetic values are dropped.

Splitting at the turning point rather than on the sign of each local step keeps repeated furnace-stabilization temperatures (where the step is zero) and noisy readings on the heating ramp within the heating branch. A point-by-point classification instead misroutes those points into a spurious cooling branch, so a heating-only run with duplicated or noisy temperatures would otherwise produce a phantom cooling curve. This assumes a single heat-then-cool trajectory, the standard thermomagnetic protocol.

Parameters

Returns


split_hyst_loop

split_hyst_loop(field, magnetization)

function to split a hysteresis loop into upper and lower branches at the reversal of the applied field sweep

The loop reversal is located with find_hyst_turning_point, which tolerates repeated field plateaus and minor field glitches. Loops measured in either sweep order are supported: the branch measured from the positive field extreme downward is returned as the upper branch regardless of whether it was measured first or second.

Parameters

Returns


symmetric_averaging_drift_correction

symmetric_averaging_drift_correction(field, magnetization)

Apply symmetric averaging drift correction to a hysteresis loop.

This function corrects drift in magnetic hysteresis loop data by averaging the upper branch and the inverted lower branch of the magnetization curve, then adjusting for tip-to-tip separation. The corrected magnetization is constructed by concatenating the reversed, drift-corrected upper branch and its inverted counterpart, restoring symmetry to the loop.

Parameters

Returns

Examples

>>> field = np.linspace(-1, 1, 200)
>>> magnetization = some_hysteresis_measurement(field)
>>> corrected = symmetric_averaging_drift_correction(field, magnetization)

thermomag_derivative

thermomag_derivative(temps, mags, drop_first=False, drop_last=False)

Calculates the derivative of magnetization with respect to temperature and optionally drops the data corresponding to the highest and/or lowest temperature.

Parameters: temps (pd.Series): A pandas Series representing the temperatures at which magnetization measurements were taken. mags (pd.Series): A pandas Series representing the magnetization measurements. drop_last (bool): Optional; whether to drop the last row from the resulting DataFrame. Defaults to False. Useful when there is an artifact associated with the end of the experiment. drop_first (bool): Optional; whether to drop the first row from the resulting DataFrame. Defaults to False. Useful when there is an artifact associated with the start of the experiment.

Returns: pd.DataFrame: A pandas DataFrame with two columns: ‘T’ - Midpoint temperatures for each temperature interval. ‘dM_dT’ - The derivative of magnetization with respect to temperature. If drop_last is True, the last temperature point is excluded. If drop_first is True, the first temperature point is excluded.


unmix_backfield_curve

unmix_backfield_curve(x, magnetization, n_components=None, initial_parameters=None, curve_type='backfield', vary_skew=DEFAULT_UNMIX_VARY_SKEW, fit_offset=True, weights=None, dp_bounds=(0.01, 2.0), skew_bounds=(-10.0, 10.0))

Unmix a remanence curve by fitting cumulative components directly.

Fits the measured curve M(log10 B) with a sum of skew-normal CDF components (plus an optional constant offset), avoiding numerical differentiation and smoothing entirely. The component parameterization is identical to unmix_coercivity_spectrum, so results from the two data spaces are directly comparable. Fitting in measurement space uses the raw measurements with their original noise structure; fitting in spectrum space can be more visually intuitive. Agreement between the two approaches is a good indication of a robust unmixing model.

For backfield data processed with process_backfield_data, pass x = ‘log_dc_field’ and magnetization = ‘magn_mass_shift’. Note that the shifted backfield curve spans twice the saturation remanence, so each fitted ‘contribution’ is twice the remanence carried by that component; ‘proportion’ values are unaffected.

Parameters

Returns


unmix_backfield_experiments

unmix_backfield_experiments(measurements, experiments=None, n_components=2, method=DEFAULT_UNMIX_METHOD, initial_parameters=None, vary_skew=DEFAULT_UNMIX_VARY_SKEW, n_boot=0, resample='cases', proportion=1.0, noise_level=None, smooth_mode='spline', smooth_frac=0.0, drop_first=False, field='treat_dc_field', magnetization='magn_mass', random_seed=None, verbose=True, method_kwargs={})

Batch coercivity unmixing of backfield experiments in a MagIC measurements table.

Each experiment is processed with process_backfield_data and unmixed with the requested method (any name registered in UNMIXING_METHODS, dispatched through unmix_coercivity). When initial parameters are not supplied they are estimated automatically per experiment; supplying a common initial-parameter table (or a per-experiment dict, e.g. built with coercivity_unmixing_interactive) enforces a consistent starting model across specimens, which aids comparability of the resulting components.

Parameters

Returns


unmix_coercivity

unmix_coercivity(x, magnetization, method=DEFAULT_UNMIX_METHOD, n_components=None, initial_parameters=None, curve_type='backfield', vary_skew=DEFAULT_UNMIX_VARY_SKEW, kwargs={})

Unmix a remanence curve into coercivity components with a named method.

This is the common entry point to the unmixing approaches implemented in rockmagpy (and to any user-registered methods; see register_unmixing_method). All methods take the measured remanence curve -- not a precomputed derivative -- and share the same skew-normal component parameterization, so their results are directly comparable.

Built-in methods:

Parameters

Returns


unmix_coercivity_bayes

unmix_coercivity_bayes(x, magnetization, n_components=2, curve_type='backfield', space='curve', vary_skew=False, fit_offset=True, priors=None, nlive=250, dlogz=0.1, sample='rslice', random_seed=None, n_grid=200, n_posterior_curves=300, verbose=False)

Bayesian coercivity unmixing by nested sampling (requires dynesty).

The remanence data are modeled as a sum of skew-normal components, with the noise standard deviation treated as a free parameter, and sampled with static nested sampling (Skilling, 2006) as implemented in dynesty (Speagle, 2020), which also returns the Bayesian evidence (logz) -- the principled criterion for choosing the number of components (compare logz between runs with different n_components). The fit can be performed in either of two data spaces (see the space argument):

The component parameterization (contribution=area, location, dp, skew) is identical in both spaces, so their results are directly comparable, and comparing them is a useful robustness check.

Unlike bootstrap resampling of a single fit, the posterior represents the full range of component decompositions consistent with the data and priors: parameter trade-offs between overlapping components appear as wide, correlated, and possibly multimodal posterior distributions rather than being hidden by a single optimizer solution.

Component locations are sampled as ordered order-statistics, which fixes component labels without distorting the prior. Default priors are weakly informative (locations uniform across the measured field range, dispersions log-uniform on [0.02, 1.0] decades, contributions uniform up to ~3x the data range); mineralogical knowledge can be injected through the priors argument.

Parameters

Returns


unmix_coercivity_spectrum

unmix_coercivity_spectrum(x, spectrum, n_components=None, initial_parameters=None, vary_skew=DEFAULT_UNMIX_VARY_SKEW, weights=None, dp_bounds=(0.01, 2.0), skew_bounds=(-10.0, 10.0))

Unmix a coercivity spectrum into skew-normal (log-Gaussian) components.

Fits the derivative spectrum dM/dlog10(B) with a sum of skew-normal densities, following the approach popularized by Kruiver et al. (2001) and the MAX UnMix program (Maxbauer et al., 2016). Compared to fitting the measured curve directly (unmix_backfield_curve) this operates on a numerically differentiated (and possibly smoothed) version of the data, so the choice of smoothing can influence the result; the advantage is that components are fit in the space where they are most readily interpreted visually.

Parameters

Returns


unmixing_bootstrap

unmixing_bootstrap(result, n_boot=500, resample='cases', proportion=1.0, noise_level=None, random_seed=None, n_grid=200, verbose=False)

Bootstrap uncertainty estimation for an unmixing result.

Repeatedly refits the model to resampled data, starting each fit from the best-fit parameters, and summarizes the distributions of parameters and model curves. Two resampling schemes are available:

Bootstrap distributions capture the full nonlinearity of the model and are generally more trustworthy than the linearized standard errors in the ‘params’ table, especially for strongly overlapping components.

Parameters

Returns


unmixing_multistart

unmixing_multistart(x, magnetization, method=DEFAULT_UNMIX_METHOD, n_components=2, n_starts=100, vary_skew=DEFAULT_UNMIX_VARY_SKEW, curve_type='backfield', random_seed=None, location_tolerance=0.1, proportion_tolerance=0.05, verbose=False, kwargs={})

Map the distinct unmixing solutions reachable from many initializations.

Coercivity unmixing is a non-convex problem: fits started from different initial parameters can converge to different local minima that describe the data almost equally well. A single fit (and a bootstrap of it, which restarts every replicate from the best-fit values) is conditioned on one solution basin and therefore hides this non-uniqueness. This function launches the fit from n_starts dispersed random initializations (plus the automatic peak-detection estimate), clusters the converged solutions, and reports each distinct solution with its fit statistics and Akaike weight, making the degeneracy of the decomposition explicit.

Parameters

Returns


verwey_estimate

verwey_estimate(temps, mags, t_range_background_min=50, t_range_background_max=250, excluded_t_min=75, excluded_t_max=150, poly_deg=3, plot_zero_crossing=False, plot_title=None, measurement_marker='o', measurement_color='FireBrick', background_fit_marker='s', background_fit_color='Teal', magnetite_marker='d', magnetite_color='RoyalBlue', verwey_marker='*', verwey_color='Pink', verwey_size=10, markersize=3.5)

Estimate the Verwey transition temperature and remanence loss of magnetite from MPMS data. Plots the magnetization data, background fit, and resulting magnetite curve, and optionally the zero-crossing.

Parameters

Returns

Examples

>>> temps = pd.Series([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
>>> mags = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
>>> verwey_estimate(temps, mags)
(75.0, 0.5)

verwey_estimate_interactive

verwey_estimate_interactive(measurements, specimen, method, figsize=(11, 5))

Create an interactive widget for estimating the Verwey transition temperature from low temperature remanence measurements.

This function displays interactive sliders and controls for adjusting background fitting parameters and temperature ranges, allowing the user to visually estimate the Verwey transition temperature (T_v) for a selected specimen and measurement method. The function updates plots in real-time according to user input, enabling exploration of parameter effects on the calculated transition.

Parameters

Notes

Returns

Examples

>>> verwey_estimate_interactive(measurements_df, specimen_dropdown, method_dropdown)
>>> verwey_estimate_interactive(measurements_df, 'NED2-8c', 'LP-FC')
Displays an interactive interface for estimating the Verwey transition temperature.

verwey_estimate_multiple_specimens

verwey_estimate_multiple_specimens(specimens_with_params, measurements)

Analyze Verwey transitions for a list of specimens with unique parameters.

This function uses either field-cooled (FC) or zero-field cooled (ZFC) data depending on the method_codes provided in each specimen’s parameters. If “LP-FC” is found in the colon-delimited method_codes, FC data is used; if “LP-ZFC” is found, ZFC data is used.

Parameters

Returns

Raises


verwey_specimen_method_selection_interactive

verwey_specimen_method_selection_interactive(measurements)

Creates and displays dropdown widgets for selecting a specimen and the corresponding available method codes (specifically ‘LP-FC’ and ‘LP-ZFC’) from a given DataFrame of measurements. This function filters the measurements to include only those with desired method codes, dynamically updates the method dropdown based on the selected specimen, and organizes the dropdowns vertically in the UI.

Parameters: measurements (pd.DataFrame): The DataFrame containing measurement data with columns ‘specimen’ and ‘method_codes’. It is expected to have at least these two columns where ‘specimen’ identifies the specimen name and ‘method_codes’ contains the method codes associated with each measurement.

Returns: tuple: A tuple containing the specimen dropdown widget (ipywidgets.Dropdown) and the method dropdown widget (ipywidgets.Dropdown). The specimen dropdown allows for the selection of a specimen, and the method dropdown updates to display only the methods available for the selected specimen. The initial selection in the specimen dropdown is set to the first specimen option.

Note: The method dropdown is initially populated based on the methods available for the first selected specimen. The available methods are specifically filtered for ‘LP-FC’ and ‘LP-ZFC’ codes.


zero_crossing

zero_crossing(dM_dT_temps, dM_dT, make_plot=False, xlim=None, verwey_marker='*', verwey_color='Pink', verwey_size=10)

Calculate the temperature at which the second derivative of magnetization with respect to temperature crosses zero. This value provides an estimate of the peak of the derivative curve that is more precise than the maximum value.

The function computes the second derivative of magnetization (dM/dT) with respect to temperature, identifies the nearest points around the maximum value of the derivative, and then calculates the temperature at which this second derivative crosses zero using linear interpolation.

Parameters: dM_dT_temps (pd.Series): A pandas Series representing temperatures corresponding to the first derivation of magnetization with respect to temperature. dM_dT (pd.Series): A pandas Series representing the first derivative of magnetization with respect to temperature. make_plot (bool, optional): If True, a plot will be generated. Defaults to False. xlim (tuple, optional): A tuple specifying the x-axis limits for the plot. Defaults to None. verwey_marker : str, optional Marker symbol used to denote the Verwey transition estimate on the plot. Default is ‘*’. verwey_color : str, optional Color of the marker representing the Verwey transition estimate. Default is ‘Pink’. verwey_size : int, optional Size of the marker used for the Verwey transition estimate. Default is 10.

Returns: float: The estimated temperature at which the second derivative of magnetization with respect to temperature crosses zero.

Note: The function assumes that the input series dM_dT_temps and dM_dT are related to each other and are of equal length.