MOOSE - Multiscale Object Oriented Simulation Environment
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ReadCspace.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-2004 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 <fstream>
11 #include "header.h"
12 #include "../shell/Shell.h"
13 
14 #define DO_CSPACE_DEBUG 0
15 
16 #include "ReadCspace.h"
17 
18 const double ReadCspace::SCALE = 1.0;
19 const double ReadCspace::DEFAULT_CONC = 1.0;
20 const double ReadCspace::DEFAULT_RATE = 0.1;
21 const double ReadCspace::DEFAULT_KM = 1.0;
22 const bool ReadCspace::USE_PIPE = 1;
23 
25  :
26  base_(),
27  compt_(),
28  mesh_(),
29  fout_( &cout )
30 {;}
31 
33 {
34  reaclist_.resize( 0 );
35  mollist_.resize( 0 );
36 }
37 
39 {
40  string separator = ( USE_PIPE ) ? "|" : "" ;
41  // We do this in all cases, regardless of the doOrdering flag.
42  sort( mollist_.begin(), mollist_.end() );
43  sort( reaclist_.begin(), reaclist_.end() );
44  unsigned int i;
45  *fout_ << separator;
46  for ( i = 0; i < reaclist_.size(); i++ )
47  *fout_ << reaclist_[ i ].name() << separator;
48 
49  for ( i = 0; i < mollist_.size(); i++ )
50  *fout_ << " " << mollist_[i].conc();
51  for ( i = 0; i < reaclist_.size(); i++ )
52  *fout_ << " " << reaclist_[i].r1() << " " << reaclist_[i].r2();
53  *fout_ << "\n";
54 }
55 
56 void ReadCspace::printMol( Id id, double conc, double concinit, double vol)
57 {
58 
59  // Skip explicit enzyme complexes.
60  ObjId parent = Neutral::parent( id.eref() );
61  if ( parent.element()->cinfo()->isA( "Enzyme" ) &&
62  id.element()->getName() == ( parent.element()->getName() + "_cplx" )
63  )
64  return;
65 
66  CspaceMolInfo m( id.element()->getName()[ 0 ], concinit );
67  mollist_.push_back( m );
68  // Need to look up concs in a final step so that the sorted order
69  // is maintained.
70 }
71 
72 void ReadCspace::printReac( Id id, double kf, double kb)
73 {
74  CspaceReacInfo r( id.element()->getName(), kf, kb );
75  reaclist_.push_back( r );
76 }
77 
78 void ReadCspace::printEnz( Id id, Id cplx, double k1, double k2, double k3)
79 {
80  CspaceReacInfo r( id.element()->getName(), k3, (k3 + k2) / k1 );
81  reaclist_.push_back( r );
82 }
83 
84 // Model string always includes topology, after that the parameters
85 // are filled in according to how many there are.
86 Id ReadCspace::readModelString( const string& model,
87  const string& modelname, Id pa, const string& solverClass )
88 {
89  // Defined in ReadKkit.cpp
90  extern Id makeStandardElements( Id pa, const string& modelname );
91  unsigned long pos = model.find_first_of( "|" );
92  if ( pos == string::npos ) {
93  cerr << "ReadCspace::readModelString: Error: model undefined in\n";
94  cerr << model << "\n";
95  return Id();
96  }
97  mol_.resize( 0 );
98  molseq_.resize( 0 );
99  reac_.resize( 0 );
100  molparms_.resize( 0 );
101  parms_.resize( 0 );
102  // Shell* s = reinterpret_cast< Shell* >( Id().eref().data() );
103  base_ = makeStandardElements( pa, modelname );
104  assert( base_ != Id() );
105  string modelpath = base_.path();
106  compt_ = Id( modelpath + "/kinetics");
107  assert( compt_ != Id() );
108  Field< double >::set( compt_, "volume", 1e-18 );
109  // SetGet2< double, unsigned int >::set( compt_, "buildDefaultMesh", 1e-18, 1 );
110  string temp = model.substr( pos + 1 );
111  pos = temp.find_first_of( " \n" );
112 
113  for (unsigned long i = 0 ; i < temp.length() && i < pos; i += 5 ) {
114  build( temp.c_str() + i );
115  if ( temp[ i + 4 ] != '|' )
116  break;
117  }
118 
119  parms_.insert( parms_.begin(), molparms_.begin(), molparms_.end() );
120 
121  pos = model.find_last_of( "|" ) + 1;
122  double val = 0;
123  unsigned int i = 0;
124  while ( pos < model.length() ) {
125  if ( model[ pos ] == ' ' ) {
126  val = atof( model.c_str() + pos + 1 );
127  assert( i < parms_.size() );
128  parms_[ i++ ] = val;
129  }
130  pos++;
131  }
132 
134 
135  // SetGet1< string >::set( base_, "build", solverClass );
136  return base_;
137 }
138 
139 void ReadCspace::makePlots( double plotdt )
140 {
141  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
142  vector< Id > children;
143  Neutral::children( compt_.eref(), children );
144  string basepath = base_.path();
145  Id graphs( basepath + "/graphs" );
146  assert( graphs != Id () );
147  for ( unsigned int i = 0; i < children.size(); ++i ) {
148  const Cinfo* kidCinfo = children[i].element()->cinfo();
149  if ( kidCinfo->isA( "PoolBase" ) ) {
150  string plotname = "plot" + children[i].element()->getName();
151  Id tab = shell->doCreate( "Table2", graphs, plotname, 1 );
152  assert( tab != Id() );
153  // cout << "ReadCspace made plot " << plotname << endl;
154  ObjId mid = shell->doAddMsg( "Single",
155  tab, "requestOut", children[i], "getConc" );
156  assert( mid != ObjId() );
157  }
158  }
159  /* Clocks are now assigned automatically
160  shell->doSetClock( 8, plotdt );
161 
162  string plotpath = basepath + "/graphs/##[TYPE=Table2]";
163  shell->doUseClock( plotpath, "process", 8 );
164  */
165 }
166 
167 
169 // From reacdef.cpp in CSPACE:
170 // if (line == "A <==> B") type = 'A';
171 // else if (line == "2A <==> B") type = 'B';
172 // else if (line == "A --A--> B") type = 'C';
173 // else if (line == "A --B--> B") type = 'D';
174 // else if (line == "A <==> B + C") type = 'E';
175 // else if (line == "2A <==> B + C") type = 'F';
176 // else if (line == "2A + B <==> C") type = 'G';
177 // else if (line == "2A + B <==> 2C") type = 'H';
178 // else if (line == "4A + B <==> C") type = 'I';
179 // else if (line == "A --B--> C") type = 'J';
180 // else if (line == "A --A--> B + C") type = 'K';
181 // else if (line == "A --B--> B + C") type = 'L';
183 
185  const char* name, int e, int s, int p, int p2 )
186 {
187  static Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
188 
189  Id enzMolId = mol_[ name[e] - 'a' ];
190 
191  Id enzId = shell->doCreate( "Enz", enzMolId, name, 1 );
192  assert( enzId != Id() );
193  string cplxName = name;
194  cplxName += "_cplx";
195  Id cplxId = shell->doCreate( "Pool", enzId, cplxName, 1 );
196  assert( cplxId != Id() );
197  ObjId ret = shell->doAddMsg( "OneToOne",
198  enzId, "cplx", cplxId, "reac" );
199 
200  ret = shell->doAddMsg( "OneToOne",
201  enzMolId, "reac", enzId, "enz" );
202 
203  ret = shell->doAddMsg( "OneToOne",
204  mol_[ name[ s ] - 'a' ], "reac", enzId, "sub" );
205 
206  ret = shell->doAddMsg( "OneToOne",
207  mol_[ name[ p ] - 'a' ], "reac", enzId, "prd" );
208 
209  if ( p2 != 0 )
210  ret = shell->doAddMsg( "OneToOne",
211  mol_[ name[ p2 ] - 'a' ], "reac", enzId, "prd" );
212 
213  assert( ret != ObjId() );
214 
215  reac_.push_back( enzId );
216  parms_.push_back( DEFAULT_RATE );
217  parms_.push_back( DEFAULT_KM );
218 }
219 
220 void ReadCspace::expandReaction( const char* name, int nm1 )
221 {
222  static Shell* s = reinterpret_cast< Shell* >( Id().eref().data() );
223 
224  if ( name[0] == 'C' || name[0] == 'D' || name[0] >= 'J' ) // enzymes
225  return;
226  int i;
227 
228  Id reacId = s->doCreate( "Reac", compt_, name, 1 );
229 
230  // A is always a substrate
231  for (i = 0; i < nm1; i++ ) {
232  s->doAddMsg( "OneToOne", reacId, "sub", mol_[ name[1] - 'a' ], "reac" );
233  }
234 
235  if ( name[0] < 'G' ) { // B is a product
236  s->doAddMsg( "OneToOne", reacId, "prd", mol_[ name[2] - 'a' ], "reac" );
237  } else { // B is a substrate
238  s->doAddMsg( "OneToOne", reacId, "sub", mol_[ name[2] - 'a' ], "reac" );
239  }
240 
241  if ( name[0] > 'D' ) { // C is a product
242  s->doAddMsg( "OneToOne", reacId, "prd", mol_[ name[3] - 'a' ], "reac" );
243  }
244 
245  if ( name[0] == 'H' ) { // C is a dual product
246  s->doAddMsg( "OneToOne", reacId, "prd", mol_[ name[3] - 'a' ], "reac" );
247  }
248  reac_.push_back( reacId );
249  parms_.push_back( DEFAULT_RATE );
250  parms_.push_back( DEFAULT_RATE );
251 }
252 
253 void ReadCspace::build( const char* name )
254 {
255  makeMolecule( name[1] );
256  makeMolecule( name[2] );
257  makeMolecule( name[3] );
258  char tname[6];
259  strncpy( tname, name, 4 );
260  tname[4] = '\0';
261 
262  switch ( tname[0] ) {
263  case 'A':
264  case 'E':
265  expandReaction( tname, 1 );
266  break;
267  case 'B':
268  case 'F':
269  case 'G':
270  case 'H':
271  expandReaction( tname, 2 );
272  break;
273  case 'I':
274  expandReaction( tname, 4 );
275  break;
276  case 'C':
277  expandEnzyme( tname, 1, 1, 2 );
278  break;
279  case 'D':
280  expandEnzyme( tname, 2, 1, 2 );
281  break;
282  case 'J':
283  expandEnzyme( tname, 2, 1, 3 );
284  break;
285  case 'K':
286  expandEnzyme( tname, 1, 1, 2, 3 );
287  break;
288  case 'L':
289  expandEnzyme( tname, 2, 1, 2, 3 );
290  break;
291  default:
292  break;
293  }
294 }
295 
297 {
298  static Shell* s = reinterpret_cast< Shell* >( Id().eref().data() );
299 
300  if ( name == 'X' ) // silently ignore it, as it is a legal state
301  return;
302  if ( name < 'a' || name > 'z' ) {
303  cerr << "ReadCspace::makeMolecule Error: name '" << name <<
304  "' out of range 'a' to 'z'\n";
305  return;
306  }
307 
308  unsigned int index = 1 + name - 'a';
309 
310  // Put in molecule if it is a new one.
311  if ( find( molseq_.begin(), molseq_.end(), index - 1 ) ==
312  molseq_.end() )
313  molseq_.push_back( index - 1 );
314 
315  for ( unsigned int i = mol_.size(); i < index; i++ ) {
316  string molname("");
317  molname += 'a' + i;
318  /*
319  stringstream ss( "a" );
320  ss << i ;
321  string molname = ss.str();
322  */
323  Id temp = s->doCreate( "Pool", compt_, molname, 1 );
324  mol_.push_back( temp );
325  molparms_.push_back( DEFAULT_CONC );
326  }
327 }
328 
330 {
331  // static Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
332  unsigned long i, j;
333  if ( parms_.size() != mol_.size() + 2 * reac_.size() ) {
334  cerr << "ReadCspace::deployParameters: Error: # of parms mismatch\n";
335  return;
336  }
337  for ( i = 0; i < mol_.size(); i++ ) {
338  // SetField(mol_[ i ], "volscale", volscale );
339  // SetField(mol_[ molseq_[i] ], "ninit", parms_[ i ] );
340 
341  // Parameters are in micromolar, but the conc units are millimolar.
342  Field< double >::set( mol_[i], "concInit", parms_[i] * 1e-3 );
343  }
344  for ( j = 0; j < reac_.size(); j++ ) {
345  if ( reac_[ j ].element()->cinfo()->isA( "Reac" ) ) {
346  Field< double >::set( reac_[j], "Kf", parms_[i++] );
347  Field< double >::set( reac_[j], "Kb", parms_[i++] );
348  } else {
349  Field< double >::set( reac_[j], "k3", parms_[i] );
350  Field< double >::set( reac_[j], "k2", 4.0 * parms_[i++] );
351  // Again, note that conc units in MOOSE are millimolar, so we
352  // need to convert from the CSPACE micromolar units.
353  Field< double >::set( reac_[j], "Km", parms_[i++] * 1e-3 );
354  vector< Id > cplx( 0 );
355  Neutral::children( reac_[j].eref(), cplx );
356  assert( cplx.size() == 1 );
357  }
358  }
359 }
360 
362 {
363  const double CONCSCALE = 1e-3;
364  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
365  // cout << "Testing ReadCspace::readModelString()\n";
366  Id modelId = readModelString( "|Habc|Lbca|", "mod1", Id(), "Neutral" );
367  assert( mol_.size() == 3 );
368  assert( reac_.size() == 2 );
369 
370  shell->doDelete( modelId );
371 
372  modelId = readModelString( "|AabX|BbcX|CcdX|DdeX|Eefg|Ffgh|Gghi|Hhij|Iijk|Jjkl|Kklm|Llmn| 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 101 102 201 202 301 302 401 402 501 502 601 602 701 702 801 802 901 902 1001 1002 1101 1102 1201 1202",
373  "model", Id(), "Neutral" );
374  assert( mol_.size() == 14 );
375  assert( reac_.size() == 12 );
376  double concInit;
377  int i;
378  // cout << "\nTesting ReadCspace:: conc assignment\n";
379  for ( i = 0; i < 14; i++ ) {
380  string path( base_.path() + "/kinetics/" );
381  path += 'a' + i;
382  /*
383  stringstream ss( "/kinetics/" );
384  // const char* molname = ss.str();
385  ss << 'a' + i;
386  Id temp( ss.str() );
387  */
388  Id temp( path );
389  concInit = Field< double >::get( temp, "concInit" );
390 
391  // The 0.001 is for converting to millimolar, which is the internal
392  // unit used in MOOSE.
393  assert( doubleEq( concInit, 0.001 * ( i + 1 ) ) );
394  }
395 
396  // cout << "\nTesting ReadCspace:: reac construction\n";
397  assert( reac_[ 0 ].path() == "/model/kinetics/AabX" );
398  assert( reac_[ 1 ].path() == "/model/kinetics/BbcX" );
399  assert( reac_[ 2 ].path() == "/model/kinetics/c/CcdX" );
400  assert( reac_[ 3 ].path() == "/model/kinetics/e/DdeX" );
401  assert( reac_[ 4 ].path() == "/model/kinetics/Eefg" );
402  assert( reac_[ 5 ].path() == "/model/kinetics/Ffgh" );
403  assert( reac_[ 6 ].path() == "/model/kinetics/Gghi" );
404  assert( reac_[ 7 ].path() == "/model/kinetics/Hhij" );
405  assert( reac_[ 8 ].path() == "/model/kinetics/Iijk" );
406  assert( reac_[ 9 ].path() == "/model/kinetics/k/Jjkl" );
407  assert( reac_[ 10 ].path() == "/model/kinetics/k/Kklm" );
408  assert( reac_[ 11 ].path() == "/model/kinetics/m/Llmn" );
409 
410  // cout << "\nTesting ReadCspace:: reac rate assignment\n";
411  Id tempA( "/model/kinetics/AabX" );
412  double r1 = Field< double >::get( tempA, "Kf");
413  double r2 = Field< double >::get( tempA, "Kb");
414  assert( doubleEq( r1, 101 ) && doubleEq( r2, 102 ) );
415 
416  Id tempB( "/model/kinetics/BbcX" );
417  r1 = Field< double >::get( tempB, "Kf");
418  r2 = Field< double >::get( tempB, "Kb");
419  assert( doubleEq( r1, 201 ) && doubleEq( r2, 202 ) );
420 
421  Id tempC( "/model/kinetics/c/CcdX" );
422  r1 = Field< double >::get( tempC, "k3");
423  r2 = Field< double >::get( tempC, "Km");
424  assert( doubleEq( r1, 301 ) && doubleEq( r2, 302 * CONCSCALE ) );
425 
426  Id tempD( "/model/kinetics/e/DdeX" );
427  r1 = Field< double >::get( tempD, "k3");
428  r2 = Field< double >::get( tempD, "Km");
429  assert( doubleEq( r1, 401 ) && doubleEq( r2, 402 * CONCSCALE ) );
430 
431  for ( i = 4; i < 9; i++ ) {
432  /*
433  stringstream ss( "/kinetics/A" );
434  ss << i << 'a' + i << 'b' + i << 'c' + i;
435  // sprintf( ename, "/kinetics/%c%c%c%c", 'A' + i, 'a' + i, 'b' + i, 'c' + i );
436  Id temp( ss.str() );
437  */
438 
439  string path( "/model/kinetics/" );
440  path += 'A' + i;
441  path += 'a' + i;
442  path += 'b' + i;
443  path += 'c' + i;
444  Id temp( path );
445  r1 = Field< double >::get( temp, "Kf");
446  r2 = Field< double >::get( temp, "Kb");
447  assert( doubleEq( r1, i* 100 + 101 ) &&
448  doubleEq( r2, i * 100 + 102 ) );
449  }
450 
451  Id tempJ( "/model/kinetics/k/Jjkl" );
452  r1 = Field< double >::get( tempJ, "k3");
453  r2 = Field< double >::get( tempJ, "Km");
454  assert( doubleEq( r1, 1001 ) && doubleEq( r2, 1002 * CONCSCALE ) );
455 
456  Id tempK( "/model/kinetics/k/Kklm" );
457  r1 = Field< double >::get( tempK, "k3");
458  r2 = Field< double >::get( tempK, "Km");
459  assert( doubleEq( r1, 1101 ) && doubleEq( r2, 1102 * CONCSCALE ) );
460 
461  Id tempL( "/model/kinetics/m/Llmn" );
462  r1 = Field< double >::get( tempL, "k3");
463  r2 = Field< double >::get( tempL, "Km");
464  assert( doubleEq( r1, 1201 ) && doubleEq( r2, 1202 * CONCSCALE ) );
465  shell->doDelete( modelId );
466 }
char * data() const
Definition: Eref.cpp:41
static const double DEFAULT_RATE
Definition: ReadCspace.h:107
static ObjId parent(const Eref &e)
Definition: Neutral.cpp:701
std::string path(const std::string &separator="/") const
Definition: Id.cpp:76
vector< CspaceReacInfo > reaclist_
Definition: ReadCspace.h:127
Definition: ObjId.h:20
void printMol(Id id, double conc, double concinit, double vol)
Definition: ReadCspace.cpp:56
void printHeader()
Definition: ReadCspace.cpp:32
Eref eref() const
Definition: Id.cpp:125
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
static bool set(const ObjId &dest, const string &field, A arg)
Definition: SetGet.h:245
vector< Id > reac_
Definition: ReadCspace.h:120
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
Definition: Shell.cpp:181
ostream * fout_
Definition: ReadCspace.h:114
vector< double > parms_
Definition: ReadCspace.h:122
vector< CspaceMolInfo > mollist_
Definition: ReadCspace.h:126
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
void expandEnzyme(const char *name, int e, int s, int p, int p2=0)
Definition: ReadCspace.cpp:184
static const double DEFAULT_KM
Definition: ReadCspace.h:108
void build(const char *name)
Definition: ReadCspace.cpp:253
Id readModelString(const string &model, const string &modelname, Id pa, const string &solverClass)
Definition: ReadCspace.cpp:86
void deployParameters()
Definition: ReadCspace.cpp:329
vector< Id > mol_
Definition: ReadCspace.h:117
void makeMolecule(char name)
Definition: ReadCspace.cpp:296
bool isA(const string &ancestor) const
Definition: Cinfo.cpp:280
void makePlots(double plotdt)
Definition: ReadCspace.cpp:139
const Cinfo * cinfo() const
Definition: Element.cpp:66
void expandReaction(const char *name, int nm1)
Definition: ReadCspace.cpp:220
void printEnz(Id id, Id cplx, double k1, double k2, double k3)
Definition: ReadCspace.cpp:78
static const bool USE_PIPE
Definition: ReadCspace.h:109
void printReac(Id id, double kf, double kb)
Definition: ReadCspace.cpp:72
Element * element() const
Definition: ObjId.cpp:124
Id makeStandardElements(Id pa, const string &modelname)
Definition: ReadKkit.cpp:123
static char name[]
Definition: mfield.cpp:401
void testReadModel()
Definition: ReadCspace.cpp:361
ObjId doAddMsg(const string &msgType, ObjId src, const string &srcField, ObjId dest, const string &destField)
Definition: Shell.cpp:269
bool doDelete(ObjId oid)
Definition: Shell.cpp:259
Definition: Id.h:17
void printFooter()
Definition: ReadCspace.cpp:38
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
static const double DEFAULT_CONC
Definition: ReadCspace.h:106
const string & getName() const
Definition: Element.cpp:56
Definition: Cinfo.h:18
static char path[]
Definition: mfield.cpp:403
vector< unsigned int > molseq_
Definition: ReadCspace.h:118
static const double SCALE
Definition: ReadCspace.h:105
Definition: Shell.h:43
vector< double > molparms_
Definition: ReadCspace.h:124