Skip to content

Commit

Permalink
gemmi h: don't require option --monomers when reading chemcomp file
Browse files Browse the repository at this point in the history
  • Loading branch information
wojdyr committed Nov 21, 2024
1 parent b9a5cb9 commit 063651c
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 15 deletions.
5 changes: 5 additions & 0 deletions docs/program.rst
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,11 @@ that atom is assigned one of possible positions and its occupancy is zeroed.
.. literalinclude:: h-help.txt
:language: console

To test the addition of hydrogen to a single chemical component
from a monomer library, run::

gemmi h --format=chemcomp -L+ XYZ.cif output.pdb

mondiff
=======

Expand Down
19 changes: 11 additions & 8 deletions prog/h.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,25 @@ int GEMMI_MAIN(int argc, char **argv) {
else if (p.options[RemoveH])
h_change = gemmi::HydrogenChange::Remove;

MonArguments mon_args;
if (h_change != gemmi::HydrogenChange::Remove)
mon_args = get_monomer_args(p.options);

if (p.options[Verbose])
std::printf("Reading coordinates from %s\n", input.c_str());
gemmi::CoorFormat input_format = coor_format_as_enum(p.options[FormatIn]);
if (input_format == gemmi::CoorFormat::Unknown)
input_format = gemmi::coor_format_from_ext_gz(input);
gemmi::CoorFormat output_format = gemmi::coor_format_from_ext_gz(output);
bool preserve_doc = (input_format == gemmi::CoorFormat::Mmcif &&
output_format == gemmi::CoorFormat::Mmcif);

MonArguments mon_args;
if (h_change != gemmi::HydrogenChange::Remove) {
bool needs_monlib = input_format != gemmi::CoorFormat::ChemComp;
mon_args = get_monomer_args(p.options, needs_monlib);
}

if (p.options[Verbose])
std::printf("Reading coordinates from %s\n", input.c_str());
try {
gemmi::Structure st;
std::unique_ptr<cif::Document> doc;
if (preserve_doc)
if (preserve_doc || mon_args.has_plus())
doc.reset(new cif::Document);
st = gemmi::read_structure_gz(input, input_format, doc.get());
if (st.models.empty() || st.models[0].chains.empty()) {
Expand Down Expand Up @@ -139,7 +142,7 @@ int GEMMI_MAIN(int argc, char **argv) {
if (p.options[Verbose])
std::printf("Writing coordinates to %s\n", output.c_str());
gemmi::Ofstream os(output, &std::cout);
if (gemmi::coor_format_from_ext_gz(output) == gemmi::CoorFormat::Pdb) {
if (output_format == gemmi::CoorFormat::Pdb) {
shorten_ccd_codes(st);
gemmi::write_pdb(st, os.ref());
} else {
Expand Down
17 changes: 11 additions & 6 deletions prog/monlib_opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ const option::Descriptor MonLibUsage[] = {
"\nExample 2: -L@ -L file.cif order: ML, file.cif" }
};

MonArguments get_monomer_args(const std::vector<option::Option>& options) {
MonArguments get_monomer_args(const std::vector<option::Option>& options, bool needs_monlib) {
MonArguments args;
const option::Option* mon = options[Monomers];
args.monomer_dir = mon ? mon->arg : std::getenv("CLIBD_MON");
if (args.monomer_dir == nullptr || args.monomer_dir[0] == '\0') {
fprintf(stderr, "Set $CLIBD_MON or use option --monomers.\n");
std::exit(1);
if (needs_monlib) {
fprintf(stderr, "Set $CLIBD_MON or use option --monomers.\n");
std::exit(1);
}
args.monomer_dir = nullptr;
}
args.libin = options[Libin];
args.verbose = options[Verbose].count();
Expand Down Expand Up @@ -68,9 +71,11 @@ void read_monomer_lib_and_user_files(gemmi::MonLib& monlib,
putc('\n', stderr);
}
}
if (args.verbose)
fprintf(stderr, "Reading monomer library...\n");
monlib.read_monomer_lib(args.monomer_dir, wanted, {&gemmi::Logger::to_stderr});
if (args.monomer_dir) {
if (args.verbose)
fprintf(stderr, "Reading monomer library...\n");
monlib.read_monomer_lib(args.monomer_dir, wanted, {&gemmi::Logger::to_stderr});
}
auto is_found = [&](const std::string& s) { return monlib.monomers.count(s); };
gemmi::vector_remove_if(wanted, is_found);
if (libin) {
Expand Down
10 changes: 9 additions & 1 deletion prog/monlib_opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ struct MonArguments {
const char* monomer_dir;
const option::Option* libin;
int verbose;

bool has_plus() const {
for (auto it = libin; it; it = it->next())
if (it->arg[0] == '+' && it->arg[1] == '\0')
return true;
return false;
}
};


// Exits w/ error if monomer dir is not specified (--monomers or $CLIBD_MON)
MonArguments get_monomer_args(const std::vector<option::Option>& options);
MonArguments get_monomer_args(const std::vector<option::Option>& options, bool needs_monlib=true);

// Read monomer library and user-provided cif files according to args.
// st_doc is used if we read monomer blocks from coordinate mmCIF.
Expand Down

0 comments on commit 063651c

Please sign in to comment.