Exemplo n.º 1
0
ZSwcPath ZNeuronTracer::trace(double x, double y, double z)
{
  if (m_traceWorkspace->trace_mask == NULL) {
    m_traceWorkspace->trace_mask =
        C_Stack::make(GREY, C_Stack::width(m_stack), C_Stack::height(m_stack),
                      C_Stack::depth(m_stack));
    Zero_Stack(m_traceWorkspace->trace_mask);
  }

  double pos[3];
  pos[0] = x;
  pos[1] = y;
  pos[2] = z;

  Local_Neuroseg *locseg = New_Local_Neuroseg();
  Set_Neuroseg(&(locseg->seg), 3.0, 0.0, 11.0, TZ_PI_4, 0.0, 0.0, 0.0, 1.0);

  Set_Neuroseg_Position(locseg, pos, NEUROSEG_CENTER);

  Locseg_Fit_Workspace *ws =
      (Locseg_Fit_Workspace*) m_traceWorkspace->fit_workspace;
  Local_Neuroseg_Optimize_W(locseg, m_stack, 1.0, 1, ws);

  Trace_Record *tr = New_Trace_Record();
  tr->mask = ZERO_BIT_MASK;
  Trace_Record_Set_Fix_Point(tr, 0.0);
  Trace_Record_Set_Direction(tr, DL_BOTHDIR);
  Locseg_Node *p = Make_Locseg_Node(locseg, tr);
  Locseg_Chain *locseg_chain = Make_Locseg_Chain(p);

  Trace_Workspace_Set_Trace_Status(m_traceWorkspace, TRACE_NORMAL,
                                   TRACE_NORMAL);
  Trace_Locseg(m_stack, 1.0, locseg_chain, m_traceWorkspace);
  Locseg_Chain_Remove_Overlap_Ends(locseg_chain);
  Locseg_Chain_Remove_Turn_Ends(locseg_chain, 1.0);

  int n;
  Geo3d_Circle *circles =
      Locseg_Chain_To_Geo3d_Circle_Array(locseg_chain, NULL, &n);

  ZSwcPath path;
  for (int i = 0; i < n; ++i) {
    Swc_Tree_Node *tn = SwcTreeNode::makePointer(circles[i].center[0],
        circles[i].center[1], circles[i].center[2], circles[i].radius);
    if (!path.empty()) {
      SwcTreeNode::setParent(tn, path.back());
    }
    path.push_back(tn);
  }

  return path;
}
Exemplo n.º 2
0
void Trace_Evaluate_Seed(const Geo3d_Scalar_Field *seed,
                         const Stack *signal, double z_scale,
                         Trace_Evaluate_Seed_Workspace *ws)
{
    OBJECT_SAFE_FREE(ws->score, free);
    ws->score = darray_malloc(seed->size);

    int i;
    OBJECT_SAFE_FREE(ws->locseg, free);
    ws->locseg = (Local_Neuroseg *) malloc(seed->size * sizeof(Local_Neuroseg));

    ws->nseed = seed->size;

    int index = 0;

    if (ws->base_mask == NULL) {
        ws->base_mask = Make_Stack(GREY, signal->width, signal->height,
                                   signal->depth);
        Zero_Stack(ws->base_mask);
    }

    for (i = 0; i < seed->size; i++) {
        printf("-----------------------------> seed: %d / %d\n", i, seed->size);

        index = i;
        int x = (int) seed->points[index][0];
        int y = (int) seed->points[index][1];
        int z = (int) seed->points[index][2];

        if (ws->zshift) {
            stack_adjust_zpos(signal, x, y, &z);
            if (ws->trace_mask != NULL) {
                if (Stack_Pixel(ws->trace_mask, x, y, z, 0) > 0.0) {
                    printf("traced**\n");
                    ws->score[i] = 0.0;
                    continue;
                }
            }
        }

        double width = seed->values[index];

        int seed_offset = Stack_Util_Offset(x, y, z, signal->width, signal->height,
                                            signal->depth);

        if (width < 3.0) {
            width += 0.5;
        }
        Set_Neuroseg(&(ws->locseg[i].seg), width, 0.0, NEUROSEG_DEFAULT_H,
                     0.0, 0.0, 0.0, 0.0, 1.0);

        double cpos[3];
        cpos[0] = x;
        cpos[1] = y;
        cpos[2] = z;
        cpos[2] /= z_scale;

        Set_Neuroseg_Position(&(ws->locseg[i]), cpos, NEUROSEG_CENTER);

        if (ws->base_mask->array[seed_offset] > 0) {
            printf("labeled\n");
            ws->score[i] = 0.0;
            continue;
        }

        {   /* for faster evaluation*/
            Local_Neuroseg *locseg = ws->locseg + i;
            Stack_Fit_Score fs;
            fs.n = 1;
            fs.options[0] = STACK_FIT_CORRCOEF;

            Locseg_Fit_Workspace *fw = (Locseg_Fit_Workspace*) ws->fws;

            int k;
            for (k = 0; k < fw->pos_adjust; k++) {
                Local_Neuroseg_Position_Adjust(locseg, signal, z_scale);
            }

            Local_Neuroseg_Orientation_Search_C(locseg, signal, z_scale, &fs);

            if (ws->fit_option <= 1) {
                for (k = 0; k < 3; k++) {
                    Local_Neuroseg_Position_Adjust(locseg, signal, z_scale);
                }
            }

            double bpos[3];
            double tpos[3];
            Local_Neuroseg_Bottom(locseg, bpos);
            Local_Neuroseg_Center(locseg, cpos);
            Local_Neuroseg_Top(locseg, tpos);
            if (ws->trace_mask != NULL) {
                if ((Stack_Pixel(ws->trace_mask, bpos[0], bpos[1], bpos[2], 0) > 0) &&
                        (Stack_Pixel(ws->trace_mask, cpos[0], cpos[1], cpos[2], 0) > 0) &&
                        (Stack_Pixel(ws->trace_mask, tpos[0], tpos[1], tpos[2], 0) > 0)) {
                    printf("traced*\n");
                    ws->score[i] = 0.0;
                    continue;
                }
            }

            if ((ws->fit_option == 1) || (ws->fit_option == 2)) {
                Local_Neuroseg_R_Scale_Search(locseg, signal, z_scale, 1.0, 10.0, 1.0,
                                              0.5, 5.0, 0.5, NULL);
            }

            Fit_Local_Neuroseg_W(locseg, signal, z_scale, fw);
        }

        if (ws->trace_mask != NULL) {
            if (Local_Neuroseg_Hit_Mask(ws->locseg + i,
                                        ws->trace_mask, z_scale) > 0) {
                printf("traced\n");
                ws->score[i] = 0.0;
                continue;
            }
        }

        //ws->score[i] = Local_Neuroseg_Score(ws->locseg + i, signal, z_scale, &fs);
        ws->score[i] = ws->fws->sws->fs.scores[1];

        printf("%g\n", ws->score[i]);

        if (Local_Neuroseg_Good_Score(ws->locseg + i, ws->score[i], ws->min_score)
                == TRUE) {
            Local_Neuroseg_Label_G(ws->locseg + i, ws->base_mask, -1, 2, z_scale);
        } else {
            Local_Neuroseg_Label_G(ws->locseg + i, ws->base_mask, -1, 1, z_scale);
        }
    }
}
Exemplo n.º 3
0
Stack* ZNeuronTraceSeeder::sortSeed(
    Geo3d_Scalar_Field *seedPointArray, const Stack *signal, Trace_Workspace *ws)
{
  Locseg_Fit_Workspace *fws = (Locseg_Fit_Workspace *) ws->fit_workspace;
  fws->sws->fs.n = 2;
  fws->sws->fs.options[0] = STACK_FIT_DOT;
  fws->sws->fs.options[1] = STACK_FIT_CORRCOEF;
  fws->pos_adjust = 1;

  m_seedArray.resize(seedPointArray->size);
  m_seedScoreArray.resize(seedPointArray->size);

  /* <seed_mask> allocated */
  Stack *seed_mask = C_Stack::make(GREY, signal->width, signal->height,
                                   signal->depth);
  Zero_Stack(seed_mask);

  for (int i = 0; i < seedPointArray->size; i++) {
    printf("-----------------------------> seed: %d / %d\n", i,
           seedPointArray->size);

    int index = i;
    int x = (int) seedPointArray->points[index][0];
    int y = (int) seedPointArray->points[index][1];
    int z = (int) seedPointArray->points[index][2];

    double width = seedPointArray->values[index];

    ssize_t seed_offset = C_Stack::offset(x, y, z, signal->width, signal->height,
                                          signal->depth);

    if (width < 3.0) {
      width += 0.5;
    }
    Set_Neuroseg(&(m_seedArray[i].seg), width, 0.0, NEUROSEG_DEFAULT_H,
                 0.0, 0.0, 0.0, 0.0, 1.0);

    double cpos[3];
    cpos[0] = x;
    cpos[1] = y;
    cpos[2] = z;
    //cpos[2] /= z_scale;

    Set_Neuroseg_Position(&(m_seedArray[i]), cpos, NEUROSEG_CENTER);

    if (seed_mask->array[seed_offset] > 0) {
      printf("labeled\n");
      m_seedScoreArray[i] = 0.0;
      continue;
    }

    //Local_Neuroseg_Optimize(locseg + i, signal, z_scale, 0);
    double z_scale = 1.0;
    Local_Neuroseg_Optimize_W(&(m_seedArray[i]), signal, z_scale, 0, fws);

    m_seedScoreArray[i] = fws->sws->fs.scores[1];

    double min_score = ws->min_score;

    if (m_seedScoreArray[i] > min_score) {
      Local_Neuroseg_Label_G(&(m_seedArray[i]), seed_mask, -1, 2, z_scale);
    } else {
      Local_Neuroseg_Label_G(&(m_seedArray[i]), seed_mask, -1, 1, z_scale);
    }
  }

  /* <seed_mask> freed */
//  C_Stack::kill(seed_mask);

  return seed_mask;
}
Exemplo n.º 4
0
ZSwcPath ZNeuronTracer::trace(double x, double y, double z)
{
  setTraceScoreThreshold(TRACING_INTERACTIVE);

  if (m_traceWorkspace->trace_mask == NULL) {
    m_traceWorkspace->trace_mask =
        C_Stack::make(GREY, getStack()->width(), getStack()->height(),
                      getStack()->depth());
    Zero_Stack(m_traceWorkspace->trace_mask);
  }

  Stack *stackData = getIntensityData();

  ZIntPoint stackOffset = getStack()->getOffset();

  double pos[3];
  pos[0] = x - stackOffset.getX();
  pos[1] = y - stackOffset.getY();
  pos[2] = z - stackOffset.getZ();

  /* alloc <locseg> */
  Local_Neuroseg *locseg = New_Local_Neuroseg();
  Set_Neuroseg(&(locseg->seg), 3.0, 0.0, 11.0, TZ_PI_4, 0.0, 0.0, 0.0, 1.0);

  Set_Neuroseg_Position(locseg, pos, NEUROSEG_CENTER);

  Locseg_Fit_Workspace *ws =
      (Locseg_Fit_Workspace*) m_traceWorkspace->fit_workspace;
  Local_Neuroseg_Optimize_W(locseg, stackData, 1.0, 1, ws);

  Trace_Record *tr = New_Trace_Record();
  tr->mask = ZERO_BIT_MASK;
  Trace_Record_Set_Fix_Point(tr, 0.0);
  Trace_Record_Set_Direction(tr, DL_BOTHDIR);
  /* consume <locseg> */
  Locseg_Node *p = Make_Locseg_Node(locseg, tr);

  /* alloc <locseg_chain> */
  Locseg_Chain *locseg_chain = Make_Locseg_Chain(p);

  Trace_Workspace_Set_Trace_Status(m_traceWorkspace, TRACE_NORMAL,
                                   TRACE_NORMAL);
  Trace_Locseg(stackData, 1.0, locseg_chain, m_traceWorkspace);
  Locseg_Chain_Remove_Overlap_Ends(locseg_chain);
  Locseg_Chain_Remove_Turn_Ends(locseg_chain, 1.0);

  int n;
  /* alloc <circles> */
  Geo3d_Circle *circles =
      Locseg_Chain_To_Geo3d_Circle_Array(locseg_chain, NULL, &n);

  /* free <locseg_chain> */
  Kill_Locseg_Chain(locseg_chain);

  ZSwcPath path;
  if (n > 0) {
//    bool hit = false;
    int start = 0;
    int end = n;
    if (Trace_Workspace_Mask_Value(m_traceWorkspace, circles[0].center) > 0) {
      for (int i = 1; i < n; ++i) {
        start = i - 1;
        if (Trace_Workspace_Mask_Value(m_traceWorkspace, circles[i].center) == 0) {
          break;
        }
      }
    }

    if (n > 1) {
      if (Trace_Workspace_Mask_Value(m_traceWorkspace, circles[n - 1].center) > 0) {
        for (int i = n - 2; i >= 0; --i) {
          end = i + 2;
          if (Trace_Workspace_Mask_Value(m_traceWorkspace, circles[i].center) == 0) {
            break;
          }
        }
      }
    }

    for (int i = start; i < end; ++i) {
      Swc_Tree_Node *tn = SwcTreeNode::makePointer(circles[i].center[0],
          circles[i].center[1], circles[i].center[2], circles[i].radius);
      if (!path.empty()) {
        SwcTreeNode::setParent(tn, path.back());
      }
      SwcTreeNode::translate(tn, stackOffset);
      path.push_back(tn);
    }
  }

  /* free <circles> */
  if (circles != NULL) {
    free(circles);
  }

  return path;
}
Exemplo n.º 5
0
int main(int argc, char* argv[])
{
  if (Show_Version(argc, argv, "1.00") == 1) {
    return 0;
  }

  static char *Spec[] = {
    " <image:string> -s <string> -o <string> [-e <string>] [-fo <int>] "
    "[-z <double> | -res <string>] [-field <int>] [-min_score <double>]",
    NULL};
  
  Process_Arguments(argc, argv, Spec, 1);
  
  Geo3d_Scalar_Field *seed = Read_Geo3d_Scalar_Field(Get_String_Arg("-s"));

  size_t idx;
  double max_r = darray_max(seed->values, seed->size, &idx);

  max_r *= 1.5;

  //Set_Neuroseg_Max_Radius(max_r);

  Stack *signal = Read_Stack_U(Get_String_Arg("image"));

  dim_type dim[3];
  dim[0] = signal->width;
  dim[1] = signal->height;
  dim[2] = signal->depth;

  Rgb_Color color;
  Set_Color(&color, 255, 0, 0);

  int seed_offset = -1;

  double z_scale = 1.0;

  if (Is_Arg_Matched("-res")) {
    if (fexist(Get_String_Arg("-res"))) {
      double res[3];
      int length;
      darray_read2(Get_String_Arg("-res"), res, &length);
      if (res[0] != res[1]) {
	perror("Different X-Y resolutions.");
	TZ_ERROR(ERROR_DATA_VALUE);
      }
      z_scale = res[0] / res[2] * 2.0;
    }
  }
  
  if (Is_Arg_Matched("-z")) {
    z_scale = Get_Double_Arg("-z");
  }

  printf("z scale: %g\n", z_scale);

  tic();


  double *values = darray_malloc(seed->size);

  int i;
  Local_Neuroseg *locseg = (Local_Neuroseg *) 
    malloc(seed->size * sizeof(Local_Neuroseg));


  int index = 0;

  //int ncol = LOCAL_NEUROSEG_NPARAM + 1 + 23;
  //double *features = darray_malloc(seed->size * ncol);
  //double *tmpfeats = features;

  Stack *seed_mask = Make_Stack(GREY, signal->width, signal->height, 
				signal->depth);
  Zero_Stack(seed_mask);

  Locseg_Fit_Workspace *fws = New_Locseg_Fit_Workspace();
  
  if (Is_Arg_Matched("-field")) {
    fws->sws->field_func = Neuroseg_Slice_Field_Func(Get_Int_Arg("-field"));
  }

  fws->sws->fs.n = 2;
  fws->sws->fs.options[0] = STACK_FIT_DOT;
  fws->sws->fs.options[1] = STACK_FIT_CORRCOEF;

  if (Is_Arg_Matched("-fo")) {
    fws->sws->fs.options[1] = Get_Int_Arg("-fo");
  }

  for (i = 0; i < seed->size; i++) {
    printf("-----------------------------> seed: %d / %d\n", i, seed->size);

    index = i;
    int x = (int) seed->points[index][0];
    int y = (int) seed->points[index][1];
    int z = (int) seed->points[index][2];

    double width = seed->values[index];

    seed_offset = Stack_Util_Offset(x, y, z, signal->width, signal->height,
				    signal->depth);

    if (width < 3.0) {
      width += 0.5;
    }
    Set_Neuroseg(&(locseg[i].seg), width, 0.0, NEUROSEG_DEFAULT_H, 
		 0.0, 0.0, 0.0, 0.0, 1.0);

    double cpos[3];
    cpos[0] = x;
    cpos[1] = y;
    cpos[2] = z;
    cpos[2] /= z_scale;
    
    Set_Neuroseg_Position(&(locseg[i]), cpos, NEUROSEG_CENTER);

    if (seed_mask->array[seed_offset] > 0) {
      printf("labeled\n");
      values[i] = 0.0;
      continue;
    }

    //Local_Neuroseg_Optimize(locseg + i, signal, z_scale, 0);
    Local_Neuroseg_Optimize_W(locseg + i, signal, z_scale, 0, fws);

    values[i] = fws->sws->fs.scores[1];
    /*
    Stack_Fit_Score fs;
    fs.n = 1;
    fs.options[0] = 1;
    values[i] = Local_Neuroseg_Score(locseg + i, signal, z_scale, &fs);
    */

    //values[i] = Local_Neuroseg_Score_W(locseg + i, signal, z_scale, sws);

    printf("%g\n", values[i]);

    double min_score = LOCAL_NEUROSEG_MIN_CORRCOEF;
    if (Is_Arg_Matched("-min_score")) {
      min_score = Get_Double_Arg("-min_score");
    }

    if (values[i] > min_score) {
      Local_Neuroseg_Label_G(locseg + i, seed_mask, -1, 2, z_scale);
    } else {
      Local_Neuroseg_Label_G(locseg + i, seed_mask, -1, 1, z_scale);
    }

    /*
    tmpfeats += Local_Neuroseg_Param_Array(locseg + i, z_scale, tmpfeats);
    
    tmpfeats += Local_Neuroseg_Stack_Feature(locseg + i, signal, z_scale, 
					     tmpfeats); 
    */
  }

  if (Is_Arg_Matched("-e")) {
    Write_Stack(Get_String_Arg("-e"), seed_mask);
  }
  Write_Local_Neuroseg_Array(Get_String_Arg("-o"), locseg, seed->size);

  char file_path[MAX_PATH_LENGTH];
  sprintf(file_path, "%s_score", Get_String_Arg("-o"));
  darray_write(file_path, values, seed->size);

  //sprintf(file_path, "%s_feat", Get_String_Arg("-o"));
  //darray_write(file_path, features, seed->size * ncol); 

  Kill_Geo3d_Scalar_Field(seed);

  printf("Time passed: %lld\n", toc());

  
  return 0;
}
Exemplo n.º 6
0
/*
 * trace_neuron - trace neuron from given seeds
 *
 * trace_neuron [!wtr] seed_file -Dsave_dir
 *   -r: write intermediate results
 *
 */
