MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CompartmentBase.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 "CompartmentBase.h"
13 #include "CompartmentDataHolder.h"
14 #include "../shell/Wildcard.h"
15 
16 static const double RANGE = 4.0e-17;
17 using namespace moose;
18 
19 /*
20  * This Finfo is used to send out Vm to channels, spikegens, etc.
21  *
22  * It is exposed here so that HSolve can also use it to send out
23  * the Vm to the recipients.
24  */
25 // Static function.
27  static SrcFinfo1< double > VmOut( "VmOut",
28  "Sends out Vm value of compartment on each timestep" );
29  return &VmOut;
30 }
31 
32 // Here we send out Vm, but to a different subset of targets. So we
33 // have to define a new SrcFinfo even though the contents of the msg
34 // are still only Vm.
35 
37  static SrcFinfo1< double > axialOut( "axialOut",
38  "Sends out Vm value of compartment to adjacent compartments,"
39  "on each timestep" );
40  return &axialOut;
41 }
42 
44 {
45  static SrcFinfo2< double, double > raxialOut( "raxialOut",
46  "Sends out Raxial information on each timestep, "
47  "fields are Ra and Vm" );
48  return &raxialOut;
49 }
50 
60 {
62  // Shared messages
64  static DestFinfo process( "process",
65  "Handles 'process' call",
67 
68  static DestFinfo reinit( "reinit",
69  "Handles 'reinit' call",
71 
72  static Finfo* processShared[] =
73  {
74  &process, &reinit
75  };
76 
77  static SharedFinfo proc( "proc",
78  "This is a shared message to receive Process messages from the scheduler"
79  "objects. The Process should be called _second_ in each clock tick, after the Init message."
80  "The first entry in the shared msg is a MsgDest "
81  "for the Process operation. It has a single argument, "
82  "ProcInfo, which holds lots of information about current "
83  "time, thread, dt and so on. The second entry is a MsgDest "
84  "for the Reinit operation. It also uses ProcInfo. "
85  "- Handles 'reinit' and 'process' calls.",
86  processShared, sizeof( processShared ) / sizeof( Finfo* )
87  );
89 
90  static DestFinfo initProc( "initProc",
91  "Handles Process call for the 'init' phase of the CompartmentBase "
92  "calculations. These occur as a separate Tick cycle from the "
93  "regular proc cycle, and should be called before the proc msg.",
95  static DestFinfo initReinit( "initReinit",
96  "Handles Reinit call for the 'init' phase of the CompartmentBase "
97  "calculations.",
99  static Finfo* initShared[] =
100  {
101  &initProc, &initReinit
102  };
103 
104  static SharedFinfo init( "init",
105  "This is a shared message to receive Init messages from "
106  "the scheduler objects. Its job is to separate the "
107  "compartmental calculations from the message passing. "
108  "It doesn't really need to be shared, as it does not use "
109  "the reinit part, but the scheduler objects expect this "
110  "form of message for all scheduled output. The first "
111  "entry is a MsgDest for the Process operation. It has a "
112  "single argument, ProcInfo, which holds lots of "
113  "information about current time, thread, dt and so on. "
114  "The second entry is a dummy MsgDest for the Reinit "
115  "operation. It also uses ProcInfo. "
116  "- Handles 'initProc' and 'initReinit' calls.",
117  initShared, sizeof( initShared ) / sizeof( Finfo* )
118  );
119 
121 
122  static DestFinfo handleChannel( "handleChannel",
123  "Handles conductance and Reversal potential arguments from Channel",
125  // VmOut is declared above as it needs to be in scope for later funcs.
126 
127  static Finfo* channelShared[] =
128  {
130  };
131  static SharedFinfo channel( "channel",
132  "This is a shared message from a compartment to channels. "
133  "The first entry is a MsgDest for the info coming from "
134  "the channel. It expects Gk and Ek from the channel "
135  "as args. The second entry is a MsgSrc sending Vm "
136  "- Handles 'handleChannel' and 'VmOut' calls.",
137  channelShared, sizeof( channelShared ) / sizeof( Finfo* )
138  );
140  // axialOut declared above as it is needed in file scope
141  static DestFinfo handleRaxial( "handleRaxial",
142  "Handles Raxial info: arguments are Ra and Vm.",
145  );
146 
147  static Finfo* axialShared[] =
148  {
149  axialOut(), &handleRaxial
150  };
151  static SharedFinfo axial( "axial",
152  "This is a shared message between asymmetric compartments. "
153  "axial messages (this kind) connect up to raxial "
154  "messages (defined below). The soma should use raxial "
155  "messages to connect to the axial message of all the "
156  "immediately adjacent dendritic compartments.This puts "
157  "the (low) somatic resistance in series with these "
158  "dendrites. Dendrites should then use raxial messages to"
159  "connect on to more distal dendrites. In other words, "
160  "raxial messages should face outward from the soma. "
161  "The first entry is a MsgSrc sending Vm to the axialFunc"
162  "of the target compartment. The second entry is a MsgDest "
163  "for the info coming from the other compt. It expects "
164  "Ra and Vm from the other compt as args. Note that the "
165  "message is named after the source type. "
166  "- Handles 'axialOut' and 'handleRaxial' calls.",
167  axialShared, sizeof( axialShared ) / sizeof( Finfo* )
168  );
169 
171  static DestFinfo handleAxial( "handleAxial",
172  "Handles Axial information. Argument is just Vm.",
174  // rxialOut declared above as it is needed in file scope
175  static Finfo* raxialShared[] =
176  {
178  };
179  static SharedFinfo raxial( "raxial",
180  "This is a raxial shared message between asymmetric compartments. The \n"
181  "first entry is a MsgDest for the info coming from the other compt. It \n"
182  "expects Vm from the other compt as an arg. The second is a MsgSrc sending \n"
183  "Ra and Vm to the raxialFunc of the target compartment. \n"
184  "- Handles 'handleAxial' and 'raxialOut' calls.",
185  raxialShared, sizeof( raxialShared ) / sizeof( Finfo* )
186  );
188  // Value Finfos.
190 
192  "membrane potential",
195  );
197  "Membrane capacitance",
200  );
202  "Resting membrane potential",
205  );
207  "Current going through membrane",
209  );
210  static ElementValueFinfo< CompartmentBase, double > inject( "inject",
211  "Current injection to deliver into compartment",
214  );
215  static ElementValueFinfo< CompartmentBase, double > initVm( "initVm",
216  "Initial value for membrane potential",
219  );
221  "Membrane resistance",
224  );
226  "Axial resistance of compartment",
229  );
230  static ValueFinfo< CompartmentBase, double > diameter( "diameter",
231  "Diameter of compartment",
234  );
235  static ValueFinfo< CompartmentBase, double > length( "length",
236  "Length of compartment",
239  );
241  "X coordinate of start of compartment",
244  );
246  "Y coordinate of start of compartment",
249  );
251  "Z coordinate of start of compartment",
254  );
256  "x coordinate of end of compartment",
259  );
261  "y coordinate of end of compartment",
264  );
266  "z coordinate of end of compartment",
269  );
270 
272  // DestFinfo definitions
274  static DestFinfo injectMsg( "injectMsg",
275  "The injectMsg corresponds to the INJECT message in the "
276  "GENESIS compartment. Unlike the 'inject' field, any value "
277  "assigned by handleInject applies only for a single timestep."
278  "So it needs to be updated every dt for a steady (or varying)"
279  "injection current",
281  );
282 
283  static DestFinfo randInject( "randInject",
284  "Sends a random injection current to the compartment. Must be"
285  "updated each timestep."
286  "Arguments to randInject are probability and current.",
289 
290  static DestFinfo cable( "cable",
291  "Message for organizing compartments into groups, called"
292  "cables. Doesn't do anything.",
294  );
295  static DestFinfo displace( "displace",
296  "Displaces compartment by specified vector",
299  );
300  static DestFinfo setGeomAndElec( "setGeomAndElec",
301  "Assigns length and dia and accounts for any electrical "
302  "scaling needed as a result.",
305  );
307  static Finfo* compartmentFinfos[] =
308  {
309  &Vm, // Value
310  &Cm, // Value
311  &Em, // Value
312  &Im, // ReadOnlyValue
313  &inject, // Value
314  &initVm, // Value
315  &Rm, // Value
316  &Ra, // Value
317  &diameter, // Value
318  &length, // Value
319  &x0, // Value
320  &y0, // Value
321  &z0, // Value
322  &x, // Value
323  &y, // Value
324  &z, // Value
325  &injectMsg, // DestFinfo
326  &randInject, // DestFinfo
327  &injectMsg, // DestFinfo
328  &cable, // DestFinfo
329  &displace, // DestFinfo
330  &setGeomAndElec, // DestFinfo
331  &proc, // SharedFinfo
332  &init, // SharedFinfo
333  &channel, // SharedFinfo
334  &axial, // SharedFinfo
335  &raxial // SharedFinfo
336  };
337 
338  static string doc[] =
339  {
340  "Name", "CompartmentBase",
341  "Author", "Upi Bhalla",
342  "Description", "CompartmentBase object, for branching neuron models.",
343  };
344  static ZeroSizeDinfo< int > dinfo;
345  static Cinfo compartmentCinfo(
346  "CompartmentBase",
348  compartmentFinfos,
349  sizeof( compartmentFinfos ) / sizeof( Finfo* ),
350  &dinfo,
351  doc,
352  sizeof(doc)/sizeof(string)
353  );
354 
355  return &compartmentCinfo;
356 }
357 
359 
361 // Here we put the CompartmentBase class functions.
363 
365 {
366  x_ = 0.0;
367  y_ = 0.0;
368  z_ = 0.0;
369  x0_ = 0.0;
370  y0_ = 0.0;
371  z0_ = 0.0;
372  diameter_ = 0.0;
373  length_ = 0.0;
374 }
375 
377 {
378  ;
379 }
380 
381 bool CompartmentBase::rangeWarning( const string& field, double value )
382 {
383  if ( value < RANGE ) {
384  cout << "Warning: Ignored attempt to set " << field <<
385  " of compartment " <<
386  // c->target().e->name() <<
387  " to " << value << " as it is less than " << RANGE << endl;
388  return 1;
389  }
390  return 0;
391 }
392 
393 // Value Field access function definitions.
394 void CompartmentBase::setVm( const Eref& e, double Vm )
395 {
396  vSetVm( e, Vm );
397 }
398 
399 double CompartmentBase::getVm( const Eref& e ) const
400 {
401  return vGetVm( e );
402 }
403 
404 void CompartmentBase::setEm( const Eref& e, double Em )
405 {
406  vSetEm( e, Em );
407 }
408 
409 double CompartmentBase::getEm( const Eref& e ) const
410 {
411  return vGetEm( e );
412 }
413 
414 void CompartmentBase::setCm( const Eref& e, double Cm )
415 {
416  if ( rangeWarning( "Cm", Cm ) ) return;
417  vSetCm( e, Cm );
418 }
419 
420 double CompartmentBase::getCm( const Eref& e ) const
421 {
422  return vGetCm( e );
423 }
424 
425 void CompartmentBase::setRm( const Eref& e, double Rm )
426 {
427  if ( rangeWarning( "Rm", Rm ) ) return;
428  vSetRm( e, Rm );
429 }
430 
431 double CompartmentBase::getRm( const Eref& e ) const
432 {
433  return vGetRm( e );
434 }
435 
436 void CompartmentBase::setRa( const Eref& e, double Ra )
437 {
438  if ( rangeWarning( "Ra", Ra ) ) return;
439  vSetRa( e, Ra );
440 }
441 
442 double CompartmentBase::getRa( const Eref& e ) const
443 {
444  return vGetRa( e );
445 }
446 
447 double CompartmentBase::getIm( const Eref& e ) const
448 {
449  return vGetIm( e );
450 }
451 
452 void CompartmentBase::setInject( const Eref& e, double Inject )
453 {
454  vSetInject( e, Inject );
455 }
456 
457 double CompartmentBase::getInject( const Eref& e ) const
458 {
459  return vGetInject( e );
460 }
461 
462 void CompartmentBase::setInitVm( const Eref& e, double initVm )
463 {
464  vSetInitVm( e, initVm );
465 }
466 
467 double CompartmentBase::getInitVm( const Eref& e ) const
468 {
469  return vGetInitVm( e );
470 }
471 
473 {
474  diameter_ = value;
475 }
476 
478 {
479  return diameter_;
480 }
481 
483 {
484  // If length is assigned correctly, also redo the end coords to match.
485  if ( value > 0 && length_ > 0 &&
487  (x_-x0_)*(x_-x0_) + (y_-y0_)*(y_-y0_) + (z_-z0_)*(z_-z0_) ) ) {
488  double ratio = value / length_;
489  x_ = x0_ + ratio * ( x_ - x0_ );
490  y_ = y0_ + ratio * ( y_ - y0_ );
491  z_ = z0_ + ratio * ( z_ - z0_ );
492  }
493 
494  length_ = value;
495 }
496 
498 {
499  return length_;
500 }
501 
503 {
504  length_ = sqrt( (x_-x0_)*(x_-x0_) +
505  (y_-y0_)*(y_-y0_) + (z_-z0_)*(z_-z0_) );
506 }
507 
509 {
510  x0_ = value;
511  updateLength();
512 }
513 
515 {
516  return x0_;
517 }
518 
520 {
521  y0_ = value;
522  updateLength();
523 }
524 
526 {
527  return y0_;
528 }
529 
531 {
532  z0_ = value;
533  updateLength();
534 }
535 
537 {
538  return z0_;
539 }
540 
542 {
543  x_ = value;
544  updateLength();
545 }
546 
547 double CompartmentBase::getX() const
548 {
549  return x_;
550 }
551 
553 {
554  y_ = value;
555  updateLength();
556 }
557 
558 double CompartmentBase::getY() const
559 {
560  return y_;
561 }
562 
564 {
565  z_ = value;
566  updateLength();
567 }
568 
569 double CompartmentBase::getZ() const
570 {
571  return z_;
572 }
573 
575 // CompartmentBase::Dest function definitions.
577 
579 {
580  vProcess( e, p );
581 }
582 
584 {
585  vReinit( e, p );
586 }
587 
589 {
590  vInitProc( e, p );
591 }
592 
594 {
595  vInitReinit( e, p );
596 }
597 
598 void CompartmentBase::handleChannel( const Eref& e, double Gk, double Ek)
599 {
600  vHandleChannel( e, Gk, Ek );
601 }
602 
603 void CompartmentBase::handleRaxial( double Ra, double Vm)
604 {
605  vHandleRaxial( Ra, Vm );
606 }
607 
609 {
610  vHandleAxial( Vm );
611 }
612 
613 void CompartmentBase::injectMsg( const Eref& e, double current)
614 {
615  vInjectMsg( e, current );
616 }
617 
618 void CompartmentBase::randInject( const Eref& e, double prob, double current)
619 {
620  vRandInject( e, prob, current );
621 }
622 
624 {
625  ;
626 }
627 
628 void CompartmentBase::displace( double dx, double dy, double dz )
629 {
630  x0_ += dx;
631  x_ += dx;
632  y0_ += dy;
633  y_ += dy;
634  z0_ += dz;
635  z_ += dz;
636 }
637 
638 static bool hasScaleFormula( const Eref& e ) {
639  vector< Id > kids;
640  Neutral::children( e, kids );
641  for ( vector< Id >::iterator j = kids.begin(); j != kids.end(); j++ )
642  if ( j->element()->getName() == "scaleFormula" )
643  return true;
644  return false;
645 }
646 
648  double len, double dia )
649 {
650  if ( length_ > 0 && diameter_ > 0 && len > 0 && dia > 0 &&
652  (x_-x0_)*(x_-x0_) + (y_-y0_)*(y_-y0_) + (z_-z0_)*(z_-z0_) ) ) {
653  vSetRm( e, vGetRm( e ) * diameter_ * length_ / ( dia * len ) );
654  vSetCm( e, vGetCm( e ) * dia * len / ( diameter_ * length_ ) );
655  vSetRa( e, vGetRa( e ) * len * (diameter_ * diameter_) /
656  ( length_ * dia * dia ) );
657  // Rescale channel Gbars here
658  vector< ObjId > chans;
659  allChildren( e.objId(), ALLDATA, "ISA=ChanBase", chans );
660  for ( unsigned int i = 0; i < chans.size(); ++i ) {
661  if ( hasScaleFormula( chans[i].eref() ) )
662  continue; // Later we will eval the formula with len and dia
663  double gbar = Field< double >::get( chans[i], "Gbar" );
664  gbar *= len * dia / ( length_ * diameter_ );
665  Field< double >::set( chans[i], "Gbar", gbar );
666  }
667  // Rescale CaConc sizes here
668  vector< ObjId > concs;
669  allChildren( e.objId(), ALLDATA, "ISA=CaConcBase", concs );
670  for ( unsigned int i = 0; i < concs.size(); ++i ) {
671  Field< double >::set( concs[i], "length", len );
672  Field< double >::set( concs[i], "diameter", dia );
673  }
674 
675  setLength( len );
676  setDiameter( dia );
677  }
678 }
679 
681 // CompartmentBase::Zombification.
683 
684 // Dummy instantiation of vSetSolve, does nothing
685 void CompartmentBase::vSetSolver( const Eref& e, Id hsolve )
686 {;}
687 
688 // static func
689 void CompartmentBase::zombify( Element* orig, const Cinfo* zClass,
690  Id hsolve )
691 {
692  if ( orig->cinfo() == zClass )
693  return;
694  unsigned int start = orig->localDataStart();
695  unsigned int num = orig->numLocalData();
696  if ( num == 0 )
697  return;
698  vector< CompartmentDataHolder > cdh( num );
699 
700  for ( unsigned int i = 0; i < num; ++i ) {
701  Eref er( orig, i + start );
702  const CompartmentBase* cb =
703  reinterpret_cast< const CompartmentBase* >( er.data() );
704  cdh[i].readData( cb, er );
705  }
706  orig->zombieSwap( zClass );
707  for ( unsigned int i = 0; i < num; ++i ) {
708  Eref er( orig, i + start );
709  CompartmentBase* cb = reinterpret_cast< CompartmentBase* >( er.data() );
710  cb->vSetSolver( er, hsolve );
711  cdh[i].writeData( cb, er );
712  }
713 }
714 
virtual void vInitProc(const Eref &e, ProcPtr p)=0
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
Definition: main.cpp:150
void setX(double value)
virtual void vHandleAxial(double Vm)=0
char * data() const
Definition: Eref.cpp:41
uint32_t value
Definition: moosemodule.h:42
static const Cinfo * compartmentBaseCinfo
double getVm(const Eref &e) const
void setVm(const Eref &e, double Vm)
void process(const Eref &e, ProcPtr p)
double getInject(const Eref &e) const
void setZ(double value)
double getEm(const Eref &e) const
virtual void vRandInject(const Eref &e, double prob, double current)=0
Definition: OpFunc.h:56
virtual void vSetInject(const Eref &e, double Inject)=0
void handleRaxial(double Ra, double Vm)
Definition: EpFunc.h:64
static const double RANGE
double getDiameter() const
void setLength(double length)
virtual void zombieSwap(const Cinfo *zCinfo)
virtual func, this base version must be called by all derived classes
Definition: Element.cpp:159
static const Cinfo * compartmentCinfo
Definition: Compartment.cpp:53
virtual void vSetCm(const Eref &e, double Cm)=0
virtual double vGetRm(const Eref &e) const =0
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
virtual double vGetInject(const Eref &e) const =0
virtual void vSetEm(const Eref &e, double Em)=0
virtual double vGetRa(const Eref &e) const =0
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:245
virtual void vSetVm(const Eref &e, double Vm)=0
bool rangeWarning(const string &field, double value)
void randInject(const Eref &e, double prob, double current)
virtual void vSetRm(const Eref &e, double Rm)=0
static bool hasScaleFormula(const Eref &e)
Definition: OpFunc.h:40
virtual double vGetCm(const Eref &e) const =0
const unsigned int ALLDATA
Used by ObjId and Eref.
Definition: consts.cpp:22
virtual void vProcess(const Eref &e, ProcPtr p)=0
double getCm(const Eref &e) const
void setInitVm(const Eref &e, double initVm)
void setEm(const Eref &e, double Em)
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
virtual double vGetVm(const Eref &e) const =0
void setGeomAndElec(const Eref &e, double length, double dia)
Scales electrical values along with setting length, dia.
double getInitVm(const Eref &e) const
void handleChannel(const Eref &e, double Gk, double Ek)
void initReinit(const Eref &e, ProcPtr p)
virtual void vSetRa(const Eref &e, double Ra)=0
void initProc(const Eref &e, ProcPtr p)
void setCm(const Eref &e, double Cm)
double getIm(const Eref &e) const
virtual double vGetEm(const Eref &e) const =0
virtual void vHandleChannel(const Eref &e, double Gk, double Ek)=0
ObjId objId() const
Definition: Eref.cpp:57
Definition: OpFunc.h:27
Definition: Eref.h:26
int allChildren(ObjId start, unsigned int index, const string &insideBrace, vector< ObjId > &ret)
Definition: Wildcard.cpp:495
const Cinfo * cinfo() const
Definition: Element.cpp:66
void displace(double dx, double dy, double dz)
Displaces compartment by specified distance vector.
void setInject(const Eref &e, double Inject)
virtual void vReinit(const Eref &e, ProcPtr p)=0
virtual double vGetIm(const Eref &e) const =0
virtual unsigned int localDataStart() const =0
Returns index of first data entry on this node.
virtual unsigned int numLocalData() const =0
Returns number of local data entries on this node.
void handleAxial(double Vm)
static void zombify(Element *orig, const Cinfo *zClass, Id hsolve)
void setZ0(double value)
static SrcFinfo1< double > * VmOut()
double getRa(const Eref &e) const
static SrcFinfo2< double, double > * raxialOut()
static SrcFinfo1< double > * axialOut()
virtual void vInjectMsg(const Eref &e, double current)=0
virtual void vSetInitVm(const Eref &e, double initVm)=0
void setDiameter(double diameter)
Definition: Id.h:17
virtual void vInitReinit(const Eref &e, ProcPtr p)=0
void reinit(const Eref &e, ProcPtr p)
Definition: OpFunc.h:13
virtual void vHandleRaxial(double Ra, double Vm)=0
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
void injectMsg(const Eref &e, double current)
virtual double vGetInitVm(const Eref &e) const =0
void setRa(const Eref &e, double Ra)
void setX0(double value)
double getRm(const Eref &e) const
Definition: Cinfo.h:18
static const Cinfo * initCinfo()
void setRm(const Eref &e, double Rm)
Definition: EpFunc.h:79
virtual void vSetSolver(const Eref &e, Id hsolve)
void setY0(double value)
Definition: Finfo.h:12
void setY(double value)