MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ReadSwc Class Reference

#include <ReadSwc.h>

+ Collaboration diagram for ReadSwc:

Public Member Functions

void assignKids ()
 
bool build (Id parent, double lambda, double RM, double RA, double CM)
 
void cleanZeroLength ()
 
void diagnostics () const
 
void parseBranches ()
 
 ReadSwc (const string &fname)
 
void traverseBranch (const SwcSegment &s, double &len, double &L, vector< int > &cable) const
 
bool validate () const
 

Private Attributes

vector< SwcBranchbranches_
 
vector< SwcSegmentsegs_
 

Detailed Description

This class is used to read in SWC files as found in NeuroMorph.org and other places. Note that these are only passive models at this stage.

Definition at line 18 of file ReadSwc.h.

Constructor & Destructor Documentation

ReadSwc::ReadSwc ( const string &  fname)

Each line is of the form n T x y z R P

Definition at line 24 of file ReadSwc.cpp.

References assignKids(), branches_, cleanZeroLength(), diagnostics(), SwcSegment::OK(), parseBranches(), segs_, and validate().

25 {
26  ifstream fin( fname.c_str() );
27  if ( !fin ) {
28  cerr << "ReadSwc:: could not open file " << fname << endl;
29  return;
30  }
31 
32  string temp;
33  int badSegs = 0;
34  while( getline( fin, temp ) ) {
35  if ( temp.length() == 0 )
36  continue;
37  string::size_type pos = temp.find_first_not_of( "\t " );
38  if ( pos == string::npos )
39  continue;
40  if ( temp[pos] == '#' )
41  continue;
42 
43  SwcSegment t( temp );
44  if ( t.OK() )
45  segs_.push_back( SwcSegment( temp ) );
46  else
47  badSegs++;
48  }
49  bool valid = validate();
50  if ( valid ) {
51  assignKids();
53  parseBranches();
54  }
55  cout << "ReadSwc: " << fname << " : NumSegs = " << segs_.size() <<
56  ", bad = " << badSegs <<
57  ", Validated = " << valid <<
58  ", numBranches = " << branches_.size() <<
59  endl;
60  diagnostics();
61 }
bool validate() const
Definition: ReadSwc.cpp:63
void cleanZeroLength()
Definition: ReadSwc.cpp:112
void parseBranches()
Definition: ReadSwc.cpp:162
void assignKids()
Definition: ReadSwc.cpp:98
void diagnostics() const
Definition: ReadSwc.cpp:194
vector< SwcSegment > segs_
Definition: ReadSwc.h:37
vector< SwcBranch > branches_
Definition: ReadSwc.h:45

+ Here is the call graph for this function:

Member Function Documentation

void ReadSwc::assignKids ( )

Definition at line 98 of file ReadSwc.cpp.

References SwcSegment::myIndex(), SwcSegment::parent(), and segs_.

Referenced by ReadSwc().

99 {
100  for ( unsigned int i = 0; i < segs_.size(); ++i ) {
101  const SwcSegment& s = segs_[i];
102  assert ( s.parent() != s.myIndex() );
103  if ( s.parent() != ~0U ) {
104  segs_[s.parent() - 1].addChild( i + 1 );
105  }
106  }
107  for ( unsigned int i = 0; i < segs_.size(); ++i ) {
108  segs_[i].figureOutType();
109  }
110 }
unsigned int parent() const
Definition: SwcSegment.h:44
unsigned int myIndex() const
Definition: SwcSegment.h:52
vector< SwcSegment > segs_
Definition: ReadSwc.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool ReadSwc::build ( Id  parent,
double  lambda,
double  RM,
double  RA,
double  CM 
)

Definition at line 256 of file ReadSwc.cpp.

References branches_, Eref::data(), Shell::doAddMsg(), Id::eref(), makeCompt(), SwcSegment::myIndex(), SwcSegment::parent(), segs_, and SwcBranch::segs_.

Referenced by Shell::doLoadModel().

258 {
259  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
260  vector< Id > compts( segs_.size() );
261  for ( unsigned int i = 0; i < branches_.size(); ++i ) {
262  SwcBranch& br = branches_[i];
263  for ( unsigned int j = 0; j < br.segs_.size(); ++j ) {
264  Id compt;
265  SwcSegment& seg = segs_[ br.segs_[j] -1 ];
266  unsigned int paIndex = seg.parent();
267  if ( paIndex == ~0U ) { // soma
268  compt = makeCompt( parent, seg, seg, RM, RA, CM, i, j );
269  } else {
270  SwcSegment& pa = segs_[ paIndex - 1 ];
271  compt = makeCompt( parent, seg, pa, RM, RA, CM, i, j );
272  assert( compt != Id() );
273  assert( compts[ paIndex -1 ] != Id() );
274  shell->doAddMsg( "Single",
275  compts[paIndex-1], "axial", compt, "raxial" );
276  }
277  assert( compt != Id() );
278  compts[ seg.myIndex() -1 ] = compt;
279  }
280  }
281  return true;
282 }
vector< int > segs_
Definition: SwcSegment.h:202
char * data() const
Definition: Eref.cpp:41
unsigned int parent() const
Definition: SwcSegment.h:44
Eref eref() const
Definition: Id.cpp:125
unsigned int myIndex() const
Definition: SwcSegment.h:52
vector< SwcSegment > segs_
Definition: ReadSwc.h:37
vector< SwcBranch > branches_
Definition: ReadSwc.h:45
ObjId doAddMsg(const string &msgType, ObjId src, const string &srcField, ObjId dest, const string &destField)
Definition: Shell.cpp:269
Definition: Id.h:17
static Id makeCompt(Id parent, const SwcSegment &seg, const SwcSegment &pa, double RM, double RA, double CM, unsigned int i, unsigned int j)
Definition: ReadSwc.cpp:211
Definition: Shell.h:43

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ReadSwc::cleanZeroLength ( )

