Exemplo n.º 1
0
// Normalize an exception.
NUITKA_MAY_BE_UNUSED static inline void NORMALIZE_EXCEPTION( PyObject **exception_type, PyObject **exception_value, PyTracebackObject **exception_tb )
{
#if _DEBUG_EXCEPTIONS
    PRINT_STRING("NORMALIZE_EXCEPTION:\n");
    PRINT_EXCEPTION( *exception_type,  *exception_value, (PyObject *)*exception_tb );
#endif

    if ( *exception_type != Py_None && *exception_type != NULL )
    {
        PyErr_NormalizeException( exception_type, exception_value, (PyObject **)exception_tb );
    }

#if _DEBUG_EXCEPTIONS
    PRINT_STRING("normalized:\n");
    PRINT_EXCEPTION( *exception_type,  *exception_value, (PyObject *)*exception_tb );
#endif
}
Exemplo n.º 2
0
// Fetch the current error into object variables.
NUITKA_MAY_BE_UNUSED static void FETCH_ERROR_OCCURRED( PyObject **exception_type, PyObject **exception_value, PyTracebackObject **exception_traceback)
{
    PyThreadState *tstate = PyThreadState_GET();

    *exception_type = tstate->curexc_type;
    *exception_value = tstate->curexc_value;
    *exception_traceback = (PyTracebackObject *)tstate->curexc_traceback;

#if _DEBUG_EXCEPTIONS
    PRINT_STRING("FETCH_ERROR_OCCURRED:\n");
    PRINT_EXCEPTION( tstate->curexc_type,  tstate->curexc_value, tstate->curexc_traceback );
#endif

    tstate->curexc_type = NULL;
    tstate->curexc_value = NULL;
    tstate->curexc_traceback = NULL;
}
Exemplo n.º 3
0
// Preserve the current exception as the frame to restore.
NUITKA_MAY_BE_UNUSED static inline void PRESERVE_FRAME_EXCEPTION( PyFrameObject *frame_object )
{
    // Setting exception for frame if not already done.
    if ( frame_object->f_exc_type == NULL )
    {
        PyThreadState *thread_state = PyThreadState_GET();

        if ( thread_state->exc_type != NULL && thread_state->exc_type != Py_None )
        {
#if _DEBUG_EXCEPTIONS
            PRINT_STRING("PRESERVE_FRAME_EXCEPTION: preserve thread exception\n");
#endif
            frame_object->f_exc_type = thread_state->exc_type;
            Py_INCREF( frame_object->f_exc_type );
            frame_object->f_exc_value = thread_state->exc_value;
            Py_XINCREF( frame_object->f_exc_value );
            frame_object->f_exc_traceback = thread_state->exc_traceback;
            Py_XINCREF( frame_object->f_exc_traceback );
        }
        else
        {
#if _DEBUG_EXCEPTIONS
            PRINT_STRING("PRESERVE_FRAME_EXCEPTION: no exception to preserve\n");
#endif
            frame_object->f_exc_type = Py_None;
            Py_INCREF( frame_object->f_exc_type );
            frame_object->f_exc_value = NULL;
            frame_object->f_exc_traceback = NULL;
        }
    }
#if _DEBUG_EXCEPTIONS
    else
    {
        PRINT_STRING("PRESERVE_FRAME_EXCEPTION: already preserving\n");
    }

    PRINT_ITEM( (PyObject *)frame_object );
    PRINT_NEW_LINE();
    PRINT_EXCEPTION( frame_object->f_exc_type,  frame_object->f_exc_value, frame_object->f_exc_traceback );
#endif

}
Exemplo n.º 4
0
NUITKA_MAY_BE_UNUSED static void RESTORE_ERROR_OCCURRED( PyObject *exception_type, PyObject *exception_value, PyTracebackObject *exception_traceback )
{
    PyThreadState *tstate = PyThreadState_GET();

    PyObject *old_exception_type = tstate->curexc_type;
    PyObject *old_exception_value = tstate->curexc_value;
    PyObject *old_exception_traceback = tstate->curexc_traceback;

    tstate->curexc_type = exception_type;
    tstate->curexc_value = exception_value;
    tstate->curexc_traceback = (PyObject *)exception_traceback;

#if _DEBUG_EXCEPTIONS
    PRINT_STRING("RESTORE_ERROR_OCCURRED:\n");
    PRINT_EXCEPTION( tstate->curexc_type,  tstate->curexc_value, tstate->curexc_traceback );
#endif

    Py_XDECREF( old_exception_type );
    Py_XDECREF( old_exception_value );
    Py_XDECREF( old_exception_traceback );
}
Exemplo n.º 5
0
void Stack_Draw_Point(Stack *stack, double x, double y, double z, double v,
		      int mode)
{
  if (stack == NULL) {
    TZ_ERROR(ERROR_POINTER_NULL);
  }

  if (Stack_Channel_Number(stack) != 1) {
    TZ_ERROR(ERROR_DATA_TYPE);
  }

  int is_finite = TRUE;
  double value;

  DEFINE_SCALAR_ARRAY_ALL(array, stack);

  int nvoxel = Stack_Voxel_Number(stack);

  switch(stack->kind) {
  case GREY:
    STACK_DRAW_POINT(array_grey, uint8, 0, 255, mode);
    break;
  case GREY16:
    STACK_DRAW_POINT(array_grey16, uint16, 0, 65535, mode);
    break;
  case FLOAT32:
    is_finite = FALSE;
    STACK_DRAW_POINT(array_float32, float32, 0, 0, mode);
    break;
  case FLOAT64:
    is_finite = FALSE;
    STACK_DRAW_POINT(array_float64, float64, 0, 0, mode);
    break;
  default:
    PRINT_EXCEPTION("Unsupported image kind",
		    "Nothing is drawn.");
    break;
  }
}
Exemplo n.º 6
0
// Helper that sets the current thread exception, releasing the current one, for
// use in this file only.
NUITKA_MAY_BE_UNUSED inline void SET_CURRENT_EXCEPTION( PyObject *exception_type, PyObject *exception_value, PyTracebackObject *exception_tb )
{
    PyThreadState *thread_state = PyThreadState_GET();

    PyObject *old_type  = thread_state->exc_type;
    PyObject *old_value = thread_state->exc_value;
    PyObject *old_tb    = thread_state->exc_traceback;

    thread_state->exc_type = exception_type;
    thread_state->exc_value = exception_value;
    thread_state->exc_traceback = (PyObject *)exception_tb;

#if _DEBUG_EXCEPTIONS
    PRINT_STRING("SET_CURRENT_EXCEPTION:\n");
    PRINT_EXCEPTION( exception_type, exception_value, (PyObject *)exception_tb );
#endif

    Py_XDECREF( old_type );
    Py_XDECREF( old_value );
    Py_XDECREF( old_tb );

#if PYTHON_VERSION < 300
    // Set sys attributes in the fastest possible way.
    PyObject *sys_dict = thread_state->interp->sysdict;
    CHECK_OBJECT( sys_dict );

    PyDict_SetItem( sys_dict, const_str_plain_exc_type, exception_type ? exception_type : Py_None );
    PyDict_SetItem( sys_dict, const_str_plain_exc_value, exception_value ? exception_value : Py_None );
    PyDict_SetItem( sys_dict, const_str_plain_exc_traceback, exception_tb ? (PyObject *)exception_tb : Py_None );

    if ( exception_type )
        assert( Py_REFCNT( exception_type ) >= 2 );
    if ( exception_value )
        assert( Py_REFCNT( exception_value ) >= 2 );
    if ( exception_tb )
        assert( Py_REFCNT( exception_tb ) >= 2 );
#endif
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
int main(int argc, char *argv[])
{
  static char *Spec[] = {"[-t]", NULL};
  Process_Arguments(argc, argv, Spec, 1);

  if (Is_Arg_Matched("-t")) {
    /* Example test */
    Stack *stack = Make_Stack(GREY, 7, 7, 1);
    One_Stack(stack);
    Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
    ws->conn = 26;
    ws->mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
			  Stack_Depth(stack));
    Zero_Stack(ws->mask);

    /* set seeds */
    Set_Stack_Pixel(ws->mask, 1, 1, 0, 0, 1.0);
    Set_Stack_Pixel(ws->mask, 1, 5, 0, 0, 2.0);
    Set_Stack_Pixel(ws->mask, 3, 3, 0, 0, 3.0);
    Set_Stack_Pixel(ws->mask, 5, 1, 0, 0, 4.0);
    Set_Stack_Pixel(ws->mask, 5, 5, 0, 0, 5.0);

    /* set stack values */
    Set_Stack_Pixel(stack, 1, 1, 0, 0, 3.0);
    Set_Stack_Pixel(stack, 1, 5, 0, 0, 3.0);
    Set_Stack_Pixel(stack, 3, 3, 0, 0, 3.0);
    Set_Stack_Pixel(stack, 5, 1, 0, 0, 3.0);
    Set_Stack_Pixel(stack, 5, 5, 0, 0, 3.0);
    
    Stack *out = Stack_Watershed(stack, ws);

    //Write_Stack("../data/test/watershed/golden/watershed1.tif", out);

    char *golden_file = "../data/test/watershed/golden/watershed1.tif";
    if (fexist(golden_file)) {
      Stack *golden = Read_Stack(golden_file);
      if (Stack_Identical(out, golden) == FALSE) {
	Print_Stack_Value(stack);
	Print_Stack_Value(out);
	Print_Stack_Value(golden);
	PRINT_EXCEPTION("Bug?", "Conflict with golden.");
	return 1;
      }

      Kill_Stack(stack);
      Kill_Stack(out);
      Kill_Stack(golden);
      Kill_Stack_Watershed_Workspace(ws);
    } else {
      printf("%s cannot be found.\n", golden_file);
    }

    char *test_file = "../data/benchmark/rice_label.tif";
    if (fexist(test_file)) {
      stack = Read_Stack_U(test_file);

      ws = Make_Stack_Watershed_Workspace(stack);
      ws->mask = Copy_Stack(stack);
      ws->conn = 26;
      One_Stack(stack);

      out = Stack_Watershed(stack, ws);

      //Write_Stack("../data/test/watershed/golden/watershed2.tif", out);

      Stack *golden = Read_Stack("../data/test/watershed/golden/watershed2.tif");
      if (Stack_Identical(out, golden) == FALSE) {
	PRINT_EXCEPTION("Bug?", "Conflict with golden.");
	return 1;
      }
    } else {
      printf("%s cannot be found.\n", test_file);
    }

    printf(":) Testing passed.\n");

    return 0;
  }

#if 0
  /* Initialize */
  Watershed_3d *watershed = New_Watershed_3d();
  Watershed_3d_Workspace *ws = New_Watershed_3d_Workspace();
  ws->conn = 26;

  /* Initialize stack */
  Stack *stack = Read_Stack("../data/fly_neuron/dist.tif");
  int nvoxel = Stack_Voxel_Number(stack);
  int i;
  uint16 *array16 = (uint16 *)stack->array;
  for (i = 0; i < nvoxel; i++) {
    array16[i] = 0xFFFF - array16[i];
  }
  
  /* Add mask to ignore dark voxels  */
  ws->mask = Copy_Stack(stack); 
  

  //Translate_Stack(stack, GREY, 1);

  //stack->array = stack->array + stack->width * stack->height * 100;
  //stack->depth = 1;
  // ws->mask = Copy_Stack(stack);
  //Stack_Binarize(ws->mask);
  // ws->mask = NULL;

  //Write_Stack("../data/dist.tif", stack);


  //Stack *stack2 = Copy_Stack(stack);


#  if 0
  Build_3D_Watershed(stack, watershed, ws);
  Write_Stack("../data/test.tif", watershed->labels);
#  endif

#  if 0
  
  Image_View iv = Image_View_Stack(stack2);
  Watershed_Test *watershed2 = Build_2D_Watershed_Test(&(iv.image), 0);
  Write_Image("../data/test2.tif", watershed2->labels);
#  endif
#endif

#if 0
  Image *image = Read_Image("../data/Ring15.tif_Sub1200_Original_inv.tif");
  Watershed_2D *ws = Build_2D_Watershed(image, 0);
  Image *result = Color_Watersheds(ws, image);
  Write_Image("../data/test.tif", result);
  Kill_Image(image);
#endif

#if 0
  Stack *stack = Make_Stack(GREY, 7, 7, 1);
  One_Stack(stack);
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->conn = 26;
  ws->mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
			Stack_Depth(stack));
  Zero_Stack(ws->mask);
  Set_Stack_Pixel(ws->mask, 1, 1, 0, 0, 1.0);
  Set_Stack_Pixel(ws->mask, 1, 5, 0, 0, 2.0);
  Set_Stack_Pixel(ws->mask, 3, 3, 0, 0, 3.0);
  Set_Stack_Pixel(ws->mask, 5, 1, 0, 0, 4.0);
  Set_Stack_Pixel(ws->mask, 5, 5, 0, 0, 5.0);

  Set_Stack_Pixel(stack, 1, 1, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 1, 5, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 3, 3, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 5, 1, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 5, 5, 0, 0, 3.0);
  
  Stack *out = Stack_Watershed(stack, ws);

  Print_Stack_Value(out);
