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

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

Estimate the Verwey transition temperature

This notebook demonstrates how to estimate the temperature of the Verwey transition from remanence upon warming curves developed through MPMS experiments.

Import scientific python libraries

Run the cell below to import the functions needed for the notebook.

import pmagpy.rockmag as rmag
import pmagpy.contribution_builder as cb
import pmagpy.ipmag as ipmag
import pmagpy.pmag as pmag
import matplotlib.pyplot as plt
import pandas as pd
pd.set_option('display.max_columns', 500)

%config InlineBackend.figure_format = 'retina'

Import data

We can take the same approach as in the rockmag_data_unpack.ipynb notebook to bring the MagIC data into the notebook as a Contribution. To bring in a different contribution, set the directory path (currently '../example_data/ECMB') and the name of the file (currently 'magic_contribution_20213.txt') to be those relevant to your data.

# set the dir_path to the directory where the measurements.txt file is located
dir_path = '../example_data/ECMB'

# set the name of the MagIC file
ipmag.unpack_magic('magic_contribution_20213.txt', 
                     dir_path = dir_path,
                     input_dir_path = dir_path,
                     print_progress=False)

# create a contribution object from the tables in the directory
contribution = cb.Contribution(dir_path)
measurements = contribution.tables['measurements'].df
1  records written to file  /Users/penokean/0000_GitHub/RockmagPy-notebooks/example_data/ECMB/contribution.txt
1  records written to file  /Users/penokean/0000_GitHub/RockmagPy-notebooks/example_data/ECMB/locations.txt
90  records written to file  /Users/penokean/0000_GitHub/RockmagPy-notebooks/example_data/ECMB/sites.txt
312  records written to file  /Users/penokean/0000_GitHub/RockmagPy-notebooks/example_data/ECMB/samples.txt
1574  records written to file  /Users/penokean/0000_GitHub/RockmagPy-notebooks/example_data/ECMB/specimens.txt
17428  records written to file  /Users/penokean/0000_GitHub/RockmagPy-notebooks/example_data/ECMB/measurements.txt
-I- Using online data model
-I- Getting method codes from earthref.org
-I- Importing controlled vocabularies from https://earthref.org

Background on the Verwey transition

The example data used here was collected from mafic dikes in the East Central Minnesota batholith and the specimens exhibit a significant loss of remanence across the Verwey transition. The Verwey transition as defined by Jackson and Moskowitz (2020) is:

The Verwey transition is a reorganization of the magnetite crystal structure occurring at a temperature TV in the range 80–125 K, where the room-temperature cubic inverse-spinel structure transforms to a monoclinic arrangement, and many physical properties of the mineral (e.g. electrical resistivity, heat capacity, magnetic susceptibility, remanence and coercivity) change significantly.

It is of interest to determine the Verwey transition temperature (TV) as it is highly sensitive to changes in magnetite stoichiometry associated with cation substitution or oxidation.

Estimating the Verwey transition temperature

It is preferable to estimate the temperature of the Verwey transition (TV) associated with warming curves (e.g. the FC/ZFC data) than cooling curves. The rationale is that cooling curves also pass through the isotropic point at a temperature of ∼130 K prior to going through the Verwey transition. The loss of magnetization associated with going through the isotropic point can be very large (particularly for multidomain magnetites) which can obscure the Verwey transition (Jackson and Moskowitz, 2020).

We can apply the method described in Jackson and Moskowitz (2020) to estimate the temperature of the Verwey transition. In this method,

[This approach] assumes that the loss of remanence on warming is due to the superposition of (1) progressive unblocking over the 20–300 K temperature range [e.g. due to the transition from the stable single-domain (SSD) to the superparamagnetic (SP) state in nanoparticle populations of magnetite or other magnetic phases] and (2) domain reorganization and intraparticle remanence rotation in a discrete temperature window around TV, due to the monoclinic-to-cubic transformation in magnetite.

The method to estimate the temperature of the Verwey transition of Jackson and Moskowitz (2020) is to fit the derivative of the data outside of the Verwey transition and then subtract that fit from the derivative. This approach seeks to isolate the signal that is due to the Verwey transition. The peak of the derivative curve can then be used to estimate TV. This is done as the interpolated zero-crossing of the derivative of the spectrum curve.

In the code cell below, we define the temperature and magnetization values that will be used for estimating TV. The following parameters can be adjusted:

  • t_range_background_min and t_range_background_max: The temperature range over which the polynomial fit is applied to the background

  • excluded_t_min and excluded_t_max: The temperature range that is excluded from the background fit due to remanence loss associated with the Verwey transition.

  • poly_deg: the degree of the polynomial fit that is made to the background. Following Jackson and Moskowitz (2020), the default is set to be 3 (cubic).

