Commit 797f8ab070316a36aac3ed211e6f5c6532590443

Authored by David Mayerich
1 parent 4df9ec0e

cleaned up the stim::network comparison calculation

Showing 2 changed files with 72 additions and 28 deletions   Show diff stats
stim/biomodels/fiber.h
... ... @@ -444,7 +444,7 @@ public:
444 444 return ss.str();
445 445 }
446 446 /// Returns the number of centerline points in the fiber
447   - unsigned int n_pts(){
  447 + unsigned int size(){
448 448 return N;
449 449 }
450 450  
... ... @@ -461,7 +461,7 @@ public:
461 461 return get_vec(N-1);
462 462 }
463 463 ////resample a fiber in the network
464   - stim::fiber<T> resample(T spacing=25.0)
  464 + stim::fiber<T> resample(T spacing)
465 465 {
466 466  
467 467  
... ... @@ -473,7 +473,7 @@ public:
473 473 std::vector<stim::vec<T> > fiberPositions = centerline();
474 474 std::vector<stim::vec<T> > newPointList; // initialize list of new resampled points on the fiber
475 475 // for each point on the centerline (skip if it is the last point on centerline)
476   - unsigned int N = fiberPositions.size(); // number of points on the fiber
  476 + //unsigned int N = fiberPositions.size(); // number of points on the fiber
477 477 for(unsigned int f=0; f< N-1; f++)
478 478 {
479 479  
... ...
stim/biomodels/network.h
... ... @@ -44,7 +44,7 @@ class network{
44 44  
45 45 /// Resamples an edge by calling the fiber resampling function
46 46 edge resample(T spacing){
47   - edge e(fiber<T>::resample()); //call the fiber->edge constructor
  47 + edge e(fiber<T>::resample(spacing)); //call the fiber->edge constructor
48 48 e.v[0] = v[0]; //copy the vertex data
49 49 e.v[1] = v[1];
50 50  
... ... @@ -238,10 +238,13 @@ class network{
238 238  
239 239  
240 240 // total number of points on all fibers after resampling -- function used only on a resampled network
241   - unsigned int total_points(){
242   - unsigned int n = points_afterResampling().size();
  241 + unsigned total_points(){
  242 + unsigned n = 0;
  243 + for(unsigned e = 0; e < E.size(); e++)
  244 + n += E[e].size();
  245 + //unsigned int n = points_afterResampling().size();
243 246 return n;
244   - }
  247 + }
245 248  
246 249 // gaussian function
247 250 float gaussianFunction(float x, float std=25){ return exp(-x/(2*std*std));} // by default std = 25
... ... @@ -264,40 +267,84 @@ class network{
264 267 return sqrt(sum);
265 268 }
266 269  
  270 + void stim2ann(ANNpoint &a, stim::vec<T> b){
  271 + a[0] = b[0];
  272 + a[1] = b[1];
  273 + a[2] = b[2];
  274 + }
  275 +
267 276  
268 277 /// This function compares two networks and returns a metric
269   - float compare(stim::network<T> networkTruth, float sigma){
  278 + float compare(stim::network<T> A, float sigma){
270 279 float metric = 0.0; // initialize metric to be returned after comparing the networks
271 280 ANNkd_tree* kdt; // initialize a pointer to a kd tree
272 281 double **c; // centerline (array of double pointers) - points on kdtree must be double
273 282 unsigned int n_data = total_points(); // set the number of points
274 283 c = (double**) malloc(sizeof(double*) * n_data); // allocate the array pointer
275 284 for(unsigned int i = 0; i < n_data; i++) // allocate space for each point of 3 dimensions
276   - {c[i] = (double*) malloc(sizeof(double) * 3);}
277   - std::vector<stim::vec<T> > pointsVector = points_afterResampling(); //get vertices in the network after resampling
278   - for(unsigned int i = 0; i < n_data; i++) // loop through all the vertices after resampling
279   - {
280   - for(unsigned int d = 0; d < 3; d++){ // for each dimension
281   - c[i][d] = double(pointsVector[i][d]); // copy the coordinate and convert_to_double
  285 + c[i] = (double*) malloc(sizeof(double) * 3);
  286 + //std::vector<stim::vec<T> > pointsVector = points_afterResampling(); //get vertices in the network after resampling
  287 + unsigned t = 0;
  288 + for(unsigned e = 0; e < E.size(); e++){ //for each edge in the network
  289 + for(unsigned p = 0; p < E[e].size(); p++){ //for each point in the edge
  290 + for(unsigned d = 0; d < 3; d++){ //for each coordinate
  291 +
  292 + c[t][d] = E[e][p][d];
282 293 }
  294 + t++;
283 295 }
  296 + }
  297 +
284 298 ANNpointArray pts = (ANNpointArray)c; // create an array of data points of type double
285 299 kdt = new ANNkd_tree(pts, n_data, 3); // build a KD tree using the annpointarray
286 300 double eps = 0; // error bound
287   - ANNdistArray dists1;dists1 = new ANNdist[1]; // near neighbor distances
288   - ANNdistArray dists2; dists2 = new ANNdist[1]; // near neighbor distances
289   - ANNidxArray nnIdx1; nnIdx1 = new ANNidx[1]; // near neighbor indices // allocate near neigh indices
290   - ANNidxArray nnIdx2; nnIdx2 = new ANNidx[1]; // near neighbor indices // allocate near neigh indices
291   - int N; // number of points on the fiber in the second network
292   - float totalNetworkLength = networkTruth.lengthOfNetwork();
293   - stim::vec<float> fiberMetric(networkTruth.edges()); // allocate space for accumulating fiber metric as each fiber is evaluated
  301 + ANNdistArray dists = new ANNdist[1]; // near neighbor distances
  302 + ANNidxArray nnIdx = new ANNidx[1]; // near neighbor indices // allocate near neigh indices
  303 +
  304 + stim::vec<T> p0, p1;
  305 + float m0, m1;
  306 + float M = 0; //stores the total metric value
  307 + float l; //stores the segment length
  308 + float L = 0; //stores the total network length
  309 + ANNpoint queryPt = annAllocPt(3);
  310 + for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in A
  311 + M = 0; //total metric value for the fiber
  312 + p0 = A.E[e][0]; //get the first point in the edge
  313 + stim2ann(queryPt, p0);
  314 + kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network
  315 + m0 = 1.0f - gaussianFunction(dists[0], sigma); //calculate the metric value based on the distance
  316 +
  317 + for(unsigned p = 1; p < A.E[e].size(); p++){ //for each point in the edge
  318 +
  319 + p1 = A.E[e][p]; //get the next point in the edge
  320 + stim2ann(queryPt, p1);
  321 + kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network
  322 + m1 = 1.0f - gaussianFunction(dists[0], sigma); //calculate the metric value based on the distance
  323 +
  324 + //average the metric and scale
  325 + l = (p1 - p0).len(); //calculate the length of the segment
  326 + L += l; //add the length of this segment to the total network length
  327 + M += (m0 + m1)/2 * l; //scale the metric based on segment length
  328 +
  329 + //swap points
  330 + p0 = p1;
  331 + m0 = m1;
  332 + }
  333 + }
  334 +
  335 + return M/L;
  336 +
  337 +
  338 + /*int N; // number of points on the fiber in the second network
  339 + float totalNetworkLength = A.lengthOfNetwork();
  340 + stim::vec<float> fiberMetric(A.edges()); // allocate space for accumulating fiber metric as each fiber is evaluated
294 341 stim::fiber<T> FIBER; // Initialize a fiber will be used in calculating the metric
295 342 //for each fiber in the second network, find nearest distance in the kd tree
296   - for (unsigned int i=0; i < networkTruth.edges(); i ++) // loop through all the edges/fibers in the network
  343 + for (unsigned int i=0; i < A.edges(); i ++) // loop through all the edges/fibers in the network
297 344 {
298   - FIBER = networkTruth.get_fiber(i); // Get the fiber corresponding to the index i
  345 + FIBER = A.get_fiber(i); // Get the fiber corresponding to the index i
299 346 std::vector< stim::vec<T> > fiberPoints = FIBER.centerline(); // Get the points on the fiber
300   - N = FIBER.n_pts(); // number of points on the fiber
  347 + N = FIBER.size(); // number of points on the fiber
301 348 stim::vec<float> segmentMetric(N-1); // allocate space for a vec array that stores metric for each segmen in the fiber
302 349 // for each segment in the fiber
303 350 for (unsigned j = 0; j < N - 1; j++)
... ... @@ -317,15 +364,12 @@ class network{
317 364 float error1 = 1.0f - gaussianFunction(float(dists1[0]), sigma);float error2 = 1.0f - gaussianFunction(float(dists2[0]), sigma);
318 365 // average the error and scale it with distance between the points
319 366 segmentMetric[j] = ((error1 + error2) / 2) * dist(p1, p2) ;
320   - /*segmentDists[j] = dist(p1, p2); */
321 367 }
322 368 fiberMetric[i] = sum(segmentMetric);
323   - /*distsList[i] = sum(segmentDists);*/
324 369 }
325   - /*assert (sum(distsList)==totalNetworkLength);*/
326 370 metric = sum(fiberMetric)/totalNetworkLength; //normalize the scaled error of all the points with total length of the network
327 371 assert (0<=metric <=1); //assert metroc os always less than or equal to one and greater than or equal to zero
328   - return metric;
  372 + return metric;*/
329 373 }
330 374 }; //end stim::network class
331 375 }; //end stim namespace
... ...