示例#1
0
ZSwcTree *ZNeuronConstructor::reconstruct(
    std::vector<Locseg_Chain*> &chainArray)
{
  ZSwcTree *tree = NULL;

  if (!chainArray.empty()) {
    int chain_number = chainArray.size();
    /* <neuronComponent> allocated */
    Neuron_Component *neuronComponent =
        Make_Neuron_Component_Array(chain_number);

    for (int i = 0; i < chain_number; i++) {
      Set_Neuron_Component(neuronComponent + i,
                           NEUROCOMP_TYPE_LOCSEG_CHAIN,
                           chainArray[i]);
    }

    /* reconstruct neuron */
    /* alloc <ns> */
    double zscale = 1.0;
    Neuron_Structure *ns = Locseg_Chain_Comp_Neurostruct(
          neuronComponent, chain_number, m_signal, zscale, m_connWorkspace);

    Process_Neuron_Structure(ns);

    if (m_connWorkspace->crossover_test == TRUE) {
      Neuron_Structure_Crossover_Test(ns, zscale);
    }

    /* alloc <ns2> */
    Neuron_Structure* ns2=
        Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);

    Neuron_Structure_To_Tree(ns2);

    tree = new ZSwcTree;
    tree->setData(Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL));
    tree->resortId();

    /* free <ns2> */
    Kill_Neuron_Structure(ns2);
    /* free <ns> */
    ns->comp = NULL;
    Kill_Neuron_Structure(ns);

    /* free <neuronComponent> */
    Clean_Neuron_Component_Array(neuronComponent, chain_number);
    free(neuronComponent);
  }

  return tree;
}
示例#2
0
int main(int argc, char *argv[])
{
  if (Show_Version(argc, argv, "1.0") == 1) {
    return 0;
  }

  static char *Spec[] = {
    "[-R<string> -T<string> -M<string>] -D<string> [-minlen <double>]",
    "[-root <double> <double> <double>] [-trans <double> <double> <double>]",
    "[-rtlist <string>] [-sup_root] [-dist <double>]",
    "[-C<string>] [-I<string>] [-z <double>] -o <string> [-b] [-res <string>]",
    "[-screen] [-sp] [-intp] [-sl] [-rb] [-rz] [-rs] [-ct] [-al <double>]",
    "[-screenz <double>] [-force_merge <double>] [-ct_break <double>]",
    "[-jumpz <double>] [-single_break]",
    NULL};

  Print_Arguments(argc, argv);

  Process_Arguments(argc, argv, Spec, 1);
  
  char *dir = Get_String_Arg("-D");

  Stack_Document *stack_doc = NULL;
  if (Is_Arg_Matched("-I")) {
    if (!fexist(Get_String_Arg("-I"))) {
      PRINT_EXCEPTION("File does not exist", "");
      fprintf(stderr, "%s cannot be found.\n", Get_String_Arg("-I"));
      return 1;
    }
    if (fhasext(Get_String_Arg("-I"), "xml")) {
      stack_doc = Xml_Read_Stack_Document(Get_String_Arg("-I"));
    }
  }

  /* Get number of chains */
  int chain_number2 = dir_fnum_p(dir, "^chain.*\\.tb");

  if (chain_number2 == 0) {
    printf("No tube found.\n");
    printf("Quit reconstruction.\n");
    return 1;
  }

  int i;
  int *chain_map = iarray_malloc(chain_number2);
  int chain_number;
  Locseg_Chain **chain_array =
    Dir_Locseg_Chain_Nd(dir, "chain.*\\.tb", &chain_number, chain_map);

  if (Is_Arg_Matched("-screenz")) {
    Locseg_Chain_Array_Screen_Z(chain_array, chain_number,
	Get_Double_Arg("-screenz"));
  }

  if (Is_Arg_Matched("-single_break")) {
    int i;
    for (i = 0; i < chain_number; i++) {
      if (Locseg_Chain_Length(chain_array[i]) == 1) {
	/* break the segment into two parts */
	Locseg_Chain_Break_Node(chain_array[i], 0, 0.5);
      }
    }
  }

  if (Is_Arg_Matched("-ct_break")) {
    int tmp_chain_number;
    Locseg_Chain **tmp_chain_array = 
      Locseg_Chain_Array_Break_Jump(chain_array, chain_number,
	  Get_Double_Arg("-ct_break"), &tmp_chain_number);
    kill_locseg_chain_array(chain_array, chain_number);
    chain_array = tmp_chain_array;
    chain_number = tmp_chain_number;
  }

  Connection_Test_Workspace *ctw = New_Connection_Test_Workspace();
  if (Is_Arg_Matched("-res")) {
    FILE *fp = fopen(Get_String_Arg("-res"), "r");
    if (fp != NULL) {
      if (darray_fscanf(fp, ctw->resolution, 3) != 3) {
	fprintf(stderr, "Failed to load %s\n", Get_String_Arg("-res"));
	ctw->resolution[0] = 1.0;
	ctw->resolution[1] = 1.0;
	ctw->resolution[2] = 1.0;
      } else {
	ctw->unit = 'u';
      }
      fclose(fp);
    } else {
      fprintf(stderr, "Failed to load %s. The file may not exist.\n", 
	      Get_String_Arg("-res"));
    }
  } else if (stack_doc != NULL) {
    ctw->resolution[0] = stack_doc->resolution[0];
    ctw->resolution[1] = stack_doc->resolution[1];
    ctw->resolution[2] = stack_doc->resolution[2];
  }

  if (Is_Arg_Matched("-force_merge")) {
    Connection_Test_Workspace *ws = New_Connection_Test_Workspace();
    ws->dist_thre = Get_Double_Arg("-force_merge");
    ws->interpolate = FALSE;
    ws->resolution[2] = ctw->resolution[2] / ctw->resolution[0];
    for (i = 0; i < chain_number; i++) {
      //Locseg_Chain_Correct_Ends(chain_array[i]); 
    }
    Locseg_Chain_Array_Force_Merge(chain_array, chain_number, ws); 
    Kill_Connection_Test_Workspace(ws);
  }

  chain_number2 = 0;
  Neuron_Component *chain_array2;
  GUARDED_MALLOC_ARRAY(chain_array2, chain_number, Neuron_Component); 
  for (i = 0; i < chain_number; i++) {
    if (Locseg_Chain_Is_Empty(chain_array[i]) == FALSE) {
      chain_map[chain_number2] = chain_map[i];
      Set_Neuron_Component(chain_array2+(chain_number2++), 
	  NEUROCOMP_TYPE_LOCSEG_CHAIN, chain_array[i]);
    } else {
      printf("chain_%d is empty.\n", chain_map[i]);
    }
  }
    /*
    Dir_Locseg_Chain_Nc(dir, "^chain.*\\.tb", &chain_number2, chain_map);
*/
  Stack *signal = NULL;
  //Stack *canvas = NULL;
  if (Is_Arg_Matched("-I")) {
    signal = Read_Stack_U(Get_String_Arg("-I"));
    //canvas = Translate_Stack(signal, COLOR, 0);
  } else {
    if (Is_Arg_Matched("-screen")) {
      perror("The -screen option requires -I option to be supplied.\n");
      return 1;
    }
  }

  /* Minimal tube length. */
  double minlen = 25.0;
  if (Is_Arg_Matched("-minlen")) {
    minlen = Get_Double_Arg("-minlen");
  }

  chain_number = 0;
  //int i;


  if (signal != NULL) {
    ctw->mask = Make_Stack(GREY, signal->width, signal->height, signal->depth);
    One_Stack(ctw->mask);
  }

  FILE *result_file = fopen(full_path(dir, Get_String_Arg("-o")), "w");


  double z_scale = 1.0;
  if (Is_Arg_Matched("-z")) {
    z_scale = Get_Double_Arg("-z");
  }


  /* Array to store corrected chains */
  Neuron_Component *chain_array_c = Make_Neuron_Component_Array(chain_number2);

  int screen = 0;

  double average_intensity = 0.0;

  if (Is_Arg_Matched("-screen")) {
    int good_chain_number = 0;
    int bad_chain_number = 0;
    for (i = 0; i < chain_number2; i++) {
      Locseg_Chain *chain = NEUROCOMP_LOCSEG_CHAIN(chain_array2 + i);

      average_intensity += Locseg_Chain_Average_Score(chain, signal, z_scale, 
						      STACK_FIT_MEAN_SIGNAL);

      if ((Locseg_Chain_Geolen(chain) > 55) || 
	  (Locseg_Chain_Average_Score(chain, signal, z_scale, 
				      STACK_FIT_CORRCOEF) > 0.6)) {
	good_chain_number++;
      } else {
	bad_chain_number++;
      }
    }
    
    printf("good %d bad %d\n", good_chain_number, bad_chain_number);

    if (good_chain_number + bad_chain_number > 50) {
      if (bad_chain_number > good_chain_number) {
	screen = 1;
      }
    } else {
      screen = 3;
      /*
      if (bad_chain_number > good_chain_number * 2) {
	screen = 2;
      }
      */
    }
  }

  average_intensity /= chain_number2;

  /* build chain map */
  for (i = 0; i < chain_number2; i++) {
    Locseg_Chain *chain = NEUROCOMP_LOCSEG_CHAIN(chain_array2 + i);
    BOOL good = FALSE;
    
    switch (screen) {
    case 1:
    case 2:
      if ((Locseg_Chain_Geolen(chain) > 100) || 
	  (Locseg_Chain_Average_Score(chain, signal, z_scale, 
				      STACK_FIT_CORRCOEF)
	   > 0.6)) {
	good = TRUE;
      } else {
	if (Locseg_Chain_Geolen(chain) < 100) {
	  if ((Locseg_Chain_Average_Score(chain, signal, z_scale, 
					 STACK_FIT_CORRCOEF) > 0.5) ||
	      (Locseg_Chain_Average_Score(chain, signal, z_scale, 
					  STACK_FIT_MEAN_SIGNAL) > 
	       average_intensity)) {
	    good = TRUE;
	  }
	}
      }
      break;
    case 3:
      if ((Locseg_Chain_Average_Score(chain, signal, z_scale, 
				      STACK_FIT_CORRCOEF) > 0.50) ||
	  (Locseg_Chain_Average_Score(chain, signal, z_scale, 
				      STACK_FIT_MEAN_SIGNAL) > 
	   average_intensity)) {
	good = TRUE;
      }
      break;
    default:
      good = TRUE;
    }

    if (good == TRUE) {
      if (Locseg_Chain_Geolen(chain) < minlen) {
	good = FALSE;
      }
    }

    if (good == TRUE) {
      Locseg_Chain *tmpchain = chain;
      if (signal != NULL) {
	//Locseg_Chain_Trace_Np(signal, 1.0, tmpchain, tw);
	Locseg_Chain_Erase(chain, ctw->mask, 1.0);
      }
      fprintf(result_file, "%d %d\n", chain_number, chain_map[i]);
      chain_map[chain_number] = chain_map[i];
      if (z_scale != 1.0) {
	Locseg_Chain_Scale_Z(chain, z_scale);
      }
      Set_Neuron_Component(chain_array_c + chain_number, 
			   NEUROCOMP_TYPE_LOCSEG_CHAIN, tmpchain);
      chain_number++;
    } else {
#ifdef _DEBUG_
      printf("chain%d is excluded.\n", i);
      /*
      char tmpfile[500];
      sprintf(tmpfile, "../data/diadem_c1/bad_chain/chain%d.tb", i);
      Write_Locseg_Chain(tmpfile, chain);
      */
#endif
    }
  }

  z_scale = 1.0;

  fprintf(result_file, "#\n");

  //Int_Arraylist *hit_spots = Int_Arraylist_New(0, chain_number);
  /* reconstruct neuron */

  if (Is_Arg_Matched("-res")) {
    FILE *fp = fopen(Get_String_Arg("-res"), "r");
    if (fp != NULL) {
      if (darray_fscanf(fp, ctw->resolution, 3) != 3) {
	fprintf(stderr, "Failed to load %s\n", Get_String_Arg("-res"));
	ctw->resolution[0] = 1.0;
	ctw->resolution[1] = 1.0;
	ctw->resolution[2] = 1.0;
      } else {
	ctw->unit = 'u';
      }
      fclose(fp);
    } else {
      fprintf(stderr, "Failed to load %s. The file may not exist.\n", 
	      Get_String_Arg("-res"));
    }
  } else if (stack_doc != NULL) {
    ctw->resolution[0] = stack_doc->resolution[0];
    ctw->resolution[1] = stack_doc->resolution[1];
    ctw->resolution[2] = stack_doc->resolution[2];
  }

  if (!Is_Arg_Matched("-sp")) {
    ctw->sp_test = FALSE;
    if (ctw->sp_test == FALSE) {
      ctw->dist_thre = NEUROSEG_DEFAULT_H / 2.0;
    }
  } else {
    ctw->dist_thre = NEUROSEG_DEFAULT_H * 1.5;
  }
  
  if (Is_Arg_Matched("-dist")) {
    ctw->dist_thre = Get_Double_Arg("-dist");
  }

  if (!Is_Arg_Matched("-intp")) {
    ctw->interpolate = FALSE;
  }
  //ctw->dist_thre = 100.0;

  double *tube_offset = NULL;
  if (Is_Arg_Matched("-trans")) {
    tube_offset = darray_malloc(3);
    tube_offset[0] = Get_Double_Arg("-trans", 1);
    tube_offset[1] = Get_Double_Arg("-trans", 2);
    tube_offset[2] = Get_Double_Arg("-trans", 3);
  } else {
    if (stack_doc != NULL) {
      tube_offset = darray_malloc(3);
      tube_offset[0] = stack_doc->offset[0];
      tube_offset[1] = stack_doc->offset[1];
      tube_offset[2] = stack_doc->offset[2];
    }
  }

  Neuron_Structure *ns = New_Neuron_Structure();
  ns->comp = chain_array_c;
  ns->graph = New_Graph();
  ns->graph->nvertex = chain_number;
  
  if (Is_Arg_Matched("-rtlist")) {
    int m, n;
    double *d = darray_load_matrix(Get_String_Arg("-rtlist"), NULL, &m, &n);

    if (n > 0) {
      coordinate_3d_t *roots = GUARDED_MALLOC_ARRAY(roots, n, coordinate_3d_t);
      int i;
      for (i = 0; i < n; i++) {
	if (Is_Arg_Matched("-trans")) {
	  roots[i][0] = d[i*3] - tube_offset[0];
	  roots[i][1] = d[i*3 + 1] - tube_offset[1];
	  roots[i][2] = d[i*3 + 2] - tube_offset[2];
	} else {
	  roots[i][0] = d[i*3];
	  roots[i][1] = d[i*3 + 1];
	  roots[i][2] = d[i*3 + 2];
	}
      }

      Neuron_Structure_Break_Root(ns, roots, n);
      Neuron_Structure_Load_Root(ns, roots, n);
    }
  }
  
  Locseg_Chain_Comp_Neurostruct_W(ns, signal, z_scale, ctw);

  if (tube_offset != NULL) {
    for (i = 0; i < chain_number; i++) {
      Locseg_Chain_Translate(NEUROCOMP_LOCSEG_CHAIN(chain_array_c + i), 
			     tube_offset);
    }
  }

  /*  
  Neuron_Structure *ns = Locseg_Chain_Comp_Neurostruct(chain_array, 
						       chain_number,
						       signal, z_scale, ctw);
  */

  FILE *tube_fp = fopen(full_path(dir, "tube.swc"), "w");
  int start_id = 1;

  for (i = 0; i < chain_number; i++) {
    int node_type = i % 10;
    int n = Locseg_Chain_Swc_Fprint_T(tube_fp, 
				      NEUROCOMP_LOCSEG_CHAIN(chain_array_c + i), 
				      node_type, start_id, 
				      -1, DL_FORWARD, 1.0, NULL);
    start_id += n;
  }
  fclose(tube_fp);

  //Neuron_Structure_To_Swc_File(ns, full_path(dir, "tube.swc"));
  /*
  Graph *testgraph = New_Graph(0, 0, FALSE);
  Int_Arraylist *cidx = Make_Int_Arraylist(0, 2);
  Int_Arraylist *sidx = Make_Int_Arraylist(0, 2);
  
  Locseg_Chain_Network_Simlify(&net, testgraph, cidx, sidx);
  */

  /* Find branch points */
  //Locseg_Chain *branches = Locseg_Chain_Network_Find_Branch(ns);

  //Graph *graph = Locseg_Chain_Graph(chain_array, chain_number, hit_spots);
  //Graph *graph = ns->graph;

  if (Is_Arg_Matched("-sup_root")) {
    if (Is_Arg_Matched("-rtlist")) {
      int m, n;
      double *d = darray_load_matrix(Get_String_Arg("-rtlist"), NULL, &m, &n);
      
      if (n > 0) {
	coordinate_3d_t *roots = 
	  GUARDED_MALLOC_ARRAY(roots, n, coordinate_3d_t);
	int i;
	for (i = 0; i < n; i++) {
	  roots[i][0] = d[i*3];
	  roots[i][1] = d[i*3 + 1];
	  roots[i][2] = d[i*3 + 2];
	  /*
	  if (tube_offset != NULL) {
	    roots[i][0] += tube_offset[0];
	    roots[i][1] += tube_offset[1];
	    roots[i][2] += tube_offset[2];
	  }
	  */
	}
	neuron_structure_suppress(ns, roots, n);
	free(roots);
      }
    }
  }

  Process_Neuron_Structure(ns);

  Print_Neuron_Structure(ns);

#ifdef _DEBUG_
  for (i = 0; i < NEURON_STRUCTURE_LINK_NUMBER(ns); i++) {
    printf("chain_%d (%d) -- chain_%d (%d) ", 
	chain_map[ns->graph->edges[i][0]], 
	ns->graph->edges[i][0], 
	chain_map[ns->graph->edges[i][1]],
	ns->graph->edges[i][1]);
    Print_Neurocomp_Conn(ns->conn + i);
  }
#endif

  if (Is_Arg_Matched("-ct")) {
    Neuron_Structure_Crossover_Test(ns, 
				    ctw->resolution[0] / ctw->resolution[2]);
  }

  if (Is_Arg_Matched("-al")) {
    Neuron_Structure_Adjust_Link(ns, Get_Double_Arg("-al"));
  }

  Neuron_Structure_To_Tree(ns);
  Neuron_Structure_Remove_Negative_Conn(ns);

#ifdef _DEBUG_
  printf("\nTree:\n");
  for (i = 0; i < NEURON_STRUCTURE_LINK_NUMBER(ns); i++) {
    printf("chain_%d (%d) -- chain_%d (%d) ", 
	chain_map[ns->graph->edges[i][0]], 
	ns->graph->edges[i][0], 
	chain_map[ns->graph->edges[i][1]],
	ns->graph->edges[i][1]);
    Print_Neurocomp_Conn(ns->conn + i);
  }
#endif
  /*
  printf("\ncross over changed: \n");
  Print_Neuron_Structure(ns);
  */

#ifdef _DEBUG_2
  ns->graph->nedge = 0;
  Neuron_Structure_To_Swc_File(ns, "../data/test.swc"); 
  return 1;
#endif
  
  //Print_Neuron_Structure(ns);

  
  Neuron_Structure* ns2= NULL;
  
  if (Is_Arg_Matched("-intp")) {
    ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);
  } else {
    ns2 = Neuron_Structure_Locseg_Chain_To_Circle(ns);
  }
    
  /*
  Neuron_Structure* ns2=
    Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);
  */
  Graph_To_Dot_File(ns2->graph, full_path(dir, "graph_d.dot"));

  //Neuron_Structure_Main_Graph(ns2);
  Neuron_Structure_To_Tree(ns2);
  
  double root[3];

  if (Is_Arg_Matched("-root")) {
    root[0] = Get_Double_Arg("-root", 1);
    root[1] = Get_Double_Arg("-root", 2);
    root[2] = Get_Double_Arg("-root", 3);
  }

  Swc_Tree *tree = NULL;

  if (Is_Arg_Matched("-root")) {
    /*
    int root_index = Neuron_Structure_Find_Root_Circle(ns2, root);
    Graph_Workspace *gw2 = New_Graph_Workspace();
    Graph_Clean_Root(ns2->graph, root_index, gw2);

    Neuron_Structure_To_Swc_File_Circle_Z(ns2, full_path(dir, "graph_d.swc"),
					  z_scale, root);
    */
    tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, z_scale, root);
    if (Swc_Tree_Node_Is_Virtual(tree->root) == TRUE) {
      tree->root->first_child->next_sibling = NULL;
    }
    Swc_Tree_Clean_Root(tree);
  } else {
    /*
    Neuron_Structure_To_Swc_File_Circle_Z(ns2, full_path(dir, "graph_d.swc"),
					  z_scale, NULL);
    */
    tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, z_scale, NULL);
  }

  ns->graph->nedge = 0;
  //Neuron_Structure_To_Swc_File(ns, full_path(dir, "tube.swc"));


  if (Is_Arg_Matched("-rb")) {
    //Swc_Tree_Tune_Branch(tree);
    Swc_Tree_Tune_Fork(tree);
  }

  if (Is_Arg_Matched("-sl")) {
    Swc_Tree_Leaf_Shrink(tree);
  }

  if (Is_Arg_Matched("-rz")) {
    Swc_Tree_Remove_Zigzag(tree);
  }

  if (Is_Arg_Matched("-rs")) {
    Swc_Tree_Remove_Spur(tree);
  }
  
  Swc_Tree_Resort_Id(tree);

  Write_Swc_Tree(full_path(dir, "graph_d.swc"), tree);

  if (Is_Arg_Matched("-rtlist")) {
    int m, n;
    double *d = darray_load_matrix(Get_String_Arg("-rtlist"), NULL, &m, &n);

    if (n > 0) {
      coordinate_3d_t *roots = GUARDED_MALLOC_ARRAY(roots, n, coordinate_3d_t);
      int i;
      for (i = 0; i < n; i++) {
	roots[i][0] = d[i*3];
	roots[i][1] = d[i*3 + 1];
	roots[i][2] = d[i*3 + 2];

	/*
	if (tube_offset != NULL) {
	  roots[i][0] += tube_offset[0];
	  roots[i][1] += tube_offset[1];
	  roots[i][2] += tube_offset[2];
	}
	*/

	Swc_Tree *subtree = Swc_Tree_Pull_R(tree, roots[i]);
	char filename[MAX_PATH_LENGTH];
	if (subtree->root != NULL) {
	  //Swc_Tree_Clean_Root(subtree);
	  Swc_Tree_Clean_Root(subtree);
	  Swc_Tree_Node_Set_Pos(subtree->root, roots[i]);
	  if (Is_Arg_Matched("-jumpz")) {
	    //swc_tree_remove_zjump(subtree, Get_Double_Arg("-jumpz"));
	  }
	  Swc_Tree_Resort_Id(subtree);
	  sprintf(filename, "graph%d.swc", i + 1);
	  Write_Swc_Tree(full_path(dir, filename), subtree);
	}
      }
    }
  }

  printf("%d chains\n", chain_number);

  return 0;
}
示例#3
0
int main()
{
#if 0
  char *filepath = "../data/fly_neuron_n2/graph_d.swc";
  
  Neuron_Structure *ns = Neuron_Structure_From_Swc_File(filepath);
  
  Neuron_Component_Arraylist *comp_array =
    Neuron_Structure_Branch_Point(ns);

  filepath = "../data/fly_neuron_n2.tif";
  Stack *stack = Read_Stack(filepath);
  Translate_Stack(stack, COLOR, 1);

  int i;
  Stack_Draw_Workspace *ws = New_Stack_Draw_Workspace();
  for (i = 0; i < comp_array->length; i++) {
    Neuron_Component_Draw_Stack(comp_array->array + i, stack, ws);
  }
  Kill_Stack_Draw_Workspace(ws);

  Write_Stack("../data/test.tif", stack);
#endif

#if 0
  Stack *stack = NULL;

  Locseg_Chain *chain1 = Read_Locseg_Chain("../data/fly_neuron_n3/chain0.tb");
  Locseg_Chain *chain2 = Read_Locseg_Chain("../data/fly_neuron_n3/chain10.tb");

  Connection_Test_Workspace *ws = New_Connection_Test_Workspace();
  Connection_Test_Workspace_Read_Resolution(ws, "../data/fly_neuron_n1.res");

  Neurocomp_Conn conn;
  conn.mode = NEUROCOMP_CONN_HL;
  Locseg_Chain_Connection_Test(chain1, chain2, stack, 1.0, &conn, ws);

  Print_Neurocomp_Conn(&conn);
#endif

#if 0
  Locseg_Chain **chain = (Locseg_Chain**) malloc(sizeof(Locseg_Chain*) * 3);
  chain[0] = Read_Locseg_Chain("../data/mouse_single_org/chain4.tb");
  chain[1] = Read_Locseg_Chain("../data/mouse_single_org/chain19.tb");
  chain[2] = Read_Locseg_Chain("../data/mouse_single_org/chain64.tb");

  Stack *signal = Read_Stack("../data/mouse_single_org.tif");

  Connection_Test_Workspace *ctw = New_Connection_Test_Workspace();
    
  FILE *fp = fopen("../data/mouse_single_org.res", "r");

  darray_fscanf(fp, ctw->resolution, 3);

  Neuron_Component *chain_array = Make_Neuron_Component_Array(3);

  int i;
  for (i = 0; i < 3; i++) {
    Set_Neuron_Component(chain_array + i, 
			 NEUROCOMP_TYPE_LOCSEG_CHAIN, chain[i]);
  }

  Neuron_Structure *ns = Locseg_Chain_Comp_Neurostruct(chain_array, 
						       3, signal, 1.0, ctw);
  Graph *graph = ns->graph;

  Process_Neuron_Structure(ns);

  Print_Neuron_Structure(ns);

  Neuron_Structure_Crossover_Test(ns, 0.5375);

  printf("\ncross over changed: \n");
  Print_Neuron_Structure(ns);
#endif

#if 0
  Neuron_Structure *ns = Make_Neuron_Structure(5);

  Set_Neuron_Component(ns->comp, NEUROCOMP_TYPE_GEO3D_CIRCLE, 
		       New_Geo3d_Circle());
  Set_Neuron_Component(ns->comp + 1, NEUROCOMP_TYPE_GEO3D_CIRCLE, 
		       New_Geo3d_Circle());
  Set_Neuron_Component(ns->comp + 2, NEUROCOMP_TYPE_GEO3D_CIRCLE, 
		       New_Geo3d_Circle());
  Set_Neuron_Component(ns->comp + 3, NEUROCOMP_TYPE_GEO3D_CIRCLE, 
		       New_Geo3d_Circle());
  Set_Neuron_Component(ns->comp + 4, NEUROCOMP_TYPE_GEO3D_CIRCLE, 
		       New_Geo3d_Circle());

  NEUROCOMP_GEO3D_CIRCLE(ns->comp)->radius = 1.5;
  NEUROCOMP_GEO3D_CIRCLE(ns->comp + 1)->radius = 2.5;
  NEUROCOMP_GEO3D_CIRCLE(ns->comp + 2)->radius = 3.5;
  NEUROCOMP_GEO3D_CIRCLE(ns->comp + 3)->radius = 4.5;
  NEUROCOMP_GEO3D_CIRCLE(ns->comp + 4)->radius = 5.5;
 
  ns->graph = Make_Graph(5, 4, 0);
  //Graph_Add_Edge(ns->graph, 0, 1);
  Graph_Add_Edge(ns->graph, 1, 3);
  Graph_Add_Edge(ns->graph, 1, 4);
  Graph_Add_Edge(ns->graph, 0, 2);

  Graph_Set_Directed(ns->graph, TRUE);

  Print_Graph(ns->graph);

  Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns, 1.0, NULL);
  Print_Swc_Tree(tree);

  Swc_Tree_To_Dot_File(tree, "../data/test2.dot");
