API Reference

Contents

API Reference#

pmagpy.ipmag#

pmagpy.ipmag.MADcrit(N, alpha, niter=100000000)[source]#

Estimate the MAD critical value at a given significance level to test a null hypothesis of random demagnetization behavior. function from Heslop and Roberts, 2025, Establishing a Statistical Framework for Assessing Paleomagnetic Data Quality: A Significance Test Based on Maximum Angular Deviation doi: https://doi.org/10.1029/ 2025JB031417

Parameters:
  • N (integer) – Number of demagnetization points in the unanchored PCA fit.

  • alpha (float) – Array of significance values for which the critical MAD values should be estimated.

  • niter (integer) – Number of Monte Carlo iterations (default is 1E8). Because α values of interest are in the lower tail of the MAD distribution, it is important to ensure that B is sufficiently large to sample the distribution extremes accurately.

Returns:

Array of estimated critical MAD values.

Return type:

float

Examples

>>> N = 10
>>> alpha = np.array([0.0001,0.001,0.01,0.05,0.1])
>>> MADcrit(N, alpha)
[19.5, 23.1, 27.6, 31.7, 33.9]
pmagpy.ipmag.MADcrit_95_filter(N, MAD)[source]#

A convenience function to quickly filter for MADcrit values at the 95% significance level.

class pmagpy.ipmag.Site(site_name, data_path, data_format='MagIC')[source]#

This Site class is for use within Jupyter/IPython notebooks. It reads in MagIC-formatted data (text files) and compiles fits, separates them by type, and plots equal-area projections inline. If means were not taken and output within the Demag GUI, it should automatically compute the Fisher mean for each fit type. Code is still a work in progress, but it is currently useful for succinctly computing/displaying data in notebook format.

parse_fits(fit_name)[source]#

USE PARSE_ALL_FITS unless otherwise necessary Isolate fits by the name of the fit; we also set ‘specimen_tilt_correction’ to zero in order to only include data in geographic coordinates - THIS NEEDS TO BE GENERALIZED

pmagpy.ipmag.aarm_magic(meas_file, dir_path='.', input_dir_path='', input_spec_file='specimens.txt', output_spec_file='specimens.txt')[source]#

Converts AARM data to best-fit tensor (6 elements plus sigma)

Parameters:
  • meas_file (str) – input measurement file

  • dir_path (str) – output directory, default “.”

  • input_dir_path (str) – input file directory IF different from dir_path, default “”

  • input_spec_file (str) – input specimen file name, default “specimens.txt”

  • output_spec_file (str) – output specimen file name, default “specimens.txt”

Returns:

True or False indicating if conversion was successful and output file name written

Info:

Input for is a series of baseline, ARM pairs. The baseline should be the AF demagnetized state (3 axis demag is preferable) for the following ARM acquisition. The order of the measurements is:

for 6 positions (AF demag before each step):
  1. labfield parallel to X

  2. labfield parallel to Y

  3. labfield parallel to Z

  4. labfield anti-parallel to X

  5. labfield anti-parallel to Y

  6. labfield anti-parallel to Z

for 9 positions (AF demag before each step):

positions 1,2,3,6,7,8,11,12,13 (from Figure D.2 in Essentials, earthref.org/MagIC/books/Tauxe/Essentials, Appendix D)

for 15 positions (AF demag before each step):

positions 1-15 (for 15 positions)

pmagpy.ipmag.aarm_magic_dm2(infile, dir_path='.', input_dir_path='', spec_file='specimens.txt', samp_file='samples.txt', data_model_num=3, coord='s')[source]#

Converts AARM data to best-fit tensor (6 elements plus sigma)

Parameters:
  • infile (str) – input measurement file

  • dir_path (str) – output directory, default “.”

  • input_dir_path (str) – input file directory IF different from dir_path, default “”

  • spec_file (str) – input/output specimen file name, default “specimens.txt”

  • samp_file (str) – input sample file name, default “samples.txt”

  • data_model_num (int) – MagIC data model [2, 3], default 3

  • coord (str) – coordinate system specimen/geographic/tilt-corrected, [‘s’, ‘g’, ‘t’], default ‘s’

Returns:

Tuple

True or False indicating if conversion was successful, output file name written

Info:

Input for is a series of baseline, ARM pairs. The baseline should be the AF demagnetized state (3 axis demag is preferable) for the following ARM acquisition. The order of the measurements is:

positions 1,2,3, 6,7,8, 11,12,13 (for 9 positions)

positions 1,2,3,4, 6,7,8,9, 11,12,13,14 (for 12 positions)

positions 1-15 (for 15 positions)

pmagpy.ipmag.ani_depthplot(spec_file='specimens.txt', samp_file='samples.txt', meas_file='measurements.txt', site_file='sites.txt', age_file='', sum_file='', fmt='svg', dmin=-1, dmax=-1, depth_scale='core_depth', dir_path='.', contribution=None)[source]#

returns matplotlib figure with anisotropy data plotted against depth available depth scales: ‘composite_depth’, ‘core_depth’ or ‘age’ (you must provide an age file to use this option). You must provide valid specimens and sites files, and either a samples or an ages file. You may additionally provide measurements and a summary file (csv).

Parameters:
  • spec_file (str) – default “specimens.txt”

  • samp_file (str) – default “samples.txt”

  • meas_file (str) – default “measurements.txt”

  • site_file (str) – default “sites.txt”

  • age_file (str) – default “”

  • sum_file (str) – default “”

  • fmt (str) – str, default “svg” format for figures, [“svg”, “jpg”, “pdf”, “png”]

  • dmin (number) – default -1 minimum depth to plot (if -1, default to plotting all)

  • dmax (number) – default -1 maximum depth to plot (if -1, default to plotting all)

  • depth_scale (str) – default “core_depth” scale to plot, [‘composite_depth’, ‘core_depth’, ‘age’]. if ‘age’ is selected, you must provide an ages file.

  • dir_path (str) – default “.” directory for input files

  • contribution – cb.Contribution, default None if provided, use Contribution object instead of reading in data from files

Returns:

plot

matplotlib plot, or False if no plot could be created

name

figure name, or error message if no plot could be created

pmagpy.ipmag.ani_depthplot2(ani_file='rmag_anisotropy.txt', meas_file='magic_measurements.txt', samp_file='er_samples.txt', age_file=None, sum_file=None, fmt='svg', dmin=-1, dmax=-1, depth_scale='sample_core_depth', dir_path='.')[source]#

returns matplotlib figure with anisotropy data plotted against depth available depth scales: ‘sample_composite_depth’, ‘sample_core_depth’, or ‘age’ (you must provide an age file to use this option)

pmagpy.ipmag.aniso_magic(infile='specimens.txt', samp_file='samples.txt', site_file='sites.txt', verbose=True, ipar=False, ihext=True, ivec=False, isite=False, sites=None, group_sites=False, isample=False, samples=None, group_samples=False, iboot=False, vec=0, Dir=[], PDir=[], crd='s', num_bootstraps=1000, dir_path='.', fignum=1, save_plots=True, interactive=False, fmt='png', contribution=None, image_records=False)[source]#

Makes plots of anisotropy eigenvectors, eigenvalues and confidence bounds All directions are on the lower hemisphere.

Parameters:
  • infile – specimens formatted file with aniso_s data

  • samp_file – samples formatted file with sample => site relationship

  • site_file – sites formatted file with site => location relationship

  • verbose – if True, print messages to output

  • ipar (confidence bound parameter) – if True - perform parametric bootstrap - requires non-blank aniso_s_sigma

  • ihext (confidence bound parameter) – if True - Hext ellipses

  • ivec (confidence bound parameter) – if True - plot bootstrapped eigenvectors instead of ellipses

  • isite (confidence bound parameter) – if True, produce one plot per site (iterating over all sites in the data). Statistics are computed per site. Mutually exclusive with isample. Equivalent to passing sites=<all sites>.

  • sites – str or list of str, optional (default None) a site name or list of site names to plot. Each listed site gets its own plot with statistics computed on that site alone (per-site iteration). Pass group_sites=True to instead combine all listed sites into a single plot with pooled statistics. Site names not present in the data are skipped with a message when verbose=True. May be combined with samples=… + group_samples=True to also filter by sample within each per-site plot.

  • group_sites – bool, default False if True, combine the specimens from the sites listed in sites into a single plot with pooled statistics rather than iterating per site. Has no effect if sites is None. Cannot be combined with isite=True.

  • isample (confidence bound parameter) – if True, produce one plot per sample (iterating over all samples in the data). Statistics are computed per sample. Mutually exclusive with isite. Equivalent to passing samples=<all samples>.

  • samples – str or list of str, optional (default None) a sample name or list of sample names to plot. Each listed sample gets its own plot with statistics computed on that sample alone (per-sample iteration). Pass group_samples=True to instead combine all listed samples into a single plot with pooled statistics. Sample names not present in the data are skipped with a message when verbose=True.

  • group_samples – bool, default False if True, combine the specimens from the samples listed in samples into a single plot with pooled statistics rather than iterating per sample. Has no effect if samples is None. Cannot be combined with isample=True.

  • iboot (confidence bound parameter) – if True - bootstrap ellipses

  • vec – eigenvector for comparison with Dir

  • Dir – [Dec,Inc] list for comparison direction

  • PDir – [Pole_dec, Pole_Inc] for pole to plane for comparison green dots are on the lower hemisphere, cyan are on the upper hemisphere

  • crd – [‘s’,’g’,’t’], coordinate system for plotting whereby: s : specimen coordinates, aniso_tile_correction = -1, or unspecified g : geographic coordinates, aniso_tile_correction = 0 t : tilt corrected coordinates, aniso_tile_correction = 100

  • num_bootstraps – how many bootstraps to do, default 1000

  • dir_path – directory path

  • fignum – matplotlib figure number, default 1

  • save_plots – bool, default True if True, create and save all requested plots

  • interactive – bool, default False interactively plot and display for each specimen (this is best used on the command line only)

  • fmt – str, default “svg” format for figures, [svg, jpg, pdf, png]

  • contribution – pmagpy contribution_builder.Contribution object, if not provided will be created in directory (default None). (if provided, infile/samp_file/dir_path may be left blank)

pmagpy.ipmag.aniso_magic_nb(infile='specimens.txt', samp_file='samples.txt', site_file='sites.txt', verbose=True, ipar=False, ihext=True, ivec=False, isite=False, sites=None, group_sites=False, isample=False, samples=None, group_samples=False, iboot=False, vec=0, Dir=[], PDir=[], crd='s', num_bootstraps=1000, dir_path='.', fignum=1, save_plots=True, interactive=False, fmt='png', contribution=None, image_records=False)#

Makes plots of anisotropy eigenvectors, eigenvalues and confidence bounds All directions are on the lower hemisphere.

Parameters:
  • infile – specimens formatted file with aniso_s data

  • samp_file – samples formatted file with sample => site relationship

  • site_file – sites formatted file with site => location relationship

  • verbose – if True, print messages to output

  • ipar (confidence bound parameter) – if True - perform parametric bootstrap - requires non-blank aniso_s_sigma

  • ihext (confidence bound parameter) – if True - Hext ellipses

  • ivec (confidence bound parameter) – if True - plot bootstrapped eigenvectors instead of ellipses

  • isite (confidence bound parameter) – if True, produce one plot per site (iterating over all sites in the data). Statistics are computed per site. Mutually exclusive with isample. Equivalent to passing sites=<all sites>.

  • sites – str or list of str, optional (default None) a site name or list of site names to plot. Each listed site gets its own plot with statistics computed on that site alone (per-site iteration). Pass group_sites=True to instead combine all listed sites into a single plot with pooled statistics. Site names not present in the data are skipped with a message when verbose=True. May be combined with samples=… + group_samples=True to also filter by sample within each per-site plot.

  • group_sites – bool, default False if True, combine the specimens from the sites listed in sites into a single plot with pooled statistics rather than iterating per site. Has no effect if sites is None. Cannot be combined with isite=True.

  • isample (confidence bound parameter) – if True, produce one plot per sample (iterating over all samples in the data). Statistics are computed per sample. Mutually exclusive with isite. Equivalent to passing samples=<all samples>.

  • samples – str or list of str, optional (default None) a sample name or list of sample names to plot. Each listed sample gets its own plot with statistics computed on that sample alone (per-sample iteration). Pass group_samples=True to instead combine all listed samples into a single plot with pooled statistics. Sample names not present in the data are skipped with a message when verbose=True.

  • group_samples – bool, default False if True, combine the specimens from the samples listed in samples into a single plot with pooled statistics rather than iterating per sample. Has no effect if samples is None. Cannot be combined with isample=True.

  • iboot (confidence bound parameter) – if True - bootstrap ellipses

  • vec – eigenvector for comparison with Dir

  • Dir – [Dec,Inc] list for comparison direction

  • PDir – [Pole_dec, Pole_Inc] for pole to plane for comparison green dots are on the lower hemisphere, cyan are on the upper hemisphere

  • crd – [‘s’,’g’,’t’], coordinate system for plotting whereby: s : specimen coordinates, aniso_tile_correction = -1, or unspecified g : geographic coordinates, aniso_tile_correction = 0 t : tilt corrected coordinates, aniso_tile_correction = 100

  • num_bootstraps – how many bootstraps to do, default 1000

  • dir_path – directory path

  • fignum – matplotlib figure number, default 1

  • save_plots – bool, default True if True, create and save all requested plots

  • interactive – bool, default False interactively plot and display for each specimen (this is best used on the command line only)

  • fmt – str, default “svg” format for figures, [svg, jpg, pdf, png]

  • contribution – pmagpy contribution_builder.Contribution object, if not provided will be created in directory (default None). (if provided, infile/samp_file/dir_path may be left blank)

pmagpy.ipmag.atrm_magic(meas_file, dir_path='.', input_dir_path='', input_spec_file='specimens.txt', output_spec_file='specimens.txt')[source]#

Converts ATRM data to best-fit tensor (6 elements plus sigma)

Parameters:
  • meas_file (str) – input measurement file

  • dir_path (str) – output directory, default “.”

  • input_dir_path (str) – input file directory IF different from dir_path, default “”

  • input_spec_file (str) – input specimen file name, default “specimens.txt”

  • output_spec_file (str) – output specimen file name, default “specimens.txt”

Returns:

(True or False indicating if conversion was successful, output file name written)

Return type:

Tuple

Info:

Input for is a series of ATRM measurements with optional alteration check The order of the measurements is:

positions:
  • labfield parallel to X

  • labfield parallel to Y

  • labfield parallel to Z

  • labfield anti-parallel to X

  • labfield anti-parallel to Y

  • labfield anti-parallel to Z

  • optional: labfield parallel to X

pmagpy.ipmag.atrm_magic_dm2(meas_file, dir_path='.', input_dir_path='', input_spec_file='specimens.txt', output_spec_file='specimens.txt', data_model_num=2)[source]#

Converts ATRM data to best-fit tensor (6 elements plus sigma)

Parameters:
  • meas_file (str) – input measurement file

  • dir_path (str) – output directory, default “.”

  • input_dir_path (str) – input file directory IF different from dir_path, default “”

  • input_spec_file (str) – input specimen file name, default “specimens.txt”

  • output_spec_file (str) – output specimen file name, default “specimens.txt”

  • data_model_num (number) – MagIC data model [2, 3], default 3

Returns:

Tuple

Return type:

(True or False indicating if conversion was successful, output file name written)

pmagpy.ipmag.azdip_magic(orient_file='orient.txt', samp_file='samples.txt', samp_con='1', Z=1, method_codes='FS-FD', location_name='unknown', append=False, output_dir='.', input_dir='.', data_model=3)[source]#

takes space delimited AzDip file and converts to MagIC formatted tables

Parameters:
  • orient_file – name of azdip formatted input file

  • samp_file – name of samples.txt formatted output file

  • samp_con –

    integer of sample orientation convention

    • [1] XXXXY: where XXXX is an arbitrary length site designation and Y is the single character sample designation. e.g., TG001a is the first sample from site TG001. [default]

    • [2] XXXX-YY: YY sample from site XXXX (XXX, YY of arbitrary length)

    • [3] XXXX.YY: YY sample from site XXXX (XXX, YY of arbitrary length)

    • [4-Z] XXXX[YYY]: YYY is sample designation with Z characters from site XXX

    • [5] site name same as sample

    • [6] site name entered in site_name column in the orient.txt format input file – NOT CURRENTLY SUPPORTED

    • [7-Z] [XXXX]YYY: XXXX is site designation with Z characters with sample name XXXXYYYY

  • method_codes –

    colon delimited string with the following as desired

    • FS-FD field sampling done with a drill

    • FS-H field sampling done with hand samples

    • FS-LOC-GPS field location done with GPS

    • FS-LOC-MAP field location done with map

    • SO-POM a Pomeroy orientation device was used

    • SO-ASC an ASC orientation device was used

    • SO-MAG orientation with magnetic compass

  • location_name – location of samples

  • append – boolean. if True, append to the output file

  • output_dir – path to output file directory

  • input_dir – path to input file directory

  • data_model – MagIC data model.

INPUT FORMAT
Input files must be space delimited:

Samp Az Dip Strike Dip

Orientation convention:
Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip

e.g. field_dip is degrees from horizontal of drill direction

Magnetic declination convention:

Az is already corrected in file

pmagpy.ipmag.bin_trace(lon_samples, lat_samples, resolution)[source]#

Given a trace of samples in longitude and latitude, bin them in latitude and longitude, and normalize the bins so that the integral of probability density over the sphere is one.

The resolution keyword gives the number of divisions in latitude. The divisions in longitude is twice that.

Parameters:
  • lon_samples – a list of longitudes

  • lat_samples – a list of latitudes

  • resolution – The resolution keyword gives the number of divisions in latitude. The divisions in longitude is twice that.

pmagpy.ipmag.bingham_mean(dec=None, inc=None, di_block=None)[source]#

Calculates the Bingham mean and associated statistical parameters from either a list of declination values and a separate list of inclination values or from a di_block (a nested list of [dec, inc, 1.0]). Returns a dictionary with the Bingham mean and statistical parameters.

Parameters:
  • dec – list of declinations

  • inc – list of inclinations or

  • di_block – a nested list of [dec,inc,1.0] A di_block can be provided instead of dec, inc lists in which case it will be used. Either dec, inc lists or a di_block need to passed to the function.

Returns:

dictionary containing the Bingham mean and associated statistics.

Examples

Use lists of declination and inclination to calculate a Bingham mean:

>>> ipmag.bingham_mean(dec=[140,127,142,136],inc=[21,23,19,22])
{'Edec': 220.84075754194598,
'Einc': -13.745780972597291,
'Eta': 9.9111522306938742,
'Zdec': 280.38894136954474,
'Zeta': 9.8653370276451113,
'Zinc': 64.23509410796224,
'dec': 136.32637167111312,
'inc': 21.34518678073179,
'n': 4}

Use a di_block to calculate a Bingham mean (will give the same output as the example above with the lists):

>>> ipmag.bingham_mean(di_block=[[140,21],[127,23],[142,19],[136,22]])
pmagpy.ipmag.bootstrap_fold_test(Data, num_sims=1000, min_untilt=-10, max_untilt=120, bedding_error=0, save=False, save_folder='.', fmt='svg', ninety_nine=False, random_seed=None)[source]#

Conduct a bootstrap fold test (Tauxe and Watson, 1994)

Three plots are generated: 1) equal area plot of uncorrected data; 2) tilt-corrected equal area plot; 3) bootstrap results showing the trend of the largest eigenvalues for a selection of the pseudo-samples (red dashed lines), the cumulative distribution of the eigenvalue maximum (green line) and the confidence bounds that enclose 95% of the pseudo-sample maxima. If the confidence bounds enclose 100% unfolding, the data “pass” the fold test.

Parameters:
  • Data – a numpy array of directional data [dec, inc, dip_direction, dip] dec, inc are the declination and inclination of the paleomagnetic directions dip_direction, dip are the orientation of the bedding

  • num_sims – number of bootstrap samples (default is 1000)

  • min_untilt – minimum percent untilting applied to the data (default is -10%)

  • max_untilt – maximum percent untilting applied to the data (default is 120%)

  • bedding_error – (circular standard deviation) for uncertainty on bedding poles

  • save – optional save of plots (default is False)

  • save_folder – path to directory where plots should be saved

  • fmt – format of figures to be saved (default is ‘svg’)

  • ninety_nine – changes confidence bounds from 95 percent to 99 if True

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

  • uncorrected data equal area plot

  • tilt-corrected data equal area plot

  • bootstrap results and CDF of the eigenvalue maximum

Examples

Data in separate lists of dec, inc, dip_direction, dip data can be made into the needed array using the ipmag.make_diddd_array function.

>>> dec = [132.5,124.3,142.7,130.3,163.2]
>>> inc = [12.1,23.2,34.2,37.7,32.6]
>>> dip_direction = [265.0,265.0,265.0,164.0,164.0]
>>> dip = [20.0,20.0,20.0,72.0,72.0]
>>> data_array = ipmag.make_diddd_array(dec,inc,dip_direction,dip)
>>> data_array
array([[ 132.5,   12.1,  265. ,   20. ],
[ 124.3,   23.2,  265. ,   20. ],
[ 142.7,   34.2,  265. ,   20. ],
[ 130.3,   37.7,  164. ,   72. ],
[ 163.2,   32.6,  164. ,   72. ]])

This array can then be passed to the function:

>>> ipmag.bootstrap_fold_test(data_array)
pmagpy.ipmag.calculate_aniso_parameters(K, n_pos=6)[source]#

calculate anisotropy parameters from n_pos positions plus optional baseline measurements

pmagpy.ipmag.chi_magic(infile='measurements.txt', dir_path='.', experiments='', fmt='svg', save_plots=True, interactive=False, contribution=None)[source]#
Parameters:
  • infile – str, default “measurements.txt” measurement infile

  • dir_path – str, default “.” input directory

  • experiments – str, default “” experiment name to plot

  • fmt – str, default “svg” format for figures, [“svg”, “jpg”, “pdf”, “png”]

  • save_plots – bool, default True save figures

  • interactive – bool, default False if True, interactively plot and display (this is best used on the command line only)

  • contribution – cb.Contribution, default None if provided, use Contribution object instead of reading in data from files

Returns:

True or False indicating if conversion was successful, file name(s) written

Return type:

(status, output_files) - Tuple

pmagpy.ipmag.chi_magic2(path_to_file='.', file_name='magic_measurements.txt', save=False, save_folder='.', fmt='svg')[source]#

Generates plots that compare susceptibility to temperature at different frequencies.

Parameters:
  • specified) ((defaults are used if not)

  • path_to_file – path to directory that contains file (default is current directory, ‘.’)

  • file_name – name of file to be opened (default is ‘magic_measurements.txt’)

  • save – boolean argument to save plots (default is False)

  • save_folder – relative directory where plots will be saved (default is current directory, ‘.’)

pmagpy.ipmag.combine_magic(filenames, outfile='measurements.txt', data_model=3, magic_table='measurements', dir_path='.', input_dir_path='')[source]#

Takes a list of magic-formatted files, concatenates them, and creates a single file. Returns output filename if the operation was successful.

Parameters:
  • filenames – list of MagIC formatted files

  • outfile – name of output file [e.g., measurements.txt]

  • data_model – data model number (2.5 or 3), default 3

  • magic_table – name of magic table, default ‘measurements’

  • dir_path – str output directory, default “.”

  • input_dir_path – str input file directory (if different from dir_path), default “”

Returns:

outfile name if success, False if failure

pmagpy.ipmag.common_mean_bayes(Data1, Data2, reversal_test=False)[source]#

Estimate the probability that two Fisher-distributed sets of directions originate from populations with a common mean using the Bayesian framework of Heslop and Roberts (2018). This version of the test is the one involving distributions with common precision.

Parameters:
  • Data1 – a nested list of directional data [dec,inc] (a di_block)

  • Data2 – a nested list of directional data [dec,inc] (a di_block)

  • reversal_test – whether to flip one populations to its antipode (default is False)

Returns:

BF0 (Bayes factor), P (posterior probability of the hypothesis), support (category of support based on classification of P)

pmagpy.ipmag.common_mean_bootstrap(Data1, Data2, NumSims=1000, color1='r', color2='b', save=False, save_folder='.', fmt='svg', figsize=(7, 2.3), x_tick_bins=4, verbose=True, random_seed=None)[source]#

Conducts a bootstrap test for a common mean on two directional data sets.

This function implements the bootstrap test from Tauxe (2010) to determine if two sets of directional data are consistent with sharing a common mean. It generates cumulative distribution plots for the X, Y, and Z components of the bootstrapped means. The test “passes” if the 95% confidence bounds for each of the three components overlap.

Alternatively, if a single direction is provided for Data2, the function tests if that direction falls within the 95% confidence bounds of Data1.

Parameters:
  • Data1 (array-like) – A list of lists or NumPy array of directional data, where each inner list is [declination, inclination].

  • Data2 (array-like) – A second set of directional data in the same format as Data1, or a single direction as [declination, inclination].

  • NumSims (int, optional) – The number of bootstrap samples to generate. Defaults to 1000.

  • color1 (str, optional) – Matplotlib color for the first dataset. Defaults to ‘r’ (red).

  • color2 (str, optional) – Matplotlib color for the second dataset. Defaults to ‘b’ (blue).

  • save (bool, optional) – If True, saves the generated plots. Defaults to False.

  • save_folder (str, optional) – The directory path where plots will be saved. Defaults to ‘.’.

  • fmt (str, optional) – The file format for saved plots (e.g., ‘svg’, ‘png’, ‘pdf’). Defaults to ‘svg’.

  • figsize (tuple, optional) – The size of the figure for the plots. Defaults to (7, 2.3).

  • x_tick_bins (int, optional) – The maximum number of tick mark bins for the x-axis of the plots. Defaults to 4.

  • verbose (bool, optional) – If True, prints the test result (‘Pass’ or ‘Fail’) to the console. Defaults to True.

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

Returns 1 if the datasets pass the common mean test, and 0 if they fail.

Return type:

int

Notes

The function also displays or saves three plots showing the cumulative distributions for the X, Y, and Z components of the bootstrapped means. These plots are a visual representation of the statistical test.

Examples

Develop two populations of directions using ipmag.fishrot() and then use the function to determine if they share a common mean.

>>> directions_A = ipmag.fishrot(k=20, n=30, dec=40, inc=60)
>>> directions_B = ipmag.fishrot(k=35, n=25, dec=42, inc=57)
>>> result = ipmag.common_mean_bootstrap_new(directions_A, directions_B)
Pass
>>> print(result)
1

Compare a single direction to a population.

>>> directions_A = ipmag.fishrot(k=100, n=30, dec=45, inc=45)
>>> direction_B = [45,45]
>>> common_mean_bootstrap_new(directions_A, direction_B)
Pass
pmagpy.ipmag.common_mean_bootstrap_H23(Data1, Data2, num_sims=10000, alpha=0.05, plot=True, reversal=False, save=False, save_folder='.', fmt='svg', verbose=False, random_seed=None)[source]#

Perform a bootstrap common mean direction test following Heslop et al. (2023).

This function uses a nonparametric bootstrap approach to test the null hypothesis of common mean directions between two datasets. It extends the bootstrap common mean direction test of Tauxe et al. 1991 by incorporating a null hypothesis significance testing framework.

Parameters:
  • Data1 (array) – Directional data of the first set; each row is [declination, inclination].

  • Data2 (array) – Directional data of the second set; each row is [declination, inclination].

  • num_sims (int, optional) – Number of bootstrap simulations to run. Default is 10000.

  • alpha (float, optional) – Significance level for hypothesis testing. Default is 0.05.

  • plot (bool, optional) – If True, produces a histogram plot of the test statistic. Default is True.

  • reversal (bool, optional) – If True, considers antipodal directions for the second dataset. Default is False.

  • save (bool, optional) – If True, saves the histogram plot. Default is False.

  • save_folder (str, optional) – Directory where the histogram plot will be saved. Default is the current directory.

  • fmt (str, optional) – File format for saving the histogram plot. Default is ‘svg’.

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

Contains the following elements:
  • result (int): 0 if null hypothesis is rejected, 1 otherwise.

  • Lmin (float): The test statistic value.

  • Lmin_c (float): The critical test statistic value.

  • p (float): The p-value of the test.

Return type:

tuple

References

Heslop, D., Scealy, J. L., Wood, A. T. A., Tauxe, L., & Roberts, A. P. (2023). A bootstrap common mean direction test. Journal of Geophysical Research: Solid Earth, 128, e2023JB026983. https://doi.org/10.1029/2023JB026983

pmagpy.ipmag.common_mean_watson(Data1, Data2, NumSims=5000, print_result=True, plot=False, save=False, save_folder='.', fmt='svg', random_seed=None)[source]#

Conduct a Watson V test for a common mean on two directional data sets.

This function calculates Watson’s V statistic from input lists through Monte Carlo simulation in order to test whether two populations of directional data could have been drawn from a common mean. The critical angle between the two sample mean directions and the corresponding McFadden and McElhinny (1990) classification is printed.

Parameters:
  • Data1 – a nested list of directional data [dec,inc] (a di_block)

  • Data2 – a nested list of directional data [dec,inc] (a di_block)

  • NumSims – number of Monte Carlo simulations (default is 5000)

  • print_result – default is to print the test result (True)

  • plot – if True, plot the CDF from the Monte Carlo simulations (default is False).

  • save – optional save of plots (default is False)

  • save_folder – path to where plots will be saved (default is current)

  • fmt – format of figures to be saved (default is ‘svg’)

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

result (int)1 if the test passes (common mean cannot be

rejected) or 0 if the test fails.

angle (float)angle between the Fisher means of the two

data sets.

critical_angle (float) : critical angle of the Watson V test. classification (str) : McFadden and McElhinny (1990)

classification (‘A’, ‘B’, ‘C’, ‘indeterminate’) for a positive test, or ‘’ for a negative test.

Return type:

tuple of (result, angle, critical_angle, classification) where

Examples

Develop two populations of directions using ipmag.fishrot. Use the function to determine if they share a common mean.

>>> directions_A = ipmag.fishrot(k=20, n=30, dec=40, inc=60)
>>> directions_B = ipmag.fishrot(k=35, n=25, dec=42, inc=57)
>>> ipmag.common_mean_watson(directions_A, directions_B)
pmagpy.ipmag.conglomerate_test_Watson(R, n)[source]#

The Watson (1956) test of a directional data set for randomness compares the resultant vector (R) of a group of directions to values of Ro. If R exceeds Ro, the null hypothesis of randomness is rejected. If R is less than Ro, the null hypothesis of randomness is considered to not be rejected.

Parameters:
  • R – the resultant vector length of the directions

  • n – the number of directions

Returns:

printed text (text describing test result), result (a dictionary with the Watson (1956) R values)

pmagpy.ipmag.contribution_to_magic(contribution, dir_path='.')[source]#

Write a contribution object to MagIC-formatted files in the specified directory. Compiles these files into a upload.txt file which can be uploaded into the MagIC database using the upload_magic function.

Parameters:
  • contribution (Contribution) – A contribution object containing tables to be written to a MagIC-formatted file.

  • dir_path (str) – The directory path where the MagIC-formatted file will be written.

pmagpy.ipmag.core_depthplot(input_dir_path='.', meas_file='measurements.txt', spc_file='', samp_file='samples.txt', age_file='', sum_file='', wt_file='', depth_scale='core_depth', dmin=-1, dmax=-1, sym='bo', size=5, spc_sym='ro', spc_size=5, meth='', step=0, fmt='svg', pltDec=True, pltInc=True, pltMag=True, pltLine=True, pltSus=True, logit=False, pltTime=False, timescale=None, amin=-1, amax=-1, norm=False, data_model_num=3, location='')[source]#

depth scale can be ‘core_depth’ or ‘composite_depth’ (for data model=3) if age file is provided, depth_scale will be set to ‘age’ by default. You must provide at least a measurements,specimens and sample file to plot.

Parameters:
  • input_dir_path – str, default “.” file input directory

  • meas_file – str, default “measurements.txt” input measurements file

  • spc_file – str, default “” input specimens file

  • samp_file – str, default “” input samples file

  • age_file – str, default “” input ages file

  • sum_file – str, default “” input csv summary file

  • wt_file – str, default “” input file with weights

  • depth_scale – str, default “core_depth” [‘core_depth’, ‘composite_depth’]

  • dmin – number, default -1 minimum depth to plot (if -1, default to plotting all)

  • dmax – number, default -1 maximum depth to plot (if -1, default to plotting all)

  • sym – str, default “bo” symbol color and shape, default blue circles (see matplotlib documentation for more options)

  • size – int, default 5 symbol size

  • spc_sym – str, default ‘ro’ specimen symbol color and shape, default red circles (see matplotlib documentation for more options)

  • meth – str, default “” method codes, [“LT-NO”, “AF”, “T”, “ARM”, “IRM”, “X”]

  • step –

    int, default 0 treatment step for plotting:

    for AF, in mT, for T, in C

  • fmt – str, default “svg” format for figures, [svg,jpg,png,pdf]

  • pltDec – bool, default True plot declination

  • pltInc – bool, default True plot inclination

  • pltMag – bool, default True plot magnetization

  • pltLine – bool, default True connect dots with a line

  • pltSus – bool, default True plot blanket treatment

  • logit – bool, default False plot magnetization on a log scale

  • amin – int, default -1 minimum time to plot (if -1, default to plotting all)

  • amax – int, default -1 maximum time to plot (if -1, default to plotting all)

  • norm – bool, default False normalize by weight

  • data_model_num – int, default 3 MagIC data model (please, use data model 3)

Returns:

main_plot, figname

pmagpy.ipmag.create_private_contribution(username='', password='')[source]#

Create a private contribution on earthref.org/MagIC.

Parameters:
  • username – str personal username for MagIC

  • password – str password for username

Returns:

response API requests.models.Response
response.status_code: bool

True : successful creation of private workspace

response[‘url’]str

URL of request

response[‘method’]str

’POST’

response[‘id’]str

if successful, MagIC ID number created

response[‘errors’]str

if unsuccessful, error message

pmagpy.ipmag.criteria_extract(crit_file='criteria.txt', output_file='criteria.xls', output_dir_path='.', input_dir_path='', latex=False)[source]#

Extracts criteria from a MagIC 3.0 format criteria.txt file. Default output format is an Excel file. typeset with latex on your own computer.

Parameters:
  • crit_file – str, default “criteria.txt” input file name

  • output_file – str, default “criteria.xls” output file name

  • output_dir_path – str, default “.” output file directory

  • input_dir_path – str, default “” path for intput file if different from output_dir_path (default is same)

  • latex – boolean, default False if True, output file should be latex formatted table with a .tex ending

Returns :

[True,False], data table error type : True if successful

Effects :

writes xls or latex formatted tables for use in publications

pmagpy.ipmag.cumulative_density_distribution(lon_samples, lat_samples, resolution=30)[source]#

compute cumulative density distribution of a set of vectors on a unit sphere

Parameters:
  • lon_samples – a list of longitudes

  • lat_samples – a list of latitudes

  • resolution – the resolution at which to calculate the vectors distribution. the higher the number, the finer the resolution

Returns:

Tuple

longitude grid, latitude grid, and cumulative densities

pmagpy.ipmag.curie(path_to_file='.', file_name='', magic=False, window_length=3, save=False, save_folder='.', fmt='svg', t_begin='', t_end='')[source]#

Plots and interprets curie temperature data. The 1st derivative is calculated from smoothed M-T curve (convolution with triangular window with width= <-w> degrees) The 2nd derivative is calculated from smoothed 1st derivative curve (using the same sliding window width) The estimated curie temperation is the maximum of the 2nd derivative. Temperature steps should be in multiples of 1.0 degrees.

Deprecated since version ``ipmag.curie``: is deprecated and will be removed in a future release. It reports a single Curie temperature from the maximum of the smoothed second derivative. Use the multi-method estimators in pmagpy.rockmag instead, which make method-dependent biases explicit (Fabian et al., 2013, doi:10.1029/2012GC004440):

  • rockmag.curie_temperature_estimates() applies the selected methods to the heating/cooling branches of a MagIC experiment and returns a tidy comparison table with per-method caveats.

  • rockmag.curie_derivative_estimates() is the direct analog of this function, returning both the inflection-point and maximum-curvature estimates (the max_curvature method reproduces the legacy value here: 552 C vs 549 C on data_files/curie/curie_example.dat with a 10-degree window).

Parameters:
  • file_name – name of file to be opened

  • path_to_file – path to directory that contains file (default is current directory, ‘.’)

  • window_length – dimension of smoothing window (input to smooth() function)

  • save – boolean argument to save plots (default is False)

  • save_folder – relative directory where plots will be saved (default is current directory, ‘.’)

  • fmt – format of saved figures (default is svg)

  • t_begin – start of truncated window for search (default is beginning of data)

  • t_end – end of truncated window for search (default is end of data)

  • magic – True if MagIC formatted measurements.txt file

Returns:

A plot is shown and saved if save=True.

pmagpy.ipmag.dayplot_magic(path_to_file='.', hyst_file='specimens.txt', rem_file='', save=True, save_folder='.', fmt='svg', data_model=3, interactive=False, contribution=None, image_records=False)[source]#

Makes ‘day plots’ (Day et al. 1977) and squareness/coercivity plots (Neel, 1955; plots after Tauxe et al., 2002); plots ‘linear mixing’ curve from Dunlop and Carter-Stiglitz (2006).

Parameters:
  • path_to_file – path to directory that contains files (default is current directory, ‘.’)

  • (data_model=3 (the default input file is 'specimens.txt')

  • 2 (if data_model =) – hyst_file : hysteresis file (default is ‘rmag_hysteresis.txt’) rem_file : remanence file (default is ‘rmag_remanence.txt’)

  • defaults (then must these are the) – hyst_file : hysteresis file (default is ‘rmag_hysteresis.txt’) rem_file : remanence file (default is ‘rmag_remanence.txt’)

  • save – boolean argument to save plots (default is True)

  • save_folder – relative directory where plots will be saved (default is current directory, ‘.’)

  • fmt – format of saved figures (default is ‘pdf’)

  • image_records (boolean) – generate and return a record for each image in a list of dicts which can be ingested by pmag.magic_write, default is False

pmagpy.ipmag.delete_private_contribution(contribution_id, username='', password='')[source]#

Delete a private contribution on earthref.org/MagIC.

Parameters:
  • contribution_id – int ID of MagIC contribution to delete

  • username – str personal username for MagIC

  • password – str password for username

Returns:

response (API requests.models.Response)
response.status_code: bool

True : successful creation of private workspace

response[‘url’]str

URL of request

response[‘method’] :

’DELETE’

response[‘id’]str

if successful, MagIC ID contribution deleted

response[‘errors’]str

if unsuccessful, error message

pmagpy.ipmag.demag_magic(path_to_file='.', file_name='magic_measurements.txt', save=False, save_folder='.', fmt='svg', plot_by='loc', treat=None, XLP='', individual=None, average_measurements=False, single_plot=False)[source]#

Takes demagnetization data (from magic_measurements file) and outputs intensity plots (with optional save).

Parameters:
  • path_to_file – path to directory that contains files (default is current directory, ‘.’)

  • file_name – name of measurements file (default is ‘magic_measurements.txt’)

  • save – boolean argument to save plots (default is False)

  • save_folder – relative directory where plots will be saved (default is current directory, ‘.’)

  • fmt – format of saved figures (default is ‘svg’)

  • plot_by – specifies what sampling level you wish to plot the data at (‘loc’ – plots all samples of the same location on the same plot ‘exp’ – plots all samples of the same expedition on the same plot ‘site’ – plots all samples of the same site on the same plot ‘sample’ – plots all measurements of the same sample on the same plot ‘spc’ – plots each specimen individually)

  • treat – treatment step ‘T’ = thermal demagnetization ‘AF’ = alternating field demagnetization ‘M’ = microwave radiation demagnetization (default is ‘AF’)

  • XLP – filter data by a particular method

  • individual – This function outputs all plots by default. If plotting by sample or specimen, you may not wish to see (or wait for) every single plot. You can therefore specify a particular plot by setting this keyword argument to a string of the site/sample/specimen name.

  • average_measurements – Option to average demagnetization measurements by the grouping specified with the ‘plot_by’ keyword argument (default is False)

  • single_plot – Option to output a single plot with all measurements (default is False)

pmagpy.ipmag.density_distribution(lon_samples, lat_samples, resolution=30)[source]#

calculate density distribution of a given set of vectos on a sphere

Parameters:
  • lon_samples – a list of longitudes

  • lat_samples – a list of latitudes

  • resolution – the resolution at which to calculate the vectors distribution. the higher the number, the finer the resolution (default is 30)

pmagpy.ipmag.df_depthplot(df, d_key='core_depth', fmt='png', location='unknown', save=False)[source]#

Makes depth (or height) plots of various columns in the dataframe

Parameters:
  • df – pandas dataframe

  • d_key (str) – name of column for plotting against [‘core_depth’,’composite_depth’,’height’]

  • fmt (str) – format of saved figure, default is ‘png’

  • location (str) – name of location

  • save (boolean) – if True, save plot to location.fmt

pmagpy.ipmag.dmag_magic(in_file='measurements.txt', dir_path='.', input_dir_path='', spec_file='specimens.txt', samp_file='samples.txt', site_file='sites.txt', loc_file='locations.txt', plot_by='loc', LT='AF', norm=True, XLP='', save_plots=True, fmt='svg', interactive=False, n_plots=5, contribution=None)[source]#

plots intensity decay curves for demagnetization experiments

Parameters:
  • in_file (str) – default “measurements.txt”

  • dir_path (str) – output directory, default “.”

  • input_dir_path (str) – input file directory (if different from dir_path), default “”

  • spec_file (str) – input specimen file name, default “specimens.txt”

  • samp_file (str) – input sample file name, default “samples.txt”

  • site_file (str) – input site file name, default “sites.txt”

  • loc_file (str) – input location file name, default “locations.txt”

  • plot_by (str) – [spc, sam, sit, loc] (specimen, sample, site, location), default “loc”

  • LT (str) – lab treatment [T, AF, M], default AF

  • norm (bool) – normalize by NRM magnetization, default True

  • XLP (str) – exclude specific lab protocols, (for example, method codes like LP-PI) default “”

  • save_plots (bool) – plot and save non-interactively, default True

  • fmt (str) – str [“png”, “svg”, “pdf”, “jpg”], default “svg”

  • interactive (bool) – default False interactively plot and display for each specimen (this is best used on the command line only)

  • n_plots (int) – default 5 maximum number of plots to make if you want to make all possible plots, specify “all”

  • contribution – cb.Contribution, default None if provided, use Contribution object instead of reading in data from files

Returns:

True or False indicating if conversion was successful, file name(s) written

pmagpy.ipmag.dms2dd(degrees, minutes, seconds)[source]#

Convert latitude/longitude of a location that is in degrees, minutes, seconds to decimal degrees

Parameters:
  • degrees – degrees of latitude/longitude

  • minutes – minutes of latitude/longitude

  • seconds – seconds of latitude/longitude

Returns:

float

decimal degrees of location

Examples

Convert 180 degrees 4 minutes 23 seconds to decimal degrees:

>>> ipmag.dms2dd(180,4,23)
180.07305555555556
pmagpy.ipmag.do_flip(dec=None, inc=None, di_block=None, unit_vector=True)[source]#

This function returns the antipode (i.e. it flips) of directions.

The function can take dec and inc as separate lists if they are of equal length and explicitly specified or are the first two arguments. It will then return a list of flipped decs and a list of flipped incs. If a di_block (a nested list of [dec, inc, 1.0]) is specified then it is used and the function returns a di_block with the flipped directions.

Parameters:
  • dec – list of declinations

  • inc – list of inclinations

  • di_block – a nested list of [dec, inc, 1.0] A di_block can be provided instead of dec, inc lists in which case it will be used. Either dec, inc lists or a di_block need to passed to the function.

  • unit_vector – if True will return [dec,inc,1.]; if False will return [dec,inc]

  • True) ((default is)

Returns:

either dec_flip, inc_flip as lists of flipped declinations and inclinations or dflip as a nested list of [dec, inc, 1.0] or [dec, inc]

Examples

Lists of declination and inclination can be flipped to their antipodes:

>>> decs = [1.0, 358.0, 2.0]
>>> incs = [10.0, 12.0, 8.0]
>>> ipmag.do_flip(decs, incs)
([181.0, 178.0, 182.0], [-10.0, -12.0, -8.0])

The function can also take a di_block and returns a flipped di_block:

>>> directions = [[1.0,10.0],[358.0,12.0,],[2.0,8.0]]
>>> ipmag.do_flip(di_block=directions)
[[181.0, -10.0, 1.0], [178.0, -12.0, 1.0], [182.0, -8.0, 1.0]]
pmagpy.ipmag.download_magic(infile=None, dir_path='.', input_dir_path='', overwrite=False, print_progress=True, data_model=3.0, separate_locs=False, txt='', excel=False)[source]#

Takes the name of a text file downloaded from the MagIC database and unpacks it into MagIC-formatted files. by default, download_magic assumes that you are doing everything in your current directory. if not, you may provide optional arguments dir_path (where you want the results to go) and input_dir_path (where the downloaded file is IF that location is different from dir_path).

Parameters:
  • infile – str MagIC-format file to unpack

  • dir_path – str output directory (default “.”)

  • input_dir_path – str, default “” path for intput file if different from output_dir_path (default is same)

  • overwrite – bool overwrite current directory (default False)

  • print_progress – bool verbose output (default True)

  • data_model – float MagIC data model 2.5 or 3 (default 3)

  • separate_locs – bool create a separate directory for each location (Location_*) (default False)

  • txt – str, default “” if infile is not provided, you may provide a string with file contents instead (useful for downloading MagIC file directly from earthref)

  • excel – bool input file is an excel spreadsheet (as downloaded from MagIC)

Returns:

bool

True if the unpacking operation is successful. False otherwise.

pmagpy.ipmag.download_magic_from_doi(doi)[source]#

Download a public contribution matching the provided DOI from earthref.org/MagIC.

Parameters:

doi – str DOI for a MagIC

Returns:

bool message : str

Error message if download didn’t succeed

Return type:

result

pmagpy.ipmag.download_magic_from_id(magic_id, directory='.', share_key='')[source]#

Downloads a contribution from earthref.org/MagIC using the provided ID and saves it to the specified directory. If the directory does not exist, it is created. If a share_key is provided, it downloads a private contribution.

Parameters:
  • magic_id (str) – Unique ID for a MagIC contribution.

  • directory (str) – Path to save the file. Defaults to current directory.

  • share_key (str) – Share key for downloading from Private Contribution; default is “” for public contribution.

Returns:

True if successful, False otherwise. str: Relative file path if successful or error message if failed.

Return type:

bool

pmagpy.ipmag.eigs_s(infile='', dir_path='.')[source]#

Converts eigenparamters format data to s format

Parameters:

Input –

fileinput file name with eigenvalues (tau) and eigenvectors (V) with format:

tau_1 V1_dec V1_inc tau_2 V2_dec V2_inc tau_3 V3_dec V3_inc

Returns:

the six tensor elements as a nested array

[[x11,x22,x33,x12,x23,x13],….]

pmagpy.ipmag.ellipse(map_axis, centerlon, centerlat, major_axis, minor_axis, angle, n=360, filled=False, transform=None, **kwargs)[source]#

This function enables general error ellipses to be drawn on the cartopy projection of the input map axis using a center and a set of major and minor axes and a rotation angle east of north. (Adapted from equi).

Parameters:
  • map_axis (cartopy axis)

  • centerlon (longitude of the center of the ellipse)

  • centerlat (latitude of the center of the ellipse)

  • major_axis (Major axis of ellipse in km)

  • minor_axis (Minor axis of ellipse in km)

  • angle (angle of major axis in degrees east of north)

  • n (number of points with which to apporximate the ellipse)

  • filled (boolean specifying if the ellipse should be plotted as a filled polygon or) – as a set of line segments (Doesn’t work right now)

  • kwargs (any other key word arguments can be passed for the line)

  • Returns – The map object with the ellipse plotted on it

pmagpy.ipmag.eqarea_magic(in_file='sites.txt', dir_path='.', input_dir_path='', spec_file='specimens.txt', samp_file='samples.txt', site_file='sites.txt', loc_file='locations.txt', plot_by='all', crd='g', ignore_tilt=False, save_plots=True, fmt='svg', contour=False, color_map='coolwarm', plot_ell='', n_plots=5, interactive=False, contribution=None, source_table='sites', image_records=False)[source]#

makes equal area projections from declination/inclination data

Parameters:
  • in_file – str, default “sites.txt”

  • dir_path – str output directory, default “.”

  • input_dir_path – str input file directory (if different from dir_path), default “”

  • spec_file – str input specimen file name, default “specimens.txt”

  • samp_file – str input sample file name, default “samples.txt”

  • site_file – str input site file name, default “sites.txt”

  • loc_file – str input location file name, default “locations.txt”

  • plot_by – str [spc, sam, sit, loc, all] (specimen, sample, site, location, all), default “all”

  • crd – [‘s’,’g’,’t’], coordinate system for plotting whereby: s : specimen coordinates, aniso_tile_correction = -1 g : geographic coordinates, aniso_tile_correction = 0 (default) t : tilt corrected coordinates, aniso_tile_correction = 100

  • ignore_tilt – bool default False. If True, data are unoriented (allows plotting of measurement dec/inc)

  • save_plots – bool plot and save non-interactively, default True

  • fmt – str [“png”, “svg”, “pdf”, “jpg”], default “svg”

  • contour – bool plot as color contour

  • colormap – str color map for contour plotting, default “coolwarm” see cartopy documentation for more options

  • plot_ell – str [F,K,B,Be,Bv] plot Fisher, Kent, Bingham, Bootstrap ellipses or Bootstrap eigenvectors default “” plots none

  • n_plots – int maximum number of plots to make, default 5 if you want to make all possible plots, specify “all”

  • interactive – bool, default False interactively plot and display for each specimen (this is best used on the command line or in the Python interpreter)

  • contribution – cb.Contribution, default None if provided, use Contribution object instead of reading in data from files

  • source_table – table to get plot data from (only needed with contribution argument) for example, you could specify source_table=”measurements” and plot_by=”sites” to plot measurement data by site. default “sites”

  • image_records – generate and return a record for each image in a list of dicts which can be ingested by pmag.magic_write bool, default False

Returns:

if image_records == False

type - Tuple : (True or False indicating if conversion was successful, file name(s) written)

if image_records == True

True or False indicating if conversion was successful, output file name written, list of image recs

pmagpy.ipmag.equi(map_axis, centerlon, centerlat, radius, color, alpha=1.0, outline=True, fill=False, lw=1)[source]#

This function enables A95 error ellipses to be drawn in cartopy around paleomagnetic poles in conjunction with shoot (modified from: http://www.geophysique.be/2011/02/20/matplotlib-basemap-tutorial-09-drawing-circles/).

Parameters:
  • map_axis – cartopy axis

  • centerlon – longitude of the center of the ellipse

  • centerlat – latitude of the center of the ellipse

  • radius – radius of ellipse (in degrees)

  • color – color of ellipse

  • alpha – transparency - if filled, the transparency will only apply to the facecolor of the ellipse

  • outline – boolean specifying if the ellipse should be plotted as a filled polygon or as a set of line segments

  • fill – boolean specifying if the ellipse should be plotted as a filled polygon

pmagpy.ipmag.f_factor_calc(inc_observed, inc_field)[source]#

Calculate the flattening factor (f) from an observed inclination in comparison to the expected inclination.

Parameters:
  • inc_observed – the observed inclination (e.g. magnetization of sediment)

  • inc_field – inclination of field in which magnetization was acquired

Returns:

the flattening factor

Return type:

f_factor

Examples

Calculate the f factor for an inclination that was shallowed from 40 degrees to 25 degrees:

>>> ipmag.f_factor_calc(25,40)
0.5557238268604126
pmagpy.ipmag.find_compilation_kent(plon, plat, A95, slon, slat, f_from_compilation=None, n=10000, n_fish=100, return_poles=False, return_kent_stats=True, return_paleolats=False, map_central_longitude=0, map_central_latitude=0, random_seed=None)[source]#

Applies flattening factors from the compilation to sedimentary paleomagnetic pole where only pole longitude, pole latitude, A95, site longitude, and site latitude are available.

First, calculate the paleomagnetic direction at the site of the mean pole using plon, plat via pmag.vgp_di. Then draw n resamples from the compiled f values in the compilation. The default compilation of Pierce et al., 2022 can be used or the user can provide their own compilation.

Unsquish the directions with the resampled f factors, then convert the mean directions back to pole space. Making the simplifying assumption that A95 is the same as the directions are unflattened. Resample n_fish mean poles from the Fisher distribution given the unsquished plon, plat, and A95. This will result in a total of n*n_fish number of resampled mean poles. Summarize the distribution of the mean poles using a Kent distribution.

Parameters:
  • plon – legacy mean pole longitude

  • plat – legacy mean pole latitude

  • A95 – legacy mean pole A95

  • slon – site longitude

  • slat – site latitude

  • f_from_compilation – list of f factors (default is None in which case the compilation of Pierce et al., 2022 Table S1 will be used)

  • n – number of resamples from compilation (default is 10000)

  • n_fish – number of resamples from each Fisher mean pole position (default is 100)

  • return_poles – whether or not to return the resampled mean pole positions (default is False)

  • return_kent_stats – whether or not to return the calculated Kent distribution statistics of the resampled mean poles (default is True)

  • return_paleolats – whether or not to return the computed compilation paleolatitudes (default is False)

  • map_central_longitude – central longitude for the orthographic map (default is 0)

  • map_central_latitude – central latitude for the orthographic map (default is 0)

  • random_seed – None, int, or numpy.random.Generator, optional Seed for reproducible resampling (default None).

Returns:

  • compilation_mean_lons, compilation_mean_lats: resampled mean pole positions

  • f_compilation_kent_distribution_95: Kent distribution statistics

  • compilation_paleolats: computed compilation paleolatitudes

Return type:

Depending on the combination of boolean flags provided, returns one or more of

pmagpy.ipmag.find_ei(data, nb=1000, save=False, save_folder='.', fmt='svg', site_correction=False, return_new_dirs=False, figprefix='EI', return_values=False, num_resample_to_plot=1000, data_color='k', EI_color='r', resample_EI_color='grey', resample_EI_alpha=0.05, tight_axes=False, random_seed=None)[source]#

Applies series of assumed flattening factors and “unsquishes” inclinations assuming tangent function. Finds flattening factor that gives elongation/inclination pair consistent with TK03; or, if correcting by site instead for study-level secular variation, finds flattening factor that minimizes elongation and most resembles a Fisherian distribution. Finds bootstrap confidence bounds

Parameters:
  • data – a nested list of dec/inc pairs

  • nb – number of bootstrapped pseudo-samples (default is 1000)

  • save – Boolean argument to save plots (default is False)

  • save_folder – path to folder in which plots should be saved (default is current directory)

  • fmt – specify format of saved plots (default is ‘svg’)

  • figfile – name of saved file plus format string

  • site_correction – Boolean argument to specify whether to “unsquish” data to 1) the elongation/inclination pair consistent with TK03 secular variation model (site_correction = False) or 2) a Fisherian distribution (site_correction = True). Default is FALSE. Note that many directions (~ 100) are needed for this correction to be reliable.

  • return_new_dirs – optional return of newly “unflattened” directions as di_block (default is False)

  • return_values – optional return of all bootstrap result inclinations, elongations, and f factors (default is False)

  • return_values=True (if both return_new_dirs=True and) – di_block of new directions, inclinations, elongations,and f factors

  • return (the function will) – di_block of new directions, inclinations, elongations,and f factors

  • num_resample_to_plot – number of bootstrap resample elongation/inclination curves to plot (default to to plot all)

  • data_color – the color of the direction equal area plot data (default is black)

  • EI_color – the color of the EI curve associated with the most frequent f value (rounded to 2 decimal points, default is red)

  • resample_EI_color – the color of the EI curves for all f values except for the most frequent f (default is grey)

  • resample_EI_alpha – the transparency of the EI curves for all f values except for the most frequent f (default is grey)

  • tight_axes – optional argument to tighten up the axes limits for the inclination-elongation figure

  • random_seed – None, int, or numpy.random.Generator, optional Seed for reproducible bootstrap resampling (default None).

Returns:

  • equal area plot of original directions

  • Elongation/inclination pairs as a function of f, data plus num_resample_to_plot bootstrap samples

  • Cumulative distribution of bootstrapped optimal inclinations plus uncertainties.

    Estimate from original data set plotted as solid line

  • Orientation of principal direction through unflattening

Note

If distribution does not have a solution, plot labeled: Pathological. Some bootstrap samples may have valid solutions and those are plotted in the CDFs and E/I plot.

pmagpy.ipmag.find_ei_kent(data, site_latitude, site_longitude, kent_color='k', nb=1000, save=False, save_folder='.', fmt='svg', return_new_dirs=False, return_values=False, figprefix='EI', num_resample_to_plot=1000, EI_color='r', resample_EI_color='grey', resample_EI_alpha=0.05, vgp_nb=100, cmap='viridis_r', central_longitude=0, central_latitude=0, random_seed=None)[source]#

Applies series of assumed flattening factor and “unsquishes” inclinations assuming tangent function. Finds flattening factor that gives elongation/inclination pair consistent with TK03 Finds bootstrap confidence bounds Based on all flattening factors from the E/I bootstrap results find the distribution of paleolatitudes and fit with a normal distribution Based on all flattening factors from the E/I bootstrap results calculate the correspondant VGP pole positions and their mean poles associated with each factor Perform Monte Carlo resample of the mean poles associated with each flattening factor Finds the Kent distribution statistics: mean, major and minor axes and their associated angles of dispersion.

Parameters:
  • data – a nested list of dec/inc pairs

  • site_latitude – location of the paleomagnetic site

  • site_longitude – location of the paleomagnetic site

  • kent_color – color of the Kent ellipse to plot (default is black)

  • nb – number of bootstrapped pseudo-samples (default is 1000)

  • save – Boolean argument to save plots (default is False)

  • save_folder – path to folder in which plots should be saved (default is current directory)

  • fmt – specify format of saved plots (default is ‘svg’)

  • return_new_dirs – optional return of newly “unflattened” directions as di_block (default is False)

  • return_values –

    optional return of all bootstrap result inclinations, elongations, and f factors (default is False)

    if both return_new_dirs=True and return_values=True, the function will return di_block of new directions, inclinations, elongations,and f factors

  • figprefix – prefix string for the name of the figures to be saved

  • EI_color – color of the most elongation/inclination curve corresponding to the most frequent f value

  • resample_EI_color – color of all other elongation/inclination curves

  • vgp_nb – number of virtual geomagnetic poles to resample for each iteration, the total VGPs resampled will be vgp_nb*nb

  • cmap – matplotlib color map used for plotting corrected paleomagnetic directions

  • central_longitude – central point of pole projection (defaults are 0)

  • central_latitude – central point of pole projection (defaults are 0)

  • num_resample_to_plot – number of bootstrap resample elongation/inclination curves to plot (default to to plot all)

  • vgp_nb – number of vgp to resample using a Monte Carlo approach with each f factor

  • cmap – matplotlib color map for color-coding the directions and mean poles based on the f factor

  • EI_color – the color of the EI curve associated with the most frequent f value (rounded to 2 decimal points, default is red)

  • resample_EI_color – the color of the EI curves for all f values except for the most frequent f (default is grey)

  • resample_EI_alpha – the transparency of the EI curves for all f values except for the most frequent f (default is grey)

Returns:

  1. equal area plot of original directions

  2. Elongation/inclination pairs as a function of f, data plus 25 bootstrap samples

  3. Cumulative distribution of bootstrapped optimal inclinations plus uncertainties. Estimate from original data set plotted as solid line

  4. Orientation of principle direction through unflattening

Return type:

four plots

Note

If distribution does not have a solution, plot labeled: Pathological. Some bootstrap samples may have valid solutions and those are plotted in the CDFs and E/I plot.

pmagpy.ipmag.find_svei_kent(di_block, site_latitude, site_longitude, f_low, f_high, kent_color='k', n=1000, save=False, save_folder='.', figprefix='SVEI', fmt='svg', return_poles=False, return_kent_stats=True, return_paleolats=False, vgp_nb=100, cmap='viridis_r', central_longitude=0, central_latitude=0, random_seed=None)[source]#

Uses a uniform distribution of flattening factors (f) derived from the SVEI analysis of Tauxe et al. (2024) to correct inclination shallowing in sedimentary paleomagnetic data and quantify uncertainty in the resulting mean pole using a Kent distribution.

The f values are sampled uniformly from a user-defined interval (f_low, f_high) that should be determined in advance using the find_flat function of the SVEI module (Tauxe et al., 2024), which identifies the range of flattening factors consistent with the THG24 geomagnetic field model.

For each sampled f, the directions are “unflattened” using the tangent transformation, converted to VGPs, and resampled with a Fisher distribution. The resulting distribution of mean poles is summarized with a Kent distribution. Plots of corrected directions, paleolatitudes, and resampled poles are optionally generated and saved.

Parameters:
  • di_block – list or array-like (a di block) Nested list or array of [dec, inc] or [dec, inc, intensity] directional data.

  • site_latitude – float Latitude of the paleomagnetic sampling site.

  • site_longitude – float Longitude of the paleomagnetic sampling site.

  • f_low – float Lower bound for flattening factor, as determined from SVEI analysis (e.g. 0.51).

  • f_high – float Upper bound for flattening factor, as determined from SVEI analysis (e.g. 0.89).

  • kent_color – str, optional Color of the plotted Kent ellipse (default is ‘k’).

  • n – int, optional Number of flattening factors to sample (default is 1000).

  • save – bool, optional If True, saves figures to the specified folder (default is False).

  • save_folder – str, optional Directory to save plots (default is current directory).

  • figprefix – str, optional Prefix for saved figure filenames (default is ‘SVEI’).

  • fmt – str, optional Format for saved figures (e.g., ‘svg’, ‘png’) (default is ‘svg’).

  • return_poles – bool, optional If True, returns the resampled mean pole positions (default is False).

  • return_kent_stats – bool, optional If True, returns the Kent distribution statistics (default is True).

  • return_paleolats – bool, optional If True, returns the distribution of calculated paleolatitudes (default is False).

  • vgp_nb – int, optional Number of Fisher resamples per unflattened mean pole (default is 100).

  • cmap – str, optional Colormap used to indicate f value in directional plots (default is ‘viridis_r’).

  • central_longitude – float, optional Central longitude of the orthographic projection (default is 0).

  • central_latitude – float, optional Central latitude of the orthographic projection (default is 0).

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

  • kent_statsdict

    Kent distribution parameters summarizing the resampled mean poles.

  • mean_lons, mean_latslist of float

    Longitudes and latitudes of resampled mean poles.

  • paleolatslist of float

    Paleolatitudes calculated from resampled mean poles.

Return type:

Depending on flags, returns one or more of

Notes

This function assumes the user has previously run the SVEI find_flat function (Tauxe et al., 2024) to determine the range of flattening factors (f_low, f_high) that are consistent with the THG24 GGP model for the dataset under consideration.

pmagpy.ipmag.fisher_angular_deviation(dec=None, inc=None, di_block=None, confidence=95)[source]#

The angle from the true mean within which a chosen percentage of directions lie can be calculated from the Fisher distribution. This function uses the calculated Fisher concentration parameter to estimate this angle from directional data. The 63 percent confidence interval is often called the angular standard deviation.

Parameters:
  • dec – list of declinations or longitudes

  • inc – list of inclinations or latitudes or

  • di_block – a nested list of [dec,inc,1.0] A di_block can be provided instead of dec, inc lists in which case it will be used. Either dec, inc lists or a di_block need to be provided.

  • confidence – 50 percent, 63 percent or 95 percent (default is 95 percent)

Returns:

float

theta is returned which is the critical angle of interest from the mean which contains the percentage of directions specified by the confidence parameter

pmagpy.ipmag.fisher_mean(dec=None, inc=None, di_block=None)[source]#

Calculates the Fisher mean and associated parameters from either a list of declination values and a separate list of inclination values or from a di_block (a nested list of [dec,inc,1.0]). Returns a dictionary with the Fisher mean and statistical parameters.

Parameters:
  • dec – list of declinations or longitudes

  • inc – list of inclinations or latitudes or

  • di_block – a nested list of [dec,inc,1.0] A di_block can be provided instead of dec, inc lists in which case it will be used. Either dec, inc lists or a di_block need to be provided.

Returns:

dictionary

Dictionary containing the Fisher mean parameters. This dictionary can be printed in a more readable fashion using the ipmag.print_direction_mean() function if it is a directional mean or ipmag.print_pole_mean() function if it is a pole mean.

Examples

Use lists of declination and inclination to calculate a Fisher mean:

>>> ipmag.fisher_mean(dec=[140,127,142,136],inc=[21,23,19,22])
{'alpha95': 7.292891411309177,
'csd': 6.4097743211340896,
'dec': 136.30838974272072,
'inc': 21.347784026899987,
'k': 159.69251473636305,
'n': 4,
'r': 3.9812138971889026}

Use a di_block to calculate a Fisher mean (will give the same output as the example with the lists):

>>> ipmag.fisher_mean(di_block=[[140,21],[127,23],[142,19],[136,22]])
pmagpy.ipmag.fisher_mean_resample(alpha95=20, n=100, dec=0, inc=90, di_block=True, random_seed=None)[source]#

Generates resamples of directional means from a Fisher mean with a specified alpha95. Equivalent of sampling from the angular standard deviation.

Parameters:
  • alpha95 – 95% confidence on mean direction (default is 5)

  • n – number of vectors to determine (default is 100)

  • dec – mean declination of distribution (default is 0)

  • inc – mean inclination of distribution (default is 90)

  • di_block – this function returns a nested list of [dec,inc,1.0] as the default if di_block = False it will return a list of dec and a list of inc

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

  • di_block, a nested list of [dec,inc,1.0] (default)

  • dec, inc, a list of dec and a list of inc (if di_block = False)

Examples

>>> ipmag.fisher_mean_resample(alpha95=5, n=5, dec=40, inc=60)
>>> [[41.47587050719005, 62.44682515754436, 1.0],
    [33.738299775944085, 55.88461662263949, 1.0],
    [42.98707546462242, 60.21460942319564, 1.0],
    [28.282076485842992, 59.67015046929257, 1.0],
    [41.87081053973009, 57.18064045614739, 1.0]]
pmagpy.ipmag.fishqq(lon=None, lat=None, di_block=None, plot=True, save=False, fmt='png', save_folder='.', data_type='directions')[source]#

Test whether a distribution is Fisherian and make a corresponding Q-Q plot. The Q-Q plot shows the data plotted against the value expected from a Fisher distribution. The first plot is the uniform plot which is the Fisher model distribution in terms of longitude (declination). The second plot is the exponential plot which is the Fisher model distribution in terms of latitude (inclination). In addition to the plots, the test statistics Mu (uniform) and Me (exponential) are calculated and compared against the critical test values. If Mu or Me are too large in comparison to the test statistics, the hypothesis that the distribution is Fisherian is rejected (see Fisher et al., 1987). These test statistics are returned in a dictionary.

Parameters:
  • lon – longitude or declination of the data

  • lat – latitude or inclination of the data or

  • di_block – a nested list of [dec,inc] A di_block can be provided in which case it will be used instead of dec, inc lists.

  • plot – boolean to decide whether to make a plot (default is True)

  • save – boolean to decide whether plot is saved (default is False)

  • save_folder – relative directory where plots will be saved (default is current directory, ‘.’)

  • fmt – format of saved plot (default is ‘png’)

  • data_type – ‘directions’ (default) or ‘poles’. Controls the axis/plot labels only: ‘directions’ labels the components ‘Declinations’ and ‘Inclinations’; ‘poles’ labels them ‘Longitudes’ and ‘Latitudes’ (appropriate when the input di_block is a set of VGPs/poles).

Note

The Mu and Me test statistics are computed whether or not plot is True (when plot is False they are calculated on a temporary figure that is closed without display).

Returns:

dictionary
  • lon, mean longitude (or declination)

  • lat, mean latitude (or inclination)

  • N, number of vectors

  • Mu, Mu test statistic value for the data

  • Mu_critical, critical value for Mu

  • Me, Me test statistic value for the data

  • Me_critical, critical value for Me

if the data has two modes with N >=10 (N and R) two of these dictionaries will be returned

Examples

In this example, directions are sampled from a Fisher distribution using ipmag.fishrot and then the ipmag.fishqq function is used to test whether that distribution is Fisherian:

>>> directions = ipmag.fishrot(k=40, n=50, dec=200, inc=50)
>>> ipmag.fishqq(di_block = directions)
{'Dec': 199.73564290371894,
'Inc': 49.017612342358298,
'Me': 0.78330310031220352,
'Me_critical': 1.094,
'Mode': 'Mode 1',
'Mu': 0.69915926146177099,
'Mu_critical': 1.207,
'N': 50,
'Test_result': 'consistent with Fisherian model'}

The above example passed a di_block to the function as an input. Lists of paired declination and inclination can also be used as inputs. Here the directions di_block is unpacked to separate declination and inclination lists using the ipmag.unpack_di_block functionwhich are then used as input to fishqq:

>>> dec_list, inc_list = ipmag.unpack_di_block(directions)
>>> ipmag.fishqq(lon=dec_list, lat=inc_list)
pmagpy.ipmag.fishrot(k=20, n=100, dec=0, inc=90, di_block=True, random_seed=None)[source]#

Generates Fisher distributed unit vectors from a specified distribution using the pmag.py function pmag.fshdev() and pmag.dodirot_V() functions.

Parameters:
  • k – kappa precision parameter (default is 20)

  • n – number of vectors to determine (default is 100)

  • dec – mean declination of distribution (default is 0)

  • inc – mean inclination of distribution (default is 90)

  • di_block – this function returns a nested list of [dec,inc,1.0] as the default if di_block = False it will return a list of dec and a list of inc

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

  • di_block, a nested list of [dec,inc,1.0] (default)

  • dec, inc, a list of dec and a list of inc (if di_block = False)

Examples

>>> ipmag.fishrot(k=20, n=5, dec=40, inc=60)
array([[55.30451720381376 , 56.186057037482435,  1.               ],
       [25.593998008087908, 63.544360587984784,  1.               ],
       [29.263675539971246, 54.58964868129066 ,  1.               ],
       [61.28572459596148 , 51.5004074156194  ,  1.               ],
       [55.20784339888985 , 54.186746152272484,  1.               ]])
pmagpy.ipmag.get_matrix(n_pos=6)[source]#

returns design matrix for anisotropy experiments

Parameters:

n_pos – anisotropy experiment positions (default is 6, can be 6, 9 or 15)

Returns:

matrix for n_pos of 6,9, or 15

Matrices definitions:

A design matrix B np.dot(inv(np.dot(A.transpose(),A)),A.transpose()) tmpH is used for sigma calculation (9,15 measurements only)

Anisotropy tensor:

|Mx| |s1 s4 s6| |Bx| |My| = |s4 s2 s5| . |By| |Mz| |s6 s5 s3| |Bz|

A matrix (measurement matrix): Each mesurement yields three lines in “A” matrix

|Mi | |Bx 0 0 By 0 Bz| |s1| |Mi+1| = |0 By 0 Bx Bz 0 | . |s2| |Mi+2| |0 0 Bz 0 By Bx| |s3|

pmagpy.ipmag.histplot(infile='', data=(), outfile='', xlab='x', binsize=False, norm=1, fmt='svg', save_plots=True, interactive=False)[source]#

makes histograms for data

Parameters:
  • infile (str) – default “” input file name format: single variable

  • data (tuple) – list-like, default () list/array of values to plot if infile is not provided

  • outfile (str) – default “” name for plot, if not provided defaults to hist.FMT

  • xlab (str) – default ‘x’ label for x axis

  • binsize (int) – default False desired binsize. if not specified, an appropriate binsize will be calculated.

  • norm (int) – default 1 1: norm, 0: don’t norm, -1: show normed and non-normed axes

  • fmt (str) – default “svg” format for figures, [“svg”, “jpg”, “pdf”, “png”]

  • save_plots (bool) – default True if True, create and save all requested plots

  • interactive (bool) – default False interactively plot and display (this is best used on the command line only)

pmagpy.ipmag.hysteresis_magic(output_dir_path='.', input_dir_path='', spec_file='specimens.txt', meas_file='measurements.txt', fmt='svg', save_plots=True, make_plots=True, pltspec='', n_specs=5, interactive=False)[source]#

Calculate hysteresis parameters and plot hysteresis data. Plotting may be called interactively with save_plots==False, or be suppressed entirely with make_plots==False.

Parameters:
  • output_dir_path –

    str, default “.” Note: if using Windows, all figures will be saved to working directly

    not dir_path

  • input_dir_path – str path for intput file if different from output_dir_path (default is same)

  • spec_file – str, default “specimens.txt” output file to save hysteresis data

  • meas_file – str, default “measurements.txt” input measurement file

  • fmt – str, default “svg” format for figures, [svg, jpg, pdf, png]

  • save_plots – bool, default True if True, generate and save all requested plots

  • make_plots – bool, default True if False, skip making plots and just save hysteresis data (if False, save_plots will be set to False also)

  • pltspec – str, default “” specimen name to plot, otherwise will plot all specimens

  • n_specs – int number of specimens to plot, default 5 if you want to make all possible plots, specify “all”

  • interactive – bool, default False interactively plot and display for each specimen (this is best used on the command line or in the Python interpreter)

Returns:

Tuple

(True or False indicating if conversion was successful, output file names written)

pmagpy.ipmag.hysteresis_magic2(path_to_file='.', hyst_file='rmag_hysteresis.txt', save=False, save_folder='.', fmt='svg', plots=True)[source]#

Calculates hysteresis parameters, saves them in rmag_hysteresis format file. If selected, this function also plots hysteresis loops, delta M curves, d (Delta M)/dB curves, and IRM backfield curves.

Parameters:
  • path_to_file – path to directory that contains files (default is current directory, ‘.’)

  • hyst_file – hysteresis file (default is ‘rmag_hysteresis.txt’)

  • save – boolean argument to save plots (default is False)

  • save_folder – relative directory where plots will be saved (default is current directory, ‘.’)

  • fmt – format of saved figures (default is ‘pdf’)

  • plots – whether or not to display the plots (default is true)

pmagpy.ipmag.igrf(input_list, mod='', ghfile='')[source]#

Determine declination, inclination and intensity from a geomagnetic field model. The default model used is the IGRF model (http://www.ngdc.noaa.gov/IAGA/vmod/igrf.html) with other models available for selection with the available options detailed in the mod parameter below.

Parameters:
  • input_list – list with format [Date, Altitude, Latitude, Longitude] date must be in decimal year format XXXX.XXXX (Common Era) altitude is in kilometers

  • mod –

    desired model “” : Use the IGRF14 model by default ‘custom’ : use values supplied in ghfile or choose from this list [‘arch3k’,’cals3k’,’pfm9k’,’hfm10k’,’cals10k.2’,’cals10k.1b’,’shadif14’,’shawq2k’,’shawqIA’,’ggf100k’] where:

    • arch3k (Korte et al., 2009)

    • cals3k (Korte and Constable, 2011)

    • cals10k.1b (Korte et al., 2011)

    • pfm9k (Nilsson et al., 2014)

    • hfm10k is the hfm.OL1.A1 of Constable et al. (2016)

    • cals10k.2 (Constable et al., 2016)

    • shadif14 (Pavon-Carrasco et al., 2014)

    • shawq2k (Campuzano et al., 2019)

    • shawqIA (Osete et al., 2020)

    • ggk100k (Panovska et al., 2018)[only models from -99950 in 200 year increments allowed)

    • the first four of these models, are constrained to agree

    • with gufm1 (Jackson et al., 2000) for the past four centuries

  • gh – path to file with l m g h data

Returns:

igrf_array

array of magnetic field values (0: dec; 1: inc; 2: intensity (in nT))

Examples

>>> local_field = ipmag.igrf([2013.6544, .052, 37.87, -122.27])
>>> local_field
array([1.431355648576314e+01, 6.148304376287219e+01, 4.899264739340517e+04])
>>> ipmag.igrf_print(local_field)
Declination: 14.314
Inclination: 61.483
Intensity: 48992.647 nT
pmagpy.ipmag.igrf_print(igrf_array)[source]#

Print out Declination, Inclination, Intensity from an array returned from the ipmag.igrf() function.

Parameters:

igrf_array – array that is output from ipmag.igrf() function

Examples

An array generated by the ipmag.igrf() function is passed to ipmag.igrf_print()

>>> local_field = ipmag.igrf([2013.6544, .052, 37.87, -122.27])
>>> ipmag.igrf_print(local_field)
Declination: 14.314
Inclination: 61.483
Intensity: 48992.647 nT
pmagpy.ipmag.inc_from_lat(lat)[source]#

Calculate inclination predicted from latitude using the dipole equation.

Parameter:

lat : latitude in degrees

Returns:

inclination calculated from latitude using the dipole equation

Examples

Calculate the inclination implied by an latitude of 45 degrees: >>> ipmag.inc_from_lat(45) 63.434948822922

pmagpy.ipmag.iplot_hys(fignum, B, M, s)[source]#

function to plot hysteresis data

This function has been adapted from pmagplotlib.iplot_hys for specific use within a Jupyter notebook.

Parameters:
  • fignum – reference number for matplotlib figure being created

  • B – list of B (flux density) values of hysteresis experiment

  • M – list of M (magnetization) values of hysteresis experiment

  • s – specimen name

pmagpy.ipmag.kent_distribution_95(dec=None, inc=None, di_block=None)[source]#

Calculates the Kent mean and and provides the parameters associated with the region containing 95% of the directions from either a list of declination values and a separate list of inclination values or from a di_block (a nested list a nested list of [dec,inc,1.0]). Returns a dictionary with the Kent mean and statistical parameters.

Parameters: dec: list of declinations inc: list of inclinations di_block: a nested list of [dec,inc,1.0]

A di_block can be provided instead of dec, inc lists in which case it will be used. Either dec, inc lists or a di_block need to passed to the function.

Returns:

dictionary containing Kent mean and associated statistics.

Examples

Use lists of declination and inclination to calculate a Kent mean:

>>> ipmag.kent_distribution_95(dec=[140,127,142,136],inc=[21,23,19,22])
{'dec': 136.30838974272072,
'inc': 21.347784026899987,
'n': 4,
'Zdec': 40.82469002841276,
'Zinc': 13.739412321974067,
'Edec': 280.38683553668795,
'Einc': 64.23659892174429,
'Zeta': 13.677129096579478,
'Eta': 1.4597607031196376}
Use a di_block to calculate a Kent mean (will give the same output as the
example with the lists):
>>> ipmag.kent_distribution_95(di_block=[[140,21],[127,23],[142,19],[136,22]])
pmagpy.ipmag.kent_mean(dec=None, inc=None, di_block=None)[source]#

Calculates the Kent mean and associated statistical parameters from either a list of declination values and a separate list of inclination values or from a di_block (a nested list a nested list of [dec,inc,1.0]). Returns a dictionary with the Kent mean and statistical parameters.

Parameters:
  • dec – list of declinations

  • inc – list of inclinations or

  • di_block – a nested list of [dec,inc,1.0] A di_block can be provided instead of dec, inc lists in which case it will be used. Either dec, inc lists or a di_block need to passed to the function.

Returns:

dictionary containing Kent mean and associated statistics.

Examples

Use lists of declination and inclination to calculate a Kent mean:

>>> ipmag.kent_mean(dec=[140,127,142,136],inc=[21,23,19,22])
{'Edec': 280.38683553668795,
'Einc': 64.236598921744289,
'Eta': 0.72982112760919715,
'Zdec': 40.824690028412761,
'Zeta': 6.7896823241008795,
'Zinc': 13.739412321974067,
'dec': 136.30838974272072,
'inc': 21.347784026899987,
'n': 4}

Use a di_block to calculate a Kent mean (will give the same output as the example above with the dec, inc lists):

>>> ipmag.kent_mean(di_block=[[140,21],[127,23],[142,19],[136,22]])
pmagpy.ipmag.kentrot(kent_dict, n=100, di_block=True, random_seed=None)[source]#

Generates Kent distributed unit vectors from a specified distribution using the pmag.py function pmag.kentdev().

Parameters:
  • kent_dict – a dictionary for Kent distribution parameters. It should at least have: dec: mean axis dec, inc: mean axis inc, Zdec: major axis dec, Zinc: major axis inc, Edec: minor axis dec, Einc: minor axis inc, R1: Kent distribution size quantity for calculating kappa and beta, R2: Kent distribution shape quantity for calculating kappa and beta}

  • di_block – this function returns a nested list of [dec,inc,1.0] as the default

  • inc (if di_block = False it will return a list of dec and a list of)

  • random_seed – None, int, or numpy.random.Generator Controls reproducibility. None for random, int for seeded, or a Generator instance for RNG threading through call chains.

Returns:

di_block, a nested list of [dec,inc,1.0] (default) dec, inc, a list of dec and a list of inc (if di_block = False)

pmagpy.ipmag.lat_from_inc(inc, a95=None)[source]#

Calculate paleolatitude from inclination using the dipole equation.

Parameter:

inc: (paleo)magnetic inclination in degrees a95: 95% confidence interval from Fisher mean

Returns:

if a95 is provided paleo_lat, paleo_lat_max, paleo_lat_min are returned otherwise, it just returns paleo_lat

Examples

Calculate the paleolatitude implied by an inclination of 45 degrees:

>>> ipmag.lat_from_inc(45)
26.56505117707799

Calculate the paleolatitude and the maximum and minimum paleolatitude implied by an inclination of 20 degrees with an uncertainty on the mean (a95) of 5:

>>> ipmag.lat_from_inc(20, a95=5)
(10.314104815618196, 13.12426812279171, 7.630740212430057)
pmagpy.ipmag.lat_from_pole(ref_loc_lon, ref_loc_lat, pole_plon, pole_plat)[source]#

Calculate paleolatitude for a reference location based on a paleomagnetic pole.

Parameters:
  • ref_loc_lon – longitude of reference location in degrees E

  • ref_loc_lat – latitude of reference location in degrees N

  • pole_plon – paleopole longitude in degrees in degrees E

  • pole_plat – paleopole latitude in degrees in degrees N

Returns:

paleolatitude for location based on pole

pmagpy.ipmag.mad_to_a95(mad, n_steps, anchored=False)[source]#

Convert MAD (or aMAD) to α95 using the scaling factors of Khokhlov & Hulot (2016), Table 8.

Parameters:
  • mad (float or array-like) – MAD (for standard PCA) or aMAD (for anchored PCA), in degrees.

  • n_steps (int or array-like of int) – Number of vector measurements (demagnetization steps) used in the line fit. Can be a scalar (applied to all MAD values) or an array with the same shape as mad to allow different n_steps for different specimens. Table 8 of Khokhlov & Hulot (2016) is defined for 3 <= n_steps <= 16. For n_steps > 16, the large-N asymptotic scaling factor is applied.

  • anchored (bool, default False) – If False, use CMAD factors for standard (unanchored) PCA MAD. If True, use CaMAD factors for anchored PCA aMAD. If an array of bool is provided, it must have the same shape as mad.

Returns:

a95 – Estimated α95 in degrees, with the same shape as mad.

Return type:

float or array-like

Notes

For n_steps < 3, this function raises a ValueError because Table 8 is not defined for fewer than three measurements. For n_steps > 16, the asymptotic large-N scaling factor tabulated at n = 100 in Khokhlov & Hulot (2016) is used.

Examples

Convert a MAD value of 4.2 determined from an anchored line fit with 7 steps to α95: >>> ipmag.mad_to_a95(4.2, n_steps=7, anchored=True) >>> 18.102

Convert arrays of MAD values with different n_steps for each specimen: >>> mads = np.array([2.0, 3.0, 4.0]) >>> steps = np.array([5, 7, 10]) >>> ipmag.mad_to_a95(mads, n_steps=steps, anchored=False) array([ 6.36 , 8.13 , 10.16 ])

pmagpy.ipmag.make_di_block(dec, inc, unit_vector=True)[source]#

Some pmag.py and ipmag.py functions require or will take a list of unit vectors [dec,inc,1.] as input. This function takes declination and inclination data and make it into such a nested list of lists.

Parameters:
  • dec – list of declinations

  • inc – list of inclinations

  • unit_vector – if True will return [dec,inc,1.]; if False will return [dec,inc]

Returns:

di_block

nested list of declination, inclination lists

Examples

>>> decs = [180.3, 179.2, 177.2]
>>> incs = [12.1, 13.7, 11.9]
>>> ipmag.make_di_block(decs,incs)
[[180.3, 12.1, 1.0], [179.2, 13.7, 1.0], [177.2, 11.9, 1.0]]
pmagpy.ipmag.make_diddd_array(dec, inc, dip_direction, dip)[source]#
Some pmag.py functions such as the bootstrap fold test require a numpy array

of dec, inc, dip direction, dip [dec, inc, dd, dip] as input. This function makes such an array.

Parameters:
  • dec – paleomagnetic declination in degrees

  • inc – paleomagnetic inclination in degrees

  • dip_direction – the dip direction of bedding (in degrees between 0 and 360)

  • dip – dip of bedding (in degrees)

Returns:

array

an array of [dec, inc, dip_direction, dip]

Examples

Data in separate lists of dec, inc, dip_direction, dip data can be made into an array.

>>> dec = [132.5,124.3,142.7,130.3,163.2]
>>> inc = [12.1,23.2,34.2,37.7,32.6]
>>> dip_direction = [265.0,265.0,265.0,164.0,164.0]
>>> dip = [20.0,20.0,20.0,72.0,72.0]
>>> data_array = ipmag.make_diddd_array(dec,inc,dip_direction,dip)
>>> data_array
array([[ 132.5,   12.1,  265. ,   20. ],
[ 124.3,   23.2,  265. ,   20. ],
[ 142.7,   34.2,  265. ,   20. ],
[ 130.3,   37.7,  164. ,   72. ],
[ 163.2,   32.6,  164. ,   72. ]])
pmagpy.ipmag.make_mollweide_map(central_longitude=0, figsize=(8, 8), add_land=True, land_color='tan', land_edge_color='black', add_ocean=False, ocean_color='lightblue', grid_lines=True, lat_grid=[-180.0, -150.0, -120.0, -90.0, -60.0, -30.0, 0.0, 30.0, 60.0, 90.0, 120.0, 150.0, 180.0], lon_grid=[-180.0, -150.0, -120.0, -90.0, -60.0, -30.0, 0.0, 30.0, 60.0, 90.0, 120.0, 150.0, 180.0])[source]#

Function creates and returns a Mollweide map projection using cartopy

Parameters:
  • central_longitude – central longitude of projection (default is 0)

  • central_latitude – central latitude of projection (default is 0)

  • figsize – size of the figure (default is 8x8)

  • add_land – chose whether land is plotted on map (default is True)

  • land_color – specify land color (default is ‘tan’)

  • add_ocean – chose whether land is plotted on map (default is False, change to True to plot)

  • ocean_color – specify ocean color (default is ‘lightblue’)

  • grid_lines – chose whether grid lines are plotted on map (default is true)

  • lat_grid – specify the latitude grid (default is 30 degree spacing)

  • lon_grid – specify the longitude grid (default is 30 degree spacing)

Examples

>>> map_axis = make_mollweide_map(central_longitude=200)
pmagpy.ipmag.make_orthographic_map(central_longitude=0, central_latitude=0, figsize=(8, 8), add_land=True, land_color='tan', land_edge_color='black', add_ocean=False, ocean_color='lightblue', grid_lines=True, lat_grid=[-80.0, -60.0, -30.0, 0.0, 30.0, 60.0, 80.0], lon_grid=[-180.0, -150.0, -120.0, -90.0, -60.0, -30.0, 0.0, 30.0, 60.0, 90.0, 120.0, 150.0, 180.0])[source]#

Function creates and returns an orthographic map projection using cartopy

Parameters:
  • central_longitude – central longitude of projection (default is 0)

  • central_latitude – central latitude of projection (default is 0)

  • figsize – size of the figure (default is 8x8)

  • add_land – chose whether land is plotted on map (default is true)

  • land_color – specify land color (default is ‘tan’)

  • add_ocean – chose whether land is plotted on map (default is False, change to True to plot)

  • ocean_color – specify ocean color (default is ‘lightblue’)

  • grid_lines – chose whether grid lines are plotted on map (default is true)

  • lat_grid – specify the latitude grid (default is 30 degree spacing)

  • lon_grid – specify the longitude grid (default is 30 degree spacing)

Examples

>>> map_axis = make_orthographic_map(central_longitude=200,central_latitude=30)
pmagpy.ipmag.make_robinson_map(central_longitude=0, figsize=(8, 8), add_land=True, land_color='tan', add_ocean=False, ocean_color='lightblue', grid_lines=True, lat_grid=[-180.0, -150.0, -120.0, -90.0, -60.0, -30.0, 0.0, 30.0, 60.0, 90.0, 120.0, 150.0, 180.0], lon_grid=[-180.0, -150.0, -120.0, -90.0, -60.0, -30.0, 0.0, 30.0, 60.0, 90.0, 120.0, 150.0, 180.0])[source]#

Function creates and returns a Robinson map projection using cartopy

Parameters:
  • central_longitude – central longitude of projection (default is 0)

  • central_latitude – central latitude of projection (default is 0)

  • figsize – size of the figure (default is 8x8)

  • add_land – chose whether land is plotted on map (default is True)

  • land_color – specify land color (default is ‘tan’)

  • add_ocean – chose whether land is plotted on map (default is False, change to True to plot)

  • ocean_color – specify ocean color (default is ‘lightblue’)

  • grid_lines – chose whether grid lines are plotted on map (default is true)

  • lat_grid – specify the latitude grid (default is 30 degree spacing)

  • lon_grid – specify the longitude grid (default is 30 degree spacing)

Examples

>>> map_axis = make_Robinson_map(central_longitude=200)
pmagpy.ipmag.mean_bootstrap_confidence(dec=None, inc=None, di_block=None, num_sims=10000, alpha=0.05, random_seed=None)[source]#

Estimates the bootstrap confidence region for the mean of a collection of paleomagnetic directions based on the approach of Heslop et al. (2023). This approach involves the projection onto a tangent plane for a tractable statistical analysis in two dimensions.

Parameters:
  • dec (list or None) – List of declination values. Default is None.

  • inc (list or None) – List of inclination values. Default is None.

  • di_block (list or None) – List of [dec, inc] pairs. Default is None. A di_block can be provided instead of dec, inc lists in which case it will be used. Either dec, inc lists or a di_block needs to be provided.

  • num_sims (int) – Number of bootstrap iterations. Default is 10,000.

  • alpha (float) – Confidence region. Default is 0.05 corresponding to 95% region.

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

A tuple containing:

(1) a dictionary of parameters the includes the estimated mean direction and the T statistic which is the basis of the bootstrap confidence region, (2) list of [dec, inc] pairs that represent the boundary of the confidence region. The bootstrap confidence region cannot be reported readily in a compact form so is instead a long list of points along the boundary of the confidence region.

Return type:

tuple

References

Heslop, D., Scealy, J. L., Wood, A. T. A., Tauxe, L., & Roberts, A. P. (2023). A bootstrap common mean direction test. Journal of Geophysical Research: Solid Earth, 128, e2023JB026983. https://doi.org/10.1029/2023JB026983

pmagpy.ipmag.orientation_magic(or_con=1, dec_correction_con=1, dec_correction=0, bed_correction=True, samp_con='1', hours_from_gmt=0, method_codes='', average_bedding=False, orient_file='orient.txt', samp_file='samples.txt', site_file='sites.txt', output_dir_path='.', input_dir_path='', append=False, data_model=3)[source]#

use this function to convert tab delimited field notebook information to MagIC formatted tables (er_samples and er_sites)

INPUT FORMAT

Input files must be tab delimited and have in the first line:

tab location_name
Note: The “location_name” will facilitate searching in the MagIC database. Data from different
“locations” should be put in separate files. The definition of a “location” is rather loose.

Also this is the word ‘tab’ not a tab, which will be indicated by ‘ ‘.

The second line has the names of the columns (tab delimited), e.g.: site_name sample_name mag_azimuth field_dip date lat long sample_lithology sample_type sample_class shadow_angle hhmm stratigraphic_height bedding_dip_direction bedding_dip GPS_baseline image_name image_look image_photographer participants method_codes site_description sample_description GPS_Az, sample_igsn, sample_texture, sample_cooling_rate, cooling_rate_corr, cooling_rate_mcd

defaults: orientation_magic(or_con=1, dec_correction_con=1, dec_correction=0, bed_correction=True, samp_con=’1’, hours_from_gmt=0, method_codes=’’, average_bedding=False, orient_file=’orient.txt’, samp_file=’er_samples.txt’, site_file=’er_sites.txt’, output_dir_path=’.’, input_dir_path=’’, append=False): orientation conventions:

[1] Standard Pomeroy convention of azimuth and hade (degrees from vertical down)

of the drill direction (field arrow). lab arrow azimuth= sample_azimuth = mag_azimuth; lab arrow dip = sample_dip =-field_dip. i.e. the lab arrow dip is minus the hade.

[2] Field arrow is the strike of the plane orthogonal to the drill direction,

Field dip is the hade of the drill direction. Lab arrow azimuth = mag_azimuth-90 Lab arrow dip = -field_dip

[3] Lab arrow is the same as the drill direction;

hade was measured in the field. Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip

[4] lab azimuth and dip are same as mag_azimuth, field_dip : use this for unoriented samples too [5] Same as AZDIP convention explained below -

azimuth and inclination of the drill direction are mag_azimuth and field_dip; lab arrow is as in [1] above. lab azimuth is same as mag_azimuth,lab arrow dip=field_dip-90

[6] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = 90-field_dip [7] see http://earthref.org/PmagPy/cookbook/#field_info for more information. You can customize other format yourself, or email ltauxe@ucsd.edu for help. [8] Lab arrow azimuth = mag_azimuth-180; Lab arrow dip = 90-field_dip

Magnetic declination convention:

[1] Use the IGRF value at the lat/long and date supplied [default] [2] Will supply declination correction [3] mag_az is already corrected in file [4] Correct mag_az but not bedding_dip_dir

Sample naming convention:
[1] XXXXY: where XXXX is an arbitrary length site designation and Y

is the single character sample designation. e.g., TG001a is the first sample from site TG001. [default]

[2] XXXX-YY: YY sample from site XXXX (XXX, YY of arbitrary length) [3] XXXX.YY: YY sample from site XXXX (XXX, YY of arbitrary length) [4-Z] XXXX[YYY]: YYY is sample designation with Z characters from site XXX [5] site name = sample name [6] site name entered in site_name column in the orient.txt format input file – NOT CURRENTLY SUPPORTED [7-Z] [XXX]YYY: XXX is site designation with Z characters from samples XXXYYY NB: all others you will have to either customize your

self or e-mail ltauxe@ucsd.edu for help.

Note

  1. column order doesn’t matter but the NAMES do.

  2. sample_name, sample_lithology, sample_type, sample_class, lat and long are required. all others are optional.

  3. If subsequent data are the same (e.g., date, bedding orientation, participants, stratigraphic_height),

    you can leave the field blank and the program will fill in the last recorded information. BUT if you really want a blank stratigraphic_height, enter a ‘-1’. These will not be inherited and must be specified for each entry: image_name, look, photographer or method_codes

  4. hhmm must be in the format: hh:mm and the hh must be in 24 hour time.

date must be mm/dd/yy (years < 50 will be converted to 20yy and >50 will be assumed 19yy). hours_from_gmt is the number of hours to SUBTRACT from hh to get to GMT.
  1. image_name, image_look and image_photographer are colon delimited lists of file name (e.g., IMG_001.jpg) image look direction and the name of the photographer respectively. If all images had same look and photographer, just enter info once. The images will be assigned to the site for which they were taken - not at the sample level.

  2. participants: Names of who helped take the samples. These must be a colon delimited list.

  3. method_codes: Special method codes on a sample level, e.g., SO-GT5 which means the orientation is has an uncertainty of >5 degrees

    for example if it broke off before orienting….

  4. GPS_Az is the place to put directly determined GPS Azimuths, using, e.g., points along the drill direction.

  5. sample_cooling_rate is the cooling rate in K per Ma

  6. int_corr_cooling_rate

  7. cooling_rate_mcd: data adjustment method code for cooling rate correction; DA-CR-EG is educated guess; DA-CR-PS is percent estimated from pilot samples; DA-CR-TRM is comparison between 2 TRMs acquired with slow and rapid cooling rates. is the percent cooling rate factor to apply to specimens from this sample, DA-CR-XX is the method code

pmagpy.ipmag.plate_rate_mc(pole1_plon, pole1_plat, pole1_kappa, pole1_N, pole1_age, pole1_age_error, pole2_plon, pole2_plat, pole2_kappa, pole2_N, pole2_age, pole2_age_error, ref_loc_lon, ref_loc_lat, samplesize=10000, random_seed=None, plot=True, savefig=True, save_directory='./', figure_name='')[source]#

Determine the latitudinal motion implied by a pair of poles and utilize the Monte Carlo sampling method of Swanson-Hysell (2014) to determine the associated uncertainty.

Parameters:=

plon : longitude of pole plat : latitude of pole kappa : Fisher precision parameter for VPGs in pole N : number of VGPs in pole age : age assigned to pole in Ma age_error : 1 sigma age uncertainty in million years ref_loc_lon : longitude of reference location ref_loc_lat : latitude of reference location samplesize : number of draws from pole and age distributions (default set to 10000) random_seed : set random seed for reproducible number generation (default is None) plot : whether to make figures (default is True, optional) savefig : whether to save figures (default is True, optional) save_directory = default is local directory (optional) figure_name = prefix for file names (optional)

Returns:

rate of latitudinal motion in cm/yr along with estimated 2.5 and 97.5

percentile rate estimates

pmagpy.ipmag.plot_aniso(fignum, aniso_df, Dir=[], PDir=[], ipar=False, ihext=True, ivec=False, iboot=False, vec=0, num_bootstraps=1000, title='', plot_mean=True)[source]#

Plot anisotropy eigenvectors and optional mean-tensor confidence estimates.

The first figure (fignum) shows the individual specimen eigenvectors (V1 squares, V2 triangles, V3 circles) on an equal-area net. When plot_mean is True, a second figure (fignum+1) shows the eigenvectors of the mean tensor with confidence estimates: Hext ellipses and/or bootstrapped eigenvectors or bootstrap ellipses, with additional figures for bootstrap eigenvalue and eigenvector-component CDFs as requested.

Parameters:
  • fignum (int) – matplotlib figure number for the eigenvector plot; the mean-tensor figure uses fignum+1 and bootstrap CDF figures use fignum+2 onward

  • aniso_df (pandas DataFrame) – anisotropy data with an ‘aniso_s’ column of colon-delimited six-element tensor strings (MagIC data model format)

  • Dir (list) – [declination, inclination] of a comparison direction plotted on the mean-tensor figure and, with iboot and ivec, compared against the bootstrapped components of the eigenvector selected by vec

  • PDir (list) – [declination, inclination] of the pole to a comparison plane, plotted as a great circle on the mean-tensor figure

  • ipar (bool, default False) – if True, the bootstrap resamples parametrically using the within-specimen uncertainty

  • ihext (bool, default True) – if True, plot Hext confidence ellipses on the mean-tensor figure

  • ivec (bool, default False) – if True, plot the bootstrapped eigenvectors themselves along with eigenvalue CDFs, instead of bootstrap confidence ellipses

  • iboot (bool, default False) – if True, calculate bootstrap statistics for the mean tensor

  • vec (int, default 0) – eigenvector (1, 2, or 3) whose bootstrapped cartesian components are compared against Dir (requires iboot and ivec)

  • num_bootstraps (int, default 1000) – number of bootstrap pseudo-samples

  • title (str, default "") – title for the eigenvector plot

  • plot_mean (bool, default True) – whether to plot the mean tensor at all: if False, only the individual specimen eigenvectors are plotted and the mean-tensor figure (with its Hext/bootstrap confidence estimates) is skipped, e.g. for unoriented cores where a mean direction is not meaningful

Returns:

figs – figure labels mapped to figure numbers: ‘data’ for the eigenvector plot, plus ‘conf’ and bootstrap CDF entries (‘tcdf’, ‘cdf_0’, …) when plot_mean and the relevant options are set

Return type:

dict

pmagpy.ipmag.plot_bootstrap_confidence(mean_dec, mean_inc, confidence_DI, mean_color='k', confidence_color='k', mean_marker='o', confidence_marker='.', mean_markersize=20, confidence_markersize=1)[source]#

Plot mean and bootstrap confidence outline on an equal area plot. The input confidence_DI is the output from the mean_bootstrap_confidence() function.

Before this function is called a plot needs to be initialized with code that looks something like: >fignum = 1 >plt.figure(num=fignum,figsize=(10,10),dpi=160) >ipmag.plot_net(fignum)

Parameters:
  • mean_dec – Declination of the mean point.

  • mean_inc – Inclination of the mean point.

  • confidence_DI – A nested list of [dec, inc, 1.0] representing the bootstrap confidence.

  • mean_color – Color of the mean point. Default is black.

  • confidence_color – Color of the confidence points. Default is black.

  • mean_marker – Marker style for the mean point. Default is ‘o’ (circle).

  • confidence_marker – Marker style for the confidence points. Default is ‘o’ (circle).

  • mean_markersize – Marker size for the mean point. Default is 20.

  • confidence_markersize – Marker size for the confidence points. Default is 1.

pmagpy.ipmag.plot_di(dec=None, inc=None, di_block=None, color='k', marker='o', markersize=20, legend='no', label='', connect_points=False, lw=0.25, lc='k', la=0.5, title=None, edge=None, alpha=1, zorder=2)[source]#

Plot declination, inclination data on an equal area plot.

Before this function is called a plot needs to be initialized with code that looks something like: >fignum = 1 >plt.figure(num=fignum,figsize=(10,10),dpi=160) >ipmag.plot_net(fignum)

Parameters:
  • dec – declination being plotted

  • inc – inclination being plotted

  • di_block – a nested list of [dec,inc,1.0] (di_block can be provided instead of dec, inc in which case it will be used)

  • color – the default color is black. Other colors can be chosen (e.g. ‘r’)

  • marker – the default marker is a circle (‘o’)

  • markersize – default size is 20

  • legend – the default is no legend (‘no’). Putting ‘yes’ will plot a legend.

  • label – the default label is blank (‘’)

  • connect_points – option to connect points in order of plotting, default is False

  • lw – linewidth of connecting lines

  • lc – color of connecting lines

  • la – alpha of connecting lines

  • title – the default title is False

  • edge – marker edge color - if blank, is color of marker

  • alpha – opacity

  • zorder – zorder of marker

pmagpy.ipmag.plot_di_mean(dec, inc, a95, color='k', marker='o', markersize=20, label='', legend='no', zorder=2)[source]#

Plot a mean direction (declination, inclination) with alpha_95 ellipse on an equal area plot.

Before this function is called, a plot needs to be initialized with code that looks something like: >fignum = 1 >plt.figure(num=fignum,figsize=(10,10),dpi=160) >ipmag.plot_net(fignum)

Parameters:
  • dec – declination of mean being plotted

  • inc – inclination of mean being plotted

  • a95 – a95 confidence ellipse of mean being plotted

  • color – the default color is black. Other colors can be chosen (e.g. ‘r’).

  • marker – the default is a circle. Other symbols can be chosen (e.g. ‘s’).

  • markersize – the default is 20. Other sizes can be chosen.

  • label – the default is no label. Labels can be assigned.

  • legend – the default is no legend (‘no’). Putting ‘yes’ will plot a legend.

  • zorder – zorder of marker

pmagpy.ipmag.plot_di_mean_bingham(bingham_dictionary, fignum=1, color='k', marker='o', markersize=20, label='', legend='no')[source]#

see plot_di_mean_ellipse

pmagpy.ipmag.plot_di_mean_ellipse(dictionary, fignum=1, color='k', marker='o', markersize=20, label='', legend='no')[source]#

Plot a mean direction (declination, inclination) confidence ellipse.

Parameters:

dictionary – a dictionary generated by the pmag.dobingham or pmag.dokent functions

pmagpy.ipmag.plot_distributions(ax, lon_samples, lat_samples, to_plot='d', resolution=100, **kwargs)[source]#

plot distributions of a group of vectors on a unit sphere

Parameters:
  • ax – matplotlib axis

  • lon_samples – a list or array of longitude samples

  • lat_samples – a list or array of latitude samples

  • to_plot – the type of distribution plot to show, can be ‘d’ as colormesh, ‘e’ as contour, ‘s’ as discrete scatter plots

  • resolution – the resolution at which to plot the distributions

  • kwargs – other keyword arguments inherited from matplotlib

pmagpy.ipmag.plot_dmag(data='', title='', fignum=1, norm=1, dmag_key='treat_ac_field', intensity='', quality=False)[source]#

plots demagenetization data versus step for all specimens in pandas dataframe datablock

Parameters:
  • data – Pandas dataframe with MagIC data model 3 columns:

  • fignum – figure number

  • specimen – specimen name

  • dmag_key – one of these: [‘treat_temp’,’treat_ac_field’,’treat_mw_energy’] selected using method_codes : [‘LT_T-Z’,’LT-AF-Z’,’LT-M-Z’] respectively

  • intensity – if blank will choose one of these: [‘magn_moment’, ‘magn_volume’, ‘magn_mass’]

  • quality – if True use the quality column of the DataFrame

  • title – title for plot

  • norm – if True, normalize data to first step

Returns:

matptlotlib plot

pmagpy.ipmag.plot_gc(poles, color='g', fignum=1)[source]#

plots a great circle on an equal area projection

Parameters:
  • fignum – number of matplotlib object

  • poles – nested list of [Dec,Inc] pairs of poles

  • color – color of lower hemisphere dots for great circle - must be in form: ‘g’,’r’,’y’,’k’,etc. upper hemisphere is always cyan

pmagpy.ipmag.plot_net(fignum=None, tick_spacing=10, ax=None, label_directions=False, label_type='cardinal')[source]#

Draws circle and tick marks for equal area projection.

Parameters:
  • fignum – int or None Figure number to use for creating a new figure if no axis is provided.

  • tick_spacing – int Interval for declination tick marks, default is 10.

  • ax – matplotlib.axes.Axes or None Axis to plot on. If None, the current axis will be used (or created if fignum is given).

  • label_directions – bool If True, label the directions around the perimeter of the net. Default is False.

  • label_type –

    str Style of perimeter labels used when label_directions is True. Options are:

    ’cardinal’ (default): N, E, S, W ‘numeric’: 000, 090, 180, 270 ‘numeric_degree’: 0°, 90°, 180°, 270° ‘slotz_special’: 0° at the top (N) and 90° at the right (E),

    with the bottom and left positions left blank.

pmagpy.ipmag.plot_pole(map_axis, plon, plat, A95, label='', color='k', edgecolor='k', marker='o', markersize=20, legend='no', outline=True, filled_pole=False, fill_color='k', fill_alpha=1.0, mean_alpha=1.0, A95_alpha=1.0, zorder=100)[source]#

This function plots a paleomagnetic pole and A95 error ellipse on a cartopy map axis.

Before this function is called, a plot needs to be initialized with code such as that in the make_orthographic_map function.

Parameters:
  • map_axis – the name of the current map axis that has been developed using cartopy

  • plon – the longitude of the paleomagnetic pole being plotted (in degrees E)

  • plat – the latitude of the paleomagnetic pole being plotted (in degrees)

  • A95 – the A_95 confidence ellipse of the paleomagnetic pole (in degrees)

  • color – symbol color; the default color is black. Other colors can be chosen (e.g. ‘r’)

  • marker – the default marker is a circle. Other symbols can be chosen (e.g. ‘s’)

  • markersize – the default is 20. Other size can be chosen

  • label – the default is no label. Labels can be assigned.

  • legend – the default is no legend (‘no’). Putting ‘yes’ will plot a legend.

  • filled_pole – if True, the A95 ellipse will be filled with color

  • fill_color – color of fill; the default is black.

  • fill_alpha – transparency of filled ellipse (the default is 1.0; no transparency).

  • mean_alpha – transparency of pole mean (the default is 1.0; no transparency).

  • zorder – plotting order (default is 100; higher will move to top of plot)

Examples

>>> plon = 200
>>> plat = 60
>>> A95 = 6
>>> map_axis = ipmag.make_orthographic_map(central_longitude=200,central_latitude=30)
>>> ipmag.plot_pole(map_axis, plon, plat, A95 ,color='red',markersize=40, zorder=20)
pmagpy.ipmag.plot_pole_dp_dm(map_axis, plon, plat, slon, slat, dp, dm, pole_label='pole', site_label='site', pole_color='k', pole_edgecolor='k', pole_marker='o', site_color='r', site_edgecolor='r', site_marker='s', markersize=20, legend=True, transform='PlateCarree')[source]#

This function plots a paleomagnetic pole and a dp/dm confidence ellipse on a cartopy map axis.

Before this function is called, a plot needs to be initialized with code such as that in the make_orthographic_map function.

Parameters:
  • map_axis – the name of the current map axis that has been developed using cartopy

  • plon – the longitude of the paleomagnetic pole being plotted (in degrees E)

  • plat – the latitude of the paleomagnetic pole being plotted (in degrees)

  • slon – the longitude of the site (in degrees E)

  • slat – the latitude of the site (in degrees)

  • dp – the semi-minor axis of the confidence ellipse (in degrees)

  • dm – the semi-major axis of the confidence ellipse (in degrees)

  • pole_color – the default color is black. Other colors can be chosen (e.g. ‘g’)

  • site_color – the default color is red. Other colors can be chosen (e.g. ‘g’)

  • pole_marker – the default is a circle. Other symbols can be chosen (e.g. ‘s’)

  • site_marker – the default is a square. Other symbols can be chosen (e.g. ‘^’)

  • markersize – the default is 20. Other size can be chosen

  • pole_label – string that labels the pole.

  • site_label – string that labels the site

  • legend – the default is a legend (True). Putting False will suppress legend plotting.

  • transform – str or cartopy.crs.Projection, default “PlateCarree” The coordinate reference system used to interpret input coordinates. Can be a string (“PlateCarree” or “Geodetic”) or a Cartopy CRS object (e.g., ccrs.PlateCarree()). If a string is provided, it will be internally mapped to the appropriate Cartopy transform. This parameter rarely needs to be changed, but “Geodetic” may help in certain projections.

Examples

>>> dec = 280
>>> inc = 45
>>> a95 = 5
>>> site_lat = 45
>>> site_lon = -100
>>> pole = pmag.dia_vgp(dec, inc, a95, site_lat, site_lon)
>>> pole_lon = pole[0]
>>> pole_lat = pole[1]
>>> dp = pole[2]
>>> dm = pole[3]
>>> map_axis = ipmag.make_orthographic_map(central_longitude=200,central_latitude=30)
>>> ipmag.plot_pole_dp_dm(map_axis,pole_lon,pole_lat,site_lon,site_lat,dp,dm)
pmagpy.ipmag.plot_pole_ellipse(map_axis, dictionary, color='k', edgecolor='k', marker='s', markersize=20, label='', alpha=1.0, lw=1, lower=True, zorder=100)[source]#

Plot a mean pole confidence ellipse associated with a Kent distribution

Parameters:
  • map_axis – the name of the current map axis that has been developed using cartopy

  • dictionary – a dictionary generated by the pmag.dobingham or pmag.dokent functions

  • color – symbol color; the default color is black. Other colors can be chosen (e.g. ‘r’)

  • marker – the default marker is a circle. Other symbols can be chosen (e.g. ‘s’)

  • markersize – the default is 20. Other size can be chosen

  • label – the default is no label. Labels can be assigned.

  • legend – the default is no legend (‘no’). Putting ‘yes’ will plot a legend.

  • filled_pole – if True, the A95 ellipse will be filled with color

  • fill_color – color of fill; the default is black.

  • fill_alpha – transparency of filled ellipse (the default is 1.0; no transparency).

  • lower – hemisphere to plot the ellipse when calling function pmagplotlib.plot_ell (default is True)

  • zorder – plotting order (default is 100; higher will move to top of plot)

Examples

>>> kent_dict = {'dec': 287.53798364307437,
            'inc': 88.56067392991959,
            'n': 5,
            'Zdec': 54.83073632264832,
            'Zinc': 0.8721861867684042,
            'Edec': 144.84816793561657,
            'Einc': 1.1448791390804505,
            'Zeta': 4.640345964184263,
            'Eta': 6.8378968512569465,
            'R1': 0.9914595207919079,
            'R2': 0.006259515780690272}
>>> map_axis = ipmag.make_orthographic_map(central_longitude=200,central_latitude=90)
>>> ipmag.plot_pole_ellipse(map_axis,kent_dict, color='red',markersize=40)
pmagpy.ipmag.plot_poles(map_axis, plon, plat, A95, label='', color='k', edgecolor='k', marker='o', markersize=20, legend='no', outline=True, filled_pole=False, fill_color='k', fill_alpha=1.0, alpha=1.0, zorder=101, lw=1)[source]#

This function plots paleomagnetic poles and A95 error ellipses on a cartopy map axis.

Before this function is called, a plot needs to be initialized with code such as that in the make_orthographic_map function.

Parameters:
  • map_axis – the name of the current map axis that has been developed using cartopy

  • plon – the longitude of the paleomagnetic pole being plotted (in degrees E)

  • plat – the latitude of the paleomagnetic pole being plotted (in degrees)

  • A95 – the A_95 confidence ellipse of the paleomagnetic pole (in degrees)

  • color – the default color is black. Other colors can be chosen (e.g. ‘r’) a list of colors can also be given so that each pole has a distinct color

  • edgecolor – the default edgecolor is black. Other colors can be chosen (e.g. ‘r’)

  • marker – the default is a circle. Other symbols can be chosen (e.g. ‘s’)

  • markersize – the default is 20. Other size can be chosen

  • label – the default is no label. Labels can be assigned.

  • legend – the default is no legend (‘no’). Putting ‘yes’ will plot a legend.

  • filled_pole – if True, the A95 ellipse will be filled with color

  • fill_color – color of fill; the default is black.

  • fill_alpha – transparency of filled ellipse (the default is 1.0; no transparency).

  • alpha – transparency of pole mean (the default is 1.0; no transparency).

  • zorder – plotting order (default is 100; higher will move to top of plot)

Examples

>>> plons = [200, 180, 210]
>>> plats = [60, 40, 35]
>>> A95s = [6, 3, 10]
>>> map_axis = ipmag.make_orthographic_map(central_longitude=200, central_latitude=30)
>>> ipmag.plot_poles(map_axis, plons, plats, A95s, color='red', markersize=40)
>>> plons = [200, 180, 210]
>>> plats = [60, 40, 35]
>>> A95s = [6, 3, 10]
>>> colors = ['red','green','blue']
>>> map_axis = ipmag.make_orthographic_map(central_longitude=200, central_latitude=30)
>>> ipmag.plot_poles(map_axis, plons, plats, A95s, color=colors, markersize=40)
pmagpy.ipmag.plot_poles_colorbar(map_axis, plons, plats, A95s, colorvalues, vmin, vmax, colormap='viridis', edgecolor='k', marker='o', markersize=20, alpha=1.0, colorbar=True, colorbar_label='pole age (Ma)', outline='True', filled_pole=False, fill_alpha=1.0, lw=1)[source]#

This function plots multiple paleomagnetic pole and A95 error ellipse on a cartopy map axis. The poles are colored by the defined colormap.

Before this function is called, a plot needs to be initialized with code such as that in the make_orthographic_map function.

Parameters:
  • map_axis – the name of the current map axis that has been developed using cartopy

  • plons – the longitude of the paleomagnetic pole being plotted (in degrees E)

  • plats – the latitude of the paleomagnetic pole being plotted (in degrees)

  • A95s – the A_95 confidence ellipse of the paleomagnetic pole (in degrees)

  • colorvalues – what attribute is being used to determine the colors

  • vmin – what is the minimum range for the colormap

  • vmax – what is the maximum range for the colormap

  • colormap – the colormap used (default is ‘viridis’; others should be put as a string with quotes, e.g. ‘plasma’)

  • edgecolor – the color desired for the symbol outline

  • marker – the marker shape desired for the pole mean symbol (default is ‘o’ aka a circle)

  • colorbar – the default is to include a colorbar (True). Putting False will make it so no legend is plotted.

  • colorbar_label – label for the colorbar

Examples

>>> plons = [200, 180, 210]
>>> plats = [60, 40, 35]
>>> A95s = [6, 3, 10]
>>> ages = [100,200,300]
>>> vmin = 0
>>> vmax = 300
>>> map_axis = ipmag.make_orthographic_map(central_longitude=200, central_latitude=30)
>>> ipmag.plot_poles_colorbar(map_axis, plons, plats, A95s, ages, vmin, vmax)
pmagpy.ipmag.plot_vgp(map_axis, vgp_lon=None, vgp_lat=None, di_block=None, label='', color='k', marker='o', edge='black', markersize=20, alpha=1, legend=False, zorder=100)[source]#

This function plots a paleomagnetic pole position onto a cartopy map axis.

Before this function is called, a map plot needs to be initialized with code such as that in the `ipmag.make_orthographic_map()` function (see example below).

Parameters:
  • map_axis – the name of the current map axis that has been developed using cartopy

  • plon – the longitude of the paleomagnetic pole being plotted (in degrees E)

  • plat – the latitude of the paleomagnetic pole being plotted (in degrees)

  • color – the color desired for the symbol (default is ‘k’ aka black)

  • marker – the marker shape desired for the pole mean symbol (default is ‘o’ aka a circle)

  • edge – the color of the edge of the marker (default is black); can be set to None to have no edge

  • markersize – size of the marker in pt (default is 20)

  • alpha – the transparency of the points (defaul is 1 which is opaque, 0 is fully transparent)

  • label – the default is no label. Labels can be assigned.

  • legend – the default is no legend (False). Putting True will plot a legend.

  • zorder – plotting order (default is 100; higher will move to top of plot)

Examples

>>> vgps = ipmag.fishrot(dec=200,inc=30)
>>> vgp_lon_list,vgp_lat_list,intensities= ipmag.unpack_di_block(vgps)
>>> map_axis = ipmag.make_orthographic_map(central_longitude=200,central_latitude=30)
>>> ipmag.plot_vgp(map_axis,vgp_lon=vgp_lon_list,vgp_lat=vgp_lat_list,color='red',markersize=40,zorder=20))
pmagpy.ipmag.pmag_results_extract(res_file='pmag_results.txt', crit_file='', spec_file='', age_file='', latex=False, grade=False, WD='.')[source]#

Generate tab delimited output file(s) with result data. Save output files and return True if successful. Possible output files: Directions, Intensities, SiteNfo, Criteria,

Specimens

Parameters:
  • res_file – name of pmag_results file (default is “pmag_results.txt”)

  • crit_file – name of criteria file (default is “pmag_criteria.txt”)

  • spec_file – name of specimen file (default is “pmag_specimens.txt”)

  • age_file – name of age file (default is “er_ages.txt”)

  • latex – boolean argument to output in LaTeX (default is False)

  • WD – path to directory that contains input files and takes output (default is current directory, ‘.’)

pmagpy.ipmag.pole_comparison_H2019(lon_1, lat_1, k_1, r_1, lon_2, lat_2, k_2, r_2)[source]#

Calculate the Bhattacharyya Coefficient, Bayes error and the Kullback-Leibler divergence associated with the comparison of paleomagnetic poles following Heslop and Roberts (2019). The divergence parameter is asymmetric such that the pole that is the reference pole should be (lon_1, lat_1, k_1, r_1) and the pole of interest being compared to that reference pole should be (lon_2, lat_2, k_2, r_2).

Parameters:
  • lon_1 – longitude of pole 1 (reference pole)

  • lat_1 – latitude of pole 1

  • k_1 – Fisher concentration parameter of pole 1

  • r_1 – resultant vector length of pole 1

  • lon_2 – longitude of pole 2 (pole of interest)

  • lat_2 – latitude of pole 2

  • k_2 – Fisher concentration parameter of pole 2

  • r_2 – resultant vector length of pole 2

Returns:

  • bhattacharyya, Bhattacharyya coefficient

  • bayes, bayes error

  • kld, Kullback-Leibler divergence

Notes

This function utilizes code developed by D. Heslop dave-heslop74/kld dave-heslop74/bhattacharyya

pmagpy.ipmag.polemap_magic(loc_file='locations.txt', dir_path='.', interactive=False, crd='', sym='ro', symsize=40, rsym='g^', rsymsize=40, fmt='pdf', res='c', proj='ortho', flip=False, anti=False, fancy=False, ell=False, ages=False, lat_0=90.0, lon_0=0.0, save_plots=True, contribution=None, image_records=False)[source]#

Use a MagIC format locations table to plot poles.

Parameters:
  • loc_file – str, default “locations.txt”

  • dir_path – str, default “.” directory name to find loc_file in (if not included in loc_file)

  • interactive – bool, default False

  • True (if) – (this is best used on the command line only)

  • display (interactively plot and) – (this is best used on the command line only)

  • crd – str, default “”

  • [g (coordinate system)

  • t] (geographic, tilt_corrected)

  • sym – str, default “ro” symbol color and shape, default red circles (see matplotlib documentation for more options)

  • symsize – int, default 40 symbol size

  • rsym – str, default “g^” symbol for plotting reverse poles

  • rsymsize – int, default 40 symbol size for reverse poles

  • fmt – str, default “pdf” format for figures, [“svg”, “jpg”, “pdf”, “png”]

  • res – str, default “c” resolution [c, l, i, h] (crude, low, intermediate, high)

  • proj – str, default “ortho” ortho = orthographic lcc = lambert conformal moll = molweide merc = mercator

  • flip – bool, default False if True, flip reverse poles to normal antipode

  • anti – bool, default False if True, plot antipodes for each pole

  • fancy – bool, default False if True, plot topography (not yet implementedj)

  • ell – bool, default False if True, plot ellipses

  • ages – bool, default False if True, plot ages

  • lat_0 – float, default 90. eyeball latitude

  • lon_0 – float, default 0. eyeball longitude

  • save_plots – bool, default True if True, create and save all requested plots

  • image_records – generate and return a record for each image in a list of dicts which can be ingested by pmag.magic_write bool, default False

Returns:

if image_records == False

True or False indicating if conversion was successful, file name(s) written

if image_records == True

True or False indicating if conversion was successful, output file name written, list of image recs

pmagpy.ipmag.print_direction_mean(mean_dictionary)[source]#

Does a pretty job printing a Fisher mean and associated statistics for directional data.

Parameters:

mean_dictionary – output dictionary of pmag.fisher_mean()

Returns:

prints the mean and associated statistics

Examples

Generate a Fisher mean using ipmag.fisher_mean() and then print it nicely using ipmag.print_direction_mean()

>>> my_mean = ipmag.fisher_mean(di_block=[[140,21],[127,23],[142,19],[136,22]])
>>> ipmag.print_direction_mean(my_mean)
Dec: 136.3  Inc: 21.3
Number of directions in mean (n): 4
Angular radius of 95% confidence (a_95): 7.3
Precision parameter (k) estimate: 159.7
pmagpy.ipmag.print_kent_mean(mean_dictionary)[source]#

Does a pretty job printing a Kent mean and associated statistics.

Parameters:

mean_dictionary – output dictionary of ipmag.kent_mean

Returns:

prints the mean and associated statistics

Examples

Generate a Kent mean using ipmag.kent_mean() and then print it nicely using ipmag.print_kent_mean() >>> my_di_block = [[183.2931831390693, 80.70169305002725, 1.0],

[75.50744693411644, 79.57922789535208, 1.0], [162.32513875820177, 76.51741087479394, 1.0], [143.8749848879392, 85.79156599168213, 1.0], [177.12011881027854, 84.02007456929348, 1.0]]

>>> my_kent_mean = ipmag.kent_mean(di_block = my_di_block)
>>> ipmag.print_kent_mean(my_kent_mean)
Plon: 150.4  Plat: 83.3
Major axis lon: 31.4  Major axis lat: 3.2
Minor axis lon: 301.0  Minor axis lat: 5.8
Major axis angle of 95% ellipse (Zeta): 6.5
Minor axis angle of 95% ellipse (Eta): 2.8
Number of directions in mean (n): 5
pmagpy.ipmag.print_pole_mean(mean_dictionary)[source]#

Does a pretty job printing a Fisher mean and associated statistics for mean paleomagnetic poles.

Parameters:

mean_dictionary – output dictionary of pmag.fisher_mean()

Returns:

prints the mean and associated statistics

Examples

Generate a Fisher mean using ipmag.fisher_mean() and then print it nicely using ipmag.print_pole_mean()

>>> my_mean = ipmag.fisher_mean(di_block=[[140,21],[127,23],[142,19],[136,22]])
>>> ipmag.print_pole_mean(my_mean)
Plon: 136.3  Plat: 21.3
Number of directions in mean (n): 4
Angular radius of 95% confidence (A_95): 7.3
Precision parameter (k) estimate: 159.7
pmagpy.ipmag.quick_hyst(dir_path='.', meas_file='measurements.txt', save_plots=True, interactive=False, fmt='png', specimen='', verbose=True, n_plots=10, contribution=None, image_records=False)[source]#

makes specimen plots of hysteresis data

Parameters:
  • dir_path (str, default ".") – input directory

  • meas_file (str, default "measurements.txt") – name of MagIC measurement file

  • save_plots (bool, default True) – save figures

  • interactive (bool, default False) – if True, interactively plot and display (this is best used on the command line only)

  • fmt (str, default "svg") – format for figures, [“svg”, “jpg”, “pdf”, “png”]

  • specimen (str, default "") – specific specimen to plot

  • verbose (bool, default True) – if True, print more verbose output

  • image_records (bool, default False) – if True, return a list of created images

Returns:

  • if image_records == False – Tuple : (True or False indicating if conversion was successful, output file name(s) written)

  • if image_records == True – Tuple : (True or False indicating if conversion was successful, output file name(s) written, list of images)

pmagpy.ipmag.rand_correlation_prob(sec_var, delta1, delta2, alpha, trials=10000, print_result=False, random_seed=None)[source]#

The function runs an algorithm from Bogue and Coe (1981; doi: 10.1029/JB086iB12p11883) for probabilistic correlation, evaluating the probability that the similarity between two paleomagnetic directions is due to random sampling of the ancient magnetic field. Original written in Python by S. Bogue, translated to PmagPy functionality by AFP.

Parameters: sec_var: kappa estimate of regional secular variation (probably 30 or 40) alpha: angle between paleomagnetic directions (or poles) delta1: distance of direction 1 from mean direction delta2: distance of direction 2 from mean direction trials: the number of simulations, default=10,000 print_result: the probability value printed as a sentence, default=False random_seed: None, int, or numpy.random.Generator, optional

Seed for reproducible Monte Carlo sampling (default None).

Returns:

float

number indicating probability value

Example

Provide estimate of regional secular variation, angle between directions, distance of each direction from a mean direction (like GAD) to return probability of random field sampling, compare to RC / 11 comparison from Table 2 of the original publication (exact value may differ due to RNG):

>>> ipmag.rand_correlation_prob(40, 17.2, 20, 3.6)
np.float64(0.0103)
pmagpy.ipmag.reversal_test_MM1990(dec=None, inc=None, di_block=None, plot_CDF=False, plot_stereo=False, save=False, save_folder='.', fmt='svg', random_seed=None)[source]#

Calculates Watson’s V statistic from input files through Monte Carlo simulation in order to test whether normal and reversed populations could have been drawn from a common mean. Also provides the critical angle between the two sample mean directions and the corresponding McFadden and McElhinny (1990) classification. This function is a wrapper around the ipmag.common_mean_watson() function with the first step of splitting the data into two polarities using the pmag.flip() function and flipping the reverse direction to their antipode.

Parameters:

dec (list, optional): List of declinations. inc (list, optional): List of inclinations. di_block (list of lists, optional): Nested list of [dec,inc]. If provided, it

takes precedence over separate dec and inc lists.

plot_CDF (bool, optional): If True, plot the CDF accompanying the results. Defaults to False. plot_stereo (bool, optional): If True, plot stereonet with bidirectionally separated data. Defaults to False. save (bool, optional): If True, save the plots. Defaults to False. save_folder (str, optional): Directory path for saving plots. Defaults to current directory. fmt (str, optional): Format of saved figures. Defaults to ‘svg’. random_seed (None, int, or numpy.random.Generator, optional): Seed for

reproducible Monte Carlo sampling (default None).

Returns:

0 indicates fail, 1 indicates pass. angle (float): Angle between the Fisher means of the two data sets. critical_angle (float): Critical angle for the test to pass. classification (str): MM1990 classification for a positive test.

Return type:

result (bool)

Examples

Populations of roughly antipodal directions are developed here using ipmag.fishrot. These directions are combined into a single di_block given that the function determines the principal component and splits the data accordingly by polarity.

>>> directions_n = ipmag.fishrot(k=20, n=30, dec=5, inc=-60)
>>> directions_r = ipmag.fishrot(k=35, n=25, dec=182, inc=57)
>>> directions = directions_n + directions_r
>>> ipmag.reversal_test_MM1990(di_block=directions, plot_stereo = True)

Data can also be input to the function as separate lists of dec and inc. In this example, the di_block from above is split into lists of dec and inc which are then used in the function:

>>> direction_dec, direction_inc, direction_moment = ipmag.unpack_di_block(directions)
>>> ipmag.reversal_test_MM1990(dec=direction_dec,inc=direction_inc, plot_stereo = True)
pmagpy.ipmag.reversal_test_bootstrap(dec=None, inc=None, di_block=None, plot_stereo=False, color1='blue', color2='red', save=False, save_folder='.', fmt='svg', verbose=True, random_seed=None)[source]#

Conduct a reversal test using bootstrap statistics (Tauxe, 2010) to determine whether two populations of directions could be from an antipodal common mean.

Parameters:
  • dec – list of declinations

  • inc – list of inclinations

  • di_block – a nested list of [dec,inc] A di_block can be provided in which case it will be used instead of dec, inc lists.

  • plot_stereo – before plotting the CDFs, plot stereonet with the bidirectionally separated data (default is False)

  • save – boolean argument to save plots (default is False)

  • save_folder – directory where plots will be saved (default is current directory, ‘.’)

  • fmt – format of saved figures (default is ‘svg’)

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

A boolean where 0 is fail and 1 is pass is returned. Plots of the cumulative distribution of Cartesian components are shown an equal area plot if plot_stereo = True.

Examples

Populations of roughly antipodal directions are developed here using ipmag.fishrot. These directions are combined into a single di_block given that the function determines the principal component and splits the data accordingly by polarity.

>>> directions_n = ipmag.fishrot(k=20, n=30, dec=5, inc=-60)
>>> directions_r = ipmag.fishrot(k=35, n=25, dec=182, inc=57)
>>> directions = directions_n + directions_r
>>> ipmag.reversal_test_bootstrap(di_block=directions, plot_stereo = True)

Data can also be input to the function as separate lists of dec and inc. In this example, the di_block from above is split into lists of dec and inc which are then used in the function:

>>> direction_dec, direction_inc, direction_moment = ipmag.unpack_di_block(directions)
>>> ipmag.reversal_test_bootstrap(dec=direction_dec,inc=direction_inc, plot_stereo = True)
pmagpy.ipmag.reversal_test_bootstrap_H23(dec=None, inc=None, di_block=None, num_sims=10000, alpha=0.05, plot=True, save=False, save_folder='.', fmt='svg', verbose=True, random_seed=None)[source]#

Bootstrap reversal test following Heslop et al. (2023).

This function calls common_mean_bootstrap_H23 with directional data that have been flipped, for a reversal test. The directional data can be provided either as separate declination and inclination arrays or as a di_block array.

Parameters:
  • dec (array) – Array of declinations, only considered if di_block is None.

  • inc (array) – Array of inclinations, only considered if di_block is None.

  • di_block (array, optional) – Directional data as [dec, inc] for each sample. If provided, dec and inc are ignored.

  • num_sims (int, optional) – Number of bootstrap simulations. Default is 1000.

  • alpha (float, optional) – Significance level for hypothesis testing. Default is 0.05.

  • plot (bool, optional) – If True, produce a histogram plot of the test statistic. Default is True.

  • save (bool, optional) – If True, save the histogram plot. Default is False.

  • save_folder (str, optional) – Directory where the histogram plot will be saved. Default is the current directory.

  • fmt (str, optional) – File format for saving the histogram plot. Default is ‘svg’.

  • random_seed – None, int, or numpy.random.Generator Seed for reproducible random number generation (default is None).

Returns:

Contains the following elements:
  • result (int): 0 if null hypothesis is rejected, 1 otherwise.

  • Lmin (float): The test statistic value.

  • Lmin_c (float): The critical test statistic value.

  • p (float): The p-value of the test.

Return type:

tuple

pmagpy.ipmag.sb_vgp_calc(dataframe, site_correction='yes', dec_tc='dec_tc', inc_tc='inc_tc')[source]#

This function calculates the angular dispersion of VGPs and corrects for within site dispersion (unless site_correction = ‘no’) to return a value S_b. The input data needs to be within a pandas Dataframe.

Parameters:
  • dataframe (the name of the pandas.DataFrame containing the data)

  • columns (the data frame needs to contain these)

  • dataframe['site_lat'] (latitude of the site)

  • dataframe['site_lon'] (longitude of the site)

  • dataframe['k'] (fisher precision parameter for directions)

  • dataframe['vgp_lat'] (VGP latitude)

  • dataframe['vgp_lon'] (VGP longitude)

  • ----- (----- the following default parameters can be changes by keyword argument)

  • dataframe['inc_tc'] (tilt-corrected inclination)

  • dataframe['dec_tc'] (tilt-corrected declination)

  • plot (default is 'no', will make a plot of poles if 'yes')

pmagpy.ipmag.separate_directions(dec=None, inc=None, di_block=None)[source]#

Separates directional data into two modes based on the principal direction.

Parameters:
  • dec (list, optional) – List of declinations. Defaults to None.

  • inc (list, optional) – List of inclinations. Defaults to None.

  • di_block (list of lists, optional) – Nested list of [dec,inc]. Can be provided instead of separate dec, inc lists. If provided, it takes precedence.

Returns:

Depending on input, either:
  • dec1, inc1, dec2, inc2: Lists of declinations and inclinations for the two modes (if separate dec, inc lists are provided)

  • polarity1, polarity2: Nested lists of [dec,inc] for the two modes (if di_block is provided)

Return type:

tuple

pmagpy.ipmag.shoot(lon, lat, azimuth, maxdist=None)[source]#

This function enables A95 error ellipses to be drawn around paleomagnetic poles in conjunction with equi (from: http://www.geophysique.be/2011/02/20/matplotlib-basemap-tutorial-09-drawing-circles/)

pmagpy.ipmag.simul_correlation_prob(alpha, k1, k2, trials=10000, print_result=False, random_seed=None)[source]#

The function runs an algorithm from Bogue and Coe (1981; doi: 10.1029/JB086iB12p11883) for probabilistic correlation, evaluating the probability that the similarity between two paleomagnetic directions is due to simultaneous sampling of the ancient magnetic field. Original written in Python by S. Bogue, translated to PmagPy functionality by AFP.

Parameters:
  • alpha – angle between paleomagnetic directions (site means)

  • k1 (float) – kappa estimate for first direction

  • k2 (float) – kappa estimate for second direction

  • trials (int) – the number of simulations [default = 10,000]

  • print_result (boolean) – the probability value returned in a sentence [default = False]

  • random_seed – None, int, or numpy.random.Generator, optional Seed for reproducible Monte Carlo sampling (default None).

Returns:

float

number indicating probability value

Example

Provide an angle and two precision parameter estimates to get the probability of simultaneity, compare to RC / 11 comparison from Table 2 of the original publication (exact value may differ due to RNG):

>>> ipmag.simul_correlation_prob(3.6, 391, 146)
0.8127
pmagpy.ipmag.sites_extract(site_file='sites.txt', directions_file='directions.xls', intensity_file='intensity.xls', info_file='site_info.xls', output_dir_path='.', input_dir_path='', latex=False)[source]#

Extracts directional and/or intensity data from a MagIC 3.0 format sites.txt file. Default output format is an Excel file. Optional latex format longtable file which can be uploaded to Overleaf or typeset with latex on your own computer.

Parameters:
  • site_file (str) – input file name

  • directions_file (str) – output file name for directional data

  • intensity_file (str) – output file name for intensity data

  • site_info (str) – output file name for site information (lat, lon, location, age….)

  • output_dir_path (str) – path for output files

  • input_dir_path (str) – path for intput file if different from output_dir_path (default is same)

  • latex (boolean) – if True, output file should be latex formatted table with a .tex ending

  • Return – [True,False], error type : True if successful

  • Effects – writes Excel or LaTeX formatted tables for use in publications

pmagpy.ipmag.smooth(x, window_len, window='bartlett')[source]#

Smooth the data using a sliding window with requested size - meant to be used with the ipmag function curie(). This method is based on the convolution of a scaled window with the signal. The signal is prepared by padding the beginning and the end of the signal with average of the first (last) ten values of the signal, to evoid jumps at the beginning/end. Output is an array of the smoothed signal.

Required Parameters#

x : the input signal, equally spaced! window_len : the dimension of the smoothing window

Optional Parameters (defaults are used if not specified)#

windowtype of window from numpy library [‘flat’,’hanning’,’hamming’,’bartlett’,’blackman’]

(default is Bartlett) -flat window will produce a moving average smoothing. -Bartlett window is very similar to triangular window,

but always ends with zeros at points 1 and n.

-hanning,hamming,blackman are used for smoothing the Fourier transform

pmagpy.ipmag.specimens_extract(spec_file='specimens.txt', output_file='specimens.xls', landscape=False, longtable=False, output_dir_path='.', input_dir_path='', latex=False)[source]#

Extracts specimen results from a MagIC 3.0 format specimens.txt file. Default output format is an Excel file. typeset with latex on your own computer.

Parameters:
  • spec_file (str, default "specimens.txt") – input file name

  • output_file (str, default "specimens.xls") – output file name

  • landscape (boolean, default False) – if True output latex landscape table

  • longtable (boolean) – if True output latex longtable

  • output_dir_path (str, default ".") – output file directory

  • input_dir_path (str, default "") – path for intput file if different from output_dir_path (default is same)

  • latex (boolean, default False) – if True, output file should be latex formatted table with a .tex ending

  • Return – [True,False], data table error type : True if successful

  • Effects – writes xls or latex formatted tables for use in publications

pmagpy.ipmag.specimens_results_magic(infile='pmag_specimens.txt', measfile='magic_measurements.txt', sampfile='er_samples.txt', sitefile='er_sites.txt', agefile='er_ages.txt', specout='er_specimens.txt', sampout='pmag_samples.txt', siteout='pmag_sites.txt', resout='pmag_results.txt', critout='pmag_criteria.txt', instout='magic_instruments.txt', plotsites=False, fmt='svg', dir_path='.', cors=[], priorities=['DA-AC-ARM', 'DA-AC-TRM'], coord='g', user='', vgps_level='site', do_site_intensity=True, DefaultAge=['none'], avg_directions_by_sample=False, avg_intensities_by_sample=False, avg_all_components=False, avg_by_polarity=False, skip_directions=False, skip_intensities=False, use_sample_latitude=False, use_paleolatitude=False, use_criteria='default')[source]#

Writes magic_instruments, er_specimens, pmag_samples, pmag_sites, pmag_criteria, and pmag_results. The data used to write this is obtained by reading a pmag_speciemns, a magic_measurements, a er_samples, a er_sites, a er_ages. @param -> infile: path from the WD to the pmag speciemns table @param -> measfile: path from the WD to the magic measurement file @param -> sampfile: path from the WD to the er sample file @param -> sitefile: path from the WD to the er sites data file @param -> agefile: path from the WD to the er ages data file @param -> specout: path from the WD to the place to write the er specimens data file @param -> sampout: path from the WD to the place to write the pmag samples data file @param -> siteout: path from the WD to the place to write the pmag sites data file @param -> resout: path from the WD to the place to write the pmag results data file @param -> critout: path from the WD to the place to write the pmag criteria file @param -> instout: path from th WD to the place to write the magic instruments file @param -> documentation incomplete if you know more about the purpose of the parameters in this function and it’s side effects please extend and complete this string

pmagpy.ipmag.squish(incs, f)[source]#

This function applies an flattening factor (f) to inclination data (incs) and returns ‘squished’ values.

Parameters:
  • incs (list of inclination values or a single value)

  • f (flattening factor) – A value between 0.0 and 1.0 where 1.0 is no flattening and 0.0 is complete flattening.

Returns:

incs_squished

Return type:

List of flattened directions (in degrees)

Examples

Take a list of inclinations and flatten (i.e. “squish”) them:

>>> inclinations = [43,47,41]
>>> ipmag.squish(inclinations,0.4)
[20.455818908027187, 23.216791019112204, 19.173314360172309]
pmagpy.ipmag.thellier_magic(meas_file='measurements.txt', dir_path='.', input_dir_path='', spec='', n_specs=5, save_plots=True, fmt='svg', interactive=False, contribution=None, image_records=False)[source]#

thellier_magic plots arai and other useful plots for Thellier-type experimental data

Parameters:
  • meas_file (str) – input measurement file, default “measurements.txt”

  • dir_path (str) –

    output directory, default “.” Note: if using Windows, all figures will be saved to working directly

    not dir_path

  • input_dir_path (str) – input file directory IF different from dir_path, default “”

  • spec (str) – default “”, specimen to plot

  • n_specs (int) – number of specimens to plot, default 5 if you want to make all possible plots, specify “all”

  • save_plots (bool, default True) – True, create and save all requested plots

  • fmt (str) – format of saved figures (default is ‘svg’)

  • interactive (bool, default False) – interactively plot and display for each specimen (this is best used on the command line only)

  • contribution (cb.Contribution, default None) – if provided, use Contribution object instead of reading in data from files

  • image_records (generate and return a record for each image in a list of dicts) – which can be ingested by pmag.magic_write bool, default False

Returns:

  • status (True or False)

  • saved (list of figures saved)

  • if image_records == True – image_recs : list of image records

pmagpy.ipmag.tk03(n=100, dec=0, lat=0, rev='no', G1=-18000.0, G2=0, G3=0, B_threshold=0, random_seed=None)[source]#

Generates vectors drawn from the TK03.gad model of secular variation (Tauxe and Kent, 2004) at given latitude and rotated about a vertical axis by the given declination. Returns a nested list of of [dec,inc,intensity].

Parameters:
  • n (number of vectors to determine (default is 100))

  • dec (mean declination of data set (default is 0))

  • lat (latitude at which secular variation is simulated (default is 0))

  • rev (if reversals are to be included this should be 'yes' (default is 'no'))

  • G1 (specify average g_1^0 fraction (default is -18e3 in nT, minimum = 1))

  • G2 (specify average g_2^0 fraction (default is 0))

  • G3 (specify average g_3^0 fraction (default is 0))

  • B_threshold (return vectors with B>B_threshold (in nT) (default is 0 which) – returns all vectors)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

tk_03_output

Return type:

a nested list of declination, inclination, and intensity (in nT)

Examples

>>> ipmag.tk03(n=5, dec=0, lat=0)
[[14.752502674158681, -36.189370642603834, 16584.848620957589],
 [9.2859465437113311, -10.064247301056071, 17383.950391596223],
 [2.4278460589582913, 4.8079990844938019, 18243.679003572055],
 [352.93759572283585, 0.086693343935840397, 18524.551174838372],
 [352.48366219759953, 11.579098286352332, 24928.412830772766]]
pmagpy.ipmag.transform_to_geographic(this_spec_meas_df, samp_df, samp, coord='0')[source]#

Transform decs/incs to geographic coordinates. Calls pmag.dogeo_V for the heavy lifting

Parameters:
  • this_spec_meas_df (pandas dataframe of measurements for a single specimen)

  • samp_df (pandas dataframe of samples)

  • samp (samp name)

Returns:

this_spec_meas_df

Return type:

measurements dataframe with transformed coordinates

pmagpy.ipmag.unpack_di_block(di_block)[source]#

This function unpacks a nested list of [dec,inc,mag_moment] into a list of declination values, a list of inclination values and a list of magnetic moment values. Mag_moment values are optional, while dec and inc values are required.

Parameters:

di_block (nested list of declination, inclination lists)

Returns:

  • dec (list of declinations)

  • inc (list of inclinations)

  • mag_moment (list of magnetic moment (if present in di_block))

Example

The di_block nested lists of lists can be unpacked using the function

>>> directions = [[180.3, 12.1, 1.0], [179.2, 13.7, 1.0], [177.2, 11.9, 1.0]]
>>> ipmag.unpack_di_block(directions)
([180.3, 179.2, 177.2], [12.1, 13.7, 11.9], [1.0, 1.0, 1.0])

These unpacked values can be assigned to variables:

>>> dec, inc, moment = ipmag.unpack_di_block(directions)
pmagpy.ipmag.unpack_magic(infile=None, dir_path='.', input_dir_path='', overwrite=False, print_progress=True, data_model=3.0, separate_locs=False, txt='', excel=False)[source]#

Wrapper function for ipmag.download_magic, to handle the unpacking of a MagIC contribution.

This function takes in a text file, typically downloaded from the MagIC database, and then unpacks it into MagIC-formatted files. The name emphasizes the “unpacking” nature of the operation over the “downloading” aspect.

Parameters:
  • infile – str, optional Name of the MagIC-format file to unpack.

  • dir_path – str, optional Directory path for output. Default is the current directory.

  • input_dir_path – str, optional Path to the input file if different from dir_path. Default is dir_path.

  • overwrite – bool, optional Whether to overwrite files in the current directory. Default is False.

  • print_progress – bool, optional Whether to print progress messages. Default is True.

  • data_model – float, optional Specifies the MagIC data model version, either 2.5 or 3. Default is 3.

  • separate_locs – bool, optional If True, create separate directories for each location. Default is False.

  • txt – str, optional Alternative to providing an infile, you can provide the file contents as a string. Useful for directly downloading a MagIC file from EarthRef. Default is an empty string.

  • excel – bool, optional If True, the input file is treated as an Excel spreadsheet. Default is False.

Returns:

bool

True if the unpacking operation is successful. False otherwise.

pmagpy.ipmag.unsquish(incs, f)[source]#

This function applies a flattening factor (f) to unflatten inclination data (incs) and returns ‘unsquished’ values.

Parameters:
  • incs (list of inclination values or a single value)

  • f (flattening factor) – A value greater than 0.0 and less than or equal to 1.0 that is used to unflatten inclination values. 1.0 implies no flatting and will result in no change.

Returns:

incs_unsquished

Return type:

List of unflattened inclinations (in degrees)

Examples

Take a list of inclinations, flatten them using ipmag.squish and then use ipmag.squish and the flattening factor to unflatten (i.e. “unsquish”) them:

>>> inclinations = [43,47,41]
>>> squished_incs = ipmag.squish(inclinations,0.4)
>>> ipmag.unsquish(squished_incs,0.4)
[43.0, 47.0, 41.0]
pmagpy.ipmag.upload_magic(concat=False, dir_path='.', input_dir_path='.', validate=True, verbose=True)[source]#

Finds all magic files in a given directory, and compiles them into an upload.txt file which can be uploaded into the MagIC database. If username/password set, then data will be uploaded to private workspace, otherwise validation will be done on this computer.

Parameters:
  • concat (boolean where True means do concatenate to upload.txt file in dir_path,) – False means write a new file (default is False)

  • dir_path (string for output directory (default "."))

  • input_dir_path (str, default ".")

  • validate (boolean) – validate upload file on MagIC’s public endpoint

  • verbose (boolean) – if True print progress and validation results

Returns:

  • tuple of either (True/False or (False, error_message, validation dictionary val_response[‘validation’]))

  • if there was a problem creating/validating the upload file

  • or ((filename, ‘’, None) if the file creation was fully successful.)

pmagpy.ipmag.upload_magic2(concat=0, dir_path='.', data_model=None)[source]#

Finds all magic files in a given directory, and compiles them into an upload.txt file which can be uploaded into the MagIC database. Returns a tuple of either: (False, error_message, errors) if there was a problem creating/validating the upload file or: (filename, ‘’, None) if the upload was fully successful.

pmagpy.ipmag.upload_to_private_contribution(contribution_id, upload_file, username='', password='')[source]#

Upload to a private contribution on earthref.org/MagIC.

Parameters:
  • contribution_id (int) – ID of MagIC contribution to delete

  • upload_file (str) – file to upload (complete path)

  • username (str) – personal username for MagIC

  • password (str) – password for username

Returns:

response –

response.status_code: bool

True : successful creation of private workspace

response[‘url’]str

URL of request

response[‘method’]=’PUT’ response[‘errors’] : str

if unsuccessful, error message

Return type:

API requests.models.Response

pmagpy.ipmag.validate_magic(top_dir, doi=False, private_key=False, contribution_id=False)[source]#

download and validate a magic contribution :param top_dir: name of project :type top_dir: str :param doi: DOI of paper to download :type doi: str :param contribution_id: id of contribution :type contribution_id: str :param private_key: private key of contribution in private workspace :type private_key: str

pmagpy.ipmag.validate_private_contribution(contribution_id, username='', password='', verbose=True)[source]#

validate private contribution in MagIC

Parameters:
  • contribution_id (int) – ID of MagIC contribution to delete

  • username (str) – personal username for MagIC

  • password (str) – password for username

  • verbose (bool) – if True, print error messages

Returns:

response –

response.status_code: bool

True : successful validation of private workspace

response[‘url’]str

URL of request

response[‘results’] : dictionary of validation results response[‘method’]=’POST’ response[‘errors’] : str

if unsuccessful, error message

Return type:

API requests.models.Response

pmagpy.ipmag.validate_with_public_endpoint(contribution_file, verbose=False)[source]#

validate contribution to MagIC using public endpoint

Parameters:
  • contribution_file (str) – file to validate

  • verbose (bool) – if True, print error messages

Returns:

response –

response.status_code: bool

True : successful validation of private workspace

response[‘errors’] : None or ‘trouble validating’ response[‘validation_results’] : dictionary of validation errors response[‘warnings’] : list of warnings

Return type:

API requests.models.Response

pmagpy.ipmag.vgp_calc(dataframe, tilt_correction='yes', site_lon='site_lon', site_lat='site_lat', dec_is='dec_is', inc_is='inc_is', dec_tc='dec_tc', inc_tc='inc_tc', recalc_label=False)[source]#

This function calculates paleomagnetic poles using directional data and site location data within a pandas.DataFrame. The function adds the columns ‘paleolatitude’, ‘vgp_lat’, ‘vgp_lon’, ‘vgp_lat_rev’, and ‘vgp_lon_rev’ to the dataframe. The ‘_rev’ columns allow for subsequent choice as to which polarity will be used for the VGPs.

Parameters:
  • dataframe (the name of the pandas.DataFrame containing the data)

  • tilt-correction ('yes' is the default and uses tilt-corrected data (dec_tc, inc_tc), 'no' uses data that is not tilt-corrected and is in geographic coordinates)

  • dataframe['site_lat'] (the name of the Dataframe column containing the latitude of the site)

  • dataframe['site_lon'] (the name of the Dataframe column containing the longitude of the site)

  • dataframe['inc_tc'] (the name of the Dataframe column containing the tilt-corrected inclination (used by default tilt-correction='yes'))

  • dataframe['dec_tc'] (the name of the Dataframe column containing the tilt-corrected declination (used by default tilt-correction='yes'))

  • dataframe['inc_is'] (the name of the Dataframe column containing the insitu inclination (used when tilt-correction='no'))

  • dataframe['dec_is'] (the name of the Dataframe column containing the insitu declination (used when tilt-correction='no'))

Returns:

  • dataframe[‘paleolatitude’]

  • dataframe[‘colatitude’]

  • dataframe[‘vgp_lat’]

  • dataframe[‘vgp_lon’]

  • dataframe[‘vgp_lat_rev’]

  • dataframe[‘vgp_lon_rev’]

pmagpy.ipmag.vgpmap_magic(dir_path='.', results_file='sites.txt', crd='', sym='ro', size=8, rsym='g^', rsize=8, fmt='pdf', res='c', proj='ortho', flip=False, anti=False, fancy=False, ell=False, ages=False, lat_0=0, lon_0=0, save_plots=True, interactive=False, contribution=None, image_records=False)[source]#

makes a map of vgps and a95/dp,dm for site means in a sites table

Parameters:
  • dir_path (str, default ".") – input directory path

  • results_file (str, default "sites.txt") – name of MagIC format sites file

  • crd (str, default "") – coordinate system [g, t] (geographic, tilt_corrected)

  • sym (str, default "ro") – symbol color and shape, default red circles (see matplotlib documentation for more color/shape options)

  • size (int, default 8) – symbol size

  • rsym (str, default "g^") – symbol for plotting reverse poles (see matplotlib documentation for more color/shape options)

  • rsize (int, default 8) – symbol size for reverse poles

  • fmt (str, default "pdf") – format for figures, [“svg”, “jpg”, “pdf”, “png”]

  • res (str, default "c") – resolution [c, l, i, h] (crude, low, intermediate, high)

  • proj (str, default "ortho") – ortho = orthographic lcc = lambert conformal moll = molweide merc = mercator

  • flip (bool, default False) – if True, flip reverse poles to normal antipode

  • anti (bool, default False) – if True, plot antipodes for each pole

  • fancy (bool, default False) – if True, plot topography (not yet implemented)

  • ell (bool, default False) – if True, plot ellipses

  • ages (bool, default False) – if True, plot ages

  • lat_0 (float, default 0.) – eyeball latitude

  • lon_0 (float, default 0.) – eyeball longitude

  • save_plots (bool, default True) – if True, create and save all requested plots

  • interactive (bool, default False) –

    if True, interactively plot and display

    (this is best used on the command line only)

  • image_records (bool, default False) – if True, return a list of created images

Returns:

  • if image_records == False – type - Tuple : (True or False indicating if conversion was successful, file name(s) written)

  • if image_records == True – Tuple : (True or False indicating if conversion was successful, output file name written, list of image recs)

pmagpy.ipmag.zeq(path_to_file='.', file='', data='', units='U', calculation_type='DE-BFL', save=False, save_folder='.', fmt='svg', begin_pca='', end_pca='', angle=0, make_plots=True, show_data=True)[source]#
NAME

zeq.py

DESCRIPTION
plots demagnetization data for a single specimen:
  • The solid (open) symbols in the Zijderveld diagram are X,Y (X,Z) pairs. The demagnetization diagram plots the

fractional remanence remaining after each step. The green line is the fraction of the total remaence removed between each step. If the principle direction is desired, specify begin_pca and end_pca steps as bounds for calculation.

-The equal area projection has the X direction (usually North in geographic coordinates) to the top. The red line is the X axis of the Zijderveld diagram. Solid symbols are lower hemisphere.

  • red dots and blue line is the remanence remaining after each step. The green line is the partial TRM removed in each interval

INPUT FORMAT

reads from file_name or takes a Pandas DataFrame data with specimen treatment intensity declination inclination as columns

Keywords:
file= FILE a space or tab delimited file with

specimen treatment declination inclination intensity

units= [mT,C] specify units of mT OR C, default is unscaled save=[True,False] save figure and quit, default is False fmt [svg,jpg,png,pdf] set figure format [default is svg] begin_pca [step number] treatment step for beginning of PCA calculation, default end_pca [step number] treatment step for end of PCA calculation, last step is default calculation_type [DE-BFL,DE-BFP,DE-FM] Calculation Type: best-fit line, plane or fisher mean; line is default angle=[0-360]: angle to subtract from declination to rotate in horizontal plane, default is 0

pmagpy.ipmag.zeq_magic(meas_file='measurements.txt', spec_file='', crd='s', dir_path='.', input_dir_path='', angle=0, n_plots=5, save_plots=True, fmt='svg', interactive=False, specimen='', samp_file='samples.txt', contribution=None, fignum=1, image_records=False)[source]#

eeq_magic makes zijderveld and equal area plots for magic formatted measurements files. :param meas_file: input measurement file :type meas_file: str :param spec_file: input specimen interpretation file :type spec_file: str :param samp_file: input sample orientations file :type samp_file: str :param crd: coordinate system [s,g,t] for specimen, geographic, tilt corrected

g,t options require a sample file with specimen and bedding orientation

Parameters:
  • dir_path (str) – output directory for plots, default “.”

  • input_dir_path (str) – input directory, if different from dir_path, default “”

  • angle (float) – angle of X direction with respect to specimen X

  • n_plots (int, default 5) – maximum number of plots to make if you want to make all possible plots, specify “all”

  • save_plots (bool, default True) – if True, create and save all requested plots

  • fmt (str, default "svg") – format for figures, [svg, jpg, pdf, png]

  • interactive (bool, default False) – interactively plot and display for each specimen (this is best used on the command line only)

  • specimen (str, default "") – specimen name to plot

  • samp_file (str, default 'samples.txt') – name of samples file

  • contribution (cb.Contribution, default None) – if provided, use Contribution object instead of reading in data from files

  • fignum (matplotlib figure number)

  • image_records (generate and return a record for each image in a list of dicts) – which can be ingested by pmag.magic_write bool, default False

Returns:

  • if image_records == False – Tuple : (True or False indicating if conversion was successful, output file name written)

  • if image_records == True – Tuple : (True or False indicating if conversion was successful, output file name written, list of image recs)

pmagpy.pmagplotlib#

pmagpy.pmagplotlib.add_borders(Figs, titles, border_color='#000000', text_color='#800080', con_id='')[source]#

Formatting for generating plots on the server Default border color: black Default text color: purple

pmagpy.pmagplotlib.delticks(fig)[source]#

deletes half the x-axis tick marks

Parameters:

fig (matplotlib figure number)

pmagpy.pmagplotlib.draw_figs(FIGS)[source]#

Can only be used if matplotlib backend is set to TKAgg Does not play well with wxPython :param FIGS: :type FIGS: dictionary of figure names as keys and numbers as values

pmagpy.pmagplotlib.gaussfunc(y, ybar, sigma)[source]#

cumulative normal distribution function of the variable y with mean ybar,standard deviation sigma uses expression 7.1.26 from Abramowitz & Stegun accuracy better than 1.5e-7 absolute :param y: :type y: input variable :param ybar: :type ybar: mean :param sigma: :type sigma: standard deviation

pmagpy.pmagplotlib.k_s(X)[source]#

Kolmorgorov-Smirnov statistic. Finds the probability that the data are distributed as func - used method of Numerical Recipes (Press et al., 1986)

pmagpy.pmagplotlib.label_tiepoints(ax, x, tiepoints, levels, color='black', lines=False)[source]#

Puts on labels for tiepoints in an age table on a stratigraphic plot.

Parameters:
  • ax (obj) – axis on which to plot the labels

  • x (float or integer) – x value for the tiepoint labels

  • levels (float) – stratigraphic positions of the tiepoints

  • lines (bool) – put on horizontal lines at the tiepoint heights

Returns:

ax – axis object

Return type:

obj

pmagpy.pmagplotlib.msp_magic(spec_df, axa='', axb='', site='site', labels=['a)', 'b)'], save_plots=False, fmt='pdf')[source]#

makes plots and calculations for MSP method of Dekkers & Boehnel (2006) (DB) and Fabian and Leonhardt (2010) method (DSC) of multi-specimen paleointensity technique. NB: this code requires seaborn and scipy to be installed

Parameters:#

spec_dfpandas dataframe

data frame with MagIC measurement formatted data for one MSP experiment. measurements must have these MagIC method codes: Mo (NRM step): must contain ‘LT-NO’ M1 (pTRM at T || NRM): must contain ‘LT-NRM-PAR’ and not ‘LT-PTRM-I’ M2 (pTRM NRM: must contain ‘LT-NRM-APAR’ M3 (heat to T, cool in lab field): must contain ‘LT-T-Z-NRM-PAR’ M4 (repeat of M1): must contain ‘LT-PTRM-I’ lab field must be in ‘treat_dc_field’

axa : matplotlib figure subplot for DB plot, default is to create and return. axb : matplotlib figure subplot for DSC plot, default is to create and return. site : name of group of specimens for y-axis label, default is generic ‘site’ labels : plot labels as specified. save_plots : bool, default False

if True, creat and save plot

fmtstr

format of saved figure (default is ‘pdf’)

returns:

B (in uT) standard error of slope axa, axb

pmagpy.pmagplotlib.plot3d_init(fignum)[source]#

initializes 3D plot

pmagpy.pmagplotlib.plot_arai(fignum, indata, s, units)[source]#

makes Arai plots for Thellier-Thellier type experiments

Parameters:
  • fignum (figure number of matplotlib plot object)

  • indata (nested list of data for Arai plots:) – the araiblock of data prepared by pmag.sortarai()

  • s (specimen name)

  • units ([K, J, ""] (kelvin, joules, unknown))

  • Effects

  • _______

  • plot (makes the Arai)

pmagpy.pmagplotlib.plot_arai_zij(ZED, araiblock, zijdblock, s, units)[source]#

calls the four plotting programs for Thellier-Thellier experiments

Parameters:
  • ZED (dictionary with plotting figure keys:) –

    deremag : figure for de (re) magnezation plots arai : figure for the Arai diagram eqarea : equal area projection of data, color coded by

    red circles: ZI steps blue squares: IZ steps yellow triangles : pTRM steps

    zijd : Zijderveld diagram color coded by ZI, IZ steps deremag : demagnetization and remagnetization versus temperature

  • araiblock (nested list of required data from Arai plots)

  • zijdblock (nested list of required data for Zijderveld plots)

  • s (specimen name)

  • units (units for the arai and zijderveld plots)

  • Effects

  • ________

  • calling (Makes four plots from the data by)

  • plot_arai (Arai plots)

  • plot_teq (equal area projection for Thellier data)

  • plotZ (Zijderveld diagram)

  • plot_np (de (re) magnetization diagram)

pmagpy.pmagplotlib.plot_b(Figs, araiblock, zijdblock, pars)[source]#

deprecated (used in thellier_magic/microwave_magic)

pmagpy.pmagplotlib.plot_bcr(fignum, Bcr1, Bcr2)[source]#

function to plot two estimates of Bcr against each other

pmagpy.pmagplotlib.plot_cdf(fignum, data, xlab, sym, title, **kwargs)[source]#

Makes a plot of the cumulative distribution function. :param fignum: :type fignum: matplotlib figure number :param data: :type data: list of data to be plotted - doesn’t need to be sorted :param sym: :type sym: matplotlib symbol for plotting, e.g., ‘r–’ for a red dashed line :param **kwargs: :type **kwargs: optional dictionary with {‘color’: color, ‘linewidth’:linewidth, ‘fontsize’:fontsize for axes labels}

Returns:

  • x (sorted list of data)

  • y (fraction of cdf)

pmagpy.pmagplotlib.plot_circ(fignum, pole, ang, col)[source]#

function to put a small circle on an equal area projection plot, fig,fignum :param fignum: :type fignum: matplotlib figure number :param pole: :type pole: dec,inc of center of circle :param ang: :type ang: angle of circle :param col:

pmagpy.pmagplotlib.plot_conf(fignum, s, datablock, pars, new)[source]#

plots directions and confidence ellipses

pmagpy.pmagplotlib.plot_d_delta_m(fignum, Bdm, DdeltaM, s)[source]#

function to plot d (Delta M)/dB curves

Parameters:
  • fignum (matplotlib figure number)

  • Bdm (change in field)

  • M (Ddelta)

  • s (specimen name)

pmagpy.pmagplotlib.plot_day(fignum, BcrBc, S, sym, **kwargs)[source]#

function to plot Day plots

Parameters:
  • fignum (matplotlib figure number)

  • BcrBc (list or array ratio of coercivity of remenance to coercivity)

  • S (list or array ratio of saturation remanence to saturation magnetization (squareness))

  • sym (matplotlib symbol (e.g., 'rs' for red squares))

  • **kwargs (dictionary with {'names':[list of names for symbols]})

pmagpy.pmagplotlib.plot_delta_m(fignum, B, DM, Bcr, s)[source]#

function to plot Delta M curves

Parameters:
  • fignum (matplotlib figure number)

  • B (array of field values)

  • DM (array of difference between top and bottom curves in hysteresis loop)

  • Bcr (coercivity of remanence)

  • s (specimen name)

pmagpy.pmagplotlib.plot_dir(ZED, pars, datablock, angle)[source]#

function to put the great circle on the equal area projection and plot start and end points of calculation

DEPRECATED (used in zeq_magic)

pmagpy.pmagplotlib.plot_ell(fignum, pars, col='k', lower=True, plot=True)[source]#

function to calculate/plot points on an ellipse about Pdec,Pdip with angle beta,gamma :param fignum: :type fignum: matplotlib figure number :param pars: where P is direction, Bdec,Binc are beta direction, and Gdec,Ginc are gamma direction :type pars: list of [Pdec, Pinc, beta, Bdec, Binc, gamma, Gdec, Ginc ] :param col: :type col: color for ellipse (default is black ‘k’) :param lower: :type lower: boolean, if True, lower hemisphere projection :param plot: :type plot: boolean, if False, return the points, if True, make the plot

pmagpy.pmagplotlib.plot_eq(fignum, DIblock, s)[source]#

plots directions on eqarea projection :param fignum: :type fignum: matplotlib figure number :param DIblock: :type DIblock: nested list of dec/inc pairs :param s: :type s: specimen name

pmagpy.pmagplotlib.plot_eq_cont(fignum, DIblock, color_map='coolwarm')[source]#

plots dec inc block as a color contour :param Input: fignum : figure number

DIblock : nested pairs of [Declination, Inclination] color_map : matplotlib color map [default is coolwarm]

Parameters:

Output – figure

pmagpy.pmagplotlib.plot_eq_sym(fignum, DIblock, s, sym)[source]#

plots directions with specified symbol :param fignum: :type fignum: matplotlib figure number :param DIblock: :type DIblock: nested list of dec/inc pairs :param s: :type s: specimen name :param sym: :type sym: matplotlib symbol (e.g., ‘bo’ for blue circle)

pmagpy.pmagplotlib.plot_evec(fignum, Vs, symsize, title)[source]#

plots eigenvector directions of S vectors

Parameters:
  • fignum (matplotlib figure number)

  • Vs (nested list of eigenvectors)

  • symsize (size in pts for symbol)

  • title (title for plot)

pmagpy.pmagplotlib.plot_hdd(HDD, B, M, s)[source]#

Function to make hysteresis, deltaM and DdeltaM plots Parameters: _______________ Input

HDDdictionary with figure numbers for the keys:

‘hyst’ : hysteresis plot normalized to maximum value ‘deltaM’ : Delta M plot ‘DdeltaM’ : differential of Delta M plot

B : list of field values in tesla M : list of magnetizations in arbitrary units s : specimen name string

Ouput
hparsdictionary of hysteresis parameters with keys:

‘hysteresis_xhf’, ‘hysteresis_ms_moment’, ‘hysteresis_mr_moment’, ‘hysteresis_bc’

pmagpy.pmagplotlib.plot_hpars(HDD, hpars, sym)[source]#

function to plot hysteresis parameters deprecated (used in hysteresis_magic)

pmagpy.pmagplotlib.plot_hs(fignum, Ys, c, ls)[source]#

plots horizontal lines at Ys values

Parameters:
  • fignum (matplotlib figure number)

  • Ys (list of Y values for lines)

  • c (color for lines)

  • ls (linestyle for lines)

pmagpy.pmagplotlib.plot_hys(fignum, B, M, s)[source]#

function to plot hysteresis data Parameters: _____________________ Input :

fignum : matplotlib figure number B : list of field values (in tesla) M : list of magnetizations

Output :
hparsdictionary of hysteresis parameters

keys: [‘hysteresis_xhf’, ‘hysteresis_ms_moment’, ‘hysteresis_mr_moment’, ‘hysteresis_bc’]

deltaM : list of differences between down and upgoing loops Bdm : field values

pmagpy.pmagplotlib.plot_imag(fignum, Bimag, Mimag, s)[source]#

function to plot d (Delta M)/dB curves

pmagpy.pmagplotlib.plot_init(fignum, w, h)[source]#

initializes plot number fignum with width w and height h :param fignum: :type fignum: matplotlib figure number :param w: :type w: width :param h: :type h: height

pmagpy.pmagplotlib.plot_irm(fignum, B, M, title)[source]#

function to plot IRM backfield curves

Parameters:
  • fignum (matplotlib figure number)

  • B (list or array of field values)

  • M (list or array of magnetizations)

  • title (string title for plot)

pmagpy.pmagplotlib.plot_lnp(fignum, s, datablock, fpars, direction_type_key)[source]#

plots lines and planes on a great circle with alpha 95 and mean

Parameters:
  • fignum (number of plt.figure() object)

  • s (str) – name of site for title

  • datablock (nested list of dictionaries with keys in 3.0 or 2.5 format) – 3.0 keys: dir_dec, dir_inc, dir_tilt_correction = [-1,0,100], method_codes =[‘DE-BFP’,’DE-BFL’] 2.5 keys: dec, inc, tilt_correction = [-1,0,100],direction_type_key =[‘p’,’l’]

  • fpars (Fisher parameters calculated by pmag.dolnp())

  • direction_type_key (key for dictionary direction_type ('specimen_direction_type'))

  • Effects

  • _______

  • figure (plots the site level)

pmagpy.pmagplotlib.plot_ltc(LTC_CM, LTC_CT, LTC_WM, LTC_WT, e)[source]#

function to plot low temperature cycling experiments

pmagpy.pmagplotlib.plot_mag(fignum, datablock, s, num, units, norm)[source]#

plots magnetization against (de)magnetizing temperature or field

Parameters:
  • fignum (matplotlib figure number for plotting)

  • datablock (nested list of [step, 0, 0, magnetization, 1,quality])

  • s (string for title)

  • num (matplotlib figure number, can set to 1)

  • units ([T,K,U] for tesla, kelvin or arbitrary)

  • norm ([True,False] if True, normalize)

  • Effects

  • ______ – plots figure

pmagpy.pmagplotlib.plot_mag_map(fignum, element, lons, lats, element_type, cmap='coolwarm', lon_0=0, date='', contours=False, proj='PlateCarree', min=False, max=False)[source]#

makes a color contour map of geomagnetic field element

Parameters:
  • fignum (matplotlib figure number)

  • element (plots a color contour map with the desired field)

  • lons (longitude array from pmag.do_mag_map for plotting)

  • lats (latitude array from pmag.do_mag_map for plotting)

  • element_type ([B,Br,I,D] geomagnetic element type) – B : field intensity Br : radial field intensity I : inclinations D : declinations

  • Optional

  • _________

  • contours (plot the contour lines on top of the heat map if True)

  • proj (cartopy projection ['PlateCarree','Mollweide']) – NB: The Mollweide projection can only be reliably with cartopy=0.17.0; otherwise use lon_0=0. Also, for declinations, PlateCarree is recommended.

  • cmap (matplotlib color map - see https://matplotlib.org/examples/color/colormaps_reference.html for options)

  • lon_0 (central longitude of the Mollweide projection)

  • date (date used for field evaluation,) – if custom ghfile was used, supply filename

  • min (int) – minimum value for color contour on intensity map : default is minimum value - useful for making many maps with same scale

  • max (int) – maximum value for color contour on intensity map : default is maximum value - useful for making many maps with same scale

  • Effects

  • ______________

  • element

pmagpy.pmagplotlib.plot_map(fignum, lats, lons, Opts)[source]#

makes a cartopy map with lats/lons Requires installation of cartopy

Parameters:#

fignum : matplotlib figure number lats : array or list of latitudes lons : array or list of longitudes Opts : dictionary of plotting options:

Opts.keys=
projprojection [supported cartopy projections:

pc = Plate Carree aea = Albers Equal Area aeqd = Azimuthal Equidistant lcc = Lambert Conformal lcyl = Lambert Cylindrical merc = Mercator mill = Miller Cylindrical moll = Mollweide [default] ortho = Orthographic robin = Robinson sinu = Sinusoidal stere = Stereographic tmerc = Transverse Mercator utm = UTM [set zone and south keys in Opts] laea = Lambert Azimuthal Equal Area geos = Geostationary npstere = North-Polar Stereographic spstere = South-Polar Stereographic

latmin : minimum latitude for plot latmax : maximum latitude for plot lonmin : minimum longitude for plot lonmax : maximum longitude lat_0 : central latitude lon_0 : central longitude sym : matplotlib symbol symsize : symbol size in pts edge : markeredgecolor cmap : matplotlib color map res : resolution [c,l,i,h] for low/crude, intermediate, high boundinglat : bounding latitude sym : matplotlib symbol for plotting symsize : matplotlib symbol size for plotting names : list of names for lats/lons (if empty, none will be plotted) pltgrd : if True, put on grid lines padlat : padding of latitudes padlon : padding of longitudes gridspace : grid line spacing global : global projection [default is True] oceancolor : ‘azure’ landcolor : ‘bisque’ [choose any of the valid color names for matplotlib

detailsdictionary with keys:

coasts : if True, plot coastlines rivers : if True, plot rivers states : if True, plot states countries : if True, plot countries ocean : if True, plot ocean lakes : if True, plot lakes fancy : if True, plot etopo 20 grid

NB: etopo must be installed

axoptional matplotlib/cartopy axes object on which to plot.

If provided, plot_map will add data to this axes instead of creating a new one. This allows overlaying multiple datasets (e.g., continents, site symbols) on a single map.

if Opts keys not set :these are the defaults:
Opts={‘latmin’:-90,’latmax’:90,’lonmin’:0,’lonmax’:360,’lat_0’:0,’lon_0’:0,

‘proj’:’moll’,’sym’:’ro’,’symsize’:5,’edge’:’black’,’pltgrid’:1, ‘res’:’c’,’boundinglat’:0.,’padlon’:0,’padlat’:0,’gridspace’:30, ‘details’:all False,’edge’:None,’cmap’:’jet’,’fancy’:0,’zone’:’’, ‘south’:False,’oceancolor’:’azure’,’landcolor’:’bisque’}

Returns:#

ax : matplotlib/cartopy axes object containing the map

pmagpy.pmagplotlib.plot_net(fignum)[source]#

draws circle and tick marks for equal area projection :param fignum: :type fignum: matplotlib figure number

pmagpy.pmagplotlib.plot_np(fignum, indata, s, units)[source]#

makes plot of de(re)magnetization data for Thellier-Thellier type experiment

Parameters:
  • fignum (matplotlib figure number)

  • indata (araiblock from, e.g., pmag.sortarai())

  • s (specimen name)

  • units ([K, J, ""] (kelvin, joules, unknown))

  • Effect

  • _______

  • plot (Makes a)

pmagpy.pmagplotlib.plot_qq_exp(fignum, I, title, subplot=False)[source]#

plots data against an exponential distribution in 0=>90.

Parameters:
  • fignum (matplotlib figure number)

  • I (data)

  • title (plot title)

  • subplot (boolean, if True plot as subplot with 1 row, two columns with fignum the plot number)

pmagpy.pmagplotlib.plot_qq_norm(fignum, Y, title)[source]#

makes a Quantile-Quantile plot for data :param fignum: :type fignum: matplotlib figure number :param Y: :type Y: list or array of data :param title: :type title: title string for plot

Returns:

d,dc – if d>dc, likely to be normally distributed (95% confidence)

Return type:

the values for D and Dc (the critical value)

pmagpy.pmagplotlib.plot_qq_unf(fignum, D, title, subplot=False, degrees=True)[source]#

plots data against a uniform distribution in 0=>360. :param fignum: :type fignum: matplotlib figure number :param D: :type D: data :param title: :type title: title for plot :param subplot: :type subplot: if True, make this number one of two subplots :param degrees: :type degrees: if True, assume that these are degrees :param Return: :param Mu: :type Mu: Mu statistic (Fisher et al., 1987) :param Mu_crit: :type Mu_crit: critical value of Mu for uniform distribution :param Effect: :param ______: :param makes a Quantile Quantile plot of data:

pmagpy.pmagplotlib.plot_s_bc(fignum, Bc, S, sym)[source]#

function to plot Squareness,Coercivity

Parameters:
  • fignum (matplotlib figure number)

  • Bc (list or array coercivity values)

  • S (list or array of ratio of saturation remanence to saturation)

  • sym (matplotlib symbol (e.g., 'g^' for green triangles))

pmagpy.pmagplotlib.plot_s_bcr(fignum, Bcr, S, sym)[source]#

function to plot Squareness,Coercivity of remanence

Parameters:
  • fignum (matplotlib figure number)

  • Bcr (list or array coercivity of remenence values)

  • S (list or array of ratio of saturation remanence to saturation)

  • sym (matplotlib symbol (e.g., 'g^' for green triangles))

pmagpy.pmagplotlib.plot_site(fignum, SiteRec, data, key)[source]#

deprecated (used in ipmag)

pmagpy.pmagplotlib.plot_slnp(fignum, SiteRec, datablock, key)[source]#

plots lines and planes on a great circle with alpha 95 and mean deprecated (used in pmagplotlib)

pmagpy.pmagplotlib.plot_square(fignum)[source]#

makes the figure square (equal axes) :param fignum: :type fignum: matplotlib figure number

pmagpy.pmagplotlib.plot_strat(fignum, data, labels)[source]#

plots a time/depth series :param fignum: :type fignum: matplotlib figure number :param data: :type data: nested list of [X,Y] pairs :param labels: :type labels: [xlabel, ylabel, title]

pmagpy.pmagplotlib.plot_teq(fignum, araiblock, s, pars)[source]#

plots directions of pTRM steps and zero field steps

Parameters:
  • fignum (figure number for matplotlib object)

  • araiblock (nested list of data from pmag.sortarai())

  • s (specimen name)

  • pars (default is "",) – otherwise is dictionary with keys: ‘measurement_step_min’ and ‘measurement_step_max’

  • Effects

  • _______

  • symbols (makes the equal area projection with color coded) – red circles: ZI steps blue squares: IZ steps yellow : pTRM steps

pmagpy.pmagplotlib.plot_ts(ax, agemin, agemax, step=1.0, timescale='gts20', ylabel='Age (Ma)')[source]#

This function makes a time scale plot between specified ages, using timescales as defined in pmag.get_ts(). The maximum possible age is ca. 83 Ma.

Parameters: ax : figure object agemin : (float) Minimum age for timescale in Ma agemax : (float) Maximum age for timescale in Ma step : (float) Y tick label spacing in Ma timescale : (string) polarity time scale, default is gts20 (Gradstein et al. 2020), other options ck95, gts04, gts20 ylabel : (string) if set, plot as ylabel

Returns:

figure object

Example

Creates time scale plot from 0.5 to 5.5 Ma using the gts12 timescale:

>>> fig=plt.figure(figsize=(9,12))
>>> ax=fig.add_subplot(121)
>>> pmagplotlib.plot_ts(ax, 0.5, 5.5, timescale='gts12')
pmagpy.pmagplotlib.plot_vs(fignum, Xs, c, ls)[source]#

plots vertical lines at Xs values

Parameters:
  • fignum (matplotlib figure number)

  • Xs (list of X values for lines)

  • c (color for lines)

  • ls (linestyle for lines)

pmagpy.pmagplotlib.plot_xbt(fignum, XB, T, e, b)[source]#

function to plot series of chi measurements as a function of temperature, holding field constant and varying frequency

pmagpy.pmagplotlib.plot_xft(fignum, XF, T, e, b)[source]#

function to plot series of chi measurements as a function of temperature, holding field constant and varying frequency

pmagpy.pmagplotlib.plot_xtb(fignum, XTB, Bs, e, f)[source]#

function to plot series of chi measurements as a function of temperature, holding frequency constant and varying B

pmagpy.pmagplotlib.plot_xtf(fignum, XTF, Fs, e, b)[source]#

function to plot series of chi measurements as a function of temperature, holding field constant and varying frequency

pmagpy.pmagplotlib.plot_xy(fignum, X, Y, **kwargs)[source]#

deprecated, used in curie

pmagpy.pmagplotlib.plot_zed(ZED, datablock, angle, s, units)[source]#

function to make equal area plot and zijderveld plot

Parameters:
  • ZED (dictionary with keys for plots) –

    eqarea : figure number for equal area projection zijd : figure number for zijderveld plot demag : figure number for magnetization against demag step datablock : nested list of [step, dec, inc, M (Am2), type, quality]

    (type indicates the IZZI step for paleointensity experiments — ‘ZI’/’IZ’ or 1/0; empty string for pure demagnetization data)

    step : units assumed in SI M : units assumed Am2 quality : [g,b], good or bad measurement; if bad will be marked as such

  • angle (angle for X axis in horizontal plane, if 0, x will be 0 declination)

  • s (specimen name)

  • units (SI units ['K','T','U'] for kelvin, tesla or undefined)

  • Effects

  • _______ – calls plotting functions for equal area, zijderveld and demag figures

pmagpy.pmagplotlib.plot_zij(fignum, datablock, angle, s, norm=True)[source]#

function to make Zijderveld diagrams

Parameters:
  • fignum (matplotlib figure number)

  • datablock (nested list of [step, dec, inc, M (Am2), type, quality]) – (type indicates the IZZI step for paleointensity experiments — ‘ZI’/’IZ’ or 1/0; empty string for pure demagnetization data)

  • angle (desired rotation in the horizontal plane (0 puts X on X axis))

  • s (specimen name)

  • norm (if True, normalize to initial magnetization = unity)

  • Effects

  • _______

  • plot (makes a zijderveld)

pmagpy.pmagplotlib.qsnorm(p)[source]#

rational approximation for x where q(x)=d, q being the cumulative normal distribution function. taken from Abramowitz & Stegun p. 933 |error(x)| < 4.5*10**-4

pmagpy.pmagplotlib.save_plots(Figs, filenames, dir_path=None, **kwargs)[source]#
Parameters:
  • Figs (dict) – dictionary of plots, e.g. {‘eqarea’: 1, …}

  • filenames (dict) – dictionary of filenames, e.g. {‘eqarea’: ‘mc01a_eqarea.svg’, …} dict keys should correspond with Figs

  • dir_path (str) – string of directory name where plots will be saved to

  • kwargs (other keyword arguments)

pmagpy.pmag#

pmagpy.pmag.Dir_anis_corr(InDir, AniSpec)[source]#

This function takes the 6 element ‘s’ vector and the Dec,Inc ‘InDir’ data and performs a simple anisotropy correction, returning corrected Dec, Inc. Used in thellier_magic2.py.

pmagpy.pmag.EI(inc)[source]#

Given a mean inclination value of a distribution of directions, this function calculates the expected elongation of this distribution using a best-fit polynomial of the TK03 GAD secular variation model (Tauxe and Kent, 2004).

Parameters:

inc (Integer or float) – Inclination in degrees.

Returns:

elongation

Return type:

float

Examples

>>> pmag.EI(20)
2.4863973732
>>> pmag.EI(90)
1.0241570135500004
exception pmagpy.pmag.MissingCommandLineArgException(message)[source]#
pmagpy.pmag.PintPars(datablock, araiblock, zijdblock, start, end, accept, **kwargs)[source]#

Calculate the paleointensity with magic parameters and make some definitions.

Uses functions int_pars and dovds

pmagpy.pmag.Tmatrix(X)[source]#

Gets the orientation matrix (T) from data in X.

Parameters:

X (nested lists of input data)

Returns:

T

Return type:

orientation matrix as a nested list

Examples

>>> X = [[1., 0.8, 5.], [0.5, 0.2, 2.], [1.4, 0.6, 0.1]]
>>> pmag.Tmatrix(X)
[[3.21, 1.74, 6.14], [1.74, 1.04, 4.46], [6.14, 4.46, 29.01]]
pmagpy.pmag.Vdiff(D1, D2)[source]#

Calculates the vector difference between two directions D1, D2.

Parameters:
  • D1 (Direction 1 as an array of [declination, inclination] pair or pairs)

  • D2 (Direction 2 as an array of [declination, inclination] pair or pairs)

Returns:

The vector difference between D1 and D2

Return type:

array

Examples

>>> pmag.Vdiff([350.0,10.0],[320.0,20.0])
array([ 60.00000000000001 , -18.61064009110688 ,   0.527588019973717])
pmagpy.pmag.a2s(a)[source]#

Convert 3x3 a matrix to 6 element “s” list (see Tauxe 1998).

Parameters:

a (3x3 matrix as an array)

Returns:

s

Return type:

list of six elements based on a

Examples

>>> pmag.a2s([[1, 4, 6],
              [4, 2, 5],
              [6, 5, 3]])
array([1., 2., 3., 4., 5., 6.], dtype=float32)
pmagpy.pmag.add_flag(var, flag)[source]#

For use when calling command-line scripts from within a program. if a variable is present, add its proper command_line flag. return a string.

pmagpy.pmag.adjust_ages(AgesIn)[source]#

Function to adjust ages to a common age_unit.

pmagpy.pmag.adjust_all_to_360(dictionary)[source]#

Take a dictionary and check each key/value pair. If this key is of type: declination/longitude/azimuth/direction, adjust it to be within 0-360 as required by the MagIC data model

pmagpy.pmag.adjust_to_360(val, key)[source]#

Take in a value and a key. If the key is of the type: declination/longitude/azimuth/direction, adjust it to be within the range 0-360 as required by the MagIC data model

pmagpy.pmag.adjust_val_to_360(val)[source]#

Take in a single numeric (or null) argument. Return argument adjusted to be between 0 and 360 degrees.

pmagpy.pmag.age_to_BP(age, age_unit)[source]#

Convert an age value into the equivalent in time Before Present(BP) where Present is 1950.

Parameters:
  • age (age as a float)

  • age_unit (age unit as a str, valid strings:) – (Years AD (+/-), Years Cal AD (+/-), Years BP, ka, Ma, or Ga)

Returns:

ageBP

Return type:

age before present

pmagpy.pmag.angle(D1, D2)[source]#

Calculate the angle between two directions.

Parameters:
  • D1 (Direction 1 as an array of [declination, inclination] pair or pairs)

  • D2 (Direction 2 as an array of [declination, inclination] pair or pairs)

Returns:

angle – angle between the input directions

Return type:

single-element array

Examples

>>> pmag.angle([350.0,10.0],[320.0,20.0])
array([ 30.59060998])
>>> pmag.angle([[350.0,10.0],[320.0,20.0]],[[345,13],[340,14]])
array([ 5.744522410794302, 20.026413431433475])
pmagpy.pmag.apseudo(Ss, ipar, sigma, random_seed=None)[source]#

This function draws a bootstrap sample of Ss, for use in pmag.s_boot.

Parameters:
  • Ss (six element tensor as a list)

  • ipar (boolean (True, False, or zero value))

  • sigma (sigma of Ss)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

BSs – bootstrap sample of Ss

Return type:

array

Examples

>>> pmag.apseudo(np.array([2,2,1,6,1,1]),0,0)
array([1, 2, 1, 2, 2, 1])
pmagpy.pmag.apwp(data, print_results=False)[source]#

Calculates expected pole positions and directions for given plate, location and age.

Parameters:
  • data ([plate,lat,lon,age]) –

    plate[NA, SA, AF, IN, EU, AU, ANT, GL]

    NA : North America SA : South America AF : Africa IN : India EU : Eurasia AU : Australia ANT: Antarctica GL : Greenland lat/lon : latitude/longitude in degrees N/E age : age in millions of years

  • print_results (if True will print out nicely formatted results)

Return type:

if print_results is False, [Age,Paleolat, Dec, Inc, Pole_lat, Pole_lon]

pmagpy.pmag.b_vdm(B, lat)[source]#

Converts a magnetic field value of list of values to virtual dipole moment (VDM) or a virtual axial dipole moment (VADM).

Parameters B: local magnetic field strength in tesla, as a value or list of values lat: latitude of site in degrees

Returns VDM or V(A)DM in units of Am^2

Examples

>>> pmag.b_vdm(33e-6,22)*1e-21
71.58815974511788
pmagpy.pmag.bc02(data)[source]#

Get APWP from Besse and Courtillot 2002 paper

Parameters:
  • [plate (Takes input as)

  • site_lat (float)

  • site_lon (float)

  • age]

  • plate (string (options: AF, ANT, AU, EU, GL, IN, NA, SA))

  • site_lat

  • site_lon

  • age (float in Myr)

Returns:

  • pole_lat (pole latitude)

  • pole_lon (pole longitude)

pmagpy.pmag.binglookup(w1i, w2i)[source]#

Bingham statistics lookup table.

Parameters:
  • w1i (initial values for w1 and w2)

  • w2i (initial values for w1 and w2)

Returns:

k1,k2

Return type:

k1 and k2 for Bingham distribution

Examples

>>> pmag.binglookup(0.12,0.15)
(-4.868, -3.7289999999999996)
pmagpy.pmag.binglookup_old(w1i, w2i)[source]#

Bingham statistics lookup table.

pmagpy.pmag.calculate_best_fit_vectors(L, E, V, n_planes)[source]#

Calculates the best fit vectors for a set of plane interpretations used in fisher mean calculations.

Parameters:
  • L (a list of the "EL, EM, EN" array of MM88 or the cartisian form of dec and inc of the plane interpretation)

  • E (the sum of the cartisian coordinates of all the line fits to be used in the mean)

  • V (initial direction to start iterating from to get plane best fits)

  • n_planes (number of planes)

Returns:

XV

Return type:

nested list of n_plane by 3 dimension where the 3 are the cartisian dimension of the best fit vector

pmagpy.pmag.calculate_k(R, N)[source]#

Calculates the the Fisher concentration parameter (k) based on the number of vectors and the resultant vector length. This calculation occurs within the fisher_mean() function. Use of this function can be helpful when R and N are available, but the vectors themselves are not.

Parameters:
  • R (Resultant vector length)

  • N (Number of vectors)

Returns:

k

Return type:

Fisher concentration parameter

Examples

>>> n,r = 3, 4.335
>>> pmag.calculate_k(r,n)
-1.4981273408
pmagpy.pmag.calculate_r(alpha95, N)[source]#

Calculates the resultant vector length (R) based on the number of vectors and provided Fisher alpha95. Doing so can be useful for conducting statistical tests that require R when it is not provided.

Parameters:
  • alpha95 (Fisher alpha_95 value)

  • N (number of vectors)

Returns:

R

Return type:

resultant vector length

Examples

>>> alpha95, N = 6.41, 3
>>> pmag.calculate_r(alpha95,N)
2.994608233588127
pmagpy.pmag.cart2dir(cart)[source]#

Converts a direction in cartesian coordinates into declinations and inclination.

Parameters:

cart (list of [x,y,z] or list of lists [[x1,y1,z1],[x2,y2,z2]...])

Returns:

direction_array

Return type:

array of [declination, inclination, intensity]

Examples

>>> pmag.cart2dir([0,1,0])
array([ 90.,   0.,   1.])
pmagpy.pmag.cdfout(data, file)[source]#

spits out the cdf for data to file

pmagpy.pmag.chart_maker(Int, Top, start=100, outfile='chart.txt')[source]#

Makes a chart for performing IZZI experiments. Print out the file and tape it to the oven. This chart will help keep track of the different steps. Z : performed in zero field - enter the temperature XXX.0 in the sio

formatted measurement file created by the LabView program

I : performed in the lab field written at the top of the form P : a pTRM step - performed at the temperature and in the lab field.

Parameters:
  • Int (list of intervals [e.g., 50,10,5])

  • Top (list of upper bounds for each interval [e.g., 500, 550, 600])

  • start (first temperature step, default is 100)

  • outfile (name of output file, default is 'chart.txt')

Returns:

file: write down the name of the measurement file field: write down the lab field for the infield steps (in uT) the type of step (Z: zerofield, I: infield, P: pTRM step temperature of the step and code for SIO-like treatment steps

XXX.0 [zero field] XXX.1 [in field] XXX.2 [pTRM check] - done in a lab field

date : date the step was performed run # : an optional run number zones I-III : field in the zones in the oven start : time the run was started sp : time the setpoint was reached cool : time cooling started

Return type:

creates a file with

pmagpy.pmag.circ(dec, dip, alpha, npts=201)[source]#

Calculates points on an circle about dec and dip with angle alpha.

Parameters:
  • dec (float) – declination of vector

  • dip (float) – dip of vector

  • alpha (float) – angle of small circle - 90 if vector is pole to great circle

  • npts (int) – number of points on the circle, default 201

Returns:

D_out, I_out – declinations and inclinations along small (great) circle about dec, dip

Return type:

list

Examples

>>> pmag.circ(50,10,10,5)
([60.15108171104812,
  50.0,
  39.848918288951864,
  49.99999999999999,
  60.15108171104812],
 [9.846551939834077, 0.0, 9.846551939834077, 20.0, 9.846551939834079])
pmagpy.pmag.cleanup(first_I, first_Z)[source]#

cleans up unbalanced steps failure can be from unbalanced final step, or from missing steps, this takes care of missing steps

pmagpy.pmag.convert_ages(Recs, data_model=3)[source]#

Converts ages in a list of dictionaries to units of Millions of years ago, Ma.

Recs : list of dictionaries in data model by data_model data_model : MagIC data model (default is 3)

New : list of dictionaries with the converted ages

>>> sites = pd.read_csv('data_files/convert_ages/sites.txt',sep='   ',header=1) # create a dataframe from example file
>>> sites_age = sites.dropna(subset=['age'])     # drop all rows that have nan in the age column since our function does not work with nans
>>> sites_dict = sites_age.to_dict('records')    # 'records' to return list like values within dict
>>> sites_ages_converted = pmag.convert_ages(sites_dict)
>>> sites_ages_converted_df = pd.DataFrame.from_dict(sites_ages_converted)   # convert new age converted list of dictionaries back to a dataframe
>>> print('ORIGINAL FILE:
‘,sites_age[‘age’].head())
>>> print('CONVERTED AGES FILE:
‘,sites_ages_converted_df[‘age’].head());

ORIGINAL FILE: 1 100.0 3 625.0 5 625.0 7 750.0 9 800.0 Name: age, dtype: float64 CONVERTED AGES FILE:

0 1.9110e-03

1 1.3860e-03 2 1.3860e-03 3 1.2610e-03 4 1.2110e-03 Name: age, dtype: object

pmagpy.pmag.convert_and_combine_2_to_3(dtype, map_dict, input_dir='.', output_dir='.', data_model=None)[source]#

Read in er_*.txt file and pmag_*.txt file in working directory. Combine the data, then translate headers from 2.5 –> 3.0. Last, write out the data in 3.0.

Parameters:
  • dtype (string for input type (specimens, samples, sites, etc.))

  • map_dict (dictionary with format {header2_format: header3_format, ...} (from mapping.map_magic module))

  • input_dir (input directory, default ".")

  • output_dir (output directory, default ".")

  • data_model (data_model3.DataModel object, default None)

Return type:

output_file_name with 3.0 format data (or None if translation failed)

pmagpy.pmag.convert_criteria_file_2_to_3(fname='pmag_criteria.txt', input_dir='.', output_dir='.', data_model=None)[source]#

Convert a criteria file from 2.5 to 3.0 format and write it out to file

Parameters:
  • fname (string of filename (default "pmag_criteria.txt"))

  • input_dir (string of input directory (default "."))

  • output_dir (string of output directory (default "."))

  • data_model (data_model.DataModel object (default None))

Returns:

  • outfile (string output criteria filename, or False)

  • crit_container (cb.MagicDataFrame with 3.0 criteria table)

pmagpy.pmag.convert_directory_2_to_3(meas_fname='magic_measurements.txt', input_dir='.', output_dir='.', meas_only=False, data_model=None)[source]#

Convert 2.0 measurements file into 3.0 measurements file. Merge and convert specimen, sample, site, and location data. Also translates criteria data.

Parameters:
  • meas_name (name of measurement file (do not include full path,) – default is “magic_measurements.txt”)

  • input_dir (name of input directory (default is "."))

  • output_dir (name of output directory (default is "."))

  • meas_only (boolean, convert only measurement data (default is False))

  • data_model (data_model3.DataModel object (default is None))

Returns:

  • NewMeas (3.0 measurements data (output of pmag.convert_items))

  • upgraded (list of files successfully upgraded to 3.0)

  • no_upgrade (list of 2.5 files not upgraded to 3.0)

pmagpy.pmag.convert_items(data, mapping)[source]#

This function maps a given set of dictionsaries to the new given map and outputs an updated dictionary.

Parameters:
  • data (list of dicts (each dict a record for one item))

  • mapping (mapping with column names to swap into the records)

Returns:

new_recs

Return type:

updated list of dicts

pmagpy.pmag.convert_lat(Recs)[source]#

Uses lat, for age<5Ma, model_lat if present, else tries to use average_inc to estimate plat.

Parameters:

Recs (list of dictionaries in data model by data_model) – This list of dictionaries must only include data with ages less than 5 Ma

Returns:

New

Return type:

list of dictionaries with plat estimate

pmagpy.pmag.cross(v, w)[source]#

Cross product of two vectors.

Parameters:
  • v (3 value vector list)

  • w (3 value vector list)

Returns:

[x, y, z]

Return type:

cross product resultant vector

Examples

>>> pmag.cross([3,6,0],[1,5,1])
[6, -3, 9]
pmagpy.pmag.design(npos)[source]#

Make a design matrix for an anisotropy experiment.

Parameters:

npos (number of measurement positions.) – either 15 or 6

Returns:

  • A (design matrix array for the given number of positions)

  • B (suseptibilities array)

Examples

>>> pmag.design(10)
measurement protocol not supported yet
>>> pmag.design(15)
(array([[ 0.5,  0.5,  0. , -1. ,  0. ,  0. ],
    [ 0.5,  0.5,  0. ,  1. ,  0. ,  0. ],
    [ 1. ,  0. ,  0. ,  0. ,  0. ,  0. ],
    [ 0.5,  0.5,  0. , -1. ,  0. ,  0. ],
    [ 0.5,  0.5,  0. ,  1. ,  0. ,  0. ],
    [ 0. ,  0.5,  0.5,  0. , -1. ,  0. ],
    [ 0. ,  0.5,  0.5,  0. ,  1. ,  0. ],
    [ 0. ,  1. ,  0. ,  0. ,  0. ,  0. ],
    [ 0. ,  0.5,  0.5,  0. , -1. ,  0. ],
    [ 0. ,  0.5,  0.5,  0. ,  1. ,  0. ],
    [ 0.5,  0. ,  0.5,  0. ,  0. , -1. ],
    [ 0.5,  0. ,  0.5,  0. ,  0. ,  1. ],
    [ 0. ,  0. ,  1. ,  0. ,  0. ,  0. ],
    [ 0.5,  0. ,  0.5,  0. ,  0. , -1. ],
    [ 0.5,  0. ,  0.5,  0. ,  0. ,  1. ]]),
 array([[ 0.15,  0.15,  0.4 ,  0.15,  0.15, -0.1 , -0.1 , -0.1 , -0.1 ,
     -0.1 ,  0.15,  0.15, -0.1 ,  0.15,  0.15],
    [ 0.15,  0.15, -0.1 ,  0.15,  0.15,  0.15,  0.15,  0.4 ,  0.15,
      0.15, -0.1 , -0.1 , -0.1 , -0.1 , -0.1 ],
    [-0.1 , -0.1 , -0.1 , -0.1 , -0.1 ,  0.15,  0.15, -0.1 ,  0.15,
      0.15,  0.15,  0.15,  0.4 ,  0.15,  0.15],
    [-0.25,  0.25,  0.  , -0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,
      0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
    [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  , -0.25,  0.25,  0.  , -0.25,
      0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
    [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
      0.  , -0.25,  0.25,  0.  , -0.25,  0.25]]))
pmagpy.pmag.designAARM(npos)[source]#

Calculates B matrix for AARM calculations.

Parameters:

npos (number of positions) – 9 is the only number of positions valid.

Returns:

  • B (B matrix as an array)

  • H (Field directions)

  • tmpH (tmpH matrix)

pmagpy.pmag.designATRM(npos)[source]#

Calculates B matrix for ATRM calculations.

Parameters:

npos (number of positions) – 6 and greater number of positions valid.

Returns:

  • B (B matrix as an array)

  • H (Field directions)

  • tmpH (tmpH matrix)

pmagpy.pmag.di_boot(DIs, nb=5000, random_seed=None)[source]#

Returns bootstrap means for Directional data.

Parameters:
  • DIs (nested list of Dec,Inc pairs)

  • nb (number of bootstrap pseudosamples, default is 5000)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

BDIs

Return type:

nested list of bootstrapped mean Dec,Inc pairs

Examples

>>> di_block = ([[-45,150],
 [-40,150],
 [-38,145]])
>>> pmag.di_boot(di_block,5)
[[136.66619627955163, 30.021001931432338],
 [138.33380372044837, 30.02100193143235],
 [140.64213759144877, 31.669596401508702],
 [136.66619627955163, 30.021001931432338],
 [139.58053739971953, 33.378250658618654]]
pmagpy.pmag.dia_vgp(*args)[source]#

Converts directional data (declination, inclination, alpha95) at a given location (Site latitude, Site longitude) to pole position (pole longitude, pole latitude, dp, dm).

Parameters:
  • (Dec (Takes input as)

  • Inc

  • a95

  • latitude (Site)

  • longitude) (Site)

  • parameters) (Input can be as individual values (5)

  • or

  • lists (as a list of)

Returns:

  • if input is individual values for one pole the return is

  • pole longitude, pole latitude, dp, dm

  • if input is list of lists the return is

  • list of pole longitudes, list of pole latitudes, list of dp, list of dm

Examples

>>> pmag.dia_vgp(4, 41, 0, 33, -117)
(41.68629415047637, 79.86259998889103, 0.0, 0.0)
pmagpy.pmag.dimap(D, I)[source]#

Function to map directions to x,y pairs in equal area projection.

Parameters:
  • D (list or array of declinations (as float))

  • I (list or array or inclinations (as float))

Returns:

XY

Return type:

x, y values of directions for equal area projection [x,y]

pmagpy.pmag.dimap_V(D, I)[source]#

Maps declinations and inclinations into equal area projections.

Parameters:
  • D (numpy arrays)

  • I (numpy arrays)

Returns:

XY

Return type:

array of equal area projections

Examples

>>> pmag.dimap_V([35,60,20],[70,80,-10])
array([[0.140856382055789, 0.20116376126988 ],
   [0.106743548942519, 0.061628416716219],
   [0.310909633795401, 0.85421719834377 ]])
pmagpy.pmag.dir2cart(d)[source]#

Converts a list or array of vector directions in degrees (declination, inclination) to an array of the direction in cartesian coordinates (x,y,z).

Parameters:

d (list or array of [dec,inc] or [dec,inc,intensity])

Returns:

cart

Return type:

array of [x,y,z]

Examples

>>> pmag.dir2cart([200,40,1])
array([-0.71984631, -0.26200263,  0.64278761])
>>> pmag.dir2cart([200,40])
array([[-0.719846310392954, -0.262002630229385,  0.642787609686539]])
>>> data = np.array([  [16.0,    43.0, 21620.33],
       [30.5,    53.6, 12922.58],
        [6.9,    33.2, 15780.08],
      [352.5,    40.2, 33947.52],
      [354.2,    45.1, 19725.45]])
>>> pmag.dir2cart(data)
array([[15199.574113612794 ,  4358.407742577491 , 14745.029604010038 ],
   [ 6607.405832448041 ,  3892.0594770716   , 10401.304487835589 ],
   [13108.574245285025 ,  1586.3117853121191,  8640.591471770322 ],
   [25707.154931463603 , -3384.411152593326 , 21911.687763162565 ],
   [13852.355235322588 , -1407.0709331498472, 13972.322052043308 ]])
pmagpy.pmag.dir_df_boot(dir_df, nb=5000, par=False, random_seed=None)[source]#

Performs a bootstrap for direction DataFrame with optional parametric bootstrap

Parameters:
  • dir_df (Pandas DataFrame with columns:) –

    dir_decmean declination

    dir_inc : mean inclination

    Required for parametric bootstrap

    dir_n : number of data points in mean dir_k : Fisher k statistic for mean

  • nb (number of bootstraps, default is 5000)

  • par (if True, do a parameteric bootstrap)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

BDIs

Return type:

nested list of bootstrapped mean Dec,Inc pairs

Examples

>>> dir_df = pd.DataFrame()
>>> dir_df['dir_inc'] = [30,75,-113,-127,104]
>>> dir_df['dir_dec'] = [50,100,78,48,87]
>>> pmag.dir_df_boot(dir_df,nb=4)
[[249.0092732274716, 47.78774025782868],
 [52.15562660104691, 14.523345688004293],
 [214.5976992675414, 49.79280429500907],
 [119.6384153360684, 86.17066958304461]]
>>> dir_df['dir_n'] = [4,15,2,36,55]
>>> dir_df['dir_k'] = [1.2,3.0,0.4,0.4,0.8]
>>> pmag.dir_df_boot(dir_df,3,par=True)
[[43.54318517848151, 53.40671924110994],
 [278.5836582875345, 25.159165079114043],
 [276.59474232833645, -22.88695795286902]]
pmagpy.pmag.dir_df_fisher_mean(dir_df)[source]#

Calculates fisher mean for Pandas dataframe.

Parameters:

dir_df (pandas data frame with columns:) – dir_dec : declination dir_inc : inclination

Returns:

fpars – dec : mean declination inc : mean inclination r : resultant vector length n : number of data points k : Fisher k value csd : Fisher circular standard deviation alpha95 : Fisher circle of 95% confidence

Return type:

dictionary containing the Fisher mean and statistics

pmagpy.pmag.dms2dd(d)[source]#

Converts a list or array of degree, minute, second locations to an array of decimal degrees.

d : list or array of [deg, min, sec]

d : input list or array dd : int

decimal degree corresponding to d

>>> pmag.dms2dd([60,35,15])
60 35 15
array(60.587500000000006)
>>> data = np.array([  [16.0,    43.0, 33],
       [30.5,    53.6, 58],
        [6.9,    33.2, 8],
      [352.5,    40.2, 52],
      [354.2,    45.1, 45]])
>>> pmag.dms2dd(data)
[ 16.   30.5   6.9 352.5 354.2] [43.  53.6 33.2 40.2 45.1] [33. 58.  8. 52. 45.]
array([ 16.72583333333333 , 31.409444444444446, 7.455555555555557,

353.18444444444447 , 354.96416666666664 ])

pmagpy.pmag.do_mag_map(date, lon_0=0, alt=0, file='', mod='cals10k', resolution='low')[source]#

Returns lists of declination, inclination and intensities for lat/lon grid for desired model and date.

Parameters:
  • Era (date = Required date in decimal years (Common)

  • NB (negative for Before Common Era) -)

  • Parameters (Optional)

  • -------------------

  • ('arch3k' (mod = model to use)

  • 'cals3k'

  • 'pfm9k'

  • 'hfm10k'

  • 'cals10k.2'

  • 'shadif14k'

  • 'cals10k.1b'

  • 'custom')

  • model (file = l m g h formatted filefor custom)

  • lon_0 (central longitude for Hammer projection)

  • altitude (alt =)

  • ['low' (resolution =)

  • low ('high'] default is)

Returns:

  • Bdec=list of declinations

  • Binc=list of inclinations

  • B = list of total field intensities in nT

  • Br = list of radial field intensities

  • lons = list of longitudes evaluated

  • lats = list of latitudes evaluated

pmagpy.pmag.doaniscorr(PmagSpecRec, AniSpec)[source]#

This function takes the 6 element ‘s’ vector and the Dec,Inc, Int ‘Dir’ data, performs simple anisotropy correction, and returns corrected Dec, Inc, Int. This is used in thellier_magic2.py.

pmagpy.pmag.dobingham(di_block)[source]#

Calculates the Bingham mean and associated statistical parameters from directions that are input as a di_block.

Parameters:

di_block (a nested list of [dec,inc] or [dec,inc,intensity])

Returns:

  • bpars (dictionary containing the Bingham mean and associated statistics)

  • dictionary keys – dec : mean declination inc : mean inclination n : number of datapoints Eta : major ellipse Edec : declination of major ellipse axis Einc : inclination of major ellipse axis Zeta : minor ellipse Zdec : declination of minor ellipse axis Zinc : inclination of minor ellipse axis

pmagpy.pmag.docustom(lon, lat, alt, gh)[source]#

Passes the coefficients to the Malin and Barraclough routine (function pmag.magsyn) to calculate the field from the coefficients.

Parameters:
  • lon (east longitude in degrees (0 to 360 or -180 to 180))

  • lat (latitude in degrees (-90 to 90))

  • alt (height above mean sea level in km (itype = 1 assumed))

  • gh (list of gauss coefficients)

Returns:

  • x (north component of the magnetic field in nT)

  • y (east component of the magnetic field in nT)

  • z (downward component of the magnetic field in nT)

  • f (total magnetic field in nT)

Examples

>>> gh = pmag.doigrf(30,70,10,2022,coeffs=True)
>>> pmag.docustom(30,70,10,gh)
(10033.695088989529, 2822.610862622648, 53170.834174096184, 54182.8365443324)
pmagpy.pmag.dodirot(D, I, Dbar, Ibar)[source]#

Rotate a direction (declination, inclination) by the difference between dec = 0 and inc = 90 and the provided desired mean direction.

Parameters:
  • D (declination to be rotated)

  • I (inclination to be rotated)

  • Dbar (declination of desired mean)

  • Ibar (inclination of desired mean)

Returns:

drot, irot

Return type:

rotated declination and inclination

Examples

>>> pmag.dodirot(0,90,5,85)
(5.0, 85.0)
pmagpy.pmag.dodirot_V(di_array, Dbar, Ibar)[source]#

Rotate an array of declination, inclination pairs by the difference between dec = 0 and inc = 90 and the provided desired mean direction

Parameters:
  • di_array (numpy array of [[Dec1,Inc1],[Dec2,Inc2],....])

  • Dbar (declination of desired mean)

  • Ibar (declination of desired mean)

Returns:

Rotated decs and incs: [[rot_Dec1,rot_Inc1],[rot_Dec2,rot_Inc2],….]

Return type:

array

Examples

>>> di_array = np.array([[0,90],[0,90],[0,90]])
>>> pmag.dodirot_V(di_array,5,15)
array([[ 5.               , 15.000000000000002],
    [ 5.               , 15.000000000000002],
    [ 5.               , 15.000000000000002]])
pmagpy.pmag.doeigs_s(tau, Vdirs)[source]#

Gets elements of s from eigenvaulues - note that this is very unstable.

Parameters:
  • tau (3 element array) – list of eigenvalues in decreasing order: [t1,t2,t3]

  • V (list of the eigenvector directions) – [[V1_dec,V1_inc],[V2_dec,V2_inc],[V3_dec,V3_inc]]

Returns:

s = [x11,x22,x33,x12,x23,x13]

Return type:

The six tensor elements as a list

Examples

>>> pmag.doeigs_s([2.2, -0.33, -0.68],
     [[44.59, 40.45],
      [295.45, 21.04],
      [185.08, 42.13]])
array([0.22194667, 0.3905577 , 0.57749563, 0.7154779 , 0.8923144 ,
   1.0629525 ], dtype=float32)
pmagpy.pmag.doeqdi(x, y, UP=False)[source]#

Takes digitized x,y, data and returns the dec,inc, assuming an equal area projection.

Parameters:
  • x (array of digitized x from point on equal area projection)

  • y (array of igitized y from point on equal area projection)

  • UP (if True, is an upper hemisphere projection)

Returns:

  • dec (declination)

  • inc (inclination)

pmagpy.pmag.doflip(dec, inc)[source]#

Flips upper hemisphere data to lower hemisphere.

Parameters:
  • dec (float) – declination

  • inc (float) – inclination

Returns:

containing the flipped declination and inclination

Return type:

tuple

Examples

>>> pmag.doflip(30,-45)
(210.0, 45)
pmagpy.pmag.dogeo(dec, inc, az, pl)[source]#

Rotates declination and inclination into geographic coordinates using the azimuth and plunge of the X direction (lab arrow) of a specimen.

Parameters:
  • dec (declination in specimen coordinates)

  • inc (inclination in specimen coordinates)

Returns:

rotated_direction

Return type:

tuple of declination, inclination in geographic coordinates

Examples

>>> pmag.dogeo(0.0,90.0,0.0,45.5)
(180.0, 44.5)
pmagpy.pmag.dogeo_V(indat)[source]#

Rotates declination and inclination into geographic coordinates using the azimuth and plunge of the X direction (lab arrow) of a specimen.

Parameters:

indat (array of lists) – data format: [dec, inc, az, pl]

Returns:

an array of declinations an array of inclinations

Return type:

two arrays

Examples

>>> pmag.dogeo_V(np.array([[0.0,90.0,0.0,45.5],[0.0,90.0,0.0,45.5]]))
(array([180., 180.]), array([44.5, 44.5]))
pmagpy.pmag.dohext(nf, sigma, s)[source]#

Calculates hext parameters for nf, sigma and s.

Parameters:
  • nf (number of degrees of freedom (measurements - 6))

  • sigma (the sigma of the measurements)

  • s ([x11,x22,x33,x12,x23,x13] - the six tensor elements)

Returns:

  • hpars (dictionary of Hext statistics with keys:) – ‘F_crit’ : critical value for anisotropy ‘F12_crit’ : critical value for tau1>tau2, tau2>3 ‘F’ : value of F ‘F12’ : value of F12 ‘F23’ : value of F23 ‘v1_dec’: declination of principal eigenvector ‘v1_inc’: inclination of principal eigenvector ‘v2_dec’: declination of major eigenvector ‘v2_inc’: inclination of major eigenvector ‘v3_dec’: declination of minor eigenvector ‘v3_inc’: inclination of minor eigenvector ‘t1’: principal eigenvalue ‘t2’: major eigenvalue ‘t3’: minor eigenvalue ‘e12’: angle of confidence ellipse of principal eigenvector in direction of major eigenvector ‘e23’: angle of confidence ellipse of major eigenvector in direction of minor eigenvector ‘e13’: angle of confidence ellipse of principal eigenvector in direction of minor eigenvector

  • If working with data set with no sigmas and the average is desired, use nf,sigma,avs=pmag.sbar(Ss) as input

Examples

>>> pmag.dohext(30, 0.00027464, [0.33586472,0.32757074,0.33656454,0.0056526,0.00449771,-0.00036542])
{'F_crit': '2.5335',
 'F12_crit': '3.3158',
 'F': 820.3194287677485,
 'F12': 74.97208429827333,
 'F23': 1167.2979118918333,
 'v1_dec': 38.360480228001826,
 'v1_inc': 36.10621428141474,
 'v2_dec': 183.62757676112915,
 'v2_inc': 48.41031537341878,
 'v3_dec': 294.8243200339332,
 'v3_inc': 17.791534673908338,
 't1': 0.33999866,
 't2': 0.33663565,
 't3': 0.3233657,
 'e12': 6.002663418693858,
 'e23': 1.5264872237415046,
 'e13': 1.2179522275647792}
pmagpy.pmag.doigrf(lon, lat, alt, date, **kwargs)[source]#

Calculates the interpolated (<=2025) or extrapolated (>2025) main field and secular variation coefficients and passes them to the Malin and Barraclough routine (function pmag.magsyn) to calculate the field from the coefficients.

Parameters:
  • lon (east longitude in degrees (0 to 360 or -180 to 180))

  • lat (latitude in degrees (-90 to 90))

  • alt (height above mean sea level in km (itype = 1 assumed))

  • date (Required date in years and decimals of a year (A.D.))

  • Parameters (Optional)

  • -------------------

  • coeffs (if True, then return the gh coefficients)

  • mod (model to use ('arch3k','cals3k','pfm9k','hfm10k','cals10k.2','cals10k.1b','shadif14k','shawq2k','shawqIA')) –

    arch3k (Korte et al., 2009) cals3k (Korte and Constable, 2011) cals10k.1b (Korte et al., 2011) pfm9k (Nilsson et al., 2014) hfm.OL1.A1 (Constable et al., 2016) cals10k.2 (Constable et al., 2016) shadif14k (Pavon-Carrasco et al., 2014) shawq2k (Campuzano et al., 2019) shawqIA (Osete et al., 2020) ggf100k (Panofska et al., 2018) [in 200 year increments from -99950 to 1850 only]

    NBthe first four of these models, are constrained to agree

    with gufm1 (Jackson et al., 2000) for the past four centuries

Returns:

  • x (north component of the magnetic field in nT)

  • y (east component of the magnetic field in nT)

  • z (downward component of the magnetic field in nT)

  • f (total magnetic field in nT)

  • gh (list of gauss coefficients) – only if coeffs=True

  • By default, IGRF14 coefficients are used between 1900 and 2025

  • from http (//www.ngdc.noaa.gov/IAGA/vmod/igrf.html.)

To check the results you can run the interactive program at the NGDC www.ngdc.noaa.gov/geomag-web

Examples

>>> pmag.doigrf(30,70,10,2022)
(10030.985358058582, 2797.0490284010084, 53258.99275624336, 54267.52675339505)
>>> pmag.doigrf(30,70,10,2022,coeffs=True)
array([-2.94048e+04, -1.45090e+03,  4.65250e+03, -2.49960e+03,
    2.98200e+03, -2.99160e+03,  1.67700e+03, -7.34600e+02,
    1.36320e+03, -2.38120e+03, -8.21000e+01,  1.23620e+03,
    2.41900e+02,  5.25700e+02, -5.43400e+02,  9.03000e+02,
    8.09500e+02,  2.81900e+02,  8.63000e+01, -1.58400e+02,
   -3.09400e+02,  1.99700e+02,  4.80000e+01, -3.49700e+02, ...
pmagpy.pmag.doincfish(inc, method='mcfadden_reid')[source]#

Calculates Fisher mean inclination from inclination-only data.

Parameters:
  • inc (list of inclination values)

  • method (str, default 'mcfadden_reid') –

    ‘mcfadden_reid’the estimator of McFadden and Reid (1982), with

    asymmetric confidence limits after McElhinny and McFadden (2000). Its fitness equation can have no solution for steep, scattered data, in which case an absolute-minimum fallback is used and a warning is printed.

    ’arason_levi’the maximum likelihood estimator of Arason and Levi

    (2010, doi:10.1111/j.1365-246X.2010.04671.x), which is robust for steep data. The angular standard deviation and alpha95 follow their eqs 22 and 23; the implementation reproduces the numerical example of their Table 2 (Im = 71.85, kappa = 32.45, alpha95 = 9.17). A maximum at inclination 90 indicates that a unique solution does not exist for the data (their Section 7); the profile-likelihood limits then bound the plausible range.

Returns:

‘n’ : number of inclination values supplied ‘ginc’ : gaussian mean of inclinations ‘inc’ : estimated Fisher mean ‘r’ : estimated Fisher R value ‘k’ : estimated Fisher kappa ‘alpha95’: estimated confidence limit ‘upper_confidence_limit’ : estimated upper confidence limit of inclination ‘lower_confidence_limit’ : estimated lower confidence limit of inclination ‘csd’ : estimated circular standard deviation With method=’arason_levi’, two additional keys ‘profile_lower_confidence_limit’ and ‘profile_upper_confidence_limit’ give a 95% interval on the mean inclination from the profile likelihood (the marginal-likelihood style interval recommended by Arason and Levi for near-vertical solutions).

Return type:

dict

Examples

>>> pmag.doincfish([62.4, 61.6, 50.2, 65.2, 53.2, 61.4, 74.0, 60.0, 52.6, 71.8])
{'n': 10,
 'ginc': 61.239999999999995,
 'inc': 62.18,
 'r': 9.828974184785405,
 'k': 52.623634558953846,
 'upper_confidence_limit': 66.49823541535572,
 'lower_confidence_limit': 55.9733682324565,
 'alpha95': 5.2624335914496125,
 'csd': 11.165922232016465}
pmagpy.pmag.dok15_s(k15)[source]#

Calculates least-squares matrix for 15 measurements from Jelinek [1976].

Parameters:

k15 (k15 value)

Returns:

  • sbar (array of six 15 element tensors)

  • sigma (array of sigma, standard deviation, of the measurement)

  • bulk (array of bulk susptibility)

Examples

>>> pmag.dok15_s(0.5)
(array([[ 0.75,  0.75,  2.  ,  0.75,  0.75, -0.5 , -0.5 , -0.5 , -0.5 ,
     -0.5 ,  0.75,  0.75, -0.5 ,  0.75,  0.75],
    [ 0.75,  0.75, -0.5 ,  0.75,  0.75,  0.75,  0.75,  2.  ,  0.75,
      0.75, -0.5 , -0.5 , -0.5 , -0.5 , -0.5 ],
    [-0.5 , -0.5 , -0.5 , -0.5 , -0.5 ,  0.75,  0.75, -0.5 ,  0.75,
      0.75,  0.75,  0.75,  2.  ,  0.75,  0.75],
    [-1.25,  1.25,  0.  , -1.25,  1.25,  0.  ,  0.  ,  0.  ,  0.  ,
      0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
    [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  , -1.25,  1.25,  0.  , -1.25,
      1.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
    [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
      0.  , -1.25,  1.25,  0.  , -1.25,  1.25]]),
 array([6.101001739241042, 6.101001739241042, 6.101001739241042,
    6.101001739241042, 6.101001739241042, 6.101001739241042,
    6.101001739241042, 6.101001739241042, 6.101001739241042,
    6.101001739241042, 6.10100173924104 , 6.10100173924104 ,
    6.101001739241042, 6.10100173924104 , 6.10100173924104 ]),
 array([0.033333333333333, 0.033333333333333, 0.033333333333333,
    0.033333333333333, 0.033333333333333, 0.033333333333333,
    0.033333333333333, 0.033333333333333, 0.033333333333333,
    0.033333333333333, 0.033333333333333, 0.033333333333333,
    0.033333333333333, 0.033333333333333, 0.033333333333333]))
pmagpy.pmag.dokent(data, NN, distribution_95=False)[source]#

Gets Kent parameters for data.

Parameters:
  • data (nested pairs of [Dec,Inc])

  • NN (normalization) – Number of data for Kent ellipse NN is 1 for Kent ellipses of bootstrapped mean directions

  • distribution_95 (the default behavior (distribution_95=False) is for) – the function to return the confidence region for the mean direction. if distribution_95=True what instead will be returned is the parameters associated with the region containing 95% of the directions.

Returns:

dec : mean declination inc : mean inclination n : number of datapoints Zeta : major ellipse Zdec : declination of major ellipse axis Zinc : inclination of major ellipse axis Eta : minor ellipse Edec : declination of minor ellipse axis Einc : inclination of minor ellipse axis

Return type:

kpars dictionary keys

pmagpy.pmag.dolnp(data, direction_type_key)[source]#

Returns fisher mean, a95 for data using the method of McFadden and McElhinny 1988 for lines and planes. Handles both data-model 3.0 (dir_dec, dir_inc, method_codes) and 2.5 (dec, inc, magic_method_codes) records.

Parameters:
  • data (list of dicts with keys:) – Data model 3.0: dir_dec, dir_inc, dir_tilt_correction, method_codes Data model 2.5: dec, inc, tilt_correction, magic_method_codes

  • direction_type_key (key for line/plane classification ('direction_type', 'dir_type', etc.).) – If absent from records, classification falls back to checking method_codes for DE-BFP.

Returns:

  • dict with keys (dec, inc, n_total, n_lines, n_planes, alpha95, R, K)

  • Effects

  • ——-

  • prints to screen in case of no data

pmagpy.pmag.dolnp3_0(Data)[source]#

Compute the Fisher mean for a list of dicts using data-model 3.0 keys. Translates 3.0-style records (with dir_dec, dir_inc, dir_tilt_correction, and method_codes containing DE-BFP for planes) into the 2.5-style format that dolnp() expects, then calls dolnp() and returns the result.

Used by demag_gui.py for computing sample- and site-level Fisher means when saving MagIC tables.

Parameters:

Data (nested list of dictionaries with keys) – dir_dec dir_inc dir_tilt_correction method_codes

Returns:

ReturnData – dec : fisher mean dec of data in Data inc : fisher mean inc of data in Data n_lines : number of directed lines [method_code = DE-BFL or DE-FM] n_planes : number of best fit planes [method_code = DE-BFP] alpha95 : fisher confidence circle from Data R : fisher R value of Data K : fisher k value of Data

Return type:

dictionary with keys

Effects

prints to screen in case of no data

pmagpy.pmag.domagicmag(file, Recs)[source]#

Converts a magic record back into the SIO mag format.

pmagpy.pmag.domean(data, start, end, calculation_type)[source]#

Gets average direction using Fisher or principal component analysis (line or plane) methods.

Parameters:
  • data (nest list of data) – eg. [[treatment,dec,inc,int,quality],…]

  • start (step being used as start of fit (often temperature minimum))

  • end (step being used as end of fit (often temperature maximum))

  • calculation_type (string describing type of calculation to be made)

  • (line) ('DE-BFL')

  • (line-anchored) ('DE-BFL-A')

  • (line-with-origin) ('DE-BFL-O')

:param : :param ‘DE-BFP’ (plane): :param ‘DE-FM’ (Fisher mean):

Returns:

mpars – The keys within are “specimen_n”,”measurement_step_min”, “measurement_step_max”,”specimen_mad”,”specimen_dec”,”specimen_inc”.

Return type:

dictionary

pmagpy.pmag.doprinc(data)[source]#

Gets principal components from data in form of a list of [dec,inc,int] data.

Parameters:

data (nested list of dec, inc and optionally intensity vectors)

Returns:

ppars – dec : principal direction declination inc : principal direction inclination V2dec : intermediate eigenvector declination V2inc : intermediate eigenvector inclination V3dec : minor eigenvector declination V3inc : minor eigenvector inclination tau1 : major eigenvalue tau2 : intermediate eigenvalue tau3 : minor eigenvalue N : number of points

Return type:

dictionary with the principal components

pmagpy.pmag.doreverse(dec, inc)[source]#

Calculates the antipode of a direction.

Parameters:
  • dec (float) – declination

  • inc (float) – inclination

Returns:

  • dec (float) – antipode of the declination

  • inc (float) – antipode of the inclination

Examples

>>> pmag.doreverse(30,45)
(210.0, -45)
pmagpy.pmag.doreverse_list(decs, incs)[source]#

Calculates the antipode of list of directions.

Parameters:
  • decs (list of declinations)

  • incs (list of inclinations)

Returns:

  • decs_flipped (antipode list of declinations)

  • incs_flipped (antipode list of inclinations)

Examples

>>> pmag.doreverse_list([30,32,70,54],[60,62,0,10])
([210.0, 212.0, 250.0, 234.0], [-60, -62, 0, -10])
pmagpy.pmag.doseigs(s)[source]#

Convert s format for eigenvalues and eigenvectors.

Parameters:

s (the six tensor elements as a list) – (s=[x11,x22,x33,x12,x23,x13])

Returns:

  • A three element array and a nested list of dec, inc pairs

  • tau (three element array ([t1,t2,t3])) – tau is an list of eigenvalues in decreasing order:

  • V (second array ([[V1_dec,V1_inc],[V2_dec,V2_inc],[V3_dec,V3_inc]])) – is an list of the eigenvector directions

Examples

>>> pmag.doseigs([1,2,3,4,5,6])
([2.021399, -0.33896524, -0.6824337],
 [[44.59696385583322, 40.45122920806129],
  [295.4500678147439, 21.04129013670037],
  [185.0807541485627, 42.138918019674385]])
pmagpy.pmag.dosgeo(s, az, pl)[source]#

Rotates matrix a to its azimuth and plunge.

Parameters:
  • s ([x11,x22,x33,x12,x23,x13] - the six tensor elements)

  • az (the azimuth of the specimen X direction)

  • pl (the plunge (inclination) of the specimen X direction)

Returns:

s_rot

Return type:

[x11,x22,x33,x12,x23,x13] after rotation

Examples

>>> pmag.dosgeo([0.33586472,0.32757074,0.33656454,0.0056526,0.00449771,-0.00036542],12,33)
array([ 0.33509237  ,  0.3288845   ,  0.33602312  ,  0.0038898108,
    0.0066036563, -0.0018823999], dtype=float32)
pmagpy.pmag.dostilt(s, bed_az, bed_dip)[source]#

Rotates “s” tensor to stratigraphic coordinates

Parameters:
  • s ([x11,x22,x33,x12,x23,x13] - the six tensor elements)

  • bed_az (bedding dip direction)

  • bed_dip (bedding dip)

Returns:

s_rot

Return type:

[x11,x22,x33,x12,x23,x13] - after rotation

Examples

>>> pmag.dostilt([0.33586472,0.32757074,0.33656454,0.0056526,0.00449771,-0.00036542],20,38)
array([ 0.33473614  ,  0.32911453  ,  0.33614933  ,  0.0075679934,
    0.0020322995, -0.0014457355], dtype=float32)
pmagpy.pmag.dosundec(sundata)[source]#

Returns the declination for a given set of suncompass data.

Parameters:

sundata (dictionary with these keys:) – date: time string with the format ‘yyyy:mm:dd:hr:min’ delta_u: time to SUBTRACT from local time for Universal time lat: latitude of location (negative for south) lon: longitude of location (negative for west) shadow_angle: shadow angle of the desired direction with respect to the sun.

Returns:

sunaz

Return type:

the declination of the desired direction with respect to true north

Examples

>>> sundata={'date':'1994:05:23:16:9','delta_u':3,'lat':35,'lon':33,'shadow_angle':68}
>>> pmag.dosundec(sundata)
154.24420046668928
pmagpy.pmag.dotilt(dec, inc, bed_az, bed_dip)[source]#

Does a tilt correction on a direction (dec,inc) using bedding dip direction and bedding dip.

Parameters:
  • dec (declination directions in degrees)

  • inc (inclination direction in degrees)

  • bed_az (bedding dip direction)

  • bed_dip (bedding dip)

Returns:

dec,inc

Return type:

a tuple of rotated dec, inc values

Examples

>>> pmag.dotilt(91.2,43.1,90.0,20.0)
(90.952568837153436, 23.103411670066617)
pmagpy.pmag.dotilt_V(indat)[source]#

Does a tilt correction on an array with rows of [dec, inc, bedding dip direction, bedding dip].

Parameters:

indat (nested array of [[dec1, inc1, bed_az1, bed_dip1],[dec2,inc2,bed_az2,bed_dip2]...]) – declination, inclination, bedding dip direction and bedding dip

Returns:

dec, inc

Return type:

arrays of rotated declination, inclination

Examples

>>> pmag.dotilt_V(np.array([[91.2,43.1,90.0,20.0],[92.0,40.4,90.5,21.3]]))
(array([90.95256883715344, 91.70884991139725]),
 array([23.103411670066613, 19.105747819853423]))
pmagpy.pmag.dovandamme(vgp_df)[source]#

Determine the S_b value for VGPs using the Vandamme (1994) method for determining cutoff value for “outliers”.

Parameters:

vgp_df (pandas DataFrame with required column "vgp_lat") – This should be in the desired coordinate system and assumes one polarity

Returns:

  • vgp_df (after applying cutoff)

  • cutoff (colatitude cutoff)

  • S_b (S_b of vgp_df after applying cutoff)

pmagpy.pmag.dovds(data)[source]#

Calculates vector difference sum for demagnetization data.

Parameters:

data (nested array of data)

Returns:

vds

Return type:

vector difference of data as a float

Examples

>>> data = np.array([  [16.0,    43.0, 21620.33],
       [30.5,    53.6, 12922.58],
        [6.9,    33.2, 15780.08],
      [352.5,    40.2, 33947.52],
      [354.2,    45.1, 19725.45]])
>>> pmag.dovds(data)
69849.6597634
pmagpy.pmag.execute(st, **kwargs)[source]#

Work around for Python3 exec function which doesn’t allow changes to the local namespace because of scope. This breaks a lot of the old functionality in the code which was originally in Python2. So this function runs just like exec except that it returns the output of the input statement to the local namespace. It may break if you start feeding it multiline monoliths of statements (haven’t tested) but you shouldn’t do that anyway (bad programming).

Parameters:
  • st (the statement you want executed and for which you want the return)

  • kwargs (anything that may need to be in this namespace to execute st)

Return type:

The return value of executing the input statement

pmagpy.pmag.fcalc(col, row)[source]#

Looks up an F-test stastic from F tables F(col,row), where row is number of degrees of freedom - this is 95% confidence (p=0.05).

Parameters:
  • col (degrees of freedom column)

  • row (degrees of freedom row)

Returns:

F

Return type:

value for 95% confidence from the F-table

Examples

>>> pmag.fcalc(3,4.8)
6.5915
pmagpy.pmag.fillkeys(Recs)[source]#

Reconciles keys of dictionaries within Recs.

Parameters:

Recs (list of dictionaries in MagIC format OR pandas dataframe)

Returns:

  • input Recs

  • keylist (list of keys found in Recs)

pmagpy.pmag.find(f, seq)[source]#

Returns input value (f) if it is in the given array (seq).

Parameters:
  • f (string value)

  • seq (array of strings)

Return type:

String value ‘f’ if it is found in seq.

Examples

>>> A = ['11', '12', '13', '14']
>>> find('11',A)
'11'
pmagpy.pmag.find_CMDT_CR(Ahat, Tc, mhat12)[source]#

Find the sequence of points along the confidence region of the Common Mean Direction Test (CMDT-CR) of Heslop et al., 2023. Provides a collection of points on the boundary of the 1- 𝛼 confidence region for the common mean direction according to the procedure in Appendix B.

N.B: find_CMDT_CR should only be used if null hypothesis of common mean direction cannot be rejected

Parameters:
  • Ahat (ndarray) – Combined covariance matrix.

  • Tc (float) – T value on the boundary of the confidence region.

  • mhat12 (ndarray) – Estimated common mean direction.

Returns:

Sequence of points along the confidence region.

Return type:

ndarray

pmagpy.pmag.find_CR(mhat, Mhat, Ghat, n, Tc)[source]#

Calculates the closed confidence region boundary, mCI.

Parameters:
  • mhat – numpy array representing the mean direction of the original data set.

  • Mhat – numpy matrix representing the Mhat matrix for mean direction.

  • Ghat – numpy matrix representing the covariance matrix.

  • n – int, number of observations.

  • Tc – float, critical T value on the confidence region boundary.

Returns:

closed confidence region boundary, mCI.

Return type:

numpy array

Raises:

None –

pmagpy.pmag.find_T(m, n, Mhat, Ghat)[source]#

Calculates the T value estimated from Equation 6.

Parameters:
  • m – numpy matrix representing the direction under consideration.

  • n – int, number of observations.

  • Mhat – numpy matrix representing the Mhat matrix for mean direction.

  • Ghat – numpy matrix representing the covariance matrix.

Returns:

T value estimated from Equation 6 of Heslop et al., 2023

Return type:

numpy array

Raises:

None –

pmagpy.pmag.find_dmag_rec(s, data, **kwargs)[source]#

Returns demagnetization data for specimen s from the data. Excludes other kinds of experiments and “bad” measurements.

Parameters:
  • s (specimen name)

  • data (DataFrame with measurement data)

  • **kwargs – version : if not 3, assume data model = 2.5

Returns:

  • datablock (nested list of data for zijderveld plotting) – [[tr, dec, inc, int, ZI, flag],…] tr : treatment step dec : declination inc : inclination int : intensity ZI : whether zero-field first or infield-first step flag : g or b , default is set to ‘g’

  • units (list of units found [‘T’,’K’,’J’] for tesla, kelvin or joules)

pmagpy.pmag.find_f(data)[source]#

Given a distribution of directions, this function determines parameters (elongation, inclination, flattening factor, and elongation direction) that are consistent with the TK03 secular variation model.

Parameters:

data (array of declination, inclination pairs)

Returns:

  • Es (list of elongation values)

  • Is (list of inclination values)

  • Fs (list of flattening factors)

  • V2s (list of elongation directions (relative to the distribution))

  • The function will return a zero list ([0]) for each of these parameters if the directions constitute a pathological distribution.

Examples

>>> directions = np.array([[140,21],[127,23],[142,19],[136,22]])
>>> Es, Is, Fs, V2s = pmag.find_f(directions)
pmagpy.pmag.find_samp_rec(s, data, az_type)[source]#

Find the orientation info for samp s

pmagpy.pmag.findrec(s, data)[source]#

Finds all the records belonging to s in data.

Parameters:
  • s (str) – data value of interest

  • data (nested list of data) – eg. [[treatment,dec,inc,int,quality],…]

Returns:

datablock

Return type:

nested list of data relating to s

Examples

>>> data = [['treatment','dec','inc','int','quality'],['treatment1','dec1','inc1','int1','quality1']]
>>> pmag.findrec('treatment', data)
[['dec', 'inc', 'int', 'quality']]
pmagpy.pmag.first_rec(ofile, Rec, file_type)[source]#

Opens the file ofile as a magic template file with headers as the keys to Rec.

Parameters:

ofile (string with the path of the input file)

pmagpy.pmag.first_up(ofile, Rec, file_type)[source]#

Writes the header for a MagIC template file.

pmagpy.pmag.fisher_by_pol(data)[source]#

Do fisher mean after splitting data into two polarity domains.

Parameters:

data (list of dictionaries with 'dec' and 'inc')

Returns:

‘A’= polarity ‘A’ ‘B = polarity ‘B’ ‘ALL’= switching polarity of ‘B’ directions, and calculate fisher mean of all data

Return type:

three dictionaries

Examples

>>> data = [{'dec':-45,'inc':150}, {'dec':-44,'inc':150},{'dec':-45.3,'inc':149}]
>>> pmag.fisher_by_pol(data)
{'B': {'dec': 135.23515314555496,
  'inc': 30.334504880687444,
  'n': 3,
  'r': 2.9997932987279383,
  'k': 9675.799186195498,
  'alpha95': 1.2533447889568254,
  'csd': 0.8234582703442529,
  'sites': '',
  'locs': ''},
 'All': {'dec': 315.23515314555493,
  'inc': -30.334504880687444,
  'n': 3,
  'r': 2.999793298727938,
  'k': 9675.79918617471,
  'alpha95': 1.2533447889582796,
  'csd': 0.8234582703451375,
  'sites': '',
  'locs': ''}}
pmagpy.pmag.fisher_mean(data)[source]#

Calculates the Fisher mean and associated parameter from a di_block.

Parameters:

data (nested list of [dec,inc] or [dec,inc,intensity])

Returns:

fpars – dec : mean declination inc : mean inclination r : resultant vector length n : number of data points k : Fisher k value csd : Fisher circular standard deviation alpha95 : Fisher circle of 95% confidence

Return type:

dictionary containing the Fisher mean and statistics with keys

Examples

>>> data = [[150,-45],[151,-46],[145,-38],[146,-41]]
>>> pmag.fisher_mean(data)
{'dec': 147.87247771265734,
'inc': -42.52872729473035,
'n': 4,
'r': 3.9916088992115832,
'k': 357.52162626162925,
'alpha95': 4.865886096375297,
'csd': 4.283846101842065}
pmagpy.pmag.fix_directories(input_dir_path, output_dir_path)[source]#

Take arguments input/output directories and fixes them. If no input_directory, default to output_dir_path for both. Then return realpath for both values.

Parameters:
  • input_dir_path (str)

  • output_dir_path (str)

Return type:

input_dir_path, output_dir_path

pmagpy.pmag.flip(di_block, combine=False)[source]#

Determines ‘normal’ direction along the principle eigenvector, then flips the reverse mode to the antipode.

Parameters:
  • di_block (nested list of directions)

  • combine (whether to return directions as one di_block (default is False))

Returns:

  • D1 (normal mode)

  • D2 (flipped reverse mode as two DI blocks)

  • If combine=True one combined D1 + D2 di_block will be returned

pmagpy.pmag.form_Ghat(X, Mhat)[source]#

Form the Ghat matrix based on a collection of directions X and the Mhat matrix according to Equation 5 of Heslop et al., 2023

Parameters:
  • X (ndarray) – Cartesian coordinates of directions

  • Mhat (ndarray) – Mhat matrix for mean direction.

Returns:

Ghat matrix according to equation 5 of Heslop et al., 2023.

Return type:

ndarray

pmagpy.pmag.form_Mhat(mhat)[source]#

Calculate the Mhat matrix based on data set according to Equation 4 of Heslop et al., 2023.

Parameters:

mhat (ndarray) – Cartesian coordinates of estimated sample mean direction

Returns:

Mhat matrix according to the equation 4 of Heslop et al., 2023.

Return type:

ndarray

Raises:

ValueError – If the data sets have incompatible shapes.

pmagpy.pmag.form_Q(a, b)[source]#

Creates the rotation matrix Q so that Qb = a (according to equations (9) and (10)Heslop et al., 2023)

Parameters:
  • a (ndarray) – Destination direction (unit vector).

  • b (ndarray) – Starting direction (unit vector).

Returns:

Rotation matrix Q.

Return type:

ndarray

pmagpy.pmag.fshdev(k, random_seed=None)[source]#

Generate a random draw from a Fisher distribution with mean declination of 0 and inclination of 90 with a specified kappa.

Parameters:
  • k (single number or an array of values) – kappa (precision parameter) of the distribution

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

dec, inc – if k is an array, dec, inc are returned as arrays, otherwise, single values

Return type:

declination and inclination of random Fisher distribution draw

Examples

>>> pmag.fshdev(8)
(334.3434290469283, 61.06963783415771)
pmagpy.pmag.gaussdev(mean, sigma, N=1, random_seed=None)[source]#

Generate random samples drawn from a Gaussian (normal) distribution.

This function samples from a normal distribution with a specified mean and standard deviation, returning a NumPy array of length N.

Parameters:
  • mean (float) – Mean (center) of the normal distribution.

  • sigma (float) – Standard deviation of the normal distribution.

  • N (int, optional) – Number of random samples to generate. Defaults to 1.

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

NumPy array of length N containing random samples drawn from the specified normal distribution. If N=1, the returned array has shape (1,).

Return type:

ndarray

Notes

This function is a thin convenience wrapper around numpy.random.normal. Its primary purpose is to provide a default of N=1 and to ensure that the return value is always a NumPy array, even when generating a single sample. Pass an integer random_seed for reproducible results.

Examples

Generate six samples from a normal distribution with mean 5.5 and standard deviation 1.2:

>>> pmag.gaussdev(5.5, 1.2, 6, random_seed=42)
array([6.096056983613479, 5.334082838594578, 6.277226245720831,
    7.327635827689631, 5.219015950331997, 5.219035651660984])

Generate a single sample:

>>> pmag.gaussdev(5.5, 1.2, 1, random_seed=42)
array([6.096056983613479])
pmagpy.pmag.gausspars(data)[source]#

Compute the mean and standard deviation of a one-dimensional array of numerical data.

This function calculates the arithmetic mean and the standard deviation (using N - 1 in the denominator) for a single series of observations.

Parameters:

data (array_like) – One-dimensional list or array of numerical data.

Returns:

Mean and standard deviation of the input data. The standard deviation is calculated with N - 1 degrees of freedom.

Return type:

tuple of (float, float)

Notes

  • If the input array is empty, returns a tuple of two empty strings.

  • If the array contains a single observation, returns the observation as the mean and 0 as the standard deviation.

  • The standard deviation is computed using the ddof parameter in NumPy, which stands for delta degrees of freedom. The divisor in the calculation is N - ddof, where N is the number of observations. Here, ddof=1 is used so that the result is the sample standard deviation, the conventional choice when the data represent a sample from a larger population.

Examples

>>> data = np.array([54.15, 49.08, 50.62, 49.44, 49.64])
>>> mean, stdev = pmag.gausspars(data)
>>> print("Mean:", mean)
>>> print("Standard deviation:", stdev)
Mean: 50.586
Standard deviation: 2.072409225997607
pmagpy.pmag.get_EOL(file)[source]#

Find EOL of input file (whether mac,PC or unix format)

pmagpy.pmag.get_Sb(data)[source]#

Returns vgp scatter for a data set.

Parameters:

data (data set as a list or a pandas dataframe)

Return type:

float value of the vgp scatter

pmagpy.pmag.get_age(Rec, sitekey, keybase, Ages, DefaultAge)[source]#

Finds the age record for a given site.

pmagpy.pmag.get_azpl(cdec, cinc, gdec, ginc)[source]#

Recover the sample-orientation azimuth and plunge (az, pl) such that pmag.dogeo(cdec, cinc, az, pl) yields (gdec, ginc). This is the inverse of pmag.dogeo.

Parameters:
  • cdec (specimen declination)

  • cinc (specimen inclination)

  • gdec (geographic declination)

  • ginc (geographic inclination)

Returns:

az, pl

Return type:

tuple of azimuth (degrees, 0-360) and plunge (degrees).

Notes

The forward map (az, pl) -> (gdec, ginc) for a fixed specimen direction is generally 2-to-1: two distinct (az, pl) pairs produce the same geographic direction. To match the previous function’s convention (and the conventional drill range), the lower of the two valid plunges is returned. When the specimen direction lies along the +/- y axis the plunge is undetermined; this function returns 0 in that case.

Examples

>>> pmag.get_azpl(85, 110, 80.2, 112.3)
(324.08509406620256, -12.050207555689255)
pmagpy.pmag.get_dictitem(In, k, v, flag, float_to_int=False)[source]#

Returns a list of dictionaries from list In with key (k) = value (v) .

CASE INSENSITIVE # allowed keywords:

requires that the value of k in the dictionaries contained in In be castable to string and requires that v be castable to a string if flag is T,F, has or not and requires they be castable to float if flag is eval, min, or max. float_to_int goes through the relvant values in In and truncates them, (like “0.0” to “0”) for evaluation, default is False

Parameters:
  • In (list of dictionaries)

  • k (key to test)

  • v (key value to test)

  • flag ([T,F,has, or not])

  • int (float_to)

Return type:

List of dictionaries that meet conditions

Examples

>>> In=[{'specimen':'abc01b01','dec':'10.3','inc':'43','int':'5.2e-6'},
     {'specimen':'abc01b02','dec':'12.3','inc':'42','int':'4.9e-6'}]
>>> k = 'specimen'
>>> v = 'abc01b02'
>>> flag='T'
>>> get_dictitem(In,k,v,flag)
[{'specimen': 'abc01b02', 'dec': '12.3', 'inc': '42', 'int': '4.9e-6'}]
pmagpy.pmag.get_dictkey(In, k, dtype)[source]#

Returns list of given key (k) from input list of dictionaries (In) in data typed dtype.

Parameters:
  • In (list of dictionaries to work on)

  • k (key to return)

  • dtype (str) – “” : returns string value “f” : returns float “int” : returns integer

Returns:

Out

Return type:

List of values of the key specified to return

Examples

>>> In=[{'specimen':'abc01b01','dec':'10.3','inc':'43','int':'5.2e-6'},
     {'specimen':'abc01b02','dec':'12.3','inc':'42','int':'4.9e-6'}]
>>> k = 'specimen'
>>> dtype = ''
>>> get_dictkey(In,k,dtype)
['abc01b01', 'abc01b02']
pmagpy.pmag.get_named_arg(name, default_val=None, reqd=False)[source]#

Extract the value after a command-line flag such as ‘-f’ and return it. If the command-line flag is missing, return default_val. If reqd == True and the command-line flag is missing, throw an error.

Parameters:
  • name (str) – command line flag, e.g. “-f”

  • default_val – value to use if command line flag is missing, e.g. “measurements.txt” default is None

  • reqd (bool) – throw error if reqd==True and command line flag is missing. if reqd == True, default_val will be ignored. default is False.

Return type:

Desired value from sys.argv if available, otherwise default_val.

pmagpy.pmag.get_orient(samp_data, er_sample_name, **kwargs)[source]#

Returns orientation and orientation method of input sample (er_sample_name).

Parameters:
  • samp_data (PmagPy list of dicts or pandas DataFrame)

  • er_sample_name (string for the sample name)

Return type:

Orientation data and corresponding orientation method of specified sample (er_sample_name).

pmagpy.pmag.get_plate_data(plate)[source]#

Returns the pole list for a given plate

Parameters:

plate (string (options: AF, ANT, AU, EU, GL, IN, NA, SA))

Returns:

apwp – 0.0 90.00 0.00 1.0 88.38 182.20 2.0 86.76 182.20 …

Return type:

string with format

pmagpy.pmag.get_samp_con()[source]#

Get sample naming convention.

pmagpy.pmag.get_sb_df(df, mm97=False)[source]#

Calculates Sf for a dataframe with VGP Lat., and optional Fisher’s k, site latitude and N information can be used to correct for within site scatter (McElhinny & McFadden, 1997)

Parameters:
  • df (Pandas Dataframe with columns) –

    REQUIRED:

    vgp_lat : VGP latitude

    ONLY REQUIRED for MM97 correction:

    dir_k : Fisher kappa estimate dir_n : number of specimens (samples) per site lat : latitude of the site

  • mm97 (if True, will do the correction for within site scatter)

Returns:

Sf

Return type:

float value for the Sf

pmagpy.pmag.get_specs(data)[source]#

Takes a magic format file and returns a list of unique specimen names.

pmagpy.pmag.get_test_WD()[source]#

Find proper working directory to run tests. With developer install, tests should be run from PmagPy directory. Otherwise, assume pip install, and run tests from sys.prefix, where data_files are installed by setuptools.

pmagpy.pmag.get_tilt(dec_geo, inc_geo, dec_tilt, inc_tilt)[source]#

Return the bedding orientation (dip direction, dip) such that applying pmag.dotilt to (dec_geo, inc_geo) with that bedding yields (dec_tilt, inc_tilt). This is the inverse of pmag.dotilt.

Parameters:
  • dec_geo (declination in geographic coordinates)

  • inc_geo (inclination in geographic coordinates)

  • dec_tilt (declination in tilt-corrected coordinates)

  • inc_tilt (inclination in tilt-corrected coordinates)

Returns:

DipDir, Dip – (degrees, 0-90). When the geographic and tilt-corrected directions are identical (no tilt), bedding is undefined and the function returns (0.0, 0.0).

Return type:

tuple of dip direction (degrees, 0-360) and dip

Examples

>>> pmag.get_tilt(85,110,80.2,112.3)
(223.67057238530975, 2.95374920443805)
pmagpy.pmag.get_ts(ts)[source]#

returns GPTS timescales. options are: ck95, gts04, gts12, gts20 returns timescales and Chron labels

pmagpy.pmag.get_unf(N=100, random_seed=None)[source]#

Generates N uniformly distributed directions using the way described in Fisher et al. (1987).

Parameters:
  • N (number of directions, default is 100)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Return type:

array of nested dec, inc pairs

Examples

>>> pmag.get_unf(5)
array([[ 62.916547703466684, -30.751721919151798],
   [145.94851610484855 ,  76.45636268514875 ],
   [312.61910867788174 , -67.24338629811932 ],
   [ 61.71574344812653 ,  -4.005335509042522],
   [ 15.867001505749716,  -1.404412703673322]])
pmagpy.pmag.get_version()[source]#

Determines the version of PmagPy installed on your machine.

Returns:

version

Return type:

string of pmagpy version, such as “pmagpy-3.8.8”

Examples

>>> pmag.get_version()
'pmagpy-4.2.106'
pmagpy.pmag.getkeys(table)[source]#

Customize by commenting out unwanted keys.

pmagpy.pmag.getmeths(method_type)[source]#

Returns MagIC method codes available for a given type.

Parameters:

method_type (str)

Returns:

meths

Return type:

specified methods codes for the given type

pmagpy.pmag.getvec(gh, lat, lon)[source]#

Evaluates the vector at a given latitude and longitude for a specified set of coefficients.

Parameters:
  • gh (a list of gauss coefficients)

  • lat (latitude of location)

  • long (longitude of location)

Returns:

vec

Return type:

direction as an array [dec, inc, intensity]

Examples

>>> gh = pmag.doigrf(30,70,10,2022,coeffs=True)
>>> pmag.getvec(gh, 30,70)
array([2.007319473143944e+00, 4.740186709049829e+01,
   4.831229434010185e+04])
pmagpy.pmag.gha(julian_day, f)[source]#

Returns greenwich hour angle.

Parameters:
  • julian_day (int, julian day)

  • f (int) – fraction of the day in Universal Time, (hrs + (min/60))/24

Returns:

  • H (int, hour)

  • delta (int, angle)

Examples

>>> julianday = pmag.julian(10,20,2000)
>>> pmag.gha(julianday, 33)
(183.440612472039, -20.255315389871825)
>>> pmag.gha(2451838, 33)
(183.440612472039, -20.255315389871825)
pmagpy.pmag.grade(PmagRec, ACCEPT, type, data_model=2.5)[source]#

Finds the ‘grade’ (pass/fail; A/F) of a record (specimen,sample,site) given the acceptance criteria

pmagpy.pmag.import_cartopy()[source]#

Try to import cartopy and print out a help message if it is not installed

Returns:

  • has_cartopy (bool)

  • cartopy (cartopy package if available else None)

pmagpy.pmag.initialize_acceptance_criteria(**kwargs)[source]#

Initializes a dictionary of acceptance criteria with default null values.

This function is used by thellier_gui and demag_gui to set up the criteria for accepting or rejecting paleomagnetic data at different levels (specimen, sample, site, etc.).

Returns:

A dictionary where each key is a specific criterion name (e.g., ‘specimen_n’). The value for each key is another dictionary containing the metadata for that criterion, with the following structure:

’category’str

The category of the criterion (e.g., ‘DE-SPEC’, ‘DE-SAMP’).

’criterion_name’str

The MagIC name for the criterion.

’value’int, float, or str

The threshold value for the criterion. - Numerical value for standard criteria. - String for a flag. - 1 for True, 0 for False for boolean criteria. - -999 indicates Not Applicable (N/A).

’threshold_type’str or list

Specifies how the threshold is applied. - ‘low’: A lower bound (the measured value must be greater). - ‘high’: An upper bound (the measured value must be less). - list of str (e.g., [‘n’, ‘r’]): A list of acceptable flag values. - ‘bool’: A boolean flag.

’decimal_points’int

The number of decimal points for rounding when displaying the value. - A value of -999 formats floats with an exponent and 3 decimal places.

Return type:

dict

pmagpy.pmag.int_pars(x, y, vds, **kwargs)[source]#

This function calculates York regression and paleointensity parameters (with Tauxe Fvds), building a dictionary which is used in PintPars.

Parameters:
  • x (x values of TRM and NRM points on the Arai plot)

  • y (y values of TRM and NRM points on the Arai plot)

  • vds (vector difference sum (from pmag.dovds))

  • **kwargs

Returns:

  • pars (dctionary of regression and paleointensity parameters)

  • errcode (bool) – 0 if no errors, 1 if too few points

pmagpy.pmag.interval_overlap(interval_a, interval_b)[source]#

Determine the extent of overlap between two ranges of numbers

Parameters:
  • interval_a (a list of [min, max])

  • interval_b (a list of [min, max])

Returns:

overlap

Return type:

the amount of overlap between interval_a and interval_b

pmagpy.pmag.julian(mon, day, year)[source]#

Returns julian day.

Parameters:
  • mon (int, month)

  • day (int, day)

  • year (int, year)

Returns:

julian_day

Return type:

Julian day as a flt

Examples

>>> pmag.julian(10,20,2000)
2451838
pmagpy.pmag.kentdev(kappa, beta, n=1000, random_seed=None)[source]#

Generate a random draw from a Kent distribution with mean declination of 0 and inclination of 90, elongated along -90 to 90 longitude with a specified kappa and beta.

Parameters:
  • kappa (kappa (precision parameter) of the distribution)

  • beta (beta ellipticity of the contours of equal probability of the distribution)

  • n (number of samples to redraw)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

dec, inc

Return type:

declination and inclination of random Kent distribution draw

Examples

>>> pmag.kentdev(30,0.2,3)
([249.6338265814872, 243.60784772662754, 273.37935292238103],
 [74.05222965175194, 80.43784483273899, 82.34979130960458])
pmagpy.pmag.linreg(x, y)[source]#

Does a linear regression

pmagpy.pmag.lowes(data)[source]#

Gets Lowe’s power spectrum from gauss coefficients.

Parameters:

data (nested list of [[l,m,g,h],...] as from pmag.unpack())

Returns:

  • Ls (list of degrees l)

  • Rs (power at degree l)

pmagpy.pmag.magic_help(keyhelp)[source]#

Returns a help message for a given magic key.

Parameters:

keyhelp (str) – key name that the user seeks more information about

Returns:

Information about the input key

Return type:

str

Examples

>>> pmag.magic_help('location_url')
'Website URL for the location explicitly'
pmagpy.pmag.magic_read(infile, data=None, return_keys=False, verbose=False)[source]#

Reads a Magic template file, returns data in a list of dictionaries.

Parameters:
  • Required –

    infilethe MagIC formatted tab delimited data file

    first line contains ‘tab’ in the first column and the data file type in the second (e.g., measurements, specimen, sample, etc.)

  • Optional – data : data read in with, e.g., file.readlines()

Return type:

list of dictionaries, file type

pmagpy.pmag.magic_read_dict(path, data=None, sort_by_this_name=None, return_keys=False)[source]#

Read a magic-formatted tab-delimited file and returns a dictionary of dictionaries, with this format:

{‘Z35.5a’: {‘specimen_weight’: ‘1.000e-03’, ‘er_citation_names’: ‘This study’, ‘specimen_volume’: ‘’, ‘er_location_name’: ‘’, ‘er_site_name’: ‘Z35.’, ‘er_sample_name’: ‘Z35.5’, ‘specimen_class’: ‘’, ‘er_specimen_name’: ‘Z35.5a’, ‘specimen_lithology’: ‘’, ‘specimen_type’: ‘’}, ….} return data, file_type, and keys (if return_keys is true)

pmagpy.pmag.magic_write(ofile, Recs, file_type, dataframe=False, append=False)[source]#

Writes out a magic format list of dictionaries to ofile.

Parameters:
  • ofile (path to output file)

  • Recs (list of dictionaries in MagIC format OR pandas dataframe)

  • file_type (MagIC table type (e.g., specimens))

  • dataframe (boolean) –

    if True, Recs is a pandas dataframe which must be converted

    to a list of dictionaries

  • append (boolean) – if True, file will be appended to named file

Returns:

  • [True,False] (True if successful)

  • ofile (same as input)

  • Effects

  • ——-

  • writes a MagIC formatted file from Recs

pmagpy.pmag.magic_write_old(ofile, Recs, file_type)[source]#

Writes out a magic format list of dictionaries to ofile.

Parameters:
  • ofile (path to output file)

  • Recs (writes a MagIC formatted file from)

  • file_type (MagIC table type (e.g., specimens))

  • Effects

  • -------

  • Recs

pmagpy.pmag.magnetic_lat(inc)[source]#

Calculates the magnetic latitude from inclination.

Parameters:

inc (single float or array) – inclination value(s)

Returns:

paleo_lat – magnetic latitude from the given inclination(s)

Return type:

single float or array

Examples

>>> pmag.magnetic_lat(35)
19.29534273533122
>>> pmag.magnetic_lat([35,60,20])
array([19.29534273533122 , 40.8933946491309  , 10.314104815618196])
pmagpy.pmag.magsyn(gh, sv, b, date, itype, alt, colat, elong)[source]#

Computes x, y, z, and f for a given date and position, from the spherical harmonic coefficients of the International Geomagnetic Reference Field (IGRF). From Malin and Barraclough (1981), Computers and Geosciences, V.7, 401-405.

Parameters:
  • gh (main field values for date (calc. in igrf subroutine))

  • sv (secular variation coefficients (calc. in igrf subroutine))

  • b (date of dgrf (or igrf) field prior to required date)

  • date (Required date in years and decimals of a year (A.D.))

  • itype (1, if geodetic coordinates are used, 2 if geocentric)

  • alt (itype = 1 : height above mean sea level in km) – itype = 2 : radial distance from the center of the earth

  • colat (colatitude in degrees (0 to 180))

  • elong (east longitude in degrees (0 to 360))

Returns:

  • x (north component of the magnetic force in nT)

  • y (east component of the magnetic force in nT)

  • z (downward component of the magnetic force in nT)

  • f (total magnetic force in nT)

  • note (the coordinate system for x,y, and z is the same as that specified by itype)

pmagpy.pmag.makelist(List)[source]#

Makes a colon delimited list from List.

Parameters:

List (any list of strings or numbers)

Return type:

colon delimited list

Examples

>>> pmag.makelist(["mT","T","Am"])
'mT:T:Am'
pmagpy.pmag.measurements_methods(meas_data, noave)[source]#

Get list of unique specs

pmagpy.pmag.measurements_methods3(meas_data, noave, savelast=False)[source]#

Add necessary method codes, experiment names, sequence, etc.

pmagpy.pmag.merge_recs_headers(recs)[source]#

Take a list of recs [rec1,rec2,rec3….], each rec is a dictionary. make sure that all recs have the same headers.

pmagpy.pmag.mktk03(terms, G2, G3, G1=-18000.0, verbose=False, random_seed=None)[source]#

Generates a list of gauss coefficients drawn from the TK03 distribution.

Parameters:
  • terms (int) – number of terms to return

  • G2 (int) – ratio of axial quadrupole term to dipole term

  • G3 (int) – ratio of axial octupole term to dipole term

  • G1 (float) – value of the axial dipole, default is -18e3 (in nT)

  • verbose (default is False)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

gh – list of l,m,g,h field model generated by TK03

Return type:

list

pmagpy.pmag.open_file(infile, verbose=True)[source]#

Open file and return a list of the file’s lines. Try to use utf-8 encoding, and if that fails use Latin-1.

Parameters:

infile (str) – full path to file

Returns:

data – all lines in the file

Return type:

list

pmagpy.pmag.orient(mag_azimuth, field_dip, or_con)[source]#

Uses specified orientation convention to convert user supplied orientations to laboratory azimuth and plunge.

Parameters:
  • mag_azimuth (float) – orientation of the field orientation arrow with respect to north

  • field_dip (float) –

    dip (or hade) or field arrow.

    if hade, with respect to vertical down if inclination, with respect to horizontal (positive down)

  • or_con (int) – orientation convention : int

  • database (Samples are oriented in the field with a "field arrow" and measured in the laboratory with a "lab arrow". The lab arrow is the positive X direction of the right handed coordinate system of the specimen measurements. The lab and field arrows may not be the same. In the MagIC) –

    [1] Standard Pomeroy convention of azimuth and hade (degrees from vertical down)

    of the drill direction (field arrow). lab arrow azimuth= sample_azimuth = mag_azimuth; lab arrow dip = sample_dip =-field_dip. i.e. the lab arrow dip is minus the hade.

    [2] Field arrow is the strike of the plane orthogonal to the drill direction,

    Field dip is the hade of the drill direction. Lab arrow azimuth = mag_azimuth-90 Lab arrow dip = -field_dip

    [3] Lab arrow is the same as the drill direction;

    hade was measured in the field. Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip

    [4] lab azimuth and dip are same as mag_azimuth, field_dip : use this for unoriented samples too [5] Same as AZDIP convention explained below -

    azimuth and inclination of the drill direction are mag_azimuth and field_dip; lab arrow is as in [1] above. lab azimuth is same as mag_azimuth,lab arrow dip=field_dip-90

    [6] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = 90-field_dip

  • angles (we require the orientation (azimuth and plunge) of the X direction of the measurements (lab arrow). Here are some popular conventions that convert the field arrow azimuth (mag_azimuth in the orient.txt file) and dip (field_dip in orient.txt) to the azimuth and plunge of the laboratory arrow (sample_azimuth and sample_dip in er_samples.txt). The two) –

    [1] Standard Pomeroy convention of azimuth and hade (degrees from vertical down)

    of the drill direction (field arrow). lab arrow azimuth= sample_azimuth = mag_azimuth; lab arrow dip = sample_dip =-field_dip. i.e. the lab arrow dip is minus the hade.

    [2] Field arrow is the strike of the plane orthogonal to the drill direction,

    Field dip is the hade of the drill direction. Lab arrow azimuth = mag_azimuth-90 Lab arrow dip = -field_dip

    [3] Lab arrow is the same as the drill direction;

    hade was measured in the field. Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip

    [4] lab azimuth and dip are same as mag_azimuth, field_dip : use this for unoriented samples too [5] Same as AZDIP convention explained below -

    azimuth and inclination of the drill direction are mag_azimuth and field_dip; lab arrow is as in [1] above. lab azimuth is same as mag_azimuth,lab arrow dip=field_dip-90

    [6] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = 90-field_dip

  • below. (mag_azimuth and field_dip are explained) –

    [1] Standard Pomeroy convention of azimuth and hade (degrees from vertical down)

    of the drill direction (field arrow). lab arrow azimuth= sample_azimuth = mag_azimuth; lab arrow dip = sample_dip =-field_dip. i.e. the lab arrow dip is minus the hade.

    [2] Field arrow is the strike of the plane orthogonal to the drill direction,

    Field dip is the hade of the drill direction. Lab arrow azimuth = mag_azimuth-90 Lab arrow dip = -field_dip

    [3] Lab arrow is the same as the drill direction;

    hade was measured in the field. Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip

    [4] lab azimuth and dip are same as mag_azimuth, field_dip : use this for unoriented samples too [5] Same as AZDIP convention explained below -

    azimuth and inclination of the drill direction are mag_azimuth and field_dip; lab arrow is as in [1] above. lab azimuth is same as mag_azimuth,lab arrow dip=field_dip-90

    [6] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = 90-field_dip

Return type:

azimuth and dip of lab arrow

pmagpy.pmag.parse_site(sample, convention, Z)[source]#

Parse the site name from the sample name using the specified convention

pmagpy.pmag.pinc(lat)[source]#

Calculate paleoinclination from latitude using dipole formula: tan(I) = 2tan(lat).

Parameters:

lat (either a single value or an array of latitudes)

Return type:

array of inclinations

Examples

>>> lats = [45,40,60,80, -30,55]
>>> np.round(pmag.pinc(lats),1)
array([ 63.4,  59.2,  73.9,  85. , -49.1,  70.7])
pmagpy.pmag.plat(inc)[source]#

Calculate paleolatitude from inclination using dipole formula: tan(I) = 2tan(lat).

Parameters:

inc (either a single value or an array of inclinations)

Return type:

array of latitudes

Examples

>>> incs = [63.4,59.2,73.9,85,-49.1,70.7]
>>> np.round(pmag.plat(incs))
array([ 45.,  40.,  60.,  80., -30.,  55.])
pmagpy.pmag.process_data_for_mean(data, direction_type_key)[source]#

Takes a list of dicts with dec and inc as well as direction_type if possible or method_codes and sorts the data into lines and planes and process it for fisher means

Parameters:
  • data (list of dicts with dec inc and some manner of PCA type info)

  • direction_type_key (key that indicates the direction type variable in the dictionaries of data)

Returns:

tuple with values – number of line list of lists with [EL,EM,EN] of all planes number of planes list of sum of the cartezian components of all lines

Return type:

list of lists with [dec, inc, 1.] for all lines

pmagpy.pmag.pseudo(DIs, random_seed=None)[source]#

Draw a bootstrap sample of directions returning as many bootstrapped samples as in the input directions.

Parameters:
  • DIs (nested list of dec, inc lists (known as a di_block))

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

  • Bootstrap_directions (nested list of dec, inc lists that have been)

  • bootstrapped resampled

Examples

>>> di_block = ([[-45,150],
 [-40,150],
 [-38,145]])
>>> pmag.pseudo(di_block,10)
array([[-40, 150],
   [-40, 150],
   [-45, 150]])
pmagpy.pmag.pseudosample(x, random_seed=None)[source]#

Draw a bootstrap sample of x.

Parameters:
  • x (list) – Data to bootstrap resample.

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

BXs – Bootstrap sample of x (same length as x).

Return type:

list

pmagpy.pmag.pt_rot(EP, Lats, Lons)[source]#

Rotates points on a globe by an Euler pole rotation using method of Cox and Hart 1986, box 7-3.

Parameters:
  • EP (Euler pole list [lat,lon,angle] specifying the location of the pole;)

  • pole (the angle is for a counterclockwise rotation about the)

  • Lats (list of latitudes of points to be rotated)

  • Lons (list of longitudes of points to be rotated)

Returns:

  • RLats (list of rotated latitudes)

  • RLons (list of rotated longitudes)

pmagpy.pmag.putout(ofile, keylist, Rec)[source]#

Writes out a magic format record to ofile.

pmagpy.pmag.read_criteria_from_file(path, acceptance_criteria, **kwargs)[source]#

Read accceptance criteria from magic criteria file # old format: multiple lines. pmag_criteria_code defines the type of criteria

to deal with old format this function reads all the lines and ignore empty cells. i.e., the program assumes that in each column there is only one value (in one of the lines)

special case in the old format:

specimen_dang has a value and pmag_criteria_code is IE-specimen. The program assumes that the user means specimen_int_dang

# New format for thellier_gui and demag_gui: one long line. pmag_criteria_code=ACCEPT

path is the full path to the criteria file

the function takes exiting acceptance_criteria and updtate it with criteria from file

output: acceptance_criteria={} acceptance_criteria[MagIC Variable Names]={} acceptance_criteria[MagIC Variable Names][‘value’]:

a number for acceptance criteria value -999 for N/A 1/0 for True/False or Good/Bad

acceptance_criteria[MagIC Variable Names][‘threshold_type’]:

“low”: lower cutoff value i.e. crit>=value pass criteria “high”: high cutoff value i.e. crit<=value pass criteria [string1,string2,….]: for flags

acceptance_criteria[MagIC Variable Names][‘decimal_points’]:number of decimal points in rounding

(this is used in displaying criteria in the dialog box)

pmagpy.pmag.resolve_file_name(fname, dir_path='.')[source]#

Parse file name information and output full path. Allows input as: fname == /path/to/file.txt or fname == file.txt, dir_path == /path/to Either way, returns /path/to/file.txt. Used in conversion scripts.

Parameters:
  • fname (str) – short filename or full path to file

  • dir_path (str) – directory, optional

Returns:

full_file – full path/to/file.txt

Return type:

str

pmagpy.pmag.s2a(s)[source]#

Convert 6 element “s” list to 3x3 a matrix (see Tauxe 1998).

Parameters:

s (six element list of floats)

Returns:

a

Return type:

3x3 matrix as an array

Examples

>>> pmag.s2a([1,2,3,4,5,6])
array([[1., 4., 6.],
   [4., 2., 5.],
   [6., 5., 3.]], dtype=float32)
pmagpy.pmag.s_boot(Ss, ipar=0, nb=1000, random_seed=None)[source]#

Returns bootstrap parameters for S data.

Parameters:
  • Ss (nested array of [[x11 x22 x33 x12 x23 x13],....] data)

  • ipar (if True, do a parametric bootstrap)

  • nb (number of bootstraps)

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible random number generation (default is None).

Returns:

  • Tmean (average eigenvalues)

  • Vmean (average eigvectors)

  • Taus (bootstrapped eigenvalues)

  • Vs (bootstrapped eigenvectors)

Examples

>>> Ss = [[0.33586472,0.32757074,0.33656454,0.0056526,0.00449771,-0.00036542], [0.33815295,0.32601482,0.33583224,0.00754076,0.00405271,-0.0001627],
    [0.33806428,0.32925552,0.33268023,0.00480824,-0.00168595,0.0009308], [0.33939844,0.32750368,0.33309788,0.00763409,0.00264978,0.00070303],
    [0.3348785,0.32816416,0.33695734,0.00574405,0.00278172,-0.00073475], [0.33485019,0.32948497,0.33566481,0.00597801,0.00426423,-0.00040056]]
>>> pmag.s_boot(Ss,0,2)
([0.34040287, 0.3353659, 0.32423124],
 [[29.594002551414974, 14.457521581993113],
  [166.31028417625646, 70.4972100801602],
  [296.2343306258123, 12.805665338949966]],
 [[0.34002233, 0.33413905, 0.32583863], [0.34043044, 0.33551994, 0.32404962]],
 [[[26.298051965057486, 5.235004519419732],
   [183.15464080261913, 84.30971842978398],
   [296.0941733228108, 2.224044816930646]],
  [[28.798353815000212, 14.686330248560294],
   [166.21187481069492, 70.40546729047502],
   [295.4174263407004, 12.681162985818712]]])
pmagpy.pmag.s_l(l, alpha=27.7)[source]#

Get sigma as a function of degree l from Constable and Parker (1988)

Parameters:
  • l (int) – degree of spherical harmonic expansion

  • alpha (float) – alpha parameter for CP88 model, default is 27.7 in CP88

Return type:

sigma corresponding to degree l

Examples

>>> pmag.s_l(4)
0.36967732888223936
pmagpy.pmag.sbar(Ss)[source]#

Calculate average s,sigma from a list of S’s.

Parameters:

Ss (nested list of lists) – each list is a six element tensors

Returns:

  • nf (degrees of freedom)

  • sigma (sigma of the list)

  • avs (the original list)

Examples

>>> Ss = [[0.33586472,0.32757074,0.33656454,0.0056526,0.00449771,-0.00036542], [0.33815295,0.32601482,0.33583224,0.00754076,0.00405271,-0.0001627],
    [0.33806428,0.32925552,0.33268023,0.00480824,-0.00168595,0.0009308], [0.33939844,0.32750368,0.33309788,0.00763409,0.00264978,0.00070303],
    [0.3348785,0.32816416,0.33695734,0.00574405,0.00278172,-0.00073475], [0.33485019,0.32948497,0.33566481,0.00597801,0.00426423,-0.00040056]]
>>> pmag.sbar(Ss)
(30,
 0.0018030794236146297,
 [0.33686818,
  0.3279989816666667,
  0.33513284,
  0.0062262916666666656,
  0.002760033333333333,
  -4.933333333333345e-06])
pmagpy.pmag.sbootpars(Taus, Vs)[source]#

Get bootstrap parameters for s data from bootstrap eigenvalues and eigenvectors.

Parameters:
  • Taus (nested list of eigenvalues)

  • Vs (nested list of eigenvectors)

Returns:

bpars

Return type:

dictionary of bootstrap parameters for the bootstrap eigenvalues and eigenvectors.

Examples

>>> Taus = [[0.89332515, 0.2421235, -0.13544868], [1.2330734, 0.033398163, -0.26647156]]
>>> Vs = [[[16.71852040881784, 22.059363998317398],
       [122.30845200565045, 33.55240424468586],
       [259.90057243022835, 48.06963167162283]],
      [[36.31805058172574, 15.477280574403938],
       [183.99811452360234, 71.85809815162672],
       [303.738439079619, 9.23224775163199]]]
>>> pmag.sbootpars(Taus, Vs)
{'t1_sigma': 0.24023829147126252,
 't2_sigma': 0.1475911011981474,
 't3_sigma': 0.09264716693859128,
 'v1_dec': 26.711662224665808,
 'v1_inc': 19.026277799227568,
 'v1_zeta': 24.690888880899667,
 'v1_eta': 1.249303736510881e-14,
 'v1_zeta_dec': 290.06398627901706,
 'v1_zeta_inc': 18.55700265945684,
 'v1_eta_dec': 159.07273109103403,
 'v1_eta_inc': 62.89733254726475,
 'v2_dec': 137.92012533786792,
 'v2_inc': 55.87313967394276,
 'v2_zeta': 1.250107785929978e-14,
 'v2_eta': 75.07258147484707,
 'v2_zeta_dec': 20.268001361016218,
 'v2_zeta_inc': 17.460349183865556,
 'v2_eta_dec': 280.5183204912709,
 'v2_eta_inc': 28.297554981599696,
 'v3_dec': 286.25118089868266,
 'v3_inc': 30.42076774734727,
 'v3_zeta': 2.4071834979709793e-14,
 'v3_eta': 85.83440673704222,
 'v3_zeta_dec': 40.186767906504166,
 'v3_zeta_inc': 34.642182695768,
 'v3_eta_dec': 166.24042846510952,
 'v3_eta_inc': 40.4243181226488}
pmagpy.pmag.scalc_vgp_df(vgp_df, anti=0, rev=0, cutoff=180.0, kappa=0, n=0, spin=0, v=0, boot=False, mm97=False, nb=1000, verbose=True, random_seed=None)[source]#

Calculates Sf for a dataframe with VGP Lat., and optional Fisher’s k, site latitude and N information can be used to correct for within site scatter (McElhinny & McFadden, 1997)

Parameters:
  • vgp_df (Pandas Dataframe with columns) – REQUIRED: vgp_lat : VGP latitude ONLY REQUIRED for MM97 correction: dir_k : Fisher kappa estimate dir_n_samples : number of samples per site lat : latitude of the site mm97 : if True, will do the correction for within site scatter OPTIONAL: boot : if True. do bootstrap nb : number of bootstraps, default is 1000

  • anti (Boolean) – if True, take antipodes of reverse poles

  • spin (Boolean) – if True, transform data to spin axis

  • rev (Boolean) – if True, take only reverse poles

  • v (Boolean) – if True, filter data with Vandamme (1994) cutoff

  • boot (Boolean) – if True, use bootstrap for confidence 95% interval

  • mm97 (Boolean) – if True, use McFadden McElhinny 1997 correction for S

  • nb (int) – number of bootstrapped pseudosamples for confidence estimate

  • verbose (Boolean) – if True, print messages

  • random_seed (None, int, or numpy.random.Generator, optional) – Seed for reproducible bootstrap resampling (default None).

Returns:

  • N (number of VGPs used in calculation)

  • S_B (S value)

  • low (95% confidence lower bound [0 if boot=0])

  • high (95% confidence upper bound [0 if boot=0])

  • cutoff (cutoff used in calculation of S)

pmagpy.pmag.scoreit(pars, PmagSpecRec, accept, text, verbose)[source]#

This function produces a grade for a given set of data. Used in thellier_magic2.py and microwave_magic.py.

pmagpy.pmag.separate_directions(di_block)[source]#

Separates set of directions into two modes based on principal direction

Parameters:

di_block (block of nested dec,inc pairs)

Returns:

mode_1_block,mode_2_block

Return type:

two arrays of nested dec,inc pairs

pmagpy.pmag.set_priorities(SO_methods, ask)[source]#

Figure out which sample_azimuth to use, if multiple orientation methods

pmagpy.pmag.sort_diclist(undecorated, sort_on)[source]#

Sort a list of dictionaries by the value in each dictionary for the sorting key.

Parameters:
  • undecorated (list of dicts)

  • sort_on (str, numeric) – key that is present in all dicts to sort on

Return type:

Ordered list of dicts

Examples

>>> lst = [{'key1': 10, 'key2': 2}, {'key1': 1, 'key2': 20}]
>>> sort_diclist(lst, 'key1')
[{'key2': 20, 'key1': 1}, {'key2': 2, 'key1': 10}]
>>> sort_diclist(lst, 'key2')
pmagpy.pmag.sort_magic_data(magic_data, sort_name)[source]#

Sort magic_data by header.

Parameters:
  • magic_data (table from a MagIC upload (or downloaded) txt file)

  • sort_name (str) – name of header to sort by, (‘er_specimen_name’ for example)

Returns:

magic_data

Return type:

sorted table by indicated sort_name

pmagpy.pmag.sortarai(datablock, s, Zdiff, **kwargs)[source]#

Sorts data block in to first_Z, first_I, etc.

Parameters:
  • datablock (Pandas DataFrame with Thellier-Tellier type data)

  • s (specimen name)

  • Zdiff (if True, take difference in Z values instead of vector difference) – NB: this should always be False

  • **kwargs – version : data model. if not 3, assume data model = 2.5

Returns:

  • araiblock ([first_Z, first_I, ptrm_check,) – ptrm_tail, zptrm_check, GammaChecks]

  • field (lab field (in tesla))

pmagpy.pmag.sortmwarai(datablock, exp_type)[source]#

sorts microwave double heating data block in to first_Z, first_I, etc.

pmagpy.pmag.sortshaw(s, datablock)[source]#

Sorts data block in to ARM1,ARM2 NRM,TRM,ARM1,ARM2=[],[],[],[] stick first zero field stuff into first_Z

pmagpy.pmag.squish(incs, f)[source]#

Returns ‘flattened’ inclination, assuming factor, f and King (1955) formula: tan (I_o) = f tan (I_f)

Parameters:
  • incs (array of inclination (I_f) data to flatten)

  • f (flattening factor)

Returns:

I_o

Return type:

inclinations after flattening

pmagpy.pmag.tauV(T)[source]#

Gets the eigenvalues (tau) and eigenvectors (V) from 3x3 matrix T.

Parameters:

T (3x3 matrix)

Returns:

  • t (eigenvalues for the given matrix (T))

  • V (eigenvectors for the given matrix (T))

Examples

>>> T = [[2,4,6],
         [10,2,5],
         [1,7,8]]
>>> pmag.tauV(T)
([(1.2709559412652764+0j),
  (-0.13547797063263817+0.11627030078868397j),
  (-0.13547797063263817-0.11627030078868397j)],
 [array([0.473150982577391+0.j, 0.600336609447566+0.j,
     0.644766704353637+0.j]),
  array([-0.006695867252108+0.161305398937403j,
      0.801217123829199+0.j               ,
     -0.567608562961462-0.09903218351161j ]),
  array([-0.006695867252108-0.161305398937403j,
      0.801217123829199-0.j               ,
     -0.567608562961462+0.09903218351161j ])])
pmagpy.pmag.tcalc(nf, p)[source]#

T-table for nf degrees of freedom (95% confidence).

Parameters:
  • nf (degrees of freedom)

  • p (either 0.05 or 0.01)

Return type:

t value or 0 if given an invalid p value

Examples

>>> pmag.tcalc(8,0.05)
2.3646
>>> pmag.tcalc(8,0.07)
0
>>> pmag.tcalc(8,0.01)
3.4995
pmagpy.pmag.unpack(gh)[source]#

Unpacks gh list into l m g h type list.

Parameters:

gh (list of gauss coefficients (as returned by, e.g., doigrf))

Returns:

data

Return type:

nested list of [[l,m,g,h],…]

Examples

>>> gh = pmag.doigrf(30,70,10,2022,coeffs=True)
>>> pmag.unpack(gh)
[[1, 0, -29404.8, 0],
 [1, 1, -1450.9, 4652.5],
 [2, 0, -2499.6, 0],
 [2, 1, 2982.0, -2991.6],
 [2, 2, 1677.0, -734.6],
 [3, 0, 1363.2, 0],
 [3, 1, -2381.2, -82.1],
 [3, 2, 1236.2, 241.9],
 [3, 3, 525.7, -543.4], ...
pmagpy.pmag.unsquish(incs, f)[source]#

Restore (unsquish) inclinations using the King (1955) inclination-shallowing correction.

King (1955) described the relationship between the inclination of a specimen’s magnetization (\(I_o\), the observed inclination) and the inclination of the field in which the magnetization was acquired (\(I_f\)) as:

\[\tan(I_o) = f \, \tan(I_f)\]

where \(f\) is the flattening factor (\(0 < f \le 1\)). When \(f < 1\), the observed inclination is shallower than the original field inclination due to compaction-related flattening.

This function inverts King’s equation to estimate the original inclination from observed inclinations:

\[\tan(I_f) = \frac{\tan(I_o)}{f}\]
Parameters:
  • incs (array_like) – One-dimensional list or NumPy array of observed inclinations (\(I_o\)) in degrees, typically measured from remanent magnetization directions.

  • f (float) – Flattening factor (\(0 < f \le 1\)). Values less than 1 indicate inclination shallowing; smaller values correspond to stronger flattening.

Returns:

NumPy array of unsquished_incs (restored inclinations) in degrees with the same shape as incs.

Return type:

ndarray

Examples

Basic usage with a list of observed inclinations (degrees):

>>> incs = [63.4, 59.2, 73.9, 85.1, -49.1, 70.7]
>>> unsquished = pmag.unsquish(incs, 0.6)
>>> print(np.round(unsquished, 1))
[ 73.3  70.3  80.2  87.1 -62.5  78.1]

Loading inclinations from a data file where they are stored as the second column:

>>> directions = np.loadtxt('data_files/unsquish/unsquish_example.dat')
>>> incs = directions[:, 1]  # extract the inclination column
>>> unsquished = pmag.unsquish(incs, 0.61)
>>> print(np.round(unsquished[:5], 1))  # show first 5 results
[33.5 30.5 22.7 40.6 33.7]
pmagpy.pmag.vclose(L, V)[source]#

Calculates the closest vector.

pmagpy.pmag.vdm_b(vdm, lat)[source]#

Converts a virtual dipole moment (VDM) or a virtual axial dipole moment (VADM) to a local magnetic field value

Parameters:
  • vdm (V(A)DM in units of Am^2)

  • lat (latitude of site in degrees)

Returns:

B

Return type:

local magnetic field strength in tesla

Examples

>>> pmag.vdm_b(65, 20)
2.9215108300460446e-26
pmagpy.pmag.vector_mean(data)[source]#

Calculates the vector mean of a given set of vectors.

Parameters:

data (nested array of [dec,inc,intensity])

Returns:

  • dir (array of [dec, inc, 1])

  • R (resultant vector length)

Examples

>>> data=np.loadtxt('data_files/vector_mean/vector_mean_example.dat')
>>> Dir,R=pmag.vector_mean(data)
>>> data.shape[0],Dir[0],Dir[1],R
(100, 1.2702459152657795, 49.62123008281823, 2289431.9813831896)
>>> data = np.array([[16.0,    43.0, 21620.33],
       [30.5,    53.6, 12922.58],
        [6.9,    33.2, 15780.08],
      [352.5,    40.2, 33947.52],
      [354.2,    45.1, 19725.45]])
>>> pmag.vector_mean(data)
(array([ 3.875568482416763, 43.02570375878505 ,  1.]),
 102107.93048882612)
pmagpy.pmag.vfunc(pars_1, pars_2)[source]#

Calculate the Watson Vw test statistic. Calculated as 2*(Sw-Rw)

Parameters:
  • pars_1 (dictionary of Fisher statistics from population 1)

  • pars_2 (dictionary of Fisher statistics from population 2)

Returns:

Vw

Return type:

Watson’s Vw statistic

pmagpy.pmag.vgp_di(plat, plong, slat, slong)[source]#

Converts a pole position (pole latitude, pole longitude) to a direction (declination, inclination) at a given location (slat, slong) assuming a dipolar field.

Parameters:
  • plat (latitude of pole (vgp latitude))

  • plong (longitude of pole (vgp longitude))

  • slat (latitude of site)

  • slong (longitude of site)

Returns:

dec,inc

Return type:

tuple of declination and inclination

pmagpy.pmag.vocab_convert(vocab, standard, key='')[source]#

Converts MagIC database terms (method codes, geologic_types, etc) to other standards. May not be comprehensive for each standard. Terms added to standards as people need them and may not be up-to-date.

‘key’ can be used to distinguish vocab terms that exist in two different lists.

Return type:

value of the MagIC vocab in the standard requested

Examples

>>> pmag.vocab_convert('Egypt','GEOMAGIA')
'1'
pmagpy.pmag.vspec(data)[source]#

Takes the vector mean of replicate measurements at a given step. Used in zeq_magic2.py.

pmagpy.pmag.vspec_magic(data)[source]#

Takes average vector of replicate measurements.

pmagpy.pmag.vspec_magic3(data)[source]#

Takes average vector of replicate measurements.

pmagpy.pmag.watsonsV(Dir1, Dir2)[source]#

Calculates Watson’s V statistic for two sets of directions

pmagpy.pmag.watsons_f(DI1, DI2)[source]#

Calculates Watson’s F statistic (equation 11.16 in Essentials text book).

Parameters:
  • DI1 (nested array of [Dec,Inc] pairs)

  • DI2 (nested array of [Dec,Inc] pairs)

Returns:

  • F (Watson’s F)

  • Fcrit (critical value from F table)

Examples

>>> D1= [[-45,150],[-40,150],[-38,145]]
>>> D2= [[-43,140],[-39,130],[-38,145]]
>>> pmag.watsons_f(D1,D2)
(3.7453156915587567, 4.459)
pmagpy.pmag.weighted_mean(data)[source]#

Calculates the weighted mean of data.

Parameters:

data (array of data)

Returns:

  • mean (mean of the data as a float)

  • stdev (standard deviation of the data as a float)

Examples

>>> data = np.array([  [16.0,    43.0, 33],
       [30.5,    53.6, 58],
        [6.9,    33.2, 8],
      [352.5,    40.2, 52],
      [354.2,    45.1, 45]])
>>> pmag.weighted_mean(data)
(152.00743840074387, 81.7174866362813)

pmagpy.rockmag#

pmagpy.rockmag.ANOVA(xs, ys)[source]#

ANOVA statistics for linear regression

Parameters:
  • xs (numpy array) – x values

  • ys (numpy array) – y values

Returns:

results – dictionary of the results of the ANOVA calculation and intermediate statistics for the ANOVA calculation

Return type:

dict

pmagpy.rockmag.Fabian_nonlinear_fit(H, chi_HF, Ms, alpha, beta)[source]#

function for calculating the Fabian non-linear fit

Parameters:
  • H (numpy array) – field values

  • chi_HF (float) – high field susceptibility

  • Ms (float) – saturation magnetization

  • alpha (float) – coefficient of the H^(beta) term, needs to be negative

  • beta (float) – exponent of the H^(beta) term, needs to be negative

Returns:

fitted magnetization values for each field value in H (same shape as H)

Return type:

numpy array

pmagpy.rockmag.IRM_nonlinear_fit(H, chi_HF, Ms, a_1, a_2)[source]#

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:
  • H (numpy.ndarray) – Array of applied magnetic field values (in Tesla).

  • chi_HF (float) – High-field magnetic susceptibility. Converted to Tesla to match the unit of the field.

  • Ms (float) – Saturation magnetization (in the same units as IRM).

  • a_1 (float) – Coefficient for the H^(-1) non-linear correction term. Should be negative.

  • a_2 (float) – Coefficient for the H^(-2) non-linear correction term. Should be negative.

Returns:

IRM_fit – Array of fitted IRM values corresponding to each field value in H.

Return type:

numpy.ndarray

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()
pmagpy.rockmag.Langevin(alpha)[source]#

Langevin function

Parameters:

alpha (float) – Langevin alpha value

Returns:

L – Langevin function value

Return type:

float

pmagpy.rockmag.Me_drift_correction(H, M, descending_first=True)[source]#

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:
  • H (numpy.ndarray) – Array of magnetic field values, in canonical (descending-upper- branch-first) order.

  • M (numpy.ndarray) – Array of measured magnetization values corresponding to H.

  • descending_first (bool, optional) – Whether the loop was originally measured with the descending branch first (default True). Use measured_descending_first on the raw field values to determine this for a gridded loop.

Returns:

M_cor – Corrected magnetization values after drift correction.

Return type:

numpy.ndarray

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')
pmagpy.rockmag.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)[source]#

function to calculate the SD/MD mixture curve according to Dunlop (2002) :param Mr_Ms_SD: remanent to saturation magnetization ratio for SD. The default is 0.5. :type Mr_Ms_SD: float :param Mr_Ms_MD: remanent to saturation magnetization ratio for MD. The default is 0.019. :type Mr_Ms_MD: float :param Bc_SD: coercivity for SD. The default is 400. :type Bc_SD: float :param Bc_MD: coercivity for MD. The default is 43. :type Bc_MD: float :param Bcr_SD: coercivity of remanence for SD. The default is 500. :type Bcr_SD: float :param Bcr_MD: coercivity of remanence for MD. The default is 230. :type Bcr_MD: float :param X_sd: approximate Mrs/Bc slope for SD. The default is 0.6. :type X_sd: float :param X_MD: approximate Mrs/Bc slope for MD. The default is 0.209. :type X_MD: float :param Xr_SD: approximate Mrs/Bcr slope for SD. The default is 0.48. :type Xr_SD: float :param Xr_MD: approximate Mrs/Bcr slope for MD. The default is 0.039. :type Xr_MD: float

Returns:

  • Bcr_Bc (numpy.ndarray) – coercivity ratio array

  • Mrs_Ms (numpy.ndarray) – saturation magnetization ratio array

  • * the default values are fro the IRM database

pmagpy.rockmag.SP_SD_mixture(SP_size, SD_Mr_Ms=0.5, SD_Bcr_Bc=1.25, X_sd=3, T=300)[source]#

function to calculate the SP/SD mixture curve according to Dunlop (2002) :param SP_size: size of the superparamagnetic particle in nm :type SP_size: float :param SD_Mr_Ms: remanent to saturation magnetization ratio. The default is 0.5. :type SD_Mr_Ms: float, optional :param SD_Bcr_Bc: remanent coercivity to coercivity ratio. The default is 1.25. :type SD_Bcr_Bc: float, optional :param X_sd: approximate Mrs/Bc slope. The default is 3 for magnetite :type X_sd: float, optional :param T: temperature in Kelvin. The default is 300. :type T: float, optional

Returns:

  • Bcr_Bc (numpy.ndarray) – coercivity ratio array

  • Mrs_Ms (numpy.ndarray) – saturation magnetization ratio array

pmagpy.rockmag.SP_saturation_curve(SD_Mr_Ms=0.5, SD_Bcr_Bc=1.25)[source]#

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

Parameters:
  • SD_Mr_Ms (float, optional) – saturation magnetization ratio. The default is 0.5.

  • SD_Bcr_Bc (float, optional) – remanence coercivity to coercivity ratio. The default is 1.25.

Returns:

  • Bcr_Bc (numpy.ndarray) – coercivity ratio array

  • Mrs_Ms (numpy.ndarray) – saturation magnetization ratio array

pmagpy.rockmag.add_Bcr_to_specimens_table(specimens_df, experiment_name, Bcr)[source]#

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

Parameters:
  • specimens_df (pandas.DataFrame) – The specimens table from the MagIC database

  • experiment_name (str) – The name of the experiment to which the Bcr value belongs

  • Bcr (float) – The Bcr value to be added to the specimens table

pmagpy.rockmag.add_curie_estimates_to_specimens_table(specimens_df, experiment_name, estimates, method='inflection', branch='heating', critical_temp_type='Curie')[source]#

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:
  • specimens_df (pandas.DataFrame) – MagIC specimens table (with an ‘experiments’ column).

  • experiment_name (str) – Experiment the estimate belongs to.

  • estimates (pandas.DataFrame) – Tidy table from curie_temperature_estimates.

  • method (str, optional) – Which method’s estimate to write (default ‘inflection’).

  • branch (str, optional) – Which branch’s estimate to write (default ‘heating’).

  • critical_temp_type (str, optional) – MagIC controlled-vocabulary temperature type (default ‘Curie’).

pmagpy.rockmag.add_hyst_stats_to_specimens_table(specimens_df, hyst_results, overwrite=True)[source]#

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:
  • specimens_df (pandas.DataFrame) – dataframe with the specimens data

  • hyst_results (pandas.DataFrame) – DataFrame with hysteresis results including ‘specimen’ and ‘experiment’ columns, as output from rmag.process_hyst_loops. Has a numeric index (one row per experiment).

  • overwrite (bool, optional) – If True (default), existing MagIC column values and description stats are replaced with new values from hyst_results. If False, existing rows are preserved as-is and new rows are appended with the hyst results.

Returns:

specimens_df – A new DataFrame with hysteresis results added. If a specimen has multiple experiments, its row is duplicated so that each experiment gets its own row.

Return type:

pandas.DataFrame

pmagpy.rockmag.add_unmixing_to_specimens_table(specimens_df, components_df, mode='rows')[source]#

Record coercivity unmixing results in a MagIC specimens table.

Two recording conventions are supported:

  • mode=’rows’ (default, conformant with the MagIC data model): one new specimens row is appended per experiment and component, populating the controlled-vocabulary columns rem_cmf (component median field, in tesla), rem_cd (component dispersion, log10 units), and rem_n_comp (number of components in the model), along with specimen identity columns copied from the matching existing row. The full parameter set (proportion, skew, confidence intervals, …) is stored as JSON in each new row’s ‘description’ cell. Rows from a previous call for the same experiments are replaced.

  • mode=’description’: the matching existing specimens rows are updated in place, storing the complete unmixing model as JSON under the ‘coercivity_unmixing’ key in ‘description’ (any existing free text is preserved with a ‘text | json’ convention readable by parse_specimen_description).

Parameters:
  • specimens_df (pandas.DataFrame) – MagIC specimens table.

  • components_df (pandas.DataFrame) – Tidy components table from unmix_backfield_experiments.

  • mode (str) – ‘rows’ or ‘description’.

Returns:

The updated specimens table. With mode=’description’ the input table is also modified in place; with mode=’rows’ a new table is returned (pandas cannot append rows in place).

Return type:

pandas.DataFrame

pmagpy.rockmag.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'))[source]#

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:
  • components (pandas.DataFrame) – Tidy component table, e.g. from unmix_backfield_experiments (one row per experiment and component).

  • boundaries_mT (float or sequence of float) – Coercivity cut point(s) in mT. A single value gives two classes; a sequence of k values gives k+1 classes. A component is placed in the class between the cut points that bracket its coercivity; a component exactly on a boundary goes to the lower class.

  • class_names (sequence of str, optional) – Names for the classes, in order of increasing coercivity (length = number of boundaries + 1). Defaults to ‘class_1’, ‘class_2’, …; for a two-class split you would typically pass e.g. [‘magnetite’, ‘hematite’].

  • coercivity_column (str) – Column used to classify each component (default ‘B_mean_mT’).

  • proportion_column (str) – Column summed to give each class’s remanence fraction (default ‘proportion’).

  • contribution_column (str) – Column summed (and divided by curve_factor) to give each class’s absolute remanence; skipped if the column is absent.

  • curve_factor (float) – Divisor applied to summed contributions. Use 2 for a shift-corrected backfield curve (which spans twice the saturation remanence) and 1 for an IRM acquisition curve.

  • group_column (str) – Column identifying each specimen/experiment to aggregate within (default ‘experiment’).

  • passthrough (sequence of str) – Columns copied through unchanged (first value per group), e.g. specimen name and fit statistics. Missing columns are ignored.

Returns:

One row per group with the passthrough columns and, for each class, a ‘{name}_fraction’ column and (when contributions are present) a ‘{name}_remanence’ column.

Return type:

pandas.DataFrame

pmagpy.rockmag.build_symmetric_hyst_grid(upper_branch, lower_branch)[source]#

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

pmagpy.rockmag.calc_Bc(H, M)[source]#
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:
  • H (numpy array) – field values

  • M (numpy array) – magnetization values

Returns:

Bc – coercivity of the ferromagnetic component of the hysteresis loop

Return type:

float

pmagpy.rockmag.calc_Mr_Mrh_Mih_Brh(grid_field, grid_magnetization)[source]#

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

Parameters:
  • grid_field (numpy array) – gridded field values

  • grid_magnetization (numpy array) – gridded magnetization values

Returns:

  • H (numpy array) – field values of the upper branch (the two branches should have the same field values)

  • Mr (float) – remanent magnetization (Mrh interpolated at zero field)

  • Mrh (numpy array) – remanent hysteretic magnetization, (upper - lower)/2

  • Mih (numpy array) – induced hysteretic magnetization, (upper + lower)/2

  • Me (numpy array) – error curve err(H), the mismatch between the upper branch and the inverted lower branch

  • Brh (float) – median field of Mrh (field at which Mrh falls to half of Mr)

pmagpy.rockmag.calc_Q(H, M, type='Q')[source]#

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:
  • H (array_like) – Array of applied magnetic field values.

  • M (array_like) – Array of measured magnetization (moment) values, corresponding to H.

  • type ({'Q', 'Qf'}, optional) –

    Type of Q calculation to perform:
    • ’Q’ (default): Uses both upper and lower branches of the loop.

    • ’Qf’: Uses only the upper branch.

Returns:

  • M_sn (float) – The calculated signal-to-noise ratio (before applying the logarithm).

  • Q (float) – The quality factor, defined as log10(M_sn).

Notes

  • The function splits the hysteresis loop into upper and lower branches using split_hyst_loop.

  • For type ‘Q’, the numerator is the average of the sum of squares of the upper and lower branches; for ‘Qf’, only the upper branch is used.

  • The denominator is the sum of squares of err(H), the mismatch between the upper branch and the inverted lower branch, so M_sn is equivalent to the 1/(1 - R^2) signal/noise measure of Jackson and Solheid (2010, equation 3).

  • Higher Q values indicate a higher signal-to-noise ratio in the hysteresis loop data.

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}")
pmagpy.rockmag.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)[source]#

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:
  • temps (pd.Series) – Series representing the temperatures at which magnetization measurements were taken.

  • mags (pd.Series) – Series representing the magnetization measurements.

  • t_range_background_min (int or float, optional) – Minimum temperature for the background fitting range. Default is 50.

  • t_range_background_max (int or float, optional) – Maximum temperature for the background fitting range. Default is 250.

  • excluded_t_min (int or float, optional) – Minimum temperature to exclude from the background fitting range. Default is 75.

  • excluded_t_max (int or float, optional) – Maximum temperature to exclude from the background fitting range. Default is 150.

  • poly_deg (int, optional) – Degree of the polynomial for background fitting. Default is 3.

pmagpy.rockmag.calc_zero_crossing(dM_dT_temps, dM_dT)[source]#

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:

The estimated temperature at which the second derivative of magnetization

with respect to temperature crosses zero.

Return type:

float

Note

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

pmagpy.rockmag.chi_SP(SP_size, T)[source]#

SP size distribution function

Parameters:
  • SP_size (float) – size of the superparamagnetic particle in nm

  • T (float) – temperature in Kelvin

Returns:

chi – susceptibility value

Return type:

float

pmagpy.rockmag.clean_out_na(dataframe)[source]#

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

Parameters:

dataframe (pd.DataFrame) – The DataFrame to be cleaned.

Returns:

A cleaned DataFrame with all-NaN columns and rows removed.

Return type:

pd.DataFrame

pmagpy.rockmag.coercivity_curve_components(x, parameters, curve_type='backfield')[source]#

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:
  • x (array-like) – log10 of field values (mT).

  • parameters (pandas.DataFrame or array-like) – Component parameters (see coercivity_spectrum_components).

  • curve_type (str) – ‘backfield’ or ‘acquisition’.

Returns:

Array of shape (n_components, len(x)).

Return type:

numpy.ndarray

pmagpy.rockmag.coercivity_curve_model(x, parameters, offset=0.0, curve_type='backfield')[source]#

Evaluate the summed unmixing model in measurement space.

Parameters:
  • x (array-like) – log10 of field values (mT).

  • parameters (pandas.DataFrame or array-like) – Component parameters (see coercivity_spectrum_components).

  • offset (float) – Constant baseline added to the model (accounts for a small unsaturated or instrumental offset; default 0).

  • curve_type (str) – ‘backfield’ or ‘acquisition’.

Returns:

Total model curve at x.

Return type:

numpy.ndarray

pmagpy.rockmag.coercivity_prior_table(minerals=None)[source]#

Summarize the coercivity-component prior library as a table.

Parameters:

minerals (list of str, optional) – Component names, each a key of COERCIVITY_COMPONENT_LIBRARY. Defaults to the whole library, ordered by central (geometric-mean) coercivity.

Returns:

One row per component with its family, mean-coercivity window (mT), dispersion window (dp, log10 units), skew (Azzalini alpha) window, the implied distribution asymmetry, and the leading literature source.

Return type:

pandas.DataFrame

pmagpy.rockmag.coercivity_spectrum_components(x, parameters)[source]#

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

Parameters:
  • x (array-like) – log10 of field values (mT).

  • parameters (pandas.DataFrame or array-like) – One row per component with columns ‘contribution’ (area under the component in magnetization units), ‘location’, ‘dp’, ‘skew’.

Returns:

Array of shape (n_components, len(x)).

Return type:

numpy.ndarray

pmagpy.rockmag.coercivity_spectrum_from_curve(x, magnetization, curve_type='backfield')[source]#

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

Parameters:
  • x (array-like) – log10 of field values (mT), monotonically increasing.

  • magnetization (array-like) – Magnetization values at x (shifted to positive for backfield data, e.g. the ‘magn_mass_shift’ column from process_backfield_data).

  • curve_type (str) – ‘backfield’ (decaying curve, spectrum = -dM/dx) or ‘acquisition’ (growing curve, spectrum = dM/dx).

Returns:

(x_mid, spectrum) where x_mid are midpoints between successive x values and spectrum is the centered finite-difference derivative.

Return type:

tuple

pmagpy.rockmag.coercivity_spectrum_model(x, parameters)[source]#

Evaluate the summed unmixing model in spectrum space.

Parameters:
  • x (array-like) – log10 of field values (mT).

  • parameters (pandas.DataFrame or array-like) – Component parameters (see coercivity_spectrum_components).

Returns:

Total model spectrum at x.

Return type:

numpy.ndarray

pmagpy.rockmag.coercivity_unmixing_interactive(x, magnetization, n_components=2, method='spectrum', curve_type='backfield', vary_skew=True, figsize=(9, 5))[source]#

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:
  • x (array-like) – log10 of field values (mT), e.g. ‘log_dc_field’ from process_backfield_data.

  • magnetization (array-like) – Remanence curve values at x (e.g. ‘magn_mass_shift’).

  • n_components (int) – Number of components (default 2).

  • method (str) – ‘spectrum’ or ‘curve’ – the fitting approach used by the Fit button.

  • curve_type (str) – ‘backfield’ or ‘acquisition’.

  • vary_skew (bool) – Include skew sliders and let the fit vary skew (default True).

  • figsize (tuple) – Figure size.

Returns:

A live handle with keys ‘initial_parameters’ (DataFrame updated as sliders move; pass to the unmixing functions) and ‘result’ (filled with the standardized result dictionary after Fit is pressed).

Return type:

dict

pmagpy.rockmag.collapse_hyst_field_plateaus(field, magnetization)[source]#

Average consecutive repeated field steps into a single point.

pmagpy.rockmag.compare_unmixing_models(results)[source]#

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:

results (list of dict) – Result dictionaries from unmix_coercivity_spectrum or unmix_backfield_curve, typically with increasing n_components.

Returns:

One row per model with n_components, n_params, rss, r_squared, aic, bic, delta_aic, delta_bic, F, and p_value columns.

Return type:

pandas.DataFrame

pmagpy.rockmag.convert_temperature(temp_array, input_unit, output_unit)[source]#

Convert temperatures between Kelvin and Celsius.

Parameters:
  • temp_array (array-like) – Temperatures in input_unit.

  • input_unit ({'K', 'C'}) – Unit of the input temperatures.

  • output_unit ({'K', 'C'}) – Desired unit for output temperatures.

Returns:

Temperatures converted to output_unit.

Return type:

numpy.ndarray

Raises:

ValueError – If input_unit or output_unit is not ‘K’ or ‘C’.

pmagpy.rockmag.curie_Ms_squared_extrapolation(T, M, fit_range=None, exponent=2.0, min_points=5, min_m=None)[source]#

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 Js**2 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:
  • T (array-like) – Temperatures, ascending (Celsius or Kelvin; Tc is returned in the same unit as the input, since the x-intercept is unit-invariant).

  • M (array-like) – Saturation-magnetization (Ms) values.

  • fit_range (tuple of (float, float), optional) – Temperature interval for the linear fit of M**exponent. If None, the upper 40 percent of the temperature span is used — a starting guess only; inspect the fit and set the window explicitly (below the flattening/alteration temperature) for reported values.

  • exponent (float, optional) – Power to which M is raised before the linear fit (default 2.0, i.e. beta = 1/2). Any other exponent introduces curvature into the fit and moves Tc off the mean-field value (Moskowitz, 1981).

  • min_points (int, optional) – Minimum number of usable points in the window (default 5; floored at 3, since the covariance fit needs more than two points).

  • min_m (float, optional) – Exclude points with magnetization below this value from the fit (same units as M). Useful for screening out a flattened, weak, or altered tail.

Returns:

curie_temp (Tc = -intercept/slope, in the input temperature unit), curie_temp_stderr (1-sigma from the fit covariance), params with slope, intercept, r_squared, n_points, fit_range, exponent, a note when the fit is not usable (too few points or a non-negative slope), and a warning when the fitted points are dominated by repeated (flattened/altered) values, and diagnostics with T, m_pow (= M**exponent), the fitted points, and the extrapolated line.

Return type:

dict

pmagpy.rockmag.curie_derivative_estimates(T, y, t_range=None, smooth_window=0)[source]#

Derivative-based Curie temperature estimates from one thermomagnetic branch.

Two estimates are returned:

  • inflection_temp — the inflection point of the curve, located as the zero crossing of the second derivative between its extrema (refined by linear interpolation), with the minimum of the first derivative as fallback. For in-field magnetization curves M(T), Landau theory places the Curie temperature at this inflection point, independent of the applied field (Fabian et al., 2013, doi:10.1029/2012GC004440).

  • max_curvature_temp — the maximum of the second derivative (“maximum curvature” of the concave part of the heating curve). This is the classical practical definition of Ade-Hall et al. (1965) that is implemented in many software packages (including the legacy ipmag.curie). On M(T) curves it lies systematically above the inflection-point Tc (typically 10-15 degrees C) and shifts with the strength of the applied field (Fabian et al., 2013). It is searched on the concave shoulder above the steepest descent, consistent with this definition.

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:
  • T (array-like) – Temperatures, ascending (Celsius or Kelvin; the returned temperatures are in the same unit as the input).

  • y (array-like) – Magnetization or susceptibility values.

  • t_range (tuple of (float, float), optional) – Restrict the analysis to temperatures within (t_min, t_max). Useful for isolating one Curie transition in a multi-phase curve or excluding low-temperature structure (e.g., a Hopkinson peak).

  • smooth_window (float, optional) – Width, in the temperature units of T, of a moving-average window applied to the first and second derivatives before their extrema are located (default 0, no derivative smoothing). Recommended for noisy data; a good choice is the window used to smooth the signal. The diagnostics arrays reflect the smoothed derivatives actually used.

Returns:

inflection_temp, max_curvature_temp, first_derivative_min_temp (the discrete minimum of dy/dT), zero_crossing_temps (all interpolated zero crossings of the second derivative between its extrema), and diagnostics with the arrays T, dy_dT, and d2y_dT2.

Return type:

dict

pmagpy.rockmag.curie_inverse_susceptibility(T, chi, fit_range=None, min_points=5, min_chi=None)[source]#

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:
  • T (array-like) – Temperatures, ascending (Celsius or Kelvin; theta is returned in the same unit as the input).

  • chi (array-like) – Susceptibility values (holder-corrected).

  • fit_range (tuple of (float, float), optional) – Temperature interval for the linear fit of 1/chi. If None, the upper 20 percent of the temperature span is used — a starting guess only; inspect the fit and set the window explicitly for reported values.

  • min_points (int, optional) – Minimum number of usable points in the window (default 5).

  • min_chi (float, optional) – Exclude points with susceptibility below this value from the fit (same units as chi). Useful for screening out resolution-limited values in the high-temperature tail.

Returns:

curie_temp (theta), curie_temp_stderr (1-sigma from the fit covariance), params with slope, intercept, r_squared, curie_constant (1/slope), n_points, fit_range, and a warning when the fitted points are dominated by repeated (quantized) susceptibility values, and diagnostics with the 1/chi arrays and fitted line.

Return type:

dict

pmagpy.rockmag.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))[source]#

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:
  • experiment (pandas.DataFrame) – MagIC-formatted experiment DataFrame.

  • temperature_column

  • magnetic_column

  • temp_unit

  • input_unit

:param : :param smooth_window: As in curie_temperature_estimates. :param remove_holder: As in curie_temperature_estimates. :param branch: Branch to display (default ‘heating’). :type branch: {‘heating’, ‘cooling’}, optional :param initial_fit_range: Initial temperatures (in temp_unit) for the two fit-line

endpoints. Defaults to 70 percent and 100 percent of the branch’s temperature range — a starting position only, meant to be dragged.

Parameters:

figsize (tuple, optional) – (width, height) in inches; height sets the Bokeh plot height.

Returns:

The interactive Bokeh application is displayed as a side effect; no value is returned. For a reproducible, reportable estimate use curie_inverse_susceptibility with the fit_range identified here.

Return type:

None

Raises:

ValueError – If the requested branch is not present in the experiment, or if it has fewer than two usable (finite, positive-susceptibility) points.

pmagpy.rockmag.curie_landau_fit(T, M, fit_range=None, temp_unit='C', tc_bounds=None, n_grid=40)[source]#

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:
  • T (array-like) – Temperatures, ascending, in temp_unit.

  • M (array-like) – Magnetization values.

  • fit_range (tuple of (float, float), optional) – Temperature interval (in temp_unit) used in the fit. Default uses all points.

  • temp_unit ({'C', 'K'}, optional) – Unit of the input temperatures (default ‘C’). The reduced temperature is always formed in Kelvin internally; results are returned in temp_unit.

  • tc_bounds (tuple of (float, float), optional) – Bounds for Tc in Kelvin (default: (min(T)+1 K, 2000 K)). Tighten for extrapolation fits when independent constraints exist.

  • n_grid (int, optional) – Number of Tc values in the coarse initialization grid (default 40).

Returns:

curie_temp and curie_temp_stderr in temp_unit, params with M0, h, rss, n_points, fit_range, tc_bounds, and extrapolation (True when the highest fitted temperature is below the fitted Tc), and diagnostics with the fitted data and a dense model curve for plotting.

Return type:

dict

pmagpy.rockmag.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)[source]#

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:

  • 'inflection' — inflection point (curie_derivative_estimates); the recommended estimator for in-field M(T).

  • 'max_curvature' — second-derivative maximum (curie_derivative_estimates); classical, biased high on M(T).

  • 'two_tangent' — intersecting tangents (curie_two_tangent); for M(T), discouraged on susceptibility.

  • 'inverse_susceptibility' — Curie-Weiss extrapolation (curie_inverse_susceptibility); for susceptibility, heating branch.

  • 'landau' — in-field Landau equation-of-state fit (curie_landau_fit); for M(T), supports extrapolation from runs that end below Tc.

  • 'ms_squared_extrapolation' — mean-field extrapolation of Ms^2 to zero (curie_Ms_squared_extrapolation; Moskowitz, 1981); for M(T) curves that end below Tc. Not selectable for susceptibility data.

Parameters:
  • experiment (pandas.DataFrame) – MagIC-formatted experiment DataFrame.

  • methods (sequence of str, optional) – Methods to apply. Default depends on the data type (see data_type): susceptibility data use ('inflection', 'max_curvature', 'inverse_susceptibility'); magnetization data use ('inflection', 'max_curvature', 'two_tangent', 'landau').

  • temperature_column (str, optional) – Name of the temperature column (default ‘meas_temp’).

  • magnetic_column (str, optional) – Name of the magnetization/susceptibility column (default ‘susc_chi_mass’).

  • temp_unit ({'C', 'K'}, optional) – Unit for reported temperatures (default ‘C’).

  • input_unit ({'K', 'C'}, optional) – Unit of the temperatures in experiment (default ‘K’, the MagIC convention).

  • smooth_window (float, optional) – Smoothing window width in temp_unit (default 0, no smoothing). Derivative-based methods generally require smoothing of noisy data; see optimize_moving_average_window.

  • remove_holder (bool, optional) – Subtract the per-branch minimum (default True). Disable for runs that end below the Curie temperature.

  • branches (sequence of str, optional) – Branches to analyze, from (‘heating’, ‘cooling’).

  • method_kwargs (dict, optional) – Per-method keyword arguments, e.g. {'inverse_susceptibility': {'fit_range': (620, 700)}, 'landau': {'fit_range': (300, 650)}}. The keys 'inflection' and 'max_curvature' (or the shared key 'derivative') forward options such as t_range to curie_derivative_estimates. Unknown keys raise a ValueError rather than being silently ignored.

  • print_estimates (bool, optional) – Print a one-line summary per estimate (default False).

  • data_type ({'susceptibility', 'magnetization', None}, optional) – Explicit data type, controlling the default method set and the caveat notes. When None (default), inferred from whether magnetic_column contains ‘susc’ or ‘chi’.

  • branch_data (dict, optional) – Precomputed output of prepare_thermomag_branches (with matching preprocessing arguments). When provided, preprocessing is skipped — used by plot_curie_estimates to avoid recomputation.

  • return_method_results (bool, optional) – If True, also return a dict keyed by (branch, method) holding each estimator’s full result (including diagnostics), for plotting or further analysis (default False).

Returns:

One row per (branch, method) with columns specimen, experiment, branch, method, curie_temp, curie_temp_stderr, temp_unit, params (dict of method-specific parameters), and notes. With return_method_results=True, additionally the per-(branch, method) result dicts.

Return type:

pandas.DataFrame or (pandas.DataFrame, dict)

pmagpy.rockmag.curie_two_tangent(T, y, lower_range=None, upper_range=None, min_points=3)[source]#

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:
  • T (array-like) – Temperatures, ascending (Celsius or Kelvin; the returned intersection temperature is in the same unit as the input).

  • y (array-like) – Magnetization (preferred) or susceptibility values.

  • lower_range (tuple of (float, float), optional) – Temperature interval for the descending-limb tangent. If None, the contiguous region around the steepest descent where the slope is at least half the steepest slope is used.

  • upper_range (tuple of (float, float), optional) – Temperature interval for the baseline tangent. If None, points above the steepest descent where the slope has decayed to within 5 percent of the steepest slope are used (falling back to the uppermost decile of points).

  • min_points (int, optional) – Minimum number of points required in each tangent segment (default 3).

Returns:

curie_temp (intersection temperature, NaN if the tangents are parallel or a segment has too few points), params with the two (slope, intercept) pairs, the temperature ranges actually used, point counts, and reliable (False when no near-flat baseline was found above the transition and the upper tangent fell back to the uppermost points, i.e. the curve may end below Tc), and diagnostics with the segment masks for plotting.

Return type:

dict

pmagpy.rockmag.estimate_coercivity_components(x, spectrum, n_components, smooth_window=None)[source]#

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:
  • x (array-like) – log10 of field values (mT).

  • spectrum (array-like) – Coercivity spectrum values at x.

  • n_components (int) – Number of components to estimate.

  • smooth_window (int, optional) – Savitzky-Golay window length (grid points). Defaults to ~1/10 of the grid (minimum 5).

Returns:

Initial parameters with columns ‘contribution’, ‘location’, ‘dp’, ‘skew’ (skew = 0), sorted by location.

Return type:

pandas.DataFrame

pmagpy.rockmag.estimate_measurement_noise(x, magnetization, curve_type='backfield')[source]#

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:
  • x (array-like) – log10 of field values (mT); the data are sorted by x internally.

  • magnetization (array-like) – Remanence curve values at x.

  • curve_type (str) – Unused; accepted for signature consistency with the unmixing functions.

Returns:

Estimated measurement noise standard deviation in magnetization units.

Return type:

float

pmagpy.rockmag.experiment_selection(measurements, experiment_name)[source]#

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

Parameters:
  • measurements (pd.DataFrame) – The DataFrame containing measurement data with an ‘experiment’ column.

  • experiment_name (str) – The name of the experiment to select from the DataFrame.

Returns:

A DataFrame containing only the rows corresponding to the specified experiment.

Return type:

pd.DataFrame

pmagpy.rockmag.extract_hyst_data(df, specimen_name)[source]#

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:

Measurements for the specimen with ‘LP-HYS’ in

their method codes (empty if none are present).

Return type:

pandas.DataFrame

Example

>>> hyst_data = extract_hyst_data(measurements_df, 'Specimen_1')
pmagpy.rockmag.extract_mpms_data_dc(measurements, specimen_name)[source]#

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:

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.

Return type:

tuple

pmagpy.rockmag.find_hyst_turning_point(field)[source]#

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.

pmagpy.rockmag.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)[source]#

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:

Only if return_data is True. Returns two pandas Series

containing the corrected magnetization data for the warming and cooling sequences, respectively.

Return type:

Tuple[pd.Series, pd.Series]

pmagpy.rockmag.goethite_removal_interactive(measurements, specimen)[source]#

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:
  • measurements (pandas.DataFrame) – Low temperature remanence measurement data containing temperature and magnetization information for multiple specimens.

  • specimen (str or ipywidgets.Dropdown) – Specimen to analyze, given either as a plain specimen name or as a selection widget (e.g. from specimen_selection_interactive); for a widget the current .value is read when this function runs, so rerun the cell after changing the dropdown.

Notes

  • Uses ipywidgets for interactive controls and matplotlib for plotting.

  • The temperature range for the goethite fit and the polynomial degree of the fit can be adjusted via sliders.

  • A reset button allows restoration of default parameter values.

  • Supporting functions such as extract_mpms_data_dc and goethite_removal are required for this function to operate.

  • This function is intended to be used in a Jupyter notebook or similar interactive environment.

Returns:

The function displays interactive widgets and plots for goethite removal but does not return a value.

Return type:

None

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.
pmagpy.rockmag.grid_hyst_loop(field, magnetization)[source]#
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:
  • field (numpy array or list) – hysteresis loop field values

  • magnetization (numpy array or list) – hysteresis loop magnetization values

Returns:

  • grid_field (numpy array) – gridded field values

  • grid_magnetization (numpy array) – gridded magnetization values

pmagpy.rockmag.hyst_HF_nonlinear_optimization(H, M, HF_cutoff, fit_type, initial_guess=[1, 1, -0.1, -0.1], bounds=([0, 0, -inf, -inf], [inf, inf, 0, 0]))[source]#

Optimize a high-field nonlinear fit

Parameters:
  • H (numpy.ndarray) – Array of field values.

  • M (numpy.ndarray) – Array of magnetization values.

  • HF_cutoff (float) – Fraction of max(|H|) defining the lower bound of the high-field region.

  • fit_type ({'IRM', 'Fabian', 'Fabian_fixed_beta'}) – Type of nonlinear model to fit.

  • initial_guess (list of float, optional) – Initial parameter guess for the optimizer. Defaults to [1, 1, -0.1, -0.1]: χ_HF = 1, Mₛ = 1, a₁ = –0.1, a₂ = –0.1 (or α, β for Fabian).

  • bounds (tuple of array-like, optional) – Lower and upper bounds for each parameter. Defaults to ([0, 0, -∞, -∞], [∞, ∞, 0, 0]): - Lower: χ_HF ≥ 0, Mₛ ≥ 0, a₁ ≥ –∞, a₂ ≥ –∞ - Upper: χ_HF ≤ ∞, Mₛ ≤ ∞, a₁ ≤ 0, a₂ ≤ 0 (for Fabian, α and β follow the same positions/limits).

Returns:

Fit results with keys: - ‘chi_HF’, ‘Ms’, ‘a_1’, ‘a_2’ (for IRM) or

’chi_HF’, ‘Ms’, ‘alpha’, ‘beta’ (for Fabian variants)

  • ’Fnl_lin’: float, F statistic for the improvement of the nonlinear fit over a linear fit (Jackson and Solheid, 2010, equation 21); values above ~3-3.5 indicate a statistically significant improvement for the 4-parameter models (for ‘Fabian_fixed_beta’ the degrees of freedom are (1, N-3) and the 5% critical value is ~3.9-4.0). Because the nonlinear coefficients are constrained non-positive, the statistic is conservative under the null (saturated loops give values well below the critical value, occasionally marginally negative when the bounded fit is a hair worse than unconstrained least squares).

Return type:

dict

pmagpy.rockmag.hyst_linearity_test(grid_field, grid_magnetization)[source]#

function for testing the linearity of a hysteresis loop

Parameters:
  • grid_field (numpy array) – gridded field values

  • grid_magnetization (numpy array) – gridded magnetization values

Returns:

results – dictionary of the results of the linearity test and intermediate statistics for the ANOVA calculation

Return type:

dict

pmagpy.rockmag.hyst_loop_centering(grid_field, grid_magnetization)[source]#
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:
  • grid_field (numpy array) – gridded field values

  • grid_magnetization (numpy array) – gridded magnetization values

Returns:

  • opt_H_offset (float) – optimized applied field offset value for the loop

  • opt_M_offset (float) – calculated magnetization offset value for the loop based on the optimized applied field offset (intercept of the fitted line using the upper branch and the inverted and optimally offsetted lower branch)

  • R_squared (float) – R-squared value of the linear fit between the upper branch and the inverted and offsetted lower branch

pmagpy.rockmag.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)[source]#

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.

pmagpy.rockmag.hyst_loop_saturation_test(grid_field, grid_magnetization, max_field_cutoff=0.97)[source]#

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:
  • grid_field (array_like) – Array of applied magnetic field values for the hysteresis loop.

  • grid_magnetization (array_like) – Array of magnetization (moment) values corresponding to grid_field.

  • max_field_cutoff (float, optional) – Fraction of the maximum field to use as an upper cutoff for the analysis (default is 0.97).

Returns:

results_dict –

Dictionary containing:
  • ’FNL60’: float, FNL for the window from 60% of the maximum field.

  • ’FNL70’: float, FNL for the window from 70% of the maximum field.

  • ’FNL80’: float, FNL for the window from 80% of the maximum field.

  • ’saturation_cutoff’: float, lowest field fraction (0.6, 0.7, or 0.8) at which the high-field segment is statistically linear (saturated); 0.92 (the IRM default for a nonlinear fit window) if no tested window is linear.

  • ’loop_is_saturated’: bool, True if the loop is saturated (linear) in at least one tested high-field window; False if all windows show significant nonlinearity, in which case an approach-to-saturation fit should be used.

Return type:

dict

Notes

  • The function uses loop_saturation_stats to compute FNL values for each field fraction.

  • FNL values below 2.5 indicate statistically linear (saturated) high-field behavior; values above 2.5 indicate significant nonlinearity (nonsaturation).

  • The result is converted to standard Python types using _to_native_python.

Examples

>>> results = hyst_loop_saturation_test(fields, magnetizations)
>>> print(results['saturation_cutoff'], results['loop_is_saturated'])
0.8 False
pmagpy.rockmag.hyst_slope_correction(grid_field, grid_magnetization, chi_HF)[source]#
function for subtracting the paramagnetic/diamagnetic slope from a hysteresis loop

the input should be gridded field and magnetization values

Parameters:
  • grid_field (numpy array) – gridded field values

  • grid_magnetization (numpy array) – gridded magnetization values

  • chi_HF (float) – X_HF

Returns:

grid_magnetization_ferro – corrected ferromagnetic component of the magnetization

Return type:

numpy array

pmagpy.rockmag.landau_magnetization(tau, h)[source]#

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:
  • tau (array-like) – Reduced temperatures (T - Tc)/Tc; requires absolute temperatures (Kelvin) in the ratio.

  • h (float) – Reduced field, >= 0.

Returns:

Reduced magnetization m at each tau.

Return type:

numpy.ndarray

pmagpy.rockmag.linear_HF_fit(field, magnetization, HF_cutoff=0.8)[source]#

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

Parameters:
  • field (numpy array or list) – raw hysteresis loop field values

  • magnetization (numpy array or list) – raw hysteresis loop magnetization values

Returns:

  • chi_HF (float) – high-field susceptibility of the paramagnetic/diamagnetic contribution in SI units (the raw fitted slope in field units of Tesla multiplied by mu_0 = 4*pi*1e-7); hyst_slope_correction performs the inverse conversion when removing this contribution from a loop

  • intercept (float) – y-intercept of the linear fit can be interpreted to be the saturation magnetization of the ferromagnetic component

pmagpy.rockmag.loop_closure_test(H, Mrh, HF_cutoff=0.8, *, Me=None, max_field_cutoff=0.99)[source]#

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:
  • H (array-like) – field values of the upper branch (ascending)

  • Mrh (array-like) – remanent hysteretic magnetization Mrh(H)

  • HF_cutoff (float) – high field cutoff value taken as fraction of the max field value

  • Me (array-like, optional, keyword-only) – error curve err(H) on the same field axis (as returned by calc_Mr_Mrh_Mih_Brh); used as the noise estimate when provided

  • max_field_cutoff (float, keyword-only) – upper trim of the high-field windows as fraction of the max field

Returns:

results –

Dictionary containing:
  • ’SNR’: float, high-field signal-to-noise ratio in dB

  • ’HAR’: float, high-field to total Mrh area ratio in dB

  • ’loop_is_closed’: bool, True if SNR < 8 dB or HAR < -48 dB

Return type:

dict

pmagpy.rockmag.loop_saturation_stats(field, magnetization, HF_cutoff=0.8, max_field_cutoff=0.97)[source]#

ANOVA statistics for the high field portion of a hysteresis loop

Parameters:
  • field (numpy array) – field values

  • magnetization (numpy array) – magnetization values

  • HF_cutoff (float) – high field cutoff value default is 0.8

Returns:

results – dictionary of the results of the ANOVA calculation and intermediate statistics for the ANOVA calculation

Return type:

dict

pmagpy.rockmag.magnetite_Ms(T)[source]#

Magnetite saturation magnetization calculation

Parameters:

T (float) – temperature in Celsius

Returns:

Ms – saturation magnetization value

Return type:

float

pmagpy.rockmag.make_experiment_df(measurements, exclude_method_codes=None)[source]#

Creates a DataFrame of unique experiments from the measurements DataFrame.

Parameters:
  • measurements (pd.DataFrame) – The DataFrame containing measurement data with columns ‘specimen’, ‘method_codes’, and ‘experiment’.

  • exclude_method_codes (list of str, optional) – List of method codes to exclude from the output DataFrame. Rows with ‘method_codes’ containing any of these substrings will be removed.

Returns:

A DataFrame containing unique combinations of ‘specimen’, ‘method_codes’, and ‘experiment’.

Return type:

pd.DataFrame

pmagpy.rockmag.measured_descending_first(field)[source]#

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:

field (array_like) – Raw (ungridded) applied field values in measurement order.

Returns:

True if the sweep starts at the positive field extreme (descending branch measured first), False if it starts at the negative extreme.

Return type:

bool

pmagpy.rockmag.mineral_priors(mineral_names, tighten=1.0, widen=1.0, field_max_mT=None, overrides=None)[source]#

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:
  • mineral_names (list of str) – Component names, each a key of COERCIVITY_COMPONENT_LIBRARY (e.g. [‘magnetite_detrital’, ‘hematite_pigmentary’, ‘hematite_detrital’]).

  • tighten (float) – Factor (>= 1) by which to narrow every window about its center; 1 keeps the library width.

  • widen (float) – Factor (>= 1) by which to broaden every window about its center; 1 keeps the library width. tighten and widen compose (net width factor = widen / tighten).

  • field_max_mT (float, optional) – Maximum applied field of the measurement (mT). Coercivity upper bounds are clipped to this value, so that components whose window extends past the measured field (e.g. hard hematite or pyrrhotite in a 1-2 T experiment) are not given prior support the data cannot constrain.

  • overrides (dict, optional) – Per-mineral window replacements, mapping a mineral name to a dict with any of ‘B_median_mT’, ‘dp’, ‘skew’ as (low, high) tuples. The replacement window is used in place of the library value (before tighten/widen and field clipping are applied), letting you anchor to the library for most minerals while tuning the ones your samples require.

Returns:

A priors dictionary with ‘mean’, ‘dp’, and ‘skew’ keys, each a list of (low, high) tuples in the order of increasing coercivity, suitable for unmix_coercivity_bayes(…, priors=…). The ‘mean’ window constrains each component’s MEAN coercivity (log10 mT) – so a library window means what it says regardless of the component’s skew. The chosen component names, in the same order, are returned under the ‘components’ key.

Return type:

dict

pmagpy.rockmag.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)[source]#
function for simulating simple mixtures of MPMS dc remanence measurements using the Insitute for Rock Magnetism’s

rock magnetism bestiary data

Parameters:
  • measurement_1 (pandas.DataFrame) – MagIC formatted dataframe containing the first set of measurements.

  • measurement_2 (pandas.DataFrame) – MagIC formatted dataframe containing the second set of measurements.

  • spec_1 (str) – Specimen name for the first set of measurements.

  • spec_2 (str) – Specimen name for the second set of measurements.

  • experiments (list of str, optional) – List of experiment method codes to consider for blending. Default is [‘LP-ZFC’, ‘LP-FC’, ‘LP-CW-SIRM:LP-MC’, ‘LP-CW-SIRM:LP-MW’].

  • temp_col (str, optional) – Column name for temperature in the measurement dataframes. Default is ‘meas_temp’.

  • moment_col (str, optional) – Column name for magnetization in the measurement dataframes. Default is ‘magn_mass’.

  • fraction (float, optional) – Fraction of the first specimen’s magnetization to blend with the second specimen’s magnetization. Default is 0.5.

Returns:

A dictionary where keys are experiment method codes and values are dictionaries containing:

Return type:

dict

pmagpy.rockmag.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))[source]#
function for making interactive blender of MPMS dc remanence measurements using the Institute for Rock Magnetism’s

rock magnetism bestiary data

Parameters:
  • measurement_1 (pandas.DataFrame) – MagIC formatted dataframe containing the first set of measurements.

  • measurement_2 (pandas.DataFrame) – MagIC formatted dataframe containing the second set of measurements.

  • experiments (list of str, optional) – List of experiment method codes to consider for blending. Default is [‘LP-ZFC’, ‘LP-FC’, ‘LP-CW-SIRM:LP-MC’, ‘LP-CW-SIRM:LP-MW’].

  • temp_col (str, optional) – Column name for temperature in the measurement dataframes. Default is ‘meas_temp’.

  • moment_col (str, optional) – Column name for magnetization in the measurement dataframes. Default is ‘magn_mass’.

  • figsize (tuple of float, optional) – Size of the figure for plotting. Default is (12, 6).

pmagpy.rockmag.optimize_moving_average_window(experiment, min_temp_window=0, max_temp_window=50, steps=50, colormapwarm='tab20b', colormapcool='tab20c')[source]#

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:
  • experiment (object or structured array) – Experimental data containing temperature and measurement values. It must be compatible with the split_heating_cooling function.

  • min_temp_window (float, optional) – Minimum window size (in degrees Celsius) for the moving average. Default is 0.

  • max_temp_window (float, optional) – Maximum window size (in degrees Celsius) for the moving average. Default is 50.

  • steps (int, optional) – Number of window size steps to evaluate between the minimum and maximum. Default is 50.

  • colormapwarm (str, optional) – Matplotlib colormap name for the warm cycle plot. Default is ‘tab20b’.

  • colormapcool (str, optional) – Matplotlib colormap name for the cool cycle plot. Default is ‘tab20c’.

Returns:

  • fig (matplotlib.figure.Figure) – The matplotlib Figure object containing the optimization plots.

  • axs (numpy.ndarray of matplotlib.axes.Axes) – Array of Axes objects (one for the warm cycle, one for the cool cycle).

Examples

>>> fig, axs = optimize_moving_average_window(my_experiment, min_temp_window=5, max_temp_window=30, steps=20)
>>> fig.show()
pmagpy.rockmag.parse_specimen_description(description)[source]#

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:

description (str or NaN) – Contents of the description cell.

Returns:

(text, data) where text is the free-text portion (str, possibly empty) and data is the parsed dictionary (possibly empty).

Return type:

tuple

pmagpy.rockmag.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')[source]#

Plot magnetization versus temperature in static or interactive mode.

Parameters:
  • data (pandas.DataFrame or array-like) – Table or array containing temperature and magnetization data.

  • temperature_column (str, default 'meas_temp') – Name of the temperature column in data.

  • magnetization_column (str, default 'magn_mass') – Name of the magnetization column in data.

  • input_unit ({'K', 'C'}, default 'K') – Unit of the input temperature data.

  • plot_unit ({'K', 'C'}, default 'K') – Unit for the x-axis display.

  • interactive (bool, default False) – If True, use Bokeh for an interactive plot.

  • return_figure (bool, default False) –

    If True, return the figure object(s). Assign to capture, e.g.:

    fig, ax = plot_M_T(…, return_figure=True)

  • show_plot (bool, default True) – If True, display the plot immediately.

  • size (tuple(float, float), default (6, 3)) – Figure size in inches (Matplotlib) or height for Bokeh.

  • legend_location (str, default 'upper left') – Legend location in Matplotlib terms.

Returns:

  • If return_figure=True and interactive=False, returns (fig, ax).

  • If return_figure=True and interactive=True, returns the Bokeh layout object.

  • Otherwise, returns None.

Return type:

tuple or layout or None

pmagpy.rockmag.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')[source]#

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

Parameters:
  • experiment (DataFrame) – Must contain raw and, if requested, processed columns.

  • field (str) – Name of the magnetic field column.

  • magnetization (str) – Name of the magnetization column.

  • Bcr (float, optional) – Calculated Bcr (T). If provided, will be plotted as a pink star.

  • figsize (tuple(float, float)) – Figure size (in inches).

  • plot_raw (bool)

  • plot_processed (bool)

  • plot_spectrum (bool)

  • interactive (bool)

  • return_figure (bool)

  • show_plot (bool)

  • y_axis_units (str, optional) – Units to display on the y-axis labels of raw and processed panels.

  • legend_location (str, optional) – Location of the legend in Matplotlib terms.

Return type:

Matplotlib (fig, axes) or Bokeh grid or None

pmagpy.rockmag.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')[source]#

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:

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.

Return type:

tuple or None

pmagpy.rockmag.plot_coercivity_prior_library(minerals=None, field_range=(1.0, 5000.0), n_grid=400, figsize=None, ax=None)[source]#

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:
  • minerals (list of str, optional) – Component names to show (default: the whole library).

  • field_range (tuple) – (min, max) field in mT for the coercivity axis (default 1-5000).

  • n_grid (int) – Number of points for the density curves.

  • figsize (tuple, optional) – Figure size; a default is chosen from the number of components.

  • ax (matplotlib.axes.Axes, optional) – Axis to draw on; a new figure is created if omitted.

Returns:

(fig, ax).

Return type:

tuple

pmagpy.rockmag.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)[source]#

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:
  • result (dict) – Result from unmix_coercivity_spectrum, unmix_backfield_curve, or unmixing_bootstrap.

  • show_components (bool) – Draw the individual components (default True).

  • show_bootstrap (bool) – Draw bootstrap confidence bands if available (default True).

  • show_initial (bool) – Also draw the model implied by the initial parameters (dotted), useful for judging how far the optimizer moved (default False).

  • n_grid (int) – Number of points for smooth model curves.

  • figsize (tuple, optional) – Figure size; defaults depend on the number of panels.

  • title (str, optional) – Figure title.

  • color_by (str) – How to color the components. ‘component’ (default) colors by fit order (C0, C1, …). ‘class’ (or the alias ‘coercivity’) colors each component by the coercivity class its mean field falls into, so the mineralogy is read directly and a second component of the same mineral does not take a different color; requires class_boundaries.

  • class_boundaries (float or sequence of float, optional) – Coercivity cut points in mT that partition the components into classes when color_by=’class’ (e.g. 200 for a magnetite/hematite split, or [30, 300] for three classes).

  • class_colors (sequence, optional) – One color per class (length = number of boundaries + 1). Defaults to blue/red for two classes, or a diverging colormap otherwise.

Returns:

(fig, axes) with axes a list of the panel axes.

Return type:

tuple

pmagpy.rockmag.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), legend_loc='lower left', xlim=None, ylim=None, return_figure=False, save_path=None, data_type=None)[source]#

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:
  • experiment (pandas.DataFrame) – MagIC-formatted experiment DataFrame.

  • methods (sequence of str, optional) – Methods to display (default as in curie_temperature_estimates).

  • temperature_column

  • magnetic_column

  • temp_unit

  • input_unit

:param : :param smooth_window: As in curie_temperature_estimates. :param remove_holder: As in curie_temperature_estimates. :param branches: As in curie_temperature_estimates. :param method_kwargs: As in curie_temperature_estimates. :param data_type: As in curie_temperature_estimates. :param figsize: Figure size in inches (default (10, 10)). :type figsize: tuple, optional :param legend_loc: Legend location for the main panel, passed to

matplotlib.axes.Axes.legend (default ‘lower left’).

Parameters:
  • xlim (tuple of float, optional) – Temperature-axis limits (tmin, tmax) in temp_unit, applied to all panels (they share the x axis). Each panel’s y axis is then autoscaled to the data within the window. Useful for zooming in on a transition temperature.

  • ylim (tuple of float, optional) – y-axis limits for the main panel only; overrides the xlim autoscaling there.

  • return_figure (bool, optional) – If True, return (fig, axes) (default False).

  • save_path (str, optional) – If given, save the figure to this path.

Return type:

(matplotlib.figure.Figure, numpy.ndarray of Axes) or None

pmagpy.rockmag.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)[source]#
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:
  • Ms (float or array-like) – saturation magnetization

  • Mr (float or array-like) – remanent magnetization

  • Bc (float or array-like) – coercivity

  • Bcr (float or array-like) – coercivity of remanence

  • color (str, optional) – color of the points. The default is ‘black’.

  • marker (str, optional) – marker style of the points. The default is ‘o’.

  • label (str, optional) – label for the points. The default is ‘sample’.

  • alpha (float, optional) – transparency of the points. The default is 1.

  • lc (str, optional) – color of the lines. The default is ‘black’.

  • lw (float, optional) – line width of the lines. The default is 0.5.

  • legend (bool, optional) – whether to show the legend. The default is True.

  • figsize (tuple, optional) – size of the figure. The default is (6,6).

  • show_plot (bool, optional) – whether to show the plot. The default is True.

  • return_figure (bool, optional) – whether to return the figure and axes objects. The default is True, so that a different function (plot_day_MagIC) can use it.

Returns:

  • If return_figure is True (default), returns (fig, ax).

  • Otherwise, returns None.

Return type:

tuple or None

pmagpy.rockmag.plot_day_magic(specimen_data, by='specimen', Mr='hyst_mr_mass', Ms='hyst_ms_mass', Bcr='rem_bcr', Bc='hyst_bc', **kwargs)[source]#

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

Parameters:
  • specimen_data (pandas.DataFrame) – DataFrame containing the specimens data.

  • by (str) – Column name to group by (default is ‘specimen’).

  • Mr (str) – Column name for the remanence (default is ‘hyst_mr_mass’).

  • Ms (str) – Column name for the saturation magnetization (default is ‘hyst_ms_mass’).

  • Bcr (str) – Column name for the coercivity (default is ‘hyst_bcr’).

  • Bc (str) – Column name for the coercivity of remanence (default is ‘hyst_bc’).

  • **kwargs (keyword arguments) – Additional arguments to pass to the plotting function.

Returns:

ax – The axes object containing the plot.

Return type:

matplotlib.axes.Axes

pmagpy.rockmag.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')[source]#

function to plot a hysteresis loop

Parameters:
  • field (numpy array or list) – hysteresis loop field values

  • magnetization (numpy array or list) – hysteresis loop magnetization values

Returns:

p

Return type:

bokeh.plotting.figure

pmagpy.rockmag.plot_mpms_ac(experiment, frequency=None, phase='in', figsize=(6, 6), interactive=False, return_figure=False, show_plot=True, legend_location='upper left')[source]#

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

Parameters:
  • experiment (pandas.DataFrame) – The experiment table from the MagIC contribution.

  • frequency (float or None) – Frequency of AC measurement in Hz; None plots all frequencies.

  • phase ({'in','out','both'}) – Which phase to plot.

  • figsize (tuple of float) – Figure size for Matplotlib (width, height).

  • interactive (bool) – If True, render with Bokeh for interactive exploration.

  • return_figure (bool) – If True, return the figure object(s).

  • show_plot (bool) – If True, display the plot.

  • legend_location (str, default 'upper left') – Location of the legend in Matplotlib terms.

Return type:

fig, ax or (fig, axes) or Bokeh layout or None

pmagpy.rockmag.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)[source]#

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 (str) – HEX color codes.

  • zfc_color (str) – HEX color codes.

  • rtsirm_cool_color (str) – HEX color codes.

  • rtsirm_warm_color (str) – HEX color codes.

  • fc_marker (str) – Matplotlib-style markers.

  • zfc_marker (str) – Matplotlib-style markers.

  • rtsirm_cool_marker (str) – Matplotlib-style markers.

  • 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.

pmagpy.rockmag.plot_mpms_dc_interactive(measurements)[source]#

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

Parameters:

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

pmagpy.rockmag.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))[source]#

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:
  • Mr (array-like) – Saturation remanence values of the samples.

  • Ms (array-like) – Saturation magnetization values of the samples.

  • Bc (array-like) – Coercivity values of the samples.

  • color (str, optional) – Color of the scatter points. Default is “black”.

  • marker (str, optional) – Marker style for scatter points. Default is “o”.

  • label (str, optional) – Label for the sample to be displayed in the legend. Default is “sample”.

  • alpha (float, optional) – Transparency of the scatter points. Default is 1 (opaque).

  • lc (str, optional) – Color of the grid lines. Default is “black”.

  • lw (float, optional) – Line width of the grid lines. Default is 0.5.

  • legend (bool, optional) – Whether to show the legend. Default is True.

  • axis_scale (str, optional) – Scale for both axes: “linear” or “log”. Default is “linear”.

  • figsize (tuple of int, optional) – Figure size in inches (width, height). Default is (5, 5).

Returns:

The matplotlib axes object containing the plot.

Return type:

matplotlib.axes.Axes

pmagpy.rockmag.plot_neel_magic(specimen_data, by='specimen', Mr='hyst_mr_mass', Ms='hyst_ms_mass', Bcr='rem_bcr', Bc='hyst_bc', **kwargs)[source]#

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

Parameters:
  • specimen_data (pandas.DataFrame) – DataFrame containing the specimens data.

  • by (str) – Column name to group by (default is ‘specimen’).

  • Mr (str) – Column name for the remanence (default is ‘hyst_mr_mass’).

  • Ms (str) – Column name for the saturation magnetization (default is ‘hyst_ms_mass’).

  • Bcr (str) – Column name for the coercivity (default is ‘hyst_bcr’).

  • Bc (str) – Column name for the coercivity of remanence (default is ‘hyst_bc’).

  • **kwargs (keyword arguments) – Additional arguments to pass to the plotting function.

Returns:

ax – The axes object containing the plot.

Return type:

matplotlib.axes.Axes

pmagpy.rockmag.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)[source]#

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:
  • result (dict) – Result from unmixing_bootstrap or unmix_coercivity_bayes.

  • space (str) – ‘spectrum’ (dM/dlog10 B) or ‘curve’ (measurement space).

  • n_draws (int) – Number of draws to overlay (capped at the number available).

  • n_grid (int) – Number of field points for the smooth curves.

  • show_components (bool) – Overlay per-component curves in addition to the total.

  • figsize (tuple) – Figure size.

  • title (str, optional) – Figure title.

  • colors (list, optional) – Per-component colors.

  • random_seed (None, int, or numpy.random.Generator) – Seed for choosing which draws to plot.

Returns:

(fig, ax).

Return type:

tuple

pmagpy.rockmag.plot_unmixing_multistart(result, max_solutions=6, space='spectrum', n_grid=300, figsize=None, colors=None, marker_scale='uniform')[source]#

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:
  • result (dict) – Result from unmixing_multistart (carries a ‘multistart’ entry).

  • max_solutions (int) – Maximum number of distinct solutions to draw as small multiples (the best-fitting solutions are shown).

  • space (str) – ‘spectrum’ (dM/dlog10 B) or ‘curve’ (measurement space) for the decomposition panels.

  • n_grid (int) – Number of field points for the smooth model curves.

  • figsize (tuple, optional) – Figure size; a default is chosen from the panel count.

  • colors (list, optional) – Per-solution colors; defaults to the tab10 cycle.

  • marker_scale (str) – How the solution-map markers are sized: ‘uniform’ (default, all equal, so no solution is visually privileged), ‘n_hits’ (size scaled into a bounded range by the number of starts that reached each solution), or ‘weight’ (size scaled by Akaike weight). On low-noise data the Akaike weight collapses onto the lowest-RSS solution, so ‘uniform’ or ‘n_hits’ better reflect that the solutions are alternatives; ‘weight’ is informative mainly when the noise is large enough to spread support across solutions. The number of starts that reached each solution is annotated on the map in every case.

Returns:

(fig, axes).

Return type:

tuple

pmagpy.rockmag.plot_unmixing_posterior(result, quantity='B_mean_mT', bins=40, figsize=None, colors=None)[source]#

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:
  • result (dict) – Result from unmixing_bootstrap or unmix_coercivity_bayes.

  • quantity (str) – Name of the quantity to plot (e.g. ‘B_mean_mT’, ‘proportion’, ‘sd_log’, ‘location’, ‘dp’, ‘skew’). Must be present in the draws.

  • bins (int) – Number of histogram bins.

  • figsize (tuple, optional) – Figure size; defaults to (7, 2.2 * n_components).

  • colors (list, optional) – Per-component colors; defaults to the matplotlib C0, C1, … cycle.

Returns:

(fig, axes).

Return type:

tuple

pmagpy.rockmag.plot_unmixing_tradeoff(result, x='B_mean_mT', y='proportion', component=None, figsize=(5, 5), colors=None)[source]#

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:
  • result (dict) – Result from unmixing_bootstrap or unmix_coercivity_bayes.

  • x (str) – Quantity names for the two axes (e.g. ‘B_mean_mT’, ‘proportion’, ‘sd_log’).

  • y (str) – Quantity names for the two axes (e.g. ‘B_mean_mT’, ‘proportion’, ‘sd_log’).

  • component (int, optional) – 1-based component index to plot alone; if None, all components are overlaid.

  • figsize (tuple) – Figure size.

  • colors (list, optional) – Per-component colors.

Returns:

(fig, ax).

Return type:

tuple

pmagpy.rockmag.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')[source]#

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:
  • experiment (pandas.DataFrame) – MagIC-formatted experiment DataFrame (rows in measurement order).

  • temperature_column (str, optional) – Name of the temperature column (default ‘meas_temp’).

  • magnetic_column (str, optional) – Name of the magnetization/susceptibility column (default ‘susc_chi_mass’).

  • temp_unit ({'C', 'K'}, optional) – Unit for the returned temperatures (default ‘C’).

  • input_unit ({'K', 'C'}, optional) – Unit of the temperatures in experiment (default ‘K’, the MagIC convention for meas_temp).

  • smooth_window (float, optional) – Width of the smoothing window in units of temp_unit. If 0 (default), no smoothing is applied and the smoothed arrays equal the raw arrays.

  • remove_holder (bool, optional) – Subtract the per-branch minimum value from each branch (default True).

  • window_type ({'flat', 'hanning', 'hamming', 'bartlett', 'blackman'}, optional) –

    Weighting function applied within each smoothing window by smooth_moving_average (default ‘hanning’). Only used when smooth_window > 0. The options are:

    • ’flat’: uniform weights, i.e. a simple unweighted running mean.

    • ’hanning’: raised-cosine (Hann) taper; weights fall smoothly to zero at the window edges. A good general-purpose default that suppresses edge/ringing artifacts.

    • ’hamming’: raised-cosine taper similar to ‘hanning’ but with nonzero end weights, giving slightly less edge attenuation.

    • ’bartlett’: triangular taper; weights decrease linearly from the window center to zero at the edges.

    • ’blackman’: three-term cosine taper that is more strongly peaked than ‘hanning’/’hamming’, giving the heaviest smoothing (widest effective averaging) of the tapered options.

    All options other than ‘flat’ are the correspondingly named numpy window functions.

Returns:

{'heating': branch or None, 'cooling': branch or None} where each branch is a dict with keys 'T' and 'y' (smoothed arrays, ascending temperature) and 'raw_T' and 'raw_y' (unsmoothed arrays, ascending temperature). A branch with no measurements is None.

Return type:

dict

pmagpy.rockmag.process_backfield_data(experiment, field='treat_dc_field', magnetization='magn_mass', smooth_mode='lowess', smooth_frac=0.0, drop_first=False)[source]#

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:
  • experiment (DataFrame) – DataFrame containing the backfield data

  • field (str) – The name of the treatment field column in the DataFrame

  • magnetization (str) – The name of the magnetization column in the DataFrame

  • smooth_mode (str) – The smoothing mode to be used, either ‘lowess’ or ‘spline’

  • smooth_frac (float) – Fraction of the data to be used for LOWESS smoothing, value must be between 0 and 1

  • drop_first (bool) – Whether to drop the first data point or not in some cases you may want to drop the first data point to avoid negative log values

Returns:

The processed experiment DataFrame with new attributes.

Return type:

DataFrame

pmagpy.rockmag.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)[source]#

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:

  • a loop that is statistically linear (whole-loop lack-of-fit test) is dominated by paramagnetic or diamagnetic material; only the high-field susceptibility (from the whole-loop regression) is reported. Passing fit_linear_loop=True overrides this exit and processes the loop in full;

  • a loop that remains open at the highest fields (closure test) contains unsaturated high-coercivity phases, so Ms and chi_HF cannot be separated; the slope-independent parameters (Mr and Brh, computed from Mrh in which linear-in-field contributions cancel) and the data quality statistics are reported. Passing fit_open_loop=True overrides this exit and proceeds with the high-field fitting.

Parameters:
  • field (array_like) – Array of applied magnetic field values in tesla (the chi_HF unit conversions assume tesla; a warning is printed if the values appear to be in mT or Oe).

  • magnetization (array_like) – Array of magnetization values (same length as field), in any consistent unit; mass-normalized Am²/kg matches MagIC conventions.

  • specimen_name (str, optional) – Identifier for the specimen, used for labeling plots.

  • show_results_table (bool, optional) – If True (default), display a summary table of key parameters using Bokeh.

  • show_plot (bool, optional) – If True (default), display the Bokeh plot of the hysteresis loop and processing steps.

  • NL_fit (bool, optional) – If True, force non-linear high-field fitting regardless of the saturation test result (default is False). Because the approach-to-saturation fit exists precisely for unsaturated loops, NL_fit=True also proceeds through the open-loop exit (it implies fit_open_loop=True).

  • centering_protocol ({'legacy', 'iterative'}, optional) – Centering workflow to apply before drift and high-field corrections. Defaults to ‘legacy’ for backward compatibility.

  • fit_open_loop (bool, optional) – If True, proceed with the high-field fitting (and the Ms estimate) even when the closure test flags the loop as open. Default False: open loops exit with the slope-independent parameters and data quality statistics, since Ms and chi_HF cannot be separated for an unsaturated loop. NL_fit=True implies this behavior. Note that residual instrument drift can leave a spurious positive high-field Mrh signal that trips the closure test on a visually closed loop (particularly for loops measured from negative saturation); inspect the loop and pass fit_open_loop=True in such cases.

  • fit_linear_loop (bool, optional) – If True, process a statistically linear loop in full rather than terminating with chi_HF only (default False). Useful when a weak ferromagnetic signal near the noise level is of interest despite the loop passing the whole-loop linearity test; the ferromagnetic parameters from such a loop should be interpreted alongside the quality statistics.

Returns:

results –

Dictionary containing the following keys:
  • ’gridded_H’: gridded field values

  • ’gridded_M’: gridded magnetization values

  • ’linearity_test_results’: results of the initial linearity test

  • ’loop_is_linear’: whether the loop passes the linearity test

  • ’FNL’: F statistic for whole-loop nonlinearity (lack-of-fit F ratio)

  • ’loop_centering_results’: results of centering optimization

  • ’centered_H’: centered field values

  • ’centered_M’: centered magnetization values

  • ’drift_corrected_M’: drift-corrected magnetization

  • ’slope_corrected_M’: slope-corrected magnetization

  • ’loop_closure_test_results’: results of closure test

  • ’loop_is_closed’: whether the loop is closed

  • ’loop_saturation_stats’: saturation test results

  • ’loop_is_saturated’: whether the loop is saturated

  • ’M_sn’, ‘Q’: quality metrics from centering

  • ’H’, ‘Mr’, ‘Mrh’, ‘Mih’, ‘Me’, ‘Brh’: characteristic field and moment parameters

  • ’sigma’: shape parameter (Fabian, 2003)

  • ’chi_HF’: high-field susceptibility

  • ’FNL60’, ‘FNL70’, ‘FNL80’: high-field nonlinearity F statistics for windows starting at 60%, 70%, and 80% of the maximum field

  • ’Ms’: saturation magnetization

  • ’Bc’: coercive field

  • ’M_sn_f’, ‘Qf’: quality metrics for ferromagnetic component

  • ’Fnl_lin’: F statistic for improvement of the nonlinear over the linear high-field fit (None if the loop is saturated and no nonlinear fit is made)

  • ’plot’: Bokeh figure with overlaid processing steps

Return type:

dict

pmagpy.rockmag.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)[source]#

Process multiple hysteresis loops in batch.

Parameters:
  • hyst_experiments (DataFrame) – Must contain columns “experiment” and “specimen”.

  • measurements (DataFrame) – Must contain an “experiment” column and the data columns.

  • field_col (str, optional) – Name of the column in measurements holding field values. Defaults to “meas_field_dc”.

  • magn_col (str, optional) – Name of the column in measurements holding magnetization values. Defaults to “magn_mass”.

  • show_results_table (bool, optional) – If True, display the summary table below each plot.

  • show_plots (bool, optional) – If True, display the hysteresis plots for each specimen.

  • centering_protocol ({'legacy', 'iterative'}, optional) – Centering workflow to pass through to process_hyst_loop. Defaults to ‘legacy’ for backward compatibility.

  • fit_open_loop (bool, optional) – Passed through to process_hyst_loop: if True, high-field fitting proceeds even for loops the closure test flags as open (default False).

  • fit_linear_loop (bool, optional) – Passed through to process_hyst_loop: if True, statistically linear loops are processed in full rather than terminating with chi_HF only (default False).

Returns:

results_df – DataFrame with hysteresis results for each experiment. Has a numeric index with ‘specimen’ and ‘experiment’ as columns.

Return type:

pandas.DataFrame

pmagpy.rockmag.prorated_drift_correction(field, magnetization, descending_first=True)[source]#
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:
  • field (numpy array) – field values, in canonical (descending-upper-branch-first) order

  • magnetization (numpy array) – magnetization values

  • descending_first (bool, optional) – Whether the loop was originally measured with the descending branch first (default True). Use measured_descending_first on the raw field values to determine this for a gridded loop.

Returns:

corrected_magnetization – corrected magnetization values

Return type:

numpy array

pmagpy.rockmag.register_unmixing_method(name, function)[source]#

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:
  • name (str) – Name under which the method is registered.

  • function (callable) – The method implementation.

Return type:

None

pmagpy.rockmag.sanitize_hyst_inputs(field, magnetization, drop_nonfinite=True)[source]#

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:
  • field (array_like) – Applied field values. Expected in tesla: the chi_HF unit conversions in linear_HF_fit, hyst_slope_correction, and the nonlinear fits assume tesla, so a warning is printed if the values appear to be in mT or Oe (max |field| > 20).

  • magnetization (array_like) – Magnetization or moment values, in any unit that is consistent across the loop (mass-normalized Am²/kg matches MagIC conventions).

  • drop_nonfinite (bool, optional) – If True (default), measurement pairs where either value is NaN or infinite are dropped with a printed report. If False, a ValueError is raised when non-finite values are present.

Returns:

field, magnetization – Equal-length float arrays with only finite values.

Return type:

numpy.ndarray

pmagpy.rockmag.select_n_components(x, magnetization, method='spectrum', 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=True, verbose=False, **kwargs)[source]#

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:

  • ‘parsimony’ (default): an added component is retained only if it reduces the residual sum of squares by at least min_improvement times the baseline (single-component) residual. Because the second component typically removes most of the baseline misfit while a spurious third component removes only a tiny fraction of it, this robustly stops at the mineralogically meaningful count regardless of the noise level.

  • ‘chi2’: the simplest model whose reduced chi-square (using noise_level, estimated with estimate_measurement_noise if not given) falls at or below reduced_chi2_target, i.e. the simplest model that fits to within the measurement noise. The noise estimator is spacing-aware and unbiased on the coarse, log-spaced field grids of backfield/IRM data, but ‘chi2’ remains the less robust criterion: like the information criteria and the Bayesian evidence it tends to over-select on high-resolution, low-noise curves (once the noise is not over-estimated, any small departure of the data from a log-Gaussian pushes the reduced chi-square of a real-count model just above one), and it is sensitive to the residual scatter of the noise estimate. Prefer ‘parsimony’, or supply a trusted noise_level and a reduced_chi2_target slightly above 1, when using it. For spectrum-space methods (‘spectrum’, ‘maxunmix’, or a Bayesian fit with space=’spectrum’) the residuals and hence the noise are in dM/dlog10(B) units, so the noise is estimated on the finite-difference spectrum rather than the measured curve; that spectrum noise is mildly correlated, which the estimator does not model, making the spectrum-space chi2 more approximate still.

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:
  • x (array-like) – log10 of field values (mT).

  • magnetization (array-like) – Remanence curve values at x.

  • method (str) – Registered unmixing method used for each fit (default DEFAULT_UNMIX_METHOD, i.e. ‘spectrum’).

  • min_components (int) – Range of component counts to consider.

  • max_components (int) – Range of component counts to consider.

  • criterion (str) – ‘parsimony’ or ‘chi2’.

  • min_improvement (float) – For ‘parsimony’: minimum fraction of the baseline residual an added component must explain to be retained (default 0.02).

  • noise_level (float, optional) – Measurement noise standard deviation for ‘chi2’; estimated from the data if not given.

  • reduced_chi2_target (float) – For ‘chi2’: the reduced chi-square at or below which a model is considered adequate (default 1.0).

  • curve_type (str) – ‘backfield’ or ‘acquisition’.

  • vary_skew (bool) – Whether skew varies during fitting.

  • verbose (bool) – Print the selection outcome.

  • **kwargs – Passed to the unmixing method.

Returns:

(selected_n, table, results) where selected_n is the chosen number of components, table is a DataFrame of per-model statistics (with a boolean ‘selected’ column), and results maps component count -> result dictionary.

Return type:

tuple

pmagpy.rockmag.skewnormal_cdf(x, location, dp, skew=0.0)[source]#

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:
  • x (array-like) – Points at which to evaluate the CDF (log10 of field in mT).

  • location (float) – Location parameter (log10 mT).

  • dp (float) – Scale parameter (log10 units); must be positive.

  • skew (float) – Shape parameter alpha (default 0).

Returns:

CDF values between 0 and 1.

Return type:

numpy.ndarray

pmagpy.rockmag.skewnormal_pdf(x, location, dp, skew=0.0)[source]#

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:
  • x (array-like) – Points at which to evaluate the density (log10 of field in mT).

  • location (float) – Location parameter (log10 mT). Equal to the mean only when skew = 0.

  • dp (float) – Scale parameter (log10 units); must be positive. Equal to the standard deviation only when skew = 0.

  • skew (float) – Shape parameter alpha of the Azzalini skew-normal (default 0).

Returns:

Density values with unit integrated area.

Return type:

numpy.ndarray

pmagpy.rockmag.skewnormal_stats(location, dp, skew=0.0)[source]#

Moments and characteristic points of a skew-normal distribution.

Parameters:
  • location (float) – Location parameter (log10 mT).

  • dp (float) – Scale parameter (log10 units).

  • skew (float) – Shape parameter alpha.

Returns:

With keys ‘mean’, ‘std’, ‘median’, and ‘mode’, all in the same (log10) units as location and dp. For skew = 0 all of mean, median, and mode equal location and std equals dp.

Return type:

dict

pmagpy.rockmag.smooth_moving_average(x, y, x_window, window_type='hanning', pad_mode='edge', return_variance=False)[source]#

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:

(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.

Return type:

tuple

pmagpy.rockmag.specimen_experiment_selection_interactive(measurements)[source]#

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

Parameters:

measurements (pd.DataFrame) – DataFrame containing measurement data with at least two columns: ‘specimen’ and ‘experiment’. The ‘specimen’ column holds the specimen names while the ‘experiment’ column holds the experiment identifiers associated with each specimen.

Returns:

A tuple containing two dropdown widgets. The first widget allows for selecting a specimen, and the second widget allows for selecting an experiment associated with the chosen specimen. The experiment dropdown is dynamically updated based on the specimen selection.

Return type:

tuple of ipywidgets.Dropdown

pmagpy.rockmag.specimen_selection_interactive(measurements)[source]#

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

Parameters:

measurements (pd.DataFrame) – The DataFrame containing measurement data with a column ‘specimen’. It is expected to have at least this column where ‘specimen’ identifies the specimen name.

Returns:

A dropdown widget allowing for the selection of a specimen. The initial selection in the dropdown is set to the first specimen option.

Return type:

ipywidgets.Dropdown

pmagpy.rockmag.split_heating_cooling(experiment, temperature_column='meas_temp', magnetic_column='susc_chi_mass')[source]#

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:
  • experiment (pandas.DataFrame) – the experiment data (rows in measurement order)

  • temperature_column (str, optional) – name of the temperature column (default ‘meas_temp’)

  • magnetic_column (str, optional) – name of the magnetization/susceptibility column (default ‘susc_chi_mass’)

Returns:

  • warm_T (numpy.ndarray) – temperatures for the heating cycle (measurement order)

  • warm_X (numpy.ndarray) – magnetization/susceptibility for the heating cycle

  • cool_T (numpy.ndarray) – temperatures for the cooling cycle (measurement order)

  • cool_X (numpy.ndarray) – magnetization/susceptibility for the cooling cycle

pmagpy.rockmag.split_hyst_loop(field, magnetization)[source]#
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:
  • field (numpy array or list) – hysteresis loop field values

  • magnetization (numpy array or list) – hysteresis loop magnetization values

Returns:

  • upper_branch (list) – [field, magnetization] for the upper branch, in ascending field order

  • lower_branch (list) – [field, magnetization] for the lower branch, in ascending field order

pmagpy.rockmag.symmetric_averaging_drift_correction(field, magnetization)[source]#

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:
  • field (array_like) – Array of applied magnetic field values for the hysteresis loop.

  • magnetization (array_like) – Array of measured magnetization values corresponding to field.

Returns:

corrected_magnetization – Array of drift-corrected magnetization values, symmetrically constructed for the full loop.

Return type:

numpy.ndarray

Examples

>>> field = np.linspace(-1, 1, 200)
>>> magnetization = some_hysteresis_measurement(field)
>>> corrected = symmetric_averaging_drift_correction(field, magnetization)
pmagpy.rockmag.thermomag_derivative(temps, mags, drop_first=False, drop_last=False)[source]#

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:

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.

Return type:

pd.DataFrame

pmagpy.rockmag.unmix_backfield_curve(x, magnetization, n_components=None, initial_parameters=None, curve_type='backfield', vary_skew=True, fit_offset=True, weights=None, dp_bounds=(0.01, 2.0), skew_bounds=(-10.0, 10.0))[source]#

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:
  • x (array-like) – log10 of field values (mT).

  • magnetization (array-like) – Remanence curve values at x (shifted positive for backfield data).

  • n_components (int, optional) – Number of components. Required if initial_parameters is None.

  • initial_parameters (pandas.DataFrame, optional) – Initial guesses (see unmix_coercivity_spectrum). If None, automatic estimates are derived from the finite-difference spectrum.

  • curve_type (str) – ‘backfield’ (decaying curve) or ‘acquisition’ (growing curve).

  • vary_skew (bool) – If False, skew values are fixed at their initial values.

  • fit_offset (bool) – Whether to fit a constant baseline offset (default True).

  • weights (array-like, optional) – Multiplicative weights applied to the residuals.

  • dp_bounds (tuple) – Bounds as in unmix_coercivity_spectrum.

  • skew_bounds (tuple) – Bounds as in unmix_coercivity_spectrum.

Returns:

Standardized result dictionary (see unmix_coercivity_spectrum), additionally including the fitted ‘offset’ and ‘se_offset’.

Return type:

dict

pmagpy.rockmag.unmix_backfield_experiments(measurements, experiments=None, n_components=2, method='spectrum', initial_parameters=None, vary_skew=True, 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)[source]#

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:
  • measurements (pandas.DataFrame) – MagIC measurements table (must include ‘experiment’, ‘specimen’, ‘method_codes’, and the field/magnetization columns).

  • experiments (list, optional) – Experiment names to process. Defaults to all experiments whose method_codes include ‘LP-BCR-BF’.

  • n_components (int) – Number of components fit to each experiment (default 2).

  • method (str) – Registered unmixing method name: ‘spectrum’, ‘curve’, ‘maxunmix’, or a custom method added with register_unmixing_method.

  • initial_parameters (pandas.DataFrame or dict, optional) – Either a single initial-parameter table applied to every experiment, or a dict mapping experiment name -> table. Experiments missing from the dict fall back to automatic estimation.

  • vary_skew (bool) – Whether skew parameters vary during fitting.

  • n_boot (int) – If > 0, ensure each result carries a bootstrap with this many replicates (methods that bootstrap internally, like ‘maxunmix’, are not re-bootstrapped).

  • resample (see unmixing_bootstrap.)

  • proportion (see unmixing_bootstrap.)

  • noise_level (see unmixing_bootstrap.)

  • smooth_mode (see process_backfield_data.) – The defaults (spline with smooth_frac=0) leave the data unsmoothed.

  • smooth_frac (see process_backfield_data.) – The defaults (spline with smooth_frac=0) leave the data unsmoothed.

  • drop_first (see process_backfield_data.) – The defaults (spline with smooth_frac=0) leave the data unsmoothed.

  • field (str) – Column names in the measurements table.

  • magnetization (str) – Column names in the measurements table.

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible bootstraps.

  • verbose (bool) – Print progress and failures.

  • **method_kwargs – Additional keyword arguments passed to the unmixing method.

Returns:

(components_df, results) where components_df is a tidy DataFrame with one row per experiment and component (parameters, derived coercivities, uncertainties, fit statistics, and Bcr) and results is a dict mapping experiment name -> full result dictionary.

Return type:

tuple

pmagpy.rockmag.unmix_coercivity(x, magnetization, method='spectrum', n_components=None, initial_parameters=None, curve_type='backfield', vary_skew=True, **kwargs)[source]#

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:

  • ‘spectrum’: fits the finite-difference coercivity spectrum dM/dlog10(B) with skew-normal components (Kruiver et al., 2001; Egli, 2003 lineage). Point estimates only; combine with unmixing_bootstrap for uncertainties.

  • ‘curve’: fits the measured curve directly with cumulative (CDF) components, avoiding numerical differentiation entirely.

  • ‘maxunmix’: the ‘spectrum’ fit plus the MAX UnMix resampling uncertainty scheme (Maxbauer et al., 2016): 95% case resampling with 2% noise, 100 replicates by default.

Parameters:
  • x (array-like) – log10 of field values (mT), e.g. ‘log_dc_field’ from process_backfield_data.

  • magnetization (array-like) – Remanence curve values at x (e.g. ‘magn_mass_shift’).

  • method (str) – Name of a registered unmixing method (default ‘spectrum’).

  • n_components (int, optional) – Number of components (required if initial_parameters is None).

  • initial_parameters (pandas.DataFrame, optional) – Initial guesses with columns ‘contribution’, ‘location’, ‘dp’, ‘skew’; automatic estimates are used when omitted.

  • curve_type (str) – ‘backfield’ or ‘acquisition’.

  • vary_skew (bool) – Whether skew parameters vary during fitting.

  • **kwargs – Passed through to the method implementation (e.g. n_boot, proportion, param_noise for ‘maxunmix’; fit_offset for ‘curve’; dp_bounds, skew_bounds for the spectrum-based methods).

Returns:

Standardized result dictionary (see unmix_coercivity_spectrum).

Return type:

dict

pmagpy.rockmag.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)[source]#

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):

  • space=’curve’ (default): the measured curve M(B) is fit directly with cumulative skew-normal components plus a constant offset. An independent Gaussian noise model is defensible here, and no numerical differentiation is required. This is the more conservative choice.

  • space=’spectrum’: the finite-difference coercivity spectrum dM/dlog10(B) is fit with skew-normal densities (no offset). Fitting the derivative directly reproduces the coercivity-distribution peak that a curve fit can under-represent, and lets skewness be constrained by the peak shape. The trade-off is that differencing correlates adjacent points, so the i.i.d. Gaussian likelihood used here is an approximation (the same one the least-squares and MAX UnMix spectrum fits make); credible intervals in this space should be read with that caveat.

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:
  • x (array-like) – log10 of field values (mT).

  • magnetization (array-like) – Remanence curve values at x (e.g. ‘magn_mass_shift’).

  • n_components (int) – Number of components (default 2).

  • curve_type (str) – ‘backfield’ or ‘acquisition’.

  • space (str) – ‘curve’ (fit the measured curve, default) or ‘spectrum’ (fit the finite-difference dM/dlog10(B) spectrum). See the summary above for the trade-offs; with space=’spectrum’ the offset is not used.

  • vary_skew (bool) – Sample component skew (uniform prior on [-10, 10]); default False (symmetric log-Gaussian components). This deliberately deviates from DEFAULT_UNMIX_VARY_SKEW: free skew multiplies the nested-sampling cost and is usually better constrained through explicit priors windows (e.g. from mineral_priors) than left fully free.

  • fit_offset (bool) – Include a constant baseline offset (default True; ignored when space=’spectrum’).

  • priors (dict, optional) – Overrides for the default prior bounds. Recognized keys: ‘mean’, ‘location’, ‘dp’, ‘contribution’, ‘skew’ map to a list of (low, high) tuples, one per component (in log10 units for ‘mean’/’location’/’dp’, magnetization units for ‘contribution’); ‘offset’ and ‘noise’ map to a single (low, high) tuple in magnetization units. A ‘mean’ window constrains each component’s MEAN coercivity (log10 mT): the mean is sampled uniformly in the window and the skew-normal location is derived from the sampled dp and skew, so the window means what it says even for skewed components (this is what mineral_priors produces). A ‘location’ window instead constrains the raw location parameter directly. Either replaces the weakly-informative ordered-uniform default, so the windows should be non-overlapping or ordered to keep component labels meaningful. ‘mean’ takes precedence over ‘location’ if both are given.

  • nlive (int) – Number of live points (default 250).

  • dlogz (float) – Evidence convergence tolerance (default 0.1).

  • sample (str) – dynesty sampling method (default ‘rslice’). Slice sampling is robust to the thin, curved likelihood ridges that overlapping components produce; the dynesty default uniform-ellipsoid sampler can stall on such geometries.

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducibility.

  • n_grid (int) – Grid size for posterior model bands.

  • n_posterior_curves (int) – Number of posterior draws used for the model bands (default 300).

  • verbose (bool) – Show dynesty progress.

Returns:

Standardized result dictionary (parameters set to posterior medians) with an added ‘bayes’ entry containing ‘param_summary’ (per-component posterior mean/std/percentiles, same format as the bootstrap summary), ‘samples’ (equally weighted posterior draws for every parameter and derived quantity), ‘logz’, ‘logzerr’, ‘noise’ (posterior median noise standard deviation), and ‘curves’ (posterior percentile bands of the model).

Return type:

dict

pmagpy.rockmag.unmix_coercivity_spectrum(x, spectrum, n_components=None, initial_parameters=None, vary_skew=True, weights=None, dp_bounds=(0.01, 2.0), skew_bounds=(-10.0, 10.0))[source]#

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:
  • x (array-like) – log10 of field values (mT), e.g. midpoints from coercivity_spectrum_from_curve.

  • spectrum (array-like) – Coercivity spectrum values at x (magnetization per decade).

  • n_components (int, optional) – Number of components. Required if initial_parameters is None.

  • initial_parameters (pandas.DataFrame, optional) – Initial guesses with columns ‘contribution’, ‘location’, ‘dp’, ‘skew’ (one row per component). If None, automatic estimates from estimate_coercivity_components are used.

  • vary_skew (bool) – If False, skew values are fixed at their initial values (default 0, i.e. symmetric log-Gaussian components).

  • weights (array-like, optional) – Multiplicative weights applied to the residuals.

  • dp_bounds (tuple) – (min, max) bounds on the dp scale parameter in log10 units.

  • skew_bounds (tuple) – (min, max) bounds on the skew shape parameter.

Returns:

Standardized result dictionary with keys including ‘params’ (a DataFrame of fitted parameters, linearized standard errors, and derived quantities such as B_mean_mT and proportion), ‘y_fit’, ‘residuals’, ‘stats’ (rss, r_squared, aic, bic, …), ‘success’, and ‘initial_parameters’.

Return type:

dict

pmagpy.rockmag.unmixing_bootstrap(result, n_boot=500, resample='cases', proportion=1.0, noise_level=None, random_seed=None, n_grid=200, verbose=False)[source]#

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:

  • ‘cases’: data points are drawn with replacement (‘proportion’ controls the resample size relative to the data). With proportion=0.95 and noise_level=0.02 this emulates the resampling scheme of the MAX UnMix program (Maxbauer et al., 2016).

  • ‘residuals’: the best-fit curve is perturbed with resampled fit residuals, preserving the field spacing of the original data.

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:
  • result (dict) – Result from unmix_coercivity_spectrum or unmix_backfield_curve.

  • n_boot (int) – Number of bootstrap replicates (default 500).

  • resample (str) – ‘cases’ or ‘residuals’.

  • proportion (float) – Fraction of the data resampled per replicate for ‘cases’ (default 1).

  • noise_level (float, optional) – If given, multiplicative Gaussian noise with this relative standard deviation is added to each resampled dataset (MAX UnMix uses 0.02).

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducibility.

  • n_grid (int) – Number of grid points for the model-curve confidence bands.

  • verbose (bool) – Print a progress summary.

Returns:

A copy of the input result with an added ‘bootstrap’ entry containing ‘param_summary’ (per-component mean/std/percentiles for each parameter and derived quantity), ‘curves’ (percentile bands of the total and per-component model on ‘x_grid’), ‘n_success’, and ‘param_samples’ (the raw bootstrap parameter arrays).

Return type:

dict

pmagpy.rockmag.unmixing_multistart(x, magnetization, method='spectrum', n_components=2, n_starts=100, vary_skew=True, curve_type='backfield', random_seed=None, location_tolerance=0.1, proportion_tolerance=0.05, verbose=False, **kwargs)[source]#

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:
  • x (array-like) – log10 of field values (mT).

  • magnetization (array-like) – Remanence curve values at x (e.g. ‘magn_mass_shift’).

  • method (str) – Registered unmixing method used for each fit (default DEFAULT_UNMIX_METHOD, i.e. ‘spectrum’).

  • n_components (int) – Number of components (default 2).

  • n_starts (int) – Number of random initializations (default 100).

  • vary_skew (bool) – Whether skew varies during fitting; random starts draw skew from [-5, 5] when True.

  • curve_type (str) – ‘backfield’ or ‘acquisition’.

  • random_seed (None, int, or numpy.random.Generator) – Seed for reproducible starting points.

  • location_tolerance (float) – Two solutions are considered the same when all component locations agree within this tolerance (log10 units, default 0.1) and all proportions agree within proportion_tolerance.

  • proportion_tolerance (float) – Proportion agreement tolerance (default 0.05).

  • verbose (bool) – Print a summary of the distinct solutions.

  • **kwargs – Passed through to the unmixing method.

Returns:

The best (lowest RSS) result dictionary, augmented with a ‘multistart’ entry containing ‘solutions’ (a DataFrame with one row per distinct solution: n_hits, rss, r_squared, aic, delta_aic, akaike_weight, and per-component B_mean_mT / sd_log / proportion columns), ‘results’ (the representative result dictionary for each solution, in the same order), ‘n_starts’, and ‘n_converged’.

Return type:

dict

pmagpy.rockmag.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)[source]#

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:
  • temps (pd.Series) – Series representing the temperatures at which magnetization measurements were taken.

  • mags (pd.Series) – Series representing the magnetization measurements.

  • t_range_background_min (int or float, optional) – Minimum temperature for the background fitting range. Default is 50.

  • t_range_background_max (int or float, optional) – Maximum temperature for the background fitting range. Default is 250.

  • excluded_t_min (int or float, optional) – Minimum temperature to exclude from the background fitting range. Default is 75.

  • excluded_t_max (int or float, optional) – Maximum temperature to exclude from the background fitting range. Default is 150.

  • poly_deg (int, optional) – Degree of the polynomial for background fitting. Default is 3.

  • plot_zero_crossing (bool, optional) – If True, plots the zero-crossing of the second derivative. Default is False.

  • plot_title (str, optional) – Title for the plot. Default is None.

  • measurement_marker (str, optional) – Marker symbol for measurement data. Default is ‘o’.

  • measurement_color (str, optional) – Color for measurement data. Default is ‘black’.

  • background_fit_marker (str, optional) – Marker symbol for background fit data. Default is ‘s’.

  • background_fit_color (str, optional) – Color for background fit data. Default is ‘C1’.

  • magnetite_marker (str, optional) – Marker symbol for magnetite data. Default is ‘d’.

  • magnetite_color (str, optional) – Color for magnetite data. Default is ‘C0’.

  • 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.

  • markersize (float, optional) – Size of the markers. Default is 3.5.

Returns:

  • verwey_estimate (float) – Estimated Verwey transition temperature.

  • remanence_loss (float) – Estimated remanence loss.

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)
pmagpy.rockmag.verwey_estimate_interactive(measurements, specimen, method, figsize=(11, 5))[source]#

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:
  • measurements (pandas.DataFrame) – low temperature remanence measurement data containing temperature and magnetization columns for multiple specimens.

  • specimen (str or ipywidgets.Dropdown) – Specimen to analyze, given either as a plain specimen name or as a selection widget (e.g. from verwey_specimen_method_selection_interactive); for a widget the current .value is read when this function runs, so rerun the cell after changing the dropdown.

  • method (str or ipywidgets.Dropdown) – Measurement method (‘LP-FC’ or ‘LP-ZFC’), as a plain string or a selection widget.

  • figsize (tuple of (float, float), optional) – Size of the matplotlib figure, by default (11, 5).

Notes

  • The function uses ipywidgets for interactive controls and matplotlib for visualization.

  • The background fit and excluded temperature ranges can be adjusted using sliders.

  • The polynomial degree of the background fit is also adjustable.

  • A reset button restores the default slider values.

  • The function relies on supporting functions such as extract_mpms_data_dc, thermomag_derivative, and calc_verwey_estimate.

Returns:

This function is intended for use in Jupyter notebooks or environments that support interactive widgets and inline plotting. It displays interactive sliders and plots but does not return a value.

Return type:

None

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.
pmagpy.rockmag.verwey_estimate_multiple_specimens(specimens_with_params, measurements)[source]#

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:
  • specimens_with_params (list of dict) –

    List of specimen dictionaries. Each dictionary should contain:
    • ’specimen_name’ : str The name of the specimen.

    • ’params’ : dict Dictionary containing:

      • ’t_range_background_min’ : int or float

      • ’t_range_background_max’ : int or float

      • ’excluded_t_min’ : int or float

      • ’excluded_t_max’ : int or float

      • ’poly_deg’ : int

      • ’method_codes’ : str Colon-delimited string that must include either “LP-FC” or “LP-ZFC”.

  • measurements (object) – Measurements dataframe in MagIC format.

Returns:

DataFrame containing the Verwey transition estimates and the input parameters for each specimen. Columns include:

  • ’specimen’

  • ’critical_temp’

  • ’critical_temp_type’

  • ’remanence_loss’

plus the additional parameters from the input.

Return type:

pd.DataFrame

Raises:
  • ValueError – If neither “LP-FC” nor “LP-ZFC” is found in the method_codes for a specimen.

  • Exception – Propagates exceptions raised during data extraction or analysis.

pmagpy.rockmag.verwey_specimen_method_selection_interactive(measurements)[source]#

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:

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.

Return type:

tuple

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.

pmagpy.rockmag.zero_crossing(dM_dT_temps, dM_dT, make_plot=False, xlim=None, verwey_marker='*', verwey_color='Pink', verwey_size=10)[source]#

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:

The estimated temperature at which the second derivative of magnetization

with respect to temperature crosses zero.

Return type:

float

Note

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