#endif

#if 0
  Stack *stack = Make_Stack(GREY, 3, 3, 1);
  One_Stack(stack);
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->conn = 26;
  ws->mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
			Stack_Depth(stack));
  Zero_Stack(ws->mask);

  Set_Stack_Pixel(ws->mask, 0, 0, 0, 0, 1.0);
  Set_Stack_Pixel(ws->mask, 2, 2, 0, 0, 2.0);

  Set_Stack_Pixel(stack, 0, 0, 0, 0, 5.0);
  Set_Stack_Pixel(stack, 2, 2, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 0, 2, 0, 0, 2.0);
  //Set_Stack_Pixel(stack, 1, 1, 0, 0, 2.0);
  Set_Stack_Pixel(stack, 1, 2, 0, 0, 2.0);
  Set_Stack_Pixel(stack, 2, 0, 0, 0, 2.0);
  Set_Stack_Pixel(stack, 2, 1, 0, 0, 2.0);

  Print_Stack_Value(stack);

  ws->start_level = 6;

  Stack *out = Stack_Watershed(stack, ws);

  Print_Stack_Value(out);
#endif
 
#if 0
  Stack *stack = Read_Stack_U("../data/benchmark/rice_label.tif");

  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->mask = Copy_Stack(stack);
  ws->conn = 26;
  One_Stack(stack);

  tic();
  Stack *out = Stack_Watershed(stack, ws);
  printf("%lld\n", toc());

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