#endif

#if 0
  int n;
  Neuron_Component *chain_array = Dir_Locseg_Chain_Nc("../data/fly_neuron_n22", 
						      "^chain.*\\.tb", 
						      &n, NULL);
  
  Neuron_Structure *ns =
    Locseg_Chain_Comp_Neurostruct(chain_array, n, NULL, 1.0, NULL);
  
  Process_Neuron_Structure(ns);
  Neuron_Structure* ns2=
      Neuron_Structure_Locseg_Chain_To_Circle(ns);

  Neuron_Structure_To_Tree(ns2);

  Graph_To_Dot_File(ns2->graph, "../data/test.dot");

  Swc_Tree *tree = 
    Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL);

  Swc_Tree_Remove_Zigzag(tree);
  //Swc_Tree_Tune_Fork(tree);

  //Print_Swc_Tree(tree);
  Write_Swc_Tree("../data/test.swc", tree);
#endif

#if 0
  Graph *graph = Neuron_Structure_Import_Xml_Graph("../data/mouse_single_org/trueconn2.xml");
  Graph_Normalize_Edge(graph);
  Graph_Remove_Duplicated_Edge(graph);

  Graph *graph2 = Neuron_Structure_Import_Xml_Graph("../data/mouse_single_org/conn.xml");
  Graph_Normalize_Edge(graph2);
  Graph_Remove_Duplicated_Edge(graph2);

  Graph_Workspace *gw = New_Graph_Workspace();
  int n = Graph_Edge_Count(graph, graph2->edges, graph2->nedge, gw);

  printf("fp: %d\n", graph2->nedge - n);
  printf("tp: %d\n", n);
  printf("fn: %d\n", graph->nedge - n);

  double p = (double) n / graph2->nedge;
  double r = (double) n / graph->nedge;
  printf("precision: %g\n", p);
  printf("recall: %g\n", r);
  printf("F-measure: %g\n", 2.0 * (p * r) / (p + r));
