MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
HHChannel2D.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. 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 "header.h"
11 #include "ElementValueFinfo.h"
12 #include "../builtins/Interpol2D.h"
13 #include "ChanBase.h"
14 #include "ChanCommon.h"
15 #include "HHGate2D.h"
16 #include "HHChannel2D.h"
17 
18 const double HHChannel2D::EPSILON = 1.0e-10;
19 const int HHChannel2D::INSTANT_X = 1;
20 const int HHChannel2D::INSTANT_Y = 2;
21 const int HHChannel2D::INSTANT_Z = 4;
22 
24 {
26  // Shared messages
29 // Field definitions
31  static ValueFinfo< HHChannel2D, string > Xindex( "Xindex",
32  "String for setting X index.",
35  );
36  static ValueFinfo< HHChannel2D, string > Yindex( "Yindex",
37  "String for setting Y index.",
40  );
41  static ValueFinfo< HHChannel2D, string > Zindex( "Zindex",
42  "String for setting Z index.",
45  );
46  static ElementValueFinfo< HHChannel2D, double > Xpower( "Xpower",
47  "Power for X gate",
50  );
51  static ElementValueFinfo< HHChannel2D, double > Ypower( "Ypower",
52  "Power for Y gate",
55  );
56  static ElementValueFinfo< HHChannel2D, double > Zpower( "Zpower",
57  "Power for Z gate",
60  );
61  static ValueFinfo< HHChannel2D, int > instant( "instant",
62  "Bitmapped flag: bit 0 = Xgate, bit 1 = Ygate, bit 2 = Zgate"
63  "When true, specifies that the lookup table value should be"
64  "used directly as the state of the channel, rather than used"
65  "as a rate term for numerical integration for the state",
68  );
70  "State variable for X gate",
73  );
75  "State variable for Y gate",
78  );
80  "State variable for Y gate",
83  );
84 
86 // MsgSrc definitions
88 
90 // MsgDest definitions
92  static DestFinfo concen( "concen",
93  "Incoming message from Concen object to specific conc to use"
94  "as the first concen variable",
96  );
97  static DestFinfo concen2( "concen2",
98  "Incoming message from Concen object to specific conc to use"
99  "as the second concen variable",
101  );
103 // FieldElementFinfo definition for HHGates. Note that these are made
104 // with the deferCreate flag off, so that the HHGates are created
105 // right away even if they are empty.
106 // I assume that we only have a single HHGate entry for each one.
108  static FieldElementFinfo< HHChannel2D, HHGate2D > gateX( "gateX",
109  "Sets up HHGate X for channel",
114  );
115  static FieldElementFinfo< HHChannel2D, HHGate2D > gateY( "gateY",
116  "Sets up HHGate Y for channel",
121  );
122  static FieldElementFinfo< HHChannel2D, HHGate2D > gateZ( "gateZ",
123  "Sets up HHGate Z for channel",
128  );
129  static Finfo* HHChannel2DFinfos[] =
130  {
131  &Xindex, // Value
132  &Yindex, // Value
133  &Zindex, // Value
134  &Xpower, // Value
135  &Ypower, // Value
136  &Zpower, // Value
137  &instant, // Value
138  &X, // Value
139  &Y, // Value
140  &Z, // Value
141  &concen, // Dest
142  &concen2, // Dest
143  &gateX, // FieldElement
144  &gateY, // FieldElement
145  &gateZ // FieldElement
146  };
147 
148  static string doc[] =
149  {
150  "Name", "HHChannel2D",
151  "Author", "Niraj Dudani, 2009, NCBS, Updated Upi Bhalla, 2011",
152  "Description", "HHChannel2D: Hodgkin-Huxley type voltage-gated Ion channel. Something "
153  "like the old tabchannel from GENESIS, but also presents "
154  "a similar interface as hhchan from GENESIS. ",
155  };
156 
157  static Dinfo< HHChannel2D > dinfo;
158  static Cinfo HHChannel2DCinfo(
159  "HHChannel2D",
161  HHChannel2DFinfos,
162  sizeof( HHChannel2DFinfos ) / sizeof(Finfo *),
163  &dinfo,
164  doc,
165  sizeof(doc) / sizeof(string)
166  );
167 
168  return &HHChannel2DCinfo;
169 }
170 
172 
174  : ChanCommon(),
175  Xpower_( 0.0 ),
176  Ypower_( 0.0 ),
177  Zpower_( 0.0 ),
178  instant_(0),
179  X_(0.0),
180  Y_(0.0),
181  Z_(0.0),
182  xInited_(false),
183  yInited_(false),
184  zInited_(false),
185  conc1_(0.0),
186  conc2_(0.0),
187  Xdep0_( -1 ),
188  Xdep1_( -1 ),
189  Ydep0_( -1 ),
190  Ydep1_( -1 ),
191  Zdep0_( -1 ),
192  Zdep1_( -1 ),
193  xGate_( 0 ),
194  yGate_( 0 ),
195  zGate_( 0 )
196 {;}
197 
198 
200 // Field function definitions
202 
209 double HHChannel2D::getXpower( const Eref& e ) const
210 {
211  return Xpower_;
212 }
213 
214 double HHChannel2D::getYpower( const Eref& e ) const
215 {
216  return Ypower_;
217 }
218 
219 double HHChannel2D::getZpower( const Eref& e ) const
220 {
221  return Zpower_;
222 }
223 
224 void HHChannel2D::setInstant( int instant )
225 {
226  instant_ = instant;
227 }
229 {
230  return instant_;
231 }
232 
233 void HHChannel2D::setX( double X )
234 {
235  X_ = X;
236  xInited_ = true;
237 }
238 double HHChannel2D::getX() const
239 {
240  return X_;
241 }
242 
243 void HHChannel2D::setY( double Y )
244 {
245  Y_ = Y;
246  yInited_ = true;
247 }
248 double HHChannel2D::getY() const
249 {
250  return Y_;
251 }
252 
253 void HHChannel2D::setZ( double Z )
254 {
255  Z_ = Z;
256  zInited_ = true;
257 }
258 double HHChannel2D::getZ() const
259 {
260  return Z_;
261 }
262 
264 {
265  return Xindex_;
266 }
267 
268 void HHChannel2D::setXindex( string Xindex )
269 {
270  if ( Xindex == Xindex_ )
271  return;
272 
273  Xindex_ = Xindex;
274  Xdep0_ = dependency( Xindex, 0 );
275  Xdep1_ = dependency( Xindex, 1 );
276 
277  assert( Xdep0_ >= 0 );
278 }
279 
281 {
282  return Yindex_;
283 }
284 
285 void HHChannel2D::setYindex( string Yindex )
286 {
287  if ( Yindex == Yindex_ )
288  return;
289 
290  Yindex_ = Yindex;
291  Ydep0_ = dependency( Yindex, 0 );
292  Ydep1_ = dependency( Yindex, 1 );
293 
294  assert( Ydep0_ >= 0 );
295 }
296 
298 {
299  return Zindex_;
300 }
301 
302 void HHChannel2D::setZindex( string Zindex )
303 {
304  if ( Zindex == Zindex_ )
305  return;
306 
307  Zindex_ = Zindex;
308  Zdep0_ = dependency( Zindex, 0 );
309  Zdep1_ = dependency( Zindex, 1 );
310 
311  assert( Zdep0_ >= 0 );
312 }
313 
315 // HHGate2D access funcs
317 
318 HHGate2D* HHChannel2D::getXgate( unsigned int i )
319 {
320  return xGate_;
321 }
322 
323 HHGate2D* HHChannel2D::getYgate( unsigned int i )
324 {
325  return yGate_;
326 }
327 
328 HHGate2D* HHChannel2D::getZgate( unsigned int i )
329 {
330  return zGate_;
331 }
332 
333 void HHChannel2D::setNumGates( unsigned int num )
334 { ; }
335 
336 unsigned int HHChannel2D::getNumXgates() const
337 {
338  return ( xGate_ != 0 );
339 }
340 
341 unsigned int HHChannel2D::getNumYgates() const
342 {
343  return ( yGate_ != 0 );
344 }
345 
346 unsigned int HHChannel2D::getNumZgates() const
347 {
348  return ( zGate_ != 0 );
349 }
350 
351 double HHChannel2D::depValue( int dep )
352 {
353  switch( dep )
354  {
355  case 0: return Vm_;
356  case 1: return conc1_;
357  case 2: return conc2_;
358  default: assert( 0 ); return 0.0;
359  }
360 }
361 
362 int HHChannel2D::dependency( string index, unsigned int dim )
363 {
364  static vector< map< string, int > > dep;
365  if ( dep.empty() ) {
366  dep.resize( 2 );
367 
368  dep[ 0 ][ "VOLT_INDEX" ] = 0;
369  dep[ 0 ][ "C1_INDEX" ] = 1;
370  dep[ 0 ][ "C2_INDEX" ] = 2;
371 
372  dep[ 0 ][ "VOLT_C1_INDEX" ] = 0;
373  dep[ 0 ][ "VOLT_C2_INDEX" ] = 0;
374  dep[ 0 ][ "C1_C2_INDEX" ] = 1;
375 
376  dep[ 1 ][ "VOLT_INDEX" ] = -1;
377  dep[ 1 ][ "C1_INDEX" ] = -1;
378  dep[ 1 ][ "C2_INDEX" ] = -1;
379 
380  dep[ 1 ][ "VOLT_C1_INDEX" ] = 1;
381  dep[ 1 ][ "VOLT_C2_INDEX" ] = 2;
382  dep[ 1 ][ "C1_C2_INDEX" ] = 2;
383  }
384 
385  if ( dep[ dim ].find( index ) == dep[ dim ].end() )
386  return -1;
387 
388  if ( dep[ dim ][ index ] == 0 )
389  return 0;
390  if ( dep[ dim ][ index ] == 1 )
391  return 1;
392  if ( dep[ dim ][ index ] == 2 )
393  return 2;
394 
395  return -1;
396 }
397 
399 // Dest function definitions
401 
402 void HHChannel2D::conc1( double conc )
403 {
404  conc1_ = conc;
405 }
406 
407 void HHChannel2D::conc2( double conc )
408 {
409  conc2_ = conc;
410 }
411 
413 // utility function definitions
415 
420 double HHChannel2D::integrate( double state, double dt, double A, double B )
421 {
422  if ( B > EPSILON ) {
423  double x = exp( -B * dt );
424  return state * x + ( A / B ) * ( 1 - x );
425  }
426  return state + A * dt ;
427 }
428 
430 {
431  g_ += ChanBase::getGbar( e );
432  double A = 0;
433  double B = 0;
434  if ( Xpower_ > 0 ) {
435  xGate_->lookupBoth( depValue( Xdep0_ ), depValue( Xdep1_ ), &A, &B );
436  if ( instant_ & INSTANT_X )
437  X_ = A/B;
438  else
439  X_ = integrate( X_, info->dt, A, B );
440  g_ *= takeXpower_( X_, Xpower_ );
441  }
442 
443  if ( Ypower_ > 0 ) {
444  yGate_->lookupBoth( depValue( Ydep0_ ), depValue( Ydep1_ ), &A, &B );
445  if ( instant_ & INSTANT_Y )
446  Y_ = A/B;
447  else
448  Y_ = integrate( Y_, info->dt, A, B );
449 
450  g_ *= takeYpower_( Y_, Ypower_ );
451  }
452 
453  if ( Zpower_ > 0 ) {
454  zGate_->lookupBoth( depValue( Zdep0_ ), depValue( Zdep1_ ), &A, &B );
455  if ( instant_ & INSTANT_Z )
456  Z_ = A/B;
457  else
458  Z_ = integrate( Z_, info->dt, A, B );
459 
460  g_ *= takeZpower_( Z_, Zpower_ );
461  }
462 
463  ChanBase::setGk( e, g_ * vGetModulation( e ) );
464  updateIk();
465  // Gk_ = g_;
466  // Ik_ = ( Ek_ - Vm_ ) * g_;
467 
468  // Send out the relevant channel messages.
469  sendProcessMsgs( e, info );
470  g_ = 0.0;
471  }
472 
478  {
479  g_ = ChanBase::getGbar( er );
480  Element* e = er.element();
481 
482  double A = 0.0;
483  double B = 0.0;
484  if ( Xpower_ > 0 ) {
485  xGate_->lookupBoth( depValue( Xdep0_ ), depValue( Xdep1_ ), &A, &B );
486  if ( B < EPSILON ) {
487  cout << "Warning: B_ value for " << e->getName() <<
488  " is ~0. Check X table\n";
489  return;
490  }
491  if (!xInited_)
492  X_ = A/B;
493  g_ *= takeXpower_( X_, Xpower_ );
494  }
495 
496  if ( Ypower_ > 0 ) {
497  yGate_->lookupBoth( depValue( Ydep0_ ), depValue( Ydep1_ ), &A, &B );
498  if ( B < EPSILON ) {
499  cout << "Warning: B value for " << e->getName() <<
500  " is ~0. Check Y table\n";
501  return;
502  }
503  if (!yInited_)
504  Y_ = A/B;
505  g_ *= takeYpower_( Y_, Ypower_ );
506  }
507 
508  if ( Zpower_ > 0 ) {
509  zGate_->lookupBoth( depValue( Zdep0_ ), depValue( Zdep1_ ), &A, &B );
510  if ( B < EPSILON ) {
511  cout << "Warning: B value for " << e->getName() <<
512  " is ~0. Check Z table\n";
513  return;
514  }
515  if (!zInited_)
516  Z_ = A/B;
517  g_ *= takeZpower_( Z_, Zpower_ );
518  }
519 
520  ChanBase::setGk( er, g_ * vGetModulation( er ) );
521  updateIk();
522  // Gk_ = g_;
523  // Ik_ = ( Ek_ - Vm_ ) * g_;
524 
525  // Send out the relevant channel messages.
526  // Same for reinit as for process.
527  sendReinitMsgs( er, info );
528  g_ = 0.0;
529 }
530 
532 // Gate management stuff.
534 
535 bool HHChannel2D::setGatePower( const Eref& e, double power,
536  double *assignee, const string& gateType )
537 {
538  if ( power < 0 ) {
539  cout << "Error: HHChannel2D::set" << gateType <<
540  "power: Cannot use negative power: " << power << endl;
541  return 0;
542  }
543 
544  if ( doubleEq( power, *assignee ) )
545  return 0;
546 
547  if ( doubleEq( *assignee, 0.0 ) && power > 0 ) {
548  createGate( e, gateType );
549  } else if ( doubleEq( power, 0.0 ) ) {
550  destroyGate( e, gateType );
551  }
552 
553  *assignee = power;
554  return 1;
555 }
556 
563 void HHChannel2D::setXpower( const Eref& e, double Xpower )
564 {
565  if ( setGatePower( e, Xpower, &Xpower_, "X" ) )
566  takeXpower_ = selectPower( Xpower );
567 }
568 
569 void HHChannel2D::setYpower( const Eref& e, double Ypower )
570 {
571  if ( setGatePower( e, Ypower, &Ypower_, "Y" ) )
572  takeYpower_ = selectPower( Ypower );
573 }
574 
575 void HHChannel2D::setZpower( const Eref& e, double Zpower )
576 {
577  if ( setGatePower( e, Zpower, &Zpower_, "Z" ) )
578  takeZpower_ = selectPower( Zpower );
579 }
580 
596 // Assuming that the elements are simple elements. Use Eref for
597 // general case
598 
599 bool HHChannel2D::checkOriginal( Id chanId ) const
600 {
601  bool isOriginal = 1;
602  if ( xGate_ ) {
603  isOriginal = xGate_->isOriginalChannel( chanId );
604  } else if ( yGate_ ) {
605  isOriginal = yGate_->isOriginalChannel( chanId );
606  } else if ( zGate_ ) {
607  isOriginal = zGate_->isOriginalChannel( chanId );
608  }
609  return isOriginal;
610 }
611 
612 void HHChannel2D::innerCreateGate( const string& gateName,
613  HHGate2D** gatePtr, Id chanId, Id gateId )
614 {
615  //Shell* shell = reinterpret_cast< Shell* >( ObjId( Id(), 0 ).data() );
616  if ( *gatePtr ) {
617  cout << "Warning: HHChannel2D::createGate: '" << gateName <<
618  "' on Element '" << chanId.path() << "' already present\n";
619  return;
620  }
621  *gatePtr = new HHGate2D( chanId, gateId );
622 }
623 
625  string gateType )
626 {
627  if ( !checkOriginal( e.id() ) ) {
628  cout << "Warning: HHChannel2D::createGate: Not allowed from copied channel:\n" << e.id().path() << "\n";
629  return;
630  }
631 
632  if ( gateType == "X" )
633  innerCreateGate( "xGate", &xGate_, e.id(), Id(e.id().value() + 1) );
634  else if ( gateType == "Y" )
635  innerCreateGate( "yGate", &yGate_, e.id(), Id(e.id().value() + 2) );
636  else if ( gateType == "Z" )
637  innerCreateGate( "zGate", &zGate_, e.id(), Id(e.id().value() + 3) );
638  else
639  cout << "Warning: HHChannel2D::createGate: Unknown gate type '" <<
640  gateType << "'. Ignored\n";
641 }
642 
643 void HHChannel2D::innerDestroyGate( const string& gateName,
644  HHGate2D** gatePtr, Id chanId )
645 {
646  if ( *gatePtr == 0 ) {
647  cout << "Warning: HHChannel2D::destroyGate: '" << gateName <<
648  "' on Element '" << chanId.path() << "' not present\n";
649  return;
650  }
651  delete (*gatePtr);
652  *gatePtr = 0;
653 }
654 
656  string gateType )
657 {
658  if ( !checkOriginal( e.id() ) ) {
659  cout << "Warning: HHChannel2D::destroyGate: Not allowed from copied channel:\n" << e.id().path() << "\n";
660  return;
661  }
662 
663  if ( gateType == "X" )
664  innerDestroyGate( "xGate", &xGate_, e.id() );
665  else if ( gateType == "Y" )
666  innerDestroyGate( "yGate", &yGate_, e.id() );
667  else if ( gateType == "Z" )
668  innerDestroyGate( "zGate", &zGate_, e.id() );
669  else
670  cout << "Warning: HHChannel2D::destroyGate: Unknown gate type '" <<
671  gateType << "'. Ignored\n";
672 }
673 
674 double HHChannel2D::powerN( double x, double p )
675 {
676  if ( x > 0.0 )
677  return exp( p * log( x ) );
678  return 0.0;
679 }
680 
682 {
683  if ( power == 0.0 )
684  return powerN;
685  else if ( power == 1.0 )
686  return power1;
687  else if ( power == 2.0 )
688  return power2;
689  else if ( power == 3.0 )
690  return power3;
691  else if ( power == 4.0 )
692  return power4;
693  else
694  return powerN;
695 }
696 
698 // Unit tests
700 
701 #ifdef DO_UNIT_TESTS
702 
703 void testHHChannel2D2D()
704 {
705  ;
706 }
707 #endif
Id id() const
Definition: Eref.cpp:62
static const double EPSILON
HHGate2D for the zGate.
Definition: HHChannel2D.h:203
void setZindex(string index)
static const int INSTANT_X
Definition: HHChannel2D.h:204
bool xInited_
State variable for Z gate.
Definition: HHChannel2D.h:176
double getZpower(const Eref &e) const
double depValue(int dependency)
string getYindex() const
bool isOriginalChannel(Id id) const
Definition: HHGate2D.cpp:242
HHGate2D * yGate_
Definition: HHChannel2D.h:200
static double power1(double x, double p)
Definition: HHChannel2D.h:208
bool setGatePower(const Eref &e, double power, double *assignee, const string &gateType)
static const Cinfo * HHChannel2DCinfo
std::string path(const std::string &separator="/") const
Definition: Id.cpp:76
unsigned int value() const
Definition: Id.cpp:197
double vGetModulation(const Eref &e) const
Definition: ChanCommon.cpp:49
void setX(double X)
Definition: Dinfo.h:60
double(* PFDD)(double, double)
Definition: HHChannel2D.h:23
void setYpower(const Eref &e, double Ypower)
int instant_
Exponent for Z gate.
Definition: HHChannel2D.h:168
double Y_
State variable for X gate.
Definition: HHChannel2D.h:170
void setInstant(int Instant)
double Ypower_
Exponent for X gate.
Definition: HHChannel2D.h:164
HHGate2D * xGate_
Definition: HHChannel2D.h:199
double(* takeZpower_)(double, double)
Definition: HHChannel2D.h:115
unsigned int getNumZgates() const
Returns 1 if Z gate present, otherwise 0.
void setZpower(const Eref &e, double Zpower)
void setXpower(const Eref &e, double Xpower)
void innerDestroyGate(const string &gateName, HHGate2D **gatePtr, Id chanId)
double getYpower(const Eref &e) const
Element * element() const
Definition: Eref.h:42
void updateIk()
Definition: ChanCommon.cpp:119
HHGate2D * zGate_
HHGate2D for the yGate.
Definition: HHChannel2D.h:201
double Z_
State variable for Y gate.
Definition: HHChannel2D.h:171
static double power4(double x, double p)
Definition: HHChannel2D.h:217
void setXindex(string index)
int dependency(string index, unsigned int dim)
void log(string msg, serverity_level_ type=debug, bool redirectToConsole=true, bool removeTicks=true)
Log to console (and to a log-file)
string Zindex_
Definition: HHChannel2D.h:185
void setY(double Y)
void vReinit(const Eref &e, ProcPtr p)
void innerCreateGate(const string &gateName, HHGate2D **gatePtr, Id chanId, Id gateId)
Inner utility function for creating the gate.
int getInstant() const
void setYindex(string index)
void conc1(double conc)
void setGk(const Eref &e, double Gk)
Definition: ChanBase.cpp:216
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
static double power2(double x, double p)
Definition: HHChannel2D.h:211
double getZ() const
void setZ(double Z)
double Vm_
Vm_ is input variable from compartment, used for most rates.
Definition: ChanCommon.h:80
static const Cinfo * initCinfo()
Definition: HHChannel2D.cpp:23
string Xindex_
Definition: HHChannel2D.h:183
double(* takeYpower_)(double, double)
Definition: HHChannel2D.h:114
double conc1_
Internal variable used to calculate conductance.
Definition: HHChannel2D.h:180
static PFDD selectPower(double power)
bool checkOriginal(Id chanId) const
Returns true if channel is original, false if copy.
double dt
Definition: ProcInfo.h:18
HHGate2D * getYgate(unsigned int i)
Access function used for the Y gate. The index is ignored.
static const int INSTANT_Z
Definition: HHChannel2D.h:206
void createGate(const Eref &e, string gateType)
Definition: OpFunc.h:27
Definition: Eref.h:26
unsigned int getNumXgates() const
string getZindex() const
unsigned int getNumYgates() const
Returns 1 if Y gate present, otherwise 0.
void setNumGates(unsigned int num)
Dummy assignment function for the number of gates.
static double power3(double x, double p)
Definition: HHChannel2D.h:214
void conc2(double conc)
HHGate2D * getZgate(unsigned int i)
Access function used for the Z gate. The index is ignored.
string Yindex_
Definition: HHChannel2D.h:184
double integrate(double state, double dt, double A, double B)
void sendReinitMsgs(const Eref &e, const ProcPtr info)
Definition: ChanCommon.cpp:111
static const Cinfo * initCinfo()
Definition: HHGate2D.cpp:17
void lookupBoth(double v, double c, double *A, double *B) const
Definition: HHGate2D.cpp:208
double getXpower(const Eref &e) const
HHGate2D * getXgate(unsigned int i)
Access function used for the X gate. The index is ignored.
Definition: Id.h:17
double Zpower_
Exponent for Y gate.
Definition: HHChannel2D.h:165
static const int INSTANT_Y
Definition: HHChannel2D.h:205
double conc2_
Definition: HHChannel2D.h:181
double getY() const
void vProcess(const Eref &e, ProcPtr p)
void sendProcessMsgs(const Eref &e, const ProcPtr info)
Definition: ChanCommon.cpp:100
const string & getName() const
Definition: Element.cpp:56
double getGbar(const Eref &e) const
Definition: ChanBase.cpp:191
double Xpower_
Definition: HHChannel2D.h:163
string getXindex() const
static double powerN(double x, double p)
Definition: Cinfo.h:18
static const Cinfo * initCinfo()
Specify the Class Info static variable for initialization.
Definition: ChanBase.cpp:36
double(* takeXpower_)(double, double)
Definition: HHChannel2D.h:113
void destroyGate(const Eref &e, string gateType)
Definition: Finfo.h:12
double getX() const