As described in Jackson and Moskowitz (2020), these temperature ranges and polynomial degree can be adjusted to obtain ‘reasonable’ looking curves for the magnetite demagnetization and the progressive unblocking. The goal is for curves that are monotonic and fits that are within the measurement noise, while seeking to minimize the polynomial degree.

Interactively fit the Verwey transition

First we need to pick the specimen and the experiment (FC or ZFC curve) to analyze.

specimen_dropdown, method_dropdown = rmag.verwey_specimen_method_selection_interactive(measurements)
Loading...

Once a sample is selected, we can estimate the Verwey transition using the method described above. Adjust the sliders to change the range of the background that is being fit, the temperature range that is being excluded from the background fit, and the polynomial degree that is being used for the background fit.

Note: if you change the specimen or method in the dropdown menus above, rerun the code in the cell below to do the fit for the new specimen.

%matplotlib widget
rmag.verwey_estimate_interactive(measurements, specimen_dropdown, method_dropdown)
Loading...
Loading...
plt.close('all')
%matplotlib inline

Use the rmag.verwey_estimate function

The fit explored interactively above can be reproduced in scriptable form with the rmag.verwey_estimate function (the widget is built on the same underlying fitting routine, rmag.calc_verwey_estimate). Rather than adjusting values with the interactive widgets, the parameters are specified and passed to the function — which also makes the analysis reproducible. This approach is being taken in the code cell below.

specimen_name = 'NED2-8c'
fc_data, zfc_data, rtsirm_cool_data, rtsirm_warm_data = rmag.extract_mpms_data_dc(measurements, specimen_name)
temps = fc_data['meas_temp']
mags = fc_data['magn_mass']

#Enter the minimum temperature for the background fit
t_range_background_min = 55 

#Enter the maximum temperature for the background fit
t_range_background_max = 250 

#Enter the minimum temperature to exclude from the background fit
excluded_t_min = 75 

#Enter the maximum temperature to exclude from the background fit
excluded_t_max = 150 

#The polynomial degree for the background fit can be adjusted (default is 3)
poly_deg = 3

verwey_estimate, remanence_loss = rmag.verwey_estimate(temps, mags, 
                                       t_range_background_min,
                                       t_range_background_max,
                                       excluded_t_min,
                                       excluded_t_max,
                                       poly_deg)
<Figure size 1200x500 with 2 Axes>

Plot the second derivative curve

The estimate of the Verwey transition calculated above uses second derivative and calculates where the second derivative crosses zero by interpolating from the points on either side of the peak in the first derivative. This calculation can be visualized by setting the parameter plot_zero_crossing = True which generates an additional plot.

specimen_name = 'NED4-1c'
fc_data, zfc_data, rtsirm_cool_data, rtsirm_warm_data = rmag.extract_mpms_data_dc(measurements, specimen_name)
temps = fc_data['meas_temp']
mags = fc_data['magn_mass']

verwey_estimate, remanence_loss = rmag.verwey_estimate(temps, mags, 
                                       t_range_background_min=60,
                                       t_range_background_max=250,
                                       excluded_t_min=75,
                                       excluded_t_max=150,
                                       poly_deg=3,
                                       plot_zero_crossing = True)
<Figure size 1200x500 with 2 Axes>
<Figure size 1200x400 with 1 Axes>

Determine and record the Verwey temperatures for multiple specimens

There are three specimens with LT-SIRM data. Let’s plot the data for each specimen and estimate the Verwey temperature for each. We want to be able to record all of the parameters along with the estimated Verwey transition.

We will take the following approach:

  • define a list of dictionaries each containing the specimen name and its parameters for the fit (more specimens could be added by making additional dictionaries within the list). (Note that if you use the ZFC experiment rather than the FC, the method code should be changed to LP-ZFC. SM-1DMAX denotes that the peak of the first derivative was used to make the fit).

  • go through each specimen and make the fit using the rmag.verwey_estimate() function while recording the parameters and the estimated temperature.

  • make the recorded parameters into a Dataframe

# Define a list of dictionaries, each containing the specimen name and its unique parameters
specimens_with_params = [
    {
        'specimen_name': 'NED18-2c',
        'params': {
            't_range_background_min': 60,
            't_range_background_max': 250,
            'excluded_t_min': 75,
            'excluded_t_max': 150,
            'poly_deg': 3,
            'method_codes': 'SM-1DMAX:LP-FC'
        }
    },
    {
        'specimen_name': 'NED2-8c',
        'params': {
            't_range_background_min': 60,
            't_range_background_max': 260,
            'excluded_t_min': 75,
            'excluded_t_max': 150,
            'poly_deg': 3,
            'method_codes': 'SM-1DMAX:LP-FC'
        }
    },
    {
        'specimen_name': 'NED4-1c',
        'params': {
            't_range_background_min': 60,
            't_range_background_max': 260,
            'excluded_t_min': 75,
            'excluded_t_max': 150,
            'poly_deg': 3,
            'method_codes': 'SM-1DMAX:LP-FC'
        }
    }
]