#endif

#if 0
  Neuron_Structure *ns = Make_Neuron_Structure(2);
  
  Local_Neuroseg *locseg = New_Local_Neuroseg();

  Locseg_Chain *chain1 = New_Locseg_Chain();
  Locseg_Chain_Add(chain1, locseg, NULL, DL_TAIL);

  Set_Neuron_Component(ns->comp, NEUROCOMP_TYPE_LOCSEG_CHAIN, chain1);

  Locseg_Chain *chain2 = New_Locseg_Chain();
  locseg = New_Local_Neuroseg();
  double bottom[3] = {10, 10, 5};
  double top[3] = {5, 5, 5};
  Local_Neuroseg_Set_Bottom_Top(locseg, bottom, top);
  Locseg_Chain_Add(chain2, locseg, NULL, DL_TAIL);

  Set_Neuron_Component(ns->comp + 1, NEUROCOMP_TYPE_LOCSEG_CHAIN, chain2);
  
  Neurocomp_Conn *conn = New_Neurocomp_Conn();
  Connection_Test_Workspace *ctw = New_Connection_Test_Workspace();
  Locseg_Chain_Connection_Test(chain2, chain1, NULL, 1.0, conn, ctw);

  Neuron_Structure_Add_Conn(ns, 1, 0, conn);

  Print_Neuron_Structure(ns);

  Neuron_Structure *ns2 = 
    Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);

  Neuron_Structure_To_Swc_File(ns2, "../data/test.swc");
