Git Product home page Git Product logo

chemfiles.rs's Introduction

Chemfiles: a library for reading and writing chemistry files

Documentation Build Status Code Coverage Gitter DOI

Chemfiles is a high-quality library for reading and writing trajectory files created by computational chemistry simulations programs. To help you access information (atomic positions, velocities, names, topology, etc.) about these files, Chemfiles provides a simple and unified interface to a variety of file formats.

  • unified: the same code will work with all supported formats;
  • simple: the interface is easy to use and extensively documented.

You can use Chemfiles to conduct post-processing analysis and extract physical information about the systems you're simulating, to convert files from one format to another, to write trajectories with your own simulation software, and anything that requires reading or writing the file formats used in computational chemistry.

Chemfiles is used in multiple scientific software

  • cfiles provides ready-to-use analysis algorithms simulations trajectories as a command line tool;
  • lemon is a framework for rapidly mining structural information from the Protein Data Bank;
  • lumol is a prototype of universal extensible molecular simulation engine, supporting both molecular dynamics and Metropolis Monte Carlo simulations;
  • ANA detects cavities, calculates their volume and their flexibility in macromolecular structures and molecular dynamics trajectories;

This repository contains the core of the chemfiles library โ€” written in C++11, with a C99 interface. You can also use chemfiles from other languages: Python 2&3, Fortran, Rust, and Julia.

Quick Links

Is chemfiles for you?

You might want to use chemfiles if any of these points appeals to you:

  • you don't want to spend time writing and debugging a file parser;
  • you use binary formats because they are faster and take up less disk space;
  • you write analysis algorithms and want to read more than one trajectory format;
  • you write simulation software and want to use more than one format for input or output.

There are other libraries doing the roughly the same job as chemfiles, have a look at them if chemfiles is not for you. Here we also say why we could not use them instead of creating a new library.

  • OpenBabel is a C++ library providing convertions between more than 110 formats. It is more complex than chemfiles, and distributed under the GPL license.
  • VMD molfile plugins are a collection of plugins witten in C and C++ used by VMD to read/write trajectory files. They do not support a variable number of atoms in a trajectory.
  • MDTraj, MDAnalyis, cclib are Python libraries providing analysis and read capacities for trajectories. Unfortunely, they are only usable from Python.

Chemfiles Features

  • Reads both text (XYZ, PDB, ...) and binary (NetCDF, TNG, ...) file formats;
  • Transparently read and write compressed files (.gz, .xz and .bz2);
  • Filters atoms with a rich selection language, including constrains on multiple atoms;
  • Supports non-constant numbers of atoms in trajectories;
  • Easy-to-use programming interface in Python, C++, C, Fortran 95, Julia and Rust;
  • Cross-platform and usable from Linux, OS X and Windows;
  • Open source and freely available (3-clauses BSD license);

Contact / Contribute / Cite

Chemfiles is free and open source. Your contributions are always welcome!

If you have questions or suggestions, or need help, please open an issue or join us on our Gitter chat room.

If you are using Chemfiles in a published scientific study, please cite us using the following DOI: https://doi.org/10.5281/zenodo.3653157.

Getting Started

Here, we'll help you get started with the C++ and C interface. If you want to use Chemfiles with another language, please refer to the corresponding documentation.

Installing Compiled Packages

We provide compiled packages of the latest Chemfiles release for Linux distributions. You can use your package manager to download them here.

We also provide conda packages in the conda-forge community channel for Linux and OS X. This package provides the C++, C and Python interfaces. Install the conda package by running:

conda install -c conda-forge chemfiles

Find more information about pre-compiled packages in the documentation.

Building from Source

You will need cmake and a C++11 compiler.

git clone https://github.com/chemfiles/chemfiles
cd chemfiles
mkdir build
cd build
cmake ..
make
make install

Usage Examples

This is what the interface looks like in C++:

#include <iostream>
#include "chemfiles.hpp"

int main() {
    chemfiles::Trajectory trajectory("filename.xyz");

    auto frame = trajectory.read();
    std::cout << "There are " << frame.size() << " atoms in the frame" << std::endl;

    auto positions = frame.positions();
    // Do awesome science with the positions here !
}

