25 #define TREE_SYNCROOT_AWAR_BASE "tree/syncroot/"
26 #define TREE_SYNCROOT_TEMP_BASE "tmp/" TREE_SYNCROOT_AWAR_BASE
27 #define AWAR_TREE_SYNCROOT_SELECTED TREE_SYNCROOT_TEMP_BASE "selected"
37 addTo.
add(satree, treename);
56 SizeAwareTree *resultTree = rsync.
take_tree(t);
59 arb_assert(newRootEdge->is_inside(resultTree));
60 if (newRootEdge->is_son_of_root()) {
61 const char *what = rt<0 ?
"best found" :
"optimal";
65 SizeAwareTree *newRootEdge_nc =
const_cast<SizeAwareTree*
>(&*newRootEdge);
66 newRootEdge_nc->set_root();
90 error = ta.
close(error);
103 StrArray tosync_tree;
104 tosync_trees_selection->
get_values(tosync_tree);
106 if (tosync_tree.empty()) {
107 aw_message(
"List of trees to synchronize is empty (left list). Nothing to do.");
114 aw_message(
"No reference tree selected (in right list)");
118 progress.
subtitle(
"Loading trees..");
122 const int REF_IDX = 0;
124 for (
int i = 0; tosync_tree[i] && !
error; ++i) {
125 if (strcmp(tosync_tree[i], ref_tree_name) == 0) {
137 error =
"nothing to synchronize";
142 for (
size_t t = 1; t<=toSyncCount && !
error; ++t) {
145 string distInfo = lowestDist ?
GBS_global_string(
"distance: %i", lowestDist) :
"perfect match";
147 error =
adjustTreeRoot(bestEdge, rsync, t, gb_main, distInfo.c_str(), REF_IDX);
162 StrArray tosync_tree;
163 tosync_trees_selection->
get_values(tosync_tree);
165 if (tosync_tree.size()<2) {
166 aw_message(
"Need at least two trees to synchronize (in left list).");
172 for (
int i = 0; tosync_tree[i] && !
error; ++i) {
191 arb_progress progress(
"Multi root optimize (abort to stop early)");
198 int overallDistSum = mroot->distanceSum(rsync);
200 if (progress.
aborted())
aw_message(
"[search aborted by user -> using best result so far]");
204 int treeDistSum = mroot->singleTreeDistanceSum(rsync, t);
205 string distInfo =
GBS_global_string(
"distance to other trees: %i/%i", treeDistSum, overallDistSum);
207 error =
adjustTreeRoot(newRootEdge, rsync, t, gb_main, distInfo.c_str(), -1);
221 static AW_window_simple *aws =
NULp;
226 aws =
new AW_window_simple;
227 aws->init(awr,
"SYNCROOT",
"Adjust roots of trees");
228 aws->load_xfig(
"syncroot.fig");
230 aws->auto_space(10, 10);
234 aws->create_button(
"CLOSE",
"CLOSE",
"C");
238 aws->create_button(
"HELP",
"HELP",
"H");
246 aws->create_autosize_button(
"SYNC_ALL_TREES",
"to find common optima for all.",
"a");
250 aws->create_autosize_button(
"SYNC_TO_ONE",
"to tree selected in the right list",
"r");
262 static const char *custom_tree_name(
int dir,
const char *name) {
return GBS_global_string(
"syncroot/%i/%s.tree", dir, name); }
264 static SizeAwareTree *loadTree(
const char *treefile,
GB_ERROR&
error) {
276 GB_warningf(
"while loading tree '%s':\n%s", treefile, warnings);
283 static string wayFromTo_internal(
const TreeNode *ancestor,
const TreeNode *successor) {
284 if (successor == ancestor)
return "";
287 string wayToFather = wayFromTo_internal(ancestor, father);
289 return wayToFather+(successor->
is_leftson() ?
'l' :
'r');
291 static string wayFromTo(
const TreeNode *ancestor,
const TreeNode *successor) {
296 return wayFromTo_internal(ancestor, successor);
299 return "<not same tree>";
302 return "<wrong order>";
308 return "!"+wayFromTo_internal(brother, successor);
318 return wayFromTo_internal(root, ancestor) +
"-" + wayFromTo_internal(root, successor);
321 template<
class TREECONT>
322 int loadTreeAndAddTo(
int dir,
const char *name, TREECONT& container) {
324 SizeAwareTree *tree = loadTree(custom_tree_name(dir, name), error);
327 return container.add(tree, name);
330 void TEST_part_node_linkage() {
334 loadTreeAndAddTo(1,
"ref", tc);
336 for (
int partial = 0; partial<=1; ++partial) {
339 loadTreeAndAddTo(1,
"overlap", tc);
348 const SizeAwareTree *root = tc.
get_tree(0);
352 error = dtree.deconstruct_weighted(root, tparts.get_tree_PART(0), root->get_leaf_count(), 1.0,
false, specSpace.get_allSpecies(),
DMODE_ROOTSYNC);
356 dtree.start_sorted_retrieval();
364 const PART *rootPART = dtree.find_part(root);
367 const SizeAwareTree *leftRootSon = root->get_leftson();
368 const SizeAwareTree *rightRootSon = root->get_rightson();
370 const PART *leftRootPART = dtree.find_part(leftRootSon);
371 const PART *rightRootPART = dtree.find_part(rightRootSon);
383 std::vector<const SizeAwareTree*> toTest;
384 toTest.push_back(leftRootSon->get_leftson());
385 toTest.push_back(leftRootSon->get_rightson());
386 toTest.push_back(rightRootSon->get_leftson());
387 toTest.push_back(rightRootSon->get_rightson());
389 while (!toTest.empty()) {
390 const SizeAwareTree *
node = toTest.back();
393 const PART *nodePART = dtree.find_part(node);
398 if (!node->is_leaf()) {
399 toTest.push_back(node->get_leftson());
400 toTest.push_back(node->get_rightson());
412 void TEST_part_distance() {
415 const int tosync_idx = loadTreeAndAddTo(1,
"tosync", rs);
416 const int ref_idx = loadTreeAndAddTo(1,
"ref", rs);
417 const int disj_idx = loadTreeAndAddTo(1,
"disjunct", rs);
418 const int over_idx = loadTreeAndAddTo(1,
"overlap", rs);
428 const int SPACE_SIZE = 12;
432 const SizeAwareTree *tosync_root = rs.
get_tree(tosync_idx);
433 const SizeAwareTree *ref_root = rs.
get_tree(ref_idx);
434 const SizeAwareTree *disj_root = rs.
get_tree(disj_idx);
435 const SizeAwareTree *over_root = rs.
get_tree(over_idx);
453 const int DISJUNCT_DIST = 12;
462 const SizeAwareTree *tosync_rightson = tosync_root->get_rightson();
TEST_REJECT_NULL(tosync_rightson);
470 const SizeAwareTree *tosync_grandson = tosync_rightson->get_rightson();
TEST_REJECT_NULL(tosync_grandson);
473 int RIGHT_GRAND_DIST = 4;
482 const SizeAwareTree *tosync_othergrandson = tosync_grandson->get_brother();
TEST_REJECT_NULL(tosync_othergrandson);
488 const SizeAwareTree *disj_leftson = disj_root->get_leftson ();
TEST_REJECT_NULL(disj_leftson);
489 const SizeAwareTree *disj_grandson = disj_root->get_rightson()->get_leftson();
TEST_REJECT_NULL(disj_grandson);
491 const PART *disj_leftson_PART = disj_dtree.find_part(disj_leftson);
TEST_REJECT_NULL(disj_leftson_PART);
492 const PART *disj_grandson_PART = disj_dtree.find_part(disj_grandson);
TEST_REJECT_NULL(disj_grandson_PART);
502 const SizeAwareTree *over_leftson = over_root->get_leftson();
TEST_REJECT_NULL(over_leftson);
503 const PART *over_leftson_PART = over_dtree.find_part(over_leftson);
TEST_REJECT_NULL(over_leftson_PART);
507 const SizeAwareTree *over_somenode = over_leftson->get_leftson();
TEST_REJECT_NULL(over_somenode);
508 const PART *over_somenode_PART = over_dtree.find_part (over_somenode);
TEST_REJECT_NULL(over_somenode_PART);
516 bool reverseSearchFound_identicalIndex =
false;
517 bool reverseSearchFound_duplicateIndex =
false;
518 bool selfSearchFound_identicalIndex =
false;
519 bool selfSearchFound_duplicateIndex =
false;
521 for (
size_t pr = 0; pr<ref_dtree.get_part_count(); ++pr) {
522 const PART *ref_PART = ref_dtree.peek_part(pr);
551 if (
size_t(best_idx) == pr) reverseSearchFound_identicalIndex =
true;
552 else reverseSearchFound_duplicateIndex =
true;
562 if (
size_t(best_idx) == pr) selfSearchFound_identicalIndex =
true;
563 else selfSearchFound_duplicateIndex =
true;
574 for (
size_t pd = 0; pd<disj_dtree.get_part_count(); ++pd) {
575 const PART *disj_PART = disj_dtree.peek_part(pd);
580 for (
size_t pr = 0; pr<ref_dtree.get_part_count(); ++pr) {
581 const PART *ref_PART = ref_dtree.peek_part(pr);
591 for (
size_t po = 0; po<over_dtree.get_part_count(); ++po) {
592 const PART *over_PART = over_dtree.peek_part(po);
597 int best_dist, best_idx;
598 int worst_dist, worst_idx;
623 void TEST_RootSynchronizer() {
626 int tosync_idx = loadTreeAndAddTo(1,
"tosync", rsync1);
627 int ref_idx = loadTreeAndAddTo(1,
"ref", rsync1);
687 const int distSum0 = mr0->distanceSum(rsync1);
688 const int distCenter0 = mr0->distanceToCenterSum(rsync1);
703 mr2->replace_node(idx, newNode);
706 int distSum2 = mr2->distanceSum(rsync1);
707 int distCenter2 = mr2->distanceToCenterSum(rsync1);
713 newNode = node->get_leftson();
715 mr2->replace_node(idx, newNode);
718 int distSum2 = mr2->distanceSum(rsync1);
719 int distCenter2 = mr2->distanceToCenterSum(rsync1);
747 SizeAwareTree *tosync_released = rsync1.
take_tree(tosync_idx);
760 arb_assert(newRoot->is_inside(tosync_released));
761 SizeAwareTree *newRoot_nc =
const_cast<SizeAwareTree*
>(&*newRoot);
765 newRoot_nc->set_root();
771 tosync_idx = rsync2.
add(tosync_released,
"tosync");
775 SizeAwareTree *ref_released = rsync1.
take_tree(ref_idx);
776 ref_idx = rsync2.
add(ref_released,
"ref");
781 int tr_dist, rt_dist;
809 loadTreeAndAddTo(1,
"tosync", rsync3);
817 void TEST_sync_more_trees() {
821 const int ref_idx = loadTreeAndAddTo(1,
"ref", rsync);
822 const int disjunct_idx = loadTreeAndAddTo(1,
"disjunct", rsync);
832 const int DISTSUM = 12;
843 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(ref_idx), synced->get_node(ref_idx)),
"");
844 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(disjunct_idx), synced->get_node(disjunct_idx)),
"!l");
851 const int tosync_idx = loadTreeAndAddTo(1,
"tosync", rsync);
852 const int disjunct_idx = loadTreeAndAddTo(1,
"disjunct", rsync);
853 const int overa_idx = loadTreeAndAddTo(1,
"overlap_A", rsync);
862 const int OPTIMAL_DIST = 24;
876 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(tosync_idx), synced->get_node(tosync_idx)),
"!l");
877 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(disjunct_idx), synced->get_node(disjunct_idx)),
"!l");
878 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(overa_idx), synced->get_node(overa_idx)),
"!lrr");
885 const int tosync_idx = loadTreeAndAddTo(1,
"tosync", rsync);
886 const int ref_idx = loadTreeAndAddTo(1,
"ref", rsync);
887 const int over_idx = loadTreeAndAddTo(1,
"overlap", rsync);
888 const int overa_idx = loadTreeAndAddTo(1,
"overlap_A", rsync);
897 const int OPTIMAL_DIST = 24;
914 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(tosync_idx), synced->get_node(tosync_idx)),
"!lr");
915 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(ref_idx), synced->get_node(ref_idx)),
"");
916 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(over_idx), synced->get_node(over_idx)),
"");
917 TEST_EXPECT_EQUAL(wayFromTo(start->get_node(overa_idx), synced->get_node(overa_idx)),
"!lr");
const PART * peek_part(int idx) const
void beginDeconstructionPhase()
static void find_best_matching_PART_in(int &best_dist, int &best_idx, const PART *part, const DeconstructedTree &in, const PART *tree_part, const PART *tree_in, bool provideProgress)
const char * name() const
const TreeNode * get_origin(const PART *part)
const SpeciesSpace & get_SpeciesSpace() const
const SizeAwareTree * get_tree(int idx) const
static void create_syncroot_awars(AW_root *awr)
AW_selection * awt_create_subset_selection_list(AW_window *aww, AW_selection_list *parent_selection, const char *at_box, const char *at_add, const char *at_sort, bool autocorrect_subselection, SubsetChangedCb subChanged_cb, AW_CL cl_user)
size_t get_species_count() const
static void find_worst_matching_PART_in(int &worst_dist, int &worst_idx, const PART *part, const DeconstructedTree &in, const PART *tree_part, const PART *tree_in)
TreeRoot * get_tree_root() const
TreeNode * GBT_read_tree(GBDATA *gb_main, const char *tree_name, TreeRoot *troot)
GB_ERROR GBT_log_to_tree_remark(GBDATA *gb_tree, const char *log_entry, bool stamp)
const char * GBS_global_string(const char *templat,...)
ErrorOrSizeAwareTreePtr find_best_root_candidate(int inTree, int accordingToTree, int &best_dist, bool provideProgress)
AW_DB_selection * awt_create_TREE_selection_list(GBDATA *gb_main, AW_window *aws, const char *varname)
void AW_POPDOWN(AW_window *window)
ErrorOrMultirootPtr find_good_roots_for_trees(const int MAX_DEPTH, arb_progress *progress=NULp)
size_t get_tree_count() const
void get_values(StrArray &intoArray)
const T * plain_pointer() const
convert RefPtr to plain old pointer
int get_members(const PART *part)
#define DOWNCAST(totype, expr)
const PART * get_tree_PART(int treeIdx) const
static HelixNrInfo * start
ErrorOrDeconstructedTreePtr get_DeconstructedTree(int treeIdx)
const char * read_char_pntr() const
int calcDistance(const PART *e1, const PART *e2, const PART *t1, const PART *t2)
#define TEST_EXPECT_CONTAINS(str, part)
GB_ERROR GB_await_error()
WindowCallback makeHelpCallback(const char *helpfile)
#define TEST_EXPECT(cond)
GB_ERROR GBT_overwrite_tree(GBDATA *gb_tree, TreeNode *tree)
void GB_warningf(const char *templat,...)
const TreeInfo & get_tree_info(int idx) const
bool is_son_of_root() const
AW_window * NT_create_syncroot_window(AW_root *awr, GBDATA *gb_main)
int add(SizeAwareTree *&tree, const char *treename)
const PART * find_part(const TreeNode *node) const
CONSTEXPR_INLINE int leafs_2_edges(int leafs, TreeModel model)
#define TEST_REJECT(cond)
#define TEST_REJECT_NULL(n)
static void error(const char *msg)
TreeNode * TREE_load(const char *path, TreeRoot *troot, char **commentPtr, bool allow_length_scaling, char **warningPtr)
const PART * get_allSpecies() const
static ARB_ERROR adjustTreeRoot(ConstSizeAwareTreePtr newRootEdge, RootSynchronizer &rsync, size_t t, GBDATA *gb_main, const char *distInfo, int rt)
GB_ERROR deconstruct_all_trees(bool provideProgress)
static SearchTree * tree[SEARCH_PATTERNS]
AW_awar * awar(const char *awar)
void get_species_names(ConstStrArray &species_names) const
MultirootPtr get_innermost_edges() const
ErrorOrMultirootPtr get_current_roots() const
#define TEST_EXPECT_NULL(n)
static list< LineAttachedMessage > warnings
GB_ERROR close(GB_ERROR error)
bool represents_existing_edge(const PART *p)
bool is_inside(const TreeNode *subtree) const
static void rootsync_subsetTrees_vs_selected(AW_window *aws, GBDATA *gb_main, AW_selection *tosync_trees_selection)
const int MULTIROOT_SEARCH_DEPTH
void subtitle(const char *stitle)
#define TEST_EXPECT_NO_ERROR(call)
void aw_message(const char *msg)
static void multiroot_sync_subsetTrees(AW_window *, GBDATA *gb_main, AW_selection *tosync_trees_selection)
#define TEST_EXPECT_ERROR_CONTAINS(call, part)
int minDistanceSum() const
#define TEST_EXPECT_DIFFERENT(expr, want)
#define AWAR_TREE_SYNCROOT_SELECTED
ARB_ERROR getError() const
static GB_ERROR load_and_add_tree(GBDATA *gb_main, const char *treename, RootSynchronizer &addTo)
GBDATA * GBT_find_tree(GBDATA *gb_main, const char *tree_name)
GB_transaction ta(gb_var)
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
SizeAwareTree * take_tree(int idx)
#define TEST_EXPECT_EQUAL(expr, want)
void inc_and_check_user_abort(GB_ERROR &error)
AW_selection_list * get_sellist()
void aw_message_if(GB_ERROR error)
int calcTreeDistance(int i1, int i2) const