#endif

#if 0
  int n;
  
  Locseg_Chain **chain_array = Dir_Locseg_Chain_Nd("../data/diadem_a1_part3", 
						   "^chain.*\\.tb", &n, NULL);
  /*
  Locseg_Chain **chain_array = 
    Locseg_Chain_Import_List("../data/diadem_a1_part2/good_tube.txt", &n);
  */
  //n = 100;
  /*
  Locseg_Chain **chain_array = 
    (Locseg_Chain**) malloc(sizeof(Locseg_Chain*) * 2);
  n = 2;
  chain_array[0] = Read_Locseg_Chain("../data/diadem_a1_part2/chain58.tb");
  chain_array[1] = Read_Locseg_Chain("../data/diadem_a1_part2/chain154.tb");
  */

  Stack *stack = Read_Stack("../data/diadem_a1_part3.tif");

  Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth);
  Zero_Stack(mask);
  Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace();
  sgw->size = Stack_Voxel_Number(stack);
  sgw->resolution[0] = 0.0375 * 2.0;
  sgw->resolution[1] = 0.0375 * 2.0;
  sgw->resolution[2] = 0.33;
  Sp_Grow_Workspace_Set_Mask(sgw, mask->array);
  sgw->wf = Stack_Voxel_Weight_S;

  Stack_Sp_Grow_Infer_Parameter(sgw, stack);

  Neuron_Structure *ns = 
    Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw);
  
  Print_Neuron_Structure(ns);
  
  Graph_To_Dot_File(ns->graph, "../data/test.dot");

  //Neuron_Structure_To_Swc_File(ns, "../data/test.swc");
  Neuron_Structure *ns2 = 
    Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);
  //double root[3] = {31, 430, 0};
  double root[3] = {1221, 449, 8.5};
  Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, root);
  Swc_Tree_Clean_Root(tree);
  Swc_Tree_Resort_Id(tree);
  Write_Swc_Tree("../data/test.swc", tree);
