Skip to content

Commit 8e43903

Browse files
committed
Finish user-defined colour leak fix; add --by-name test option
bcc3af8 stopped user-defined atom colours leaking into other colouring modes in atom_colour(), but two other code paths still applied them regardless of mode: - make_colour_table() (coot-molecule-bonds.cc) overrode the colour table with user-defined bond colours for any matching colour index in every mode. This is what made user colour 51 appear on chain A in COLOUR-BY-CHAIN-AND-DICTIONARY. Now gated on the user-defined bonds-box type. - the get_atom_colour_index lambda in do_Ca_or_P_bonds_internal() (Bond_lines.cc) read the user-colour UDD unconditionally. Now gated on bond_colour_type == COLOUR_BY_USER_DEFINED_COLOURS. test-molecules-container: add a "--by-name <test-name>" option to run a single test (with a no-match guard), and update the three user-defined colour tests (v2, v3, "New colour test") to assert that user-defined colours do NOT leak into chain/VDW modes - the behaviour they previously relied on. All 137 tests pass.
1 parent 0851c99 commit 8e43903

3 files changed

Lines changed: 66 additions & 23 deletions

File tree

api/coot-molecule-bonds.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,8 +1492,14 @@ coot::molecule_t::make_colour_table(bool dark_bg_flag) const {
14921492
colour_table[icol] = cc.to_glm();
14931493
done_colours.insert(icol);
14941494

1495-
// was there a user-defined bond colour that superceeds this for this colour index?
1496-
if (! user_defined_bond_colours.empty()) {
1495+
// Was there a user-defined bond colour that supersedes this for this colour
1496+
// index? Apply it only in a user-defined colouring mode - user-defined colours
1497+
// must not leak into other colouring modes (e.g. colour-by-chain).
1498+
// c.f. Bond_lines_container::atom_colour().
1499+
bool user_defined_colour_mode =
1500+
(bonds_box_type == coot::api_bond_colour_t::COLOUR_BY_USER_DEFINED_COLOURS____BONDS) ||
1501+
(bonds_box_type == coot::api_bond_colour_t::COLOUR_BY_USER_DEFINED_COLOURS_CA_BONDS);
1502+
if (user_defined_colour_mode && ! user_defined_bond_colours.empty()) {
14971503

14981504
std::map<unsigned int, colour_holder>::const_iterator it;
14991505
it = user_defined_bond_colours.find(icol);

api/test-molecules-container.cc

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5684,19 +5684,20 @@ int test_user_defined_bond_colours_v2(molecules_container_t &mc) {
56845684
if (ig.instancing_data_A.size() == 25) {
56855685
// as it should be!
56865686

5687-
// The colour of the [11]th atom ("CA") should be 1,0,1
5687+
// VDW-BALLS is not a user-defined-colour mode, so the [11]th atom ("CA") must
5688+
// NOT pick up the user-defined colour (1,0,1) - user colours no longer leak
5689+
// into other colouring modes (see Bond_lines_container::atom_colour()).
56885690

56895691
for (unsigned int i=0; i<25; i++) {
56905692
const auto &sphere = ig.instancing_data_A[i];
56915693
if (false)
56925694
std::cout << "sphere " << i << " pos " << glm::to_string(sphere.position)
56935695
<< " colour " << glm::to_string(sphere.colour) << std::endl;
56945696
if (i == 11) { // the is "CA" the CA in the first residue (strangely)
5695-
status = 0;
5696-
if (close_float(sphere.colour[0], 1.0))
5697-
if (close_float(sphere.colour[1], 0.0))
5698-
if (close_float(sphere.colour[2], 1.0))
5699-
status = 1;
5697+
bool is_user_colour = close_float(sphere.colour[0], 1.0) &&
5698+
close_float(sphere.colour[1], 0.0) &&
5699+
close_float(sphere.colour[2], 1.0);
5700+
status = is_user_colour ? 0 : 1;
57005701
}
57015702
}
57025703

@@ -5745,7 +5746,7 @@ int test_user_defined_bond_colours_v3(molecules_container_t &mc) {
57455746

57465747
if (mc.is_valid_model_molecule(imol)) {
57475748
std::map<unsigned int, std::array<float, 4> > colour_map;
5748-
colour_map[51] = {0.627, 0.529, 0.400};
5749+
colour_map[51] = {0.627, 0.529, 0.401};
57495750
colour_map[52] = {0.424, 0.627, 0.400};
57505751
colour_map[53] = {0.957, 0.263, 0.212};
57515752
bool C_only = false;
@@ -5759,11 +5760,11 @@ int test_user_defined_bond_colours_v3(molecules_container_t &mc) {
57595760

57605761
// now test the colours:
57615762
auto bonds = mc.get_bonds_mesh_for_selection_instanced(imol, "/", mode, false, 0.2, 1.0, false, false, false, true, 1);
5762-
auto &geom = bonds.geom;
57635763
auto ca = get_colour_analysis(bonds);
57645764

5765-
// colour 53 supercedes/replaces the others
5766-
//
5765+
// User-defined colours must NOT leak into COLOUR-BY-CHAIN-AND-DICTIONARY mode;
5766+
// they apply only in USER-DEFINED-COLOURS mode (see Bond_lines_container::atom_colour()).
5767+
// So none of the user-defined colours should appear here.
57675768
bool col_51 = false;
57685769
bool col_52 = false;
57695770
bool col_53 = false;
@@ -5772,10 +5773,17 @@ int test_user_defined_bond_colours_v3(molecules_container_t &mc) {
57725773
if (is_near_colour(ca_row.col, colour_map[51])) col_51 = true;
57735774
if (is_near_colour(ca_row.col, colour_map[52])) col_52 = true;
57745775
if (is_near_colour(ca_row.col, colour_map[53])) col_53 = true;
5776+
if (is_near_colour(ca_row.col, colour_map[51])) {
5777+
std::cout << "colour " << glm::to_string(ca_row.col) << " with " << ca_row.count
5778+
<< "counts is close to col 51" << std::endl;
5779+
}
57755780
}
5781+
std::cout << "debug: test_user_defined_bond_colours_v3: col_51 " << col_51 << std::endl;
5782+
std::cout << "debug: test_user_defined_bond_colours_v3: col_52 " << col_52 << std::endl;
5783+
std::cout << "debug: test_user_defined_bond_colours_v3: col_53 " << col_53 << std::endl;
57765784
if (col_51 == false)
57775785
if (col_52 == false)
5778-
if (col_53 == true)
5786+
if (col_53 == false)
57795787
status = true;
57805788
}
57815789

@@ -5853,12 +5861,18 @@ int test_other_user_defined_colours_other(molecules_container_t &mc) {
58535861
}
58545862
std::vector<colour_analysis_row> ca_1 = get_colour_analysis(bonds_1);
58555863
std::vector<colour_analysis_row> ca_3 = get_colour_analysis(bonds_3);
5856-
// different vec indices because UD colour becomes the first colour.
5857-
// This is weird. When run in "single test only" the indices need to
5858-
// be 4 and 3. It might have something to do with reading the ATP at the start.
5859-
//
5860-
if (ca_3[3].count == (ca_1[2].count - 85))
5861-
status = 1;
5864+
// Setting user-defined atom colours must NOT change COLOUR-BY-CHAIN-AND-DICTIONARY
5865+
// rendering - user-defined colours no longer leak into other colouring modes
5866+
// (see Bond_lines_container::atom_colour()). So the colour analysis before (ca_1)
5867+
// and after (ca_3) setting the user colours should be identical.
5868+
if (ca_1.size() == ca_3.size()) {
5869+
bool all_same = true;
5870+
for (unsigned int i=0; i<ca_1.size(); i++)
5871+
if (ca_1[i].count != ca_3[i].count)
5872+
all_same = false;
5873+
if (all_same)
5874+
status = 1;
5875+
}
58625876

58635877
}
58645878
}
@@ -8192,6 +8206,9 @@ int test_template(molecules_container_t &mc) {
81928206
int n_tests = 0;
81938207
static std::vector<std::pair<std::string, int> > test_results;
81948208

8209+
// If set (via "--by-name <test-name>"), only the test with this exact name is run.
8210+
static std::string g_only_test_name;
8211+
81958212
void
81968213
write_test_name(const std::string &test_name) {
81978214

@@ -8203,6 +8220,9 @@ write_test_name(const std::string &test_name) {
82038220
int
82048221
run_test(int (*test_func) (molecules_container_t &mc), const std::string &test_name, molecules_container_t &mc) {
82058222

8223+
if (! g_only_test_name.empty() && test_name != g_only_test_name)
8224+
return 0; // --by-name: skip this test (not run, not counted)
8225+
82068226
n_tests++;
82078227
write_test_name(test_name);
82088228
int status = test_func(mc);
@@ -8267,6 +8287,14 @@ int main(int argc, char **argv) {
82678287
std::string arg(argv[1]);
82688288
if (arg == "last-test-only")
82698289
last_test_only = true;
8290+
if (arg == "--by-name") {
8291+
if (argc > 2) {
8292+
g_only_test_name = argv[2];
8293+
} else {
8294+
std::cout << "Usage: " << argv[0] << " --by-name <test-name>" << std::endl;
8295+
return 1;
8296+
}
8297+
}
82708298
}
82718299

82728300
int all_tests_status = 1; // fail!
@@ -8515,6 +8543,11 @@ int main(int argc, char **argv) {
85158543
// status += run_test(test_density_mesh, "density mesh", mc);
85168544
// status += run_test(test_molecular_placement_pipeline_r_chain, "MR R-chain", mc);
85178545
status += run_test(test_molecular_placement_pipeline, "MR pipeline", mc);
8546+
8547+
if (! g_only_test_name.empty() && n_tests == 0) {
8548+
std::cout << "ERROR:: --by-name: no test matched \"" << g_only_test_name << "\"" << std::endl;
8549+
return 1;
8550+
}
85188551
if (status == n_tests) all_tests_status = 0;
85198552

85208553
print_results_summary();

coords/Bond_lines.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5039,13 +5039,17 @@ Bond_lines_container::do_Ca_or_P_bonds_internal(atom_selection_container_t SelAt
50395039
int udd_user_defined_atom_colour_index_handle = SelAtom.mol->GetUDDHandle(mmdb::UDR_ATOM,
50405040
"user-defined-atom-colour-index");
50415041

5042-
auto get_atom_colour_index = [udd_user_defined_atom_colour_index_handle] (mmdb:: Atom *at,
5042+
auto get_atom_colour_index = [udd_user_defined_atom_colour_index_handle, bond_colour_type] (mmdb:: Atom *at,
50435043
const std::string &chain_id,
50445044
coot::my_atom_colour_map_t &atom_colour_map) {
50455045
int idx_col = atom_colour_map.index_for_chain(chain_id);
5046-
int idx_col_udd;
5047-
if (at->GetUDData(udd_user_defined_atom_colour_index_handle, idx_col_udd) == mmdb::UDDATA_Ok) {
5048-
idx_col = idx_col_udd;
5046+
// Only honour the user-defined per-atom colour in a user-defined colouring mode,
5047+
// otherwise it leaks into other modes (e.g. colour-by-chain). c.f. atom_colour().
5048+
if (bond_colour_type == coot::COLOUR_BY_USER_DEFINED_COLOURS) {
5049+
int idx_col_udd;
5050+
if (at->GetUDData(udd_user_defined_atom_colour_index_handle, idx_col_udd) == mmdb::UDDATA_Ok) {
5051+
idx_col = idx_col_udd;
5052+
}
50495053
}
50505054
return idx_col;
50515055
};

0 commit comments

Comments
 (0)