Definition at line 112 of file ReadSwc.cpp.

References SwcSegment::distance(), EPSILON, SwcSegment::kids(), SwcSegment::myIndex(), SwcSegment::parent(), SwcSegment::replaceKids(), segs_, SwcSegment::setBad(), and SwcSegment::setParent().

Referenced by ReadSwc().

113 {
114  static double EPSILON = 1e-2; // Assume units in microns.
115  for ( unsigned int i = 1; i < segs_.size(); ++i ) {
116  SwcSegment& s = segs_[i];
117  SwcSegment& pa = segs_[ s.parent() - 1 ];
118  if ( s.distance( pa ) < EPSILON ) {
119  // Remove the zero length child from pa.kids_
120  vector< int > temp;
121  for ( unsigned int j = 0; j < pa.kids().size(); ++j ) {
122  if ( static_cast< unsigned int >( pa.kids()[j] ) != s.myIndex() )
123  temp.push_back( pa.kids()[j] );
124  }
125  // Go through all kids of s and reparent them.
126  for ( unsigned int j = 0; j < s.kids().size(); ++j ) {
127  SwcSegment& kid = segs_[ s.kids()[j] - 1 ];
128  kid.setParent( pa.myIndex() );
129  temp.push_back( kid.myIndex() );
130  }
131  pa.replaceKids( temp );
132  s.setBad();
133  cout << "ReadSwc:: Cleaned zero length " << s.myIndex() << endl;
134  }
135  }
136 }
void setBad()
Definition: SwcSegment.h:39
void replaceKids(const vector< int > &kids)
Definition: SwcSegment.h:67
unsigned int parent() const
Definition: SwcSegment.h:44
const vector< int > & kids() const
Definition: SwcSegment.h:62
unsigned int myIndex() const
Definition: SwcSegment.h:52
double distance(const SwcSegment &other) const
Definition: SwcSegment.h:87
vector< SwcSegment > segs_
Definition: ReadSwc.h:37
void setParent(unsigned int pa)
Definition: SwcSegment.h:48
#define EPSILON
Definition: MatrixOps.h:28

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ReadSwc::diagnostics ( ) const

Definition at line 194 of file ReadSwc.cpp.

References segs_, SwcSegment::type(), and SwcSegment::typeName.

Referenced by ReadSwc().

195 {
196  vector< int > diag( 14 );
197  for ( unsigned int i = 0; i < segs_.size(); ++i ) {
198  const SwcSegment& s = segs_[i];
199  if ( s.type() < 14 )
200  diag[s.type()]++;
201  }
202  for ( int i = 0; i < 14; ++i )
203  cout << "ReadSwc::diagnostics: " << SwcSegment::typeName[i] << " : " << diag[i] << endl;
204 
205  /*
206  for ( unsigned int i = 0; i < branches_.size(); ++i )
207  branches_[i].printDiagnostics();
208  */
209 }
unsigned short type() const
Definition: SwcSegment.h:72
vector< SwcSegment > segs_
Definition: ReadSwc.h:37
static const string typeName[]
Definition: SwcSegment.h:137

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ReadSwc::parseBranches ( )

Definition at line 162 of file ReadSwc.cpp.

References branches_, SwcSegment::kids(), SwcSegment::OK(), segs_, and traverseBranch().

Referenced by ReadSwc().