#endif

#if 0
  int n;
  Locseg_Chain **chain_array = Dir_Locseg_Chain_Nd("../data/diadem_e1", 
						   "^chain.*\\.tb", &n, NULL);
  //n = 100;
  /*
  Locseg_Chain **chain_array = 
    (Locseg_Chain**) malloc(sizeof(Locseg_Chain*) * 2);
  n = 2;
  chain_array[0] = Read_Locseg_Chain("../data/diadem_a1_part2/chain58.tb");
  chain_array[1] = Read_Locseg_Chain("../data/diadem_a1_part2/chain154.tb");
  */

  Stack *stack = Read_Stack("../data/diadem_e1.tif");

  Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth);
  Zero_Stack(mask);
  Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace();
  sgw->size = Stack_Voxel_Number(stack);
  sgw->resolution[0] = 0.3296485;
  sgw->resolution[1] = 0.3296485;
  sgw->resolution[2] = 1.0;
  Sp_Grow_Workspace_Set_Mask(sgw, mask->array);
  sgw->wf = Stack_Voxel_Weight_S;

  Stack_Sp_Grow_Infer_Parameter(sgw, stack);

  Neuron_Structure *ns = 
    Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw);
  
  Print_Neuron_Structure(ns);
  
  //Neuron_Structure_To_Swc_File(ns, "../data/test.swc");
  Neuron_Structure *ns2 = 
    Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);

  Graph_To_Dot_File(ns2->graph, "../data/test.dot");

  double root[3] = {31, 430, 0};
  //double root[3] = {4882, 1797, 19};
  Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, root);
  //Swc_Tree_Clean_Root(tree);
  Swc_Tree_Resort_Id(tree);

  Write_Swc_Tree("../data/test2.swc", tree);