#if 0
  Stack *stack = Read_Stack_U("../data/diadem_d1_147.xml");
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
			Stack_Depth(stack));
  Zero_Stack(ws->mask);
  ws->conn = 26;

  const int *dx = Stack_Neighbor_X_Offset(ws->conn);
  const int *dy = Stack_Neighbor_X_Offset(ws->conn);
  const int *dz = Stack_Neighbor_X_Offset(ws->conn);
  
  int seed[3];
  String_Workspace *sw = New_String_Workspace();
  char *line = NULL;
  FILE *fp = fopen("../data/diadem_d1_root_z.txt", "r");
  int k = 1;
    
  while ((line = Read_Line(fp, sw)) != NULL) {
    int n;
    String_To_Integer_Array(line, seed, &n);
    double maxv = -1;
    if (n == 3) {
      maxv = Get_Stack_Pixel(stack, seed[0], seed[1], seed[2], 0);
      printf("%g\n", maxv);
      int i;
      for (i = 0; i < ws->conn; i++) {
	if (maxv < Get_Stack_Pixel(stack, seed[0] + dx[i], seed[1] + dy[i], 
				   seed[2] + dz[i], 0)) {
	  maxv = Get_Stack_Pixel(stack, seed[0] + dx[i], seed[1] + dy[i], 
				 seed[2] + dz[i], 0);
	}
      }

      //Set_Stack_Pixel(stack, seed[0], seed[1], seed[2], 0, maxv);
      Set_Stack_Pixel(ws->mask, seed[0], seed[1], seed[2], 0, k);
      for (i = 0; i < ws->conn; i++) {
	//Set_Stack_Pixel(stack, seed[0] + dx[i], seed[1] + dy[i], 
	//		seed[2] + dz[i], 0, maxv);
	Set_Stack_Pixel(ws->mask, seed[0] + dx[i], seed[1] + dy[i], 
			seed[2] + dz[i], 0, k);	
      }
      k++;
    }
  }
  fclose(fp);
  Kill_String_Workspace(sw);
  
  /*
  Set_Stack_Pixel(ws->mask, 19, 605, 112, 0, 1.0);
  Set_Stack_Pixel(ws->mask, 28, 565, 112, 0, 1.0);
  */
  Stack_Watershed_Infer_Parameter(stack, ws);

  tic();
  Stack *out = Stack_Watershed(stack, ws);
  printf("%lld\n", toc());

  Write_Stack("../data/diadem_d1_147_label.tif", out);

  static const uint8 Color_Map[][3] = { 
    {0, 0, 0},
    {0, 224, 64}, {32, 64, 128}, {64, 64, 0}, {64, 128, 64},
    {96, 64, 128}, {64, 0, 0}, {128, 200, 64}, {160, 128, 128},
    {192, 0, 0}, {192, 160, 64}, {224, 64, 128}, {224, 224, 192}};
  
  Translate_Stack(out, COLOR, 1);
  size_t nvoxel = Stack_Voxel_Number(out);
  size_t i;
  color_t *arrayc = (color_t*) out->array;
  for (i = 0; i < nvoxel; i++) {
    arrayc[i][2] = Color_Map[arrayc[i][0]][2];
    arrayc[i][1] = Color_Map[arrayc[i][0]][1];
    arrayc[i][0] = Color_Map[arrayc[i][0]][0];
  }

  Write_Stack("../data/diadem_d1_147_paint.tif", out);
#endif

#if 0
  Stack *stack = Read_Stack_U("../data/diadem_d1_146.xml");
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  Stack *mask = Read_Stack("../data/test3.tif");
  ws->mask = Crop_Stack(mask, 252, -937, 2, 1024, 1024, 63, NULL);
  ws->conn = 26;

  Stack_Watershed_Infer_Parameter(stack, ws);

  tic();
  Stack *out = Stack_Watershed(stack, ws);
  printf("%lld\n", toc());
  
  Write_Stack("../data/test2.tif", out);
#endif

#if 0
  Stack *stack = Make_Stack(GREY, 7, 7, 1);
  One_Stack(stack);
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->conn = 26;
  ws->mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
			Stack_Depth(stack));
  Zero_Stack(ws->mask);
  Set_Stack_Pixel(ws->mask, 1, 1, 0, 0, 1.0);
  Set_Stack_Pixel(ws->mask, 1, 5, 0, 0, 2.0);
  Set_Stack_Pixel(ws->mask, 3, 3, 0, 0, 3.0);
  Set_Stack_Pixel(ws->mask, 5, 1, 0, 0, 4.0);
  Set_Stack_Pixel(ws->mask, 5, 5, 0, 0, 5.0);

  Set_Stack_Pixel(stack, 1, 1, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 1, 5, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 3, 3, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 5, 1, 0, 0, 3.0);
  Set_Stack_Pixel(stack, 5, 5, 0, 0, 3.0);
  
  Stack *out = Stack_Watershed(stack, ws);
  Print_Stack_Value(out);

  Stack *out2 = Stack_Region_Border_Shrink(out, ws);
  
  Print_Stack_Value(out2);

#endif

#if 0
  Stack *stack = Read_Stack("../data/diadem_d1_013_label.tif");
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  //ws->conn = 26;

  Stack *out = Stack_Region_Border_Shrink(stack, ws);
  Write_Stack("../data/test.tif", out);
#endif

#if 0
  Stack *stack = Make_Stack(GREY, 1, 1, 19);
  One_Stack(stack);
  
  stack->array[3] = 5;
  stack->array[4] = 5;
  stack->array[7] = 5;
  stack->array[8] = 5;
  stack->array[10] = 4;
  stack->array[11] = 5;
  stack->array[12] = 5;
  stack->array[13] = 4;
  stack->array[16] = 5;
  stack->array[17] = 5;

  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->conn = 26;
  ws->mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
			Stack_Depth(stack));
  Zero_Stack(ws->mask);

  
  Print_Stack_Value(stack);
  Stack_Watershed_Zgap_Barrier(stack, ws->mask);
  Print_Stack_Value(ws->mask);
#endif

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

  Stack *stack2 = Stack_Bwdist_L_U16(stack, NULL, 0);
  Write_Stack("../data/test.tif", stack2);  
#endif

#if 0
  char stack_path[100];
  char mask_path[100];

  strcpy(stack_path, "../data/diadem_d1_064.xml");

  strcpy(mask_path, stack_path);
  strsplit(mask_path, '.', -1);
  sprintf(mask_path, "%s_label.tif", mask_path);

  if (!fexist(stack_path)) {
    fprintf(stderr, "Cannot find %s\n", stack_path);
    return 1;
  }
  
  printf("Processing %s\n", stack_path);
  Stack *stack = Read_Stack_U(stack_path);
  Stack *mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
			   Stack_Depth(stack));
  Zero_Stack(mask);

  int conn = 26;
  const int *dx = Stack_Neighbor_X_Offset(conn);
  const int *dy = Stack_Neighbor_X_Offset(conn);
  const int *dz = Stack_Neighbor_X_Offset(conn);
  
  int seed[3];
  String_Workspace *sw = New_String_Workspace();
  char *line = NULL;
  FILE *fp = fopen("../data/064.seeds.txt", "r");
  int k = 1;

  /* label seeds */
  while ((line = Read_Line(fp, sw)) != NULL) {
    int n;
    String_To_Integer_Array(line, seed, &n);
    double maxv = -1;
    if (n == 3) {
      maxv = Get_Stack_Pixel(stack, seed[0], seed[1], seed[2], 0);
      int i;
      for (i = 0; i < conn; i++) {
	if (maxv < Get_Stack_Pixel(stack, seed[0] + dx[i], seed[1] + dy[i], 
				   seed[2] + dz[i], 0)) {
	  maxv = Get_Stack_Pixel(stack, seed[0] + dx[i], seed[1] + dy[i], 
				 seed[2] + dz[i], 0);
	}
      }
      
      Set_Stack_Pixel(mask, seed[0], seed[1], seed[2], 0, k);
      for (i = 0; i < conn; i++) {
	Set_Stack_Pixel(mask, seed[0] + dx[i], seed[1] + dy[i], 
			seed[2] + dz[i], 0, k);	
      }
      k++;
    }
  }
  fclose(fp);
  Kill_String_Workspace(sw);

  Stack_Running_Median(stack, 0, stack);
  Stack_Running_Median(stack, 1, stack);
    
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->mask = mask;
    
  Filter_3d *filter = Gaussian_Filter_3d(2.0, 2.0, 1.5);
  Stack *filtered_stack  = Filter_Stack(stack, filter);
  Stack_Watershed_Zgap_Barrier(filtered_stack, ws->mask);
  Stack_Running_Max(ws->mask, 0, ws->mask);
  Stack_Running_Max(ws->mask, 1, ws->mask);
  //Write_Stack("../data/test.tif", ws->mask);
    
  Kill_Stack(filtered_stack);
  filtered_stack = NULL;

    
  FMatrix *dm = Mexihat_3D1_F(2.0, NULL, 2);
  //FMatrix *dm = Mexihat_3D_F(2.0, NULL);
  FMatrix_Negative(dm);

  filtered_stack = Filter_Stack(stack, dm);
  
  Stack_Threshold_Common(filtered_stack, 0, 65535);
  Stack_Binarize(filtered_stack);
  Translate_Stack(filtered_stack, GREY, 1);
    
    
  {
    int i, j, k;
    int offset = 0;
    uint16 *array = (uint16*) stack->array;
    for (k = 0; k < stack->depth; k++) {
      for (j = 0; j < stack->height; j++) {
	for (i = 0; i < stack->width; i++) {
	  if (filtered_stack != NULL) {
	    if (filtered_stack->array[offset] == 1) {
	      ws->mask->array[offset] = STACK_WATERSHED_BARRIER;
	    }
	  }
	  array[offset++] += k * 2;
	}
      }
    }
  }

  Kill_Stack(filtered_stack);
  
  Stack_Watershed_Infer_Parameter(stack, ws);
  ws->conn = 6;

  double weights[26] = {0.5, 0.5, 1.0, 1.0, 0.2, 0.2, 0.75, 0.75, 0.75, 0.75,
			0.35, 0.35, 0.35, 0.35, 0.6, 0.6, 0.6, 0.6, 
			0.45, 0.45, 0.45, 0.45,
			0.45, 0.45, 0.45, 0.45};

  ws->weights = weights;
  ws->weights = NULL;
  
  if (ws->weights != NULL) {
    ws->min_level /= 3;
  }
    
  Stack_Running_Median(stack, 0, stack);
  Stack_Running_Median(stack, 1, stack);
  
  Stack *out = Stack_Watershed(stack, ws);
  
  strcpy(mask_path, stack_path);
  strsplit(mask_path, '.', -1);
  sprintf(mask_path, "%s_label.tif", mask_path);
  
  Write_Stack("../data/test.tif", out);

