#ifndef _HHChannel_h #define _HHChannel_h /********************************************************************** ** This program is part of 'MOOSE', the ** Messaging Object Oriented Simulation Environment, ** also known as GENESIS 3 base code. ** copyright (C) 2003-2014 Upinder S. Bhalla. and NCBS ** It is made available under the terms of the ** GNU Lesser General Public License version 2.1 ** See the file COPYING.LIB for the full notice. ********************************************************************* */ /** * The HHChannel class sets up a Hodkin-Huxley type ion channel. * The form used here is quite general and can handle up to 3 * gates, named X, Y and Z. The Z gate can be a function of * concentration as well as voltage. The gates are normally computed * using the form * * alpha(V) * closed <------------> open * beta(V) * * where the rates for the transition are alpha and beta, and both * are functions of V. * The state variables for each gate (X_, Y_, and Z_) are * the fraction in the open state. * * Gates can also be computed instantaneously, giving the instantaneous * ratio of alpha to beta rather than solving the above conversion * process. * The actual functions alpha and beta are provided by an auxiliary * class, the HHGate. The idea is that all copies of a channel share the * same gate, thus saving a great deal of space. It also makes it * possible to cleanly change the parameters of all the channels of * a give class, all at once. Should one want to mutate a subset * of channels, they just need to set up separate gates. * * HHGates are implemented as a special category of FieldElement, so that * they can be accessed as readonly pointers available to the HHChannel. * The FieldElement containing the HHGate appears as a child Element of * the HHChannel. The HHChannel Element can be an array; the associated * HHGate is a singleton. So there has to be a local copy of the HHGate * on each node. */ class HHChannel: public HHChannelBase, public ChanCommon { #ifdef DO_UNIT_TESTS friend void testHHChannel(); friend void testHHGateCreation(); #endif // DO_UNIT_TESTS public: HHChannel(); ~HHChannel(); ///////////////////////////////////////////////////////////// // Value field access function definitions ///////////////////////////////////////////////////////////// void vSetXpower( const Eref& e, double Xpower ); void vSetYpower( const Eref& e, double Ypower ); void vSetZpower( const Eref& e, double Zpower ); void vSetInstant( const Eref& e, int Instant ); int vGetInstant( const Eref& e ) const; void vSetX( const Eref& e, double X ); double vGetX( const Eref& e ) const; void vSetY( const Eref& e, double Y ); double vGetY( const Eref& e ) const; void vSetZ( const Eref& e, double Z ); double vGetZ( const Eref& e ) const; void vSetUseConcentration( const Eref& e, int value ); void vSetModulation( const Eref& e, double modulation ); double vGetModulation( const Eref& e ) const; void innerSetXpower( double Xpower ); void innerSetYpower( double Ypower ); void innerSetZpower( double Zpower ); ///////////////////////////////////////////////////////////// // Dest function definitions ///////////////////////////////////////////////////////////// /** * processFunc handles the update and calculations every * clock tick. It first sends the request for evaluation of * the gate variables to the respective gate objects and * recieves their response immediately through a return * message. This is done so that many channel instances can * share the same gate lookup tables, but do so cleanly. * Such messages should never go to a remote node. * Then the function does its own little calculations to * send back to the parent compartment through regular * messages. */ void vProcess( const Eref& e, ProcPtr p ); /** * Reinitializes the values for the channel. This involves * computing the steady-state value for the channel gates * using the provided Vm from the parent compartment. It * involves a similar cycle through the gates and then * updates to the parent compartment as for the processFunc. */ void vReinit( const Eref& e, ProcPtr p ); /** * Assign the local Vm_ to the incoming Vm from the compartment void handleVm( double Vm ); */ /** * Assign the local conc_ to the incoming conc from the * concentration calculations for the compartment. Typically * the message source will be a CaConc object, but there * are other options for computing the conc. */ void vHandleConc( const Eref& e, double conc ); ///////////////////////////////////////////////////////////// // Gate handling functions ///////////////////////////////////////////////////////////// /** * Access function used for the X gate. The index is ignored. */ HHGate* vGetXgate( unsigned int i ) const; /** * Access function used for the Y gate. The index is ignored. */ HHGate* vGetYgate( unsigned int i ) const; /** * Access function used for the Z gate. The index is ignored. */ HHGate* vGetZgate( unsigned int i ) const; /// Inner utility function for creating the gate. void innerCreateGate( const string& gateName, HHGate** gatePtr, Id chanId, Id gateId ); /// Returns true if channel is original, false if copy. bool checkOriginal( Id chanId ) const; void vCreateGate( const Eref& e, string gateType ); /** * Utility function for destroying gate. Works only on original * HHChannel. Somewhat dangerous, should never be used after a * copy has been made as the pointer of the gate will be in use * elsewhere. */ void destroyGate( const Eref& e, string gateType ); /** * Inner utility for destroying the gate */ void innerDestroyGate( const string& gateName, HHGate** gatePtr, Id chanId ); /** * Utility for altering gate powers */ bool setGatePower( const Eref& e, double power, double* assignee, const string& gateType ); ///////////////////////////////////////////////////////////// static const Cinfo* initCinfo(); private: /// Conc_ is input variable for Ca-dependent channels. double conc_; double ( *takeXpower_ )( double, double ); double ( *takeYpower_ )( double, double ); double ( *takeZpower_ )( double, double ); /// bitmapped flag for X, Y, Z, to do equil calculation for gate int instant_; /// Channel actual conductance depending on opening of gates. /// State variable for X gate double X_; /// State variable for Y gate double Y_; /// State variable for Z gate double Z_; bool xInited_, yInited_, zInited_; // true when a state variable // has been initialized double g_; /// Internal variable used to calculate conductance double integrate( double state, double dt, double A, double B ); /** * HHGate data structure for the xGate. This is writable only * on the HHChannel that originally created the HHGate, for others * it must be treated as readonly. */ HHGate* xGate_; /// HHGate data structure for the yGate. HHGate* yGate_; /// HHGate data structure for the yGate. HHGate* zGate_; Id myId_; static const double EPSILON; static const int INSTANT_X; static const int INSTANT_Y; static const int INSTANT_Z; }; #endif // _HHChannel_h