#endif

#if 0
  int n;
  Locseg_Chain **chain_array = 
    Dir_Locseg_Chain_Nd("../data/benchmark/stack_graph/fork", "^chain.*\\.tb", 
			&n, NULL);

  Stack *stack = Read_Stack("../data/benchmark/stack_graph/fork/fork.tif");
  Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth);
  Zero_Stack(mask);
  Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace();
  sgw->size = Stack_Voxel_Number(stack);
  Sp_Grow_Workspace_Set_Mask(sgw, mask->array);
  sgw->wf = Stack_Voxel_Weight_S;

  Stack_Sp_Grow_Infer_Parameter(sgw, stack);
  Neuron_Structure *ns = 
    Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw);
  
  Neuron_Structure *ns2 = 
    Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);
  Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL);
  //Swc_Tree_Clean_Root(tree);
  Swc_Tree_Resort_Id(tree);
  Write_Swc_Tree("../data/test.swc", tree);
#endif

#if 0
  int n = 3;
  Locseg_Chain **chain_array = 
    (Locseg_Chain**) malloc(sizeof(Locseg_Chain) * n);
  chain_array[0] = Read_Locseg_Chain("/Users/zhaot/Work/neurolabi/data/benchmark/stack_graph/fork/chain0.tb");
  chain_array[1] = Read_Locseg_Chain("/Users/zhaot/Work/neurolabi/data/benchmark/stack_graph/fork/chain1.tb");
  chain_array[2] = New_Locseg_Chain();
  
  printf("%d\n", Locseg_Chain_Is_Empty(chain_array[2]));

  Stack *stack = Read_Stack("../data/benchmark/stack_graph/fork/fork.tif");
  Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth);
  Zero_Stack(mask);
  Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace();
  sgw->size = Stack_Voxel_Number(stack);
  Sp_Grow_Workspace_Set_Mask(sgw, mask->array);
  sgw->wf = Stack_Voxel_Weight_S;

  Stack_Sp_Grow_Infer_Parameter(sgw, stack);
  Neuron_Structure *ns = 
    Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw);
  
  Neuron_Structure *ns2 = 
    Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);
  Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL);
  //Swc_Tree_Clean_Root(tree);
  Swc_Tree_Remove_Zigzag(tree);
  Swc_Tree_Resort_Id(tree);
  Write_Swc_Tree("../data/test2.swc", tree);
