libcootapi
 
Loading...
Searching...
No Matches
/opt/conda/conda-bld/coot-headless_1775057007360/work/api/coot-molecule.hh
1/*
2 * api/coot-molecule.hh
3 *
4 * Copyright 2020 by Medical Research Council
5 * Author: Paul Emsley
6 *
7 * This file is part of Coot
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copies of the GNU General Public License and
20 * the GNU Lesser General Public License along with this program; if not,
21 * write to the Free Software Foundation, Inc., 51 Franklin Street,
22 * Fifth Floor, Boston, MA, 02110-1301, USA.
23 * See http://www.gnu.org/licenses/
24 *
25 */
26
27#ifndef COOT_MOLECULE_HH
28#define COOT_MOLECULE_HH
29
30#include <utility>
31#include <atomic>
32#include <array>
33#include <set>
34
35
36#include "compat/coot-sysdep.h"
37
38#include <clipper/core/xmap.h>
39#include "utils/ctpl.h"
40#include "utils/coot-fasta.hh"
41#include "coot-utils/atom-selection-container.hh"
42#include "coot-utils/coot-rama.hh"
43#include "coot-utils/sfcalc-genmap.hh"
44#include "coot-utils/atom-tree.hh"
45#include "coot-utils/texture-as-floats.hh"
46#include "coot-utils/coot-align.hh"
47#include "geometry/residue-and-atom-specs.hh"
48#include "coords/Cartesian.hh"
49#include "coords/Bond_lines.hh"
50#include "ideal/simple-restraint.hh"
51#include "ideal/extra-restraints.hh"
52#include "coot-utils/simple-mesh.hh"
53#include "ghost-molecule-display.hh"
54
55#ifdef MAKE_ENHANCED_LIGAND_TOOLS
56#include "lidia-core/rdkit-interface.hh"
57#endif
58
59#include "density-contour/CIsoSurface.h"
60#include "gensurf.hh"
61#include "coot-utils/coot-shelx.hh"
62
63#include "coot-colour.hh" // put this in utils
64
65#include "coords/mmdb-extras.hh"
66#include "merge-molecule-results-info-t.hh"
67#include "phi-psi-prob.hh"
68
69#include "coot-utils/atom-overlaps.hh"
70#include "symmetry-info.hh" // contains cell
71
72#include "instancing.hh"
73
74#include "generic-3d-lines.hh"
75
76#include "coot-simple-molecule.hh"
77
78#include "coot-utils/coot-map-utils.hh" // for map_molecule_centre_info_t
79#include "api-cell.hh" // 20230702-PE not needed in this file - remove it from here
80
81#include "moved-atom.hh"
82#include "moved-residue.hh"
83
84#include "bond-colour.hh"
85#include "blender-mesh.hh"
86#include "user-defined-colour-table.hh"
87
88// 2023-07-04-PE This is a hack. This should be configured - and the
89// various functions that depend on this being true should be
90// reworked so that they run without a thread pool.
91
92#ifdef HAVE_BOOST_THREAD // part of DEFS in Makefile
93#define HAVE_BOOST_BASED_THREAD_POOL_LIBRARY
94#endif
95
96#include "plain-atom-overlap.hh"
97
98
99namespace coot {
100
101 enum { RESIDUE_NUMBER_UNSET = -1111}; // from molecule-class-info
102
104 class residue_range_t {
105 public:
106 residue_range_t() : res_no_start(-999), res_no_end(-999) {}
107 residue_range_t(const std::string &c, int r1, int r2) : res_no_start(r1), res_no_end(r2) {}
108 std::string chain_id;
109 int res_no_start;
110 int res_no_end;
111 };
112
114 class atom_distance_t {
115 public:
116 atom_distance_t(const atom_spec_t &a1, const atom_spec_t &a2,
117 float d) : atom_1(a1), atom_2(a2), distance(d) {}
118 atom_distance_t() : distance(-1) {}
119 atom_spec_t atom_1;
120 atom_spec_t atom_2;
121 float distance;
122 };
123
125
126 class molecule_save_info_t {
127 public:
128 // ints because we subtract from them.
129 std::pair<time_t, int> last_saved;
130 int modification_index;
131 int max_modification_index;
132 molecule_save_info_t() : last_saved(std::make_pair(0,0)), modification_index(0),
133 max_modification_index(0) {}
134 void new_modification(const std::string &mod_string) {
135 modification_index++;
136 if (false) // debugging
137 std::cout << "new_modification: moved on to " << modification_index
138 << " by " << mod_string << std::endl;
139 if (modification_index > max_modification_index)
140 max_modification_index = modification_index;
141 }
142 void made_a_save() {
143 // this is called when the server says that it has saved the file
144 last_saved.first = time(nullptr);
145 last_saved.second = modification_index;
146 }
147 bool have_unsaved_changes() const {
148 return modification_index > last_saved.second;
149 }
150 std::string index_string(int idx) const {
151 return std::to_string(idx);
152 }
153 void set_modification_index(int idx) {
154 // undo() and redo() (acutally restore_from_backup()) use this.
155 // the index is the idx number given to restore_from_backup() by
156 // the functions below
157 modification_index = idx;
158 }
159 int get_previous_modification_index() const {
160 return modification_index - 1;
161 }
162 int get_next_modification_index() const {
163 return modification_index + 1;
164 }
165 };
166
167 // molecule_save_info_t save_info;
168
169
170 class modification_info_t {
171 public:
172 class save_info_t {
173 public:
174 save_info_t(const std::string &file_name, const std::string &mis) : file_name(file_name), modification_info_string(mis) {}
175 std::string file_name;
176 std::string modification_info_string;
177 mmdb::Manager *get_mol();
178 };
179 private:
180 void init() {};
181 void print_save_info() const;
182 public:
183 modification_info_t() : backup_dir("coot-backup"), mol_name("placeholder"), is_mmcif_flag(false),
184 modification_index(0), max_modification_index(0) {}
185 modification_info_t(const std::string &mol_name_for_backup, bool is_mmcif) :
186 backup_dir("coot-backup"), mol_name(mol_name_for_backup), is_mmcif_flag(is_mmcif),
187 modification_index(0), max_modification_index(0) {}
188 std::string backup_dir;
189 std::string mol_name; // used in construction of filename, it is a stub to which we add an extension
190 bool is_mmcif_flag;
191 std::vector<save_info_t> save_info;
192 int modification_index;
193 int max_modification_index;
194 bool have_unsaved_changes() const;
195 void set_molecule_name(const std::string &molecule_name, bool is_mmcif) { mol_name = molecule_name; is_mmcif_flag = is_mmcif; }
196 std::string get_index_string(int idx) const { return std::to_string(idx); }
197 std::string get_backup_file_name_from_index(int idx) const;
199 std::string make_backup(mmdb::Manager *mol, const std::string &modification_info_string);
201 mmdb::Manager *undo(mmdb::Manager *mol);
203 mmdb::Manager *redo();
204
205 };
206
207 modification_info_t modification_info;
208
209 bool use_gemmi; // true now
210 int imol_no; // this molecule's index in the container vector
211 bool is_closed_flag;
212 int ligand_flip_number;
213 std::string name;
214 bool is_from_shelx_ins_flag;
215 ShelxIns shelxins;
216
217 std::map<residue_spec_t, int> current_rotamer_map;
218 bool really_do_backups; // default true
219
220 // private
221 void makebonds(protein_geometry *geom, rotamer_probability_tables *rotamer_tables_p,
222 const std::set<int> &no_bonds_to_these_atoms,
223 bool draw_hydrogen_atoms_flag, bool draw_missing_loops_flag);
224
225#if defined __has_builtin
226#if __has_builtin (__builtin_FUNCTION)
227 void make_bonds_type_checked(protein_geometry *geom, rotamer_probability_tables *rot_prob_tables_p, bool draw_hydrogen_atoms_flag, bool draw_missing_loops_flag, const char *s = __builtin_FUNCTION());
228 void make_bonds_type_checked(protein_geometry *geom, const std::set<int> &no_bonds_to_these_atom_indices, bool draw_hydrogen_atoms_flag, bool draw_missing_loops_flag, const char *s = __builtin_FUNCTION());
229#else
230 void make_bonds_type_checked(protein_geometry *geom, const char *s = 0);
231 void make_bonds_type_checked(protein_geometry *geom, rotamer_probability_tables *rot_prob_tables_p, bool draw_hydrogen_atoms_flag, bool draw_missing_loops_flag, const char *s = 0);
232#endif
233#else // repeat above
234 void make_bonds_type_checked(protein_geometry *geom, const char *s = 0);
235 void make_bonds_type_checked(protein_geometry *geom, rotamer_probability_tables *rot_prob_tables_p, bool draw_hydrogen_atoms_flag, bool draw_missing_loops_flag, const char *s = 0);
236#endif
237
238 api_bond_colour_t bonds_box_type; // public accessable via get_bonds_box_type(); // wass Bonds_box_type()
239 graphical_bonds_container bonds_box;
240 api_bond_colour_t get_bonds_box_type() const { return bonds_box_type; }
241
242 // this is the bond dictionary also mode.
243 // 20221011-PE force_rebonding arg is not currently used.
244 void make_colour_by_chain_bonds(protein_geometry *geom,
245 const std::set<int> &no_bonds_to_these_atoms,
246 bool change_c_only_flag,
247 bool goodsell_mode,
248 bool draw_hydrogen_atoms_flag,
249 bool draw_missing_loops_flag,
250 bool do_rota_markup=false,
251 rotamer_probability_tables *rotamer_tables_p = nullptr,
252 bool force_rebonding=true);
253 void make_ca_bonds();
254 // just a copy of the version in src
255 float bonds_colour_map_rotation;
256 // std::vector<glm::vec4> make_colour_table(bool against_a_dark_background) const; public now
257 glm::vec4 get_bond_colour_by_colour_wheel_position(int icol, api_bond_colour_t bonds_box_type) const;
258 colour_t get_bond_colour_by_mol_no(int colour_index, bool against_a_dark_background) const;
259 colour_t get_bond_colour_basic(int colour_index, bool against_a_dark_background) const;
260 bool use_bespoke_grey_colour_for_carbon_atoms;
261 colour_t bespoke_carbon_atoms_colour;
262
263 void update_map_triangles(float radius, Cartesian centre, float contour_level); // using vector of threads
264 void update_map_triangles_using_thread_pool(float radius, Cartesian centre, float contour_level, ctpl::thread_pool *thread_pool_p);
265
266 short int is_em_map_cached_flag; // -1 mean unset (so set it, 0 means no, 1 means yes)
267 short int is_em_map_cached_state(); // set is_em_map_cached_flag if not set
268 ghost_molecule_display_t map_ghost_info;
269
270 bool xmap_is_diff_map;
271 bool has_xmap() const { return is_valid_map_molecule(); }
272
273 colour_holder map_colour;
274 glm::vec4 position_to_colour_using_other_map(const clipper::Coord_orth &position,
275 const clipper::Xmap<float> &other_map_for_colouring) const;
276 float other_map_for_colouring_min_value;
277 float other_map_for_colouring_max_value;
278 glm::vec4 fraction_to_colour(float f) const; // for other map colouring - perhaps this function name is too generic?
279 bool radial_map_colour_invert_flag;
280 float radial_map_colour_saturation;
281
282 // save the data used for the fourier, so that we can use it to
283 // sharpen the map:
284 // uncommenting the following line causes a crash in the multi-molecule
285 // (expand molecule space) test.
286 bool original_fphis_filled;
287 bool original_fobs_sigfobs_filled;
288 bool original_fobs_sigfobs_fill_tried_and_failed;
289 clipper::HKL_data< clipper::datatypes::F_phi<float> > *original_fphis_p;
290 clipper::HKL_data< clipper::datatypes::F_sigF<float> > *original_fobs_sigfobs_p;
291 clipper::HKL_data< clipper::data32::Flag> *original_r_free_flags_p;
292
293 void clear_draw_vecs();
294 void clear_diff_map_draw_vecs();
295 std::vector<density_contour_triangles_container_t> draw_vector_sets;
296 std::vector<density_contour_triangles_container_t> draw_diff_map_vector_sets;
297 std::vector<std::pair<int, TRIANGLE> > map_triangle_centres; // with associated mid-points and indices
298
299 // insert coords - c.f function in molecule-class-info_t
300 void insert_coords_internal(const atom_selection_container_t &asc);
301
302 // This function no longer does a backup or updates the save_info!
303 // The calling function should do that.
304 void replace_coords(const atom_selection_container_t &asc,
305 bool change_altconf_occs_flag,
306 bool replace_coords_with_zero_occ_flag);
307 // helper function for above function
308 bool movable_atom(mmdb::Atom *mol_atom, bool replace_coords_with_zero_occ_flag) const;
309 bool moving_atom_matches(mmdb::Atom *at, int this_mol_index_maybe) const;
310 void adjust_occupancy_other_residue_atoms(mmdb::Atom *at,
311 mmdb::Residue *residue,
312 short int force_sum_1_flag);
313
314 // return -1 on failure
315 int full_atom_spec_to_atom_index(const atom_spec_t &atom_spec) const;
316 // return -1 on no atom found.
317 int full_atom_spec_to_atom_index(const std::string &chain,
318 int resno,
319 const std::string &insertion_code,
320 const std::string &atom_name,
321 const std::string &alt_conf) const;
322
323 std::string name_for_display_manager() const;
324 std::string dotted_chopped_name() const;
325 // std::string get_save_molecule_filename(const std::string &dir);
326 std::string make_backup(const std::string &modification_type); // returns warning message, otherwise empty string
327 void save_history_file_name(const std::string &file);
328 std::vector<std::string> history_filename_vec;
329 std::string save_time_string;
330 void restore_from_backup(int mod_index, const std::string &cwd);
331
332 std::vector<atom_spec_t> fixed_atom_specs;
333
334 std::pair<int, mmdb::Residue *>
335 find_serial_number_for_insert(int seqnum_for_new,
336 const std::string &ins_code_for_new,
337 const std::string &chain_id) const;
338
339 // remove TER record from residue
340 //
341 void remove_TER_internal(mmdb::Residue *res_p);
342 void remove_TER_on_last_residue(mmdb::Chain *chain_p);
343 std::pair<bool, std::string> unused_chain_id() const;
344 int append_to_molecule(const minimol::molecule &water_mol);
345
346 glm::vec4 colour_holder_to_glm(const colour_holder &ch) const;
347
348 std::pair<bool, Cartesian> get_HA_unit_vector(mmdb::Residue *r) const;
349
351 void setup_cylinder_clashes(instanced_mesh_t &im, const atom_overlaps_dots_container_t &c,
352 float ball_size, unsigned int num_subdivisions,
353 const std::string &molecule_name_stub) const;
354
356 void setup_dots(instanced_mesh_t &im,
357 const atom_overlaps_dots_container_t &c,
358 float ball_size, unsigned int num_subdivisions,
359 const std::string &molecule_name_stub) const;
360
361 // ====================== SHELX stuff ======================================
362
363 std::pair<int, std::string> write_shelx_ins_file(const std::string &filename) const;
364 int read_shelx_ins_file(const std::string &filename);
365 // return the success status, 0 for fail, 1 for good.
366 int add_shelx_string_to_molecule(const std::string &str);
367 bool is_from_shelx_ins() const { return is_from_shelx_ins_flag; }
368
369 void trim_atom_label_table();
370 void delete_ghost_selections();
371 void update_symmetry();
372 bool show_symmetry;
373
375 void delete_any_link_containing_residue(const residue_spec_t &res_spec);
376 // this doesn't do a backup - the calling function is in charge of that
377 void delete_link(mmdb::Link *link, mmdb::Model *model_p);
378
379 bool sanity_check_atoms(mmdb::Manager *mol) const; // sfcalc_genmap crashes after merge of ligand.
380 // Why? Something wrong with the atoms after merge?
381 // Let's diagnose.... Return false on non-sane.
382
383 // internal function for public rotamer functions
384 int set_residue_to_rotamer_move_atoms(mmdb::Residue *res, mmdb::Residue *moving_res);
385
386 // ====================== Jiggle-Fit (internal) ================================
387
388 float fit_to_map_by_random_jiggle(mmdb::PPAtom atom_selection,
389 int n_atoms,
390 const clipper::Xmap<float> &xmap,
391 float map_sigma,
392 int n_trials,
393 float jiggle_scale_factor,
394 bool use_biased_density_scoring,
395 std::vector<mmdb::Chain *> chains_for_moving);
396
397 minimol::molecule rigid_body_fit(const minimol::molecule &mol_in,
398 const clipper::Xmap<float> &xmap,
399 float map_sigma) const;
400
401 // ====================== validation ======================================
402
403 std::vector<coot::geometry_distortion_info_pod_container_t>
404 geometric_distortions_from_mol(const atom_selection_container_t &asc, bool with_nbcs,
405 coot::protein_geometry &geom,
406 ctpl::thread_pool &static_thread_pool);
407
408
409 // ====================== dragged refinement ======================================
410
411 coot::restraints_container_t *last_restraints;
412
413 // ====================== init ======================================
414
415 void init() {
416 is_closed_flag = false; // changed on close_yourself()
417 // use_gemmi = true; // 20240112-PE woohoo! Let the bugs flow!
418 // 20240118 Turns out the bugs flowed too much. Let's set this back to false.
419 use_gemmi = false;
420 // set the imol before calling this function.
421 ligand_flip_number = 0;
422 bonds_box_type = api_bond_colour_t::UNSET_TYPE;
423 is_em_map_cached_flag = false;
424 xmap_is_diff_map = false;
425 is_from_shelx_ins_flag = false;
426 show_symmetry = false;
427 default_temperature_factor_for_new_atoms = 20.0;
428 original_fphis_filled = false;
429 original_fobs_sigfobs_filled = false;
430 original_fobs_sigfobs_fill_tried_and_failed = false;
431 original_fphis_p = nullptr;
432 original_fobs_sigfobs_p = nullptr;
433 original_r_free_flags_p = nullptr;
434 refmac_r_free_flag_sensible = false;
435 use_bespoke_grey_colour_for_carbon_atoms = false;
436 really_do_backups = true;
437
438 radial_map_colour_saturation = 0.5;
439 radial_map_colour_invert_flag = false;
440
441 other_map_for_colouring_min_value = 0.0;
442 other_map_for_colouring_max_value = 1.0;
443
444 map_colour = colour_holder(0.3, 0.3, 0.7);
445 last_restraints = nullptr;
446
447 float rotate_colour_map_on_read_pdb = 0.24;
448 bonds_colour_map_rotation = (imol_no + 1) * rotate_colour_map_on_read_pdb;
449 while (bonds_colour_map_rotation > 360.0)
450 bonds_colour_map_rotation -= 360.0;
451
452 base_colour_for_bonds = colour_holder(0.43, 0.33, 0.2);
453
454 fill_default_colour_rules();
455 if (false) {
456 auto v = get_colour_rules();
457 std::cout << "colour rules: " << std::endl;
458 std::cout << "-------------" << std::endl;
459 for (unsigned int i=0; i<v.size(); i++) {
460 std::cout << i << " " << v[i].first << " " << v[i].second << std::endl;
461 }
462 std::cout << "-------------" << std::endl;
463 }
464
465 indexed_user_defined_colour_selection_cids_apply_to_non_carbon_atoms_also = true;
466
467 gltf_pbr_roughness = 0.2;
468 gltf_pbr_metalicity = 0.0;
469
470 }
471
472 // chain-id (maybe) and plain sequence.
473 coot::fasta_multi multi_fasta_seq;
474
475 static std::string file_to_string(const std::string &fn);
476
477 public:
478
479 // ---------------------------------------------------------------------------------------------------------------
480 // ---------------------------------------------------------------------------------------------------------------
481 // public
482 // ---------------------------------------------------------------------------------------------------------------
483 // ---------------------------------------------------------------------------------------------------------------
484
485 // enum refine_residues_mode {SINGLE, TRIPLE, QUINTUPLE, HEPTUPLE, SPHERE, BIG_SPHERE, CHAIN, ALL};
486
487 atom_selection_container_t atom_sel;
488 // set this on reading a pdb file
489 float default_temperature_factor_for_new_atoms; // direct access
490
491 // for rsr neighbours - they are fixed.
492 std::vector<std::pair<bool, mmdb::Residue *> > neighbouring_residues;
493
495 molecule_t(const std::string &name_in, int mol_no_in) : name(name_in) {imol_no = mol_no_in; init(); }
497 molecule_t(const std::string &name_in, int mol_no_in, short int is_em_map) : name(name_in) {
498 imol_no = mol_no_in; init(); is_em_map_cached_flag = is_em_map; }
499
500 molecule_t(const std::string &name_in, int mol_no_in, const clipper::Xmap<float> &xmap_in, bool is_em_map_flag)
501 : name(name_in), xmap(xmap_in) {imol_no = mol_no_in; init(); is_em_map_cached_flag = is_em_map_flag; }
502
503 explicit molecule_t(atom_selection_container_t asc, int imol_no_in, const std::string &name_in) : name(name_in), atom_sel(asc) {
504 imol_no = imol_no_in;
505 init();
506 default_temperature_factor_for_new_atoms =
507 util::median_temperature_factor(atom_sel.atom_selection,
508 atom_sel.n_selected_atoms,
509 99999.9, 0.0, false, false);
510 }
511
512 float get_median_temperature_factor() const;
513
514 float get_temperature_factor_of_atom(const std::string &atom_cid) const;
515
516 // ------------------------ close
517
518 int close_yourself();
519
520 bool is_closed() const { return is_closed_flag; }
521
522 // --------------------- backups
523
524 void set_really_do_backups(bool state) { really_do_backups = state; }
525
526 // ------------------------------- rsr utils
527 // - add in the environment of this fragment molecule
528 // from the residue from which this fragment was copied
529 void add_neighbor_residues_for_refinement_help(mmdb::Manager *mol);
530
531 // ----------------------- structure factor stuff ------------------------------------------------------
532
533 void fill_fobs_sigfobs(); // re-reads MTZ file (currently 20210816-PE)
534
535 // used to be a const ref. Now return the whole thing!. Caller must call
536 // fill_fobs_sigfobs() directly before using this function - meh, not a good API.
537 // Return a *pointer* to the data so that we don't get this hideous non-reproducable
538 // crash when we access this data item after the moelcule vector has been resized
539 // 20210816-PE.
540 // CAUTION: this function can throw a std::runtime_error.
541 clipper::HKL_data<clipper::data32::F_sigF> *get_original_fobs_sigfobs() const {
542 if (!original_fobs_sigfobs_filled) {
543 std::string m("Original Fobs/sigFobs is not filled");
544 throw(std::runtime_error(m));
545 }
546 return original_fobs_sigfobs_p;
547 }
548
549 clipper::HKL_data<clipper::data32::Flag> *get_original_rfree_flags() const {
550 if (!original_fobs_sigfobs_filled) {
551 std::string m("Original Fobs/sigFobs is not filled - so no RFree flags");
552 throw(std::runtime_error(m));
553 }
554 return original_r_free_flags_p;
555 }
556 // use this molecules mol and the passed data to make a map for some other
557 // molecule
558 int sfcalc_genmap(const clipper::HKL_data<clipper::data32::F_sigF> &fobs,
559 const clipper::HKL_data<clipper::data32::Flag> &free,
560 clipper::Xmap<float> *xmap_p);
561 util::sfcalc_genmap_stats_t
562 sfcalc_genmaps_using_bulk_solvent(const clipper::HKL_data<clipper::data32::F_sigF> &fobs,
563 const clipper::HKL_data<clipper::data32::Flag> &free,
564 clipper::Xmap<float> *xmap_2fofc_p,
565 clipper::Xmap<float> *xmap_fofc_p);
566 // String munging helper function (for reading mtz files).
567 // Return a pair.first string of length 0 on error to construct dataname(s).
568 std::pair<std::string, std::string> make_import_datanames(const std::string &fcol,
569 const std::string &phi_col,
570 const std::string &weight_col,
571 int use_weights) const;
572 // make these private?
573 std::string refmac_fobs_col;
574 std::string refmac_sigfobs_col;
575 std::string refmac_mtz_filename;
576 std::string refmac_r_free_col;
577 std::string Refmac_fobs_col() const { return refmac_fobs_col; }
578 std::string Refmac_sigfobs_col() const { return refmac_sigfobs_col; }
579 std::string Refmac_mtz_filename() const { return refmac_mtz_filename; }
580 bool refmac_r_free_flag_sensible;
581
582 void associate_data_mtz_file_with_map(const std::string &data_mtz_file_name,
583 const std::string &f_col, const std::string &sigf_col,
584 const std::string &r_free_col);
585
586 // ----------------------- xmap
587
588 clipper::Xmap<float> xmap; // public because the filling function needs access
589
590 // public access to the lock (from threads)
591 static std::atomic<bool> draw_vector_sets_lock;
592
593 util::map_molecule_centre_info_t get_map_molecule_centre() const;
594
595 // ----------------------- utils
596
597 void replace_molecule_by_model_from_file(const std::string &pdb_file_name);
598
599 std::string get_name() const { return name; }
600 void set_molecule_name(const std::string &n) { name = n; };
601 mmdb::Manager *get_mol(); // return null on failure
602 int get_molecule_index() const { return imol_no; }
603 // void set_molecule_index(int idx) { imol_no = idx; } // 20221011-PE needed?
604 bool is_valid_model_molecule() const;
605 bool is_valid_map_molecule() const;
606 unsigned int get_number_of_atoms() const;
607 int get_number_of_hydrogen_atoms() const;
608 float get_molecule_diameter() const;
616
618 std::vector<std::string> get_types_in_molecule() const;
619 mmdb::Residue *cid_to_residue(const std::string &cid) const;
620 std::vector<mmdb::Residue *> cid_to_residues(const std::string &cid) const;
621 mmdb::Atom *cid_to_atom(const std::string &cid) const;
622 std::pair<bool, residue_spec_t> cid_to_residue_spec(const std::string &cid) const;
623 std::pair<bool, atom_spec_t> cid_to_atom_spec(const std::string &cid) const;
624 std::vector<std::string> get_residue_names_with_no_dictionary(const protein_geometry &geom) const;
625 // here res-name might be HOH or DUM
626 int insert_waters_into_molecule(const minimol::molecule &water_mol, const std::string &res_name);
627
628 std::string get_molecule_selection_as_json(const std::string &cid) const;
629 std::string get_torsions_for_residues_in_chain_as_json(const std::string &chain_id) const;
630
631 // ----------------------- model utils
632
637 std::vector<residue_range_t> get_missing_residue_ranges() const;
638
639 // public
640 void make_bonds(protein_geometry *geom, rotamer_probability_tables *rot_prob_tables_p,
641 bool draw_hydrogen_atoms_flag, bool draw_missing_loops_flag);
642
644 std::vector<glm::vec4> make_colour_table(bool against_a_dark_background) const;
645 std::vector<glm::vec4> make_colour_table_for_goodsell_style(float colour_wheel_rotation_step,
646 float saturation, float goodselliness) const;
647
648 // for debugging
649 void print_colour_table(const std::string &debugging_label) const;
650
651 // print_secondary_structure_info
652 void print_secondary_structure_info() const;
653
654 // returns either the specified atom or null if not found
655 mmdb::Atom *get_atom(const atom_spec_t &atom_spec) const;
656 // returns either the specified residue or null if not found
657 mmdb::Residue *get_residue(const residue_spec_t &residue_spec) const;
658
659 // can return null
660 mmdb::Residue *get_residue(const std::string &residue_cid) const;
661
662 std::string get_residue_name(const residue_spec_t &residue_spec) const;
663
664 bool have_unsaved_changes() const { return modification_info.have_unsaved_changes(); }
665 int undo(); // 20221018-PE return status not yet useful
666 int redo(); // likewise
667 // the return value of WritePDBASCII() or WriteCIFASCII(). mmdb return type
668 int write_coordinates(const std::string &file_name) const; // return 0 on OK, 1 on failure
669
671 std::string molecule_to_PDB_string() const;
672
674 std::string molecule_to_mmCIF_string() const;
675
676 std::vector<atom_spec_t> get_fixed_atoms() const;
677
678 std::vector<std::string> chains_in_model() const;
679 std::vector<std::pair<residue_spec_t, std::string> > get_single_letter_codes_for_chain(const std::string &chain_id) const;
680
681 residue_spec_t get_residue_closest_to(mmdb::Manager *mol, const clipper::Coord_orth &co) const;
682
683 std::vector<std::string> get_chain_ids() const;
684
686 std::vector<std::vector<std::string> > get_ncs_related_chains() const;
687
689 bool copy_ncs_chain(const std::string &from_chain_id, const std::string &to_chain_id);
690
694 std::vector<double> get_residue_CA_position(const std::string &cid) const;
695
699 std::vector<double> get_residue_average_position(const std::string &cid) const;
700
704 std::vector<double> get_residue_sidechain_average_position(const std::string &cid) const;
705
712 void set_occupancy(const std::string &cid, float occ_new);
713
714 // ----------------------- model bonds
715
716 simple_mesh_t get_bonds_mesh(const std::string &mode, protein_geometry *geom,
717 bool against_a_dark_background,
718 float bonds_width, float atom_radius_to_bond_width_ratio,
719 int smoothness_factor,
720 bool draw_hydrogen_atoms_flag,
721 bool draw_missing_residue_loops);
722
723 simple_mesh_t get_goodsell_style_mesh(protein_geometry *geom_p, float colour_wheel_rotation_step,
724 float saturation, float goodselliness);
725
726 instanced_mesh_t get_bonds_mesh_instanced(const std::string &mode, protein_geometry *geom,
727 bool against_a_dark_background,
728 float bonds_width, float atom_radius_to_bond_width_ratio,
729 bool render_atoms_as_aniso, // if possible, of course
730 float aniso_probability,
731 bool render_aniso_atoms_as_ortep,
732 bool render_aniso_atoms_as_empty,
733 int smoothness_factor,
734 bool draw_hydrogen_atoms_flag,
735 bool draw_missing_residue_loops);
736
737 instanced_mesh_t get_bonds_mesh_for_selection_instanced(const std::string &mode, const std::string &selection_cid,
738 protein_geometry *geom,
739 bool against_a_dark_background,
740 float bonds_width, float atom_radius_to_bond_width_ratio,
741 bool render_atoms_as_aniso, // if possible, of course
742 bool render_aniso_atoms_as_ortep,
743 bool render_aniso_atoms_as_empty,
744 int smoothness_factor,
745 bool draw_hydrogen_atoms_flag,
746 bool draw_missing_residue_loops);
747
748 instanced_mesh_t get_goodsell_style_mesh_instanced(protein_geometry *geom_p, float colour_wheel_rotation_step,
749 float saturation, float goodselliness);
750
751
752 // adding colours using the functions below add into user_defined_colours
753 std::map<unsigned int, colour_holder> user_defined_bond_colours;
754
755 // we store these variables so that they can be used by (temporary) molecules constructed from atom selections
756 //
757 std::vector<std::pair<std::string, unsigned int> > indexed_user_defined_colour_selection_cids;
758 bool indexed_user_defined_colour_selection_cids_apply_to_non_carbon_atoms_also;
759
763 void set_user_defined_bond_colours(const std::map<unsigned int, std::array<float, 4> > &colour_map);
764
766 // make this static?
767 void set_user_defined_atom_colour_by_selections(const std::vector<std::pair<std::string, unsigned int> > &indexed_residues_cids,
768 bool colour_applies_to_non_carbon_atoms_also,
769 mmdb::Manager *mol);
770
771 // need not be public
772 void store_user_defined_atom_colour_selections(const std::vector<std::pair<std::string, unsigned int> > &indexed_residues_cids,
773 bool colour_applies_to_non_carbon_atoms_also);
774
775 void apply_user_defined_atom_colour_selections(const std::vector<std::pair<std::string, unsigned int> > &indexed_residues_cids,
776 bool colour_applies_to_non_carbon_atoms_also,
777 mmdb::Manager *mol);
778
781
782 colour_holder base_colour_for_bonds;
783
785 void set_base_colour_for_bonds(float r, float g, float b);
786
787 std::set<int> no_bonds_to_these_atom_indices;
788
789 void add_to_non_drawn_bonds(const std::string &atom_selection_cid);
790
791 void clear_non_drawn_bonds() { no_bonds_to_these_atom_indices.clear(); }
792
793 void print_non_drawn_bonds() const;
794
795 void fill_default_colour_rules(); // assign colours to chains.
796
801 std::vector<std::pair<std::string, std::string> > colour_rules;
802
804 void add_colour_rule(const std::string &selection, const std::string &colour_name);
805
808
809 void print_colour_rules() const;
810
813 std::vector<std::pair<std::string, std::string> > get_colour_rules() const;
814
815 std::vector<std::pair<std::string, float> > M2T_float_params;
816 std::vector<std::pair<std::string, int> > M2T_int_params;
817
819 void M2T_updateFloatParameter(const std::string &param_name, float value);
820
822 void M2T_updateFloatParameter(const std::string &param_name, int value);
823
824 void print_M2T_FloatParameters() const;
825
826 void print_M2T_IntParameters() const;
827
829 void M2T_updateIntParameter(const std::string &param_name, int value);
830
831 simple_mesh_t get_molecular_representation_mesh(const std::string &cid,
832 const std::string &colour_scheme,
833 const std::string &style,
834 int secondaryStructureUsageFlag) const;
835
836 class res_prop_t {
837 public:
838 float value; // e.g. worm-radius
839 float value_x; // for aniso props
840 float value_y;
841 float value_z;
842 res_prop_t() : value(-1.1f), value_x(-1.1f), value_y(-1.1f), value_z(-1.1f) {}
843 bool filled_aniso() const { return value_x > 0.0f && value_y > 0.0f && value_z > 0.0f; }
844 };
845 std::map<coot::residue_spec_t, res_prop_t> residue_properties_map;
846
853 bool set_residue_properties(const std::string &json_string);
854
855 void clear_residue_properties();
856
857 simple_mesh_t get_gaussian_surface(float sigma, float contour_level,
858 float box_radius, float grid_scale, float fft_b_factor) const;
859
860 simple_mesh_t get_gaussian_surface_for_atom_selection(const std::string &cid, float sigma, float contour_level,
861 float box_radius, float grid_scale, float fft_b_factor) const;
862
863 simple_mesh_t get_chemical_features_mesh(const std::string &cid, const protein_geometry &geom) const;
864
865 bool hydrogen_atom_should_be_drawn() const { return false; } // 20221018-PE for now.
866 void set_use_bespoke_carbon_atom_colour(bool state) {
867 use_bespoke_grey_colour_for_carbon_atoms = state;
868 // make_bonds_type_checked("set_use_bespoke_carbon_atom_colour");
869 }
870 void set_bespoke_carbon_atom_colour(const colour_t &col) {
871 bespoke_carbon_atoms_colour = col;
872 // make_bonds_type_checked("set_bespoke_carbon_atom_colour");
873 }
874
876 void export_map_molecule_as_gltf(clipper::Coord_orth &position,
877 float radius, float contour_level,
878 const std::string &file_name);
879
881 void export_model_molecule_as_gltf(const std::string &mode,
882 const std::string &selection_cid,
883 protein_geometry *geom,
884 bool against_a_dark_background,
885 float bonds_width, float atom_radius_to_bond_width_ratio, int smoothness_factor,
886 bool draw_hydrogen_atoms_flag, bool draw_missing_residue_loops,
887 const std::string &file_name);
888
889 // this is the ribbons and surfaces API
890 void export_molecular_representation_as_gltf(const std::string &atom_selection_cid,
891 const std::string &colour_scheme,
892 const std::string &style,
893 int secondary_structure_usage_flag,
894 const std::string &file_name);
895
896 void export_chemical_features_as_gltf(const std::string &cid,
897 const protein_geometry &geom,
898 const std::string &file_name) const;
899
900 float gltf_pbr_roughness;
901 float gltf_pbr_metalicity;
902
903 void set_show_symmetry(bool f) { show_symmetry = f;}
904 bool get_show_symmetry() { return show_symmetry;}
905 void transform_by(mmdb::mat44 SSMAlign_TMatrix);
906 void transform_by(const clipper::RTop_orth &rtop, mmdb::Residue *res);
907 void transform_by(const clipper::RTop_orth &rtop);
908
909 symmetry_info_t get_symmetry(float symmetry_search_radius, const Cartesian &symm_centre) const;
910
911 // ----------------------- model analysis functions
912
913 std::vector<std::string> non_standard_residue_types_in_model() const;
914 std::vector<phi_psi_prob_t> ramachandran_validation(const ramachandrans_container_t &rc) const;
915 // not const because it recalculates the bonds.
916 simple_mesh_t get_rotamer_dodecs(protein_geometry *geom_p, rotamer_probability_tables *rpt);
917
918 instanced_mesh_t get_rotamer_dodecs_instanced(protein_geometry *geom_p, rotamer_probability_tables *rpt);
919
920 omega_distortion_info_container_t peptide_omega_analysis(const protein_geometry &geom,
921 const std::string &chain_id,
922 bool mark_cis_peptides_as_bad_flag) const;
923
924 std::vector<residue_spec_t> get_non_standard_residues_in_molecule() const;
925
926 std::vector<std::string> get_residue_types_without_dictionaries(const protein_geometry &geom) const;
927
929 instanced_mesh_t contact_dots_for_ligand(const std::string &cid, const protein_geometry &geom,
930 unsigned int num_subdivisions) const;
931
933 instanced_mesh_t all_molecule_contact_dots(const coot::protein_geometry &geom,
934 unsigned int num_subdivisions) const;
935
937 make_exportable_environment_bond_box(coot::residue_spec_t &spec, float max_dist, coot::protein_geometry &geom) const;
938
942 simple::molecule_t get_simple_molecule(int imol, const std::string &residue_cid,
943 const bool draw_hydrogen_atoms_flag,
944 coot::protein_geometry *geom_p);
945 // which call this function:
946 simple::molecule_t get_simple_molecule(int imol, mmdb::Residue *residue_p,
947 bool draw_hydrogen_atoms_flag,
948 coot::protein_geometry *geom_p);
949
953 // We need the thread pool?
955 coot::protein_geometry &geom,
956 ctpl::thread_pool &static_thread_pool);
957
962 std::vector<coot::geometry_distortion_info_pod_container_t>
963 geometric_distortions_for_one_residue_from_mol(const std::string &ligand_cid, bool with_nbcs,
964 coot::protein_geometry &geom,
965 ctpl::thread_pool &static_thread_pool);
966
971 std::vector<coot::geometry_distortion_info_pod_container_t>
972 geometric_distortions_for_selection_from_mol(const std::string &selection_cid, bool with_nbcs,
973 coot::protein_geometry &geom,
974 ctpl::thread_pool &static_thread_pool);
975
976 // I want a function that does the evaluation of the distortion
977 // in place - I don't want to get a function that allows me to
978 // calculate the distortion from the restraints.
979 //
980 std::pair<int, double>
981 simple_geometric_distortions_from_mol(const std::string &ligand_cid, bool with_nbcs,
982 coot::protein_geometry &geom,
983 ctpl::thread_pool &static_thread_pool);
984
985 coot::instanced_mesh_t get_extra_restraints_mesh(int mode) const;
986
988 std::vector<coot::residue_spec_t> residues_near_residue(const std::string &residue_cid, float dist) const;
989
992 std::vector<coot::atom_distance_t>
993 get_distances_between_atoms_of_residues(const std::string &cid_res_1,
994 const std::string &cid_res_2,
995 float dist_max) const;
996
998 std::vector<plain_atom_overlap_t> get_atom_overlaps(protein_geometry *geom_p);
999
1001 float get_atom_overlap_score(protein_geometry *geom_p) const;
1002
1004 std::vector<plain_atom_overlap_t> get_overlaps_for_ligand(const std::string &cid_ligand,
1005 protein_geometry *geom_p);
1006
1008 coot::atom_overlaps_dots_container_t get_overlap_dots(protein_geometry *geom_p);
1009
1011 coot::atom_overlaps_dots_container_t get_overlap_dots_for_ligand(const std::string &cid_ligand,
1012 protein_geometry *geom_p);
1013
1014 instanced_mesh_t get_HOLE(const clipper::Coord_orth &start_pos,
1015 const clipper::Coord_orth &end_pos,
1016 const protein_geometry &geom) const;
1017
1022 std::string get_pucker_analysis_info() const;
1023
1031 std::string get_svg_for_2d_ligand_environment_view(const std::string &residue_cid,
1032 protein_geometry *geom,
1033 bool add_key) const;
1034
1035
1036#ifdef MAKE_ENHANCED_LIGAND_TOOLS
1039 RDKit::ROMol *rdkit_mol(const std::string &ligand_cid);
1040#endif
1041
1042 // ------------------------ model-changing functions
1043
1044 int move_molecule_to_new_centre(const coot::Cartesian &new_centre);
1045 coot::Cartesian get_molecule_centre() const;
1046
1047 int flip_peptide(const atom_spec_t &rs, const std::string &alt_conf);
1048 int auto_fit_rotamer(const std::string &chain_id, int res_no, const std::string &ins_code,
1049 const std::string &alt_conf,
1050 const clipper::Xmap<float> &xmap, const coot::protein_geometry &pg);
1051
1052 std::pair<bool,float> backrub_rotamer(mmdb::Residue *residue_p,
1053 const clipper::Xmap<float> &xmap,
1054 const coot::protein_geometry &pg);
1055
1056 std::pair<bool,float> backrub_rotamer(const std::string &chain_id, int res_no,
1057 const std::string &ins_code, const std::string &alt_conf,
1058 const clipper::Xmap<float> &xmap,
1059 const coot::protein_geometry &pg);
1060
1061 // return the number of deleted atoms
1062 int delete_atoms(const std::vector<atom_spec_t> &atoms);
1063 int delete_atom(atom_spec_t &atom_spec);
1064 int delete_residue(residue_spec_t &residue_spec);
1065 int delete_residue_atoms_with_alt_conf(coot::residue_spec_t &residue_spec, const std::string &alt_conf);
1066 int delete_chain_using_atom_cid(const std::string &cid);
1067 int delete_literal_using_cid(const std::string &cid); // cid is an atom selection, e.g. containing a residue range
1068
1069 int change_alt_locs(const std::string &cid, const std::string &change_mode);
1070
1071 std::pair<int, std::string> add_terminal_residue_directly(const residue_spec_t &spec,
1072 const std::string &new_res_type,
1073 const protein_geometry &geom,
1074 const clipper::Xmap<float> &xmap,
1075 mmdb::Manager *standard_residues_asc_mol, // for RNA
1076 ctpl::thread_pool &static_thread_pool);
1077
1078 void execute_simple_nucleotide_addition(const std::string &term_type,
1079 mmdb::Residue *res_p, const std::string &chain_id,
1080 mmdb::Manager *standard_residues_asc_mol);
1081 void execute_simple_nucleotide_addition(mmdb::Residue *residue_p,
1082 mmdb::Manager *standard_residues_asc_mol);
1083 void execute_simple_nucleotide_addition(const std::string &cid,
1084 mmdb::Manager *standard_residues_asc_mol);
1085
1086 int add_compound(const dictionary_residue_restraints_t &monomer_restraints, const Cartesian &position,
1087 const clipper::Xmap<float> &xmap, float map_rmsd);
1088
1089
1091 int add_alternative_conformation(const std::string &cid);
1092
1094 int fill_partial_residue(const residue_spec_t &res_spec, const std::string &alt_conf,
1095 const clipper::Xmap<float> &xmap, const protein_geometry &geom);
1096
1098 int fill_partial_residues(const clipper::Xmap<float> &xmap, protein_geometry *geom);
1099
1100 int mutate(const residue_spec_t &spec, const std::string &new_res_type);
1101
1102 void add_named_glyco_tree(const std::string &glycosylation_name, const std::string &chain_id, int res_no,
1103 const clipper::Xmap<float> &xmap, protein_geometry *geom);
1104
1105 int side_chain_180(const residue_spec_t &residue_spec, const std::string &alt_conf,
1106 coot::protein_geometry *geom_p); // sub functions are non-const
1107
1108 int delete_side_chain(const residue_spec_t &residue_spec);
1109
1110 std::string jed_flip(coot::residue_spec_t &spec, const std::string &atom_name, const std::string &alt_conf,
1111 bool invert_selection, protein_geometry *geom);
1112
1113 // move this up
1114 std::string jed_flip_internal(coot::atom_tree_t &tree,
1115 const std::vector<coot::dict_torsion_restraint_t> &interesting_torsions,
1116 const std::string &atom_name,
1117 bool invert_selection);
1118
1119 // return a non-null string on a problem
1120 std::string jed_flip_internal(coot::atom_tree_t &tree,
1121 const dict_torsion_restraint_t &torsion,
1122 const std::string &atom_name,
1123 bool invert_selection);
1124
1125 // manipulate the torsion angles of first residue in this molecule to
1126 // match those of the passed (reference residue (from a different
1127 // molecule, typically). This function presumes that this molecule
1128 // contains just a ligand.
1129 // @return the number of torsion angles changed
1130 int match_torsions(mmdb::Residue *res_ref,
1131 const std::vector <coot::dict_torsion_restraint_t> &tr_ligand,
1132 const coot::protein_geometry &geom);
1133
1134 coot::minimol::molecule eigen_flip_residue(const residue_spec_t &residue_spec);
1135
1136 int apply_transformation_to_atom_selection(const std::string &atom_selection_cid,
1137 int n_atoms_in_selection,
1138 clipper::Coord_orth &rotation_centre,
1139 clipper::RTop_orth &rtop);
1140
1143 void multiply_residue_temperature_factors(const std::string &cid, float factor);
1144
1146 int add_hydrogen_atoms(protein_geometry *geom); // because of coot::reduce api - hmm.
1147
1150
1155
1164 bool residue_is_nucleic_acid(const std::string &cid) const;
1165
1166 // change the chain id
1167 // return -1 on a conflict
1168 // 1 on good.
1169 // 0 on did nothing
1170 // return also an information/error message
1171 std::pair<int, std::string> change_chain_id(const std::string &from_chain_id,
1172 const std::string &to_chain_id,
1173 bool use_resno_range,
1174 int start_resno, int end_resno);
1175
1176 // make these private
1177 //
1178 std::pair<int, std::string>
1179 change_chain_id_with_residue_range(const std::string &from_chain_id,
1180 const std::string &to_chain_id,
1181 int start_resno,
1182 int end_resno);
1183 void change_chain_id_with_residue_range_helper_insert_or_add(mmdb::Chain *to_chain_p, mmdb::Residue *new_residue);
1184
1186 int new_positions_for_residue_atoms(const std::string &residue_cid, const std::vector<api::moved_atom_t> &moved_atoms);
1187
1189 int new_positions_for_atoms_in_residues(const std::vector<api::moved_residue_t> &moved_residues);
1190
1194 int new_positions_for_residue_atoms(mmdb::Residue *residue_p, const std::vector<api::moved_atom_t> &moved_atoms,
1195 bool do_backup);
1196
1199 int merge_molecules(const std::vector<mmdb::Manager *> &mols);
1200
1201 // My ligands don't jiggle-jiggle...
1202 //
1203 // Hey, what do you know, they actually do.
1204 float fit_to_map_by_random_jiggle(const residue_spec_t &res_spec, const clipper::Xmap<float> &xmap, float map_rmsd,
1205 int n_trials, float translation_scale_factor);
1206
1210 float fit_to_map_by_random_jiggle_using_atom_selection(const std::string &cid, const clipper::Xmap<float> &xmap, float map_rmsd,
1211 int n_trials, float translation_scale_factor);
1212
1213 int cis_trans_conversion(const std::string &atom_cid, mmdb::Manager *standard_residues_mol);
1214
1215 int replace_residue(const std::string &residue_cid, const std::string &new_residue_type, int imol_enc,
1216 const protein_geometry &geom);
1217
1218 // the above is a wrapper for this:
1219 // (which was a scripting function and now has been moved into coot utils)
1220 int mutate_by_overlap(mmdb::Residue *residue_p, const dictionary_residue_restraints_t &restraints);
1221
1223 int replace_fragment(atom_selection_container_t asc);
1224
1225 // replace the atoms of SelHnd, which is a selection of mol_ref into this molecule.
1226 // Use old_atom_index_handle for fast indexing.
1227 int replace_fragment(mmdb::Manager *mol_ref, int old_atom_index_handle, int SelHnd);
1228
1230 class rotamer_change_info_t {
1231 public:
1233 int rank;
1235 std::string name;
1240 rotamer_change_info_t(int rank, const std::string &name, float rp, int status) : rank(rank), name(name), richardson_probability(rp), status(status) {}
1241 rotamer_change_info_t() : rank(-1), name(""), richardson_probability(-1), status(0) {}
1242 };
1243
1245 rotamer_change_info_t change_to_next_rotamer(const coot::residue_spec_t &res_spec, const std::string &alt_conf, const coot::protein_geometry &pg);
1246
1247 rotamer_change_info_t change_to_previous_rotamer(const coot::residue_spec_t &res_spec, const std::string &alt_conf, const coot::protein_geometry &pg);
1248
1249 rotamer_change_info_t change_to_first_rotamer(const coot::residue_spec_t &res_spec, const std::string &alt_conf, const coot::protein_geometry &pg);
1250
1251 // rotamer_change_direction is 1 for increase rotamer index
1252 // rotamer_change_direction is -1 for decrease rotamer index
1253 // rotamer_change_direction is 0 for change to 0th
1254 // index cycling is handled by the function
1255 //
1256 rotamer_change_info_t change_rotamer_number(const coot::residue_spec_t &res_spec, const std::string &alt_conf,
1257 int rotamer_change_direction,
1258 const coot::protein_geometry &pg);
1259
1260 int set_residue_to_rotamer_number(coot::residue_spec_t res_spec,
1261 const std::string &alt_conf_in,
1262 int rotamer_number,
1263 const coot::protein_geometry &pg);
1264
1265 void associate_sequence_with_molecule(const std::string &chain_id, const std::string &sequence);
1266
1268 void assign_sequence(const clipper::Xmap<float> &xmap, const coot::protein_geometry &geom);
1269
1271 std::vector<std::pair<std::string, std::string> > get_sequence_info() const;
1272
1274 chain_mutation_info_container_t get_mutation_info() const;
1275
1276 // ----------------------- merge molecules
1277
1278 // merge molecules helper functions
1279
1280 bool is_het_residue(mmdb::Residue *residue_p) const;
1281 // return state, max_resno + 1, or 0, 1 of no residues in chain.
1282 //
1283 std::pair<short int, int> next_residue_number_in_chain(mmdb::Chain *w,
1284 bool new_res_no_by_hundreds=false) const;
1285
1286 mmdb::Residue *copy_and_add_residue_to_chain(mmdb::Chain *this_model_chain,
1287 mmdb::Residue *add_model_residue,
1288 bool new_resno_by_hundreds_flag=true);
1289 void copy_and_add_chain_residues_to_chain(mmdb::Chain *new_chain, mmdb::Chain *this_molecule_chain);
1290 std::vector<std::string> map_chains_to_new_chains(const std::vector<std::string> &adding_model_chains,
1291 const std::vector<std::string> &this_model_chains) const;
1292 // that's too complicated for try_add_by_consolidation(), we just want this:
1293 std::string suggest_new_chain_id(const std::string &current_chain_id) const;
1294 std::pair<bool, std::vector<std::string> > try_add_by_consolidation(mmdb::Manager *adding_mol);
1295 bool merge_molecules_just_one_residue_homogeneous(atom_selection_container_t molecule_to_add);
1296 bool merge_molecules_just_one_residue_at_given_spec(atom_selection_container_t molecule_to_add,
1297 residue_spec_t target_spec);
1298
1299 // return success status and spec if new residue if possible.
1300 std::pair<bool, coot::residue_spec_t> merge_ligand_to_near_chain(mmdb::Manager *mol);
1301
1302 // return success status and spec if new residue if possible.
1303 std::pair<int, std::vector<merge_molecule_results_info_t> >
1304 merge_molecules(const std::vector<atom_selection_container_t> &add_molecules);
1305
1306
1307 std::pair<int, double>
1308 get_torsion(const std::string &cid, const std::vector<std::string> &atom_names) const;
1309
1310
1311 void
1312 set_temperature_factors_using_cid(const std::string &cid, float temp_fact);
1313
1314 // ----------------------- refinement
1315
1316 coot::extra_restraints_t extra_restraints;
1317
1319 int read_extra_restraints(const std::string &file_name);
1321 std::vector<mmdb::Residue *> select_residues(const residue_spec_t &spec, const std::string &mode) const;
1323 std::vector<mmdb::Residue *> select_residues(const std::string &chain_id, int resno_start, int resno_end) const;
1325 std::vector<mmdb::Residue *> select_residues(const std::string &multi_cid, const std::string &mode) const;
1326
1328 int refine_direct(std::vector<mmdb::Residue *> rv, const std::string &alt_loc, const clipper::Xmap<float> &xmap,
1329 unsigned int max_number_of_threads,
1330 float map_weight, int n_cycles, const coot::protein_geometry &geom,
1331 bool do_rama_plot_restraints, float rama_plot_weight,
1332 bool do_torsion_restraints, float torsion_weight,
1333 bool refinement_is_quiet);
1334
1335 int minimize(const std::string &atom_selection_cid,
1336 int n_cycles,
1337 bool do_rama_plot_restraints, float rama_plot_weight,
1338 bool do_torsion_restraints, float torsion_weight, bool refinement_is_quiet,
1339 coot::protein_geometry *geom_p);
1340
1341 bool shiftfield_b_factor_refinement(const clipper::HKL_data<clipper::data32::F_sigF> &F_sigF,
1342 const clipper::HKL_data<clipper::data32::Flag> &free_flag);
1343
1344 void fix_atom_selection_during_refinement(const std::string &atom_selection_cid);
1345
1346 // refine all of this molecule - the links and non-bonded contacts will be determined from mol_ref;
1347 void init_all_molecule_refinement(int imol_ref_mol, coot::protein_geometry &geom,
1348 const clipper::Xmap<float> &xmap, float map_weight,
1349 ctpl::thread_pool *thread_pool);
1350
1351 // add or update.
1352 void add_target_position_restraint(const std::string &atom_cid, float pos_x, float pos_y, float pos_z);
1353
1354 //
1355 void turn_off_when_close_target_position_restraint();
1356
1357 std::vector<std::pair<mmdb::Atom *, clipper::Coord_orth> > atoms_with_position_restraints;
1358
1359 instanced_mesh_t add_target_position_restraint_and_refine(const std::string &atom_cid, float pos_x, float pos_y, float pos_z,
1360 int n_cyles,
1361 coot::protein_geometry *geom_p);
1363 void clear_target_position_restraint(const std::string &atom_cid);
1364
1369
1370 // something is happening to this pointer - where is it being reset?
1371 restraints_container_t *get_last_restraints() { return last_restraints; }
1372
1375
1379
1380 // make them yourself - easy as pie.
1381 void generate_self_restraints(float local_dist_max,
1382 const coot::protein_geometry &geom);
1383 void generate_chain_self_restraints(float local_dist_max,
1384 const std::string &chain_id,
1385 const coot::protein_geometry &geom);
1386 void generate_local_self_restraints(float local_dist_max,
1387 const std::vector<coot::residue_spec_t> &residue_specs,
1388 const coot::protein_geometry &geom);
1389 void generate_local_self_restraints(float local_dist_max,
1390 const std::string &multi_selection_cid,
1391 const coot::protein_geometry &geom);
1392 void generate_local_self_restraints(int selHnd, float local_dist_max,
1393 const coot::protein_geometry &geom);
1394
1395 void add_parallel_plane_restraint(coot::residue_spec_t spec_1,
1396 coot::residue_spec_t spec_2);
1397
1398 // which uses:
1399 std::vector<std::string> nucelotide_residue_name_to_base_atom_names(const std::string &rn) const;
1400 // for non-bases, normal amino acids (simple-minded, currently).
1401 std::vector<std::string> residue_name_to_plane_atom_names(const std::string &rn) const;
1402
1403 void clear_extra_restraints();
1404
1405 // --------------- rigid body fit
1406 int rigid_body_fit(const std::string &mult_cids, const clipper::Xmap<float> &xmap);
1407
1408 int rotate_around_bond(const std::string &residue_cid,
1409 const std::string &alt_conf,
1410 coot::atom_name_quad quad,
1411 double torsion_angle, protein_geometry &geom);
1412
1413 // ----------------------- map functions
1414
1415 void scale_map(float scale_factor);
1416
1417 bool is_EM_map() const;
1418
1419 float get_density_at_position(const clipper::Coord_orth &pos) const;
1420
1421 // return -1.0 on not-a-map
1422 float get_map_mean() const;
1423 // return -1.1 on not-a-map
1424 float get_map_rmsd_approx() const;
1425 int write_map(const std::string &file_name) const;
1426 void set_map_is_difference_map(bool flag);
1427 bool is_difference_map_p() const;
1428
1429 // gets updated in sfcalc_genmaps_using_bulk_solvent
1430 clipper::Xmap<float> updating_maps_previous_difference_map;
1431 // these are in the asymmetric unit
1432 std::vector<std::pair<clipper::Coord_orth, float> > updating_maps_diff_diff_map_peaks;
1433 void set_updating_maps_diff_diff_map_peaks(const std::vector<std::pair<clipper::Coord_orth, float> > &v) {
1434 updating_maps_diff_diff_map_peaks = v; }
1436 std::vector<std::pair<clipper::Coord_orth, float> > get_updating_maps_diff_diff_map_peaks(const clipper::Coord_orth &screen_centre) const;
1437
1440
1441 // changes the internal map mesh holder (hence not const)
1442 simple_mesh_t get_map_contours_mesh(clipper::Coord_orth position, float radius, float contour_level,
1443 bool use_thread_pool, ctpl::thread_pool *thread_pool_p);
1444 simple_mesh_t get_map_contours_mesh_using_other_map_for_colours(const clipper::Coord_orth &position, float radius, float contour_level,
1445 const clipper::Xmap<float> &xmap);
1446 simple_mesh_t get_map_contours_mesh_using_other_map_for_colours(const clipper::Coord_orth &position, float radius, float contour_level,
1447 const user_defined_colour_table_t &udct,
1448 const clipper::Xmap<float> &xmap);
1449
1451 class histogram_info_t {
1452 public:
1454 float base;
1458 std::vector<int> counts;
1460 float mean;
1463 histogram_info_t() : base(-1), bin_width(-1), mean(-1), variance(-1) {}
1464 histogram_info_t(float min_density, float bw, const std::vector<int> &c) :
1465 base(min_density), bin_width(bw), counts(c), mean(-1), variance(-1) {}
1466 };
1467
1472 histogram_info_t get_map_histogram(unsigned int n_bins, float zoom_factor) const;
1473
1474 // just look at the vertices of the map - not the whole thing
1475 // Sample the points from other_map
1477 get_map_vertices_histogram(const clipper::Xmap<float> &other_xmap,
1478 const clipper::Coord_orth &pt,
1479 float radius, float contour_level,
1480 bool use_thread_pool, ctpl::thread_pool *thread_pool_p,
1481 unsigned int n_bins);
1482
1483 void set_map_colour(colour_holder holder);
1484 void set_map_colour_saturation(float s) { radial_map_colour_saturation = s; }
1485
1489 void set_other_map_for_colouring_min_max(float min_v, float max_v);
1490 void set_other_map_for_colouring_invert_colour_ramp(bool state) {
1491 radial_map_colour_invert_flag = state;
1492 }
1493
1494 double sum_density_for_atoms_in_residue(const std::string &cid,
1495 const std::vector<std::string> &atom_names,
1496 const clipper::Xmap<float> &xmap) const;
1497
1502 public:
1504 std::string feature_type;
1506 residue_spec_t residue_spec; // use this for sorting a combination of interesting_place_t types.
1508 float x, y, z;
1510 std::string button_label;
1512 float feature_value; // e.g. peak-height (not all "interesting" feature values can be captured by a float of course)
1514 float badness; // a nubmer between 100.0 and 0.0 (inclusive) if it's negative then it's not set.
1518 interesting_place_t(const std::string &feature_type, const residue_spec_t &rs, const clipper::Coord_orth &pt, const std::string &bl) :
1520 x = pt.x(); y = pt.y(); z = pt.z();
1521 feature_value = -1; // something "unset"
1522 badness = -1.1; // "unset"
1523 }
1524
1525 interesting_place_t(const std::string &feature_type, const clipper::Coord_orth &pt, const std::string &button_label) :
1527 x = pt.x(); y = pt.y(); z = pt.z();
1528 feature_value = -1; // something "unset"
1529 badness = -1.1; // "unset"
1530 }
1531
1532 void set_feature_value(const float &f) { feature_value = f; }
1533 void set_badness_value(const float &b) { badness = b; }
1534 };
1535
1537 class difference_map_peaks_info_t {
1538 public:
1539 clipper::Coord_orth pos;
1540 float peak_height; // nrmsd
1541 // maybe other useful stuff here in future
1542 difference_map_peaks_info_t(const clipper::Coord_orth &p, float ph) : pos(p), peak_height(ph) {}
1543 };
1544
1545 // the molecule is passed so that the peaks are placed around the protein
1546 std::vector<interesting_place_t> difference_map_peaks(mmdb::Manager *mol, float n_rmsd) const;
1547
1548 texture_as_floats_t get_map_section_texture(int section_index, int axis,
1549 float data_value_for_bottom, float data_value_for_top) const;
1550
1554 int get_number_of_map_sections(int axis_id) const;
1555
1556 // ---------------------------------- blender --------------------------------------
1557
1558 blender_mesh_t blender_mesh;
1559 std::vector<float> get_vertices_for_blender() const;
1560 std::vector<int> get_triangles_for_blender() const;
1561 std::vector<float> get_colour_table_for_blender() const;
1562
1563 // pass other things here
1564 void make_mesh_for_bonds_for_blender(const std::string &mode, protein_geometry *geom, bool against_a_dark_background,
1565 float bond_width, float atom_radius_to_bond_width_ratio,
1566 int smoothness_factor);
1567
1575 const std::string &colour_scheme,
1576 const std::string &style,
1577 int secondary_structure_usage_flag);
1578
1579 void make_mesh_for_goodsell_style_for_blender(protein_geometry *geom_p,
1580 float colour_wheel_rotation_step,
1581 float saturation,
1582 float goodselliness);
1583
1584 void make_mesh_for_map_contours_for_blender(Cartesian position, float contour_level, float radius);
1585 void make_mesh_for_gaussian_surface_for_blender(float sigma, float contour_level, float box_radius, float grid_scale,float b_factor);
1586 };
1587}
1588
1589
1590#endif // COOT_MOLECULE_HH
Definition residue-and-atom-specs.hh:35
Definition instancing.hh:58
map histogram class
Definition coot-molecule.hh:1451
float base
base
Definition coot-molecule.hh:1454
float mean
mean
Definition coot-molecule.hh:1460
float variance
variance
Definition coot-molecule.hh:1462
float bin_width
bin width
Definition coot-molecule.hh:1456
std::vector< int > counts
counts
Definition coot-molecule.hh:1458
std::string button_label
button label
Definition coot-molecule.hh:1510
interesting_place_t(const std::string &feature_type, const clipper::Coord_orth &pt, const std::string &button_label)
constructor
Definition coot-molecule.hh:1525
float badness
synthetic badness (for "score by badness")
Definition coot-molecule.hh:1514
interesting_place_t(const std::string &feature_type, const residue_spec_t &rs, const clipper::Coord_orth &pt, const std::string &bl)
constructor
Definition coot-molecule.hh:1518
std::string feature_type
Feature.
Definition coot-molecule.hh:1504
interesting_place_t()
constructor
Definition coot-molecule.hh:1516
void set_feature_value(const float &f)
internal to libcootapi function to set the values
Definition coot-molecule.hh:1532
float x
Position.
Definition coot-molecule.hh:1508
float feature_value
actual value of the feature
Definition coot-molecule.hh:1512
residue_spec_t residue_spec
Residue specifier.
Definition coot-molecule.hh:1506
a container class for information about changing rotamers
Definition coot-molecule.hh:1230
int rank
the rank of the new rotamer
Definition coot-molecule.hh:1233
std::string name
new rotamer name
Definition coot-molecule.hh:1235
float richardson_probability
Richardson probability.
Definition coot-molecule.hh:1237
int status
status: did the change take place?
Definition coot-molecule.hh:1239
int add_alternative_conformation(const std::string &cid)
add an alternative conformation for the specified residue
std::vector< mmdb::Residue * > select_residues(const std::string &multi_cid, const std::string &mode) const
select residues given a multi-cid
int fill_partial_residues(const clipper::Xmap< float > &xmap, protein_geometry *geom)
add atoms to a partially-filled side chaain
std::vector< std::vector< std::string > > get_ncs_related_chains() const
Get the chains that are related by NCS:
void make_mesh_for_molecular_representation_for_blender(const std::string &cid, const std::string &colour_scheme, const std::string &style, int secondary_structure_usage_flag)
void add_colour_rule(const std::string &selection, const std::string &colour_name)
Add a colour rule: eg. ("//A", "red")
std::vector< coot::geometry_distortion_info_pod_container_t > geometric_distortions_for_one_residue_from_mol(const std::string &ligand_cid, bool with_nbcs, coot::protein_geometry &geom, ctpl::thread_pool &static_thread_pool)
std::vector< std::pair< clipper::Coord_orth, float > > get_updating_maps_diff_diff_map_peaks(const clipper::Coord_orth &screen_centre) const
does the peaks-move operation.
std::vector< coot::geometry_distortion_info_pod_container_t > geometric_distortions_for_selection_from_mol(const std::string &selection_cid, bool with_nbcs, coot::protein_geometry &geom, ctpl::thread_pool &static_thread_pool)
void set_other_map_for_colouring_min_max(float min_v, float max_v)
bool copy_ncs_chain(const std::string &from_chain_id, const std::string &to_chain_id)
copy chain using NCS matrix
void M2T_updateIntParameter(const std::string &param_name, int value)
Update int parameter for MoleculesToTriangles molecular mesh.
bool set_residue_properties(const std::string &json_string)
set the residue properties
void M2T_updateFloatParameter(const std::string &param_name, int value)
Update int parameter for MoleculesToTriangles molecular mesh.
molecule_t(const std::string &name_in, int mol_no_in, short int is_em_map)
constructor, when we know we are giving it an em map
Definition coot-molecule.hh:497
simple::molecule_t get_simple_molecule(int imol, const std::string &residue_cid, const bool draw_hydrogen_atoms_flag, coot::protein_geometry *geom_p)
void delete_colour_rules()
delete all the colour rules
molecule_t(atom_selection_container_t asc, int imol_no_in, const std::string &name_in)
constructor
Definition coot-molecule.hh:503
std::vector< std::string > get_types_in_molecule() const
get types
std::vector< double > get_residue_CA_position(const std::string &cid) const
std::vector< coot::residue_spec_t > residues_near_residue(const std::string &residue_cid, float dist) const
int delete_hydrogen_atoms()
instanced_mesh_t all_molecule_contact_dots(const coot::protein_geometry &geom, unsigned int num_subdivisions) const
void assign_sequence(const clipper::Xmap< float > &xmap, const coot::protein_geometry &geom)
try to fit all of the sequences to all of the chains
int new_positions_for_atoms_in_residues(const std::vector< api::moved_residue_t > &moved_residues)
set new positions for the atoms of the specified residues
int merge_molecules(const std::vector< mmdb::Manager * > &mols)
void export_map_molecule_as_gltf(clipper::Coord_orth &position, float radius, float contour_level, const std::string &file_name)
export map molecule as glTF
std::vector< mmdb::Residue * > select_residues(const residue_spec_t &spec, const std::string &mode) const
refinement tool
int refine_direct(std::vector< mmdb::Residue * > rv, const std::string &alt_loc, const clipper::Xmap< float > &xmap, unsigned int max_number_of_threads, float map_weight, int n_cycles, const coot::protein_geometry &geom, bool do_rama_plot_restraints, float rama_plot_weight, bool do_torsion_restraints, float torsion_weight, bool refinement_is_quiet)
real space refinement
void clear_target_position_restraints()
clear any and all drag-atom target position restraints
std::vector< mmdb::Residue * > select_residues(const std::string &chain_id, int resno_start, int resno_end) const
resno_start and resno_end are inclusive
std::vector< residue_range_t > get_missing_residue_ranges() const
std::string get_pucker_analysis_info() const
void set_user_defined_atom_colour_by_selections(const std::vector< std::pair< std::string, unsigned int > > &indexed_residues_cids, bool colour_applies_to_non_carbon_atoms_also, mmdb::Manager *mol)
user-defined atom selection to colour index.
void M2T_updateFloatParameter(const std::string &param_name, float value)
Update float parameter for MoleculesToTriangles molecular mesh.
coot::atom_overlaps_dots_container_t get_overlap_dots_for_ligand(const std::string &cid_ligand, protein_geometry *geom_p)
not const because it can dynamically add dictionaries
float fit_to_map_by_random_jiggle_using_atom_selection(const std::string &cid, const clipper::Xmap< float > &xmap, float map_rmsd, int n_trials, float translation_scale_factor)
int add_hydrogen_atoms(protein_geometry *geom)
bool residue_is_nucleic_acid(const std::string &cid) const
std::vector< double > get_residue_sidechain_average_position(const std::string &cid) const
void multiply_residue_temperature_factors(const std::string &cid, float factor)
void set_colour_wheel_rotation_base(float r)
set the colour wheel rotation base for the specified molecule
molecule_t(const std::string &name_in, int mol_no_in, const clipper::Xmap< float > &xmap_in, bool is_em_map_flag)
constructor
Definition coot-molecule.hh:500
void set_base_colour_for_bonds(float r, float g, float b)
set the base colour - to be used as a base for colour wheel rotation
void export_model_molecule_as_gltf(const std::string &mode, const std::string &selection_cid, protein_geometry *geom, bool against_a_dark_background, float bonds_width, float atom_radius_to_bond_width_ratio, int smoothness_factor, bool draw_hydrogen_atoms_flag, bool draw_missing_residue_loops, const std::string &file_name)
export model molecule as glTF - this is the bonds and atoms API
int read_extra_restraints(const std::string &file_name)
read extra restraints (e.g. from ProSMART)
std::vector< std::pair< std::string, std::string > > colour_rules
Definition coot-molecule.hh:801
int fill_partial_residue(const residue_spec_t &res_spec, const std::string &alt_conf, const clipper::Xmap< float > &xmap, const protein_geometry &geom)
add atoms to a partially-filled side chaain
int replace_fragment(atom_selection_container_t asc)
std::string molecule_to_PDB_string() const
RDKit::ROMol * rdkit_mol(const std::string &ligand_cid)
float get_atom_overlap_score(protein_geometry *geom_p) const
get the atom overlap
molecule_t(const std::string &name_in, int mol_no_in)
constructor
Definition coot-molecule.hh:495
void clear_target_position_restraint(const std::string &atom_cid)
clear
void clear_refinement()
std::vector< plain_atom_overlap_t > get_atom_overlaps(protein_geometry *geom_p)
not const because it can dynamically add dictionaries
chain_mutation_info_container_t get_mutation_info() const
return the mismatches/mutations:
coot::atom_overlaps_dots_container_t get_overlap_dots(protein_geometry *geom_p)
not const because it can dynamically add dictionaries
std::vector< plain_atom_overlap_t > get_overlaps_for_ligand(const std::string &cid_ligand, protein_geometry *geom_p)
not const because it can dynamically add dictionaries
std::vector< coot::atom_distance_t > get_distances_between_atoms_of_residues(const std::string &cid_res_1, const std::string &cid_res_2, float dist_max) const
int get_number_of_map_sections(int axis_id) const
double get_radius_of_gyration() const
instanced_mesh_t contact_dots_for_ligand(const std::string &cid, const protein_geometry &geom, unsigned int num_subdivisions) const
int new_positions_for_residue_atoms(mmdb::Residue *residue_p, const std::vector< api::moved_atom_t > &moved_atoms, bool do_backup)
std::vector< std::pair< std::string, std::string > > get_sequence_info() const
simple return the associated sequences
void set_occupancy(const std::string &cid, float occ_new)
float get_suggested_initial_contour_level() const
std::vector< glm::vec4 > make_colour_table(bool against_a_dark_background) const
useful for debugging, perhaps
histogram_info_t get_map_histogram(unsigned int n_bins, float zoom_factor) const
int refine_using_last_restraints(int n_steps)
int new_positions_for_residue_atoms(const std::string &residue_cid, const std::vector< api::moved_atom_t > &moved_atoms)
set new positions for the atoms in the specified residue
bool delete_all_carbohydrate()
void set_user_defined_bond_colours(const std::map< unsigned int, std::array< float, 4 > > &colour_map)
coot::simple_mesh_t get_mesh_for_ligand_validation_vs_dictionary(const std::string &ligand_cid, coot::protein_geometry &geom, ctpl::thread_pool &static_thread_pool)
std::vector< std::pair< std::string, std::string > > get_colour_rules() const
std::vector< double > get_residue_average_position(const std::string &cid) const
std::string get_svg_for_2d_ligand_environment_view(const std::string &residue_cid, protein_geometry *geom, bool add_key) const
std::string molecule_to_mmCIF_string() const
rotamer_change_info_t change_to_next_rotamer(const coot::residue_spec_t &res_spec, const std::string &alt_conf, const coot::protein_geometry &pg)
change rotamers
Definition residue-and-atom-specs.hh:216
The basic mesh for transfering mesh geometry and colours.
Definition simple-mesh.hh:38
Definition generic-3d-lines.hh:12