Skip to content

feat: get_density_from_cloud() COD workflow #331

Description

@yucongalicechen

Problem:
User enters a chemical formula (e.g. SiO2, Nacl) and optionally a phase. The function returns the material density.

Proposed steps:

  • 1. Initialize a structure object (e.g., ase.Atoms?) using the given chemical formula and optional phase information.
  • 2. Implement a method (e.g., Atoms.hill_formula) to compute the Hill notation for the chemical formula and attach it to the structure object.
  • 3. Retrive matching COD JSON files based on the Hill notation.
  • 4. Load the COD JSON files to the structure object, e.g. store it in Atoms.info["cod_entries"].
  • 5. Extract and store properties like molar mass, lattice parameters, etc., so that we are ready for computing density.
  • 6. Compute density for each COD JSON file: density = (Z * molar_mass) / (volume_cm3 * AVOGADRO_NUMBER).
  • 7. Return the average density (per phase, if applicable)

@sbillinge I edited the tasks based on our discussion today. Please take a look and let me know if everything looks good :) I might close some of the current PRs to keep the commiting history clean. Thanks!

Activity

  1. added this to the 3.7.0 release milestone on Apr 18, 2025
  2. deleted a comment from yucongalicechen on May 15, 2025
  3. sbillinge commented on May 15, 2025

    @sbillinge
    Contributor

    @yucongalicechen I deleted some of the discussion comments that are now out of date based on your edits and so leaving them is confusing

  4. sbillinge commented on May 15, 2025

    @sbillinge
    Contributor

    OK, Now I comment on your comment. I agree with this basically, but here is a preferred way if it is possible:
    Proposed steps:

    • 1. Initialize a str = ase.Atoms structure using the given chemical formula
    • 2. get structure data from COD database (initially)
      1. extract hill formula str.hill_formula
      2. formulate a COD request
      3. execute the request
    • 7. Return the average density

    There is no automated way to load from JSON payload into ASE. This is something we could think about requesting in ASE (they have such a thing for materials project) so it looks like the easiest is to temporarily write and read a cif file (ChatGPT answer):

    import urllib.request
    from ase.io import read
    import os
    
    def load_cod_structure(cod_id: int):
        cif_url = f"https://www.crystallography.net/cod/{cod_id:07d}.cif"
        cif_file = f"{cod_id}.cif"
        
        # Download CIF file
        urllib.request.urlretrieve(cif_url, cif_file)
        
        # Read into ASE
        atoms = read(cif_file)
        
        # Clean up if desired
        os.remove(cif_file)
        
        return atoms
    
    # Example usage
    atoms = load_cod_structure(1000001)
    atoms
    

    Ours would look a bit different because of handling the filter and getting multiple responses, but I think we should go with this for now, at risk of it having somewhat poor performance.

    We could think about caching to speed things up. ASE seems to have a database capability so we could save structure objects given a composition request. Let's not implement that until we find the performance is low. We could make an issue now though.

    We could also make an issue to implement an interface to materials project. We would have to handle MP API keys in our config. If there was a MP api key that we can access we could search MP. Please make an issue for this, but again, this can wait for the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions