Docs are under construction. Content may be incomplete or change.

Structures and Calculators

Page type: Reference · Generated from src/script/apiDocs · Verified 2026-07-13T00:00:00.000Z
On this page

Calculator narrative and method-selection guidance live in Calculator Construction and Validation and the Calculator Reference.

A calculator is a small reusable object built once with tako.calculator.gxtb, gfn2, mlip, or dft. Construction is synchronous and only records a method specification; it does not load a model or run anything. Every calculator carries capabilities(), elementSupport(structure), validate(operation, request), and readiness(manifest, records) inspection methods. Passing structure to validate performs the same fast supported-element check used by the UI before any model or WASM is loaded.

Naming rule for this namespace: snake_case methods (get_positions, set_cell, get_chemical_formula, …) deliberately mirror ASE’s Atoms API name-for-name so ASE muscle memory transfers; Tako-native helpers with no ASE counterpart use camelCase (addAtoms, addFractionalAtoms, setCellOrigin). The two styles coexisting is intentional, not drift — a snake_case name is a promise of ASE-matching semantics.

Every tako.structure.* editing call is an immutable, ASE-shaped helper: it takes a Structure (and, for the mutators, extra arguments) and returns a brand-new Structure without modifying its input — duplicate is the one exception, returning { structure, newIds } so the caller can learn the ids of the atoms it just created. Cartesian positions and cell vectors are in Å; rotation angles are in degrees; fractional/scaled coordinates are dimensionless and are not automatically wrapped into [0, 1) unless wrap() is called explicitly. Atom selectors are not interchangeable across calls: delete and fix take 0-based array indices into structure.atoms, while translate, rotate, and duplicate take atom id numbers — mixing the two up silently selects the wrong atoms or throws an out-of-range error.

Method choice is part of the scientific record. g-xTB is the balanced default and provides the faster sTDA route from its converged electronic state. GFN2 adds implicit solvation and remains the accuracy-first sTDA default for absorption-band positions. MLIPs target fast neutral, closed-shell and periodic work. DFT exposes periodic LDA/VWN plus PBE, r2SCAN, and molecular SKALA 1.1. LDA/VWN is the validated GTH-DZVP-MOLOPT-SR/GTH-PADE identity and has no empirical dispersion by default. The UI defaults new DFT selections to PBE/def2-SVP (and restores the user’s last-run calculator settings thereafter). Semantic script levels still resolve bare pbe/r2scan to def2-SVP on molecules and GTH-DZVP-MOLOPT-SR/GTH-PBE on periodic cells. Explicit PBC bases include GTH-SZV-MOLOPT-SR, UZH GTH-SVP/DZVP/TZVP/TZV2P-MOLOPT-PBE, and legacy narrow GTH sets; elementSupport reports Z coverage before any WASM load. SKALA 1.1 resolves to def2-SVP and remains molecular-only.

tako.calculator.gxtb

tako.calculator.gxtb(options?: { dispersion?: 'none' | 'd3-bj' | 'd4-rev'; charge?: number; unpaired?: number; spinPolarized?: boolean; scf?: object }) => TakoScriptCalculator

Constructs the balanced default g-xTB calculator through tb.rs.

ParameterTypeDefaultContract
options.dispersion'none' | 'd3-bj' | 'd4-rev''d4-rev'Selects no correction, DFT-D3 with the published ωB97M reference-functional parameters, or native self-consistent DFT-revD4.
options.chargenumber0Total charge.
options.unpairedinteger0Number of unpaired electrons.
options.spinPolarizedbooleanfalseRequests open-shell treatment.
options.scfobjectbackend defaultsPartial SCF controls.

Returns: TakoScriptCalculator with engine: ‘gfn2’, levelOfTheory: ‘gxtb’, and tb runtime readiness.

  • g-xTB supports molecular and periodic energy, forces, stress, optimization, MD, phonons, vibrations, reaction paths, and transition-state work.
  • The g-xTB parametrization is molecular; the theory itself is unreliable under periodic boundary conditions. Periodic g-xTB runs proceed but should be treated with caution — prefer GFN2-xTB, an MLIP, or periodic DFT for crystals.
  • DFT-revD4 is the native g-xTB dispersion model and the default. DFT-D3 uses the published ωB97M D3(BJ) record because no separate g-xTB-specific D3 fit has been published; result metadata records wb97m explicitly.
  • g-xTB supports sTDA by passing its accepted orbitals, energies, and occupations directly to the simplified response kernel. The cached density remains unchanged, and response dipole integrals are evaluated in the calculator-owned q-vSZP basis. It does not support GFN2 implicit solvation.
const calculator = tako.calculator.gxtb({ dispersion: 'd4-rev', charge: -1, unpaired: 1 });

tako.calculator.gfn2

tako.calculator.gfn2(options?: { levelOfTheory?: 'gfn2'; dispersion?: 'default' | 'none' | 'd4'; charge?: number; unpaired?: number; spinPolarized?: boolean; scf?: object; solvation?: object }) => TakoScriptCalculator

Constructs a reusable semi-empirical GFN2-xTB calculator object with a normalized method specification and inspection methods.

ParameterTypeDefaultContract
options.levelOfTheory'gfn2''gfn2'Selects GFN2-xTB independently of its dispersion correction.
options.dispersion'default' | 'none' | 'd4''default'Selects dispersion separately; ‘default’ resolves to native D4 for GFN2-xTB.
options.chargenumber0Total molecular charge in elementary-charge units; any finite number is accepted (not rounded).
options.unpairedinteger0Number of unpaired electrons (backend spin-population input); floored and clamped to >= 0.
options.spinPolarizedbooleanfalseRequests the unrestricted/open-shell SCF treatment.
options.scfobjectbackend defaultsPartial override of SCF cycle limits, energy/density thresholds, electronic temperature, mixer, and temperature annealing.
options.solvationobject{ enabled: false, model: 'alpb-cds', solvent: 'water', ... }Partial override requesting an implicit-solvent model ({ enabled, model, solvent, electrostatic, bornKernel, cds, cm5, shift }).

Returns: TakoScriptCalculator: { engine: ‘gfn2’, levelOfTheory, charge, unpaired, spinPolarized, dispersion, scf, solvation, capabilities(): AseCalculatorCapabilities, validate(operation, request?): { ok: boolean; reasons: string[] }, readiness(manifest?, records?): { ready: boolean; summary: string[] } }.

  • Construction is synchronous and does not download or load anything; it only normalizes the method specification.
  • capabilities() for GFN2 reports { name: ‘Gfn2Calculator’, backend: ‘tb.rs’, properties: [‘energy’,‘forces’,‘stress’,‘charges’,‘dipole’], operations: […COMMON_OPERATIONS,‘stda’,‘reactionPath’,‘transitionState’], supportsPbc: true, supportsCharge: true, supportsSpin: true, supportsCellOptimization: true, dynamics, phonons, analysis.xrd }.
  • validate(operation, { properties }) returns { ok: false, reasons } when an operation is unsupported, when a requested property is unavailable at this level, or when an electronic property (dos, pdos, charges, electronDensity, chargeDensity, nci, wfn) is requested for an operation other than ‘singlePoint’.
  • readiness(manifest, records) reports asset status for the tb WASM runtime; with no manifest/records it only describes requirements, not the live cache.
  • Charge and spin describe the modeled electronic state, not correction knobs — construct one calculator per intended electronic state rather than mutating charge/unpaired on a shared object.
const calculator = tako.calculator.gfn2({ dispersion: 'default', charge: 1, unpaired: 1, spinPolarized: true });
const check = calculator.validate('optimization', { properties: ['energy', 'forces'] });

tako.calculator.mlip

tako.calculator.mlip(options?: { levelOfTheory?: string; runtime?: string; model?: string }) => TakoScriptCalculator

Constructs a reusable machine-learned interatomic potential (MLIP) calculator object with a normalized runtime/model pairing.

ParameterTypeDefaultContract
options.levelOfTheory'nequix' | 'nequix-phono' | 'nequip-s' | 'nequip-l' | 'equiformer' | 'equiformer-gradient''nequip-s'Selects a registered runtime + weight-set pairing.
options.runtime'nequix' | 'nequip' | 'equiformer'level-dependent (or derived from model, see notes)Overrides the inference runtime; only meaningful with a matching model.
options.model'nequix-mp-1' | 'nequix-mp-1-pft' | 'nequip-s' | 'nequip-l' | 'equiformer' | 'equiformer-gradient'level-dependentOverrides the registered weight identifier.

Returns: TakoScriptCalculator: { engine: ‘mlip’, levelOfTheory, runtime, model, capabilities(): AseCalculatorCapabilities, validate(operation, request?): { ok: boolean; reasons: string[] }, readiness(manifest?, records?): { ready: boolean; summary: string[] } }.

  • An explicitly named model pins its own runtime (nequix-mp-1/-pft => ‘nequix’, equiformer/-gradient => ‘equiformer’, nequip-s/-l => ‘nequip’); the level’s default runtime applies only when the model is also left at its default.
  • capabilities() for MLIP reports { name: ‘MlipCalculator’, backend: runtime, properties: [‘energy’,‘forces’,‘stress’], operations: […COMMON_OPERATIONS,‘reactionPath’,‘transitionState’], supportsPbc: true, supportsCharge: false, supportsSpin: false, supportsCellOptimization: true, dynamics, phonons, analysis.xrd }.
  • An MLIP calculator has no charge, multiplicity, orbital, or solvent state; passing charge/unpaired/spinPolarized-like fields has no effect on the model. Use tako.calculator.gfn2 whenever the question depends on electron count, spin, or a dielectric environment.
  • readiness(manifest, records) describes required WASM runtime and model-weight assets relative to the manifest/records supplied; it does not itself probe the browser cache.
const calculator = tako.calculator.mlip({ levelOfTheory: 'nequix' });
const ready = calculator.readiness(manifest, assetRecords);

tako.calculator.dft

tako.calculator.dft(options: { levelOfTheory: 'lda' | 'pbe' | 'r2scan' | 'skala'; dispersion?: 'default' | 'none' | 'd3-bj'; charge?: number; unpaired?: number; spinPolarized?: boolean; kpoints?: { mode: 'auto' | 'gamma' | 'custom'; mesh?: [number, number, number] }; scf?: object }) => TakoScriptCalculator

Constructs a DFT calculator through the ase.rs QC adapter.

ParameterTypeDefaultContract
options.levelOfTheory'lda' | 'pbe' | 'r2scan' | 'skala'Required functional identity. LDA/VWN is periodic-only and pins GTH-DZVP-MOLOPT-SR/GTH-PADE; Tako resolves the other broad-coverage bases from the input boundary conditions.
options.dispersion'default' | 'none' | 'd3-bj''none' for LDA/VWN; 'default' otherwiseSelects dispersion separately; ‘default’ resolves to none for LDA/VWN and functional-specific D3(BJ) for the other QC methods.
options.chargenumber0Total molecular charge.
options.unpairedinteger0Number of unpaired electrons.
options.spinPolarizedbooleanfalseRequests open-shell treatment.
options.kpoints{ mode: 'auto' | 'gamma' | 'custom'; mesh?: [number, number, number] }{ mode: 'auto' }Reciprocal-space sampling for periodic cells: ‘auto’ picks the smallest mesh with k·L ≥ 15 Å per lattice vector, ‘gamma’ forces the Γ point, ‘custom’ uses mesh (entries clamped to 1–48). Molecular runs ignore it.
options.scfobjectUnified SCF surface overrides (energyThreshold, densityThreshold, maxIterations, mixerDamping, electronicTemperatureKelvin). The electronic temperature sets periodic Fermi–Dirac smearing (σ = kB·T); metals often need 1000–2000 K to converge, and the default 300 K is negligible for gapped systems.

