11 #include "../shell/Shell.h"
13 #include "../utility/utility.h"
14 #include "../utility/numutil.h"
51 numCompartments_( 0 ),
61 relativeCoordsFlag_( 0 ),
62 doubleEndpointFlag_( 0 ),
65 shell_( reinterpret_cast<
Shell* >(
Id().eref().data() ) )
83 string libPath =
"/library";
86 if ( libId.
path() != libPath ) {
87 cerr <<
"Warning: ReadCell: No library for channels.\n";
91 vector< Id > chanList =
93 ObjId( libId ),
"children" );
95 vector< Id >::iterator i;
96 for ( i = chanList.begin(); i != chanList.end(); ++i ) {
98 string name =
id.element()->getName();
109 const string& fileName,
110 const string& cellName,
115 ifstream fin( fileName.c_str() );
117 cerr <<
"ReadCell::read -- could not open file " << fileName <<
".\n";
137 unsigned int size = 1;
150 cerr <<
"Readcell failed.\n";
161 string::size_type pos;
163 while ( getline( fin, line ) ) {
167 if ( line.length() == 0 )
170 pos = line.find_first_not_of(
"\t " );
171 if ( pos == string::npos )
174 line = line.substr( pos );
176 if ( line.substr( 0, 2 ) ==
"//" )
179 if ( ( pos = line.find(
"//" ) ) != string::npos )
180 line = line.substr( 0, pos );
182 if ( line.substr( 0, 2 ) ==
"/*" ) {
184 }
else if ( line.find(
"*/" ) != string::npos ) {
187 }
else if ( line[ 0 ] ==
'*' ) {
192 pos = line.find(
"*/" );
193 if ( pos != string::npos ) {
195 if ( line.length() > pos + 2 )
196 line = line.substr( pos + 2 );
200 if ( parseMode ==
DATA ) {
204 }
else if ( parseMode ==
SCRIPT ) {
223 vector< string > argv;
224 string delimiters(
"\t " );
227 if ( argv[ 0 ] ==
"*cartesian" ) {
229 }
else if ( argv[ 0 ] ==
"*polar" ) {
231 }
else if ( argv[ 0 ] ==
"*relative" ) {
233 }
else if ( argv[ 0 ] ==
"*absolute" ) {
235 }
else if ( argv[ 0 ] ==
"*symmetric" ) {
237 }
else if ( argv[ 0 ] ==
"*asymmetric" ) {
239 }
else if ( argv[ 0 ] ==
"*set_global" || argv[ 0 ] ==
"*set_compt_param" ) {
240 if ( argv.size() != 3 ) {
241 cerr <<
"Error: ReadCell: Bad line: " <<
247 if ( argv[ 1 ] ==
"RM" )
248 RM_ = atof( argv[ 2 ].c_str() );
249 if ( argv[ 1 ] ==
"RA" )
250 RA_ = atof( argv[ 2 ].c_str() );
251 if ( argv[ 1 ] ==
"CM" )
252 CM_ = atof( argv[ 2 ].c_str() );
253 if ( argv[ 1 ] ==
"EREST_ACT" ) {
256 }
if (argv[ 1 ] ==
"ELEAK" ) {
257 ELEAK_ = atof( argv[ 2 ].c_str() );
260 }
else if ( argv[ 0 ] ==
"*start_cell" ) {
261 if ( argv.size() == 1 ) {
264 }
else if ( argv.size() == 2 ) {
270 cerr <<
"Error: ReadCell: Bad line: " <<
275 }
else if ( argv[ 0 ] ==
"*compt" ) {
276 if ( argv.size() != 2 ) {
277 cerr <<
"Error: ReadCell: Bad line: " <<
283 Id protoId( argv[ 1 ] );
284 if ( protoId.
path() != argv[ 1 ] ) {
285 cerr <<
"Error: ReadCell: Bad path: " << argv[ 1 ] <<
" " <<
293 }
else if ( argv[ 0 ] ==
"*double_endpoint" ) {
295 }
else if ( argv[ 0 ] ==
"*double_endpoint_off" ) {
297 }
else if ( argv[ 0 ] ==
"*makeproto" ) {
300 cerr <<
"Warning: ReadCell: Command " <<
301 argv[ 0 ] <<
" not recognized. Ignoring. " <<
311 vector< string > argv;
312 string delimiters(
"\t " );
315 if ( argv.size() < 6 ) {
316 cerr <<
"Error: ReadCell: Too few arguments in line: " << argv.size() <<
317 ", should be > 6.\n";
329 string name = argv[ 0 ];
330 string parent = argv[ 1 ];
335 x0 = 1.0e-6 * atof( argv[ 2 ].c_str() );
336 y0 = atof( argv[ 3 ].c_str() );
337 z0 = atof( argv[ 4 ].c_str() );
340 double theta = y0 *
M_PI / 180.0;
341 double phi = z0 *
M_PI / 180.0;
342 x0 = r * sin( phi ) * cos ( theta );
343 y0 = r * sin( phi ) * sin ( theta );
351 x = 1.0e-6 * atof( argv[ argOffset + 2 ].c_str() );
352 y = atof( argv[ argOffset + 3 ].c_str() );
353 z = atof( argv[ argOffset + 4 ].c_str() );
356 double theta = y *
M_PI / 180.0;
357 double phi = z *
M_PI / 180.0;
358 x = r * sin( phi ) * cos ( theta );
359 y = r * sin( phi ) * sin ( theta );
366 d = 1.0e-6 * atof( argv[ argOffset + 5 ].c_str() );
370 buildCompartment( name, parent, x0, y0, z0, x, y, z, d, length, argv );
380 const string& parent,
381 double x0,
double y0,
double z0,
382 double x,
double y,
double z,
385 vector< string >& argv )
387 static const Finfo* raxial2OutFinfo =
400 if ( parent ==
"." ) {
402 }
else if ( parent ==
"none" || parent ==
"nil" ) {
407 if ( parentObjId.
bad() ) {
408 cerr <<
"Error: ReadCell: could not find parent compt '"
410 <<
"' for child '" << name <<
"'.\n";
414 parentId = parentObjId;
445 unsigned int size = 1;
447 if (
graftFlag_ && ( parent ==
"none" || parent ==
"nil" ) ) {
464 "SymCompartment" :
"Compartment";
473 if ( parentId !=
Id()){
501 length = sqrt( dx * dx + dy * dy + dz * dz );
509 parentId,
"distal", compt,
"proximal" );
510 for ( vector< Id >::iterator i = sibs.begin();
511 i != sibs.end(); ++i ) {
513 compt,
"sibling", *i,
"sibling" );
518 parentId,
"axial", compt,
"raxial" );
521 length = sqrt( x * x + y * y + z * z );
531 Ra =
RA_ * length * 4.0 / ( d * d *
M_PI );
565 Id cellId( cellPath );
566 if ( cellId.
path() == cellPath ) {
567 cerr <<
"Warning: ReadCell: cell '" << cellPath <<
"' already exists.\n";
574 string::size_type pos_1 = cellPath.find_first_of(
"/" );
575 string::size_type pos_2 = cellPath.find_last_of(
"/" );
578 cerr <<
"Error: ReadCell: *start_cell should be given absolute path.\n";
584 parentObjId =
ObjId(
"/");
585 cellName = cellPath.substr( 1 );
587 string parentPath = cellPath.substr( 0, pos_2 );
588 parentObjId =
ObjId( parentPath );
589 if ( parentObjId.
bad() ) {
590 cerr <<
"Error: ReadCell: cell path '" << cellPath
596 cellName = cellPath.substr( pos_2 + 1 );
599 unsigned int size = 1;
611 map< string, Id >::iterator pos =
chanProtos_.find( name );
622 area = dia * dia *
M_PI;
624 area = len * dia *
M_PI;
631 vector< string >& argv,
637 vector< Id > goodChannels;
640 isArgOK = ( argv.size() % 2 ) == 1;
643 isArgOK = ( argv.size() % 2 ) == 0;
648 cerr <<
"Error: ReadCell: Bad number of arguments in channel list\n";
653 for (
unsigned int j = argStart; j < argv.size(); j++ ) {
656 string chan = argv[ j ];
658 double value = atof( argv[ ++j ].c_str() );
659 if ( chan ==
"RA" ) {
662 temp = 8.0 * value / ( diameter *
M_PI );
664 temp = 4.0 * value * length / ( diameter * diameter *
M_PI );
666 }
else if ( chan ==
"RM" ) {
668 }
else if ( chan ==
"CM" ) {
670 }
else if ( chan ==
"Rm" ) {
672 }
else if ( chan ==
"Ra" ) {
674 }
else if ( chan ==
"Cm" ) {
676 }
else if ( chan ==
"kinModel" ) {
680 if ( j + 2 < argv.size() ) {
681 string protoName = argv[ ++j ];
682 string method = argv[ ++j ];
685 cerr <<
"Error: ReadCell: kinModel needs 3 args\n";
689 }
else if ( chan ==
"m2c" ) {
693 if ( j + 4 < argv.size() ) {
697 cerr <<
"Error: ReadCell: m2c adaptor needs 5 args\n";
701 }
else if ( chan ==
"c2m" ) {
704 if ( j + 4 < argv.size() ) {
708 cerr <<
"Error: ReadCell: c2m adaptor needs 5 args\n";
714 if ( chanId ==
Id() ) {
715 cerr <<
"Error: ReadCell: Channel '" << chan <<
721 Id copy =
addChannel( compt, chanId, value, diameter, length );
722 if ( copy !=
Id() ) {
723 goodChannels.push_back( copy );
725 cerr <<
"Error: ReadCell: Could not add " << chan
732 for (
unsigned int i = 0; i < goodChannels.size(); i++ )
756 assert( copy !=
Id() );
759 if (
addSpikeGen( compt, copy, value, dia, length ) )
return copy;
760 if (
addCaConc( compt, copy, value, dia, length ) )
return copy;
761 if (
addNernst( compt, copy, value ) )
return copy;
783 className ==
"HHChannel" ||
784 className ==
"HHChannel2D" ||
785 className ==
"SynChan" ||
786 className ==
"NMDAChan"
796 cout <<
"failed to connect message from compt " << compt <<
797 " to channel " << chan << endl;
822 if ( className ==
"SpikeGen" ) {
854 if ( thickness > dia / 2.0 )
858 if ( className ==
"CaConc" ) {
862 if ( thickness > 0.0 ) {
863 vol =
M_PI * length * ( dia - thickness ) * thickness;
865 vol = dia * dia *
M_PI * length / 4.0;
868 if ( thickness > 0.0 ) {
869 double inner_dia = dia - 2 * thickness;
872 inner_dia * inner_dia * inner_dia
875 vol =
M_PI * dia * dia * dia / 6.0;
995 Id cwe = shell->getCwe();
996 shell->setCwe( chan );
997 for ( vector< Id >::iterator i = kids.begin(); i != kids.end(); ++i )
1000 const string&
name = i->element()->getName();
1001 if ( name.find(
"addmsg", 0 ) != 0 )
1005 vector< string > token;
1007 assert( token.size() == 4 );
1008 ObjId src = shell->doFind( token[0] );
1009 ObjId dest = shell->doFind( token[2] );
1014 if ( src.bad() || dest.
bad()) {
1025 shell->doAddMsg(
"single", src, token[1], dest, token[3] );
1026 assert( !mid.
bad());
1028 shell->setCwe( cwe );
bool addCanonicalChannel(Id compt, Id chan, double value, double dia, double length)
Element * element() const
Synonym for Id::operator()()
std::string path(const std::string &separator="/") const
bool buildChannels(Id compt, vector< string > &argv, double diameter, double length)
Id doCopy(Id orig, ObjId newParent, string newName, unsigned int n, bool toGlobal, bool copyExtMsgs)
Returns the Id of the root of the copied tree upon success.
double calcSurf(double, double)
Id buildCompartment(const string &name, const string &parent, double x0, double y0, double z0, double x, double y, double z, double d, double &length, vector< string > &argv)
static void children(const Eref &e, vector< Id > &ret)
Id addChannel(Id compt, Id chan, double value, double dia, double length)
static bool set(const ObjId &dest, const string &field, A arg)
unsigned int numChannels_
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
const std::string & name() const
map< string, Id > chanProtos_
Id read(const string &filename, const string &cellname, Id parent)
unsigned int numCompartments_
bool innerRead(ifstream &fin)
bool addNernst(Id compt, Id chan, double value)
unsigned int numProtoCompts_
static const Cinfo * initCinfo()
bool isA(const string &ancestor) const
bool readData(const string &line)
bool readScript(const string &line)
const Cinfo * cinfo() const
static void addChannelMessage(Id chan)
Id findChannel(const string &name)
Id startGraftCell(const string &cellPath)
ObjId doAddMsg(const string &msgType, ObjId src, const string &srcField, ObjId dest, const string &destField)
void tokenize(const string &str, const string &delimiters, vector< string > &tokens)
unsigned int getNeighbors(vector< Id > &ret, const Finfo *finfo) const
static A get(const ObjId &dest, const string &field)
std::string trim(const std::string myString, const string &delimiters)
const string & getName() const
const unsigned int BADINDEX
Used by ObjId and Eref.
unsigned int numProtoChans_
bool addCaConc(Id compt, Id chan, double value, double dia, double length)
const Finfo * findFinfo(const string &name) const
bool addSpikeGen(Id compt, Id chan, double value, double dia, double length)
unsigned int numProtoOthers_