#endif

#if 0
  Neuron_Structure *ns = New_Neuron_Structure();
  ns->graph = New_Graph();

  Graph_Add_Edge(ns->graph, 0, 1);
  Graph_Add_Edge(ns->graph, 0, 2);
  Graph_Add_Edge(ns->graph, 2, 3);
  Graph_Add_Edge(ns->graph, 2, 4);
  Graph_Add_Edge(ns->graph, 4, 5);
  Graph_Add_Edge(ns->graph, 5, 6);
  
  ns->conn = (Neurocomp_Conn*) malloc(sizeof(Neurocomp_Conn) * ns->graph->nedge);

  ns->conn[0].info[0] = 0;
  ns->conn[0].info[1] = 0;
  ns->conn[0].cost = 0.0;
  ns->conn[0].mode = NEUROCOMP_CONN_LINK;

  ns->conn[1].info[0] = 1;
  ns->conn[1].info[1] = 1;
  ns->conn[1].cost = 0.0;
  ns->conn[1].mode = NEUROCOMP_CONN_LINK;

  ns->conn[2].info[0] = 0;
  ns->conn[2].info[1] = 0;
  ns->conn[2].cost = 0.0;
  ns->conn[2].mode = NEUROCOMP_CONN_LINK;

  ns->conn[3].info[0] = 1;
  ns->conn[3].info[1] = 0;
  ns->conn[3].cost = 1.0;
  ns->conn[3].mode = NEUROCOMP_CONN_HL;

  ns->conn[4].info[0] = 0;
  ns->conn[4].info[1] = 1;
  ns->conn[4].cost = 0.0;
  ns->conn[4].mode = NEUROCOMP_CONN_LINK;

  ns->conn[5].info[0] = 1;
  ns->conn[5].info[1] = 1;
  ns->conn[5].cost = 1.0;
  ns->conn[5].mode = NEUROCOMP_CONN_LINK;

  Neuron_Structure_Merge_Locseg_Chain(ns);
  
#endif

