@matteria-js/io
v0.1.0
Published
Structure and molecule file I/O for MATTERIA.
Readme
@matteria-js/io
Basic MATTERIA file I/O for the first migration slice. This package is the file-format boundary above @matteria-js/core: it parses strings into core data objects or simple records and writes them back to strings.
@matteria-js/io should stay boring and explicit. It should not own filesystem access, uploads, rendering, adapters, solvers, or analysis.
Public API
parsePoscar(text): parse VASP POSCAR/CONTCAR text into aStructure.writePoscar(structure): write aStructureas POSCAR-style text.parseXdatcar(text): parse a VASP XDATCAR trajectory into fixed-lattice frame records.xdatcarFrameToStructure(file, frameIndex): convert one parsed XDATCAR frame into aStructure.parseCif(text): parse a simple CIF structure from cell parameters and fractional atom sites.writeCif(structure): write a simple P1 CIF.parseXsf(text): parse a CRYSTAL XSF file withPRIMVECandPRIMCOORD.parseXsfFile(text): parse a CRYSTAL XSF structure plusDATAGRID_3Dscalar grids.parseXsfDatagrids(text): parse XSFDATAGRID_3Dscalar grids without requiring callers to use the structure record.writeXsf(structure): write aStructureas CRYSTAL/PRIMCOORD XSF.parseCube(text): parse scalar Gaussian CUBE text into aCubeFile.writeCube(cube): write a scalarCubeFileor compatible input as CUBE text.parseVaspVolumetric(text): parse a CHGCAR/PARCHG/LOCPOT/ELFCAR-like VASP scalar volumetric file, including consecutive extra scalar-grid sections when present.writeVaspVolumetric(file): write the supported VASP scalar volumetric subset.parseQePwInput(text): parse a Quantum ESPRESSOpw.xinput withibrav = 0into aStructureplus namelist, atomic-species, and k-point metadata.parseQuantumEspressoPwInput(text): parse a richer Quantum ESPRESSOpw.xinput record with namelists, cards, atomic species, positions, cell, k-points, and optional structure.parseQuantumEspressoPwOutput(text): parse a Quantum ESPRESSOpw.xoutput summary for convergence, energies, forces, stress, magnetization, warnings, and Fermi level.parseQuantumEspressoPpOutput(text): parse a Quantum ESPRESSOpp.xstdout summary for generated files, plot settings, warnings, and errors.parseQuantumEspressoDos(text): parse Quantum ESPRESSOdos.xtotal DOS text into@matteria-js/electronicDensityOfStates.parseQuantumEspressoProjectedDos(text): parse Quantum ESPRESSOprojwfc.x.pdos_totor.pdos_atm#...text into@matteria-js/electronicProjectedDensityOfStates.parseQuantumEspressoBands(text): parse Quantum ESPRESSObands.xfilband or GNU output into@matteria-js/electronicBandStructure.parseDoscar(text): parse VASP DOSCAR total DOS intoDensityOfStatesand common site-projected DOS blocks intoProjectedDensityOfStates.parseEigenval(text): parse VASP EIGENVAL band eigenvalues into@matteria-js/electronicBandStructure.parseProcar(text): parse VASP PROCAR LORBIT-style site/orbital projections into typed arrays and aBandStructure.parseVasprunXml(text): parse a common VASPvasprun.xmlsubset into structures, k-points, energies, forces, stress, total DOS, and band eigenvalues.parsePhonopyYaml(text): parse phonopy-styleband.yamlq-points, frequencies, distances, and optional eigenvectors into@matteria-js/phonons.parsePhonopyTotalDos(text): parse phonopytotal_dos.datinto@matteria-js/phononsPhononDensityOfStates.parsePhonopyProjectedDos(text): parse phonopyprojected_dos.datfrequency and projected-DOS columns.parsePhonopyThermalPropertiesYaml(text): parse phonopythermal_properties.yamlinto@matteria-js/phononsPhononThermalProperties.parsePhonopyForceConstants(text): parse phonopy textFORCE_CONSTANTSinto@matteria-js/phononsPhononForceConstants.parseXyz(text): parse simple XYZ text with element symbols and Cartesian coordinates.parseXyz(text, { lattice }): parse XYZ Cartesian coordinates into aStructurewhen a lattice is explicitly supplied.writeXyz(record): write parsed XYZ data or another{ comment, atoms }record as XYZ text.parseDftProject(entries): detect VASP and Quantum ESPRESSO files from virtual project entries and parse supported lightweight VASP/QE summaries without reading the filesystem.collectDftProjectEntries(sources)/parseDftProjectSources(sources): consume callback-backed virtual sources such as browserFile.text()wrappers or Node-side file wrappers supplied by the caller.
POSCAR / CONTCAR
import { parsePoscar, writePoscar } from "@matteria-js/io";
const poscarText = `Si
1.0
5.431 0 0
0 5.431 0
0 0 5.431
Si
2
Direct
0 0 0
0.25 0.25 0.25
`;
const structure = parsePoscar(poscarText);
console.log(structure.reducedFormula); // Si
console.log(structure.lattice.a); // 5.431
const roundTripped = writePoscar(structure);POSCAR/CONTCAR is the periodic crystal format in this slice. Use it when lattice vectors and fractional/cartesian site coordinates must round-trip.
Current POSCAR limits:
- VASP 5-style files with an explicit species-symbol line are required.
- Direct and Cartesian coordinate modes are supported.
- Selective dynamics lines and flags are accepted so common files parse, but flags are not preserved or written yet.
- Velocities, predictor-corrector blocks, lattice velocities, and temperature metadata are deferred.
XDATCAR
parseXdatcar reads VASP XDATCAR trajectory text as a POSCAR-like fixed-lattice header plus one or more ionic-configuration frames. Frames keep the frame index from Direct configuration= ... lines when present. Use xdatcarFrameToStructure when an individual frame should become a Structure.
import { parseXdatcar, xdatcarFrameToStructure } from "@matteria-js/io";
const trajectory = parseXdatcar(xdatcarText);
const lastFrame = xdatcarFrameToStructure(trajectory, trajectory.frameCount - 1);
console.log(trajectory.frameCount);
console.log(trajectory.frames[0]?.coordinateMode);
console.log(lastFrame.reducedFormula);Current XDATCAR limits:
- VASP 5-style symbol lines are required.
- Direct and Cartesian frame coordinate modes are supported.
- The lattice is read once from the header; variable-cell trajectories are not modeled yet.
- Frame velocities, predictor-corrector metadata, and writer support are deferred.
CIF
import { parseCif, writeCif } from "@matteria-js/io";
const structure = parseCif(cifText);
const roundTripped = writeCif(structure, { dataName: "MATTERIA" });CIF support is deliberately small. It reads _cell_length_*, _cell_angle_*, and an _atom_site loop with type symbols and fractional coordinates. It understands quoted values, simple fractions, and uncertainty suffixes such as 5.431(2).
Current CIF limits:
- writes P1 CIF only
- does not preserve symmetry operations, occupancies, disorder, labels, oxidation states, or metadata
- reads the first atom-site loop matching the supported headers
XSF
import { parseXsf, parseXsfDatagrids, parseXsfFile, writeXsf } from "@matteria-js/io";
const structure = parseXsf(xsfText);
const roundTripped = writeXsf(structure);
const xsfFile = parseXsfFile(xsfWithGridText);
const firstGrid = xsfFile.datagrids[0]?.grid;
console.log(firstGrid?.dimensions);
console.log(firstGrid?.valueLayout); // x-fastest
console.log(firstGrid?.planarAverage("z").values);
const gridsOnly = parseXsfDatagrids(qePpXsfText);XSF support covers periodic CRYSTAL files with PRIMVEC and PRIMCOORD. Atom rows may use element symbols or integer atomic numbers. parseXsfFile also reads 3D scalar datagrids from BEGIN_BLOCK_DATAGRID_3D sections, including common QE pp.x XSF output, into ScalarFieldGrid with explicit x-fastest value layout and Angstrom length metadata.
Current XSF limits:
- does not read molecular
ATOMSblocks - does not read animation frames
- reads 3D scalar datagrid blocks but does not write them
- does not read 2D grids, animation grids, or molecular-grid variants
XYZ
import { Lattice } from "@matteria-js/core";
import { parseXyz, writeXyz } from "@matteria-js/io";
const xyzText = `2
silicon pair
Si 0 0 0
Si 1.35775 1.35775 1.35775
`;
const xyzRecord = parseXyz(xyzText);
const roundTripped = writeXyz(xyzRecord);
const boxedStructure = parseXyz(xyzText, { lattice: Lattice.cubic(10) });XYZ is intentionally limited to simple element-symbol and Cartesian-coordinate records. Plain XYZ does not carry lattice vectors, periodic images, charges, bonding, or site properties, so it is not a full crystal serialization format.
DFT Project Manifests
import { parseDftProject } from "@matteria-js/io";
const manifest = parseDftProject([
{ path: "calc/POSCAR", text: poscarText },
{ path: "calc/INCAR", text: incarText },
{ path: "calc/KPOINTS", text: kpointsText },
{ path: "calc/OUTCAR", text: outcarText },
{ path: "calc/XDATCAR", text: xdatcarText },
{ path: "calc/vasprun.xml", size: 123_456 },
]);
console.log(manifest.codeFamily); // vasp
console.log(manifest.files.map((file) => file.role)); // ["poscar", "incar", "kpoints", "outcar", "xdatcar", "vasprun"]
console.log(manifest.files.find((file) => file.role === "incar")?.parsed?.vaspIncar?.parameters.ENCUT);
console.log(manifest.files.find((file) => file.role === "kpoints")?.parsed?.vaspKpoints?.mode);
console.log(manifest.files.find((file) => file.role === "outcar")?.parsed?.vaspOutput?.finalEnergy);
console.log(manifest.files.find((file) => file.role === "xdatcar")?.parsed?.vaspXdatcar?.frameCount);DFT project manifests are browser/Node-compatible metadata records. Callers pass virtual entries with path or name, optional text, and optional sizeBytes/size; @matteria-js/io does not read directories or files. VASP POSCAR/CONTCAR text and explicit-cell QE pw.x inputs can be stored as serializable structure dictionaries. VASP INCAR, KPOINTS, OUTCAR/OSZICAR, XDATCAR, QE pw.x outputs, and QE pp.x outputs are parsed into compact manifest summaries for settings, k-point mode, energy/Fermi/convergence, force/stress metadata, post-processing files, and trajectory frame metadata. Large XML, volumetric, electronic, and binary-like outputs are still recorded by presence and metadata; pass vasprun.xml text to parseVasprunXml when you want the parsed VASP XML result subset.
When the caller owns an async source boundary, use parseDftProjectSources instead of giving MATTERIA filesystem access:
import { parseDftProjectSources } from "@matteria-js/io";
const manifest = await parseDftProjectSources([
{ path: "calc/POSCAR", readText: () => poscarFile.text() },
{ path: "calc/INCAR", readText: () => incarFile.text() },
{ path: "calc/CHGCAR", sizeBytes: chgcarFile.size },
]);The default source policy reads known lightweight summary files and unknown files small enough to inspect. Use { readText: "all" } to read every source under maxTextBytes, { readText: "never" } to only detect from names and sizes, or { maxTextBytes } to cap callback-backed reads.
Use { parseStructures: false } to skip POSCAR/CONTCAR, QE input structures, and XDATCAR final-frame structure dictionaries. Use { parseVaspSummaries: false } to detect VASP files without parsing INCAR, KPOINTS, OUTCAR/OSZICAR, or XDATCAR summaries. Use { parseQeSummaries: false } to detect QE files without parsing pw.x or pp.x output summaries.
CUBE
CUBE is the first volumetric file boundary. parseCube returns a CubeFile with comments, atom metadata, a Structure, and a ScalarFieldGrid from @matteria-js/volumetric. The grid stores Angstrom-space origin, a full-cell lattice, integer dimensions, explicit x-fastest typed data, length-unit metadata, and step vectors derived from that lattice.
import { parseCube, writeCube } from "@matteria-js/io";
const cube = parseCube(cubeText);
console.log(cube.structure.numSites);
console.log(cube.grid.dimensions);
console.log(cube.grid.valueLayout); // x-fastest
console.log(cube.grid.lengthUnit); // angstrom
console.log(cube.grid.data);
console.log(cube.grid.planarAverage("z").values);
const nextText = writeCube(cube, { precision: 6 });Current CUBE limits:
- scalar fields only
- one value per grid point
- no negative atom-count multi-dataset CUBE files
- geometry is normalized to Angstrom after parsing
- positive grid counts are treated as Bohr in auto mode; negative grid counts are treated as Angstrom
Structurecoordinates are stored relative to the grid origin because@matteria-js/coredoes not carry a separate origin yet
VASP Volumetric
parseVaspVolumetric reads CHGCAR/PARCHG/LOCPOT/ELFCAR-like files with a VASP 5 POSCAR-style header and a primary scalar grid. The primary grid is returned as ScalarFieldGrid on grid; consecutive extra scalar-grid sections are exposed through gridSections and additionalGrids.
import { parseVaspVolumetric, writeVaspVolumetric } from "@matteria-js/io";
const parsed = parseVaspVolumetric(chgcarText, { kind: "CHGCAR" });
console.log(parsed.structure.reducedFormula);
console.log(parsed.grid.dimensions);
console.log(parsed.grid.valueLayout); // x-fastest
console.log(parsed.grid.lengthUnit); // angstrom
console.log(parsed.gridSections[0]?.role);
console.log(parsed.additionalGrids?.[0]?.role);
console.log(parsed.grid.planarAverage("z").distances);
const text = writeVaspVolumetric(parsed, { valuesPerLine: 5 });Current VASP volumetric limits:
- VASP 5 symbol lines are required
- one primary scalar grid is supported for writing
- consecutive extra scalar grids are parsed into
additionalGrids; for CHGCAR/PARCHG the first extra grid is labeled as magnetization density metadata - separated-band/k-point PARCHG variants, unlabeled trailing grids, interleaved augmentation-plus-grid blocks, and full augmentation parsing are not supported
- clearly labeled augmentation sections are recorded as ignored metadata
- code-specific projection metadata is deferred
Quantum ESPRESSO
parseQePwInput reads a basic Quantum ESPRESSO pw.x input with ibrav = 0, CELL_PARAMETERS, ATOMIC_SPECIES, ATOMIC_POSITIONS, and optional K_POINTS. parseQuantumEspressoPwInput preserves a richer card/namelist record while also building a Structure when the explicit cell can be resolved.
import {
parseQeBands,
parseQeDos,
parseQePpOutput,
parseQeProjectedDos,
parseQePwInput,
parseQePwOutput,
parseQuantumEspressoPwInput,
} from "@matteria-js/io";
const parsed = parseQePwInput(pwInputText);
const richInput = parseQuantumEspressoPwInput(pwInputText);
const output = parseQePwOutput(pwOutputText);
const pp = parseQePpOutput(ppOutputText);
const dos = parseQeDos(dosText);
const projected = parseQeProjectedDos(projwfcPdosText, {
sourceName: "Si.pdos_atm#1(Si)_wfc#2(p)",
});
const bands = parseQeBands(bandsText);
console.log(parsed.structure.reducedFormula);
console.log(parsed.namelists.SYSTEM?.ecutwfc);
console.log(parsed.atomicSpecies[0]?.pseudoFile);
console.log(parsed.kpoints?.mode);
console.log(richInput.cards.length);
console.log(output.finalEnergy?.value);
console.log(pp.outputFile);
console.log(dos.dos.fermiLevel);
console.log(projected.projectedDos.selectRecords({ element: "Si", orbital: "pz" }));
console.log(bands.bandStructure.getBandEnergies()[0]?.length);Current QE limits:
- the structure-building input path still expects explicit cell vectors; generic
ibravexpansion is not implemented CELL_PARAMETERSunitsangstrom,bohr, andalatare supportedATOMIC_POSITIONSmodescrystal,angstrom,bohr, andalatare supportedK_POINTSmodesgamma,automatic,crystal,crystal_b,tpiba, andtpiba_bare parsed as metadatapw.xoutput parsing extracts summary data only; it does not reconstruct full trajectories or XML/HDF5 resultspp.xoutput parsing extracts namelist settings, generated file names, job completion, warnings, and errors from stdout; scalar XSF grids written bypp.xare read throughparseXsfFileorparseXsfDatagridsdos.xsupport is total-DOS focused; projected DOS fromprojwfc.x.pdos_totand.pdos_atm#...text files is parsed separately byparseQuantumEspressoProjectedDosprojwfc.xprojected-DOS support preserves LDOS, atom/site metadata inferred from filenames, and component labels such ass,px,py,pz, but it does not parse the fullprojwfc.outlog or wavefunction coefficientsbands.xsupport covers filband and GNU-style numeric outputs; labels and rich path metadata are caller supplied later- CUBE variants, XML/HDF5 results, non-DOS projection data, and projected wavefunction files are still future slices
DOSCAR
parseDoscar reads the DOSCAR header and the total-DOS section into a DensityOfStates object from @matteria-js/electronic. It supports both non-spin rows with energy DOS integrated-DOS and spin-polarized rows with energy DOS(up) DOS(down) integrated(up) integrated(down). When the DOSCAR contains common VASP l- or lm-decomposed per-ion blocks, it also returns a ProjectedDensityOfStates object.
import { parseDoscar } from "@matteria-js/io";
import { Spin } from "@matteria-js/electronic";
const parsed = parseDoscar(doscarText);
console.log(parsed.header.fermiLevel);
console.log(parsed.totalDos.energies); // Float64Array
console.log(parsed.totalDos.getDensity(Spin.Up));
console.log(parsed.integratedDensities[Spin.Up]);
console.log(parsed.projectedDos?.selectRecords({ siteIndex: 0, orbital: "px" }));Current DOSCAR limits:
- reads total DOS plus common l-decomposed
s p d/s p d fand lm-decomposeds py pz px dxy dyz dz2 dxz dx2-y2projected blocks - preserves integrated DOS arrays separately from
DensityOfStates - can use
siteElementsandprojectedOrbitalLabelsoptions to attach element labels or parse unusual projection-column layouts - does not parse non-collinear spinor-resolved projected DOS or SOC-specific projected-DOS variants yet
- does not write DOSCAR
EIGENVAL
parseEigenval reads VASP EIGENVAL band energies, k-point fractional coordinates, weights, occupations, and spin channels. It returns a BandStructure from @matteria-js/electronic plus the occupation arrays that EIGENVAL stores beside the eigenvalues.
import { parseEigenval } from "@matteria-js/io";
import { Spin } from "@matteria-js/electronic";
const parsed = parseEigenval(eigenvalText, { fermiLevel: 0 });
console.log(parsed.header.kpointCount);
console.log(parsed.bandStructure.getBandEnergies(Spin.Up));
console.log(parsed.occupations[Spin.Up]);Current EIGENVAL limits:
- reads spin and non-spin eigenvalue sections
- preserves occupations separately from
BandStructure - uses the EIGENVAL
ISPINheader to choose row shape - does not parse projections, k-point labels, velocities, or line-mode path metadata
- does not write EIGENVAL
PROCAR
parseProcar reads VASP PROCAR LORBIT-style projection tables. It returns a BandStructure, occupation arrays, orbital labels, and one typed projection record per spin/k-point/band block.
import { parseProcar } from "@matteria-js/io";
import { Spin } from "@matteria-js/electronic";
const parsed = parseProcar(procarText, { fermiLevel: 0 });
console.log(parsed.header.ionCount);
console.log(parsed.orbitals);
console.log(parsed.bandStructure.getBandEnergies(Spin.Up));
console.log(parsed.projections[0]?.projections); // Float64ArrayCurrent PROCAR limits:
- reads ordinary LORBIT-style
ion ... tottables - preserves per-ion, per-orbital, ion-total, orbital-total, and grand-total values
- supports explicit
spin component 1/spin component 2sections - does not parse SOC, phase-factor, or complex-projection variants yet
- does not write PROCAR
vasprun.xml
parseVasprunXml reads the common VASP XML result structure into existing MATTERIA containers. It returns atom symbols, parsed Structure records, initialStructure, finalStructure, k-points, per-ionic-step energies, final energy values, final forces, final stress, Fermi level, total DOS, integrated DOS, and band eigenvalues as BandStructure.
import { parseVasprunXml } from "@matteria-js/io";
const parsed = parseVasprunXml(vasprunXmlText);
console.log(parsed.finalStructure?.reducedFormula);
console.log(parsed.finalEnergy?.freeEnergy);
console.log(parsed.calculationSteps.map((step) => step.energy?.freeEnergy));
console.log(parsed.finalForces?.maxForce);
console.log(parsed.finalStress?.tensor);
console.log(parsed.fermiLevel);
console.log(parsed.totalDos?.energies);
console.log(parsed.bandStructure?.getBandEnergies()[0]);Current vasprun.xml limits:
- parses common
atominfo,structure,kpoints,calculation/energy,calculation/varray[@name="forces"],calculation/varray[@name="stress"],dos/total, andeigenvaluesblocks - maps
spin 1andspin 2into@matteria-js/electronicSpin.UpandSpin.Down - reports force vectors in
eV/angstromby default and stress tensors inkBby default when the XML block does not carry an explicit unit attribute - does not parse projected DOS, dielectric/optical data, parameters, magnetization, Born charges, or Hessian-like data yet
- uses a small browser-compatible XML reader for this subset; streaming very large XML files is deferred
- does not write vasprun.xml
Phonopy YAML
parsePhonopyYaml reads the common phonopy band.yaml shape into a PhononBandStructure from @matteria-js/phonons. It preserves q-point fractional coordinates, labels, phonopy path distances, branch frequencies, and optional complex eigenvectors in qpoint-branch-atom-xyz typed-array layout.
import { parsePhonopyYaml } from "@matteria-js/io";
const parsed = parsePhonopyYaml(phonopyBandYaml);
console.log(parsed.bandStructure.branchCount);
console.log(parsed.distances); // Float64Array when band.yaml distances are present
console.log(parsed.bandStructure.getModeVector(0, 0, 0));Current phonopy YAML limits:
- supports
phonon: - q-position: ... band: ... frequency: ...band/mesh-like blocks - supports phonopy path
distance,label,weight,nqpoint,natom, and optional eigenvectors - does not parse group velocities, Born charges, force-constant YAML variants, or full YAML as a general-purpose YAML parser
- does not write phonopy YAML
Phonopy DOS
parsePhonopyTotalDos reads phonopy total_dos.dat rows as frequency and total-DOS columns, with an optional third integrated-DOS column. parsePhonopyProjectedDos reads phonopy projected_dos.dat rows as one frequency column followed by one projected-DOS column per atom/component/group. The projected parser also returns a summed PhononDensityOfStates for callers that want a total curve.
import { parsePhonopyProjectedDos, parsePhonopyTotalDos } from "@matteria-js/io";
const total = parsePhonopyTotalDos(totalDosDat);
const projected = parsePhonopyProjectedDos(projectedDosDat, {
labels: ["Na", "Cl"],
});
console.log(total.dos.densities); // Float64Array
console.log(total.integratedDensities); // Float64Array when present
console.log(projected.series[0]?.densities); // Float64Array
console.log(projected.totalDos.densities); // summed projectionsCurrent phonopy DOS limits:
- supports whitespace- or comma-separated numeric text rows
- preserves comments only by ignoring them; file headers are not retained
- does not infer atom names or projection grouping from external structure files
- does not write phonopy DOS files
Phonopy Thermal Properties
parsePhonopyThermalPropertiesYaml reads phonopy thermal_properties.yaml curves into PhononThermalProperties from @matteria-js/phonons. It preserves the unit: section for temperature, free energy, entropy, and heat capacity when present, plus common top-level metadata such as zero-point energy, cutoff frequency, mode count, and integrated-mode count.
import { parsePhonopyThermalPropertiesYaml } from "@matteria-js/io";
const parsed = parsePhonopyThermalPropertiesYaml(thermalPropertiesYaml);
console.log(parsed.thermalProperties.temperatures); // Float64Array
console.log(parsed.thermalProperties.freeEnergies); // Float64Array
console.log(parsed.thermalProperties.interpolate(300));
console.log(parsed.metadata.zeroPointEnergy);Current phonopy thermal-property limits:
- supports the common
thermal_properties:list withtemperature,free_energy,entropy, andheat_capacity - preserves explicit Phonopy units but does not convert between units
- does not parse projected thermal properties, thermal displacement files, or quasi-harmonic workflows
- does not write
thermal_properties.yaml
Phonopy FORCE_CONSTANTS
parsePhonopyForceConstants reads the standard text FORCE_CONSTANTS shape: an atom-count header followed by one 1-based source/target atom-pair header and three numeric rows for every pair. It stores values in PhononForceConstants with explicit source-target-cartesian-cartesian layout, so callers can look up a 3x3 matrix by zero-based source and target atom indices without depending on input block order.
import { parsePhonopyForceConstants } from "@matteria-js/io";
const parsed = parsePhonopyForceConstants(forceConstantsText, {
unit: "eV/angstrom^2",
});
console.log(parsed.forceConstants.atomCount);
console.log(parsed.forceConstants.getMatrix(0, 1));
console.log(parsed.forceConstants.summary().maxTransposeResidual);Current phonopy FORCE_CONSTANTS limits:
- supports the plain text
FORCE_CONSTANTSformat with complete atom-pair blocks - validates duplicate pairs, missing pairs, malformed 3x3 rows, and out-of-range atom indices
- preserves an optional caller-supplied unit string but does not infer or convert units
- does not parse
force_constants.hdf5, Born effective charges, displacement datasets, or YAML force-constant variants - does not generate force constants, build dynamical matrices, diagonalize phonons, or write
FORCE_CONSTANTS
Next Slice
After the current CIF, XSF, XSF DATAGRID, scalar CUBE, QE pw.x input/output, QE pp.x output summaries, QE DOS/bands/projwfc PDOS, VASP volumetric, XDATCAR, DOSCAR total/projected-DOS, EIGENVAL, PROCAR, vasprun.xml, phonopy band.yaml, phonopy DOS, phonopy thermal-property, and phonopy FORCE_CONSTANTS subsets, add more VASP, Quantum ESPRESSO, and phonon result files in parser-sized increments:
- richer CHGCAR/PARCHG/LOCPOT/ELFCAR variants, including interleaved augmentation and separated-band/k-point PARCHG metadata
- richer vasprun.xml, DOSCAR spinor, and PROCAR variants
- richer Quantum ESPRESSO post-processing grids, richer output variants, and non-DOS projection records
- richer phonopy force-constant metadata, binary force constants, and richer thermal/displacement files
Each parser should state what it preserves, what it ignores, whether writing is supported, and how its data maps into @matteria-js/volumetric, @matteria-js/electronic, or @matteria-js/phonons.
Deferred
Filesystem helpers, upload widgets, network access, unimplemented trajectory formats, molecule-specific models, and adapter-specific conversions are out of scope for this package. Callers should pass strings, streams, or parsed records across explicit boundaries rather than asking @matteria-js/io to own application I/O.