163 {
164  // Fill vector of all branches.
165  for ( unsigned int i = 0; i < segs_.size(); ++i ) {
166  const SwcSegment& s = segs_[i];
167  if ( s.OK() && s.kids().size() != 1 ) { // Either use a fork or an end.
168  vector< int > cable;
169  // int branchIndex = branches_.
170  // branches_.push_back( i + 1 );
171  double len = 0;
172  double L = 0;
173  traverseBranch( s, len, L, cable );
174  // branchGeomLength_.push_back( len );
175  // branchElectroLength_.push_back( L );
176  SwcBranch br( branches_.size(), s, len, L, cable );
177  branches_.push_back( br );
178  }
179  }
180  // Assign the parent of each branch. This is known because the
181  // parent of the first segment in the branch is the last segment
182  // in the parent branch. I construct a reverse lookup table to find
183  // the branch # from its last segment number.
184  vector< int > reverseSeg ( segs_.size() + 1, 0 );
185  for ( unsigned int i = 0; i < branches_.size(); ++i )
186  reverseSeg[ branches_[i].segs_.back() ] = i;
187  for ( unsigned int i = 0; i < branches_.size(); ++i ) {
188  int parentSeg = segs_[ branches_[i].segs_[0] - 1 ].parent();
189  assert( parentSeg != 0 ); // Note that segment indices start from 1
190  branches_[i].setParent( reverseSeg[ parentSeg ] );
191  }
192 }
void traverseBranch(const SwcSegment &s, double &len, double &L, vector< int > &cable) const
Definition: ReadSwc.cpp:138
const vector< int > & kids() const
Definition: SwcSegment.h:62
bool OK() const
Definition: SwcSegment.h:34
vector< SwcSegment > segs_
Definition: ReadSwc.h:37
vector< SwcBranch > branches_
Definition: ReadSwc.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ReadSwc::traverseBranch ( const SwcSegment s,
double &  len,
double &  L,
vector< int > &  cable 
) const

Definition at line 138 of file ReadSwc.cpp.

References SwcSegment::distance(), SwcSegment::kids(), SwcSegment::L(), SwcSegment::myIndex(), SwcSegment::parent(), SwcSegment::radius(), and segs_.

Referenced by parseBranches().

140 {
141  const SwcSegment* prev = &s;
142  cable.resize( 1, s.myIndex() ); // Always include the starting seg.
143  // Note that the cable is filled up with entries in reverse order.
144 
145  if ( s.parent() == ~0U ) {
146  len = s.radius();
147  L = sqrt( len );
148  return ;
149  }
150 
151  do {
152  // Beware the indexing!
153  const SwcSegment& pa = segs_[prev->parent() - 1];
154  len += pa.distance( *prev );
155  L += pa.L( );
156  cable.push_back( pa.myIndex() );
157  prev = &pa;
158  } while ( (prev->parent() != ~0U) && (prev->kids().size() == 1) );
159  cable.pop_back(); // Get rid of the last entry, it is on the parent.
160 }
double L() const
Definition: SwcSegment.h:83
unsigned int parent() const
Definition: SwcSegment.h:44
const vector< int > & kids() const
Definition: SwcSegment.h:62
unsigned int myIndex() const
Definition: SwcSegment.h:52
double distance(const SwcSegment &other) const
Definition: SwcSegment.h:87
double radius() const
Definition: SwcSegment.h:76
vector< SwcSegment > segs_
Definition: ReadSwc.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool ReadSwc::validate ( ) const

Definition at line 63 of file ReadSwc.cpp.

References branches_, MinRadius, SwcSegment::myIndex(), SwcSegment::parent(), SwcSegment::radius(), and segs_.

Referenced by ReadSwc().

64 {
65  int numStart = 0;
66  int numOrphans = 0;
67  int badIndex = 0;
68  int badRadius = 0;
69  for ( unsigned int i = 0; i < segs_.size(); ++i ) {
70  const SwcSegment& s = segs_[i];
71  if ( s.myIndex() != i + 1 )
72  badIndex++;
73  if ( s.parent() == ~0U ) {
74  numStart++;
75  } else {
76  if ( s.parent() > i ) {
77  numOrphans++;
78  }
79  }
80  if ( s.radius() < MinRadius ) {
81  badRadius++;
82  }
83  }
84  bool valid = ( numStart == 1 && numOrphans == 0 && badRadius == 0 );
85  if ( !valid ) {
86  cout << "ReadSwc::validate() failed: \nNumSegs = " <<
87  segs_.size() <<
88  ", numStart = " << numStart <<
89  ", orphans = " << numOrphans <<
90  ", badIndex = " << badIndex <<
91  ", badRadius = " << badRadius <<
92  ", numBranches = " << branches_.size() <<
93  endl;
94  }
95  return valid;
96 }
unsigned int parent() const
Definition: SwcSegment.h:44
static const double MinRadius
Definition: ReadSwc.cpp:22
unsigned int myIndex() const
Definition: SwcSegment.h:52
double radius() const
Definition: SwcSegment.h:76
vector< SwcSegment > segs_
Definition: ReadSwc.h:37
vector< SwcBranch > branches_
Definition: ReadSwc.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

vector< SwcBranch > ReadSwc::branches_
private

branches holds the NeuroMorpho index of the end segment of each branch. Note that NeuroMorph index starts from 1. To traverse the branch, go to the end segment, and traverse through all parents till you get to a fork.

Definition at line 45 of file ReadSwc.h.

Referenced by build(), parseBranches(), ReadSwc(), and validate().

vector< SwcSegment > ReadSwc::segs_
private

The documentation for this class was generated from the following files: