MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
MarkovRateTable.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-2011 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 #include <iomanip>
10 #include "header.h"
11 #include "VectorTable.h"
12 #include "../builtins/Interpol2D.h"
13 #include "MarkovRateTable.h"
14 
15 //Message source that sends out instantaneous rate information at each time step
16 //to the solver object.
18 {
20  "instratesOut",
21  "Sends out instantaneous rate information of varying transition rates"
22  "at each time step.");
23 
24  return &instRatesOut;
25 }
26 
28 {
30  //SharedFinfos
32  static DestFinfo handleVm("handleVm",
33  "Handles incoming message containing voltage information.",
35  );
36 
37  static Finfo* channelShared[] =
38  {
39  &handleVm
40  };
41 
42  static SharedFinfo channel("channel",
43  "This message couples the rate table to the compartment. The rate table"
44  " needs updates on voltage in order to compute the rate table.",
45  channelShared, sizeof( channelShared ) / sizeof( Finfo* )
46  );
47 
49  //DestFinfos
51  static DestFinfo process( "process",
52  "Handles process call",
54 
55  static DestFinfo reinit( "reinit",
56  "Handles reinit call",
58 
59  static Finfo* processShared[] =
60  {
61  &process, &reinit
62  };
63 
64  static SharedFinfo proc( "proc",
65  "This is a shared message to receive Process message from the"
66  "scheduler. The first entry is a MsgDest for the Process "
67  "operation. It has a single argument, ProcInfo, which "
68  "holds lots of information about current time, thread, dt and"
69  "so on. The second entry is a MsgDest for the Reinit "
70  "operation. It also uses ProcInfo.",
71  processShared, sizeof( processShared ) / sizeof( Finfo* )
72  );
73 
74  static DestFinfo init("init",
75  "Initialization of the class. Allocates memory for all the tables.",
77 
78  static DestFinfo handleLigandConc("handleLigandConc",
79  "Handles incoming message containing ligand concentration.",
81 
82  static DestFinfo set1d("set1d",
83  "Setting up of 1D lookup table for the (i,j)'th rate.",
84  new OpFunc4< MarkovRateTable, unsigned int, unsigned int, Id,
85  unsigned int >
87  );
88 
89  static DestFinfo set2d("set2d",
90  "Setting up of 2D lookup table for the (i,j)'th rate.",
93  );
94 
95  static DestFinfo setconst("setconst",
96  "Setting a constant value for the (i,j)'th rate. Internally, this is"
97  " stored as a 1-D rate with a lookup table containing 1 entry.",
100  );
101 
103  //Field information.
105  static ValueFinfo< MarkovRateTable, double > ligandconc( "ligandConc",
106  "Ligand concentration.",
109  );
110 
112  "Membrane voltage.",
115  );
116 
118  Q( "Q",
119  "Instantaneous rate matrix.",
121  );
122 
123  //Really no point in allowing access to Vm_ and ligandConc_ when it is
124  //available from the MarkovChannel class.
125 
127  size( "size",
128  "Dimension of the families of lookup tables. Is always equal to the number of states in the model.",
130  );
131 
132  static Finfo* markovRateTableFinfos[] =
133  {
134  &channel, //SharedFinfo
135  instRatesOut(), //SrcFinfo
136  &proc, //DestFinfo
137  &init, //DestFinfo
138  &handleLigandConc, //DestFinfo
139  &set1d, //DestFinfo
140  &set2d, //DestFinfo
141  &setconst, //DestFinfo
142  &vm, //ValueFinfo
143  &ligandconc, //ValueFinfo
144  &Q, //ReadOnlyValueFinfo
145  &size, //ReadOnlyValueFinfo
146  };
147 
148  static string doc[] =
149  {
150  "Name", "MarkovRateTable",
151  "Author", "Vishaka Datta S, 2011, NCBS",
152  "Description", "Rate Table for Markov channel calculations. "
153  };
154  static Dinfo< MarkovRateTable > dinfo;
156  "MarkovRateTable",
158  markovRateTableFinfos,
159  sizeof(markovRateTableFinfos)/sizeof(Finfo *),
160  &dinfo,
161  doc,
162  sizeof( doc ) / sizeof( string )
163  );
164 
165  return &MarkovRateTableCinfo;
166 }
167 
169 
171  Vm_(0),
172  ligandConc_(0),
173  size_(0)
174 { ; }
175 
177 {
178  for ( unsigned int i = 0; i < size_; ++i )
179  {
180  for ( unsigned int j = 0; j < size_; ++j )
181  {
182  if ( isRate1d( i, j ) || isRateConstant( i, j ) )
183  delete vtTables_[i][j];
184  if ( isRate2d( i, j ) )
185  delete int2dTables_[i][j];
186  }
187  }
188 }
189 
190 VectorTable* MarkovRateTable::getVtChildTable( unsigned int i, unsigned int j ) const
191 {
192  if ( isRate1d( i, j ) || isRateConstant( i, j ) )
193  return vtTables_[i][j];
194  else
195  {
196  cerr << "MarkovRateTable::getVtChildTable : Error : No one parameter rate "
197  "table set for (" << i+1 << "," << j+1 << "). Returing NULL.\n";
198  return 0;
199  }
200 }
201 
202 void MarkovRateTable::innerSetVtChildTable( unsigned int i, unsigned int j,
203  VectorTable vecTable,
204  unsigned int ligandFlag )
205 {
206  if ( areIndicesOutOfBounds( i, j ) )
207  {
208  cerr << "MarkovRateTable::innerSetVtChildTable : Error : Table requested"
209  "is out of bounds!.\n";
210  return;
211  }
212 
213  //Checking to see if this rate has already been set with a 2-parameter rate.
214  if ( isRate2d( i, j ) || isRateConstant( i, j ) || isRate1d( i, j ) )
215  {
216  cerr << "MarkovRateTable::innerSetVtChildTable : Error : "
217  "Rate (" << i+1 << "," << j+1 << ")has already been set.\n";
218  return;
219  }
220 
221  if ( i == j )
222  {
223  cerr << "MarkovRateTable::innerSetVtChildTable : Error : Cannot "
224  "set diagonal rate (" << i+1 << "," << i+1 << endl;
225  return;
226  }
227 
228  //If table hasnt been allocated any memory, do so.
229  if ( vtTables_[i][j] == 0 )
230  vtTables_[i][j] = new VectorTable();
231 
232  *vtTables_[i][j] = vecTable;
233  useLigandConc_[i][j] = ligandFlag;
234 }
235 
236 Interpol2D* MarkovRateTable::getInt2dChildTable( unsigned int i, unsigned int j ) const
237 {
238  if ( isRate2d( i, j ) )
239  return int2dTables_[i][j];
240  else
241  {
242  cerr << "MarkovRateTable::getInt2dChildTable : Error : No two parameter"
243  " rate table set for (" << i+1 << "," << j+1 << "). Returning NULL.\n";
244  return 0;
245  }
246 }
247 
248 void MarkovRateTable::innerSetInt2dChildTable( unsigned int i, unsigned int j, Interpol2D int2dTable )
249 {
250  if ( areIndicesOutOfBounds( i, j ) )
251  {
252  cerr << "MarkovRateTable::innerSetInt2dChildTable : Error : Table requested"
253  " is out of bounds\n";
254  return;
255  }
256 
257  if ( isRate1d( i, j ) || isRate2d( i, j ) || isRateConstant( i, j ) )
258  {
259  cerr << "MarkovRateTable::innerSetInt2dChildTable : Error : Rate (" <<
260  i+1 << "," << j+1 << ") has already been set!\n";
261  return;
262  }
263 
264  if ( i == j )
265  {
266  cerr << "MarkovRateTable::innerSetInt2dChildTable : Error : Cannot "
267  "set diagonal rate (" << i+1 << "," << i+1 << endl;
268  return;
269  }
270 
271  //If table isn't already initialized, do so.
272  if ( int2dTables_[i][j] == 0 )
273  int2dTables_[i][j] = new Interpol2D();
274 
275  //Checking to see if this rate has already been set with a one parameter rate
276  //table.
277  *int2dTables_[i][j] = int2dTable;
278 }
279 
280 double MarkovRateTable::lookup1dValue( unsigned int i, unsigned int j, double x )
281 {
282  if ( areIndicesOutOfBounds( i, j ) )
283  {
284  cerr << "MarkovRateTable::lookup1dValue : Lookup requested on non-existent"
285  "table at (" << i + 1 << "," << j + 1 << "). Returning 0.\n";
286  return 0;
287  }
288 
289  if ( !isRate1d( i, j ) && !isRateConstant( i, j ) )
290  {
291  cerr << "MarkovRateTable::lookup1dValue : No 1D or constant rate set at "
292  "(" << i + 1 << "," << j + 1 << "). Returning 0.\n";
293  return 0;
294  }
295 
296  return vtTables_[i][j]->lookupByValue( x );
297 }
298 
299 double MarkovRateTable::lookup1dIndex( unsigned int i, unsigned int j,
300  unsigned int xIndex )
301 {
302  if ( areIndicesOutOfBounds( i, j ) )
303  {
304  cerr << "MarkovRateTable::lookup1dIndex : Lookup requested on non-"
305  "existent table at (" << i << "," << j << "). Returning 0.\n";
306  return 0;
307  }
308 
309  if ( !isRate1d( i, j ) && !isRateConstant( i, j ) )
310  {
311  cerr << "MarkovRateTable::lookup1dIndex : No 1D or constant rate set at ("
312  << i << "," << j << "). Returning 0.\n";
313  return 0;
314  }
315 
316  return vtTables_[i][j]->lookupByIndex( xIndex );
317 }
318 
319 double MarkovRateTable::lookup2dValue( unsigned int i, unsigned int j,
320  double x, double y )
321 {
322  if ( areIndicesOutOfBounds( i, j ) )
323  {
324  cerr << "MarkovRateTable::lookup2dValue : Lookup requested on non-existent"
325  " table at (" << i + 1<< "," << j+1 << "). Returning 0.\n";
326  return 0;
327  }
328 
329  if ( !isRate2d( i, j ) )
330  {
331  cerr << "MarkovRateTable::lookup2dValue : No 2D rate set at (" << i+1 << ","
332  << j+1 << "). Returning 0.\n";
333  return 0;
334  }
335 
336  return int2dTables_[i][j]->innerLookup( x, y );
337 }
338 
339 double MarkovRateTable::lookup2dIndex( unsigned int i, unsigned int j,
340  unsigned int xIndex, unsigned int yIndex )
341 {
342  if ( areIndicesOutOfBounds( i, j ) )
343  {
344  cerr << "MarkovRateTable::lookup2dIndex : Lookup requested on non-existent"
345  " table at (" << i+1 << "," << j+1 << "). Returning 0.\n";
346  return 0;
347  }
348 
349  if ( !isRate2d( i, j ) )
350  {
351  cerr << "MarkovRateTable::lookup2dIndex : No 2D rate set at (" << i+1 << ","
352  << j+1 << "). Returning 0.\n";
353  return 0;
354  }
355 
356  vector< unsigned int > indices;
357  indices.push_back( xIndex );
358  indices.push_back( yIndex );
359 
360  return int2dTables_[i][j]->getTableValue( indices );
361 }
362 
363 vector< vector< double > > MarkovRateTable::getQ() const
364 {
365  return Q_;
366 }
367 
368 unsigned int MarkovRateTable::getSize() const
369 {
370  return size_;
371 }
372 
373 double MarkovRateTable::getVm( ) const
374 {
375  return Vm_;
376 }
377 
378 void MarkovRateTable::setVm( double Vm )
379 {
380  Vm_ = Vm;
381 }
382 
384 {
385  return ligandConc_;
386 }
387 
388 void MarkovRateTable::setLigandConc( double ligandConc )
389 {
390  ligandConc_ = ligandConc;
391 }
392 
393 bool MarkovRateTable::isRateZero( unsigned int i, unsigned int j ) const
394 {
395  return ( vtTables_[i][j] == 0 && int2dTables_[i][j] == 0 );
396 }
397 
398 bool MarkovRateTable::isRateConstant( unsigned int i, unsigned int j ) const
399 {
400  if ( isRate2d( i, j ) || isRateZero( i, j ) )
401  return false;
402 
403  return ( vtTables_[i][j]->getDiv() == 0 );
404 }
405 
406 bool MarkovRateTable::isRate1d( unsigned int i, unsigned int j ) const
407 {
408  //Second condition is necessary because for a constant rate, the 1D lookup
409  //table class is set, but has only one entry. So a constant rate would pass
410  //off as a one-parameter rate transition if not for this check.
411  if ( vtTables_[i][j] == 0 )
412  return false;
413  else
414  return ( vtTables_[i][j]->getDiv() > 0 );
415 }
416 
417 bool MarkovRateTable::isRateLigandDep( unsigned int i, unsigned int j ) const
418 {
419  return ( isRate1d( i, j ) && useLigandConc_[i][j] > 0 );
420 }
421 
422 bool MarkovRateTable::isRate2d( unsigned int i, unsigned int j ) const
423 {
424  return ( int2dTables_[i][j] != 0 );
425 }
426 
427 bool MarkovRateTable::areIndicesOutOfBounds( unsigned int i, unsigned int j ) const
428 {
429  return ( i > size_ || j > size_ );
430 }
431 
433 {
434  return listOf1dRates_.empty() && listOf2dRates_.empty() &&
435  !listOfConstantRates_.empty();
436 }
437 
438 //Returns true if any of the rates vary with only one parameter.
440 {
441  return !listOf1dRates_.empty();
442 }
443 
445 {
446  return areAnyRates1d() && !areAnyRates2d();
447 }
448 
449 //Returns true if any of the rates vary with two parameters.
451 {
452  return !listOf2dRates_.empty();
453 }
454 
456 {
457  return areAnyRates2d() && !areAnyRates1d();
458 }
459 
460 //Returns true if at least one of the rates are ligand dependent.
462 {
463  return !listOfLigandRates_.empty();
464 }
465 
467 {
468  return areAllRates1d() && !areAnyRatesVoltageDep() &&
470 }
471 
472 //Returns true if at least one of the rates are voltage dependent.
474 {
475  return !listOfVoltageRates_.empty();
476 }
477 
479 {
480  return areAllRates1d() && areAnyRatesVoltageDep() &&
482 }
483 
485 {
486  double temp;
487  unsigned int i,j;
488 
489  //Update 1D rates, if any.
490  for( unsigned int k = 0; k < listOf1dRates_.size(); ++k )
491  {
492  j = ( listOf1dRates_[k] % 10 ) - 1;
493  i = ( ( listOf1dRates_[k] / 10 ) % 10 ) - 1;
494 
495  temp = Q_[i][j];
496 
497  if ( isRateLigandDep( i, j ) )
498  Q_[i][j] = lookup1dValue( i, j, ligandConc_ );
499  else
500  {
501  Q_[i][j] = lookup1dValue( i, j, Vm_ );
502  }
503 
504  //Ensures that the row sums to zero.
505  if ( !doubleEq( temp, Q_[i][j] ) )
506  Q_[i][i] = Q_[i][i] - Q_[i][j] + temp;
507  }
508 
509  //Update 2D rates, if any.
510  for( unsigned int k = 0; k < listOf2dRates_.size(); ++k )
511  {
512  j = ( listOf2dRates_[k] % 10 ) - 1;
513  i = ( ( listOf2dRates_[k] / 10 ) % 10 ) - 1;
514 
515  temp = Q_[i][j];
516 
517  Q_[i][j] = lookup2dValue( i, j, Vm_, ligandConc_ );
518 
519  //Ensures that the row sums to zero.
520  if ( !doubleEq( temp, Q_[i][j] ) )
521  Q_[i][i] = Q_[i][i] - Q_[i][j] + temp;
522  }
523 }
524 
526 {
527  unsigned int n = listOfConstantRates_.size(), i, j;
528  for ( unsigned int k = 0; k < n; ++k )
529  {
530  i = ( ( listOfConstantRates_[k] / 10 ) % 10 ) - 1;
531  j = ( listOfConstantRates_[k] % 10 ) - 1;
532 
533  Q_[i][i] += Q_[i][j];
534 
535  //Doesn't really matter which value is looked up as there is only one
536  //entry in the table.
537  Q_[i][j] = lookup1dValue( i, j, 0.0 );
538 
539  Q_[i][i] -= Q_[i][j];
540  }
541 }
542 
543 vector< unsigned int > MarkovRateTable::getListOf1dRates()
544 {
545  return listOf1dRates_;
546 }
547 
548 vector< unsigned int > MarkovRateTable::getListOf2dRates()
549 {
550  return listOf2dRates_;
551 }
552 
554 {
555  return listOfVoltageRates_;
556 }
557 
559 {
560  return listOfLigandRates_;
561 }
562 
564 {
565  return listOfConstantRates_;
566 }
567 
568 istream& operator>>( istream& in, MarkovRateTable& rateTable )
569 {
570  for ( unsigned int i = 0; i < rateTable.size_; ++i )
571  {
572  for ( unsigned int j = 0; j < rateTable.size_; ++j )
573  {
574  if ( rateTable.isRate1d( i, j ) )
575  in >> *rateTable.vtTables_[i][j];
576  }
577  }
578 
579  for ( unsigned int i = 0; i < rateTable.size_; ++i )
580  {
581  for ( unsigned int j = 0; j < rateTable.size_; ++j )
582  {
583  if ( rateTable.isRate2d( i, j ) )
584  in >> *rateTable.int2dTables_[i][j];
585  }
586  }
587 
588  for ( unsigned int i = 0; i < rateTable.size_; ++i )
589  {
590  for ( unsigned int j = 0; j < rateTable.size_; ++j )
591  in >> rateTable.useLigandConc_[i][j];
592  }
593  in >> rateTable.Vm_;
594  in >> rateTable.ligandConc_;
595  in >> rateTable.size_;
596 
597  return in;
598 }
599 
601 {
602  return ( size_ > 0 );
603 }
604 
606 // MsgDest functions.
609 {
610  if ( !areAllRatesConstant() )
611  updateRates();
612 
613  instRatesOut()->send( e, Q_ );
614 }
615 
617 {
618  if ( isInitialized() )
620  else
621  cerr << "MarkovRateTable::reinit : MarkovRateTable class has not been"
622  " initialized!.";
623 
624  instRatesOut()->send( e, Q_ );
625 }
626 
628 //MsgDest functions.
630 void MarkovRateTable::init( unsigned int size )
631 {
632  size_ = size;
633 
634  if ( vtTables_.empty() )
635  vtTables_ = resize< VectorTable* >( vtTables_, size, 0 );
636  if ( int2dTables_.empty() )
637  int2dTables_ = resize< Interpol2D* >( int2dTables_, size, 0 );
638  if ( useLigandConc_.empty() )
639  useLigandConc_ = resize< unsigned int >( useLigandConc_, size, 0 );
640  if ( Q_.empty() )
641  Q_ = resize< double >( Q_, size, 0 );
642 }
643 
644 void MarkovRateTable::handleVm( double Vm )
645 {
646  Vm_ = Vm;
647 }
648 
649 void MarkovRateTable::handleLigandConc( double ligandConc )
650 {
651  ligandConc_ = ligandConc;
652 }
653 
654 void MarkovRateTable::setVtChildTable( unsigned int i, unsigned int j,
655  Id vecTabId, unsigned int ligandFlag )
656 {
657  VectorTable* vecTable = reinterpret_cast< VectorTable* >
658  ( vecTabId.eref().data() );
659 
660  innerSetVtChildTable( i - 1, j - 1, *vecTable, ligandFlag );
661 
662  listOf1dRates_.push_back( i * 10 + j );
663 
664  if ( ligandFlag > 0 )
665  listOfLigandRates_.push_back( i * 10 + j );
666  else
667  listOfVoltageRates_.push_back( i * 10 + j );
668 }
669 
670 void MarkovRateTable::setInt2dChildTable( unsigned int i, unsigned int j,
671  Id int2dTabId )
672 {
673  Interpol2D* int2dTable = reinterpret_cast< Interpol2D* >
674  ( int2dTabId.eref().data() );
675 
676  innerSetInt2dChildTable( i - 1, j - 1, *int2dTable );
677 
678  listOf2dRates_.push_back( i * 10 + j );
679 }
680 
681 //Using the default 'setTable' function from the VectorTable class is rather
682 //clumsy when trying to set a constant rate, as one has to set up an entire
683 //VectorTable object. This function provides a wrapper around this rather
684 //complex setTable call.
685 void MarkovRateTable::setConstantRate( unsigned int i, unsigned int j, double rate )
686 {
687  VectorTable vecTable;
688 
689  vecTable.setMin( rate );
690  vecTable.setMax( rate );
691  vecTable.setDiv( 1 );
692 
693  vector< double > rateWrap;
694  rateWrap.push_back( rate );
695 
696  vecTable.setTable( rateWrap );
697 
698  innerSetVtChildTable( i - 1, j - 1, vecTable, 0 );
699 
700  listOfConstantRates_.push_back( i * 10 + j );
701 }
vector< unsigned int > listOfConstantRates_
static SrcFinfo1< vector< vector< double > > > * instRatesOut()
istream & operator>>(istream &in, MarkovRateTable &rateTable)
char * data() const
Definition: Eref.cpp:41
vector< vector< Interpol2D * > > int2dTables_
vector< unsigned int > getListOf2dRates()
bool areIndicesOutOfBounds(unsigned int, unsigned int) const
void process(const Eref &, ProcPtr)
Interpol2D * getInt2dChildTable(unsigned int, unsigned int) const
Definition: Dinfo.h:60
Definition: OpFunc.h:56
void setMin(double)
void reinit(const Eref &, ProcPtr)
bool isRateConstant(unsigned int, unsigned int) const
vector< vector< double > > getQ() const
void setVtChildTable(unsigned int, unsigned int, Id, unsigned int)
vector< unsigned int > listOf2dRates_
VectorTable * getVtChildTable(unsigned int, unsigned int) const
Eref eref() const
Definition: Id.cpp:125
void setTable(vector< double >)
vector< unsigned int > getListOfConstantRates()
vector< unsigned int > listOfLigandRates_
static const Cinfo * initCinfo()
unsigned int size_
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
void handleVm(double)
vector< unsigned int > getListOf1dRates()
void setVm(double)
bool isRateLigandDep(unsigned int, unsigned int) const
vector< unsigned int > getListOfVoltageRates()
void init(unsigned int)
void setMax(double)
bool isRate1d(unsigned int, unsigned int) const
bool isInitialized() const
vector< vector< VectorTable * > > vtTables_
Definition: OpFunc.h:27
Definition: Eref.h:26
bool isRate2d(unsigned int, unsigned int) const
bool isRateZero(unsigned int, unsigned int) const
static const Cinfo * MarkovRateTableCinfo
vector< vector< unsigned int > > useLigandConc_
void innerSetVtChildTable(unsigned int, unsigned int, VectorTable, unsigned int)
double lookup2dValue(unsigned int, unsigned int, double, double)
void setConstantRate(unsigned int, unsigned int, double)
unsigned int getSize() const
Definition: Id.h:17
vector< unsigned int > listOfVoltageRates_
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
void setLigandConc(double)
vector< unsigned int > getListOfLigandRates()
void handleLigandConc(double)
void setInt2dChildTable(unsigned int, unsigned int, Id)
double lookup2dIndex(unsigned int, unsigned int, unsigned int, unsigned int)
vector< unsigned int > listOf1dRates_
double getLigandConc() const
void setDiv(unsigned int)
Definition: Cinfo.h:18
Definition: OpFunc.h:70
double lookup1dValue(unsigned int, unsigned int, double)
double lookup1dIndex(unsigned int, unsigned int, unsigned int)
void innerSetInt2dChildTable(unsigned int, unsigned int, Interpol2D)
double getVm() const
vector< vector< double > > Q_
Definition: Finfo.h:12