00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "../utility/numutil.h"
00018 class RateTerm
00019 {
00020 public:
00021 RateTerm() {;}
00022 virtual ~RateTerm() {;}
00024 virtual double operator() ( const double* S ) const = 0;
00025
00029 virtual void setRates( double k1, double k2 ) = 0;
00030
00032 virtual void setR1( double k1 ) = 0;
00033
00035 virtual void setR2( double k2 ) = 0;
00036
00038 virtual double getR1() const = 0;
00039
00041 virtual double getR2() const = 0;
00042
00050 virtual unsigned int getReactants(
00051 vector< unsigned int >& molIndex ) const = 0;
00052 static const double EPSILON;
00053
00063 virtual void rescaleVolume( short comptIndex,
00064 const vector< short >& compartmentLookup, double ratio ) = 0;
00065
00075 virtual RateTerm* copyWithVolScaling(
00076 double vol, double sub, double prd ) const = 0;
00077 };
00078
00079
00080
00081 class MMEnzymeBase: public RateTerm
00082 {
00083 public:
00084 MMEnzymeBase( double Km, double kcat, unsigned int enz )
00085 : Km_( Km ), kcat_( kcat ), enz_( enz )
00086 {
00087 assert( Km_ > 0.0 );
00088 }
00089
00090 void setKm( double Km ) {
00091 if ( Km > 0.0 )
00092 Km_ = Km;
00093 }
00094
00095 void setKcat( double kcat ) {
00096 if ( kcat > 0 )
00097 kcat_ = kcat;
00098 }
00099
00100 void setRates( double Km, double kcat ) {
00101 setKm( Km );
00102 setKcat( kcat );
00103 }
00104
00105 void setR1( double Km ) {
00106 setKm( Km );
00107 }
00108
00109 void setR2( double kcat ) {
00110 setKcat( kcat );
00111 }
00112
00113 double getR1() const {
00114 return Km_;
00115 }
00116
00117 double getR2() const {
00118 return kcat_;
00119 }
00120
00121 void rescaleVolume( short comptIndex,
00122 const vector< short >& compartmentLookup, double ratio )
00123 {
00124 Km_ *= ratio;
00125 }
00126
00127 unsigned int getEnzIndex() const
00128 {
00129 return enz_;
00130 }
00131
00132 protected:
00133 double Km_;
00134 double kcat_;
00135 unsigned int enz_;
00136 };
00137
00138
00139 class MMEnzyme1: public MMEnzymeBase
00140 {
00141 public:
00142 MMEnzyme1( double Km, double kcat,
00143 unsigned int enz, unsigned int sub )
00144 : MMEnzymeBase( Km, kcat, enz ), sub_( sub )
00145 {
00146 ;
00147 }
00148
00149 double operator() ( const double* S ) const {
00150
00151 return ( kcat_ * S[ sub_ ] * S[ enz_ ] ) / ( Km_ + S[ sub_ ] );
00152 }
00153
00154 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00155 molIndex.resize( 2 );
00156 molIndex[0] = enz_;
00157 molIndex[1] = sub_;
00158 return 2;
00159 }
00160
00161 RateTerm* copyWithVolScaling(
00162 double vol, double sub, double prd ) const
00163 {
00164 double ratio = vol * sub * NA;
00165 return new MMEnzyme1( ratio * Km_, kcat_, enz_, sub_);
00166 }
00167
00168 private:
00169 unsigned int sub_;
00170 };
00171
00172 class MMEnzyme: public MMEnzymeBase
00173 {
00174 public:
00175 MMEnzyme( double Km, double kcat,
00176 unsigned int enz, RateTerm* sub )
00177 : MMEnzymeBase( Km, kcat, enz ), substrates_( sub )
00178 {
00179 ;
00180 }
00181
00182 double operator() ( const double* S ) const {
00183 double sub = (*substrates_)( S );
00184
00185 assert( sub >= -EPSILON );
00186 return ( sub * kcat_ * S[ enz_ ] ) / ( Km_ + sub );
00187 }
00188
00189 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00190 substrates_->getReactants( molIndex );
00191 molIndex.insert( molIndex.begin(), enz_ );
00192 return molIndex.size();
00193 }
00194
00195 RateTerm* copyWithVolScaling(
00196 double vol, double sub, double prd ) const
00197 {
00198 double ratio = sub * vol * NA;
00199 return new MMEnzyme( ratio * Km_, kcat_, enz_, substrates_ );
00200 }
00201 private:
00202 RateTerm* substrates_;
00203 };
00204
00205 class ExternReac: public RateTerm
00206 {
00207 public:
00208
00209
00210 double operator() ( const double* S ) const {
00211 double ret = 0.0;
00212 return ret;
00213 }
00214 void setRates( double k1, double k2 ) {
00215 ;
00216 }
00217
00218 void setR1( double k1 ) {
00219 ;
00220 }
00221
00222 void setR2( double k2 ) {
00223 ;
00224 }
00225
00226 double getR1() const {
00227 return 0.0;
00228 }
00229
00230 double getR2() const {
00231 return 0.0;
00232 }
00233
00234 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00235 molIndex.resize( 0 );
00236 return 0;
00237 }
00238
00239 void rescaleVolume( short comptIndex,
00240 const vector< short >& compartmentLookup, double ratio )
00241 {
00242 return;
00243 }
00244
00245 RateTerm* copyWithVolScaling(
00246 double vol, double sub, double prd ) const
00247 {
00248 return new ExternReac();
00249 }
00250
00251 private:
00252 };
00253
00254 class ZeroOrder: public RateTerm
00255 {
00256 public:
00257 ZeroOrder( double k )
00258 : k_( k )
00259 {
00260 assert( !std::isnan( k_ ) );
00261 }
00262
00263 double operator() ( const double* S ) const {
00264 assert( !std::isnan( k_ ) );
00265 return k_;
00266 }
00267
00268 void setK( double k ) {
00269 assert( !std::isnan( k ) );
00270 if ( k >= 0.0 )
00271 k_ = k;
00272 }
00273
00274 void setRates( double k1, double k2 ) {
00275 setK( k1 );
00276 }
00277
00278 void setR1( double k1 ) {
00279 setK( k1 );
00280 }
00281
00282 void setR2( double k2 ) {
00283 ;
00284 }
00285
00286 double getR1() const {
00287 return k_;
00288 }
00289
00290 double getR2() const {
00291 return 0.0;
00292 }
00293
00294 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00295 molIndex.resize( 0 );
00296 return 0;
00297 }
00298
00299 void rescaleVolume( short comptIndex,
00300 const vector< short >& compartmentLookup, double ratio )
00301 {
00302 return;
00303 }
00304
00305 RateTerm* copyWithVolScaling(
00306 double vol, double sub, double prd ) const
00307 {
00308 return new ZeroOrder( k_ );
00309 }
00310 protected:
00311 double k_;
00312 };
00313
00320 class Flux: public ZeroOrder
00321 {
00322 public:
00323 Flux( double k, unsigned int y )
00324 : ZeroOrder( k ), y_( y )
00325 {;}
00326
00327 double operator() ( const double* S ) const {
00328 assert( !std::isnan( S[ y_ ] ) );
00329 return k_ * S[ y_ ];
00330 }
00331
00332 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00333 molIndex.resize( 0 );
00334 return 0;
00335 }
00336
00337 void rescaleVolume( short comptIndex,
00338 const vector< short >& compartmentLookup, double ratio )
00339 {
00340 return;
00341 }
00342
00343 RateTerm* copyWithVolScaling(
00344 double vol, double sub, double prd ) const
00345 {
00346 return new Flux( k_, y_ );
00347 }
00348
00349 private:
00350 unsigned int y_;
00351 };
00352
00353 class FirstOrder: public ZeroOrder
00354 {
00355 public:
00356 FirstOrder( double k, unsigned int y )
00357 : ZeroOrder( k ), y_( y )
00358 {;}
00359
00360 double operator() ( const double* S ) const {
00361 assert( !std::isnan( S[ y_ ] ) );
00362 return k_ * S[ y_ ];
00363 }
00364
00365 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00366 molIndex.resize( 1 );
00367 molIndex[0] = y_;
00368 return 1;
00369 }
00370
00371 void rescaleVolume( short comptIndex,
00372 const vector< short >& compartmentLookup, double ratio )
00373 {
00374 return;
00375 }
00376
00377 RateTerm* copyWithVolScaling(
00378 double vol, double sub, double prd ) const
00379 {
00380 return new FirstOrder( k_ / sub, y_ );
00381 }
00382
00383 private:
00384 unsigned int y_;
00385 };
00386
00387 class SecondOrder: public ZeroOrder
00388 {
00389 public:
00390 SecondOrder( double k, unsigned int y1, unsigned int y2 )
00391 : ZeroOrder( k ), y1_( y1 ), y2_( y2 )
00392 {;}
00393
00394 double operator() ( const double* S ) const {
00395 assert( !std::isnan( S[ y1_ ] ) );
00396 assert( !std::isnan( S[ y2_ ] ) );
00397 return k_ * S[ y1_ ] * S[ y2_ ];
00398 }
00399
00400 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00401 molIndex.resize( 2 );
00402 molIndex[0] = y1_;
00403 molIndex[1] = y2_;
00404 return 2;
00405 }
00406
00407 void rescaleVolume( short comptIndex,
00408 const vector< short >& compartmentLookup, double ratio )
00409 {
00410 if ( comptIndex == compartmentLookup[ y1_ ] ||
00411 comptIndex == compartmentLookup[ y2_ ] )
00412 k_ /= ratio;
00413 }
00414
00415 RateTerm* copyWithVolScaling(
00416 double vol, double sub, double prd ) const
00417 {
00418 double ratio = sub * vol * NA;
00419 return new SecondOrder( k_ / ratio, y1_, y2_ );
00420 }
00421
00422 private:
00423 unsigned int y1_;
00424 unsigned int y2_;
00425 };
00426
00434 class StochSecondOrderSingleSubstrate: public ZeroOrder
00435 {
00436 public:
00437 StochSecondOrderSingleSubstrate( double k, unsigned int y )
00438 : ZeroOrder( k ), y_( y )
00439 {;}
00440
00441 double operator() ( const double* S ) const {
00442 double y = S[ y_ ];
00443 assert( !std::isnan( y ) );
00444 return k_ * ( y - 1 ) * y;
00445 }
00446
00447 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00448 molIndex.resize( 2 );
00449 molIndex[0] = y_;
00450 molIndex[1] = y_;
00451 return 2;
00452 }
00453
00454 void rescaleVolume( short comptIndex,
00455 const vector< short >& compartmentLookup, double ratio )
00456 {
00457 if ( comptIndex == compartmentLookup[ y_ ] )
00458 k_ /= ratio;
00459 }
00460
00461 RateTerm* copyWithVolScaling(
00462 double vol, double sub, double prd ) const
00463 {
00464 double ratio = sub * vol * NA;
00465 return new StochSecondOrderSingleSubstrate( k_ / ratio, y_ );
00466 }
00467
00468 private:
00469 const unsigned int y_;
00470 };
00471
00472 class NOrder: public ZeroOrder
00473 {
00474 public:
00475 NOrder( double k, vector< unsigned int > v )
00476 : ZeroOrder( k ), v_( v )
00477 {;}
00478
00479 double operator() ( const double* S ) const {
00480 double ret = k_;
00481 vector< unsigned int >::const_iterator i;
00482 for ( i = v_.begin(); i != v_.end(); i++) {
00483 assert( !std::isnan( S[ *i ] ) );
00484 ret *= S[ *i ];
00485 }
00486 return ret;
00487 }
00488
00489 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00490 molIndex = v_;
00491 return v_.size();
00492 }
00493
00494 void rescaleVolume( short comptIndex,
00495 const vector< short >& compartmentLookup, double ratio )
00496 {
00497 for ( unsigned int i = 1; i < v_.size(); ++i ) {
00498 if ( comptIndex == compartmentLookup[ v_[i] ] )
00499 k_ /= ratio;
00500 }
00501 }
00502
00503 RateTerm* copyWithVolScaling(
00504 double vol, double sub, double prd ) const
00505 {
00506 assert( v_.size() > 0 );
00507 double ratio = sub * pow( NA * vol, (int)( v_.size() ) - 1 );
00508 return new NOrder( k_ / ratio, v_ );
00509 }
00510
00511 protected:
00512 vector< unsigned int > v_;
00513 };
00514
00522 class StochNOrder: public NOrder
00523 {
00524 public:
00525 StochNOrder( double k, vector< unsigned int > v );
00526
00527 double operator() ( const double* S ) const;
00528
00529 RateTerm* copyWithVolScaling(
00530 double vol, double sub, double prd ) const
00531 {
00532 assert( v_.size() > 0 );
00533 double ratio = sub * pow( vol * NA, (int)( v_.size() ) -1);
00534 return new StochNOrder( k_ / ratio, v_ );
00535 }
00536 };
00537
00538 extern class ZeroOrder*
00539 makeHalfReaction( double k, vector< unsigned int > v );
00540
00541 class BidirectionalReaction: public RateTerm
00542 {
00543 public:
00544 BidirectionalReaction(
00545 ZeroOrder* forward, ZeroOrder* backward)
00546 : forward_( forward ), backward_( backward )
00547 {
00548
00549 ;
00550 }
00551 ~BidirectionalReaction()
00552 {
00553 delete forward_;
00554 delete backward_;
00555 }
00556
00557 double operator() ( const double* S ) const {
00558 return (*forward_)( S ) - (*backward_)( S );
00559 }
00560
00561 void setRates( double kf, double kb ) {
00562 forward_->setK( kf );
00563 backward_->setK( kb );
00564 }
00565
00566 void setR1( double kf ) {
00567 forward_->setK( kf );
00568 }
00569
00570 void setR2( double kb ) {
00571 backward_->setK( kb );
00572 }
00573
00574 double getR1() const {
00575 return forward_->getR1();
00576 }
00577
00578 double getR2() const {
00579 return backward_->getR1();
00580 }
00581
00582 unsigned int getReactants( vector< unsigned int >& molIndex ) const{
00583 forward_->getReactants( molIndex );
00584 unsigned int ret = molIndex.size();
00585 vector< unsigned int > temp;
00586 backward_->getReactants( temp );
00587 molIndex.insert( molIndex.end(), temp.begin(), temp.end() );
00588 return ret;
00589 }
00590
00591 void rescaleVolume( short comptIndex,
00592 const vector< short >& compartmentLookup, double ratio )
00593 {
00594 forward_->rescaleVolume( comptIndex, compartmentLookup, ratio );
00595 backward_->rescaleVolume( comptIndex, compartmentLookup, ratio);
00596 }
00597 RateTerm* copyWithVolScaling(
00598 double vol, double sub, double prd ) const
00599 {
00600 ZeroOrder* f = static_cast< ZeroOrder* >(
00601 forward_->copyWithVolScaling( vol, sub, 1 ) );
00602 ZeroOrder* b = static_cast< ZeroOrder* >(
00603 backward_->copyWithVolScaling( vol, prd, 1 ) );
00604 return new BidirectionalReaction( f, b );
00605 }
00606
00607 private:
00608 ZeroOrder* forward_;
00609 ZeroOrder* backward_;
00610 };