Swc_Tree_Node *Find_Closest_Leaf_Point(Swc_Tree *tree, double *pos, double *dist_xy, double *dist_z){ double tn_pos[3]; double dxy, dz; Swc_Tree_Iterator_Start(tree, 2, FALSE); Swc_Tree_Node *tn = NULL; Swc_Tree_Node *close_tn = NULL; double mindist = -1.0; while ((tn = Swc_Tree_Next(tree)) != NULL) { if (Swc_Tree_Node_Is_Regular(tn) && Swc_Tree_Node_Is_Leaf(tn)) { Swc_Tree_Node_Pos(tn, tn_pos); if (mindist < 0) { close_tn = tn; mindist = Geo3d_Dist_Sqr(pos[0], pos[1], pos[2], tn_pos[0], tn_pos[1], tn_pos[2]); dxy = sqrt((pos[0]-tn_pos[0])*(pos[0]-tn_pos[0])+(pos[1]-tn_pos[1])*(pos[1]-tn_pos[1])); dz = fabs(pos[2] - tn_pos[2]); }else { double d = Geo3d_Dist_Sqr(pos[0], pos[1], pos[2], tn_pos[0], tn_pos[1], tn_pos[2]); if (d < mindist) { mindist = d; close_tn = tn; dxy = sqrt((pos[0]-tn_pos[0])*(pos[0]-tn_pos[0])+(pos[1]-tn_pos[1])*(pos[1]-tn_pos[1])); dz = fabs(pos[2] - tn_pos[2]); } } } } *dist_xy = dxy; *dist_z = dz; return close_tn; }
double Puncta_Tree_Distance(double x, double y, double z, double r, Swc_Tree* tree, double pixelperumxy, double pixelperumz, BOOL bmask, double maskextendbyum, Swc_Tree_Node** refNode) { double min_dist = DBL_MAX; double zscale = pixelperumxy/pixelperumz; Swc_Tree_Iterator_Start(tree, SWC_TREE_ITERATOR_DEPTH_FIRST, FALSE); Swc_Tree_Node *tn; while ((tn = Swc_Tree_Next(tree)) != NULL) { if (!Swc_Tree_Node_Is_Virtual(tn) && !Swc_Tree_Node_Is_Root(tn) && tn->node.type != 1) { double dist = sqrt((tn->node.x-x)*(tn->node.x-x) + (tn->node.y-y)*(tn->node.y-y) + (tn->node.z-z)*(tn->node.z-z))-tn->node.d; if (dist > 1000) { continue; } dist = Point_Frustum_Cone_Distance(x, y, z, &(tn->node), &(tn->parent->node), zscale); if (bmask) { double maskextendxy = maskextendbyum*pixelperumxy; if (dist < maskextendxy + r && dist < min_dist) { //in mask area min_dist = dist; if (refNode) *refNode = tn; } } else { if (dist < min_dist) { min_dist = dist; if (refNode) *refNode = tn; } } } } return min_dist; }
double Point_Tree_Distance(double x, double y, double z, Swc_Tree* tree, double zScale, Swc_Tree_Node** refNode) { double min_dist = DBL_MAX; Swc_Tree_Iterator_Start(tree, SWC_TREE_ITERATOR_DEPTH_FIRST, FALSE); Swc_Tree_Node *tn; while ((tn = Swc_Tree_Next(tree)) != NULL) { if (!Swc_Tree_Node_Is_Virtual(tn) && !Swc_Tree_Node_Is_Root(tn)) { double dist = Point_Frustum_Cone_Distance(x, y, z, &(tn->node), &(tn->parent->node), zScale); if (dist < min_dist) { min_dist = dist; if (refNode) *refNode = tn; } } } return min_dist; }
void ZSwcSignalFitter::fitSignal( Swc_Tree *tree, const ZStack *stack, int channel) { Swc_Tree_Iterator_Start(tree, SWC_TREE_ITERATOR_DEPTH_FIRST, false); Swc_Tree_Node *tmptn = NULL; while ((tmptn = Swc_Tree_Next(tree)) != NULL) { if (!SwcTreeNode::isRoot(tmptn)) { ZPoint oldCenter = SwcTreeNode::center(tmptn); double oldBend = SwcTreeNode::maxBendingEnergy(tmptn); fitSignal(tmptn, stack, channel); double newBend = SwcTreeNode::maxBendingEnergy(tmptn); if (newBend > 1.0) { if (newBend - oldBend > 0.5) { SwcTreeNode::setPos(tmptn, oldCenter); } } } } }
/* Calculate positions of key nodes in the dendrogram of <tree>, which is a * reduced tree. */ static void swc_tree_dendrogram_position(Swc_Tree *tree, int max_vx, int max_vy, double *x, double *y, double *dm, double *xscale) { int count = Swc_Tree_Iterator_Start(tree, 1, TRUE) + 1; /* alloc <decided> */ uint8 *decided = u8array_calloc(count); /* alloc <isleaf> */ uint8 *isleaf = u8array_calloc(count); /* the left-top corner of the bounding box is <margin> */ double margin = 10.0; x[1] = 0.0; x[2] = 0.0; Swc_Tree_Node *root = tree->root; Swc_Tree_Node *node = root; int leaf_count = 0; double xmax = x[1]; /* Calculate the x positions and the right most position. */ /* x(tn) = x(p(tn)) + length(p(tn)->tn) */ while ((node = node->next) != NULL) { x[Swc_Tree_Node_Data(node)->label] = node->weight + x[Swc_Tree_Node_Data(node->parent)->label]; xmax = dmax2(x[Swc_Tree_Node_Data(node)->label], xmax); if (node->first_child == NULL) { isleaf[Swc_Tree_Node_Data(node)->label] = 1; leaf_count++; } } *dm = 10.0; if (leaf_count > 1) { *dm = ((double) max_vy - 2.0 * margin) / (leaf_count - 1); } *xscale = (max_vx - margin * 2) / xmax; node = root; x[1] += margin; double cur_y = margin; //double ymax = 0.0; /* Calculate y positions of the leaves. */ while ((node = node->next) != NULL) { if (Swc_Tree_Node_Label(node) > 1) { x[Swc_Tree_Node_Label(node)] = x[Swc_Tree_Node_Label(node)] * *xscale + margin; if (isleaf[Swc_Tree_Node_Data(node)->label]) { y[Swc_Tree_Node_Data(node)->label] = cur_y; decided[Swc_Tree_Node_Data(node)->label] = 1; cur_y += *dm; } } } Swc_Tree_Iterator_Start(tree, 2, FALSE); Swc_Tree_Iterator_Start(tree, -1, FALSE); /* Calculate the y positions by traversing backward */ while ((node = Swc_Tree_Next(tree)) != NULL) { double tmp_miny = -1.0; double tmp_maxy = -1.0; if (decided[Swc_Tree_Node_Data(node)->label] == 0) { Swc_Tree_Node *child = node->first_child; int n = 0; cur_y = 0.0; while (child != NULL) { //cur_y += y[Swc_Tree_Node_Data(child)->label]; cur_y = y[Swc_Tree_Node_Data(child)->label]; if (tmp_miny < 0.0) { tmp_miny = cur_y; tmp_maxy = cur_y; } else { if (tmp_miny > cur_y) { tmp_miny = cur_y; } else if (tmp_maxy < cur_y) { tmp_maxy = cur_y; } } n++; child = child->next_sibling; } //y[Swc_Tree_Node_Data(node)->label] = cur_y / n; y[Swc_Tree_Node_Data(node)->label] = (tmp_miny + tmp_maxy) / 2.0; decided[Swc_Tree_Node_Data(node)->label] = 1; } } x[0] = x[1]; y[0] = y[1]; /* free <decided> */ free(decided); /* free <isleaf> */ free(isleaf); }
int main(int argc, char *argv[]) { static char *Spec[] = {"<dataset:string> | -D <string>", NULL}; Process_Arguments(argc, argv, Spec, 1); char file_path[100]; if (Is_Arg_Matched("-D")) { sprintf(file_path, "%s/error.xml", Get_String_Arg("-D")); } else { sprintf(file_path, "../data/diadem_%s/error.xml", Get_String_Arg("dataset")); } xmlDocPtr doc; xmlNodePtr cur; doc = xmlParseFile(file_path); if (doc == NULL) { fprintf(stderr, "XML parsing failed.\n"); return 1; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "empty document\n"); xmlFreeDoc(doc); return 1; } if (xmlStrcmp(cur->name, (const xmlChar*) "diadem_metric")) { fprintf(stderr, "document of wrong type\n"); xmlFreeDoc(doc); return 1; } cur = cur->xmlChildrenNode; char *miss_file = NULL; char *golden_file = NULL; char *extra_file = NULL; char *nearby_file = NULL; char *test_file = NULL; char *miss_swc_file = NULL; char *extra_swc_file = NULL; char *nearby_swc_file = NULL; char *miss_vlm_file = NULL; char *extra_vlm_file = NULL; char *nearby_vlm_file = NULL; char *miss_score_file = NULL; char *extra_score_file = NULL; double EuDistThre_xy = 0.0; double EuDistThre_z = 0.0; double score; while (cur != NULL) { if (Xml_Node_Is_Element(cur, "miss") == TRUE) { miss_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "extra") == TRUE) { extra_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "score") == TRUE) { score = Xml_Node_Double_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "golden") == TRUE) { golden_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "nearby") == TRUE) { nearby_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "test") == TRUE) { test_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "miss_swc") == TRUE) { miss_swc_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "extra_swc") == TRUE) { extra_swc_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "nearby_swc") == TRUE) { nearby_swc_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "miss_vlm") == TRUE) { miss_vlm_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "extra_vlm") == TRUE) { extra_vlm_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "nearby_vlm") == TRUE) { nearby_vlm_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "miss_score") == TRUE) { miss_score_file = Xml_Node_String_Value(doc, cur); } else if (Xml_Node_Is_Element(cur, "extra_score") == TRUE) { extra_score_file = Xml_Node_String_Value(doc, cur); }else if(Xml_Node_Is_Element(cur, "xyth") == TRUE) { EuDistThre_xy = Xml_Node_Double_Value(doc, cur); }else if(Xml_Node_Is_Element(cur, "zth") == TRUE) { EuDistThre_z = Xml_Node_Double_Value(doc, cur); } cur = cur->next; } if ((EuDistThre_xy <= 0.0) || (EuDistThre_z <= 0.0)) { fprintf(stderr, "Invalid threshold value\n"); xmlFreeDoc(doc); return 1; } Swc_Tree *tree = Read_Swc_Tree(golden_file); double bound[6]; Swc_Tree_Bound_Box(tree, bound); double marker_ratio = dmax3(bound[3] - bound[0], bound[4] - bound[1], bound[5] - bound[2]) / 512.0; Geo3d_Scalar_Field *miss_field = read_node_file(miss_file); printf("The missed nodes:\n"); Print_Geo3d_Scalar_Field(miss_field); Geo3d_Scalar_Field *extra_field = read_node_file(extra_file); printf("The extra nodes:\n"); Print_Geo3d_Scalar_Field(extra_field); Geo3d_Scalar_Field *nearby_field = read_node_file(nearby_file); // Print_Geo3d_Scalar_Field(nearby_field); double wm = darray_sum(miss_field->values, miss_field->size); double we = darray_sum(extra_field->values, extra_field->size); double wg = round((score * we + wm) / (1 - score)); // printf("%g %g %g\n", wm, we, wg); Swc_Tree_Iterator_Start(tree, 2, FALSE); int max_id = 0; Swc_Tree_Node *tn = NULL; while ((tn = Swc_Tree_Next(tree)) != NULL) { Swc_Tree_Node_Data(tn)->type = 3; if (max_id < Swc_Tree_Node_Data(tn)->id) { max_id = Swc_Tree_Node_Data(tn)->id; } } uint8 *nearby_mask = u8array_calloc(max_id + 1); /* process nearby nodes */ FILE *fp = NULL; FILE *fp3 = NULL; if (nearby_swc_file != NULL) { fp = fopen(nearby_swc_file, "w"); } if (nearby_vlm_file != NULL) { fp3 = fopen(nearby_vlm_file, "w"); } // printf("Nearby list\n"); int i; for (i = 0; i < nearby_field->size; i++) { Swc_Tree_Node *tn = Swc_Tree_Closest_Node(tree, nearby_field->points[i]); nearby_mask[Swc_Tree_Node_Data(tn)->id] = 1; double w = (1.0+3.0/(1+exp(-(nearby_field->values[i]*2.0-2.0)))) * marker_ratio; if (fp != NULL) { fprintf(fp, "%d %d %g %g %g %g %d\n", i + 1, 7, Swc_Tree_Node_Data(tn)->x, Swc_Tree_Node_Data(tn)->y, Swc_Tree_Node_Data(tn)->z,w, -1); } if (fp3 != NULL) { fprintf(fp3, "%g,%g,%g,%g,1,%g\n", Swc_Tree_Node_Data(tn)->x, Swc_Tree_Node_Data(tn)->y, Swc_Tree_Node_Data(tn)->z, w, nearby_field->values[i]); } } if (fp != NULL) { fclose(fp); } if (fp3 != NULL) { fclose(fp3); } /* process missing nodes */ fp = NULL; FILE *fp2 = fopen(miss_score_file, "w"); fp3 = NULL; if (miss_swc_file != NULL) { fp = fopen(miss_swc_file, "w"); } if (miss_vlm_file != NULL) { fp3 = fopen(miss_vlm_file, "w"); } Swc_Tree *test_tree = Read_Swc_Tree(test_file); // printf("Missing list\n"); int n_leaves = 0; int n_branchings = 0; int n_leaves_distance = 0; int n_leaves_path = 0; int n_branchings_distance = 0; int n_branchings_path = 0; double score_leaves = 0.0; double score_branchings = 0.0; double score_leaves_distance = 0.0; double score_leaves_path = 0.0; double score_branching_distance = 0.0; double score_branching_path = 0.0; BOOL error_type; // 'true' indicates distance-error, 'false' indicates path-error for (i = 0; i < miss_field->size; i++) { Swc_Tree_Node *tn = Swc_Tree_Closest_Node(tree, miss_field->points[i]); double cur_score = miss_field->values[i] / (wg + we); fprintf(fp2, "%4d | %5.2f %5.2f %5.2f | %g | %g\n", Swc_Tree_Node_Data(tn)->id, Swc_Tree_Node_Data(tn)->x, Swc_Tree_Node_Data(tn)->y, Swc_Tree_Node_Data(tn)->z, miss_field->values[i], cur_score); Swc_Tree_Node_Data(tn)->type = 2; double w = (1.0+3.0/(1+exp(-(miss_field->values[i]*2.0-2.0)))) * marker_ratio; if (fp != NULL) { int type = 0; if (nearby_mask[Swc_Tree_Node_Data(tn)->id] == 1) { type = 1; } fprintf(fp, "%d %d %g %g %g %g %d\n", i + 1, type, Swc_Tree_Node_Data(tn)->x, Swc_Tree_Node_Data(tn)->y, Swc_Tree_Node_Data(tn)->z, w, -1); } if (fp3 != NULL) { double xy_dist, z_dist; Swc_Tree_Node *test_tn; double pos[3]; Swc_Tree_Node_Pos(tn, pos); if(Swc_Tree_Node_Is_Branch_Point(tn)) test_tn = Find_Closest_Branch_Point(test_tree, pos, &xy_dist, &z_dist); else test_tn = Find_Closest_Leaf_Point(test_tree, pos, &xy_dist, &z_dist); if(xy_dist >= EuDistThre_xy || z_dist >= EuDistThre_z){ fprintf(fp3, "%g,%g,%g,%g,1,%g,[xy-%g z-%g | distance_error], 255, 255, 0\n",Swc_Tree_Node_Data(tn)->x + 1.0, Swc_Tree_Node_Data(tn)->y + 1.0, Swc_Tree_Node_Data(tn)->z + 1.0, w, miss_field->values[i], xy_dist, z_dist); error_type = TRUE; }else{ fprintf(fp3, "%g,%g,%g,%g,1,%g,[xy-%g z-%g | path_error], 255, 0, 255\n",Swc_Tree_Node_Data(tn)->x + 1.0, Swc_Tree_Node_Data(tn)->y + 1.0, Swc_Tree_Node_Data(tn)->z + 1.0, w, miss_field->values[i], xy_dist, z_dist); error_type = FALSE; } } if(miss_field->values[i]==1){ n_leaves ++; score_leaves += cur_score; if(error_type){ // distance error n_leaves_distance ++; score_leaves_distance += cur_score; }else{ n_leaves_path ++; score_leaves_path += cur_score; } }else{ n_branchings ++; score_branchings += cur_score; if(error_type){ // distance error n_branchings_distance ++; score_branching_distance += cur_score; }else{ n_branchings_path ++; score_branching_path += cur_score; } } } if(fp2 != NULL){ fprintf(fp2, "\nleaf errors: \t %d | loss score: %g(%2.1f%%)\n", n_leaves, score_leaves, 100*score_leaves/(1 - score)); fprintf(fp2, "leaf errors (dist): %d | loss score: %g(%2.1f%%) \n", n_leaves_distance, score_leaves_distance, 100*score_leaves_distance/(1 - score)); fprintf(fp2, "leaf errors (path): %d | loss score: %g(%2.1f%%) \n", n_leaves_path, score_leaves_path, 100*score_leaves_path/(1 - score)); fprintf(fp2, "\nbranching errors: \t %d | score loss: %g(%2.1f%%) \n", n_branchings, score_branchings, 100*score_branchings/(1 - score)); fprintf(fp2, "branching error (dist): %d | score loss: %g(%2.1f%%) \n", n_branchings_distance, score_branching_distance, 100*score_branching_distance/(1 - score)); fprintf(fp2, "branching error (path): %d | score loss: %g(%2.1f%%) \n", n_branchings_path, score_branching_path, 100*score_branching_path/(1 - score)); } if (fp != NULL) { fclose(fp); } fclose(fp2); if (fp3 != NULL) { fclose(fp3); } /* sprintf(file_path, "../data/diadem_%s/error.swc", Get_String_Arg("dataset")); Write_Swc_Tree(file_path, tree); */ tree = test_tree; /* process extra nodes*/ fp = NULL; fp2 = fopen(extra_score_file, "w"); fp3 = NULL; if (extra_swc_file != NULL) { fp = fopen(extra_swc_file, "w"); } if (extra_vlm_file != NULL) { fp3 = fopen(extra_vlm_file, "w"); } // printf("Extra list\n"); n_leaves = 0; n_branchings = 0; score_leaves = 0.0; score_branchings = 0.0; for (i = 0; i < extra_field->size; i++) { Swc_Tree_Node *tn = Swc_Tree_Closest_Node(tree, extra_field->points[i]); double cur_score = extra_field->values[i] * (wg - wm) / (wg + we) / (wg + we - extra_field->values[i]); fprintf(fp2, "%4d | %5.2f %5.2f %5.2f | %g | %g\n", Swc_Tree_Node_Data(tn)->id, Swc_Tree_Node_Data(tn)->x, Swc_Tree_Node_Data(tn)->y, Swc_Tree_Node_Data(tn)->z, extra_field->values[i], cur_score); double w = (1.0+3.0/(1+exp(-(extra_field->values[i]*2.0-2.0)))) * marker_ratio; if (fp != NULL) { fprintf(fp, "%d %d %g %g %g %g %d\n", i + 1, 1, Swc_Tree_Node_Data(tn)->x, Swc_Tree_Node_Data(tn)->y, Swc_Tree_Node_Data(tn)->z, w, -1); } if (fp3 != NULL) { fprintf(fp3, "%g,%g,%g,%g,1,%g, error, 255, 255, 0\n", Swc_Tree_Node_Data(tn)->x + 1.0, Swc_Tree_Node_Data(tn)->y + 1.0, Swc_Tree_Node_Data(tn)->z + 1.0, w, extra_field->values[i]); } if(extra_field->values[i]==1){ n_leaves ++; score_leaves += cur_score; }else{ n_branchings ++; score_branchings += cur_score; } } if(fp2 != NULL){ fprintf(fp2, "\nleaf errors: %d | loss score: %g(%2.1f%%)\n", n_leaves, score_leaves, 100*score_leaves/(1 - score)); fprintf(fp2, "branching errors: %d | score loss: %g(%2.1f%%) \n", n_branchings, score_branchings, 100*score_branchings/(1 - score)); } if (fp != NULL) { fclose(fp); } fclose(fp2); if (fp3 != NULL) { fclose(fp3); } xmlFreeDoc(doc); printf("Score = %g\n", score); return 0; }
static void swc_tree_remove_zjump(Swc_Tree *tree, double thre) { BOOL stop = FALSE; while (stop == FALSE) { stop = TRUE; Swc_Tree_Iterator_Start(tree, SWC_TREE_ITERATOR_DEPTH_FIRST, FALSE); double length = 0.0; /* branch length */ Swc_Tree_Node *tn = NULL; Swc_Tree_Node *prev_tn = NULL; int state = 0; prev_tn = Swc_Tree_Next(tree); if (Swc_Tree_Node_Is_Virtual(prev_tn)) { prev_tn = Swc_Tree_Next(tree); } if (Swc_Tree_Node_Is_Branch_Point(prev_tn)) { state = 1; } while ((tn = Swc_Tree_Next(tree)) != NULL) { switch (state) { case 0: /* wait for starting branching point */ if (Swc_Tree_Node_Is_Branch_Point(tn)) { state = 1; } break; case 1: /* branching on */ if (tn->parent == prev_tn) { length += Swc_Tree_Node_Length(tn); if (Swc_Tree_Node_Is_Branch_Point(tn)) { state = 2; } else if (Swc_Tree_Node_Is_Leaf(tn)) { length = 0.0; } } else { length = Swc_Tree_Node_Length(tn); if (Swc_Tree_Node_Is_Branch_Point(tn)) { state = 2; } } break; default: break; } if (state == 2) { state = 1; if (length <= thre) { /* check orientation */ Swc_Tree_Node *tmp_tn = tn->parent; double z = 0.0; while (Swc_Tree_Node_Is_Continuation(tmp_tn)) { tmp_tn = tmp_tn->parent; } z = fabs(Swc_Tree_Node_Data(tmp_tn)->z - Swc_Tree_Node_Data(tn)->z); double a = Swc_Tree_Node_Dot(tn->parent, tn, tn->first_child); printf("%g, %g\n", z/length, a); if (z/length > 0.3 /*&& a < 0.7*/) { //Swc_Tree_Node_Label_Branch_U(tn, 5); Swc_Tree_Node_Detach_Parent(tn); stop = FALSE; break; } } length = 0.0; } prev_tn = tn; } } Swc_Tree_Set_Type_As_Label(tree); Swc_Tree_Resort_Id(tree); }