int main(int argc, char* argv[])
{
  static char *Spec[] = {
    "[!wtr] [-canvas <string>] [-mask <string>] [-res <string>] [-minr <int>]",
    "-minlen <double>",
    " <image:string> -S<string> -D<string>",
    NULL};
  
  Process_Arguments(argc, argv, Spec, 1);
  
  char *dir = Get_String_Arg("-D");
  
  char file_path[100];
  sprintf(file_path, "%s/%s", dir, Get_String_Arg("-S"));
  printf("%s\n", file_path);

  Geo3d_Scalar_Field *seed = Read_Geo3d_Scalar_Field(file_path);

  int idx;

  sprintf(file_path, "%s/%s.bn", dir, "max_r");
  double max_r;
  int tmp;
  if (fexist(file_path)) {
    darray_read2(file_path, &max_r, &tmp);
  } else {
    max_r = darray_max(seed->values, seed->size, &idx);
  }

  printf("%g\n", max_r);

  max_r *= 1.5;

  /*
  sprintf(file_path, "%s/%s", dir, "soma0.bn");
  if (!fexist(file_path)) {
    max_r *= 2.0;
  }
  */
   
  Set_Neuroseg_Max_Radius(max_r);

  Stack *signal = Read_Stack(Get_String_Arg("image"));

  dim_type dim[3];
  dim[0] = signal->width;
  dim[1] = signal->height;
  dim[2] = signal->depth;
  /* 
  IMatrix *chord = Make_IMatrix(dim, 3);
  
  Stack *code = Make_Stack(GREY16, 
			   signal->width, signal->height, signal->depth);
  */
  Rgb_Color color;
  Set_Color(&color, 255, 0, 0);

  Stack *canvas = NULL;

  char trace_file_path[100];
  sprintf(trace_file_path, "%s/%s", dir, Get_String_Arg("-canvas"));
  
  if (fexist(trace_file_path) == 1) {
    canvas = Read_Stack((char *) trace_file_path);
  } else {
    canvas = Copy_Stack(signal);
    Stretch_Stack_Value_Q(canvas, 0.999);
    Translate_Stack(canvas, COLOR, 1);
  }

  Stack *traced = NULL;
  
  char trace_mask_path[100];
  sprintf(trace_mask_path, "%s/%s", dir, Get_String_Arg("-mask"));

  if (fexist(trace_mask_path) == 1) {
    traced = Read_Stack((char *) trace_mask_path);
  } else {
    traced = Make_Stack(GREY, signal->width, signal->height, signal->depth);
    One_Stack(traced);
  }
  

  //Object_3d *obj = NULL;
  int seed_offset = -1;

  Neurochain *chain = NULL;

  double z_scale = 1.0;

  if (Is_Arg_Matched("-res")) {
    sprintf(file_path, "%s", Get_String_Arg("-res"));

    if (fexist(file_path)) {
      double res[3];
      int length;
      darray_read2(file_path, res, &length);
      if (res[0] != res[1]) {
	perror("Different X-Y resolutions.");
	TZ_ERROR(ERROR_DATA_VALUE);
      }
      z_scale = res[0] / res[2];
    }
  }

  //sprintf(file_path, "%s/%s", dir, Get_String_Arg("-M"));
  //Stack *stack = Read_Stack(file_path);

  tic();

  FILE *fp = NULL;
  char chain_file_path[100];
  char vrml_file_path[100];

  double min_chain_length = 25.0;

  if (Is_Arg_Matched("-minlen")) {
    min_chain_length = Get_Double_Arg("-minlen");
  }

  int *indices = iarray_malloc(seed->size);
  double *values = darray_malloc(seed->size);
  int i;

  Local_Neuroseg *locseg = (Local_Neuroseg *) 
    malloc(seed->size * sizeof(Local_Neuroseg));

  int index = 0;
  for (i = 0; i < seed->size; i++) {
    printf("-----------------------------> seed: %d / %d\n", i, seed->size);
    indices[i] = i;
    index = i;
    int x = (int) seed->points[index][0];
    int y = (int) seed->points[index][1];
    int z = (int) seed->points[index][2];

    double width = seed->values[index];

    chain = New_Neurochain();

    seed_offset = Stack_Util_Offset(x, y, z, signal->width, signal->height,
				    signal->depth);

    if (width < 3.0) {
      width += 0.5;
    }
    Set_Neuroseg(&(locseg[i].seg), width, width, 12.0, 
		 0.0, 0.0, 0.0);

    double cpos[3];
    cpos[0] = x;
    cpos[1] = y;
    cpos[2] = z;
    cpos[2] *= z_scale;
    
    Set_Neuroseg_Position(&(locseg[i]), cpos, NEUROSEG_CENTER);
    Stack_Fit_Score fs;
    fs.n = 1;
    fs.options[0] = 1;
    values[i] = Local_Neuroseg_Orientation_Search_C(&(locseg[i]), signal, z_scale, &fs);
  }

  darray_qsort(values, indices, seed->size);

  /*
  for (i = 0; i < seed->size; i++) {
    indices[i] = i;
  }
  darraycpy(values, seed->values, 0, seed->size);
  darray_qsort(values, indices, seed->size);
  */

  int counter = 0;

  //  for (i = seed->size - 1; i >= seed->size - 231; i--) {
  for (i = seed->size - 1; i >= 0; i--) {
    index = indices[i];

    printf("-----------------------------> seed: %d / %d\n", i, seed->size);
    
    sprintf(chain_file_path, "%s/chain%d.bn", dir, index);
    sprintf(vrml_file_path, "%s/chain%d.wrl", dir, index);

    if (fexist(chain_file_path) == 1) {
      chain = Read_Neurochain(chain_file_path);
      if (Neurochain_Geolen(chain) >= min_chain_length) {
	Write_Neurochain_Vrml(vrml_file_path, chain);
	Neurochain_Label(canvas, chain, z_scale);
	Neurochain_Erase_E(traced, chain, z_scale, 0,
			   Neurochain_Length(chain, FORWARD),
			   1.5, 0.0);
      }

      Free_Neurochain(chain);
      printf("chain exists\n");
      continue;
    }
    
    
    int x = (int) seed->points[index][0];
    int y = (int) seed->points[index][1];
    int z = (int) seed->points[index][2];

    if (*STACK_PIXEL_8(traced, x, y, z, 0) == 0) {
      printf("traced \n");
      continue;
    }

    double width = seed->values[index];

    if (width > max_r) {
      printf("too thick\n");
      continue;
    }
    
    if (Is_Arg_Matched("-minr")) {
      int max_level = (int) (width + 0.5);
      if (max_level <= Get_Int_Arg("-minr")) {
	printf("too thin\n");
	continue;
      }
    }
    /*
    seed_offset = Stack_Util_Offset(x, y, z, signal->width, signal->height,
				    signal->depth);
    */

    chain = New_Neurochain();
    /*
    Stack_Level_Code_Constraint(stack, code, chord->array, &seed_offset, 1, 
				max_level + 1);

    Voxel_t v;
    v[0] = x;
    v[1] = y;
    v[2] = z;

    Stack *tmp_stack = Copy_Stack(stack);
    obj = Stack_Grow_Object_Constraint(tmp_stack, 1, v, chord, code, 
				       max_level);
    Free_Stack(tmp_stack);

    Print_Object_3d_Info(obj);
    
    double vec[3];
    Object_3d_Orientation_Zscale(obj, vec, MAJOR_AXIS, z_scale);

    double theta, psi;
    Geo3d_Vector obj_vec;
    Set_Geo3d_Vector(&obj_vec, vec[0], vec[1], vec[2]);

    Geo3d_Vector_Orientation(&obj_vec, &theta, &psi);
    */

    /*
    if (width < 3.0) {
      width += 0.5;
    }
    Set_Neuroseg(&(chain->locseg.seg), width, width, 12.0, 
		 0.0, 0.0, 0.0);

    double cpos[3];
    cpos[0] = x;
    cpos[1] = y;
    cpos[2] = z;
    cpos[2] *= z_scale;
    
    //Set_Neuroseg_Position(&(chain->locseg), cpos, NEUROSEG_BOTTOM);
    Set_Neuroseg_Position(&(chain->locseg), cpos, NEUROSEG_CENTER);
    Stack_Fit_Score fs;
    fs.n = 1;
    fs.options[0] = 1;
    Local_Neuroseg_Orientation_Search_C(&(chain->locseg), signal, z_scale,
					&fs); 
    //fs.options[0] = 1;
    */

    Copy_Local_Neuroseg(&(chain->locseg), &(locseg[index]));
    Neurochain *chain_head = chain;
    
    
    if (Initialize_Tracing(signal, chain, NULL, z_scale) >= MIN_SCORE) {
      if ((Neuroseg_Hit_Traced(&(chain->locseg), traced, z_scale) == FALSE) &&
	  (chain->locseg.seg.r1 < max_r) && 
	  (chain->locseg.seg.r2 < max_r)) {
	//Initialize_Tracing(signal, chain, NULL, z_scale);
	chain = Trace_Neuron2(signal, chain, BOTH, traced, z_scale, 500);

	//Neurochain *chain_head = Neurochain_Head(chain);
	chain_head = Neurochain_Remove_Overlap_Segs(chain);
	chain_head = Neurochain_Remove_Turn_Ends(chain_head, 0.5);
	/*
	if (i == seed->size - 231) {
	  Print_Neurochain(chain_head);
	}
	*/

	fp = fopen(chain_file_path, "w");
	Neurochain_Fwrite(chain_head, fp);
	fclose(fp);
	if (Neurochain_Geolen(chain_head) >= min_chain_length) {
	  Write_Neurochain_Vrml(vrml_file_path, chain_head);

	  Neurochain_Erase_E(traced, chain_head, z_scale, 0,
			     Neurochain_Length(chain_head, FORWARD),
			     1.5, 0.0);
	  Neurochain_Label(canvas, chain_head, z_scale);

	  counter += Neurochain_Length(chain_head, FORWARD);
	  if (counter > 500) {
	    if (Is_Arg_Matched("-r")) {
	      Write_Stack((char *) trace_mask_path, traced);
	    }
	    
	    if (Is_Arg_Matched("-r")) {
	    Write_Stack((char *) trace_file_path, canvas);
	    }

	    counter = 0;
	  }
	}
      }
    }

    Free_Neurochain(chain_head);

    //Kill_Object_3d(obj);
  }

  Write_Stack((char *) trace_file_path, canvas);
  if (Is_Arg_Matched("-r")) {
    Write_Stack((char *) trace_mask_path, traced);
  }

  Kill_Geo3d_Scalar_Field(seed);

  printf("Time passed: %lld\n", toc());

  
  return 0;
}