Authored by David Mayerich
1 parent 4df9ec0e

### cleaned up the stim::network comparison calculation

Showing 2 changed files with 72 additions and 28 deletions
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 resample(T spacing=25.0) 464 + stim::fiber resample(T spacing) 465 465 { 466 466 467 467 ... ... @@ -473,7 +473,7 @@ public: 473 473 std::vector > fiberPositions = centerline(); 474 474 std::vector > 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::resample()); //call the fiber->edge constructor 47 + edge e(fiber::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 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 networkTruth, float sigma){ 278 + float compare(stim::network 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 > 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 > 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 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 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 fiberMetric(A.edges()); // allocate space for accumulating fiber metric as each fiber is evaluated 294 341 stim::fiber 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 > 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 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 ... ...