Commit eb119a4f8520f37c648a94435f159c025a4b2743

Authored by Pavel Govyadinov
1 parent 9f5c0d4a

renamed fiber into centerline and removed all of the radius information from fiber.

Showing 1 changed file with 0 additions and 483 deletions   Show diff stats
stim/biomodels/fiber.h deleted
1   -#ifndef STIM_FIBER_H
2   -#define STIM_FIBER_H
3   -
4   -#include <vector>
5   -#include <ANN/ANN.h>
6   -
7   -namespace stim{
8   -
9   -/** This class stores information about a single fiber represented as a set of geometric points
10   - * between two branch or end points. This class is used as a fundamental component of the stim::network
11   - * class to describe an interconnected (often biological) network.
12   - */
13   -template<typename T>
14   -class fiber{
15   -
16   -protected:
17   - unsigned int N; //number of points in the fiber
18   - double **c; //centerline (array of double pointers)
19   -
20   - T* r; // array of fiber radii
21   - ANNkd_tree* kdt; //kd-tree stores all points in the fiber for fast searching
22   -
23   - /// Initialize an empty fiber
24   - void init()
25   - {
26   - kdt = NULL;
27   - c=NULL;
28   - r=NULL;
29   - N=0;
30   - }
31   -
32   - /// Initialize a fiber with N centerline points (all located at [0, 0, 0] with radius 0)
33   - void init(unsigned int n)
34   - {
35   -
36   - N = n; //set the number of points
37   - kdt = NULL;
38   - c = (double**) malloc(sizeof(double*) * N); //allocate the array pointer
39   -
40   - for(unsigned int i = 0; i < N; i++) //allocate space for each point
41   - c[i] = (double*) malloc(sizeof(double) * 3);
42   -
43   - r = (T*) malloc(sizeof(T) * N); //allocate space for the radii
44   - }
45   -
46   - /// Copies an existing fiber to the current fiber
47   -
48   - /// @param cpy stores the new copy of the fiber
49   - void copy( const stim::fiber<T>& cpy ){
50   -
51   - ///allocate space for the new fiber
52   - init(cpy.N);
53   -
54   - ///copy the points
55   - for(unsigned int i = 0; i < N; i++){
56   - for(unsigned int d = 0; d < 3; d++) //for each dimension
57   - c[i][d] = cpy.c[i][d]; //copy the coordinate
58   -
59   - r[i] = cpy.r[i]; //copy the radius
60   - }
61   -
62   - gen_kdtree(); //generate the kd tree for the new fiber
63   - }
64   -
65   - /// generate a KD tree for points on fiber
66   - void gen_kdtree()
67   - {
68   - int n_data = N; //create an array of data points
69   - ANNpointArray pts = (ANNpointArray)c; //cast the centerline list to an ANNpointArray
70   - kdt = new ANNkd_tree(pts, n_data, 3); //build a KD tree
71   - }
72   -
73   - /// find distance between two points
74   - double dist(double* p0, double* p1){
75   -
76   - double sum = 0; // initialize variables
77   - float v;
78   - for(unsigned int d = 0; d < 3; d++)
79   - {
80   - v = p1[d] - p0[d];
81   - sum +=v * v;
82   -
83   - }
84   - return sqrt(sum);
85   - }
86   -
87   - /// This function retreives the index for the fiber point closest to q
88   -
89   - /// @param q is a reference point used to find the closest point on the fiber center line
90   - unsigned int ann( stim::vec<double> q ){
91   -
92   - ANNidxArray idx = new ANNidx[1]; //variable used to hold the nearest point
93   - ANNdistArray sq_dist = new ANNdist[1]; //variable used to hold the squared distance to the nearest point
94   -
95   - kdt->annkSearch(q.data(), 1, idx, sq_dist); //search the KD tree for the nearest neighbor
96   -
97   - return *idx;
98   - }
99   -
100   - /// Returns a stim::vec representing the point at index i
101   -
102   - /// @param i is an index of the desired centerline point
103   - stim::vec<T> get_vec(unsigned i){
104   - stim::vec<T> r;
105   - r.resize(3);
106   - r[0] = c[i][0];
107   - r[1] = c[i][1];
108   - r[2] = c[i][2];
109   -
110   - return r;
111   - }
112   -
113   -
114   -public:
115   -
116   - fiber(){
117   - init();
118   - }
119   -
120   - /// Copy constructor
121   - fiber(const stim::fiber<T> &obj){
122   -
123   - copy(obj);
124   -
125   - }
126   -
127   - //temp constructor for graph visualization
128   - fiber(int n)
129   - {
130   - init(n);
131   - }
132   -
133   - /// Constructor takes a list of stim::vec points, the radius at each point is set to zero
134   - fiber(std::vector< stim::vec<T> > p){
135   - init(p.size()); //initialize the fiber
136   -
137   - //for each point, set the centerline position and radius
138   - for(unsigned int i = 0; i < N; i++){
139   -
140   - //set the centerline position
141   - for(unsigned int d = 0; d < 3; d++)
142   - c[i][d] = (double) p[i][d];
143   -
144   - //set the radius
145   - r[i] = 0;
146   - }
147   -
148   - //generate a kd tree
149   - gen_kdtree();
150   - }
151   -
152   - /// constructor takes a list of points and radii
153   - fiber(std::vector< stim::vec< T > > pos, std::vector< T > radii){
154   - init(pos.size()); //initialize the fiber
155   -
156   - //for each point, set the centerline position and radius
157   - for(unsigned int i = 0; i < N; i++){
158   -
159   - //set the centerline position
160   - for(unsigned int d = 0; d < 3; d++)
161   - c[i][d] = (double) pos[i][d];
162   -
163   - //set the radius
164   - r[i] = radii[i];
165   - }
166   -
167   - //generate a kd tree
168   - gen_kdtree();
169   - }
170   -
171   - /// constructor takes an array of points and radii
172   - // this function is used when the radii are represented as a stim::vec,
173   - // since this may be easier when importing OBJs
174   - fiber(std::vector< stim::vec<T> > pos, std::vector< stim::vec<T> > radii){
175   -
176   - init(pos.size());
177   -
178   - //for each point, set the position and radius
179   - for(unsigned int i = 0; i < N; i++){
180   - //at(i) = (double*)malloc(sizeof(double) * 3);
181   - for(unsigned int d = 0; d < 3; d++)
182   - c[i][d] = (double) pos[i][d];
183   -
184   - r[i] = radii[i][(unsigned int)0];
185   - }
186   -
187   - gen_kdtree();
188   - }
189   -
190   - /// Assignment operation
191   - fiber& operator=(const fiber &rhs){
192   -
193   - if(this == &rhs) return *this; //test for and handle self-assignment
194   -
195   - copy(rhs);
196   - }
197   -
198   - /// Calculate the length of the fiber and return it.
199   - double length(){
200   -
201   - double* p0;
202   - double *p1;
203   - double l = 0; //initialize the length to zero
204   -
205   - //for each point
206   - //typename std::list< point<T> >::iterator i; //create a point iterator
207   - for(unsigned int i = 0; i < N; i++){ //for each point in the fiber
208   -
209   - if(i == 0) //if this is the first point, just store it
210   - p1 = c[0];
211   - else{ //if this is any other point
212   - p0 = p1; //shift p1->p0
213   - p1 = c[i]; //set p1 to the new point
214   - l += dist(p0, p1); //add the length of p1 - p0 to the running sum
215   - }
216   - }
217   -
218   - return l; //return the length
219   - }
220   -
221   - /// Calculates the length and average radius of the fiber
222   -
223   - /// @param length is filled with the fiber length
224   - T radius(T& length){
225   -
226   - double* p0; //temporary variables to store point positions
227   - double* p1;
228   - T r0, r1; //temporary variables to store radii at points
229   - double l;
230   - T r_mean; //temporary variable to store the length and average radius of a fiber segment
231   - double length_sum = 0; //initialize the length to zero
232   - T radius_sum = 0; //initialize the radius sum to zero
233   -
234   - //for each point
235   - //typename std::list< point<T> >::iterator i; //create a point iterator
236   - for(unsigned int i = 0; i < N; i++){ //for each point in the fiber
237   -
238   - if(i == 0){ //if this is the first point, just store it
239   - p1 = c[0];
240   - r1 = r[0];
241   - }
242   - else{ //if this is any other point
243   - p0 = p1; //shift p1->p0 and r1->r0
244   - r0 = r1;
245   - p1 = c[i]; //set p1 to the new point
246   - r1 = r[i];
247   -
248   - l = dist(p0, p1); //calculate the length of the p0-p1 segment
249   - r_mean = (r0 + r1) / 2; //calculate the average radius of the segment
250   -
251   - radius_sum += r_mean * (T) l; //add the radius scaled by the length to a running sum
252   - length_sum += l; //add the length of p1 - p0 to the running sum
253   - }
254   - }
255   -
256   - length = length_sum; //store the total length
257   -
258   - //if the total length is zero, store a radius of zero
259   - if(length == 0)
260   - return 0;
261   - else
262   - return (T)(radius_sum / length); //return the average radius of the fiber
263   - }
264   - T average_radius()
265   - {
266   - T r_sum = 0.;
267   - for(unsigned int i = 0; i < N; i++)
268   - {
269   - r_sum = r_sum + r[i];
270   - }
271   - return r_sum/((T) N);
272   - }
273   -
274   - /// Calculates the average radius of the fiber
275   - T radius(){
276   - T length;
277   - return radius(length);
278   - }
279   -
280   - /// Returns the radius at index idx.
281   - T radius(int idx){
282   - return r[idx];
283   - }
284   -
285   - /// Return the point on the fiber closest to q
286   - /// @param q is the query point used to locate the nearest point on the fiber centerline
287   - stim::vec<T> nearest(stim::vec<T> q){
288   -
289   - stim::vec<double> temp( (double) q[0], (double) q[1], (double) q[2]);
290   -
291   - unsigned int idx = ann(temp); //determine the index of the nearest neighbor
292   -
293   - return stim::vec<T>((T) c[idx][0], (T) c[idx][1], (T) c[idx][2]); //return the nearest centerline point
294   - }
295   -
296   - /// Return the point index on the fiber closest to q
297   - /// @param q is the query point used to locate the nearest point on the fiber centerline
298   - unsigned int nearest_idx(stim::vec<T> q){
299   -
300   - stim::vec<double> temp((double) q[0], (double) q[1], (double) q[2]);
301   -
302   - unsigned int idx = ann(temp); //determine the index of the nearest neighbor
303   -
304   - return idx; //return the nearest centerline point index
305   - }
306   -
307   - /// Returns the fiber centerline as an array of stim::vec points
308   - std::vector< stim::vec<T> > centerline(){
309   -
310   - //create an array of stim vectors
311   - std::vector< stim::vec<T> > pts(N);
312   -
313   - //cast each point to a stim::vec, keeping only the position information
314   - for(unsigned int i = 0; i < N; i++)
315   - pts[i] = stim::vec<T>((T) c[i][0], (T) c[i][1], (T) c[i][2]);
316   -
317   - //return the centerline array
318   - return pts;
319   - }
320   -
321   - /// Returns the fiber centerline magnitudes as an array of stim::vec points
322   - std::vector< stim::vec<T> > centerlinemag(){
323   -
324   - //create an array of stim vectors
325   - std::vector< stim::vec<T> > pts(N);
326   -
327   - //cast each point to a stim::vec, keeping only the position information
328   - for(unsigned int i = 0; i < N; i++)
329   - pts[i] = stim::vec<T>(r[i], r[i]);;
330   -
331   - //return the centerline array
332   - return pts;
333   - }
334   -
335   - /// Split the fiber at the specified index. If the index is an end point, only one fiber is returned
336   - std::vector< stim::fiber<T> > split(unsigned int idx){
337   -
338   - std::vector< stim::fiber<T> > fl; //create an array to store up to two fibers
339   -
340   - //if the index is an end point, only the existing fiber is returned
341   - if(idx == 0 || idx == N-1){
342   - fl.resize(1); //set the size of the fiber to 1
343   - fl[0] = *this; //copy the current fiber
344   - }
345   -
346   - //if the index is not an end point
347   - else{
348   -
349   - unsigned int N1 = idx + 1; //calculate the size of both fibers
350   - unsigned int N2 = N - idx;
351   -
352   - fl.resize(2); //set the array size to 2
353   -
354   - fl[0].init(N1); //set the size of each fiber
355   - fl[1].init(N2);
356   -
357   - //copy both halves of the fiber
358   - unsigned int i, d;
359   -
360   - //first half
361   - for(i = 0; i < N1; i++){ //for each centerline point
362   - for(d = 0; d < 3; d++)
363   - fl[0].c[i][d] = c[i][d]; //copy each coordinate
364   - fl[0].r[i] = r[i]; //copy the corresponding radius
365   - }
366   -
367   - //second half
368   - for(i = 0; i < N2; i++){
369   - for(d = 0; d < 3; d++)
370   - fl[1].c[i][d] = c[idx + i][d];
371   - fl[1].r[i] = r[idx + i];
372   - }
373   - }
374   -
375   - return fl; //return the array
376   -
377   - }
378   -
379   - /// Calculates the set of fibers resulting from a connection between the current fiber and a fiber f
380   -
381   - /// @param f is the fiber that will be connected to the current fiber
382   - std::vector< stim::fiber<T> > connect( stim::fiber<T> &f, double dist){
383   -
384   - double min_dist;
385   - unsigned int idx0, idx1;
386   -
387   - //go through each point in the query fiber, looking for the indices for the closest points
388   - for(unsigned int i = 0; i < f.n_pts(); i++){
389   - //Run through all points and find the index with the closest point, then partition the fiber and return two fibers.
390   -
391   - }
392   -
393   -
394   -
395   - }
396   -
397   - /// Outputs the fiber as a string
398   - std::string str(){
399   - std::stringstream ss;
400   -
401   - //create an iterator for the point list
402   - //typename std::list< point<T> >::iterator i;
403   - for(unsigned int i = 0; i < N; i++){
404   - ss<<" [ ";
405   - for(unsigned int d = 0; d < 3; d++){
406   - ss<<c[i][d]<<" ";
407   - }
408   - ss<<"] r = "<<r[i]<<std::endl;
409   - }
410   -
411   - return ss.str();
412   - }
413   - /// Returns the number of centerline points in the fiber
414   - unsigned int size(){
415   - return N;
416   - }
417   -
418   -
419   - /// Bracket operator returns the element at index i
420   -
421   - /// @param i is the index of the element to be returned as a stim::vec
422   - stim::vec<T> operator[](unsigned i){
423   - return get_vec(i);
424   - }
425   -
426   - /// Back method returns the last point in the fiber
427   - stim::vec<T> back(){
428   - return get_vec(N-1);
429   - }
430   - ////resample a fiber in the network
431   - stim::fiber<T> resample(T spacing)
432   - {
433   - std::cout<<"fiber::resample()"<<std::endl;
434   -
435   - std::vector<T> v(3); //v-direction vector of the segment
436   - stim::vec<T> p(3); //- intermediate point to be added
437   - stim::vec<T> p1(3); // p1 - starting point of an segment on the fiber,
438   - stim::vec<T> p2(3); // p2 - ending point,
439   - double sum=0; //distance summation
440   - std::vector<stim::vec<T> > fiberPositions = centerline();
441   - std::vector<stim::vec<T> > newPointList; // initialize list of new resampled points on the fiber
442   - // for each point on the centerline (skip if it is the last point on centerline)
443   - //unsigned int N = fiberPositions.size(); // number of points on the fiber
444   - for(unsigned int f=0; f< N-1; f++)
445   - {
446   -
447   - p1 = fiberPositions[f]; p2 = fiberPositions[f + 1]; v = p2 - p1;
448   - for(unsigned int d = 0; d < 3; d++){
449   - sum +=v[d] * v[d];} //length of segment-distance between starting and ending point
450   -
451   - T lengthSegment = sqrt(sum); //find Length of the segment as distance between the starting and ending points of the segment
452   -
453   - if(lengthSegment >= spacing) // if length of the segment is greater than standard deviation resample
454   - {
455   - // repeat resampling until accumulated stepsize is equsl to length of the segment
456   - for(T step=0.0; step<lengthSegment; step+=spacing)
457   - {
458   - // calculate the resampled point by travelling step size in the direction of normalized gradient vector
459   - for(unsigned int i=0; i<3;i++)
460   - {
461   - p[i] = p1[i] + v[i]*(step/lengthSegment);
462   - } //for each dimension
463   - // add this resampled points to the new fiber list
464   - newPointList.push_back(p);
465   - }
466   - }
467   - else // length of the segment is now less than standard deviation, push the ending point of the segment and proceed to the next point in the fiber
468   - newPointList.push_back(fiberPositions[f+1]);
469   - }
470   - newPointList.push_back(fiberPositions[N-1]); //add the last point on the fiber to the new fiber list
471   - fiber newFiber(newPointList);
472   - return newFiber;
473   - }
474   -
475   -};
476   -
477   -
478   -
479   -} //end namespace stim
480   -
481   -
482   -
483   -#endif