#endif

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

  int thre = Stack_Find_Threshold_A(stack, THRESHOLD_LOCMAX_TRIANGLE);
  Filter_3d *filter = Gaussian_Filter_3d(1.0, 1.0, 0.5);
  Stack *out = Filter_Stack(stack, filter);
  stack = Copy_Stack(out);
  Stack_Threshold_Binarize(out, thre);
  Stack *out2 = Stack_Bwdist_L_U16P(out, NULL, 0);
  int nvoxel = Stack_Voxel_Number(out);
  uint16_t *dist_array = (uint16_t*) out2->array;
  int i;
  for (i = 0; i < nvoxel; i++) {
    dist_array[i] = sqrt(dist_array[i]);
  }

  Write_Stack("../data/labmeeting13/distp.tif", out2);
#endif

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

  Stack *stack = Read_Stack("/Users/zhaot/Data/jinny/slice7_2to34ds_soma_c2.tif");
  int thre = Stack_Find_Threshold_A(stack, THRESHOLD_LOCMAX_TRIANGLE);
  Filter_3d *filter = Gaussian_Filter_3d(1.0, 1.0, 0.5);
  Stack *out = Filter_Stack(stack, filter);
  stack = Copy_Stack(out);
  Stack_Threshold_Binarize(out, thre);
  Stack *out2 = Stack_Bwdist_L_U16P(out, NULL, 0);

  /*
  out = Stack_Locmax_Region(out2, 26);
  */
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->mask = Make_Stack(GREY, Stack_Width(stack), Stack_Height(stack),
      Stack_Depth(stack));
  Zero_Stack(ws->mask);
  size_t nvoxel = Stack_Voxel_Number(stack);
  size_t offset;
  uint16_t *dist_array = (uint16_t*) out2->array;
  for (offset = 0; offset < nvoxel; offset++) {
    if (/*(out->array[offset] == 1) && */(dist_array[offset] > 1000)) {
      ws->mask->array[offset] = 1;
    }
  }

  //Objlabel_Workspace *ow = New_Objlabel_Workspace();
  //Stack_Label_Large_Objects_W(ws->mask, 1, 2, 10, ow);
  //Stack_Label_Objects_N(ws->mask, NULL, 1, 2, 26);
  Object_3d_List *objs = Stack_Find_Object(ws->mask, 1, 100);
  Zero_Stack(ws->mask);
  Stack_Draw_Objects_Bw(ws->mask, objs, -255);
  printf("%g\n", Stack_Max(ws->mask, NULL));

  /*
  Write_Stack("../data/test.tif", ws->mask);
  return 1;
*/

  ws->min_level = thre;
  ws->start_level = 65535;

  Stack *out3 = Stack_Watershed(stack, ws);
  /*
  Write_Stack("../data/labmeeting13/watershed.tif", out3);
  return 1;
*/
  for (offset = 0; offset < nvoxel; offset++) {
    if (dist_array[offset] < 300) {
      out3->array[offset] = 0;
    }
  }

  int nregion = Stack_Max(out3, NULL);

  Kill_Stack(out2);
  Stack *filtered = Copy_Stack(stack);
  Kill_Stack(stack);
  
  ws->conn = 8;
  stack = Stack_Region_Border_Shrink(out3, ws);
  out2 = Stack_Region_Expand(stack, 4, 30, NULL);

  for (offset = 0; offset < nvoxel; offset++) {
    if (out->array[offset] == 0) {
      out2->array[offset] = 0;
    }
  }

  Write_Stack("../data/test2.tif", out2);

  Kill_Stack(stack);
  //stack = Read_Stack("../data/test/soma2.tif");
  stack = Read_Stack("/Users/zhaot/Data/jinny/slice7_2to34ds_soma_c2.tif");
  Translate_Stack(stack, COLOR, 1);
  int i;
  double h = 0.0;
  double s = 1.0;
  for (i = 0; i < nregion; i++) {
    Stack_Label_Color_L(stack, out2, i+1, h+=0.35, s, filtered);
    /*
    Rgb_Color color;
    Set_Color_Jet(&color, i*3);
    Stack_Label_Level(stack, out2, i+1, color);
    */
  }
  Write_Stack("../data/test.tif", stack);
#endif

#if 0
  Stack *stack = Read_Stack("../data/leaktest/leak3.tif");
  Stack *distmap = Stack_Bwdist_L_U16P(stack, NULL, 0);

  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->mask = Copy_Stack(distmap);
  Stack_Threshold_Binarize(ws->mask, 10);
  Translate_Stack(ws->mask, GREY, 1);
  Object_3d_List *objs = Stack_Find_Object(ws->mask, 1, 100);
  Zero_Stack(ws->mask);
  Stack_Draw_Objects_Bw(ws->mask, objs, -255);

  ws->min_level = 1;
  ws->start_level = 65535;
  Stack *out3 = Stack_Watershed(distmap, ws);
  Write_Stack("../data/test.tif", out3);

#endif

#if 0
  Stack *stack = Read_Stack("../data/benchmark/two_disk.tif");
  Stack_Watershed_Workspace *ws = Make_Stack_Watershed_Workspace(stack);
  ws->conn = 26;
  Stack *out = Stack_Watershed(stack, ws);

  Write_Stack("../data/test.tif", out);
