void ReadKkit::setupSlaveMsg( const string& src, const string& dest ) { // Convert the pool to a BufPool, if it isn't one already Id destId( basePath_ + "/kinetics/" + dest ); assert( destId != Id() ); if( !destId.element()->cinfo()->isA( "BufPool" )) { destId.element()->zombieSwap( BufPool::initCinfo() ); } map< string, Id >* nameMap; // Check if the src is a table or a stim Id srcId( basePath_ + "/kinetics/" + src ); assert( srcId != Id() ); string output = "output"; if ( srcId.element()->cinfo()->isA( "TableBase" ) ) { nameMap = &tabIds_; } else if ( srcId.element()->cinfo()->isA( "PulseGen" ) ) { nameMap = &stimIds_; output = "output"; } else { cout << "Error: Unknown source for SLAVE msg: (" << src << ", " << dest << ")\n"; return; } // NSLAVE is 1, CONCSLAVE is 2. map< Id, int >::iterator i = poolFlags_.find( destId ); if ( i == poolFlags_.end() || !( i->second & 2 ) ) { innerAddMsg( src, *nameMap, output, dest, poolIds_, "setNInit" ); } else { innerAddMsg( src, *nameMap, output, dest, poolIds_, "setConcInit" ); double CONCSCALE = 0.001; // Rescale from uM to millimolar. if ( nameMap == &tabIds_ ) { SetGet2< double, double >::set( srcId, "linearTransform", CONCSCALE, 0 ); } else if ( nameMap == &stimIds_ ) { double x = Field< double >::get( srcId, "baseLevel" ); Field< double >::set( srcId, "baseLevel", x * CONCSCALE ); x = Field< double >::get( srcId, "firstLevel" ); Field< double >::set( srcId, "firstLevel", x * CONCSCALE ); x = Field< double >::get( srcId, "secondLevel" ); Field< double >::set( srcId, "secondLevel", x * CONCSCALE ); } } // cout << "Added slave msg from " << src << " to " << dest << endl; }
ObjId Shell::doAddMsg( const string& msgType, ObjId src, const string& srcField, ObjId dest, const string& destField ) { #ifdef ENABLE_LOGGER clock_t t = clock(); #endif if ( !src.id.element() ) { cout << myNode_ << ": Error: Shell::doAddMsg: src not found" << endl; return ObjId(); } if ( !dest.id.element() ) { cout << myNode_ << ": Error: Shell::doAddMsg: dest not found" << endl; return ObjId(0, BADINDEX ); } const Finfo* f1 = src.id.element()->cinfo()->findFinfo( srcField ); if ( !f1 ) { cout << myNode_ << ": Shell::doAddMsg: Error: Failed to find field " << srcField << " on src: " << src.id.element()->getName() << endl; return ObjId(0, BADINDEX ); } const Finfo* f2 = dest.id.element()->cinfo()->findFinfo( destField ); if ( !f2 ) { cout << myNode_ << ": Shell::doAddMsg: Error: Failed to find field " << destField << " on dest: " << dest.id.element()->getName() << endl; cout << "Available fields are : " << endl << mapToString<string, Finfo*>(dest.id.element()->cinfo()->finfoMap()); return ObjId( 0, BADINDEX ); } if ( ! f1->checkTarget( f2 ) ) { cout << myNode_ << ": Shell::doAddMsg: Error: Src/Dest Msg type mismatch: " << srcField << "/" << destField << endl; return ObjId( 0, BADINDEX ); } const Msg* m = innerAddMsg( msgType, src, srcField, dest, destField, 0 ); SetGet6< string, ObjId, string, ObjId, string, unsigned int >::set( ObjId(), // Apply command to Shell "addMsg", // Function to call. msgType, src, srcField, dest, destField, m->mid().dataIndex ); #ifdef ENABLE_LOGGER logger.updateGlobalCount("Msgs"); float time = (float(clock() - t)/ CLOCKS_PER_SEC); logger.creationTime.push_back(time); #endif return m->mid(); // const Msg* m = innerAddMsg( msgType, src, srcField, dest, destField ); // return m->mid(); // return Msg::lastMsg()->mid(); }
/** * Wrapper function, that does the ack. Other functions also use the * inner function to build message trees, so we don't want it to emit * multiple acks. */ void Shell::handleAddMsg( const Eref& e, string msgType, ObjId src, string srcField, ObjId dest, string destField, unsigned int msgIndex ) { // Node 0 will have already called innerAddMsg to get the msgIndex if ( myNode() != 0 ) innerAddMsg( msgType, src, srcField, dest, destField, msgIndex ); /* if ( innerAddMsg( msgType, src, srcField, dest, destField ) ) ack()->send( Eref( shelle_, 0 ), Shell::myNode(), OkStatus ); else ack()->send( Eref( shelle_, 0), Shell::myNode(), ErrorStatus ); */ }
// Non-static function. The innerAddMsg needs the shell. void Shell::addClockMsgs( const vector< ObjId >& list, const string& field, unsigned int tick, unsigned int msgIndex ) { if ( !Id( 1 ).element() ) return; ObjId clockId( 1 ); dropClockMsgs( list, field ); // Forbid duplicate PROCESS actions. for ( vector< ObjId >::const_iterator i = list.begin(); i != list.end(); ++i ) { if ( i->element() ) { stringstream ss; ss << "proc" << tick; const Msg* m = innerAddMsg( "OneToAll", clockId, ss.str(), *i, field, msgIndex++ ); if ( m ) i->element()->innerSetTick( tick ); } } }
void ReadKkit::addmsg( const vector< string >& args) { string src = cleanPath( args[1] ).substr( 10 ); string dest = cleanPath( args[2] ).substr( 10 ); if ( args[3] == "REAC" ) { if ( args[4] == "A" && args[5] == "B" ) { // Ignore kchans if ( chanIds_.find( src ) != chanIds_.end() ) ; // found a kchan, do nothing else innerAddMsg( src, reacIds_, "sub", dest, poolIds_, "reac"); } else if ( args[4] == "B" && args[5] == "A" ) { // Ignore kchans if ( chanIds_.find( src ) != chanIds_.end() ) ; // found a kchan, do nothing else // dest pool is product of src reac innerAddMsg( src, reacIds_, "prd", dest, poolIds_, "reac"); } else if ( args[4] == "sA" && args[5] == "B" ) { // Msg from enzyme to substrate. if ( mmEnzIds_.find( src ) == mmEnzIds_.end() ) innerAddMsg( src, enzIds_, "sub", dest, poolIds_, "reac" ); else innerAddMsg( src, mmEnzIds_, "sub", dest, poolIds_, "reac" ); } } else if ( args[3] == "ENZYME" ) { // Msg from enz pool to enz site if ( mmEnzIds_.find( dest ) == mmEnzIds_.end() ) innerAddMsg( dest, enzIds_, "enz", src, poolIds_, "reac" ); else innerAddMsg( src, poolIds_, "nOut", dest, mmEnzIds_, "enzDest", 1); // innerAddMsg( dest, mmEnzIds_, "enz", src, poolIds_, "nOut", 1); /* if ( mmEnzIds_.find( dest ) == mmEnzIds_.end() ) innerAddMsg( src, poolIds_, "reac", dest, enzIds_, "enz" ); else innerAddMsg( src, poolIds_, "nOut", dest, mmEnzIds_, "enz" ); */ } else if ( args[3] == "MM_PRD" ) { // Msg from enz to Prd pool if ( mmEnzIds_.find( src ) == mmEnzIds_.end() ) innerAddMsg( src, enzIds_, "prd", dest, poolIds_, "reac" ); else innerAddMsg( src, mmEnzIds_, "prd", dest, poolIds_, "reac" ); } else if ( args[3] == "PLOT" ) { // Time-course output for pool string head; string temp; dest = pathTail( cleanPath( args[2] ), head ); string graph = pathTail( head, temp ); temp = graph + "/" + dest; map< string, Id >::const_iterator i = plotIds_.find( temp ); assert( i != plotIds_.end() ); Id plot = i->second; i = poolIds_.find( src ); Id pool; if ( i == poolIds_.end() ) { i = enzIds_.find( src ); // might be plotting an enzCplx. if ( i == enzIds_.end() ) { cout << "Error: ReadKkit: Unable to find src for plot: " << src << ", " << dest << endl; assert( 0 ); return; } vector< Id > enzcplx; i->second.element()->getNeighbors( enzcplx, i->second.element()->cinfo()->findFinfo( "toCplx" ) ); assert( enzcplx.size() == 1 ); pool = enzcplx[0]; } else { pool = i->second; } if ( args[4] == "Co" || args[4] == "CoComplex" ) { ObjId ret = shell_->doAddMsg( "Single", plot, "requestOut", pool, "getConc" ); assert( ret != ObjId() ); } else if ( args[4] == "n" || args[4] == "nComplex") { ObjId ret = shell_->doAddMsg( "Single", plot, "requestOut", pool, "getN" ); assert( ret != ObjId() ); } else { cout << "Unknown PLOT msg field '" << args[4] << "'\n"; } } else if ( args[3] == "SUMTOTAL" ) { // Summation function. buildSumTotal( src, dest ); } else if ( args[3] == "SLAVE" ) { // Summation function. if ( args[4] == "output" ) { setupSlaveMsg( src, dest ); } } }