You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This task marks a major milestone in transitioning cheq from a core library into a fully-featured, standalone scientific tool. The goal is to build a robust and user-friendly Command-Line Interface (CLI) that exposes the power of the cheq solver directly to end-users. This will enable researchers, students, and engineers to perform charge equilibration calculations without writing any code, using standard molecular file formats.
The implementation will be a new binary target within the cheq crate, located at src/bin/cheq/. It will leverage the clap crate for state-of-the-art argument parsing and will be architected with a strong separation of concerns: CLI definition, I/O handling, and application logic will reside in distinct modules to ensure maintainability and testability. The CLI will support reading from both files and standard input (stdin), making it highly composable within Unix-style pipelines.
Tasks:
Phase 1: Project Scaffolding and CLI Definition
Add clap (version = "4.0", with derive feature) and thiserror to the [dependencies] section in Cargo.toml.
Create a new binary target in Cargo.toml: [[bin]] name = "cheq" path = "src/bin/main.rs".
Create the new directory structure: src/bin/.
Create src/bin/cli.rs and define the Cli struct using clap::Parser.
Arguments & Options:
input: A required positional argument for the input XYZ file path. Special value - should be supported for stdin.
-o, --output <PATH>: An optional path for the output file. Defaults to stdout.
-f, --format <FORMAT>: An optional output format. Define an enum OutputFormat with variants Pretty, Xyz, Csv, Json. Default to Pretty.
-c, --charge <CHARGE>: An optional total system charge, defaulting to 0.0.
-p, --params <PATH>: An optional path to a custom TOML parameter file.
-v, --verbose: An optional flag to enable verbose logging (e.g., SCF iterations).
Advanced solver options: --tolerance, --max-iter, --lambda for fine-tuning.
Handle both file paths and the special - stdin identifier.
Correctly parse element symbols or atomic numbers from the first column.
Store and return the comment line for later use.
Return a custom CliError::XyzParse on format errors.
Output Formatting: Implement a dispatcher write_results(...).
write_pretty_table: Formats a human-readable, aligned table to a Write buffer.
write_xyz_charged: Writes a standard XYZ file with an additional fifth column for the computed charges.
write_csv: Writes a CSV file with header atomic_number,x,y,z,charge.
write_json: Serializes the results (including input atoms and computed charges) into a structured JSON format.
Phase 3: Application Logic and Error Handling (main.rs, error.rs)
Create src/bin/main.rs as the application entry point.
Create src/bin/error.rs and define a top-level CliError enum using thiserror.
It should wrap std::io::Error, cheq::CheqError, and define custom variants like XyzParse.
In main.rs, implement the main workflow:
Parse arguments using Cli::parse().
Load parameters: Use the custom file if provided via --params, otherwise use cheq::get_default_parameters().
Configure SolverOptions from CLI arguments.
Instantiate QEqSolver.
Call io::read_xyz to get atom data.
Call solver.solve(...) with the atoms and total charge.
On success, call io::write_results.
On failure, gracefully print the CliError to stderr and exit with a non-zero status code.
Phase 4: End-to-End and Integration Testing
Create integration tests (e.g., in a tests/cli.rs file).
Test Basic Invocation: Run cheq tests/data/water.xyz and check for a successful exit code and valid-looking pretty-table output.
Test Output Formats:
Run cheq tests/data/co.xyz --format xyz and verify the output is a valid 3-line XYZ file with a fifth column.
Run cheq tests/data/methane.xyz --format csv --charge 1 and parse the CSV output to confirm headers and correct total charge sum.
Test I/O Redirection:
Test piping: cat tests/data/water.xyz | cheq -.
Test output to file: cheq tests/data/water.xyz -o temp.txt, then read and verify temp.txt.
Test Custom Parameters: Create a minimal custom params.toml, run cheq ... --params custom.toml, and assert the calculated charges differ from the default run.
Test Error Scenarios:
Run cheq non_existent_file.xyz and check for a file-not-found error message and non-zero exit code.
Run cheq malformed.xyz and check for a parsing error.
Run cheq molecule_with_unknown_element.xyz and check that the ParameterNotFound error from the core library is propagated correctly.
Description:
This task marks a major milestone in transitioning
cheqfrom a core library into a fully-featured, standalone scientific tool. The goal is to build a robust and user-friendly Command-Line Interface (CLI) that exposes the power of thecheqsolver directly to end-users. This will enable researchers, students, and engineers to perform charge equilibration calculations without writing any code, using standard molecular file formats.The implementation will be a new binary target within the
cheqcrate, located atsrc/bin/cheq/. It will leverage theclapcrate for state-of-the-art argument parsing and will be architected with a strong separation of concerns: CLI definition, I/O handling, and application logic will reside in distinct modules to ensure maintainability and testability. The CLI will support reading from both files and standard input (stdin), making it highly composable within Unix-style pipelines.Tasks:
Phase 1: Project Scaffolding and CLI Definition
clap(version = "4.0", withderivefeature) andthiserrorto the[dependencies]section inCargo.toml.Cargo.toml:[[bin]] name = "cheq" path = "src/bin/main.rs".src/bin/.src/bin/cli.rsand define theClistruct usingclap::Parser.input: A required positional argument for the input XYZ file path. Special value-should be supported for stdin.-o, --output <PATH>: An optional path for the output file. Defaults to stdout.-f, --format <FORMAT>: An optional output format. Define an enumOutputFormatwith variantsPretty,Xyz,Csv,Json. Default toPretty.-c, --charge <CHARGE>: An optional total system charge, defaulting to0.0.-p, --params <PATH>: An optional path to a custom TOML parameter file.-v, --verbose: An optional flag to enable verbose logging (e.g., SCF iterations).--tolerance,--max-iter,--lambdafor fine-tuning.Phase 2: I/O Module Implementation (
io.rs)src/bin/io.rs.read_xyz(input_path: &str) -> Result<(Vec<cheq::Atom>, String), CliError>.-stdin identifier.CliError::XyzParseon format errors.write_results(...).write_pretty_table: Formats a human-readable, aligned table to aWritebuffer.write_xyz_charged: Writes a standard XYZ file with an additional fifth column for the computed charges.write_csv: Writes a CSV file with headeratomic_number,x,y,z,charge.write_json: Serializes the results (including input atoms and computed charges) into a structured JSON format.Phase 3: Application Logic and Error Handling (
main.rs,error.rs)src/bin/main.rsas the application entry point.src/bin/error.rsand define a top-levelCliErrorenum usingthiserror.std::io::Error,cheq::CheqError, and define custom variants likeXyzParse.main.rs, implement the main workflow:Cli::parse().--params, otherwise usecheq::get_default_parameters().SolverOptionsfrom CLI arguments.QEqSolver.io::read_xyzto get atom data.solver.solve(...)with the atoms and total charge.io::write_results.CliErrorto stderr and exit with a non-zero status code.Phase 4: End-to-End and Integration Testing
tests/cli.rsfile).cheq tests/data/water.xyzand check for a successful exit code and valid-looking pretty-table output.cheq tests/data/co.xyz --format xyzand verify the output is a valid 3-line XYZ file with a fifth column.cheq tests/data/methane.xyz --format csv --charge 1and parse the CSV output to confirm headers and correct total charge sum.cat tests/data/water.xyz | cheq -.cheq tests/data/water.xyz -o temp.txt, then read and verifytemp.txt.params.toml, runcheq ... --params custom.toml, and assert the calculated charges differ from the default run.cheq non_existent_file.xyzand check for a file-not-found error message and non-zero exit code.cheq malformed.xyzand check for a parsing error.cheq molecule_with_unknown_element.xyzand check that theParameterNotFounderror from the core library is propagated correctly.