#endif
  return 0;
}
Exemplo n.º 9
0
void Stack_Build_Seed_Graph(Stack *stack, int *seed, int nseed,
			    uint8_t **connmat, Objlabel_Workspace *ow)
{
  if (stack->kind != GREY16) {
    PRINT_EXCEPTION("Unsupported stack kind", "The stack must be GREY16");
    return;
  }

  STACK_OBJLABEL_OPEN_WORKSPACE(stack, ow);
  
  int i, j, k;
  int nvoxel = Stack_Voxel_Number(stack);

  if (ow->init_chord == TRUE) {
    for (i = 0; i < nvoxel; i++) {
      ow->chord->array[i] = -1;
    }
  }

  uint16 *mask = (uint16 *) stack->array;

  const int conn = 26;

  /* each seed has a queue */
  int *queue_head = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_tail = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_length = iarray_malloc(nseed);  /* queue_length malloced */

  /* At the beginning, each queue has one element, the corresponding seed */
  iarraycpy(queue_head, seed, 0, nseed);
  iarraycpy(queue_tail, seed, 0, nseed);

  for (i = 0; i < nseed; i++) {
    queue_length[i] = 1;
  }

  int neighbor[26];
  int bound[26];
  int nbound;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  BOOL stop = FALSE;
  int x, y, z;

  Stack_Neighbor_Offset(conn, stack->width, stack->height, neighbor);
  
#define STACK_SEED_GRAPH_UPDATE_QUEUE(test)				\
  for (k = 0; k < conn; k++) {						\
    if (test) {								\
      int checking_voxel = queue_head[i] + neighbor[k];			\
      if ((mask[checking_voxel] > 0) && (mask[checking_voxel] != label)) { \
	if (mask[checking_voxel] == 1) {				\
	  ow->chord->array[queue_tail[i]] = checking_voxel;		\
	  queue_tail[i] = checking_voxel;				\
	  mask[checking_voxel] = label;					\
	  queue_length[i]++;						\
	} else {							\
	  if (mask[checking_voxel] > label) {				\
	    connmat[i][mask[checking_voxel] - 2] = 1;			\
	  } else {							\
	    connmat[mask[checking_voxel] - 2][i] = 1;			\
	  }								\
	}								\
      }									\
    }									\
  }

  while (stop == FALSE) {
    stop = TRUE;
    for (i = 0; i < nseed; i++) {
      if (queue_length[i] > 0) {
	int label = i + 2;
	for (j = 0; j < queue_length[i]; j++) {
	  Stack_Util_Coord(queue_head[i], stack->width, stack->height, 
			   &x, &y, &z);
	  nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth,
					     x, y, z, bound);
	  if (nbound == conn) {
	    STACK_SEED_GRAPH_UPDATE_QUEUE(1);
	    /*
	    for (k = 0; k < conn; k++) {
	      if (1) {
		int checking_voxel = queue_head[i] + neighbor[k];
		if ((mask[checking_voxel] > 0) && (mask[checking_voxel] != label)) { 
		  if (mask[checking_voxel] == 1) {				
		    ow->chord->array[queue_tail[i]] = checking_voxel;		
		    queue_tail[i] = checking_voxel;				
		    mask[checking_voxel] = label;  
		    queue_length[i]++;		
		  } else {				
		    if (mask[checking_voxel] > label) {		
		      connmat[mask[checking_voxel] - 2][i] = 1;		
		    } else {				
		      connmat[i][mask[checking_voxel] - 2] = 1;	
		    }						
		  }						
		}								
	      }					
	    }
	    */
	  } else {
	    STACK_SEED_GRAPH_UPDATE_QUEUE(bound[k]);
	  }
	}
	queue_head[i] = ow->chord->array[queue_head[i]];
	queue_length[i]--;
	stop = FALSE;
      }
    }
  }

  free(queue_head); /* queue_head freed */
  free(queue_tail); /* queue_head freed */
  free(queue_length);  /* queue_length freed */

  STACK_OBJLABEL_CLOSE_WORKSPACE(ow);
}
Exemplo n.º 10
0
/**
 * Stack_Build_Seed_Graph_Gg() allows users to build a seed graph using 
 * approximate geodesdic distances. The workspace should be created by
 * Make_Objlabel_Workspace_Gg() and initialized by Init_Objlabel_Workspace_Gg()
 * if necessary.
 */