#if 0
  Neuron_Structure *ns = New_Neuron_Structure();
  ns->graph = New_Graph();
  ns->comp = Dir_Locseg_Chain_Nc("../data/diadem_e3", "^chain.*\\.tb", 
				 &(ns->graph->nvertex), NULL);

  Graph_Add_Edge(ns->graph, 0, 1);
  Graph_Add_Edge(ns->graph, 0, 2);
  Graph_Add_Edge(ns->graph, 2, 3);
  Graph_Add_Edge(ns->graph, 3, 4);
  Graph_Add_Edge(ns->graph, 4, 5);
  
  ns->conn = (Neurocomp_Conn*) malloc(sizeof(Neurocomp_Conn) * ns->graph->nedge);

  ns->conn[0].info[0] = 0;
  ns->conn[0].info[1] = 0;
  ns->conn[0].cost = 0.0;
  ns->conn[0].mode = NEUROCOMP_CONN_LINK;

  ns->conn[1].info[0] = 0;
  ns->conn[1].info[1] = 0;
  ns->conn[1].cost = 0.0;
  ns->conn[1].mode = NEUROCOMP_CONN_LINK;

  ns->conn[2].info[0] = 0;
  ns->conn[2].info[1] = 0;
  ns->conn[2].cost = 1.0;
  ns->conn[2].mode = NEUROCOMP_CONN_LINK;

  ns->conn[3].info[0] = 0;
  ns->conn[3].info[1] = 0;
  ns->conn[3].cost = 2.0;
  ns->conn[3].mode = NEUROCOMP_CONN_LINK;

  ns->conn[4].info[0] = 0;
  ns->conn[4].info[1] = 0;
  ns->conn[4].cost = 0.0;
  ns->conn[4].mode = NEUROCOMP_CONN_LINK;

  int i;
  for (i = 0; i < ns->graph->nvertex; i++) {
    printf("%d ", Locseg_Chain_Length(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i)));
  }
  printf("\n");

  Neuron_Structure_Merge_Locseg_Chain(ns);  

  for (i = 0; i < ns->graph->nvertex; i++) {
    printf("%d ", Locseg_Chain_Length(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i)));
  }
  printf("\n");

#endif

#if 0
  int n;
  Locseg_Chain **chain_array = Dir_Locseg_Chain_Nd("../data/diadem_e1", 
						   "^chain.*\\.tb", &n, NULL);
  Stack *stack = Read_Stack("../data/diadem_e1.tif");

  Stack *mask = Make_Stack(GREY, stack->width, stack->height, stack->depth);
  Zero_Stack(mask);
  Sp_Grow_Workspace *sgw = New_Sp_Grow_Workspace();
  sgw->size = Stack_Voxel_Number(stack);
  sgw->resolution[0] = 0.3296485;
  sgw->resolution[1] = 0.3296485;
  sgw->resolution[2] = 1.0;
  Sp_Grow_Workspace_Set_Mask(sgw, mask->array);
  sgw->wf = Stack_Voxel_Weight_S;

  Stack_Sp_Grow_Infer_Parameter(sgw, stack);

  Neuron_Structure *ns = 
    Locseg_Chain_Sp_Grow_Reconstruct(chain_array, n, stack, 1.0, sgw);  
  
  Neuron_Structure_Merge_Locseg_Chain(ns);
  int i;
  char filepath[100];
  for (i = 0; i < ns->graph->nvertex; i++) {
    Locseg_Chain_Regularize(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i));
    if (Locseg_Chain_Is_Empty(NEUROCOMP_LOCSEG_CHAIN(ns->comp+i)) == FALSE) {
      sprintf(filepath, "../data/tmp/chain%d.tb", i);
      Write_Locseg_Chain(filepath, NEUROCOMP_LOCSEG_CHAIN(ns->comp+i));
    }
  }
#endif

#if 0
  Stack *stack = Read_Stack("../data/benchmark/fork2/fork2.tif");

  Neuron_Structure *ns = New_Neuron_Structure();
  ns->graph = New_Graph();
  ns->comp = Dir_Locseg_Chain_Nc("../data/benchmark/fork2/tubes",
				 "^chain.*\\.tb", &(ns->graph->nvertex), NULL);

  coordinate_3d_t roots[3];
  roots[0][0] = 51;
  roots[0][1] = 23;
  roots[0][2] = 60;

  roots[1][0] = 51;
  roots[1][1] = 23;
  roots[1][2] = 40;

  roots[2][0] = 25;
  roots[2][1] = 76;
  roots[2][2] = 60;

  Neuron_Structure_Break_Root(ns, roots, 3);
  Neuron_Structure_Load_Root(ns, roots, 3);

  Connection_Test_Workspace *ctw = New_Connection_Test_Workspace();
  ctw->dist_thre = 100.0;
  ctw->sp_test = FALSE;
  
  Locseg_Chain_Comp_Neurostruct_W(ns, stack, 1.0, ctw);

  Process_Neuron_Structure(ns);
  Neuron_Structure_To_Tree(ns);
  
  /*
  Neuron_Structure_Remove_Conn(ns, 0, 2);
  Neuron_Structure_Remove_Conn(ns, 2, 0);
  */

  Neuron_Structure_Remove_Negative_Conn(ns);

  Neuron_Structure* ns2= NULL;
  
  ns2 = Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0);
    
  Neuron_Structure_To_Tree(ns2);
  
  Swc_Tree *tree = Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL);
  
  Swc_Tree_Resort_Id(tree);

  Write_Swc_Tree("../data/test3.swc", tree);  
#endif

#if 1
  Stack *stack = NULL;

  Locseg_Chain *chain1 = Read_Locseg_Chain("../data/benchmark/diadem/diadem_e1/chain22.tb");
  Locseg_Chain *chain2 = Read_Locseg_Chain("../data/benchmark/diadem/diadem_e1/chain0.tb");

  Connection_Test_Workspace *ws = New_Connection_Test_Workspace();
  Connection_Test_Workspace_Read_Resolution(ws, "../data/diadem_e3.res");

  Neurocomp_Conn conn;
  conn.mode = NEUROCOMP_CONN_HL;
  Locseg_Chain_Connection_Test(chain1, chain2, stack, 1.0, &conn, ws);

  Print_Neurocomp_Conn(&conn);
#endif

  return 0;
}