Returns: TakoScriptCalculator with engine: ‘qc’, a geometry-aware DFT level, elementSupport(structure), and synchronous validation.

  • Molecular PBE, r2SCAN, and SKALA 1.1 use def2-SVP. The bundled def2 table covers H-La and Hf-Rn; Ce-Lu are absent and are rejected during selection.
  • LDA/VWN is periodic-only and uses the tested GTH-DZVP-MOLOPT-SR/GTH-PADE pair. dispersion: "default" resolves to none because no D3 correction was validated for this public identity. Automatic force/stress requests use total-energy finite differences until the periodic LDA analytical derivative path is translated.
  • Default dispersion uses published BJ-damped D3 parameters: pbe for PBE, r2scan for r2SCAN, and the skala-1.0 D3 parameter record for SKALA 1.1. The SKALA parameter-record name identifies the published fit; it does not change the selected SKALA 1.1 electronic model.
  • For molecules, all three functionals support single points, optimization, MD, vibrations, reaction paths, and transition states.
  • For full 3D PBC, semantic PBE and r2SCAN default to GTH-DZVP-MOLOPT-SR/GTH-PBE (Z=1–56, 72–86). Explicit bases include GTH-SZV-MOLOPT-SR (fastest broad), UZH GTH-SVP-MOLOPT-PBE (heavy-only fast), GTH-DZVP/TZVP/TZV2P-MOLOPT-PBE (UZH quality ladder), legacy narrow GTH-DZVP/TZV2P/QZV3P, and def2. GTH families support energy, forces, stress, optimization, cell relaxation, MD, phonons, vibrations, and periodic analyses (charges, DOS/PDOS, density cubes, NCI, ESP, Fukui, HDF5). Periodic def2 carries the same forces/stress and force-driven operations for every covered element: all-electron cells (every atom H–Kr) differentiate analytically, and scalar-ECP cells (any atom Rb+) automatically fall back to total-energy finite differences, which cost one converged SCF per displacement. Molecular-only formats (orbital cubes, ELF, Molden, WFN) stay unavailable under k-point PBC. SKALA 1.1 is molecular-only.
  • elementSupport(structure) is a synchronous lookup over precomputed element sets. It reports requestedElements, supportedElements, missingElements, basis, and pseudopotential (with Z-range reasons on failure). validate(operation, { structure, properties }) runs the same check used by both UI selectors, and execution rejects before model or WASM dispatch when it fails.
  • Explicit basis-bearing DFT identities remain readable for archived workspaces, but new scripts should use the four semantic levels above.
  • Periodic QC derives its FFT mesh from a fixed 100 Ha reciprocal kinetic-energy cutoff using qc.rs/PySCF cutoff_to_mesh semantics. The mesh therefore scales with lattice vectors, so energies from different cell volumes remain on one reciprocal-resolution control instead of reusing a fixed mesh count.
  • All three phases of a metallic system can carry odd per-cell electron counts under a k-point mesh: electrons fill the sampled ensemble (PySCF KRKS/KUKS semantics), so closed-shell runs on metals like LiC6 or primitive-cell Al are valid without artificial spin. Pair them with an elevated electronicTemperatureKelvin when the SCF oscillates.
  • SKALA readiness includes the separate skala-1.1 model asset. LDA/VWN, PBE, and r2SCAN require only the QC WASM module.
const calculator = tako.calculator.dft({ levelOfTheory: 'r2scan', dispersion: 'default' });
const check = calculator.validate('singlePoint', { structure, properties: ['energy', 'forces'] });

tako.structure.atom

tako.structure.atom(element: string, positionOrOptions?: [number, number, number] | { title?: string; position?: [number, number, number] }) => Structure

Creates a non-periodic, single-atom Structure at an optional Cartesian position.

ParameterTypeDefaultContract
elementstringElement symbol for the atom.
positionOrOptions[x, y, z] | { title?: string; position?: [x, y, z] }[0, 0, 0]A bare [x, y, z] tuple (Å), or an options object with an optional title and position.

Returns: Structure with one atom (id 1), cell: null, title defaulting to ’ atom’.

  • Always produces a non-periodic structure (cell is null regardless of position).
const na = tako.structure.atom('Na', [0, 0, 0]);

tako.structure.benzene

tako.structure.benzene(options?: { title?: string }) => Structure

Creates a planar, non-periodic benzene ring (6 carbons at radius 1.397 Å, 6 hydrogens at radius 2.479 Å, both in the z = 0 plane).

ParameterTypeDefaultContract
options.titlestring'Benzene'Title for the returned structure.

Returns: Structure with 12 atoms (ids 1-6 carbons, 7-12 hydrogens), cell: null.

tako.structure.crystal

tako.structure.crystal(options: { title: string; cell: [[number,number,number],[number,number,number],[number,number,number]]; fractionalAtoms: Array<[string, [number, number, number]]> }) => Structure

Creates a periodic Structure from explicit lattice vectors and a list of fractional-coordinate atoms.

ParameterTypeDefaultContract
options.titlestringTitle for the returned structure.
options.cell[[number,number,number] x3]Three lattice vectors in Å.
options.fractionalAtomsArray<[element, [fx, fy, fz]]>Element symbol and fractional (dimensionless) coordinate for each atom, in the order they receive ids starting at 1.

Returns: Structure with atoms Cartesian-placed from fractionalAtoms x cell, cell: { vectors: options.cell, scale: 1 }.

  • Unlike most other structure builders (e.g. Atoms, bulk), this call does not validate the shape of cell or fractionalAtoms before use (no assertCell/assertVec3 check) — a malformed cell surfaces as a downstream numeric error rather than a clear validation message.
  • Atoms built by crystal() are tagged layerId: ‘molecule’ even though the structure is periodic, unlike Atoms()/bulk() which tag periodic atoms layerId: ‘crystal’; this only affects the app’s layer grouping, not the physics.
const nacl = tako.structure.crystal({
  title: 'NaCl',
  cell: [[5.64, 0, 0], [0, 5.64, 0], [0, 0, 5.64]],
  fractionalAtoms: [['Na', [0, 0, 0]], ['Cl', [0.5, 0.5, 0.5]]],
});