Graph* Stack_Build_Seed_Graph_Gg(Stack *stack, int *seed, int nseed,
				BOOL weighted, Objlabel_Workspace *ow)
{
  if (stack->kind != GREY16) {
    PRINT_EXCEPTION("Unsupported stack kind", "The stack must be GREY16");
    return NULL;
  }
  
  int i, j, k;

  uint16 *level = (uint16 *) ow->u;
  uint16 *mask = (uint16 *) stack->array;

  const int conn = 26;

  /* each seed has a queue */
  int *queue_head = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_tail = iarray_malloc(nseed); /* queue_head malloced */
  int *queue_length = iarray_malloc(nseed);  /* queue_length malloced */

  /* At the beginning, each queue has one element, the corresponding seed */
  iarraycpy(queue_head, seed, 0, nseed);
  iarraycpy(queue_tail, seed, 0, nseed);

  for (i = 0; i < nseed; i++) {
    queue_length[i] = 1;
  }

  int neighbor[26];
  int bound[26];
  int nbound;
  int cwidth = stack->width - 1;
  int cheight = stack->height - 1;
  int cdepth = stack->depth - 1;

  BOOL stop = FALSE;
  int x, y, z;

  Stack_Neighbor_Offset(conn, stack->width, stack->height, neighbor);
  
#define STACK_SEED_GRAPH_UPDATE_QUEUE_GG(test)				\
  for (k = 0; k < conn; k++) {						\
    if (test) {								\
      int checking_voxel = queue_head[i] + neighbor[k];			\
      if ((mask[checking_voxel] > 0) && (mask[checking_voxel] != label)) { \
	if (mask[checking_voxel] == 1) {				\
	  ow->chord->array[queue_tail[i]] = checking_voxel;		\
	  queue_tail[i] = checking_voxel;				\
	  mask[checking_voxel] = label;					\
	  level[checking_voxel] = level[queue_head[i]] + 1;		\
	  queue_length[i]++;						\
	} else {							\
	  int v1, v2, tmp;						\
	  v1 = i;							\
	  v2 = mask[checking_voxel] - 2;				\
	  ASSERT(v1 != v2, "Bug in Stack_Build_Seed_Graph_G()");	\
	  if (v1 > v2) {						\
	    SWAP2(v1, v2, tmp);						\
	  }								\
	  if (Graph_Edge_Index(v1, v2, gw) < 0) {			\
	    if (weighted == TRUE) {					\
	      /*double dist = Stack_Util_Voxel_Distance(seed[v1], seed[v2], stack->width, stack->height);*/ \
	      double dist = level[checking_voxel] + level[queue_head[i]]; \
	      Graph_Add_Weighted_Edge(graph, v1, v2, dist);		\
	    } else {							\
	      Graph_Add_Edge(graph, v1, v2);				\
	    }								\
	    Graph_Expand_Edge_Table(v1, v2, graph->nedge -1, gw);	\
	  }								\
	}								\
      }									\
    }									\
  }

  Graph *graph = Make_Graph(nseed, nseed, weighted);
  Graph_Workspace *gw = New_Graph_Workspace();

  while (stop == FALSE) {
    stop = TRUE;
    for (i = 0; i < nseed; i++) {
      if (queue_length[i] > 0) {
	int label = i + 2;
	for (j = 0; j < queue_length[i]; j++) {
	  Stack_Util_Coord(queue_head[i], stack->width, stack->height, 
			   &x, &y, &z);
	  nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth,
					     x, y, z, bound);
	  if (nbound == conn) {
	    STACK_SEED_GRAPH_UPDATE_QUEUE_GG(1);
	  } else {
	    STACK_SEED_GRAPH_UPDATE_QUEUE_GG(bound[k]);
	  }
	}
	queue_head[i] = ow->chord->array[queue_head[i]];
	queue_length[i]--;
	stop = FALSE;
      }
    }
  }

  free(queue_head); /* queue_head freed */
  free(queue_tail); /* queue_head freed */
  free(queue_length);  /* queue_length freed */

  return graph;
}
Exemplo n.º 11
0
int main(int argc, char *argv[])
{
  static char *Spec[] = {"[-t]", NULL};
  Process_Arguments(argc, argv, Spec, 1);
 
  if (Is_Arg_Matched("-t")) {
    coordinate_3d_t coord = {0, 0, 0};
    
    /* Translate coordinates. */
    Geo3d_Translate_Coordinate(coord, coord+1, coord+2, 1.0, 2.0, 3.0);

    if ((coord[0] != 1.0) || (coord[1] != 2.0) || (coord[2] != 3.0)) {
      Print_Coordinate_3d(coord);
      PRINT_EXCEPTION(":( Bug?", "Unexpected coordinate values.");
      return 1;      
    }
    
    coordinate_3d_t coord2 = {0, 0, 0};
    double dx, dy, dz;

    Geo3d_Coordinate_Offset(coord[0], coord[1], coord[2], coord2[0], coord2[1],
			    coord2[2], &dx, &dy, &dz);
    if ((dx != -coord[0]) || (dy != -coord[1]) || (dz != -coord[2])) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected offset values.");
      return 1;      
    }
    
    Coordinate_3d_Copy(coord2, coord);

    /* Rotate coordinates. */
    Geo3d_Rotate_Coordinate(coord, coord+1, coord+2, 0.1, 0.5, 0);
    
    if (fabs(Geo3d_Orgdist_Sqr(coord[0], coord[1], coord[2]) - 
	     Geo3d_Orgdist_Sqr(coord2[0], coord2[1], coord2[2])) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Rotation failed.");
      return 1;            
    }

    /* inverse rotation */
    Geo3d_Rotate_Coordinate(coord, coord+1, coord+2, 0.1, 0.5, 1);
    if ((fabs(coord[0] - coord2[0]) > 0.01) || 
	(fabs(coord[1] - coord2[1]) > 0.01) ||
	(fabs(coord[2] - coord2[2]) > 0.01)){
      PRINT_EXCEPTION(":( Bug?", "Rotation failed.");
      return 1;            
    }

    /* Normal vector of an orientation. This is a canonical representaion
     * of an orientation. */ 
    Geo3d_Orientation_Normal(0.1, 0.5, coord, coord+1, coord+2);

    /* We can also turn the normal vector into orientation. */
    double theta, psi;
    Geo3d_Normal_Orientation(coord[0], coord[1], coord[2], &theta, &psi);
    if (fabs(theta - 0.1) > 0.01 || fabs(Normalize_Radian(psi) - 0.5) > 0.01) {
      printf("%g, %g\n", theta, psi);
      PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values.");
      return 1; 
    }

    /* If we rotate the vector back, we should get (0, 0, 1). */
    Geo3d_Rotate_Coordinate(coord, coord+1, coord+2, 0.1, 0.5, 1);
    
    if ((fabs(coord[0]) > 0.01) || (fabs(coord[1]) > 0.01) ||
	(fabs(coord[2] - 1.0) > 0.01)){
      PRINT_EXCEPTION(":( Bug?", "Rotation failed.");
      return 1;            
    }

    Geo3d_Coord_Orientation(1, 0, 0, &theta, &psi);
    double in[3] = {0, 0, 1};
    double out[3] = {0, 0, 0};
    Rotate_XZ(in, out, 1, theta, psi, 0);

    if (fabs(out[0] - 1.0) > 0.01 || fabs(out[1]) > 0.01 || 
	fabs(out[2]) > 0.01) {
      printf("%g, %g, %g\n", out[0], out[1], out[2]);
      printf("%g, %g\n", theta, psi);
      PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values.");
      return 1; 
    }
    /*
    if (fabs(theta - TZ_PI_2) > 0.01 || 
	fabs(Normalize_Radian(psi) - TZ_PI_2) > 0.01) {
      printf("%g, %g\n", theta, psi);
      PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values.");
      return 1; 
    }
    */

    Geo3d_Coord_Orientation(5, 0, 0, &theta, &psi);
    {
    double in[3] = {0, 0, 5};
    double out[3] = {0, 0, 0};
    Rotate_XZ(in, out, 1, theta, psi, 0);

    if (fabs(out[0] - 5.0) > 0.01 || fabs(out[1]) > 0.01 || 
	fabs(out[2]) > 0.01) {
      printf("%g, %g, %g\n", out[0], out[1], out[2]);
      printf("%g, %g\n", theta, psi);
      PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values.");
      return 1; 
    }
    }
    /*
    if (fabs(theta - TZ_PI_2) > 0.01 || 
	fabs(Normalize_Radian(psi) - TZ_PI_2) > 0.01) {
      printf("%g, %g\n", theta, psi);
      PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values.");
      return 1; 
    }
    */

    /* Rotate the orientation. */
    theta = TZ_PI_2;
    psi = TZ_PI;
    Geo3d_Rotate_Orientation(-TZ_PI, TZ_PI_2, &theta, &psi);
    if (fabs(theta + TZ_PI_2) > 0.01 || 
	fabs(psi + TZ_PI_2) > 0.01) {
      printf("%g, %g\n", theta, psi);
      PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values.");
      return 1; 
    }
    
    /* More extensive test on rotation */
    Random_Seed(time(NULL) - getpid());
    int i;
    for (i = 0; i < 100; i++) {
      double x = Unifrnd() * (1 - Bernrnd(0.5) * 2.0);
      double y = Unifrnd() * (1 - Bernrnd(0.5) * 2.0);
      double z = Unifrnd() * (1 - Bernrnd(0.5) * 2.0);
      double theta, psi;
      Geo3d_Coord_Orientation(x, y, z, &theta, &psi);

      double x2 = 0.0;
      double y2 = 0.0;
      double z2 = Geo3d_Orgdist(x, y, z);
      Geo3d_Rotate_Coordinate(&x2, &y2, &z2, theta, psi, 0);

      if (fabs(x - x2) > 0.01 || fabs(y - y2) > 0.01 || fabs(z - z2) > 0.01) {
        printf("%g, %g\n", theta, psi);
        printf("%g, %g, %g\n", x, y, z);
        printf("%g, %g, %g\n", x2, y2, z2);
        PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values.");
        return 1; 
      }
    }

    /* Dot product. */
    if (Geo3d_Dot_Product(1.0, 2.0, 3.0, 3.0, 2.0, 1.0) != 10.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected dot product.");
      return 1; 
    }

    /* Cross product. */
    Geo3d_Cross_Product(1.0, 2.0, 3.0, 3.0, 1.0, 2.0, coord, coord+1, coord+2);

    if (fabs(Geo3d_Dot_Product(1.0, 2.0, 3.0, coord[0], coord[1], coord[2])) >
	0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected dot product.");
      return 1; 
    }

    if (fabs(Geo3d_Dot_Product(3.0, 1.0, 2.0, coord[0], coord[1], coord[2])) >
	0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected dot product.");
      return 1; 
    }

    /* Distance calculations. */
    if (Geo3d_Orgdist_Sqr(1.0, 2.0, 3.0) != 14.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected value.");
      return 1;       
    }

    if (fabs(Geo3d_Orgdist(1.0, 2.0, 3.0) - sqrt(14.0)) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected value.");
      return 1;       
    }

    if (Geo3d_Dist(1.0, 2.0, 3.0, 1.0, 2.0, 3.0) != 0.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected value.");
      return 1;       
    }

    if (Geo3d_Dist_Sqr(1.0, 2.0, 3.0, 0.0, 0.0, 0.0) != 14.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected value.");
      return 1;       
    }

    /* Angle between two vectors. */
    if (fabs(Geo3d_Angle2(1, 0, 0, 0, 0, 1) - TZ_PI_2) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected value.");
      return 1;             
    }

    /* Distance between two lines */
    coordinate_3d_t line1_start = {0, 0, 0};
    coordinate_3d_t line1_end = {1, 0, 0};
    coordinate_3d_t line2_start = {0, 1, 1}; 
    coordinate_3d_t line2_end = {0, 2, 1}; 

    double d = Geo3d_Line_Line_Dist(line1_start, line1_end,
				    line2_start, line2_end);

    if (fabs(d - 1.0) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected distance.");
      return 1;             
    }
    
    /* Distance between two line segments. */
    double intersect1, intersect2;
    int cond;
    d = Geo3d_Lineseg_Lineseg_Dist(line1_start, line1_end,
				   line2_start, line2_end, 
				   &intersect1, &intersect2, &cond);
    if (fabs(d - sqrt(2.0)) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected distance.");
      return 1;             
    }

    /* Distance between a point and a line segment. */
    coord[0] = 0.5;
    coord[1] = 1.0;
    coord[2] = 1.0;
    d = Geo3d_Point_Lineseg_Dist(coord, line1_start, line1_end, &intersect1);
    if (fabs(d - sqrt(2.0)) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected distance.");
      return 1;             
    }

    /* Get a break point of a line segment. */
    Geo3d_Lineseg_Break(line1_start, line1_end, 0.1, coord);
    if ((coord[0] != 0.1) || (coord[1] != 0.0) || (coord[2] != 0.0)) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected break point.");
      return 1;                   
    }

    /* Orientations of a set of points */

    /* Orientation of a covariance matrix */

    /* 3D coordinates routines */
    /* Unitize a point. */
    Coordinate_3d_Unitize(coord);
    
    if (fabs(Coordinate_3d_Norm(coord) - 1.0) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected norm.");
      return 1;                   
    }

    Set_Coordinate_3d(coord, 0.0, 0.0, 0.0);

    /* origin point is not affected by unitization */
    Coordinate_3d_Unitize(coord);
    
    if (Coordinate_3d_Norm(coord) != 0.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected norm.");
      return 1;                   
    }
    
    Set_Coordinate_3d(coord, 1.0, 2.0, 3.0);

    /* Square length */
    if (Coordinate_3d_Length_Square(coord) != 14) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected square length");
    }

    /* Angle between two vectors */
    coordinate_3d_t coord_a1 = { 1, 0, 0 }; 
    coordinate_3d_t coord_a2 = { 0, 0, 1 };

    if (fabs(Coordinate_3d_Angle2(coord_a1, coord_a2) - TZ_PI_2) > 0.01) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected angle");
    }


    /* Scale coordinates */
    Coordinate_3d_Scale(coord, 2.0);
    
    if ((coord[0] != 2.0) || (coord[1] != 4.0) || (coord[2] != 6.0)) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected coordinate value.");
      return 1;                         
    }

    /* Normalizd dot product */
    if (Coordinate_3d_Normalized_Dot(coord, coord2) > 1.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected dot product.");
      return 1;                               
    }

    Set_Coordinate_3d(coord, 1.0, 2.0, 3.0);    

    Coordinate_3d_Copy(coord2, coord);
    Coordinate_3d_Scale(coord2, 2.0);

    coordinate_3d_t coord3;
    Coordinate_3d_Copy(coord3, coord);
    Coordinate_3d_Scale(coord3, 3.0);

    /* cos value of an angle formed by 3 points */
    if (Coordinate_3d_Cos3(coord, coord2, coord3) != 1.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected cos value.");
      return 1;      
    }

    /* cos value of an angle formed by 4 points */
    coordinate_3d_t coord4;
    Coordinate_3d_Copy(coord4, coord);
    Coordinate_3d_Scale(coord4, 4.0);

    if (Coordinate_3d_Cos4(coord, coord2, coord3, coord4) != 1.0) {
      PRINT_EXCEPTION(":( Bug?", "Unexpected cos value.");
      return 1;      
    }

    printf(":) Testing passed.\n");

    return 0;
  }