# Initialize an empty list to store Verwey transition estimates along with parameters
verwey_estimates_and_params = []

# Process each specimen with its unique parameters
for specimen in specimens_with_params:
    specimen_name = specimen['specimen_name']
    params = specimen['params']
    
    fc_data, zfc_data, rtsirm_cool_data, rtsirm_warm_data = rmag.extract_mpms_data_dc(measurements, specimen_name)
    temps = fc_data['meas_temp']
    mags = fc_data['magn_mass']
    
    verwey_estimate, rem_loss = rmag.verwey_estimate(temps, mags, 
                                           t_range_background_min=params['t_range_background_min'],
                                           t_range_background_max=params['t_range_background_max'],
                                           excluded_t_min=params['excluded_t_min'],
                                           excluded_t_max=params['excluded_t_max'],
                                           poly_deg=params['poly_deg'],
                                           plot_title=specimen_name)
    # Append the specimen name, Verwey estimate, and all parameters to the list
    record = {'specimen': specimen_name, 'critical_temp': verwey_estimate, 
              'critical_temp_type': 'Verwey'}
    record.update(params)  # Merge the parameters with the record
    verwey_estimates_and_params.append(record)
    
verwey_estimates = pd.DataFrame(verwey_estimates_and_params)
<Figure size 1200x500 with 2 Axes>
<Figure size 1200x500 with 2 Axes>
<Figure size 1200x500 with 2 Axes>

We can now have a look at Verwey estimate that have been recorded:

verwey_estimates
Loading...

Add these Verwey estimates to the specimens MagIC table

Having computed the Verwey transition estimates (and captured the fitting parameters) for each specimen, we now want to record those results alongside the rest of our specimen metadata in the MagIC “specimens” table. The following loop does this in a few stages:

  1. Iterate over every Verwey-fit result
    We step through the list verwey_estimates_and_params, where each element is a dict containing the specimen name, the Verwey estimate itself, and all of the fit parameters we used.

  2. Build a human-readable description string
    We create a new description field for each entry that notes:

    “calculated using MPMS_verwey_fit.ipynb with parameters …”
    We then append the specific numerical values of the fit (e.g. the temperature ranges, polynomial degree) so that anyone inspecting the table later can immediately see exactly how that Verwey estimate was obtained.

  3. Clean up the dict
    Once those key–value pairs have been folded into the description, we remove them from the top-level of the dict so that only the final summary string remains in the table column (and we avoid redundant columns).

  4. Fetch the matching sample & weight from the existing specimens table
    To maintain the MagIC convention, each specimen row must also carry its associated sample name and mass. We look those up by matching on the specimen identifier in our specimens DataFrame.

  5. Insert the new row into the MagIC table
    Finally, we call the table’s add_row() method, passing the specimen name and our enriched dict. This appends a fully-populated row (with Verwey estimate, description, sample, weight, etc.) into the MagIC “specimens” table.

for n in range(0,len(verwey_estimates_and_params)):

    entry = verwey_estimates_and_params[n]
    version_num = pmag.get_version()
    entry['description'] = 'calculated using MPMS_verwey_fit.ipynb in ' + version_num + ' with parameters'
    
    # Specify the keys to append to the description and then remove
    keys_to_include = [
        't_range_background_min',
        't_range_background_max',
        'excluded_t_min',
        'excluded_t_max',
        'poly_deg',
    ]

    # Update the description by appending selected key-value pairs
    for key in keys_to_include:
        entry['description'] += f', {key}: {entry[key]}'

    # Remove the keys that were added to the description
    for key in keys_to_include:
        del entry[key]
     
    df = contribution.tables['specimens'].df
    sample = df.loc[df['specimen'] == entry['specimen'], 'sample'].iloc[0]
    weight = df.loc[df['specimen'] == entry['specimen'], 'weight'].iloc[0]
    entry['sample'] = sample
    entry['weight'] = weight
    
    contribution.tables['specimens'].add_row(entry['specimen'],verwey_estimates_and_params[n])
# Expand column width and ensure no truncation of long text
pd.set_option("display.max_colwidth", None)

# Filter and display Verwey rows
verwey_specimens = contribution.tables["specimens"].df
verwey_specimens = verwey_specimens[
    verwey_specimens["critical_temp_type"] == "Verwey"
]

display(verwey_specimens)
Loading...
#ipmag.contribution_to_magic(contribution, dir_path=dir_path)
References
  1. Jackson, M. J., & Moskowitz, B. (2020). On the distribution of Verwey transition temperatures in natural magnetites. Geophysical Journal International, 224(2), 1314–1325. 10.1093/gji/ggaa516