tako.structure.bulk

tako.structure.bulk(symbol: string, crystalstructure: string, a: number, options?: { c?: number; covera?: number; cubic?: boolean; orthorhombic?: boolean; title?: string }) => Structure
tako.structure.bulk(symbol: string, crystalstructure: string, options: { a: number; c?: number; covera?: number; cubic?: boolean; orthorhombic?: boolean; title?: string }) => Structure

Creates a periodic bulk Structure for a single element in a named crystal structure (ASE bulk()-style).

ParameterTypeDefaultContract
symbolstringA single element symbol (a formula naming more than one element throws).
crystalstructure'sc' | 'bcc' | 'fcc' | 'diamond' | 'hcp'Case/underscore/hyphen-insensitive; accepts aliases like ‘simple-cubic’, ‘body-centered-cubic’, ‘face-centred-cubic’, ‘hexagonal-close-packed’.
anumberLattice constant a in Å, either as the 3rd positional argument or as options.a; required (throws if neither is a positive finite number).
options.cubicbooleanfalseFor bcc/fcc/diamond, builds the conventional (multi-atom) cubic cell instead of the primitive cell.
options.orthorhombicbooleanfalseFor hcp, builds a 4-atom orthorhombic cell instead of the 2-atom hexagonal cell.
options.cnumberhcp only: sqrt(8/3) * a, or covera * a if covera is givenhcp c lattice constant in Å.
options.coveranumbersqrt(8/3)hcp c/a ratio, used to derive c when c is not given directly.
options.titlestring'<symbol> <crystalstructure>'Title for the returned structure.

Returns: Periodic Structure built by delegating to tako.structure.Atoms with pbc: true and the scaled_positions for the chosen lattice.

const cu = tako.structure.bulk('Cu', 'fcc', 3.615, { cubic: true });

tako.structure.Atoms

tako.structure.Atoms(symbols: string | string[], options?: { title?: string; positions?: [number,number,number][]; scaled_positions?: [number,number,number][]; scaledPositions?: [number,number,number][]; cell?: [[number,number,number],[number,number,number],[number,number,number]]; pbc?: boolean | [boolean,boolean,boolean]; layerId?: string }) => Structure

Creates a Structure from element symbols and optional positions/cell (ASE Atoms()-style constructor).

ParameterTypeDefaultContract
symbolsstring | string[]A chemical-formula string parsed left-to-right by element+count tokens (e.g. ‘H2O’ -> [‘H’,‘H’,‘O’]), or an explicit array of element symbols, one per atom.
options.positions[x,y,z][]Cartesian positions in Å, one per atom (array length must equal symbols length).
options.scaled_positions / scaledPositions[fx,fy,fz][]Fractional positions, one per atom; requires options.cell (throws otherwise). Both spellings are accepted aliases.
options.cell[[number,number,number] x3]Three lattice vectors in Å; presence of a cell is what makes the structure periodic.
options.pbcboolean | [boolean,boolean,boolean]Accepted for ASE-signature compatibility but not read: periodicity is determined solely by whether options.cell is given, not by this flag.
options.layerIdstring'crystal' if cell is given, else 'molecule'Layer tag written onto every created atom.
options.titlestring'Atoms'Title for the returned structure.

Returns: Structure with one atom per symbol; cell: { vectors, scale: 1 } if options.cell given, else null.

  • If neither positions nor scaled_positions is given, every atom is placed at the origin [0, 0, 0].
  • options.pbc is accepted but ignored — passing { cell, pbc: false } still produces a periodic structure, because Structure has no independent pbc flag (only cell: Cell | null).
const water = tako.structure.Atoms(['O', 'H', 'H'], {
  title: 'Water',
  positions: [[0, 0, 0], [0.76, 0.59, 0], [-0.76, 0.59, 0]],
});

tako.structure.get_chemical_symbols

tako.structure.get_chemical_symbols(structure: Structure) => string[]

Returns each atom’s element symbol in structure.atoms order.

ParameterTypeDefaultContract
structureStructureStructure to read.

Returns: string[], same length and order as structure.atoms.

tako.structure.get_chemical_formula

tako.structure.get_chemical_formula(structure: Structure, mode?: 'hill' | 'reduce' | 'all') => string

Returns a formula string built from raw per-element atom counts, in one of three symbol orderings.

ParameterTypeDefaultContract
structureStructureStructure to read.
mode'hill' | 'reduce' | 'all''hill'Symbol ordering: ‘hill’ puts C first, then H, then remaining elements alphabetically (pure alphabetical if there is no carbon); ‘reduce’ and ‘all’ order by each element’s first occurrence in structure.atoms.

Returns: String such as ‘C6H6’; each element appears once, suffixed with its atom count when the count is greater than 1.

  • Counts are the real atom counts, never divided by a common factor — mode: ‘reduce’ does not produce an empirically-reduced formula the way ASE’s get_chemical_formula(mode=‘reduce’) does.
  • mode: ‘all’ is expected (by ASE convention) to repeat every atom’s symbol without deduplication, but the implementation applies a first-occurrence de-duplication after ordering regardless of mode, so ‘all’ currently produces the same unique, counted output as ‘reduce’ (only ‘hill’ differs, by ordering). Verify against source before relying on ‘all’ returning a non-deduplicated per-atom list.
tako.structure.get_chemical_formula(benzene); // 'C6H6'

tako.structure.get_positions

tako.structure.get_positions(structure: Structure) => [number, number, number][]

Returns the Cartesian position of every atom.

ParameterTypeDefaultContract
structureStructureStructure to read.

Returns: [x, y, z][] in Å, same order as structure.atoms.

tako.structure.get_scaled_positions

tako.structure.get_scaled_positions(structure: Structure) => [number, number, number][]

Returns each atom’s fractional (scaled) coordinate relative to the structure’s cell.

ParameterTypeDefaultContract
structureStructureStructure to read.

Returns: [fx, fy, fz][], dimensionless, same order as structure.atoms.

  • If structure.cell is null, this returns each atom’s stored fx/fy/fz fields directly (which equal its Cartesian x/y/z for atoms created without a cell) rather than throwing.
  • Values are not wrapped into [0, 1) — an atom placed outside the cell keeps out-of-range fractional coordinates until wrap() is called.

tako.structure.get_cell

tako.structure.get_cell(structure: Structure) => [[number,number,number],[number,number,number],[number,number,number]] | null

Returns the three lattice vectors of the structure, or null if it is not periodic.

ParameterTypeDefaultContract
structureStructureStructure to read.

Returns: 3x3 array of Å lattice vectors, or null when structure.cell is null.

tako.structure.set_positions

tako.structure.set_positions(structure: Structure, positions: [number,number,number][], options?: { title?: string }) => Structure

Returns a new Structure with every atom moved to an explicit Cartesian position.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
positions[x,y,z][]One Cartesian position per atom, in Å; length must equal structure.atoms.length (throws otherwise).
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with updated x/y/z (and recomputed fx/fy/fz if a cell is present) and refreshed elements/elementCounts.

const moved = tako.structure.set_positions(structure, tako.structure.get_positions(structure).map(([x, y, z]) => [x, y, z + 1]));

tako.structure.set_scaled_positions

tako.structure.set_scaled_positions(structure: Structure, positions: [number,number,number][], options?: { title?: string }) => Structure

Returns a new Structure with every atom moved to an explicit fractional position, converted to Cartesian via the current cell.

ParameterTypeDefaultContract
structureStructureBase structure; must already have a cell (throws otherwise).
positions[fx,fy,fz][]One fractional coordinate per atom; length must equal structure.atoms.length.
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with x/y/z recomputed from the fractional inputs and the existing cell.

  • Throws “set_scaled_positions requires a cell.” when structure.cell is null.

tako.structure.set_cell

tako.structure.set_cell(structure: Structure, cell: [[number,number,number],[number,number,number],[number,number,number]], options?: { scale_atoms?: boolean; title?: string }) => Structure

Returns a new Structure with a different cell, either keeping Cartesian positions fixed or keeping fractional positions fixed.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
cell[[number,number,number] x3]New lattice vectors in Å.
options.scale_atomsbooleanfalsefalse: keep every atom’s current Cartesian position and recompute fractional coordinates under the new cell. true: keep every atom’s current fractional coordinates and recompute Cartesian positions under the new cell.
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with cell: { vectors: cell, scale: 1 } and positions adjusted per scale_atoms.

const scaled = tako.structure.set_cell(structure, [[6, 0, 0], [0, 6, 0], [0, 0, 6]], { scale_atoms: true });

tako.structure.addAtoms

tako.structure.addAtoms(structure: Structure, atoms: Structure | Structure[], options?: { title?: string }) => Structure

Returns a new Structure with the atoms of one or more other Structures appended, assigning fresh sequential ids.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
atomsStructure | Structure[]Additional structure(s) whose atoms are appended, in argument/array order; each atom’s id is replaced starting at base’s current max id + 1.
options.titlestringstructure.titleTitle for the returned structure.

Returns: New Structure containing base’s atoms followed by the appended atoms, with elements/elementCounts recomputed.

  • The base structure’s cell is preserved: appending to a periodic slab/crystal keeps it periodic, and the appended atoms’ fractional coordinates are recomputed from their Cartesian positions against that cell. Appended atom positions are always interpreted as Cartesian Å — use addFractionalAtoms to place atoms by fractional coordinates.
const co = tako.structure.addAtoms(tako.structure.atom('C', [0, 0, 0]), tako.structure.atom('O', [0, 0, 1.15]));

tako.structure.addFractionalAtoms

tako.structure.addFractionalAtoms(structure: Structure, atoms: Array<[string, [number, number, number]]>, options?: { title?: string }) => Structure

Returns a new periodic Structure with atoms appended at explicit fractional coordinates, converted via the current cell.

ParameterTypeDefaultContract
structureStructureBase structure; must already have a cell (throws “addFractionalAtoms requires a periodic structure with a cell.” otherwise).
atomsArray<[element, [fx, fy, fz]]>Element symbol and fractional coordinate for each new atom; ids assigned starting at base’s current max id + 1.
options.titlestringstructure.titleTitle for the returned structure.

Returns: New Structure with base’s atoms plus the new atoms (Cartesian computed from fractional x cell), and the base’s cell preserved.

const doped = tako.structure.addFractionalAtoms(mapbi3, [['H', [0.02, 0.08, 0.05]]], { title: mapbi3.title });

tako.structure.delete

tako.structure.delete(structure: Structure, selector: number[] | ((atom, index: number) => boolean) | { symbol?: string; element?: string; indices?: number[]; ids?: number[] }, options?: { title?: string }) => Structure

Returns a new Structure with the matched atoms removed and the remaining atoms renumbered.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
selectornumber[] | predicate | { symbol?, element?, indices?, ids? }An array of 0-based atom-array indices (throws if any index is out of range); a predicate (atom, index) => boolean; or an object matching by explicit indices, atom ids, or element/symbol.
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with matched atoms removed; every remaining atom is renumbered id = 1..N in its new order (original ids are not preserved).

  • Selector indices are array positions (0-based), not the atoms’ persistent id field — the same convention as fix, and different from translate/rotate/duplicate, which take id values.
const noHydrogens = tako.structure.delete(structure, { element: 'H' });

tako.structure.translate

tako.structure.translate(structure: Structure, ids: number[], delta: [number, number, number], options?: { title?: string }) => Structure

Returns a new Structure with the atoms matching the given ids shifted by a Cartesian offset.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
idsnumber[]Atom id values (not array indices) to move; ids with no matching atom are silently ignored.
delta[dx, dy, dz]Cartesian offset in Å applied to each selected atom.
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with the selected atoms’ x/y/z shifted by delta (and fx/fy/fz recomputed if a cell is present); unselected atoms are unchanged.

const shifted = tako.structure.translate(structure, [7, 8], [0, 0, 1.5]);

tako.structure.rotate

tako.structure.rotate(structure: Structure, ids: number[], options: { center: [number, number, number]; rotations: Array<{ axis: [number, number, number]; degrees: number }>; title?: string }) => Structure

Returns a new Structure with the atoms matching the given ids rotated in sequence about a shared center.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
idsnumber[]Atom id values (not array indices) to rotate.
options.center[x, y, z]Cartesian rotation center in Å.
options.rotationsArray<{ axis: [x,y,z]; degrees: number }>Ordered list of axis/angle rotations (Rodrigues’ formula), each applied to the result of the previous one — not combined into a single matrix. Near-zero axis length or angle entries are skipped.
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with selected atoms rotated about options.center (fx/fy/fz recomputed if a cell is present); unselected atoms are unchanged.

const spun = tako.structure.rotate(structure, [1, 2, 3], { center: [0, 0, 0], rotations: [{ axis: [0, 0, 1], degrees: 90 }] });

tako.structure.duplicate

tako.structure.duplicate(structure: Structure, ids: number[], delta: [number, number, number], options?: { title?: string }) => { structure: Structure; newIds: number[] }

Returns a new Structure with copies of the atoms matching the given ids, offset by delta, plus the ids assigned to the copies.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
idsnumber[]Atom id values (not array indices) to duplicate.
delta[dx, dy, dz]Cartesian offset in Å applied to each duplicate, relative to its source atom.
options.titlestringunchangedOverrides the title on the returned structure.

Returns: { structure: Structure (original atoms plus duplicates appended), newIds: number[] } — newIds are fresh sequential ids continuing after the structure-wide max id, listed in structure order (not selector order).

  • This is the only tako.structure.* editing call that does not return a bare Structure — the caller needs newIds to select/highlight the copies.
const { structure: withCopy, newIds } = tako.structure.duplicate(structure, [1], [2, 0, 0]);

tako.structure.repeat

tako.structure.repeat(structure: Structure, repeats: [number, number, number], options?: { title?: string }) => Structure

Returns a new periodic Structure tiled nx x ny x nz times, with the cell scaled to match.

ParameterTypeDefaultContract
structureStructureBase structure; must already have a cell (throws “repeat requires a cell.” otherwise).
repeats[nx, ny, nz]Three positive integer repeat counts.
options.titlestring'<structure.title> nx x ny x nz'Title for the returned structure.

Returns: New Structure with nxnynz*atoms.length atoms (ids renumbered 1..N) and cell vectors scaled by [nx, ny, nz] respectively.

const supercell = tako.structure.repeat(unitCell, [2, 2, 1]);

tako.structure.wrap

tako.structure.wrap(structure: Structure, options?: { title?: string }) => Structure

Returns a new Structure with every atom’s fractional coordinates wrapped into [0, 1).

ParameterTypeDefaultContract
structureStructureBase structure; must already have a cell (implemented via set_scaled_positions, which throws “set_scaled_positions requires a cell.” otherwise).
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with fx/fy/fz each wrapped independently via value - floor(value), and Cartesian x/y/z recomputed from the wrapped fractional coordinates.

tako.structure.copy

tako.structure.copy(structure: Structure, options?: { title?: string }) => Structure

Returns a deep (JSON round-trip) clone of the structure, optionally with a new title.

ParameterTypeDefaultContract
structureStructureStructure to clone.
options.titlestringunchangedOverrides the title on the returned copy.

Returns: New Structure, deep-equal to the input except for an optional title change.

tako.structure.fix

tako.structure.fix(structure: Structure, indices: number[], options?: { move?: [boolean, boolean, boolean] }) => Structure

Returns a new Structure with an explicit per-axis movement mask (atom.selective) written onto the selected atoms.

ParameterTypeDefaultContract
structureStructureBase structure (not mutated).
indicesnumber[]0-based atom-array indices (not atom ids) to constrain — the same convention as delete’s array selector.
options.move[boolean, boolean, boolean][false, false, false]Per-axis (x, y, z) freedom mask; true = free to move on that axis. Omitting move freezes all three axes for the selected atoms.

Returns: New Structure where each selected atom has atom.selective set to the given (or default all-false) 3-tuple; unselected atoms are unchanged.

  • The selective mask is forwarded verbatim into the calculation WASM input for any atom that has it set, and is consumed there to freeze the corresponding Cartesian degrees of freedom during optimization/molecular dynamics.
  • fix always writes an explicit mask, including an all-true (fully free) one. The app’s own constraint UI (setAtomConstraints in src/store.ts) additionally deletes atom.selective entirely when the mask is all-true, because a present selective field (even all-true) changes VASP POSCAR export (“Selective dynamics”); tako.structure.fix itself does not do this deletion, so a script that wants to fully release a constraint should delete the field itself rather than call fix with move: [true, true, true] and expect the field to disappear.
const slabFixed = tako.structure.fix(slab, [0, 1, 2, 3]); // freeze the bottom four indices in place

tako.structure.setCellOrigin

tako.structure.setCellOrigin(structure: Structure, origin: [number, number, number], options?: { title?: string }) => Structure

Returns a new Structure whose cell’s fractional origin is moved to a new Cartesian point, without moving any atom’s Cartesian position.

ParameterTypeDefaultContract
structureStructureBase structure; must already have a cell (throws “setCellOrigin requires a cell.” otherwise).
origin[x, y, z]New Cartesian origin (Å) for the cell’s fractional coordinate system.
options.titlestringunchangedOverrides the title on the returned structure.

Returns: New Structure with cell.origin set to origin and every atom’s fx/fy/fz recomputed relative to it; every atom’s Cartesian x/y/z is unchanged.

  • This is a native Tako addition with no ASE equivalent — it only changes where the fractional coordinate system is anchored, not the physical geometry.

Return to the Tako Script API index.