#if 0
  Geo3d_Vector v1 = {1.1, 0, 0};
  Geo3d_Vector v2 = {5, 0, 0};

  double theta1 = 3.83812;
  double psi1 = 3.53202;
  double theta2 = 0.72657;
  double psi2 = 3.61214;

  Geo3d_Orientation_Normal(theta1, psi1, &(v1.x), &(v1.y), &(v1.z));
  Geo3d_Orientation_Normal(theta2, psi2, &(v2.x), &(v2.y), &(v2.z));
 
  Print_Geo3d_Vector(&v1);
  Print_Geo3d_Vector(&v2);

  printf("%g\n", Geo3d_Vector_Dot(&v1, &v2));
  printf("%g\n", Geo3d_Vector_Angle2(&v1, &v2));

  
  double angle = Vector_Angle(-1.0, -1.0);
  
  theta1 = -3.0;
  psi1 = -5.0;
  
  double x, y, z;
  Geo3d_Orientation_Normal(theta1, psi1, &x, &y, &z);
  printf("%g, %g, %g\n", x, y, z);

  Geo3d_Normal_Orientation(x, y, z, &theta1, &psi1);

  printf("%g\n", angle * 180.0 / TZ_PI);

  printf("%g, %g\n", theta1, psi1);
  Geo3d_Orientation_Normal(theta1, psi1, &x, &y, &z);
  printf("%g, %g, %g\n", x, y, z);
#endif

#if 0
  Geo3d_Scalar_Field *field = 
    Read_Geo3d_Scalar_Field("../data/mouse_neuron/seeds.bn");
  Print_Geo3d_Scalar_Field_Info(field);
  Stack *stack = Read_Stack("../data/mouse_neuron/mask.tif");
  Geo3d_Scalar_Field_Draw_Stack(field, stack, NULL, NULL);
  Write_Stack("../data/test.tif", stack);
#endif

#if 0
  double line_start[3] = {2.0, 3.0, 4.0};
  double line_end[3] = {1.0, 1.0, 6.0};

  double point[3] = {10.5, 20.5, 40.7};

  double lamda;
  printf("%g\n", Geo3d_Point_Lineseg_Dist(point, line_start, line_end, &lamda));
  double line_point[3];
  double length = sqrt(Geo3d_Dist_Sqr(line_start[0], line_start[1], line_start[2], line_end[0], line_end[1], line_end[2]));
  line_point[0] = line_start[0] + lamda * (line_end[0] - line_start[0]);
  line_point[1] = line_start[1] + lamda * (line_end[1] - line_start[1]);
  line_point[2] = line_start[2] + lamda * (line_end[2] - line_start[2]);
  printf("%g\n", lamda);
  printf("%g\n", sqrt(Geo3d_Dist_Sqr(line_point[0], line_point[1], line_point[2], point[0], point[1], point[2])));

  darray_sub(point, line_point, 3);
  darray_sub(line_end, line_point, 3);
  printf("%g\n", Geo3d_Dot_Product(point[0], point[1], point[2],
				   line_end[0], line_end[1], line_end[2]));

#endif

#if 0
  Geo3d_Scalar_Field *field = Read_Geo3d_Scalar_Field("../data/mouse_neuron3_org/seeds");
  //Print_Geo3d_Scalar_Field(field);

  darray_write("../data/pts.bn", (double *)field->points, field->size * 3);
  darray_write("../data/ws.bn", field->values, field->size);

  coordinate_3d_t centroid;
  Geo3d_Scalar_Field_Centroid(field, centroid);
  Print_Coordinate_3d(centroid);
  
  double cov[9];
  Geo3d_Scalar_Field_Cov(field, cov);
  darray_print2(cov, 3, 3);

  darray_write("../data/cov.bn", cov, 9);

  double vec[3];
  Geo3d_Cov_Orientation(cov, vec);
  darray_print2(vec, 3, 1);

  
#endif

#if 0
  double mu1, mu2;

#  if 0 /* parallel case */
  double line1_start[3] = {0, 0, 0};
  double line1_end[3] = {1, 1, 10};
  double line2_start[3] = {0, 1, 0};
  double line2_end[3] = {1, 2, 10};
#  endif

#  if 0 /* parallel case */
  double line1_start[3] = {0, 0, 0};
  double line1_end[3] = {1, 1, 10};
  double line2_start[3] = {-1, -1, -1};
  double line2_end[3] = {-3, -3, -21};
