MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
HSolveUtils.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** copyright (C) 2003-2007 Upinder S. Bhalla, Niraj Dudani and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "HSolveUtils.h"
11 
13 {
14  //~ ProcInfoBase p;
15  //~ SetConn c( object(), 0 );
16  //~
17  //~ if ( object()->className() == "Compartment" )
18  //~ moose::Compartment::reinitFunc( &c, &p );
19  //~ else if ( object()->className() == "HHChannel" )
20  //~ HHChannel::reinitFunc( &c, &p );
21  //~ else if ( object()->className() == "CaConc" )
22  //~ CaConc::reinitFunc( &c, &p );
23 }
24 
25 int HSolveUtils::adjacent( Id compartment, Id exclude, vector< Id >& ret )
26 {
27  int size = ret.size();
28  adjacent( compartment, ret );
29  ret.erase(
30  remove( ret.begin(), ret.end(), exclude ),
31  ret.end()
32  );
33  return ret.size() - size;
34 }
35 
36 int HSolveUtils::adjacent( Id compartment, vector< Id >& ret )
37 {
38  int size = 0;
39  size += targets( compartment, "axial", ret, "Compartment" );
40  size += targets( compartment, "raxial", ret, "Compartment" );
41  size += targets( compartment, "distalOut", ret, "SymCompartment" );
42  size += targets( compartment, "proximalOut", ret, "SymCompartment" );
43  size += targets( compartment, "cylinderOut", ret, "SymCompartment" );
44  return size;
45 }
46 
47 int HSolveUtils::children( Id compartment, vector< Id >& ret )
48 {
49  int size = targets( compartment, "axial", ret, "Compartment" );
50  size += targets( compartment, "distalOut", ret, "SymCompartment" );
51  size += targets( compartment, "cylinderOut", ret, "SymCompartment" );
52  return size;
53 }
54 
59 int HSolveUtils::channels( Id compartment, vector< Id >& ret )
60 {
61  return targets( compartment, "channel", ret );
62 }
63 
64 int HSolveUtils::hhchannels( Id compartment, vector< Id >& ret )
65 {
66  // Request for elements of type "HHChannel" only since
67  // channel messages can lead to synchans as well.
68  return targets( compartment, "channel", ret, "HHChannel" );
69 }
70 
76  Id channel,
77  vector< Id >& ret,
78  bool getOriginals )
79 {
80 // dump("HSolveUtils::gates() is not tested with new hsolve api", "FIXME");
81  unsigned int oldSize = ret.size();
82 
83  static string gateName[] = {
84  string( "gateX[0]" ),
85  string( "gateY[0]" ),
86  string( "gateZ[0]" )
87  };
88 
89  static string powerField[] = {
90  string( "Xpower" ),
91  string( "Ypower" ),
92  string( "Zpower" )
93  };
94 
95  unsigned int nGates = 3; // Number of possible gates
96  for ( unsigned int i = 0; i < nGates; i++ ) {
97  double power = Field< double >::get ( channel, powerField[i] );
98 
99  if ( power > 0.0 ) {
100  // string gatePath = moose::joinPath(channel.path(), gateName[i]);
101  string gatePath = moose::fixPath( channel.path() ) +
102  "/" + gateName[i];
103  Id gate( gatePath );
104 
105  string gPath = moose::fixPath(gate.path());
106  errorSS.str("");
107  errorSS << "Got " << gatePath << " expected " << gPath;
108  SIMPLE_ASSERT_MSG(gPath == gatePath, errorSS.str().c_str());
109 
110  if ( getOriginals ) {
111  HHGate* g = reinterpret_cast< HHGate* >( gate.eref().data() );
112  gate = g->originalGateId();
113  }
114 
115  ret.push_back( gate );
116  }
117  }
118 
119  return ret.size() - oldSize;
120 }
121 
122 int HSolveUtils::spikegens( Id compartment, vector< Id >& ret )
123 {
124  return targets( compartment, "VmOut", ret, "SpikeGen" );
125 }
126 
127 int HSolveUtils::synchans( Id compartment, vector< Id >& ret )
128 {
129  // "channel" msgs lead to SynChans as well HHChannels, so request
130  // explicitly for former.
131  return targets( compartment, "channel", ret, "SynChan" );
132 }
133 
134 int HSolveUtils::leakageChannels( Id compartment, vector< Id >& ret )
135 {
136  return targets( compartment, "channel", ret, "Leakage" );
137 }
138 
139 int HSolveUtils::caTarget( Id channel, vector< Id >& ret )
140 {
141  return targets( channel, "IkOut", ret, "CaConc" );
142 }
143 
144 int HSolveUtils::caDepend( Id channel, vector< Id >& ret )
145 {
146  return targets( channel, "concen", ret, "CaConc" );
147 }
148 
149 /*
150  * Functions for accessing gates' lookup tables.
151  */
152 
153 //~ /**
154  //~ * Finds the xmin and xmax for the lookup tables (A and B) belonging to a gate.
155  //~ *
156  //~ * 'min' will be the smaller of the 2 mins.
157  //~ * 'max' will be the greater of the 2 maxs.
158  //~ */
159 //~ int HSolveUtils::domain(
160  //~ Id gate,
161  //~ double& min,
162  //~ double& max )
163 //~ {
164  //~ Id A;
165  //~ Id B;
166  //~
167  //~ bool success;
168  //~ success = lookupGet< Id, string >( gate(), "lookupChild", A, "A" );
169  //~ if ( ! success ) {
170  //~ cerr << "Error: Interpol A not found as child of " << gate()->name();
171  //~ return 0;
172  //~ }
173  //~
174  //~ success = lookupGet< Id, string >( gate(), "lookupChild", B, "B" );
175  //~ if ( ! success ) {
176  //~ cerr << "Error: Interpol B not found as child of " << gate()->name();
177  //~ return 0;
178  //~ }
179  //~
180  //~ double Amin, Amax;
181  //~ double Bmin, Bmax;
182  //~ get< double >( A(), "xmin", Amin );
183  //~ get< double >( A(), "xmax", Amax );
184  //~ get< double >( B(), "xmin", Bmin );
185  //~ get< double >( B(), "xmax", Bmax );
186  //~
187  //~ min = Amin < Bmin ? Amin : Bmin;
188  //~ max = Amax > Bmax ? Amax : Bmax;
189  //~
190  //~ return 1;
191 //~ }
192 
194 {
195  return divs_ + 1;
196 }
197 
198 double HSolveUtils::Grid::entry( unsigned int i )
199 {
200  assert( i <= divs_ + 1 );
201 
202  return ( min_ + dx_ * i );
203 }
204 
206  Id gateId,
207  HSolveUtils::Grid grid,
208  vector< double >& A,
209  vector< double >& B )
210 {
211  // dump("HSolveUtils::rates() has not been tested yet.", "WARN");
212  double min = Field< double >::get( gateId, "min" );
213  double max = Field< double >::get( gateId, "max" );
214  unsigned int divs = Field< unsigned int >::get( gateId, "divs" );
215 
216  if ( grid == Grid( min, max, divs ) ) {
217  A = Field< vector< double > >::get( gateId, "tableA" );
218  B = Field< vector< double > >::get( gateId, "tableB" );
219  return;
220  }
221 
222  A.resize( grid.size() );
223  B.resize( grid.size() );
224 
225  /*
226  * Getting Id of original (prototype) gate, so that we can set fields on
227  * it. Copied gates are read-only.
228  */
229  HHGate* gate = reinterpret_cast< HHGate* >( gateId.eref().data() );
230  gateId = gate->originalGateId();
231 
232  /*
233  * Setting interpolation flag on. Will set back to its original value once
234  * we're done.
235  */
236  bool useInterpolation = Field< bool >::get( gateId, "useInterpolation");
237  gate->setUseInterpolation( gateId.eref(), true );
238 
239  unsigned int igrid;
240  double* ia = &A[ 0 ];
241  double* ib = &B[ 0 ];
242  for ( igrid = 0; igrid < grid.size(); ++igrid ) {
243  gate->lookupBoth( grid.entry( igrid ), ia, ib );
244 
245  ++ia, ++ib;
246  }
247 
248  // Setting interpolation flag back to its original value.
249  //~ HSolveUtils::set< HHGate, bool >
250  //~ ( gateId, "useInterpolation", useInterpolation );
251  gate->setUseInterpolation( gateId.eref(), useInterpolation );
252 }
253 
254 //~ int HSolveUtils::modes( Id gate, int& AMode, int& BMode )
255 //~ {
256  //~ Id A;
257  //~ Id B;
258  //~
259  //~ bool success;
260  //~ success = lookupGet< Id, string >( gate(), "lookupChild", A, "A" );
261  //~ if ( ! success ) {
262  //~ cerr << "Error: Interpol A not found as child of " << gate()->name();
263  //~ return 0;
264  //~ }
265  //~
266  //~ success = lookupGet< Id, string >( gate(), "lookupChild", B, "B" );
267  //~ if ( ! success ) {
268  //~ cerr << "Error: Interpol B not found as child of " << gate()->name();
269  //~ return 0;
270  //~ }
271  //~
272  //~ get< int >( A(), "mode", AMode );
273  //~ get< int >( B(), "mode", BMode );
274  //~ return 1;
275 //~ }
276 
278 // Utility functions
280 
282  Id object,
283  string msg,
284  vector< Id >& target,
285  string filter, // Default: ""
286  bool include ) // Default: true
287 {
288  vector< string > filter_v;
289 
290  if ( filter != "" )
291  filter_v.push_back( filter );
292 
293  return targets( object, msg, target, filter_v, include );
294 }
295 
304  Id object,
305  string msg,
306  vector< Id >& target,
307  const vector< string >& filter, // This does not have a default value,
308  // to avoid ambiguity between the two
309  // 'targets()' functions when the last 2
310  // arguments are skipped.
311  bool include ) // Default: true
312 {
313  unsigned int oldSize = target.size();
314 
315  vector< Id > all;
316  Element* e = object.element();
317  const Finfo* f = e->cinfo()->findFinfo( msg );
318  if ( !f ) // Might not find SymCompartment Finfos if it is a Compartment
319  return 0;
320  e->getNeighbors( all, f );
321 
322  vector< Id >::iterator ia;
323  if ( filter.empty() ) {
324  target.insert( target.end(), all.begin(), all.end() );
325  } else {
326  for ( ia = all.begin(); ia != all.end(); ++ia ) {
327  string className = (*ia).element()->cinfo()->name();
328  bool hit =
329  find(
330  filter.begin(),
331  filter.end(),
332  className
333  ) != filter.end();
334 
335  if ( ( hit && include ) || ( !hit && !include ) )
336  target.push_back( *ia );
337  }
338  }
339 
340  return target.size() - oldSize;
341 }
342 
344 
345 #ifdef DO_UNIT_TESTS
346 
347 #include "HinesMatrix.h"
348 #include "../shell/Shell.h"
349 void testHSolveUtils( )
350 {
351  //TEST_BEGIN;
352  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
353  bool success;
354 
355  Id n = shell->doCreate( "Neutral", Id(), "n", 1 );
356 
372  Id c[ 6 ];
373  c[ 0 ] = shell->doCreate( "Compartment", n, "c0", 1 );
374  c[ 1 ] = shell->doCreate( "Compartment", n, "c1", 1 );
375  c[ 2 ] = shell->doCreate( "Compartment", n, "c2", 1 );
376  c[ 3 ] = shell->doCreate( "Compartment", n, "c3", 1 );
377  c[ 4 ] = shell->doCreate( "Compartment", n, "c4", 1 );
378  c[ 5 ] = shell->doCreate( "Compartment", n, "c5", 1 );
379 
380  ObjId mid;
381  mid = shell->doAddMsg( "Single", c[ 0 ], "axial", c[ 1 ], "raxial" );
382  ASSERT( ! mid.bad(), "Linking compartments" );
383  mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 2 ], "raxial" );
384  ASSERT( ! mid.bad(), "Linking compartments" );
385  mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 3 ], "raxial" );
386  ASSERT( ! mid.bad(), "Linking compartments" );
387  mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 4 ], "raxial" );
388  ASSERT( ! mid.bad(), "Linking compartments" );
389  mid = shell->doAddMsg( "Single", c[ 1 ], "axial", c[ 5 ], "raxial" );
390  ASSERT( ! mid.bad(), "Linking compartments" );
391 
392  vector< Id > found;
393  unsigned int nFound;
394 
395  /*
396  * Testing version 1 of HSolveUtils::adjacent.
397  * It finds all neighbors of given compartment.
398  */
399  // Neighbors of c0
400  nFound = HSolveUtils::adjacent( c[ 0 ], found );
401  ASSERT( nFound == found.size(), "Finding adjacent compartments" );
402  // c1 is adjacent
403  ASSERT( nFound == 1, "Finding adjacent compartments" );
404  ASSERT( found[ 0 ] == c[ 1 ], "Finding adjacent compartments" );
405 
406  // Neighbors of c1
407  found.clear();
408  nFound = HSolveUtils::adjacent( c[ 1 ], found );
409  ASSERT( nFound == 5, "Finding adjacent compartments" );
410  // c0 is adjacent
411  success =
412  find( found.begin(), found.end(), c[ 0 ] ) != found.end();
413  ASSERT( success, "Finding adjacent compartments" );
414  // c2 - c5 are adjacent
415  for ( int i = 2; i < 6; i++ ) {
416  success =
417  find( found.begin(), found.end(), c[ i ] ) != found.end();
418  ASSERT( success, "Finding adjacent compartments" );
419  }
420 
421  // Neighbors of c2
422  found.clear();
423  nFound = HSolveUtils::adjacent( c[ 2 ], found );
424  // c1 is adjacent
425  ASSERT( nFound == 1, "Finding adjacent compartments" );
426  ASSERT( found[ 0 ] == c[ 1 ], "Finding adjacent compartments" );
427 
428  /*
429  * Testing version 2 of HSolveUtils::adjacent.
430  * It finds all but one neighbors of given compartment.
431  * The the second argument to 'adjacent' is the one that is excluded.
432  */
433  // Neighbors of c1 (excluding c0)
434  found.clear();
435  nFound = HSolveUtils::adjacent( c[ 1 ], c[ 0 ], found );
436  ASSERT( nFound == 4, "Finding adjacent compartments" );
437  // c2 - c5 are adjacent
438  for ( int i = 2; i < 6; i++ ) {
439  success =
440  find( found.begin(), found.end(), c[ i ] ) != found.end();
441  ASSERT( success, "Finding adjacent compartments" );
442  }
443 
444  // Neighbors of c1 (excluding c2)
445  found.clear();
446  nFound = HSolveUtils::adjacent( c[ 1 ], c[ 2 ], found );
447  ASSERT( nFound == 4, "Finding adjacent compartments" );
448  // c0 is adjacent
449  success =
450  find( found.begin(), found.end(), c[ 0 ] ) != found.end();
451  ASSERT( success, "Finding adjacent compartments" );
452  // c3 - c5 are adjacent
453  for ( int i = 3; i < 6; i++ ) {
454  success =
455  find( found.begin(), found.end(), c[ i ] ) != found.end();
456  ASSERT( success, "Finding adjacent compartments" );
457  }
458 
459  // Neighbors of c2 (excluding c1)
460  found.clear();
461  nFound = HSolveUtils::adjacent( c[ 2 ], c[ 1 ], found );
462  // None adjacent, if c1 is excluded
463  ASSERT( nFound == 0, "Finding adjacent compartments" );
464 
465  // Neighbors of c2 (excluding c3)
466  found.clear();
467  nFound = HSolveUtils::adjacent( c[ 2 ], c[ 3 ], found );
468  // c1 is adjacent, while c3 is not even connected
469  ASSERT( nFound == 1, "Finding adjacent compartments" );
470  ASSERT( found[ 0 ] == c[ 1 ], "Finding adjacent compartments" );
471 
472  /*
473  * Testing HSolveUtils::children.
474  * It finds all compartments which are dests for the "axial" message.
475  */
476  // Children of c0
477  found.clear();
478  nFound = HSolveUtils::children( c[ 0 ], found );
479  ASSERT( nFound == 1, "Finding child compartments" );
480  // c1 is a child
481  ASSERT( found[ 0 ] == c[ 1 ], "Finding child compartments" );
482 
483  // Children of c1
484  found.clear();
485  nFound = HSolveUtils::children( c[ 1 ], found );
486  ASSERT( nFound == 4, "Finding child compartments" );
487  // c2 - c5 are c1's children
488  for ( int i = 2; i < 6; i++ ) {
489  success =
490  find( found.begin(), found.end(), c[ i ] ) != found.end();
491  ASSERT( success, "Finding child compartments" );
492  }
493 
494  // Children of c2
495  found.clear();
496  nFound = HSolveUtils::children( c[ 2 ], found );
497  // c2 has no children
498  ASSERT( nFound == 0, "Finding child compartments" );
499 
500  // Clean up
501  shell->doDelete( n );
502  cout << "." << flush;
503  // TEST_END;
504 }
505 
506 #endif // DO_UNIT_TESTS
unsigned int divs_
Definition: HSolveUtils.h:67
#define ASSERT(unused, message)
Definition: HinesMatrix.h:22
static int children(Id compartment, vector< Id > &ret)
Definition: HSolveUtils.cpp:47
char * data() const
Definition: Eref.cpp:41
Definition: HHGate.h:31
static int caDepend(Id channel, vector< Id > &ret)
static int leakageChannels(Id compartment, vector< Id > &ret)
bool bad() const
Definition: ObjId.cpp:18
std::string path(const std::string &separator="/") const
Definition: Id.cpp:76
static int spikegens(Id compartment, vector< Id > &ret)
Definition: SetGet.h:236
Id originalGateId() const
Definition: HHGate.cpp:801
void setUseInterpolation(const Eref &e, bool val)
Definition: HHGate.cpp:485
static int caTarget(Id channel, vector< Id > &ret)
Definition: ObjId.h:20
static int adjacent(Id compartment, vector< Id > &ret)
Definition: HSolveUtils.cpp:36
Eref eref() const
Definition: Id.cpp:125
static int gates(Id channel, vector< Id > &ret, bool getOriginals=true)
Definition: HSolveUtils.cpp:75
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
Definition: Shell.cpp:181
unsigned int size()
static int targets(Id object, string msg, vector< Id > &target, string filter="", bool include=true)
void lookupBoth(double v, double *A, double *B) const
Definition: HHGate.cpp:275
static int channels(Id compartment, vector< Id > &ret)
Definition: HSolveUtils.cpp:59
static void initialize(Id object)
Definition: HSolveUtils.cpp:12
string fixPath(string path)
Fix a path. For testing purpose.
Definition: global.cpp:74
static void rates(Id gate, Grid grid, vector< double > &A, vector< double > &B)
const Cinfo * cinfo() const
Definition: Element.cpp:66
static int synchans(Id compartment, vector< Id > &ret)
stringstream errorSS
Global stringstream for message printing.
Definition: global.cpp:32
static int hhchannels(Id compartment, vector< Id > &ret)
Definition: HSolveUtils.cpp:64
ObjId doAddMsg(const string &msgType, ObjId src, const string &srcField, ObjId dest, const string &destField)
Definition: Shell.cpp:269
bool doDelete(ObjId oid)
Definition: Shell.cpp:259
Definition: Id.h:17
double entry(unsigned int i)
unsigned int getNeighbors(vector< Id > &ret, const Finfo *finfo) const
Definition: Element.cpp:949
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
#define SIMPLE_ASSERT_MSG(expr, msg)
Definition: Shell.h:43
const Finfo * findFinfo(const string &name) const
Definition: Cinfo.cpp:224
Definition: Finfo.h:12