Library
* completely changed build system for Python module, from setuptools to scikit-build-core
* optimized electron density calculation: single-precision version is now about 2x faster and slightly less exact; some other grid-based calculations also got optimized in the process
* as part of the above optimizations, some of the grid computations require that the model is in the standard orientation (conventional axis directions); in other cases (which are very rare after the [remediation of non-standard coordinate frames](https://www.wwpdb.org/news/news?year=2023#6525a09ad78e004e766a96af) in the PDB) call standardize_crystal_frame()
* CIF output: more flexible formatting
* mmCIF writing: category _entity_poly is included by default, with pdbx_strand_id and pdbx_seq_one_letter_code
* minor changes in reading mmCIF coordinate files
* cif: added functions Loop::add_columns(), Loop::remove_column(), Column::erase()
* MRC map format: ORIGIN record is ignored (previously, if ORIGIN was non-zero, Ccp4::full_cell() returned false and some map properties were not set)
* new function Grid::symmetrize_avg()
* fixed bug in ReciprocalGrid::prepare_asu_data()
* added function read_pir_or_fasta() for reading sequences (previously it was undocumented and more limited)
* added function pdbx_one_letter_code() which returns a string like AA(MSE)H…, for _entity_poly.pdbx_seq_one_letter_code
* new functions expand_one_letter() and expand_one_letter_sequence() that take ResidueKind.AA/RNA/DNA as argument replaced expand_protein_one_letter*()
* adjusted weights in align_sequence_to_polymer()
* added function assign_best_sequences()
* PDB reading: added Structure::ter_status flag to indicate if TER records were: absent, present, clearly in wrong places
* experimental (not documented yet) new functions: Model::get_cra(), Model::get_parent_of()
* Topo::Bond stores a flag for bonds between different symmetry images
* ChemComp::Atom: store _chem_comp_atom.alt_atom_id as old_id, use it in new function update_old_atom_names()
* riding hydrogens: added H had wrong occupancy in special, rare cases
* added Vec3f – Vec3 with single-precision numbers
* minor API changes: Binner::setup() doesn't return anything, changed argument types of Scaling::scale_data(), align_sequences()
Program
* new tool gemmi-diff that compares categories and tags in two (mm)CIF files
* gemmi-align prints vertical list with option --verbose
* gemmi-residues has new options: -e, -sss, --chains
* gemmi-rmsz: added option --missing to print missing atoms
* gemmi-validate: more options for validating monomer files
* gemmi-h: more options
* gemmi-mtz: prints info about SYMM records