Commit 52cb8dfd2dc3f38bd35a6860afad2f86f4ec5f53

Authored by pranathivemuri
1 parent 1c3c8f1a

added function to resample a fiber in the network, adding resampled edges to the network

Showing 1 changed file with 132 additions and 88 deletions   Show diff stats
stim/visualization/network.h
... ... @@ -14,7 +14,6 @@
14 14 #include <ANN/ANN.h>
15 15 #include <boost/tuple/tuple.hpp>
16 16  
17   -#define multfactor 2.51
18 17  
19 18 namespace stim{
20 19 /** This is the a class that interfaces with gl_spider in order to store the currently
... ... @@ -171,10 +170,13 @@ class network{
171 170 edges_to_str()
172 171 {
173 172 std::ostringstream ss;
  173 + std::cout<<"here"<<std::endl;
174 174 // ss << "[";
175 175 for(int i = 0; i < edges.size()-1; i++)
176 176 {
  177 + std::cout<<"here"<<i<<std::endl;
177 178 ss << edges[i] << ";";
  179 + std::cout<<edges.size()-1<<std::endl;
178 180 }
179 181 ss << edges[edges.size()-1];
180 182 // ss << "]";
... ... @@ -187,6 +189,8 @@ class network{
187 189  
188 190 std::vector<edge*> E; //list of pointers to edges.
189 191 std::vector<node> V; //list of nodes.
  192 + std::vector< stim::vec<T> > allVerticesList; // all nodes before sampling
  193 + std::vector<stim::vec<T> > allVerticesAfterSampling ; //all vertices after sampling
190 194  
191 195 ///Returns the number of edges in the network.
192 196 unsigned int
... ... @@ -201,7 +205,11 @@ class network{
201 205 {
202 206 return V.size();
203 207 }
204   -
  208 + unsigned int
  209 + sizeAfterSamplingV()
  210 + {
  211 + return allVerticesAfterSampling.size();
  212 + }
205 213 /* //adds an edge from two std::vectors with positions and radii.
206 214 void
207 215 addEdge(std::vector< stim::vec<T> > pos, std::vector<stim::vec<T> > radii, int endId)
... ... @@ -500,7 +508,7 @@ class network{
500 508 totalEdges()
501 509 {
502 510 int totalEdgeVertices=0;int N=0;
503   - for (int i=0; i < sizeE(); i ++)
  511 + for (unsigned int i=0; i < sizeE(); i ++)
504 512 {// FOR N points on the fiber N-1 edges are possible
505 513 N = E[i]->n_pts();
506 514 totalEdgeVertices = totalEdgeVertices + N- 1;
... ... @@ -512,46 +520,13 @@ class network{
512 520 lengthOfNetwork()
513 521 {
514 522 float networkLength=0;float N=0;
515   - for (int i=0; i < sizeE(); i ++)
  523 + for (unsigned int i=0; i < sizeE(); i ++)
516 524 {
517 525 N = E[i]->length();
518 526 networkLength = networkLength + N;
519 527 }
520 528 return networkLength;
521 529 }
522   - /// get index of a node on a fiber
523   - // by matching the node on fiber to already set vertices (both strings)
524   - // used in obj file conversion
525   - int
526   - getIndexes(std::string* input, std::string searched, int sizeV)
527   - {
528   - int result = 0;
529   - for (int i = 0; i < sizeV; i++)
530   - {
531   - if (input[i] == searched)
532   - {
533   - result = i + 1;
534   - }
535   - }
536   - return result;
537   - }
538   - // strObj returns a string of fiber indices corresponding to vectors of positions in the fiber including intermediate nodes
539   - std::string
540   - strObj(std::string* strArray, int sizeV)
541   - {
542   - std::stringstream ss;
543   - std::stringstream oss;
544   - for(unsigned int i = 0; i < N; i++)
545   - {
546   - ss.str(std::string());
547   - for(unsigned int d = 0; d < 3; d++)
548   - {
549   - ss<<c[i][d];
550   - }
551   - oss<<getIndexes(strArray, ss.str(), sizeV)<<" ";
552   - }
553   - return oss.str();
554   - }
555 530 ///@param i: index of the required fiber.
556 531 ///Returns an std::vector with the centerline of the ith fiber in the edgelist.
557 532 std::vector< stim::vec<T> >
... ... @@ -584,6 +559,7 @@ class network{
584 559 objToNetwork(stim::obj<T> objInput)
585 560 {
586 561 stim::network<T> nwc;
  562 + //network network2;
587 563 // function to convert an obj file loaded using stim/visualization/obj.h
588 564 // to a 3D network class using network.h methods.
589 565 std::vector< stim::vec<T> > fiberPositions; //initialize positions on the fiber to be added to network
... ... @@ -595,7 +571,8 @@ class network{
595 571 // using addNode function for adding nodes
596 572 // and the line as an edge(belongs to fiber class) using addEdge function
597 573 std::vector<unsigned> vertexIndices(objInput.numV());
598   - std::vector< stim::vec<T> > allVerticesList = objInput.getAllV(vertexIndices);
  574 + std::vector< stim::vec<T> > vertices = objInput.getAllV(vertexIndices);
  575 + nwc.addVertices(vertices);
599 576 for (unsigned i =1; i< objInput.numL() + 1; i++)
600 577 {
601 578 // edges/fibers could be added to the network class
... ... @@ -630,28 +607,33 @@ class network{
630 607 {
631 608 fiberPositions1 = fiberPositions;
632 609 }
633   - std::vector<T> radii(numPointsOnFiber); // allocating radii to zero
634 610 // then add edge
635   - // edge* a = new edge(fiberPositions1,radii);
636   - //E.push_back(a);
637   - nwc.addEdge(fiberPositions1, radii);
  611 + //edge* a = new edge(fiberPositions1,radii);
  612 + //std::cout<<"here"<<std::endl;
  613 + //E.push_back(a);
  614 + std::vector<stim::vec<T> > newPointList;
  615 + newPointList = Resample(fiberPositions1);
  616 + int numPointsOnnewFiber = newPointList.size();
  617 + nwc.addVerticesAfterSamplimg(newPointList);
  618 + std::vector<T> radii(numPointsOnnewFiber); // allocating radii to zero
  619 + nwc.addEdge(newPointList, radii);
638 620 // add nodes
639 621 stim::vec<T> v0(3);stim::vec<T> vN(3);
640   - int endId = numPointsOnFiber -1;
641   - v0[0] = fiberPositions1[0][0];v0[1] = fiberPositions1[0][1];v0[2] = fiberPositions1[0][2];
642   - vN[0] = fiberPositions1[endId][0];vN[1] = fiberPositions1[endId][1];vN[2] = fiberPositions1[endId][2];
  622 + int endId = numPointsOnnewFiber -1;
  623 + v0[0] = newPointList[0][0];v0[1] = newPointList[0][1];v0[2] = newPointList[0][2];
  624 + vN[0] = newPointList[endId][0];vN[1] = newPointList[endId][1];vN[2] = newPointList[endId][2];
643 625 // VISITED INDEXES OF the nodes are set to true
644   - if(!validList[objInput.getIndex(allVerticesList, v0)])
  626 + if(!validList[objInput.getIndex(vertices, v0)])
645 627 {
646 628 //V.push_back(node(v0));
647 629 nwc.addNode(v0);
648   - validList[objInput.getIndex(allVerticesList, v0)] = true;
  630 + validList[objInput.getIndex(vertices, v0)] = true;
649 631 }
650   - if(!validList[objInput.getIndex(allVerticesList, vN)])
  632 + if(!validList[objInput.getIndex(vertices, vN)])
651 633 {
652 634 //V.push_back(node(vN));
653 635 nwc.addNode(vN);
654   - validList[objInput.getIndex(allVerticesList, vN)] = true;
  636 + validList[objInput.getIndex(vertices, vN)] = true;
655 637 }
656 638 }
657 639 return nwc;
... ... @@ -672,6 +654,7 @@ class network{
672 654 kdTree2 = generateKdTreeFromNetwork(network2);
673 655 std::cout<<"Test Network:network and kdtree generated"<<std::endl;
674 656 return boost::make_tuple(kdTree1, kdTree2, network1, network2);
  657 + std::cout<<"out of this loop"<<std::endl;
675 658 }
676 659 //distance between two points
677 660 double dist(std::vector<T> p0, std::vector<T> p1)
... ... @@ -686,7 +669,7 @@ class network{
686 669 double sum(stim::vec<T> metricList)
687 670 {
688 671 float sumMetricList = 0;
689   - for (int count=0; count<metricList.size(); count++)
  672 + for (unsigned int count=0; count<metricList.size(); count++)
690 673 { sumMetricList += metricList[count];}
691 674 return sumMetricList;
692 675 }
... ... @@ -694,21 +677,22 @@ class network{
694 677 ANNkd_tree*
695 678 generateKdTreeFromNetwork(stim::network<T> network) //kd-tree stores all points in the fiber for fast searching
696 679 {
  680 + std::cout<<"kd trees generated"<<std::endl;
697 681 ANNkd_tree* kdt;
698 682 double **c; //centerline (array of double pointers)
699 683 float* r; // array of fiber radii
700   - unsigned int n_data = network.sizeV(); //set the number of points
  684 + unsigned int n_data = network.sizeAfterSamplingV(); //set the number of points
701 685 c = (double**) malloc(sizeof(double*) * n_data); //allocate the array pointer
702 686 for(unsigned int i = 0; i < n_data; i++) //allocate space for each point
703 687 {c[i] = (double*) malloc(sizeof(double) * 3);}
704 688 r = (float*) malloc(sizeof(float) * n_data); //allocate space for the radii
705   - stim::vec<T> node;
706   - for(int i = 0; i < n_data; i++)
  689 + //stim::vec<T> node;
  690 + for(unsigned int i = 0; i < n_data; i++)
707 691 {
708   - node = network.V[i].getPosition();
  692 + //node = network.V[i].getPosition();
709 693 //convert_to_double
710 694 for(unsigned int d = 0; d < 3; d++){ //for each dimension
711   - c[i][d] = double(node[d]); //copy the coordinate
  695 + c[i][d] = double(network.allVerticesAfterSampling[i][d]); //copy the coordinate
712 696 }
713 697 r[i] = r[i]; //copy the radius
714 698 }
... ... @@ -731,54 +715,38 @@ class network{
731 715 {
732 716 V.push_back(nodes);
733 717 }
734   - ///exports the graph.
735 718 void
736   - to_csv()
  719 + addVertices(std::vector< stim::vec<T> > vertices)
737 720 {
738   - std::ofstream ofs;
739   - ofs.open("Graph.csv", std::ofstream::out | std::ofstream::app);
740   - for(int i = 0; i < V.size(); i++)
  721 + for (unsigned int i=0; i < vertices.size(); i ++)
741 722 {
742   - ofs << V[i].edges_to_str() << "\n";
  723 + allVerticesList.push_back(vertices[i]);
743 724 }
744   - ofs.close();
745 725 }
746   -
747   - ///exports the graph.
748 726 void
749   - to_gdf()
  727 + addVerticesAfterSamplimg(std::vector< stim::vec<T> > vertices)
750 728 {
751   - std::ofstream ofs;
752   - ofs.open("Graph.gdf", std::ofstream::out | std::ofstream::app);
753   - ofs << "nodedef>name VARCHAR\n";
754   - for(int i = 0; i < V.size(); i++)
  729 + for (unsigned int i=0; i < vertices.size(); i ++)
755 730 {
756   - ofs << i << "\n";
  731 + allVerticesAfterSampling.push_back(vertices[i]);
757 732 }
758   - ofs << "edgedef>Nodes[1] VARCHAR, Nodes[2] VARCHAR, weight INT, length FLOAT, av_radius FLOAT \n";
759   - for(int i = 0; i < E.size(); i++)
760   - {
761   - ofs << E[i]->Nodes[1] << "," << E[i]->Nodes[2] << "," <<E[i]->n_pts()
762   - << ","<< E[i]->length() << "," << E[i]->average_radius() << "\n";
763   - }
764   - ofs.close();
765 733 }
766 734 // gaussian function
767 735 float gaussianFunction(float x, float std=25)
768 736 {
769   - float normalization = multfactor * std;
770   - float evaluate = 1.0 - (exp(-x/(2*std*std)));
  737 + float evaluate = 1.0f - ((exp(-x/(2*std*std))));
771 738 return evaluate;
772 739 }
  740 + // compares point on a network to a kd tree for two skeletons
773 741 boost::tuple< float, float >
774   - compareSkeletons(boost::tuple< ANNkd_tree*, ANNkd_tree*, stim::network<int>, stim::network<int> > networkKdtree)
  742 + compareSkeletons(boost::tuple< ANNkd_tree*, ANNkd_tree*, stim::network<float>, stim::network<float> > networkKdtree)
775 743 {
776 744 float gFPR, gFNR;
777 745 gFPR = CompareNetKD(networkKdtree.get<0>(), networkKdtree.get<3>());
778 746 gFNR = CompareNetKD(networkKdtree.get<1>(), networkKdtree.get<2>());
779 747 return boost::make_tuple(gFPR, gFNR);
780 748 }
781   - // gaussian distance of points on network to Kdtree
  749 + // gaussian distance of points on network to Kdtree
782 750 float
783 751 CompareNetKD(ANNkd_tree* kdTreeGroundtruth, stim::network<T> networkTruth)
784 752 {
... ... @@ -793,14 +761,14 @@ class network{
793 761 float totalNetworkLength = networkTruth.lengthOfNetwork();
794 762 stim::vec<float> fiberMetric(networkTruth.sizeE());
795 763 //for each fiber
796   - for (unsigned i=0; i < networkTruth.sizeE(); i ++)
  764 + for (unsigned int i=0; i < networkTruth.sizeE(); i ++)
797 765 {
798 766 std::vector<T> p1(3); std::vector<T> p2(3);//temporary variables to store point positions
799 767 fiberPoints = networkTruth.E[i]->centerline();
800 768 N = networkTruth.E[i]->n_pts();
801 769 stim::vec<float> segmentMetric(N-1);
802 770 // for each segment in the fiber
803   - for (unsigned j = 0; j < N - 1; j++)
  771 + for (unsigned int j = 0; j < N - 1; j++)
804 772 {
805 773 ANNpoint queryPt1; queryPt1 = annAllocPt(3);
806 774 ANNpoint queryPt2; queryPt2 = annAllocPt(3);
... ... @@ -814,14 +782,56 @@ class network{
814 782 }
815 783 kdTreeGroundtruth->annkSearch( queryPt1, 1, nnIdx1, dists1, eps); // error bound
816 784 kdTreeGroundtruth->annkSearch( queryPt2, 1, nnIdx2, dists2, eps); // error bound
817   - float dist1 = gaussianFunction(dists1[0]);float dist2 = gaussianFunction(dists2[0]);
  785 + std::cout<<float(dists1[0])<<"dist1-----"<<float(dists2[0])<<"dist2---"<<std::endl;
  786 + float dist1 = gaussianFunction(float(dists1[0]));float dist2 = gaussianFunction(float(dists2[0]));
818 787 segmentMetric[j] = (((dist1 + dist2) / 2) * dist(p1, p2)) ;
819 788 }
820   - fiberMetric[i] = sum(segmentMetric);
  789 + fiberMetric[i] = sum(segmentMetric)/;
821 790 }
822 791 netmetsMetric = sum(fiberMetric)/totalNetworkLength ;
823 792 return netmetsMetric;
824 793 }
  794 + //resample a fiber in the network
  795 + std::vector<stim::vec<T> > Resample(std::vector< stim::vec<T> > fiberPositions, float spacing=25.0)
  796 + {
  797 + std::vector<T> p1(3), p2(3), v(3);
  798 + stim::vec<T> p(3);
  799 + std::vector<stim::vec<T> > newPointList;
  800 + for(unsigned int f=0; f<fiberPositions.size()-1; f++)
  801 + {
  802 + T lengthSegment = dist(p1,p2);
  803 + for(int d=0; d<3;d++)
  804 + {
  805 + p1[d] = T(fiberPositions[f][d]);
  806 + p2[d] = T(fiberPositions[f + 1][d]);
  807 + }// for each dimension
  808 + if( lengthSegment >= spacing )
  809 + { for (int dim=0; dim<3;dim++) //find the direction of travel
  810 + {v[dim] = p2[dim] - p1[dim];}
  811 + //set the step size to the voxel size
  812 + T step;
  813 + for(step=0.0; step<lengthSegment; step+=spacing)
  814 + {
  815 + for(int i=0; i<3;i++)
  816 + {p[i] = p1[i] + v[i]*(step/lengthSegment);}
  817 + newPointList.push_back(p);
  818 + }
  819 + }
  820 + else
  821 + newPointList = fiberPositions;
  822 + }
  823 + return newPointList;
  824 + }
  825 + // modulus of a vector
  826 + T
  827 + Length(std::vector<T> v)
  828 + {
  829 + T sum=0;
  830 + for (int i=0; i<v.size(); i++)
  831 + sum += v[i] * v[i];
  832 + return sum;
  833 + }
  834 + // function to remove characters from a string
825 835 void removeCharsFromString(std::string &str, char* charsToRemove ) {
826 836 for ( unsigned int i = 0; i < strlen(charsToRemove); ++i ) {
827 837 str.erase( remove(str.begin(), str.end(), charsToRemove[i]), str.end() );
... ... @@ -833,9 +843,9 @@ class network{
833 843 {
834 844 std::ofstream ofs;
835 845 ofs.open("Graph.obj", std::ofstream::out | std::ofstream::app);
836   - int num = V.size();
837   - string *strArray = new string[num];
838   - for(int i = 0; i < allVerticesList.size(); i++)
  846 + int num = allVerticesList.size();
  847 + std::string *strArray = new std::string[num];
  848 + for(unsigned int i = 0; i < allVerticesList.size(); i++)
839 849 {
840 850 std::string str;
841 851 str = allVerticesList[i].str();
... ... @@ -848,10 +858,44 @@ class network{
848 858 {
849 859 std::string str;
850 860 str = E[i]->strObj(strArray, num);
  861 + //removeCharsFromString(str,"0");
851 862 ofs << "l " << str << "\n";
852 863 }
853 864 ofs.close();
854 865 }
  866 + ///exports the graph.
  867 + void
  868 + to_csv()
  869 + {
  870 + std::ofstream ofs;
  871 + ofs.open("Graph.csv", std::ofstream::out | std::ofstream::app);
  872 + std::cout<<"here"<<std::endl;
  873 + for(int i = 0; i < V.size(); i++)
  874 + {
  875 + std::cout<<"here"<<i<<std::endl;
  876 + ofs << V[i].edges_to_str() << "\n";
  877 + }
  878 + ofs.close();
  879 + }
  880 + ///exports the graph.
  881 + void
  882 + to_gdf()
  883 + {
  884 + std::ofstream ofs;
  885 + ofs.open("Graph.gdf", std::ofstream::out | std::ofstream::app);
  886 + ofs << "nodedef>name VARCHAR\n";
  887 + for(int i = 0; i < V.size(); i++)
  888 + {
  889 + ofs << i << "\n";
  890 + }
  891 + ofs << "edgedef>Nodes[1] VARCHAR, Nodes[2] VARCHAR, weight INT, length FLOAT, av_radius FLOAT \n";
  892 + for(int i = 0; i < E.size(); i++)
  893 + {
  894 + ofs << E[i]->Nodes[1] << "," << E[i]->Nodes[2] << "," <<E[i]->n_pts()
  895 + << ","<< E[i]->length() << "," << E[i]->average_radius() << "\n";
  896 + }
  897 + ofs.close();
  898 + }
855 899  
856 900 };
857 901 };
... ...