How to extract magnetic moment data from the relaxation trajectories using API

Dear users and developers,

I’m interested in extracting materials project relaxation trajectories data using python API. I need to get energy, force, stress and magnetic moments (atom-specific) labels to train machine learning force field (CHGNet). But I couldn’t find any API that’s able to extract magmoms from trajectories.

I note that a previous topic mentioned the related problem of getting the magnetic moments for a given material (relaxed, rather than individual frames of trajectory): https://matsci.org/t/how-to-get-magnetic-moment-of-each-atom-using-the-materials-project-api/1447/4?u=ffarya

I tried the following code

from pymatgen.core.trajectory import Trajectory

trajs = mpr.materials.tasks.get_trajectory(task_ids[-1])
traj = Trajectory.from_dict(trajs[1])
traj.site_properties

But it just gives a list of empty dicts

[{}, {}, {}, {}, {}, {}, {}]

The VASP input for this calculation shows that LORBIT = 11, so I believe that VASP has magnetic moments information in its output (OUTCAR).

I have the following questions:

  1. Do the trajectories as stored by materials project usually contain this information? I believe the answer maybe yes, since a notable fraction of structures in the MPTrj datasets have magmom labels (around 18%).
  2. If the answer is yes, what is the correct way to extract it?

Appreciate any of your help!

Hi @ffArya,

Just confirming, did your api query return the trajectories that you expected there? i.e., your trajs variable isn’t an empty list?

@ffArya: The magnetic moments aren’t stored in each step of the ionic relaxation, only the final step. So for each task, you will have at most two sets of magnetic moments (if the task has two calcs_reversed entries for a double relaxation)

1 Like

Yes, I got the expected trajectories. I can extract other information like energy and forces from trajs variable.

Thanks! This is very important information. I use the following codes to extract the final magnetic moments for each calculation. If you have a better way (more elegant? I guess) please tell me.

task_docs = mpr.materials.tasks.search(
    "mp-2629535", fields = ["task_id", "input", "output", "calcs_reversed", "last_updated"] 
)
task_doc = task_docs[0]

calcs = task_doc.calcs_reversed
calc = calcs[0]
mags = calc.output.outcar["magnetization"]
mags

which ouputs

[{'s': -0.0, 'p': -0.0, 'd': 0.0, 'tot': -0.0},
 {'s': -0.0, 'p': -0.0, 'd': 0.0, 'tot': -0.0},
 {'s': -0.0, 'p': -0.0, 'd': 0.0, 'tot': -0.0},
 {'s': -0.0, 'p': -0.0, 'd': 0.0, 'tot': -0.0},
 {'s': -0.024, 'p': -0.019, 'd': -3.734, 'tot': -3.776},
 {'s': -0.024, 'p': -0.019, 'd': -3.734, 'tot': -3.776},
 {'s': 0.024, 'p': 0.019, 'd': 3.734, 'tot': 3.776},
 {'s': 0.024, 'p': 0.019, 'd': 3.734, 'tot': 3.776},
 {'s': -0.001, 'p': 0.0, 'd': 0.0, 'tot': -0.0},
 {'s': 0.001, 'p': -0.0, 'd': 0.0, 'tot': 0.0},
 {'s': -0.001, 'p': 0.0, 'd': 0.0, 'tot': -0.0},
 {'s': 0.001, 'p': -0.0, 'd': 0.0, 'tot': 0.0},
 {'s': 0.003, 'p': 0.013000000000000001, 'd': 0.0, 'tot': 0.016},
 {'s': -0.003, 'p': -0.013000000000000001, 'd': 0.0, 'tot': -0.016},
 {'s': 0.003, 'p': 0.013000000000000001, 'd': 0.0, 'tot': 0.016},
 {'s': -0.003, 'p': -0.013000000000000001, 'd': 0.0, 'tot': -0.016},
 {'s': 0.003, 'p': 0.013000000000000001, 'd': 0.0, 'tot': 0.017},
 {'s': -0.003, 'p': -0.013000000000000001, 'd': 0.0, 'tot': -0.017},
 {'s': 0.003, 'p': 0.013000000000000001, 'd': 0.0, 'tot': 0.017},
 {'s': -0.003, 'p': -0.013000000000000001, 'd': 0.0, 'tot': -0.017},
 {'s': -0.001, 'p': -0.002, 'd': 0.0, 'tot': -0.003},
 {'s': 0.001, 'p': 0.002, 'd': 0.0, 'tot': 0.003},
 {'s': 0.001, 'p': 0.002, 'd': 0.0, 'tot': 0.003},
 {'s': -0.001, 'p': -0.002, 'd': 0.0, 'tot': -0.003},
 {'s': -0.001, 'p': -0.002, 'd': 0.0, 'tot': -0.003},
 {'s': 0.001, 'p': 0.002, 'd': 0.0, 'tot': 0.003},
 {'s': 0.001, 'p': 0.002, 'd': 0.0, 'tot': 0.003},
 {'s': -0.001, 'p': -0.002, 'd': 0.0, 'tot': -0.003}]

These should be accessible from the site_properties of a structure, e.g.:

task_doc.output.structure.site_properties.get("magmom")

unless you prefer the orbital-decomposition of the magmoms. The site_properties include just the total magnetic moment.