/** * In this destructor we need to put messages back to process, * and we need to replace the SolveFinfos on zombies with the * original ThisFinfo. This should really just use the clearFunc. */ void HSolveHub::destroy( const Conn* c ) { static Finfo* origCompartmentFinfo = const_cast< Finfo* >( initCompartmentCinfo()->getThisFinfo() ); static Finfo* origHHChannelFinfo = const_cast< Finfo* >( initHHChannelCinfo()->getThisFinfo() ); Element* hub = c->target().e; unsigned int eIndex = c->target().i; Conn* i = hub->targets( compartmentSolveFinfo->msg(), eIndex ); while ( i->good() ) { i->target().e->setThisFinfo( origCompartmentFinfo ); i->increment(); } delete i; i = hub->targets( hhchannelSolveFinfo->msg(), eIndex ); while ( i->good() ) { i->target().e->setThisFinfo( origHHChannelFinfo ); i->increment(); } delete i; Neutral::destroy( c ); }
Finfo* initHHChannelZombieFinfo() { static Finfo* hhchannelFields[] = { new ValueFinfo( "Gbar", ValueFtype1< double >::global(), GFCAST( &HSolveHub::getHHChannelGbar ), RFCAST( &HSolveHub::setHHChannelGbar ) ), new ValueFinfo( "Ek", ValueFtype1< double >::global(), GFCAST( &HSolveHub::getEk ), RFCAST( &HSolveHub::setEk ) ), new ValueFinfo( "Gk", ValueFtype1< double >::global(), GFCAST( &HSolveHub::getGk ), RFCAST( &HSolveHub::setGk ) ), new ValueFinfo( "Ik", ValueFtype1< double >::global(), GFCAST( &HSolveHub::getIk ), &dummyFunc ), new ValueFinfo( "X", ValueFtype1< double >::global(), GFCAST( &HSolveHub::getX ), RFCAST( &HSolveHub::setX ) ), new ValueFinfo( "Y", ValueFtype1< double >::global(), GFCAST( &HSolveHub::getY ), RFCAST( &HSolveHub::setY ) ), new ValueFinfo( "Z", ValueFtype1< double >::global(), GFCAST( &HSolveHub::getZ ), RFCAST( &HSolveHub::setZ ) ), }; static const ThisFinfo* tf = dynamic_cast< const ThisFinfo* >( initHHChannelCinfo()->getThisFinfo() ); assert( tf != 0 ); static SolveFinfo hhchannelZombieFinfo( hhchannelFields, sizeof( hhchannelFields ) / sizeof( Finfo* ), tf ); return &hhchannelZombieFinfo; }
static const Finfo* hubCompartmentChannelFinfo = initHSolveHubCinfo()->findFinfo( "compartmentChannel" ); /* * Finfos from biophysical objects. Needed so that 'set' operations are done * on the solver as well as the objects. Also needed for redirecting any dest * messages on these finfos to the solver (e.g.: to the inject field). */ static const Finfo* compartmentInjectFinfo = initCompartmentCinfo()->findFinfo( "injectMsg" ); static const Finfo* compartmentChannelFinfo = initCompartmentCinfo()->findFinfo( "channel" ); static const Finfo* compartmentVmFinfo = initCompartmentCinfo()->findFinfo( "Vm" ); static const Finfo* channelGbarFinfo = initHHChannelCinfo()->findFinfo( "Gbar" ); static const Finfo* channelEkFinfo = initHHChannelCinfo()->findFinfo( "Ek" ); static const Finfo* channelGkFinfo = initHHChannelCinfo()->findFinfo( "Gk" ); static const Finfo* channelXFinfo = initHHChannelCinfo()->findFinfo( "X" ); static const Finfo* channelYFinfo = initHHChannelCinfo()->findFinfo( "Y" ); static const Finfo* channelZFinfo = initHHChannelCinfo()->findFinfo( "Z" ); static const Finfo* caConcCaFinfo = initCaConcCinfo()->findFinfo( "Ca" ); ///////////////////////////////////////////////////////////////////////// // Replacement fields for aspiring zombies /////////////////////////////////////////////////////////////////////////
void adaptSig2Chan( TreeNode& t, map< string, Element* >& m, unsigned int offset, const string& mol, Id chanId ) { static const Finfo* inputFinfo = initAdaptorCinfo()->findFinfo( "input" ); static const Finfo* outputFinfo = initAdaptorCinfo()->findFinfo( "outputSrc" ); static const Finfo* scaleFinfo = initAdaptorCinfo()->findFinfo( "scale" ); static const Finfo* inputOffsetFinfo = initAdaptorCinfo()->findFinfo( "inputOffset" ); static const Finfo* outputOffsetFinfo = initAdaptorCinfo()->findFinfo( "outputOffset" ); // Not sure if these update when solved static const Finfo* molNumFinfo = initMoleculeCinfo()->findFinfo( "nSrc" ); static const Finfo* nInitFinfo = initMoleculeCinfo()->findFinfo( "nInit" ); // This isn't yet a separate destMsg. Again, issue with update. static const Finfo* hhChanGbarFinfo = initHHChannelCinfo()->findFinfo( "Gbar" ); static const Finfo* synChanGbarFinfo = initSynChanCinfo()->findFinfo( "Gbar" ); // Set up the correct Finfo. Complain if we try to connect up an // unknown chan type. const Finfo* gbarFinfo = 0; if ( chanId()->cinfo()->isA( initHHChannelCinfo() ) ) gbarFinfo = hhChanGbarFinfo; if ( chanId()->cinfo()->isA( initSynChanCinfo() ) ) gbarFinfo = synChanGbarFinfo; if ( gbarFinfo == 0 ) { cout << "Error: attempt to set up adaptor from signaling to \n" << " biophysics for an unknown channel type: " << chanId()->cinfo()->name() << endl << "for channel " << chanId.path() << endl; return; } // Look up matching molecule map< string, Element* >::iterator i = m.find( mol ); if ( i != m.end() ) { Element* e = i->second; // cout << "Adding adaptor from " << e->name() << " to " << chanId.path() << endl; assert( t.sigStart >= offset ); assert( t.sigEnd - offset <= e->numEntries() ); // Create the adaptor string name = "adapt_" + mol + "_2_" + chanId.eref().e->name(); Element* adaptor = Neutral::create( "Adaptor", name, t.compt, Id::childId( t.compt ) ); assert( adaptor != 0 ); Eref adaptorE( adaptor, 0 ); double n = 0.00; Eref MolE( e, t.sigStart - offset ); bool ret = get< double >( e, nInitFinfo, n ); assert( ret ); if ( n > 0.0 ) { double gbar = 0.0; ret = get< double >( chanId.eref(), gbarFinfo, gbar ); assert( ret ); double scale = gbar / n; ret = set< double >( adaptorE, scaleFinfo, scale ); assert( ret ); } ret = set< double >( adaptorE, inputOffsetFinfo, 0.0 ); assert( ret ); ret = set< double >( adaptorE, outputOffsetFinfo, 0.0 ); assert( ret ); for ( unsigned int j = t.sigStart; j < t.sigEnd; ++j ) { // Connect up the adaptor. Eref molE( e, j - offset ); ret = molE.add( molNumFinfo->msg(), adaptorE, inputFinfo->msg(), ConnTainer::Default ); assert( ret ); // Here we set the parameters of the adaptor. } ret = adaptorE.add( outputFinfo->msg(), chanId.eref(), gbarFinfo->msg(), ConnTainer::Default ); assert( ret ); } }