diff --git a/README.md b/README.md index 1e5b0b3..afd7ae3 100644 --- a/README.md +++ b/README.md @@ -42,26 +42,25 @@ ttsim3d-cli --help The following are descriptions of each of the options for the program -| Argument | Type | Description -|----------|------|------------ -| `--pixel-spacing` | float | Value greater than zero for the size of each pixel/voxel, in units of Angstroms. -| `--volume-shape` | list | List of integers specifying the output volume shape in pixels. For example, `'[256, 256, 256]'`. -| `--pdb-filepath` | path | Path to the .pdb file to simulate -| `--b-factor-scaling` | float | Multiplicative scaling to apply to atom b-factors in the .pdb file. Default is `1.0`. -| `--additional-b-factor` | float | Additional b-factor to add to all atoms in the .pdb file. Default is `0.0`. -| `--config-voltage` | float | Microscope voltage, in keV, to use for the simulation. -| `--config-apply-dose-weighting` / `--no-config-apply-dose-weighting` | selection | Option for choosing weather to apply cumulative dose weighting to the simulation. Default is `True`. -| `--config-crit-exposure-bfactor` | float | The critical exposure b-factor to use in the dose weighting. If `-1`, then use the resolution-dependent curve described in [Grant & Grigorieff (2015)](https://doi.org/10.7554/eLife.06980). Default is `-1`. -| `--config-dose-filter-modify-signal` | str | Either `"None"`, `"sqrt"`, or `"rel_diff"`. Default is `"None"`. -| `--config-dose-start` | float | Beginning exposure for the cumulative dose filter in e-/A^2. Must be at least `0.0`. Default is `0.0`. -| `--config-dose-end` | float | Ending exposure for the cumulative dose filter in e-/A^2. Must be at least `0.0`. Default is `30.0`. -| `--config-apply-dqe` / `--no-config-apply-dqe` | selection | Option for choosing weather to apply DQE filter to the final volume. -| `--config-mtf-reference` | path | Path to RELION-style .star file holding the modulation transfer function frequencies and amplitudes. -| `--config-upsampling` | int | Integer specifying the level of upsampling used in the simulation. Default is `-1` which corresponds to automatic calculation. -| `--config-store-volume` / `--no-config-store-volume` | selection | Unused for CLI program. -| `--mrc-filepath` | path | The file path to save the MRC file. -| `--gpu-ids` | list | A list of GPU IDs to use for the simulation. -| `--help` | None | Show this message and exit. + +| Option | Type | Default | Description | +| ------------------------------|---------------------------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `--pdb-filepath` | Path | required | The path to the PDB file containing the atomic structure to simulate. +| `--mrc-filepath` | Path | required | File path to save simulated volume. +| `--pixel-spacing` | float | required | The pixel spacing of the simulated volume in units of Angstroms. Must be greater than 0. +| `--volume-shape` | (int, int, int) | required | The shape of the simulated volume in pixels. +| `--voltage` | float | `300.0` | The voltage of the microscope in kV. Default is 300 kV. +| `--upsampling` | int | `-1` | The upsampling factor to apply to the simulation. The default is -1 and corresponds to automatic calculation of the upsampling factor. +| `--b-factor-scaling` | float | `1.0` | The scaling factor to apply to the B-factors of the atoms in the pdb file. The default is 1.0. +| `--additional-b-factor` | float | `0.0` | Additional B-factor to apply to the atoms in the pdb file. The default is 0.0. +| `--apply-dose-weighting` | bool | `True` | If True, apply dose weighting to the simulation. Default is True. +| `--crit-exposure-bfactor` | float | `-1.0` | B-factor to use in critical exposure calculations. The default is -1 and corresponds to the fitted critical exposure function in Grant and Grigorieff, 2015. +| `--dose-filter-modify-signal` | Literal["None", "sqrt", "rel_diff"] | `"None"` | Signal modification to apply to the dose filter. Currently supports 'None', 'sqrt', and 'rel_diff'. +| `--dose-start` | float | `0.0` | The starting dose in e/A^2. +| `--dose-end` | float | `30.0` | The ending dose in e/A^2. +| `--apply-dqe` | bool | `True` | If True, apply a DQE filter to the simulation. +| `--mtf-reference` | Path or str | `"k2_300kV"` | Path to the modulation transfer function (MTF) reference star file, or one of the known MTF reference files. Default is 'k2_300kV'. +| `--gpu-ids` | list[int] | unused | A list of GPU IDs to use for the simulation. Currently unused. ## Python objects diff --git a/pyproject.toml b/pyproject.toml index f379d03..14ec28b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,6 @@ dependencies = [ "requests", "torch-fourier-filter", "pydantic", - "pydanclick" ] [tool.hatch.metadata] @@ -74,7 +73,7 @@ repository = "https://github.com/jdickerson95/ttsim3d" # https://peps.python.org/pep-0621/#entry-points # same as console_scripts entry point [project.scripts] -ttsim3d-cli = "programs.ttsim3d:main" +ttsim3d-cli = "programs.run_ttsim3d:main" # [project.entry-points."some.group"] # tomatoes = "ttsim3d:main_tomatoes" diff --git a/src/programs/run_ttsim3d.py b/src/programs/run_ttsim3d.py new file mode 100644 index 0000000..bd8ed37 --- /dev/null +++ b/src/programs/run_ttsim3d.py @@ -0,0 +1,167 @@ +"""Simple run script.""" + +import click + +from ttsim3d.models import Simulator, SimulatorConfig + + +@click.command() +@click.option( + "--pdb-filepath", + type=click.Path(), + required=True, + help="The path to the PDB file containing the atomic structure to simulate.", +) +@click.option( + "--mrc-filepath", + type=click.Path(), + required=True, + help="File path to save simulated volume.", +) +@click.option( + "--pixel-spacing", + type=float, + help=( + "The pixel spacing of the simulated volume in units of Angstroms. " + "Must be greater than 0." + ), +) +@click.option( + "--volume-shape", + type=(int, int, int), + help="The shape of the simulated volume in pixels.", +) +@click.option( + "--voltage", + type=float, + default=300.0, + help="The voltage of the microscope in kV. Default is 300 kV.", +) +@click.option( + "--upsampling", + type=int, + default=-1, + help=( + "The upsampling factor to apply to the simulation. The default is -1 " + "and corresponds to automatic calculation of the upsampling factor." + ), +) +@click.option( + "--b-factor-scaling", + type=float, + default=1.0, + help=( + "The scaling factor to apply to the B-factors of the atoms in the " + "pdb file. The default is 1.0." + ), +) +@click.option( + "--additional-b-factor", + type=float, + default=0.0, + help=( + "Additional B-factor to apply to the atoms in the pdb file. The " + "default is 0.0." + ), +) +@click.option( + "--apply-dose-weighting", + type=bool, + default=True, + help="If True, apply dose weighting to the simulation. Default is True.", +) +@click.option( + "--crit-exposure-bfactor", + type=float, + default=-1.0, + help=( + "B-factor to use in critical exposure calculations. The default is -1 " + "and corresponds to the fitted critical exposure function in Grant " + "and Grigorieff, 2015." + ), +) +@click.option( + "--dose-filter-modify-signal", + type=click.Choice(["None", "sqrt", "rel_diff"]), + default="None", + help=( + "Signal modification to apply to the dose filter. Currently supports " + "'None', 'sqrt', and 'rel_diff'." + ), +) +@click.option( + "--dose-start", + type=float, + default=0.0, + help="The starting dose in e/A^2. Default is 0.0.", +) +@click.option( + "--dose-end", + type=float, + default=30.0, + help="The ending dose in e/A^2. Default is 30.0.", +) +@click.option( + "--apply-dqe", + is_flag=True, + help="If True, apply a DQE filter to the simulation.", +) +@click.option( + "--mtf-reference", + type=str, + default="k2_300kV", + help=( + "Path to the modulation transfer function (MTF) reference star " + "file, or one of the known MTF reference files. " + "Default is 'k2_300kV'." + ), +) +@click.option( + "--gpu-ids", + type=list[int], + multiple=True, + help="A list of GPU IDs to use for the simulation. Currently unused.", +) +def main( + pdb_filepath: str, + mrc_filepath: str, + pixel_spacing: float, + volume_shape: tuple[int, int, int], + voltage: float, + upsampling: int, + b_factor_scaling: float, + additional_b_factor: float, + apply_dose_weighting: bool, + crit_exposure_bfactor: float, + dose_filter_modify_signal: str, + dose_start: float, + dose_end: float, + apply_dqe: bool, + mtf_reference: str, + gpu_ids: list[int], +) -> None: + """Run a structure simulation through the CLI.""" + simulator_config = SimulatorConfig( + voltage=voltage, + apply_dose_weighting=apply_dose_weighting, + crit_exposure_bfactor=crit_exposure_bfactor, + dose_filter_modify_signal=dose_filter_modify_signal, # type: ignore + dose_start=dose_start, + dose_end=dose_end, + apply_dqe=apply_dqe, + mtf_reference=mtf_reference, + upsampling=upsampling, + ) + simulator = Simulator( + pixel_spacing=pixel_spacing, + volume_shape=volume_shape, + pdb_filepath=pdb_filepath, + b_factor_scaling=b_factor_scaling, + additional_b_factor=additional_b_factor, + simulator_config=simulator_config, + ) + simulator.export_to_mrc(mrc_filepath=mrc_filepath) + + +if __name__ == "__main__": + main() diff --git a/src/programs/ttsim3d.py b/src/programs/ttsim3d.py deleted file mode 100644 index 1488bcd..0000000 --- a/src/programs/ttsim3d.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Simple run script.""" - -import click -from pydanclick import from_pydantic - -from ttsim3d.models import Simulator - - -# TODO: Add brief description for each argument in the help message -# TODO: Test the script for input validation -@click.command() -@from_pydantic( - Simulator, - exclude=[ # These are large, non-serializable tensors - "atom_positions_zyx", - "atom_identities", - "atom_b_factors", - "volume", - ], - docstring_style="numpy", - parse_docstring=True, - rename={"simulator_config": "--config"}, -) # type: ignore -@click.option( - "--mrc-filepath", - type=click.Path(), - required=True, - help="The file path to save the MRC file.", -) -@click.option( - "--gpu-ids", - type=list[int], - multiple=True, - help="A list of GPU IDs to use for the simulation.", -) -def main(params: Simulator, mrc_filepath: str, gpu_ids: tuple[int, ...]) -> None: - """A test function to run the simulate3d function from the ttsim3d package.""" - simulator = Simulator(**params.dict()) - simulator.export_to_mrc( - mrc_filepath=mrc_filepath, gpu_ids=list(gpu_ids) if gpu_ids else None - ) - - -if __name__ == "__main__": - main() diff --git a/src/ttsim3d/simulate3d.py b/src/ttsim3d/simulate3d.py index 3d103b9..6b39f0d 100644 --- a/src/ttsim3d/simulate3d.py +++ b/src/ttsim3d/simulate3d.py @@ -31,7 +31,7 @@ def _calculate_lead_term(beam_energy_kev: float, sim_pixel_spacing: float) -> fl Parameters ---------- beam_energy_kev : float - The beam energy in keV. + The beam energy in kV. sim_pixel_spacing : float The pixel spacing for the final simulation in Angstroms. @@ -492,7 +492,7 @@ def simulate3d( atom_b_factors : torch.Tensor The B factors of each atom in the model. beam_energy_kev : float - The electron beam energy in keV. + The electron beam energy in kV. sim_pixel_spacing : float The pixel spacing for the final simulation in Angstroms. sim_volume_shape : tuple[int, int, int]