License

Guillaume Fraux created and maintains Chemfiles, which is distributed under the 3 clauses BSD license. By contributing to Chemfiles, you agree to distribute your contributions under the same license.

Chemfiles depends on multiple external libraries, which are distributed under their respective licenses. All external libraries licenses should be compatible with chemfiles's 3 clauses BSD. One notable execption depending on your use case is Gemmi which is distributed under the Mozilla Public License version 2. You can use CHFL_DISABLE_GEMMI=ON CMake flag to remove this dependency.

The AUTHORS file lists all contributors to Chemfiles. Many thanks to all of them!

chemfiles.rs's People

Contributors

ezavod avatar luthaf avatar schneiderfelipe avatar xis19 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

chemfiles.rs's Issues

Change return type of frame cell to Option

Many file formats do not always store a bounding box. I think it would be a significant usability improvement if getting the cell from a frame behaved the same way as getting the velocities (#25).

Currently, if the frame does not contain a cell it will silently return a default cell that is initialized with all matrix elements set to zero. In order to check for this one must iterate over the matrix elements and assume that a matrix full of zeros means the cell was not found in the file.

I would be happy to make a pull request that addresses this from the Rust side if it is something that doesn't need to be handled in the underlying C++ code.

Implement Debug for Trajectory

It looks like that Trajectory does not implement Debug

/// The `Trajectory` type is the main entry point when using chemfiles. A
/// `Trajectory` behave a bit like a file, allowing to read and/or write
/// `Frame`.
pub struct Trajectory {
handle: *mut CHFL_TRAJECTORY,
}

Is there a reason for that?

Build error on FreeBSD

Indeed, now it goes a bit further, but still fails with:

error: linking with `cc` failed: exit status: 1
|
= note: LC_ALL="C" PATH="/usr/local/lib/rustlib/x86_64-unknown-freebsd/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/home/vedran/bin" VSLANG="1033" "cc" "-m64" "/tmp/rustcQevRot/symbols.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.130h5kqru05rr8ro.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.1at30heg74g0c2e6.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.1i3t0v8r5eovt8vj.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.1rf7p6t4islwzwf7.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.1u8rl6lsr3p3dpit.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.1xryfs9kll1oodc8.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.2bmpnjz8x0gouyd8.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.2f8oqycsmsj89qmw.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.2i78pzqw1dsn6pmp.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.2jbuyonqavws4azb.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.2jvx05fzg5k6f6ty.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.2o87ebjjf4fh5n9u.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.2z2zzq4840jebj7x.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.333mnlbd9ink2huc.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.33zwh5esq91ad59j.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.34gt9qo0e7v22al3.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.3bryiswb1dwv74ww.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.3mrsup8gfa2uevuy.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.3pgb3c7fvmp3m4qu.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.3sp3tqxb4at5woxg.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.3u17y5s5i7efzlbo.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.3vjgecv7nj2ql6ou.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.42crbf2a4k5j2db.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.49ot3tup8v2b9jzp.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.4fedee36eiilwvig.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.4g0obb2c07nas7l9.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.4gjz8bbdqs0xmrnq.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.4ladmqfdpbwexkpq.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.bdl61ul540324pg.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.nusywcdkjx7nuk1.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.xiz33lq7q3cia4x.rcgu.o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25.3uocuac4x8tt97mx.rcgu.o" "-Wl,--as-needed" "-L" "/home/vedran/workspace/lumol/target/debug/deps" "-L" "/home/vedran/workspace/lumol/target/debug/build/chemfiles-sys-566666270bf800cd/out/lib" "-L" "/usr/lib" "-L" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib" "-Wl,-Bstatic" "/home/vedran/workspace/lumol/target/debug/deps/liblumol-af24433331c132e4.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblumol_input-37d7d2fd51f4db1a.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblog4rs-97bcb8cb8811fa59.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblog_mdc-f32789b18930b5ee.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libthread_id-24de1b0ff188da02.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libanyhow-bc4ac4a1ed9e7f7b.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libthiserror-19aeceee9f60fb50.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libparking_lot-5c188b5b8017e01d.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libparking_lot_core-e59680b1eb07a763.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libsmallvec-ca4d3571a5c8c098.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblock_api-3a514ecfd18b7934.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libscopeguard-8385fde059363cfb.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libfnv-4a7da0919bab09e2.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libarc_swap-695b13bf5232f654.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libtoml-1897ab00d34c1f12.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libtoml_edit-cf0a0f7f3c25723d.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libserde_spanned-b8fc01c6e398616c.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libindexmap-28a06835edde9fd9.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libequivalent-537bbbe1e7eef26d.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libhashbrown-7709bd1844a1e2ed.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libwinnow-1b85482073adf75b.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libtoml_datetime-3f503e58728e265f.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libserde-9f5bc48fac903a6b.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblumol_sim-aa7dfc0fb3f2a502.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librand_xorshift-3fef059075d90afb.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librand_distr-808287e556768a65.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librand-89723c19071fa17c.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librand_chacha-fce2e506fce70542.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libppv_lite86-172b9fb161880884.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librand_core-bd36663fd3fcb664.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libgetrandom-7dd9bba8dd49d75f.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libcaldyn-cfd5c135bc73a1b7.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblumol_core-5ae317d98aec2667.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libndarray-7d07db1e2a0314cb.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libmatrixmultiply-088206204f9c97a2.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libnum_complex-f2545bb7e348f5c5.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libnum_integer-98d01c20e8a7feb2.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librawpointer-5ebc9ef366ab7a4f.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libchemfiles-fad81fdddc25de6e.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libchemfiles_sys-67207b92ccc9a731.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libbitflags-bafb7e17fbeb7729.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libsoa_derive-8b0073497c50b7d8.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libpermutation-c04f976f79a6410d.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librayon-938faddbd6e7b6ac.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librayon_core-0dd8e8bf28d6aa57.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libcrossbeam_deque-e2173b2dac5282b1.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libcrossbeam_epoch-9c1f5fdc882de003.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libcrossbeam_utils-d81d46f55b81eb0f.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libeither-226e3f8001646fff.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblog_once-02ef154c52f7dd30.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblazy_static-192e6184851990b5.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libspecial-2bd1d156852a9022.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblibm-793f12ecbfd756a2.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libthread_local-d1362bdf3bee472b.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libonce_cell-7051b6138c53b2cf.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblog-3752f34268c1f335.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libclap-d234d283a26bfc02.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libclap_builder-dc213f1daa455dab.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libstrsim-8bb31688261f44a7.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libanstream-8741da0b6bad9867.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libanstyle_query-a0cb7129e8cd0b44.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libcolorchoice-e3f0bb0e4c50c0ee.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libanstyle_parse-9939fe0a7485741d.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libutf8parse-f3ccd09581932eb3.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libclap_lex-2c0bf59f3bcaa105.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libanstyle-3c57e224ef964a94.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libchrono-035cb39a84b09ded.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libnum_traits-effd3fcbf008d0c3.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libiana_time_zone-c01ec3fcc96110ef.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libbacktrace-9ea7549e89b3c602.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libminiz_oxide-5b0e45bda437bbc3.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libadler-a905b27adb3df7ae.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libobject-7665aead2a5bc33a.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libmemchr-00caa8612e79ad09.rlib" "/home/vedran/workspace/lumol/target/debug/deps/liblibc-e5c91cb361609993.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libaddr2line-14585abcbd2c6883.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libgimli-f350de4a1c584736.rlib" "/home/vedran/workspace/lumol/target/debug/deps/libcfg_if-b4544ba88038e686.rlib" "/home/vedran/workspace/lumol/target/debug/deps/librustc_demangle-fc0684191aed3f95.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libstd-749fc163998e3b57.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libpanic_unwind-3324aedb7da8df53.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libobject-bc443a8c9b6a5af6.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libmemchr-32aa4d6d2c594b5a.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libaddr2line-ed7601c080312510.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libgimli-0081e03f58ee1da7.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/librustc_demangle-d609ff5272dccaba.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libstd_detect-3a5ac86785f500b3.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libhashbrown-32378335710e5990.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/librustc_std_workspace_alloc-1bdd891611287621.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libminiz_oxide-10783897338a5242.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libadler-a209363d25099528.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libunwind-5df04f060bbbbd80.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libcfg_if-24680301f326b512.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/liblibc-157fec8f38914dc1.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/liballoc-fa2699c8de87ae5a.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/librustc_std_workspace_core-9d191736d9334602.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libcore-5cc782c3786c4249.rlib" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib/libcompiler_builtins-86cbd9faabce4993.rlib" "-Wl,-Bdynamic" "-lc++" "-lm" "-lc" "-lgcc" "-lgcc_s" "-lrt" "-lutil" "-lexecinfo" "-lkvm" "-lmemstat" "-lkvm" "-lutil" "-lprocstat" "-lrt" "-ldevstat" "-lexecinfo" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lrt" "-lutil" "-lexecinfo" "-lkvm" "-lmemstat" "-lkvm" "-lutil" "-lprocstat" "-lrt" "-ldevstat" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/usr/local/lib/rustlib/x86_64-unknown-freebsd/lib" "-o" "/home/vedran/workspace/lumol/target/debug/deps/lumol-ef1b8494ed028c25" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs"
= note: ld: error: undefined symbol: lseek64
>>> referenced by gzlib.c
>>>               gzlib.c.o:(gz_open) in archive /home/vedran/workspace/lumol/target/debug/deps/libchemfiles_sys-67207b92ccc9a731.rlib
>>> referenced by gzlib.c
>>>               gzlib.c.o:(gz_open) in archive /home/vedran/workspace/lumol/target/debug/deps/libchemfiles_sys-67207b92ccc9a731.rlib
>>> referenced by gzlib.c
>>>               gzlib.c.o:(gzrewind) in archive /home/vedran/workspace/lumol/target/debug/deps/libchemfiles_sys-67207b92ccc9a731.rlib
>>> referenced 3 more times
cc: error: linker command failed with exit code 1 (use -v to see invocation)


error: could not compile `lumol` (bin "lumol") due to previous error

Any ideas? I completely understand if Lumol is not your focus anymore and don't have time to look into it deeper.

Originally posted by @vedranmiletic in lumol-org/lumol#269 (comment)

Return type of frame velocities

Should frame.velocities() return an Option?

This would eliminate the use of boilerplate code like

let velocities = if frame.has_velocities() {
    Some(frame.velocities())
} else {
    None
};

(from #24) and would make the Rust API more similar to the C++ API which uses optional<span<Vector3D>>.

Install Molfiles plugins

Molfiles plugins are currently built with the chemfiles library, but not installed, nor available for usage.

Here is a two step way of getting them available to the C++ code

  • Export CHEMFILES_PLUGINS from rust code to point to .../chemfiles.rs/target/release/build/chemfiles-sys-*/out/build/lib/molfiles;
  • Install the plugins in some way system wide.

Floating point exception when linked with lld

lld is a linker developed by the LLVM team that (supposedly) has better performance than most system linkers. It is recommended for faster iterative builds by popular crates like Bevy and by the Rust performance book. chemfiles seems to crash with floating point exception (core dumped) when compiled with this linker.

To reproduce this, create a new project using lld:

cargo init chemfiles_lld
cd chemfiles_lld
mkdir .cargo
echo '[build]\nrustflags = ["-C", "link-arg=-fuse-ld=lld"]\n' > .cargo/config.toml

Then add chemfiles to Cargo.toml, add the example program in the readme to src/main.rs, and try to run with cargo run.

I understand that this is probably more effort than it's worth to fix, but I thought I'd raise it just in case someone was interested :) Thanks for chemfiles!

Shouldn't guess_format accept &Path instead of &str?

In

chemfiles.rs/src/misc.rs

Lines 127 to 136 in 9f3b1b2

pub fn guess_format(path: &str) -> String {
let path = crate::strings::to_c(path);
let mut buffer = vec![0; 128];
unsafe {
check_success(chfl_guess_format(
path.as_ptr(), buffer.as_mut_ptr(), buffer.len() as u64
));
}
return crate::strings::from_c(buffer.as_ptr());
}

one would expect &Path (even better: AsRef<Path>) to be received instead of &str, as the conversion from the first to the second may fail in Rust due to Unicode requirements.

Maybe there's a reason for that?

Shared methods could be defined as traits

The Frame and the Topology structs share methods to access and modify the topology of a system. These methods, defined as a trait, would allow writing functions that can accept both a Frame and a Topology. Having more than one trait would also allow sharing methods with TopologyRef.

From a quick look at the documentation, I would suggest two traits:

  • AccessTopology could be defined for Topology, TopologyRef, and Frame. It could have the following methods:
    • atom
    • size
  • MulateTopology could be defined for Topology and Frame and have:
    • atom_mut
    • resize
    • add_atom
    • remove
    • add_bond
    • add_bond_with_order
    • remove_bond
    • add_residue
    • clear_bonds

Counterintuitively, neither Topology nor TopologyRef have iter_atoms, which would work well in the AccessTopology trait. Since Frame does not have any method to access residues, bonds, angles, or dihedrals (bond, angle, and dihedral return the measure of the connection, not the connection itself), the AccessTopology trait could also be named AccessAtoms.

With these traits, it would be possible to write code like:

fn do_something_with_the_atoms(source: &impl AccessTopology) {
    for atom in source.iter_atoms() {
        // something
    }
}

fn main() {
    let frame: Frame = ...;
    let topology: Topology = ...;
    do_something_with_the_atoms(frame);
    do_something_with_the_atoms(topology);
}

If there is interest, I'd be happy to work on a pull request.

Error handling in guess_format

chemfiles::guess_format checks errors by using check_success, which panics, but it could use check and return an error without panicking. Maybe there's a reason for that?

chemfiles.rs/src/misc.rs

Lines 127 to 136 in 9f3b1b2

pub fn guess_format(path: &str) -> String {
let path = crate::strings::to_c(path);
let mut buffer = vec![0; 128];
unsafe {
check_success(chfl_guess_format(
path.as_ptr(), buffer.as_mut_ptr(), buffer.len() as u64
));
}
return crate::strings::from_c(buffer.as_ptr());
}

A suggested modification would be

        // From line 131:
        check(chfl_guess_format( 
            path.as_ptr(), buffer.as_mut_ptr(), buffer.len() as u64 
        ))?;

and changing the return type accordingly.

For reference:

chemfiles.rs/src/errors.rs

Lines 108 to 120 in 92e393b

/// Check return value of a C function, and get the error if needed.
pub(crate) fn check(status: chfl_status) -> Result<(), Error> {
if status == chfl_status::CHFL_SUCCESS {
Ok(())
} else {
Err(Error::from(status))
}
}
/// Check return value of a C function, panic if it failed.
pub(crate) fn check_success(status: chfl_status) {
assert!(status == chfl_status::CHFL_SUCCESS, "unexpected failure: {}", Error::last_error());
}

Add examples to all functions

We need to add usage example to all function, possibly re-using and adapting the C API examples.

If you want to help with this, please comment here! I can mentor you and help you going.

Decouple argument types in Trajectory::memory_reader

This is sort of a suggestion, but the current signature is

pub fn memory_reader<'a, S>(data: S, format: S) -> Result<Trajectory, Error>
where S: Into<&'a str>,

when it could be

pub fn memory_reader<'a, S, T>(data: S, format: T) -> Result<Trajectory, Error> 
where S: Into<&'a str>,
      T: Into<&'a str>,
...

which would allow things such as

let data = if maybe_should_modify_string {
    maybe_modifies_string("cc")  // may sometimes allocate, so returns Cow<'_, str>
} else {
    "cc".into()
};
let _ = Trajectory::memory_reader(data, "SMI")?;
...

As a side note, is there a reason why it is Into<&'a str> and not AsRef<str>?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.