#  endif

#  if 0 /* i-i case */
  double line1_start[3] = {0, 0, 0};
  double line1_end[3] = {3, 4, 5};
  double line2_start[3] = {-1, 8, 9};
  double line2_end[3] = {1, -3, -4};
#  endif

#  if 0 /* point to line case */
  double line1_start[3] = {3, 4, 5};
  double line1_end[3] = {3, 4, 5};
  double line2_start[3] = {-1, 8, 9};
  double line2_end[3] = {1, -3, -4};
#  endif

#  if 0 /* point to line case */
  double line2_start[3] = {3, 4, 5};
  double line2_end[3] = {3, 4, 5};
  double line1_start[3] = {-1, 8, 9};
  double line1_end[3] = {1, -3, -4};
#  endif

#  if 0 /* point to line case */
  double line2_start[3] = {3, 4, 5};
  double line2_end[3] = {3, 4, 5};
  double line1_start[3] = {-1, 8, 9};
  double line1_end[3] = {-1, 8, 9};
#  endif

#  if 0
  double line1_start[3] = {256.062, 328.674, 67.9029};
  double line1_end[3] = {246.162, 330.078, 67.9896};
  double line2_start[3] = {262.368, 336.609, 68.3076};
  double line2_end[3] = {259.956, 326.944, 67.4325};
#  endif

  int cond;
  double dist = Geo3d_Lineseg_Lineseg_Dist(line1_start, line1_end, 
					   line2_start, line2_end, 
					   &mu1, &mu2, &cond);
  printf("%d, %g\n", cond, dist);

  dist = Geo3d_Line_Line_Dist(line1_start, line1_end, line2_start, line2_end);

  printf("%g\n", dist);
#endif

#if 1
  double *d = Unifrnd_Double_Array(12000000, NULL);
  double *d2 = Unifrnd_Double_Array(12000000, NULL);
  tic();
  Rotate_XZ(d, d, 4000000, 0.1, 0.2, 1);
  printf("%llu\n", toc());
  tic();
  Rotate_XZ2(d, d, 4000000, 0.1, 0.2, 0);
  printf("%llu\n", toc());

#endif

#if 0
  double d[3] = {0.1, 0.2, 0.3};
  Rotate_XZ(d, d, 1, 0.1, 0.2, 0);
  darray_print2(d, 3, 1);
#endif

#if 0
  printf("%g\n", Ellipse_Point_Distance(5, 5, 3, 5));
#endif

#if 0
  Geo3d_Ellipse *ellipse = New_Geo3d_Ellipse();
  ellipse->scale = 0.5;
  ellipse->orientation[0] = 1.0;
  Print_Geo3d_Ellipse(ellipse);

  FILE *fp = fopen("../data/test.swc", "w");
  Swc_Node node;
  
  Geo3d_Ellipse_To_Swc_Node(ellipse, 1, -1, 1.0, 2, &node);
  Swc_Node_Fprint(fp, &node);  
  
  /*
  double pt[3] = {0.0, 0.0, 1.0};
  printf("%g\n", Geo3d_Ellipse_Point_Distance(ellipse, pt));
  */
  
  Geo3d_Ellipse *ellipse2 = Copy_Geo3d_Ellipse(ellipse);
  ellipse2->center[0] += 10.0;
  ellipse2->orientation[0] = 2.0;
  ellipse2->radius += 3.0;

  Geo3d_Ellipse *ellipse3 = Geo3d_Ellipse_Interpolate(ellipse, ellipse2, 0.2,
						      NULL);
  Geo3d_Ellipse_To_Swc_Node(ellipse3, 2, 1, 1.0, 2, &node);
  Swc_Node_Fprint(fp, &node);

  Geo3d_Ellipse_To_Swc_Node(ellipse2, 3, 2, 1.0, 2, &node);
  Swc_Node_Fprint(fp, &node);

  Print_Geo3d_Ellipse(ellipse3);

  fclose(fp);
#endif

#if 0
  Geo3d_Ellipse *ellipse = New_Geo3d_Ellipse();
  ellipse->scale = 0.5;

  FILE *fp = fopen("../data/test.swc", "w");
  coordinate_3d_t *pts = Geo3d_Ellipse_Sampling(ellipse, 20, 0, NULL);
  Geo3d_Point_Array_Swc_Fprint(fp, pts, 20, 1, -1, 1.0, 2);

  ellipse->orientation[0] = 1.0;
  pts = Geo3d_Ellipse_Sampling(ellipse, 20, 0, NULL);
  Geo3d_Point_Array_Swc_Fprint(fp, pts, 20, 21, -1, 1.0, 3);

  ellipse->center[2] = 5.0;
  pts = Geo3d_Ellipse_Sampling(ellipse, 20, 0, NULL);
  Geo3d_Point_Array_Swc_Fprint(fp, pts, 20, 41, -1, 1.0, 4);

  coordinate_3d_t vec[2];
  Coordinate_3d_Copy(vec[0], ellipse->center);
  Geo3d_Ellipse_First_Vector(ellipse, vec[1]);
  Coordinate_3d_Add(vec[0], vec[1], vec[1]);
  Geo3d_Point_Array_Swc_Fprint(fp, vec, 2, 101, -1, 1.0, 5);
 
  Geo3d_Ellipse_Second_Vector(ellipse, vec[1]);
  Coordinate_3d_Add(vec[0], vec[1], vec[1]);
  Geo3d_Point_Array_Swc_Fprint(fp, vec, 2, 111, -1, 1.0, 6);
 
  Geo3d_Ellipse_Normal_Vector(ellipse, vec[1]);
  Coordinate_3d_Add(vec[0], vec[1], vec[1]);
  Geo3d_Point_Array_Swc_Fprint(fp, vec, 2, 121, -1, 1.0, 7);
 
  fclose(fp);
#endif

#if 0
  Geo3d_Ellipse ep_array[10];

  Geo3d_Ellipse *ellipse = New_Geo3d_Ellipse();
  ellipse->scale = 0.5;

  Geo3d_Ellipse_Copy(ep_array, ellipse);

  FILE *fp = fopen("../data/test.swc", "w");

  ellipse->orientation[0] += 0.5;
  ellipse->center[2] += 3.0;
  ellipse->center[0] += 1.0;
  Geo3d_Ellipse_Copy(ep_array + 1, ellipse);

  ellipse->center[2] += 3.0;
  Geo3d_Ellipse_Copy(ep_array + 2, ellipse);

  coordinate_3d_t *pts = Geo3d_Ellipse_Array_Sampling(ep_array, 3, 20, NULL);
  Geo3d_Point_Array_Swc_Fprint(fp, pts, 60, 1, -1, 1.0, 2);

  fclose(fp);
#endif

#if 0
  printf("%g\n", Vector_Angle(1.0, 1.0) * 180 / TZ_PI);
#endif

#if 0
  double theta, psi;
  coordinate_3d_t coord;
  coord[0] = 0.0822;
  coord[1] = 0.1515;
  coord[2] = 0.1369;
  Geo3d_Coord_Orientation(coord[0], coord[1], coord[2], &theta, &psi);
  printf("%g, %g\n", theta, psi);

  Geo3d_Orientation_Normal(theta, psi, coord, coord+1, coord+2); 
  Print_Coordinate_3d(coord);
#endif

#if 0
  double theta, psi;
  double x = -1;
  double y = 1.83697019872103e-16;
  double z = 3;
  
  Geo3d_Coord_Orientation(x, y, z, &theta, &psi);
#endif

#if 0
  double theta = Vector_Angle2(0, 1, 1, 0, TRUE);
  printf("angle: %g\n", theta);

  theta = Vector_Angle2(0, 1, -1, 0, FALSE);
  printf("angle: %g\n", theta);

  theta = Vector_Angle2(-1, 0, -1, -1, TRUE);
  printf("angle: %g\n", theta);
#endif

  return 0;
}