/**********************************************************************
** This program is part of the kinetics library and is
** copyright (C) 1995 Upinder S. Bhalla.
** It is made available under the terms of the
** GNU Library General Public License.
** See the file COPYRIGHT for the full notice.
**********************************************************************/
/* $Id: kin_struct.h,v 1.3 2005/08/12 09:38:17 svitak Exp $ */
/*
* $Log: kin_struct.h,v $
* Revision 1.3 2005/08/12 09:38:17 svitak
* Switched comment style from slashslash to slashstar.
*
* Revision 1.2 2005/07/01 10:03:04 svitak
* Misc fixes to address compiler warnings, esp. providing explicit types
* for all functions and cleaning up unused variables.
*
* Revision 1.1.1.1 2005/06/14 04:38:34 svitak
* Import from snapshot of CalTech CVS tree of June 8, 2005
*
* Revision 1.5 2003/05/29 22:26:40 gen-dbeeman
* New version of kinetics library from Upi Bhalla, April 2003
*
* Revision 1.4 2000/06/12 04:44:47 mhucka
* Removed nested comments to quiet some compilers.
*
* Revision 1.3 1998/07/15 06:45:33 dhb
* Upi update
*
* Revision 1.2 1997/07/24 18:26:26 dhb
* Library modified to live in the GENESIS distribution source heirarchy
* and to exclude the 2D interpolation and table modules which have been
* integrated into the distribution elsewhere.
*
* Also excluded ksolve object as it no longer works (per the author).
*
* Revision 1.1 1997/07/24 17:49:40 dhb
* Initial revision
*
* Revision 1.3 1994/08/30 21:28:35 bhalla
* Many changes related to the new ksolve object
*
* Revision 1.2 1994/08/05 19:25:24 bhalla
* Changed many structs so that we can use n rather than conc.
* Also added conserve flag to the pool for handling conservation eqns.
*
* Revision 1.1 1994/06/13 22:55:39 bhalla
* Initial revision
* */
#include "struct_defs.h"
/*
** The 2D interpolation and table modules have been integrated into
** the GENESIS distribution elsewhere. If this library is used in
** some other code and the 2D table code is desired, define
** INCLUDE_INTERP.
*/
#ifdef INCLUDE_INTERP
#ifndef _kin_interp_h
#define _kin_interp_h
#ifndef TABCREATE
#define TABCREATE 200
#endif
/* 2-d interpolation can use either a uniform grid or a nonuniform
** grid. The former is more efficient but not good for handling
** wide-ranging values. The latter is slower both since a search is
** needed to find the correct grid points, and since the calculations
** are a little longer, but good
** for grids with varying coarseness. For now only the first is used
*/
struct interpol2d_struct {
double xmin;
double xmax;
int xdivs;
double dx;
double invdx;
double *xgrid;
short xgrid_allocated;
double ymin;
double ymax;
int ydivs;
double dy;
double invdy;
double *ygrid;
short ygrid_allocated;
double sx,sy,sz;
double ox,oy,oz;
double **table;
short calc_mode; /* This can be one of : NO_INTERP, LIN_INTERP,
** FIXED */
short allocated;
};
typedef struct interpol2d_struct Interpol2D;
#define TAB_IO 0
#define TAB_LOOP 1
#define TAB_ONCE 2
#define TAB_BUF 3
struct table2d_type {
ELEMENT_TYPE
double input;
double input2;
double output;
double negoutput;
struct interpol2d_struct *table;
short alloced;
short step_mode;
double stepsize;
};
#endif /* _kin_interp_h */
#endif /* INCLUDE_INTERP */
/*
**Sequence of processing must be:
** 1. PROCESS of enz and reac. Collects all the concens from the pools
** and figures out changes.
** 2. PROCESS of pools. Updates concens using calculations of enz and
** reac.
*/
#define KIN_POOL_MSGCOUNT 8
struct pool_type {
ELEMENT_TYPE
double CoTotal; /* Total concen of C. Needed when C exists in
** 2 states, and the other should be slaved to
** this one */
double CoInit; /* Initial value for Co after RESET */
double Co; /* Current concen of C */
double CoRemaining; /* Cototal - Co */
double CoMin; /* minimum value (usually 0) that Co can take*/
double n; /* Current # of pool molecules */
double nInit; /* Initial value for n after RESET */
double nTotal; /* Total number of pool molecules */
double nRemaining; /* nTotal - n */
double nMin; /* Minimum allowed value for n */
double vol; /* Volume of pool */
int slave_enable;
int keepconc; /* flag for whether to change concs or n when
** vol changes */
int consv_flag; /* Internal flag keeping track of presence
** of CONSERVE and SUMTOTAL msgs */
int stoch_flag; /* Flag for doing stochastic calculations */
int mirror_src; /* Flag for mirror sources */
/* Private fields */
double** msgdata;
int mirrormsgoffset; /* Saves start of mirror msgs */
int msgcount[KIN_POOL_MSGCOUNT];
int was_slaved;
int oldmsgmode;
};
/*
** These numbers apply when stochastic integration is in progress.
** They limit the value that the probability of a transition may
** reach. If the probability is greater than KIN_STOCH_UPPER_PROB_LIMIT
** the system switches into continuous integration mode. If it falls
** below KIN_STOCH_LOWER_PROB_LIMIT it goes back into stoch mode.
** There are two limits so as to introduce some hysteresis and
** prevent 'surfing' oscillatory behaviour.
*/
extern double KIN_STOCH_PROB_LIMIT;
/* This sets a minimum on the number of molecules that must be
* present before continuous integration is allowed
*
*/
#define KIN_STOCH_EPSILON 1e-9
extern double KIN_STOCH_MOL_LIMIT;
struct reac_type {
ELEMENT_TYPE
double A,B; /* state variables used in communicating
** with pools */
float kf,kb; /* forward and backward rate consts */
int stoch_flag; /* Flag for doing stochastic calculations */
int sub_stoch_flag; /* Flag for forward part of reacn */
int prd_stoch_flag; /* Flag for backward part of reacn */
int dep_graph_index;
/* private */
double **msgdata;
int *se[50]; /* Hack. I don't expect more than 20 messages
from pools, hence 20 slave_enable flags. */
int msgcount[2];
int oldmsgmode;
};
struct enz_type {
ELEMENT_TYPE
double CoComplexInit; /* Initial value for CoComplex */
double CoComplex; /* enzyme complex */
double nComplexInit; /* Initial value for nComplex */
double nComplex; /* enzyme complex */
double vol; /* enzyme vol: normally slaved to pool vol */
double sA,pA,eA,B; /* values for returning msgs to pools */
float k1,k2,k3; /* Michaelis-Menten parameters */
int keepconc; /* flag for whether to change concs or n when
** vol changes */
int usecomplex; /* Flag for whether the enz complex can be
** used in other reactions */
int stoch_flag; /* Flag for doing stochastic calculations */
int sub_stoch_flag;
int complex_stoch_flag;
int propensity_problem;
int dep_graph_index;
/* private fields */
float ksum; /* ksum = k2+k3, set automatically */
double **msgdata;
int *se[50]; /* Hack. I don't expect more than 20 messages
from pools, hence 20 slave_enable flags. */
int msgcount[5];
int oldmsgmode;
};
struct concchan_type {
ELEMENT_TYPE
double A,B; /* state variables used in communicating
** with pools */
float perm; /* Permeability */
float gmax; /* conductance */
double n; /* number of concchans */
double Vm; /* potential across channel */
/* private */
int is_active;
int use_nernst;
};
#if 0
/* For each coeff, the product of the pool 'n's with the coeff is
** summed back onto the destpool. This arrangement handles all
** enz and reacs.
*/
struct reac_coeff_type {
double coeff; /* the rate const */
int npools; /* the number of pools involved */
double **n; /* pointers to the pools; */
double *destpool; /* pointer to the pool whose rate consts are
** being calculated */
};
/* Calculates all terms for a simple first-order reacn */
/* ddest = -dsrc = kf * src - kb * dest */
struct reac_1_1_type {
double *src;
double *dest;
double kf;
double kb;
};
/* Calculates all terms for a simple 2nd-order reacn */
/* ddest = -dsrc = kf * src1 * src2 - kb * dest */
struct reac_2_1_type {
double *src1;
double *src2;
double *dest;
double kf;
double kb;
};
/* Calculates all terms for a simple 3rd-order reacn */
/* ddest = -dsrc = kf * src1 * src2 * src3 - kb * dest */
struct reac_3_1_type {
double *src1;
double *src2;
double *src3;
double *dest;
double kf;
double kb;
};
#endif
/* This isn't used in the integration steps, but for
** housekeeping and other not-too-expensive operations
*/
struct pool_coeff_type {
double *pool;
double init;
};
/* Calculates all terms for a simple nth-order reacn */
/* ddest = -dsrc = kf * prd(srci) - kb * prd(desti) */
struct reac_coeff_type {
double **pools; /* first the src, then NULL, then prd, then NULL*/
double kf;
double kb;
};
/* Calculates all terms for an enz reaction */
/* dsub = -k1 * enz * PRD(sub) + k2 * enzcomplex
dprd = k3 * enzcomplex
denz = dsub + dprd
*/
struct enz_coeff_type {
double k1,k2,k3;
double enzcomplexinit;
double *enzcomplex;
double *enz;
double **prd;
double **sub;
};
/* Calculates terms for concchan */
/* Calculates dnsrc = -dndest =
-nchan * (perm_by_vol1 * nsrc - perm_by_vol2 * ndest)
*/
struct concchan_coeff_type {
double *chan; /* pointer to the channel n */
double perm_by_vol1; /* coeff for source pool */
double *src; /* n of source */
double perm_by_vol2; /* coeff for dest pool */
double *dest; /* n of dest */
};
/* Calculates npool = nTot - sum(n) to handle conservation reactions.
** This is done after all other calculations in case any of the
** other eager calculations changed npool. In a reflection of
** a similar hack with the pool, if nTot is -ve then it uses
** npool = sum(nothers) */
struct conserve_coeff_type {
double *pool;
double tot;
double init;
int num_others;
double **others;
};
struct handle_msgins {
int clockno; /* this is the largest dt of the src and dest
** It is used to decide whether to sample the msg */
double nexttime;
int nmsgins; /* Number of incoming msgs handled at this dt */
Element **msgelm; /* Array of pointers to the elms getting msg */
MsgIn **msgin; /* array of pointers to the msgs itself */
double **destpool; /* destination pools */
};
struct gsolve_type
{
ELEMENT_TYPE
/*
* gsolve fields
*/
/*
* int stoch_flag;
*/
/*
* Flag for doing stochastic calculations
*/
/*
* Private fields
*/
double **msgdata;
int mirrormsgoffset; /* Saves start of mirror msgs */
int msgcount[KIN_POOL_MSGCOUNT];
int was_slaved;
int oldmsgmode;
ElementList *reac_list;
int reac_list_populated;
ElementList *enz_list;
int enz_list_populated;
ElementList *pool_list;
int pool_list_populated;
ElementList *sumtotal_list; /* List of pools handling sumtotals */
double propensity_reac[2][500]; /* stores propensity values, one
* dimension for forward/backward,
* other for different reactions */
double propensity_enz[3][300]; /* stores propensity values for
enzymes */
double propensity_total;
double internal_time;
int method;
};
struct handle_msgouts {
int clockno; /* this is clockno of the largest dt of the
** src and dest.
** It is used to decide whether to update the field */
double nexttime;
int nmsgouts; /* number of fields needing update at this dt*/
Element **msgelm; /* array of pointers to the elms with msgouts */
double **srcpool; /* array of source pools */
int *isenz;
};
struct kentry_type {
int type;
char *coeff;
double *pool;
};
struct ksolve_type {
ELEMENT_TYPE
double currtime;/* current time to which integration has been done.
** Note that this may exceed Simtime because
** ksolve uses adaptive timesteps */
double lasttime; /* previous time found */
double nextstep; /* next time step to use */
double minstep; /* minimum allowed time step */
int nok; /* count the good and bad steps */
int nbad;
double vol;
double *xtrapvector;
double *xtrapmatrix;
char *path;
int method;
double eps;
char *elm_to_pointer; /* Hash table for finding pointers */
int npools;
double *pools; /* successive entries are explained in the
** ksolve.c. There are 8 entries for each pool */
/* The array is filled in order, by pools, enzs,
** sumtots, consvs, slaves, and dummys. We assume
** that the correct state is known at setup time
** so that the pools can be ordered efficiently,
** with the pools, enzs and sumtots first, since
** they are the only ones that need to be
** integrated. */
int npoolcoeffs;
struct pool_coeff_type *poolcoeffs;
int nreacs;
struct reac_coeff_type *reacs;
int nenzs;
struct enz_coeff_type *enzs;
int nconcchans;
struct concchan_coeff_type *concchans;
int nconsvs; /* consvs and sumtots share a common data struct */
int nsumtots;
struct conserve_coeff_type *consvs;
int nslaves;
int nmsgins;
struct handle_msgins *msgins;
int nmsgouts;
struct handle_msgouts *msgouts;
int nkentries;
struct kentry_type *kentries;
};
#define TEXT_START_SIZE 1000
struct text_type {
ELEMENT_TYPE
char *str;
int len;
};