#include #include #include #include #define PI 3.1415926535897932384626433 // QUICKSORT INCLUDED!! // REAL DATA INPUT!! // INFINITE CELLS!! // INNER DYNAMICS!! /*************************************************************************************/ /***************************** Declare New Structures ********************************/ /*************************************************************************************/ typedef struct{ // Create a new structure called 'coord' to contain cell coordinates float x; // Create 'x' member of coord float y; // Create 'y' member of coord float z; // Create 'z' member of coord float hsl; float iptg; int lysis; // Lysis state (on or off) int condition; // 0 - not , 1= qs, 2 = lysis, 3 = dead float randx; // Create 'x' member of coord float randy; // Create 'y' member of coord float randz; // Create 'z' member of coord float radii; int tumble; } data; typedef struct{ float x; float y; float z; }coord; /*************************************************************************************/ /***************************** Declare Subfunctions **********************************/ /*************************************************************************************/ void initial_cell_number(int *cell_number, float density, float observed_radius, FILE *outfile10); void initial_cell_prop(int cell_number, float observed_radius, data *cell, FILE *outfile10); void movement(int cell_number, data *cell, coord source); void radii_function(int cell_number, data *cell, coord source, FILE *outfile10); void sort(int i,int cell_number,float *radii,int *order,data *cell, FILE *outfile10); void quorum_sensing(int i, int cell_number, float *effective_radius, float qs_density, data *cell, float *radii, int *order, FILE *outfile10); void inner_dynamics(int cell_number, data *cell, int *number_death, int *number_alive, int *number_qs, FILE *outfile6); void cell_increase(int cell_number, int *increase_cell_number, float observed_radius, float density, float *radii, FILE *outfile10); void increase_cell_prop(int cell_number, int increase_cell_number, float observed_radius, data *cell); void cell_decrease(int cell_number, int *decrease_cell_number, data *cell); void density_function(int i, int cell_number, float observed_radius, float *radii, FILE *outfile2); //////////////////////////////// float vsphere(float r); void quicksort(float *radii,int *order,int first,int last); int partition(float *radii,int *order,int first,int last); const int PoissonRandomNumber(const double lambda); int main(){ /*************************************************************************************/ /****************************** Seed random number ***********************************/ /*************************************************************************************/ srand(time(NULL)); /*************************************************************************************/ /********************************* Variables Known ***********************************/ /*************************************************************************************/ int i; // Used as a counter for time int j; // Used as a counter for cells int k; // Spare counter int qs_number; int counter = 0; ////////////////////////////// int time_step = 20000; // Number of time iterations (second) float observed_radius = 0.005; // Radius within which 'observe' - determine properties (meter) float density = 1.0*pow(10,12); // TEMP: Initial density of cells (meter^3) float qs_density = 7*pow(10,14); // Density which causes quorum sensing (meter^3) $$Cellular COntrol Of Synthesis$$ /*************************************************************************************/ /********************************* Variables Unknown *********************************/ /*************************************************************************************/ int cell_number = 0; // Number of cells at each time step int increase_cell_number = 0; // Increase in cells each time step int decrease_cell_number = 0; // Decrease in cells each time step float effective_radius = 0; // Minimum quroum sensing radius int number_death = 0; int number_alive = 0; int number_qs = 0; /*************************************************************************************/ /************************************ Scale ******************************************/ /*************************************************************************************/ float scale = 5000; density /= scale; qs_density /= scale; /*************************************************************************************/ /****************************** Initialise Variables *********************************/ /*************************************************************************************/ coord source; source.x = 0.0; source.y = 0.0; source.z = 0.0; /*************************************************************************************/ /************************************* Outfiles **************************************/ /*************************************************************************************/ // Outfile 1 lists results as a single column FILE *outfile1; outfile1=fopen("output/chemotaxis_single.dat","w"); // Outfile 2 lists density aginst time step and position FILE *outfile2; outfile2=fopen("output/density.dat","w"); // Outfile 3 lists cell number aginst time step FILE *outfile3; outfile3=fopen("output/cell_number.dat","w"); // Outfile 4 lists effective radius aginst time step FILE *outfile4; outfile4=fopen("output/effective_radius.dat","w"); // Outfile 5 lists hsl and iptg aginst time step FILE *outfile5; outfile5=fopen("output/environment.dat","w"); // Outfile 6 lists condition FILE *outfile6; outfile6=fopen("output/condition.dat","w"); // Outfile 10 Check FILE *outfile10; outfile10=fopen("output/check.dat","w"); ////////////////////////////////////////////////////////// printf("main\n"); initial_cell_number(&cell_number, density, observed_radius, outfile10); // FUNCTION: Calculate the initial cell number data *cell; cell = (data *) malloc (cell_number * sizeof(data)); // Initialise memory float *radii; radii = (float *) malloc (cell_number * sizeof(float)); // Initialise memory int *order; order = (int *) malloc (cell_number * sizeof(int)); initial_cell_prop(cell_number, observed_radius, cell, outfile10); // FUNCTION: Assign properties to initial cells (position, steady state, etc) printf("Cell Number = %d\n",cell_number); for(i=0; i=20; --j){ // Countdown from cell_number to 2 (largest radii to smallest radii) volume = vsphere(radii[j]); // Volume of a sphere density = j / volume; // Calculate the density if(density > qs_density){ // If the density is greater than the density required for quorum sensing *effective_radius = radii[j]; // Record the radius at which density fails to be high enough for(k=j; k>0; --k){ l = order[k]; if(cell[l].condition == 0){ cell[l].condition = 1; // Quorum sensed } } break; } } } /******************************************************************************************/ /************************************ inner_dynamics **************************************/ /******************************************************************************************/ void inner_dynamics(int cell_number, data *cell, int *number_death, int *number_alive, int *number_qs, FILE *outfile6){ //printf("inner_dynamics\n"); int j; *number_alive = 0; *number_qs = 0; for(j=0; j=0; --j){ // NOTE: cell_number-1 used!!! if(radii[j] < critical_radius){ // When the radius falls below the 'critical_radius' set 'critical_number' to j critical_number = j; break; } } critical_diff = cell_number - critical_number; // Calculate number of cells within critical zone critical_volume = vsphere(radii[cell_number-1]) - vsphere(radii[critical_number]); // // NOTE: cell_number-1 used!! Calculate volume of critical zone critical_density = critical_diff / critical_volume; // Calculate density within critical zone fprintf(outfile10,"cell_number = %d\n",cell_number); fprintf(outfile10,"critical_number = %d\n",critical_number); fprintf(outfile10,"critical_diff = %d\n",critical_diff); fprintf(outfile10,"critical_volume = %f\n",critical_volume); fprintf(outfile10,"density = %f\n",density); fprintf(outfile10,"critical_density = %f\n",critical_density); density_diff = density - critical_density; if(density_diff > 0){ *increase_cell_number = (int)(density_diff * critical_volume); } else{ *increase_cell_number = 0; } fprintf(outfile10,"increase_cell_number = %d\n",*increase_cell_number); } /******************************************************************************************/ /******************************** cell_increase_prop **************************************/ /******************************************************************************************/ void increase_cell_prop(int cell_number, int increase_cell_number, float observed_radius, data *cell){ //printf("increase_cell_prop\n"); int j; for(j=cell_number; j<(cell_number+increase_cell_number); ++j){ float random_radius = (0.9 * observed_radius) + (0.1 * observed_radius * ((float)(rand() - RAND_MAX/2) / (RAND_MAX/2))); // Radial distance - enter them in critical zone float random_theta = ((double)rand() / RAND_MAX) * 180; // Theta angle - random float random_alpha = ((double)rand() / RAND_MAX) * 360; // Alpha angle - random cell[j].x = random_radius * cos(random_alpha) * sin(random_theta); // Convert to cartesian x-coordinate cell[j].y = random_radius * sin(random_alpha) * sin(random_theta); // Convert to cartesian y-coordinate cell[j].z = random_radius * cos(random_theta); // Convert to cartesian z-coordinate cell[j].tumble = 0; // Set tumbles to zero cell[j].condition = 0; // Set condition to zero (alive) cell[j].lysis = 3000; // Analysis } } /******************************************************************************************/ /********************************* density_function ***************************************/ /******************************************************************************************/ void density_function(int i, int cell_number, float observed_radius, float *radii, FILE *outfile2){ //printf("density\n"); int j; int k; int partition; // The number of partitions to 'break' observed_radius float partition_size; // The size of each partition float threshold_radii; partition = 50; // TEMP struct density_prop{ // Define new structure to record density properties int number[partition]; float radii[partition]; float volume[partition]; float density[partition]; }; struct density_prop store; // Declare a structure 'density_prop' called 'store' for(k=0; k=p) return 0; //done allready for (k=1; k=p) break; //Leave loop } return k; //return random number }