fakeplant

Four models that can be run in isolation or as an integration. Each model approximates a simplified model of a process governing plant growth. When run in isolation each model receives input from a file and sends output to a file. In the larger integration, the canopy model receives input from three files (initial structure, time steps, and some growth parameters. For each time step received, the canopy model also receives a growth rate from the growth model, computes the new structure. and send the structure to the light model. The light model receives the ambient light level from a file, calculates the intensity for each element of the structure, and sends the output to the photosynthesis model. The photosynthesis model receives temperature and CO2 from files, calculates the photosynthesis rate, and sends the result to the growth model. The growth model calculates the growth rate and sends the output to the canopy model.

Mixed Version

Model Code:

  1#include "YggInterface.hpp"
  2#include <string>
  3#include <iostream>
  4using namespace std;
  5
  6
  7void grow_canopy(double tstep, double *growth_rate, double *layout,
  8		 int npatch, double **x1, double **x2, double **x3) {
  9  int i, j;
 10  for (i = 0; i < npatch; i++) {
 11    for (j = 0; j < 3; j++) {
 12      x1[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x1[j][i];
 13      x2[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x2[j][i];
 14      x3[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x3[j][i];
 15    }
 16  }
 17
 18}
 19
 20		
 21int main(int argc, char *argv[]) {
 22
 23  int i, return_code = 0;
 24  YggInput in_layout("plant_layout");
 25  YggAsciiArrayInput in_struct("init_canopy_structure");
 26  YggInput in_time("time");
 27  YggInput in_growth("growth_rate");
 28  char struct_format[200] = "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n";
 29  YggAsciiArrayOutput out_struct("canopy_structure", struct_format);
 30  double time_prev, time_curr;
 31  time_curr = 0.0;
 32
 33  // Malloc arrays for use
 34  double *layout = (double*)malloc(3*sizeof(double));
 35  double **x1 = (double**)malloc(3*sizeof(double*));
 36  double **x2 = (double**)malloc(3*sizeof(double*));
 37  double **x3 = (double**)malloc(3*sizeof(double*));
 38  for (i = 0; i < 3; i++) {
 39    x1[i] = NULL;
 40    x2[i] = NULL;
 41    x3[i] = NULL;
 42  }
 43
 44  // Receive layout and initial structure
 45  int ret = 0;
 46  int64_t npatch = 0;
 47  ret = in_layout.recv(3, layout, layout + 1, layout + 2);
 48  if (ret < 0) {
 49    printf("canopy: Error receiving layout.\n");
 50    free(layout);
 51    free(x1);
 52    free(x2);
 53    free(x3);
 54    return -1;
 55  }
 56  printf("canopy: layout = %f, %f, %f\n",
 57	 layout[0], layout[1], layout[2]);
 58  ret = in_struct.recvRealloc(10, &npatch, &x1[0], &x1[1], &x1[2],
 59			      &x2[0], &x2[1], &x2[2],
 60			      &x3[0], &x3[1], &x3[2]);
 61  if (ret < 0) {
 62    printf("canopy: Error receiving structure\n");
 63    free(layout);
 64    free(x1);
 65    free(x2);
 66    free(x3);
 67    return -1;
 68  }
 69  printf("canopy: %d patches in initial structure:\n\t\t%f\t%f\t%f\n\t\t%f\t%f\t%f\n\t\t%f\t%f\t%f...\n",
 70	 npatch, x1[0][0], x1[1][0], x1[2][0],
 71	 x2[0][0], x2[1][0], x2[2][0],
 72	 x3[0][0], x3[1][0], x3[2][0]);
 73
 74  // Send canopy to output and get growth rate for it
 75  double *growth_rate = (double*)malloc(npatch*sizeof(double));
 76  ret = out_struct.send(10, npatch,
 77			x1[0], x1[1], x1[2],
 78			x2[0], x2[1], x2[2],
 79			x3[0], x3[1], x3[2]);
 80  if (ret < 0) {
 81    printf("canopy: Error sending initial structure to output.\n");
 82    return_code = -1;
 83  } else {
 84    for (i = 0; i < npatch; i++) {
 85      ret = in_growth.recv(1, growth_rate + i);
 86      if (ret < 0) {
 87	printf("canopy: Failed to get initial growth rate for patch %d.\n", i);
 88	return_code = -1;
 89	break;
 90      }
 91    }
 92  }
 93
 94  // Loop over growth rates calculating new structure
 95  while (ret >= 0) {
 96    // Check for next time
 97    time_prev = time_curr;
 98    ret = in_time.recv(1, &time_curr);
 99    if (ret < 0) {
100      printf("canopy: No more input.\n");
101      break;
102    }
103    // Update structure and send to out
104    grow_canopy(time_curr - time_prev, growth_rate, layout, npatch, x1, x2, x3);
105    for (i = 0; i < npatch; i++) {
106      printf("canopy: patch %d: growth rate = %f --> \t%f\t%f\t%f\n\t\t\t\t\t\t%f\t%f\t%f\n\t\t\t\t\t\t%f\t%f\t%f...\n",
107	     i, growth_rate[i], x1[0][i], x1[1][i], x1[2][i],
108	     x2[0][i], x2[1][i], x2[2][i],
109	     x3[0][i], x3[1][i], x3[2][i]);
110    }
111    ret = out_struct.send(10, npatch,
112			  x1[0], x1[1], x1[2],
113			  x2[0], x2[1], x2[2],
114			  x3[0], x3[1], x3[2]);
115    if (ret < 0) {
116      printf("canopy: Error sending structure output.\n");
117      return_code = -1;
118      break;
119    }
120    // Receive growth rate for each patch
121    for (i = 0; i < npatch; i++) {
122      ret = in_growth.recv(1, growth_rate + i);
123      if (ret < 0) {
124	printf("canopy: Failed to get growth rate for patch %d during time frame %f to %f\n",
125	       i, time_prev, time_curr);
126	return_code = -1;
127	break;
128      }
129    }
130  }
131  
132  for (i = 0; i < 3; i++) {
133    if (x1[i] != NULL) free(x1[i]);
134    if (x2[i] != NULL) free(x2[i]);
135    if (x3[i] != NULL) free(x3[i]);
136  }
137  free(layout);
138  free(growth_rate);
139  free(x1);
140  free(x2);
141  free(x3);
142  return return_code;
143}
 1#include <stdio.h>
 2#include <stdlib.h>
 3#include <math.h>
 4#include "YggInterface.h"
 5
 6
 7double calc_light_intensity(double ambient_light, 
 8			    double x1, double y1, double z1,
 9			    double x2, double y2, double z2,
10			    double x3, double y3, double z3) {
11  double a = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
12  double b = sqrt(pow(x3 - x2, 2) + pow(y3 - y2, 2));
13  double c = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
14  double s = (a + b + c)/2.0;
15  double A = sqrt(s*(s - a)*(s - b)*(s - c));
16  return ambient_light * A * (10.0 - (z1 + z2 + z3)/3.0)/10.0;
17}
18
19
20int main(int argc,char *argv[]) {
21  int i, ret, return_code = 0;
22
23  yggInput_t AmbInput = yggAsciiTableInput("ambient_light");
24  yggInput_t StructInput = yggAsciiArrayInput("canopy_structure");
25  yggOutput_t LightOutput = yggAsciiTableOutput("light_intensity", "%lf\n");
26
27  // Receive Ambient light
28  double ambient_light;
29  ret = yggRecv(AmbInput, &ambient_light);
30  if (ret < 0) {
31    printf("light: Error receiving ambient light.\n");
32    return -1;
33  }
34  printf("light: ambient light = %f\n", ambient_light);
35
36  // Malloc arrays for use
37  double **x1 = (double**)malloc(3*sizeof(double*));
38  double **x2 = (double**)malloc(3*sizeof(double*));
39  double **x3 = (double**)malloc(3*sizeof(double*));
40  for (i = 0; i < 3; i++) {
41    x1[i] = NULL;
42    x2[i] = NULL;
43    x3[i] = NULL;
44  }
45
46  // Loop over canopy structures
47  size_t npatch = 0;
48  double light_intensity = 0.0;
49  ret = 0;
50  while (1) {
51    ret = yggRecvRealloc(StructInput, &npatch,
52			 &x1[0], &x1[1], &x1[2],
53			 &x2[0], &x2[1], &x2[2],
54			 &x3[0], &x3[1], &x3[2]);
55    if (ret < 0) {
56      printf("light: End of input.\n");
57      break;
58    }
59    for (i = 0; i < (int)npatch; i++) {
60      light_intensity = calc_light_intensity(ambient_light,
61					     x1[0][i], x1[1][i], x1[2][i],
62					     x2[0][i], x2[1][i], x2[2][i],
63					     x3[0][i], x3[1][i], x3[2][i]);
64      printf("light: structure = \t%f\t%f\t%f --> light_intensity = %f\n\t\t\t%f\t%f\t%f\n\t\t\t%f\t%f\t%f\n",
65	     x1[0][i], x1[1][i], x1[2][i], light_intensity,
66	     x2[0][i], x2[1][i], x2[2][i],
67	     x3[0][i], x3[1][i], x3[2][i]);
68      ret = yggSend(LightOutput, light_intensity);
69      if (ret < 0) {
70	printf("light: Error sending light intensity output.\n");
71	return_code = -1;
72	break;
73      }
74    }
75    if (ret < 0)
76      break;
77  }
78
79  for (i = 0; i < 3; i++) {
80    if (x1[i] != NULL) free(x1[i]);
81    if (x2[i] != NULL) free(x2[i]);
82    if (x3[i] != NULL) free(x3[i]);
83  }
84  free(x1);
85  free(x2);
86  free(x3);
87  return return_code;
88}
 1from yggdrasil.interface import YggInput, YggOutput
 2
 3
 4def calc_photosynthesis_rate(T, CO2, light):
 5    r"""Calculate the rate of photosynthesis from environment properties.
 6
 7    Args:
 8        T (float): Temperature.
 9        CO2 (float): CO2 concentration.
10        light (float): Light intensity.
11
12    Returns:
13        float: Photosynthesis rate.
14
15    """
16    return light * CO2 / T
17
18
19if __name__ == '__main__':
20    in_temp = YggInput('temperature')
21    in_co2 = YggInput('co2')
22    in_light = YggInput('light_intensity')
23    out_photo = YggOutput('photosynthesis_rate', '%lf\n')
24    
25    # Receive temperature & CO2 concentration of environment
26    flag, msg = in_temp.recv()
27    if not flag:
28        raise RuntimeError("photosynthesis: Failed to receive temperature.")
29    T = msg[0]
30    print("photosynthesis: T = %f" % T)
31    flag, msg = in_co2.recv()
32    if not flag:
33        raise RuntimeError("photosynthesis: Failed to receive CO2 concentration.")
34    CO2 = msg[0]
35    print("photosynthesis: CO2 = %f" % CO2)
36
37    # Loop over light intensities
38    while True:
39        flag, msg = in_light.recv()
40        if not flag:
41            print("photosynthesis: No more input.")
42            break
43        LI = msg[0]
44        PR = calc_photosynthesis_rate(T, CO2, LI)
45        print("photosynthesis: light intensity = %f " % LI
46              + "--> photosynthesis rate = %f" % PR)
47        flag = out_photo.send(PR)
48        if not flag:
49            raise RuntimeError("photosynthesis: Failed to send output.")
 1input = YggInterface('YggInput', 'photosynthesis_rate');
 2output = YggInterface('YggOutput', 'growth_rate', '%f\n');
 3
 4while (1)
 5  [flag, prate] = input.recv();
 6  if (~flag)
 7    disp('growth: No more input.');
 8    break;
 9  end;
10  grate = 0.5 * prate{1};
11  fprintf('growth: photosynthesis rate = %f ---> growth rate = %f\n', ...
12          prate{1}, grate);
13  flag = output.send(grate);
14  if (~flag)
15    error('growth: Error sending growth rate.');
16  end;
17end;

Model YAML:

 1model:
 2  name: CanopyModel
 3  language: c++
 4  args: ./src/canopy.cpp
 5  inputs:
 6    - plant_layout
 7    - init_canopy_structure
 8    - growth_rate
 9    - time
10  outputs:
11    - canopy_structure
 1model:
 2  name: LightModel
 3  language: c
 4  args:
 5    - ./src/light.c
 6    - -lm
 7  inputs:
 8    - ambient_light
 9    - canopy_structure
10  outputs:
11    - light_intensity
 1model:
 2  name: PhotosynthesisModel
 3  language: python
 4  args: ./src/photosynthesis.py
 5  inputs:
 6    - name: light_intensity
 7      default_file:
 8        name: ./Input/light_intensity.txt
 9        filetype: table
10    - name: temperature
11      default_file:
12        name: ./Input/temperature.txt
13        filetype: table
14    - name: co2
15      default_file:
16        name: ./Input/co2.txt
17        filetype: table
18  outputs:
19    - name: photosynthesis_rate
20      default_file:
21        name: ./Output/photosynthesis_rate.txt
22        filetype: table
23        field_names: photosynthesis_rate
 1connections:
 2  - input: growth_rate
 3    output: growth_rate
 4    field_names: growth_rate
 5  - input: photosynthesis_rate
 6    output: photosynthesis_rate
 7    field_names: photosynthesis_rate
 8  - input: canopy_structure
 9    output: canopy_structure
10    field_names: x1,y1,z1,x2,y2,z2,x3,y3,z3
11  - input: light_intensity
12    output: light_intensity
13    field_names: light_intensity
14  # Canopy file input
15  - input: ./Input/plant_layout.txt
16    output: plant_layout
17    filetype: table
18  - input: ./Input/canopy_structure.txt
19    output: init_canopy_structure
20    filetype: table
21    as_array: True
22  - input: ./Input/time.txt
23    output: time
24    filetype: table
25  # Light file input
26  - input: ./Input/ambient_light.txt
27    output: ambient_light
28    filetype: table
29  # Photosynthesis file input
30  - input: ./Input/temperature.txt
31    output: temperature
32    filetype: table
33  - input: ./Input/co2.txt
34    output: co2
35    filetype: table
1model:
2  name: GrowthModel
3  language: matlab
4  args: ./src/growth.m
5  inputs:
6    - photosynthesis_rate
7  outputs:
8    - growth_rate

Mixed w/o Matlab Version

Model Code:

  1#include "YggInterface.hpp"
  2#include <string>
  3#include <iostream>
  4using namespace std;
  5
  6
  7void grow_canopy(double tstep, double *growth_rate, double *layout,
  8		 int npatch, double **x1, double **x2, double **x3) {
  9  int i, j;
 10  for (i = 0; i < npatch; i++) {
 11    for (j = 0; j < 3; j++) {
 12      x1[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x1[j][i];
 13      x2[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x2[j][i];
 14      x3[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x3[j][i];
 15    }
 16  }
 17
 18}
 19
 20		
 21int main(int argc, char *argv[]) {
 22
 23  int i, return_code = 0;
 24  YggInput in_layout("plant_layout");
 25  YggAsciiArrayInput in_struct("init_canopy_structure");
 26  YggInput in_time("time");
 27  YggInput in_growth("growth_rate");
 28  char struct_format[200] = "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n";
 29  YggAsciiArrayOutput out_struct("canopy_structure", struct_format);
 30  double time_prev, time_curr;
 31  time_curr = 0.0;
 32
 33  // Malloc arrays for use
 34  double *layout = (double*)malloc(3*sizeof(double));
 35  double **x1 = (double**)malloc(3*sizeof(double*));
 36  double **x2 = (double**)malloc(3*sizeof(double*));
 37  double **x3 = (double**)malloc(3*sizeof(double*));
 38  for (i = 0; i < 3; i++) {
 39    x1[i] = NULL;
 40    x2[i] = NULL;
 41    x3[i] = NULL;
 42  }
 43
 44  // Receive layout and initial structure
 45  int ret = 0;
 46  int64_t npatch = 0;
 47  ret = in_layout.recv(3, layout, layout + 1, layout + 2);
 48  if (ret < 0) {
 49    printf("canopy: Error receiving layout.\n");
 50    free(layout);
 51    free(x1);
 52    free(x2);
 53    free(x3);
 54    return -1;
 55  }
 56  printf("canopy: layout = %f, %f, %f\n",
 57	 layout[0], layout[1], layout[2]);
 58  ret = in_struct.recvRealloc(10, &npatch, &x1[0], &x1[1], &x1[2],
 59			      &x2[0], &x2[1], &x2[2],
 60			      &x3[0], &x3[1], &x3[2]);
 61  if (ret < 0) {
 62    printf("canopy: Error receiving structure\n");
 63    free(layout);
 64    free(x1);
 65    free(x2);
 66    free(x3);
 67    return -1;
 68  }
 69  printf("canopy: %d patches in initial structure:\n\t\t%f\t%f\t%f\n\t\t%f\t%f\t%f\n\t\t%f\t%f\t%f...\n",
 70	 npatch, x1[0][0], x1[1][0], x1[2][0],
 71	 x2[0][0], x2[1][0], x2[2][0],
 72	 x3[0][0], x3[1][0], x3[2][0]);
 73
 74  // Send canopy to output and get growth rate for it
 75  double *growth_rate = (double*)malloc(npatch*sizeof(double));
 76  ret = out_struct.send(10, npatch,
 77			x1[0], x1[1], x1[2],
 78			x2[0], x2[1], x2[2],
 79			x3[0], x3[1], x3[2]);
 80  if (ret < 0) {
 81    printf("canopy: Error sending initial structure to output.\n");
 82    return_code = -1;
 83  } else {
 84    for (i = 0; i < npatch; i++) {
 85      ret = in_growth.recv(1, growth_rate + i);
 86      if (ret < 0) {
 87	printf("canopy: Failed to get initial growth rate for patch %d.\n", i);
 88	return_code = -1;
 89	break;
 90      }
 91    }
 92  }
 93
 94  // Loop over growth rates calculating new structure
 95  while (ret >= 0) {
 96    // Check for next time
 97    time_prev = time_curr;
 98    ret = in_time.recv(1, &time_curr);
 99    if (ret < 0) {
100      printf("canopy: No more input.\n");
101      break;
102    }
103    // Update structure and send to out
104    grow_canopy(time_curr - time_prev, growth_rate, layout, npatch, x1, x2, x3);
105    for (i = 0; i < npatch; i++) {
106      printf("canopy: patch %d: growth rate = %f --> \t%f\t%f\t%f\n\t\t\t\t\t\t%f\t%f\t%f\n\t\t\t\t\t\t%f\t%f\t%f...\n",
107	     i, growth_rate[i], x1[0][i], x1[1][i], x1[2][i],
108	     x2[0][i], x2[1][i], x2[2][i],
109	     x3[0][i], x3[1][i], x3[2][i]);
110    }
111    ret = out_struct.send(10, npatch,
112			  x1[0], x1[1], x1[2],
113			  x2[0], x2[1], x2[2],
114			  x3[0], x3[1], x3[2]);
115    if (ret < 0) {
116      printf("canopy: Error sending structure output.\n");
117      return_code = -1;
118      break;
119    }
120    // Receive growth rate for each patch
121    for (i = 0; i < npatch; i++) {
122      ret = in_growth.recv(1, growth_rate + i);
123      if (ret < 0) {
124	printf("canopy: Failed to get growth rate for patch %d during time frame %f to %f\n",
125	       i, time_prev, time_curr);
126	return_code = -1;
127	break;
128      }
129    }
130  }
131  
132  for (i = 0; i < 3; i++) {
133    if (x1[i] != NULL) free(x1[i]);
134    if (x2[i] != NULL) free(x2[i]);
135    if (x3[i] != NULL) free(x3[i]);
136  }
137  free(layout);
138  free(growth_rate);
139  free(x1);
140  free(x2);
141  free(x3);
142  return return_code;
143}
 1#include <stdio.h>
 2#include <stdlib.h>
 3#include <math.h>
 4#include "YggInterface.h"
 5
 6
 7double calc_light_intensity(double ambient_light, 
 8			    double x1, double y1, double z1,
 9			    double x2, double y2, double z2,
10			    double x3, double y3, double z3) {
11  double a = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
12  double b = sqrt(pow(x3 - x2, 2) + pow(y3 - y2, 2));
13  double c = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
14  double s = (a + b + c)/2.0;
15  double A = sqrt(s*(s - a)*(s - b)*(s - c));
16  return ambient_light * A * (10.0 - (z1 + z2 + z3)/3.0)/10.0;
17}
18
19
20int main(int argc,char *argv[]) {
21  int i, ret, return_code = 0;
22
23  yggInput_t AmbInput = yggAsciiTableInput("ambient_light");
24  yggInput_t StructInput = yggAsciiArrayInput("canopy_structure");
25  yggOutput_t LightOutput = yggAsciiTableOutput("light_intensity", "%lf\n");
26
27  // Receive Ambient light
28  double ambient_light;
29  ret = yggRecv(AmbInput, &ambient_light);
30  if (ret < 0) {
31    printf("light: Error receiving ambient light.\n");
32    return -1;
33  }
34  printf("light: ambient light = %f\n", ambient_light);
35
36  // Malloc arrays for use
37  double **x1 = (double**)malloc(3*sizeof(double*));
38  double **x2 = (double**)malloc(3*sizeof(double*));
39  double **x3 = (double**)malloc(3*sizeof(double*));
40  for (i = 0; i < 3; i++) {
41    x1[i] = NULL;
42    x2[i] = NULL;
43    x3[i] = NULL;
44  }
45
46  // Loop over canopy structures
47  size_t npatch = 0;
48  double light_intensity = 0.0;
49  ret = 0;
50  while (1) {
51    ret = yggRecvRealloc(StructInput, &npatch,
52			 &x1[0], &x1[1], &x1[2],
53			 &x2[0], &x2[1], &x2[2],
54			 &x3[0], &x3[1], &x3[2]);
55    if (ret < 0) {
56      printf("light: End of input.\n");
57      break;
58    }
59    for (i = 0; i < (int)npatch; i++) {
60      light_intensity = calc_light_intensity(ambient_light,
61					     x1[0][i], x1[1][i], x1[2][i],
62					     x2[0][i], x2[1][i], x2[2][i],
63					     x3[0][i], x3[1][i], x3[2][i]);
64      printf("light: structure = \t%f\t%f\t%f --> light_intensity = %f\n\t\t\t%f\t%f\t%f\n\t\t\t%f\t%f\t%f\n",
65	     x1[0][i], x1[1][i], x1[2][i], light_intensity,
66	     x2[0][i], x2[1][i], x2[2][i],
67	     x3[0][i], x3[1][i], x3[2][i]);
68      ret = yggSend(LightOutput, light_intensity);
69      if (ret < 0) {
70	printf("light: Error sending light intensity output.\n");
71	return_code = -1;
72	break;
73      }
74    }
75    if (ret < 0)
76      break;
77  }
78
79  for (i = 0; i < 3; i++) {
80    if (x1[i] != NULL) free(x1[i]);
81    if (x2[i] != NULL) free(x2[i]);
82    if (x3[i] != NULL) free(x3[i]);
83  }
84  free(x1);
85  free(x2);
86  free(x3);
87  return return_code;
88}
 1from yggdrasil.interface import YggInput, YggOutput
 2
 3
 4def calc_photosynthesis_rate(T, CO2, light):
 5    r"""Calculate the rate of photosynthesis from environment properties.
 6
 7    Args:
 8        T (float): Temperature.
 9        CO2 (float): CO2 concentration.
10        light (float): Light intensity.
11
12    Returns:
13        float: Photosynthesis rate.
14
15    """
16    return light * CO2 / T
17
18
19if __name__ == '__main__':
20    in_temp = YggInput('temperature')
21    in_co2 = YggInput('co2')
22    in_light = YggInput('light_intensity')
23    out_photo = YggOutput('photosynthesis_rate', '%lf\n')
24    
25    # Receive temperature & CO2 concentration of environment
26    flag, msg = in_temp.recv()
27    if not flag:
28        raise RuntimeError("photosynthesis: Failed to receive temperature.")
29    T = msg[0]
30    print("photosynthesis: T = %f" % T)
31    flag, msg = in_co2.recv()
32    if not flag:
33        raise RuntimeError("photosynthesis: Failed to receive CO2 concentration.")
34    CO2 = msg[0]
35    print("photosynthesis: CO2 = %f" % CO2)
36
37    # Loop over light intensities
38    while True:
39        flag, msg = in_light.recv()
40        if not flag:
41            print("photosynthesis: No more input.")
42            break
43        LI = msg[0]
44        PR = calc_photosynthesis_rate(T, CO2, LI)
45        print("photosynthesis: light intensity = %f " % LI
46              + "--> photosynthesis rate = %f" % PR)
47        flag = out_photo.send(PR)
48        if not flag:
49            raise RuntimeError("photosynthesis: Failed to send output.")
 1from yggdrasil.interface import YggInput, YggOutput
 2
 3
 4def calculate_growth(photosynthesis_rate):
 5    r"""Calculate the plant growth rate from the photosynthesis rate.
 6
 7    Args:
 8        photosynthesis_rate (float): Rate of photosynthesis.
 9
10    Returns:
11        float: Growth rate.
12
13    """
14    return 0.5 * photosynthesis_rate
15
16
17if __name__ == '__main__':
18    input = YggInput('photosynthesis_rate')
19    output = YggOutput('growth_rate', '%f\n')
20    
21    while True:
22        flag, prate = input.recv()
23        if not flag:
24            print('growth: No more input.')
25            break
26        grate = calculate_growth(*prate)
27        print('growth: photosynthesis rate = %f ---> growth rate = %f' % (
28            prate[0], grate))
29        flag = output.send(grate)
30        if not flag:
31            raise RuntimeError('growth: Error sending growth rate.')

Model YAML:

 1model:
 2  name: CanopyModel
 3  language: c++
 4  args: ./src/canopy.cpp
 5  inputs:
 6    - plant_layout
 7    - init_canopy_structure
 8    - growth_rate
 9    - time
10  outputs:
11    - canopy_structure
 1model:
 2  name: LightModel
 3  language: c
 4  args:
 5    - ./src/light.c
 6    - -lm
 7  inputs:
 8    - ambient_light
 9    - canopy_structure
10  outputs:
11    - light_intensity
 1model:
 2  name: PhotosynthesisModel
 3  language: python
 4  args: ./src/photosynthesis.py
 5  inputs:
 6    - name: light_intensity
 7      default_file:
 8        name: ./Input/light_intensity.txt
 9        filetype: table
10    - name: temperature
11      default_file:
12        name: ./Input/temperature.txt
13        filetype: table
14    - name: co2
15      default_file:
16        name: ./Input/co2.txt
17        filetype: table
18  outputs:
19    - name: photosynthesis_rate
20      default_file:
21        name: ./Output/photosynthesis_rate.txt
22        filetype: table
23        field_names: photosynthesis_rate
 1connections:
 2  - input: growth_rate
 3    output: growth_rate
 4    field_names: growth_rate
 5  - input: photosynthesis_rate
 6    output: photosynthesis_rate
 7    field_names: photosynthesis_rate
 8  - input: canopy_structure
 9    output: canopy_structure
10    field_names: x1,y1,z1,x2,y2,z2,x3,y3,z3
11  - input: light_intensity
12    output: light_intensity
13    field_names: light_intensity
14  # Canopy file input
15  - input: ./Input/plant_layout.txt
16    output: plant_layout
17    filetype: table
18  - input: ./Input/canopy_structure.txt
19    output: init_canopy_structure
20    filetype: table
21    as_array: True
22  - input: ./Input/time.txt
23    output: time
24    filetype: table
25  # Light file input
26  - input: ./Input/ambient_light.txt
27    output: ambient_light
28    filetype: table
29  # Photosynthesis file input
30  - input: ./Input/temperature.txt
31    output: temperature
32    filetype: table
33  - input: ./Input/co2.txt
34    output: co2
35    filetype: table
1model:
2  name: GrowthModel
3  language: python
4  args: ./src/growth.py
5  inputs:
6    - photosynthesis_rate
7  outputs:
8    - growth_rate

C Version

Model Code:

 1#include <stdio.h>
 2#include <stdlib.h>
 3#include <math.h>
 4#include "YggInterface.h"
 5
 6
 7double calc_light_intensity(double ambient_light, 
 8			    double x1, double y1, double z1,
 9			    double x2, double y2, double z2,
10			    double x3, double y3, double z3) {
11  double a = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
12  double b = sqrt(pow(x3 - x2, 2) + pow(y3 - y2, 2));
13  double c = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
14  double s = (a + b + c)/2.0;
15  double A = sqrt(s*(s - a)*(s - b)*(s - c));
16  return ambient_light * A * (10.0 - (z1 + z2 + z3)/3.0)/10.0;
17}
18
19
20int main(int argc,char *argv[]) {
21  int i, ret, return_code = 0;
22
23  yggInput_t AmbInput = yggAsciiTableInput("ambient_light");
24  yggInput_t StructInput = yggAsciiArrayInput("canopy_structure");
25  yggOutput_t LightOutput = yggAsciiTableOutput("light_intensity", "%lf\n");
26
27  // Receive Ambient light
28  double ambient_light;
29  ret = yggRecv(AmbInput, &ambient_light);
30  if (ret < 0) {
31    printf("light: Error receiving ambient light.\n");
32    return -1;
33  }
34  printf("light: ambient light = %f\n", ambient_light);
35
36  // Malloc arrays for use
37  double **x1 = (double**)malloc(3*sizeof(double*));
38  double **x2 = (double**)malloc(3*sizeof(double*));
39  double **x3 = (double**)malloc(3*sizeof(double*));
40  for (i = 0; i < 3; i++) {
41    x1[i] = NULL;
42    x2[i] = NULL;
43    x3[i] = NULL;
44  }
45
46  // Loop over canopy structures
47  size_t npatch = 0;
48  double light_intensity = 0.0;
49  ret = 0;
50  while (1) {
51    ret = yggRecvRealloc(StructInput, &npatch,
52			 &x1[0], &x1[1], &x1[2],
53			 &x2[0], &x2[1], &x2[2],
54			 &x3[0], &x3[1], &x3[2]);
55    if (ret < 0) {
56      printf("light: End of input.\n");
57      break;
58    }
59    for (i = 0; i < (int)npatch; i++) {
60      light_intensity = calc_light_intensity(ambient_light,
61					     x1[0][i], x1[1][i], x1[2][i],
62					     x2[0][i], x2[1][i], x2[2][i],
63					     x3[0][i], x3[1][i], x3[2][i]);
64      printf("light: structure = \t%f\t%f\t%f --> light_intensity = %f\n\t\t\t%f\t%f\t%f\n\t\t\t%f\t%f\t%f\n",
65	     x1[0][i], x1[1][i], x1[2][i], light_intensity,
66	     x2[0][i], x2[1][i], x2[2][i],
67	     x3[0][i], x3[1][i], x3[2][i]);
68      ret = yggSend(LightOutput, light_intensity);
69      if (ret < 0) {
70	printf("light: Error sending light intensity output.\n");
71	return_code = -1;
72	break;
73      }
74    }
75    if (ret < 0)
76      break;
77  }
78
79  for (i = 0; i < 3; i++) {
80    if (x1[i] != NULL) free(x1[i]);
81    if (x2[i] != NULL) free(x2[i]);
82    if (x3[i] != NULL) free(x3[i]);
83  }
84  free(x1);
85  free(x2);
86  free(x3);
87  return return_code;
88}

Model YAML:

 1model:
 2  name: LightModel
 3  language: c
 4  args:
 5    - ./src/light.c
 6    - -lm
 7  inputs:
 8    - ambient_light
 9    - canopy_structure
10  outputs:
11    - light_intensity
 1connections:
 2  - input: ./Input/ambient_light.txt
 3    output: ambient_light
 4    filetype: table
 5  - input: ./Input/canopy_structure.txt
 6    output: canopy_structure
 7    filetype: table
 8    as_array: True
 9  - input: light_intensity
10    output: ./Output/light_intensity.txt
11    filetype: table
12    field_names: light_intensity

C++ Version

Model Code:

  1#include "YggInterface.hpp"
  2#include <string>
  3#include <iostream>
  4using namespace std;
  5
  6
  7void grow_canopy(double tstep, double *growth_rate, double *layout,
  8		 int npatch, double **x1, double **x2, double **x3) {
  9  int i, j;
 10  for (i = 0; i < npatch; i++) {
 11    for (j = 0; j < 3; j++) {
 12      x1[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x1[j][i];
 13      x2[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x2[j][i];
 14      x3[j][i] = (1.0 + growth_rate[i] * tstep * layout[j]) * x3[j][i];
 15    }
 16  }
 17
 18}
 19
 20		
 21int main(int argc, char *argv[]) {
 22
 23  int i, return_code = 0;
 24  YggInput in_layout("plant_layout");
 25  YggAsciiArrayInput in_struct("init_canopy_structure");
 26  YggInput in_time("time");
 27  YggInput in_growth("growth_rate");
 28  char struct_format[200] = "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n";
 29  YggAsciiArrayOutput out_struct("canopy_structure", struct_format);
 30  double time_prev, time_curr;
 31  time_curr = 0.0;
 32
 33  // Malloc arrays for use
 34  double *layout = (double*)malloc(3*sizeof(double));
 35  double **x1 = (double**)malloc(3*sizeof(double*));
 36  double **x2 = (double**)malloc(3*sizeof(double*));
 37  double **x3 = (double**)malloc(3*sizeof(double*));
 38  for (i = 0; i < 3; i++) {
 39    x1[i] = NULL;
 40    x2[i] = NULL;
 41    x3[i] = NULL;
 42  }
 43
 44  // Receive layout and initial structure
 45  int ret = 0;
 46  int64_t npatch = 0;
 47  ret = in_layout.recv(3, layout, layout + 1, layout + 2);
 48  if (ret < 0) {
 49    printf("canopy: Error receiving layout.\n");
 50    free(layout);
 51    free(x1);
 52    free(x2);
 53    free(x3);
 54    return -1;
 55  }
 56  printf("canopy: layout = %f, %f, %f\n",
 57	 layout[0], layout[1], layout[2]);
 58  ret = in_struct.recvRealloc(10, &npatch, &x1[0], &x1[1], &x1[2],
 59			      &x2[0], &x2[1], &x2[2],
 60			      &x3[0], &x3[1], &x3[2]);
 61  if (ret < 0) {
 62    printf("canopy: Error receiving structure\n");
 63    free(layout);
 64    free(x1);
 65    free(x2);
 66    free(x3);
 67    return -1;
 68  }
 69  printf("canopy: %d patches in initial structure:\n\t\t%f\t%f\t%f\n\t\t%f\t%f\t%f\n\t\t%f\t%f\t%f...\n",
 70	 npatch, x1[0][0], x1[1][0], x1[2][0],
 71	 x2[0][0], x2[1][0], x2[2][0],
 72	 x3[0][0], x3[1][0], x3[2][0]);
 73
 74  // Send canopy to output and get growth rate for it
 75  double *growth_rate = (double*)malloc(npatch*sizeof(double));
 76  ret = out_struct.send(10, npatch,
 77			x1[0], x1[1], x1[2],
 78			x2[0], x2[1], x2[2],
 79			x3[0], x3[1], x3[2]);
 80  if (ret < 0) {
 81    printf("canopy: Error sending initial structure to output.\n");
 82    return_code = -1;
 83  } else {
 84    for (i = 0; i < npatch; i++) {
 85      ret = in_growth.recv(1, growth_rate + i);
 86      if (ret < 0) {
 87	printf("canopy: Failed to get initial growth rate for patch %d.\n", i);
 88	return_code = -1;
 89	break;
 90      }
 91    }
 92  }
 93
 94  // Loop over growth rates calculating new structure
 95  while (ret >= 0) {
 96    // Check for next time
 97    time_prev = time_curr;
 98    ret = in_time.recv(1, &time_curr);
 99    if (ret < 0) {
100      printf("canopy: No more input.\n");
101      break;
102    }
103    // Update structure and send to out
104    grow_canopy(time_curr - time_prev, growth_rate, layout, npatch, x1, x2, x3);
105    for (i = 0; i < npatch; i++) {
106      printf("canopy: patch %d: growth rate = %f --> \t%f\t%f\t%f\n\t\t\t\t\t\t%f\t%f\t%f\n\t\t\t\t\t\t%f\t%f\t%f...\n",
107	     i, growth_rate[i], x1[0][i], x1[1][i], x1[2][i],
108	     x2[0][i], x2[1][i], x2[2][i],
109	     x3[0][i], x3[1][i], x3[2][i]);
110    }
111    ret = out_struct.send(10, npatch,
112			  x1[0], x1[1], x1[2],
113			  x2[0], x2[1], x2[2],
114			  x3[0], x3[1], x3[2]);
115    if (ret < 0) {
116      printf("canopy: Error sending structure output.\n");
117      return_code = -1;
118      break;
119    }
120    // Receive growth rate for each patch
121    for (i = 0; i < npatch; i++) {
122      ret = in_growth.recv(1, growth_rate + i);
123      if (ret < 0) {
124	printf("canopy: Failed to get growth rate for patch %d during time frame %f to %f\n",
125	       i, time_prev, time_curr);
126	return_code = -1;
127	break;
128      }
129    }
130  }
131  
132  for (i = 0; i < 3; i++) {
133    if (x1[i] != NULL) free(x1[i]);
134    if (x2[i] != NULL) free(x2[i]);
135    if (x3[i] != NULL) free(x3[i]);
136  }
137  free(layout);
138  free(growth_rate);
139  free(x1);
140  free(x2);
141  free(x3);
142  return return_code;
143}

Model YAML:

 1model:
 2  name: CanopyModel
 3  language: c++
 4  args: ./src/canopy.cpp
 5  inputs:
 6    - plant_layout
 7    - init_canopy_structure
 8    - growth_rate
 9    - time
10  outputs:
11    - canopy_structure
 1connections:
 2  - input: ./Input/plant_layout.txt
 3    output: plant_layout
 4    filetype: table
 5  - input: ./Input/canopy_structure.txt
 6    output: init_canopy_structure
 7    filetype: table
 8    as_array: True
 9  - input: ./Input/time.txt
10    output: time
11    filetype: table
12  - input: ./Input/growth_rate.txt
13    output: growth_rate
14    filetype: table
15  - input: canopy_structure
16    output: ./Output/canopy_structure.txt
17    filetype: table
18    as_array: True
19    field_names: x1,y1,z1,x2,y2,z2,x3,y3,z3

Matlab Version

Model Code:

 1input = YggInterface('YggInput', 'photosynthesis_rate');
 2output = YggInterface('YggOutput', 'growth_rate', '%f\n');
 3
 4while (1)
 5  [flag, prate] = input.recv();
 6  if (~flag)
 7    disp('growth: No more input.');
 8    break;
 9  end;
10  grate = 0.5 * prate{1};
11  fprintf('growth: photosynthesis rate = %f ---> growth rate = %f\n', ...
12          prate{1}, grate);
13  flag = output.send(grate);
14  if (~flag)
15    error('growth: Error sending growth rate.');
16  end;
17end;

Model YAML:

1model:
2  name: GrowthModel
3  language: matlab
4  args: ./src/growth.m
5  inputs:
6    - photosynthesis_rate
7  outputs:
8    - growth_rate
1connections:
2  - input: ./Input/photosynthesis_rate.txt
3    output: photosynthesis_rate
4    filetype: table
5  - input: growth_rate
6    output: ./Output/growth_rate.txt
7    filetype: table
8    field_names: growth_rate

Python Version

Model Code:

 1from yggdrasil.interface import YggInput, YggOutput
 2
 3
 4def calc_photosynthesis_rate(T, CO2, light):
 5    r"""Calculate the rate of photosynthesis from environment properties.
 6
 7    Args:
 8        T (float): Temperature.
 9        CO2 (float): CO2 concentration.
10        light (float): Light intensity.
11
12    Returns:
13        float: Photosynthesis rate.
14
15    """
16    return light * CO2 / T
17
18
19if __name__ == '__main__':
20    in_temp = YggInput('temperature')
21    in_co2 = YggInput('co2')
22    in_light = YggInput('light_intensity')
23    out_photo = YggOutput('photosynthesis_rate', '%lf\n')
24    
25    # Receive temperature & CO2 concentration of environment
26    flag, msg = in_temp.recv()
27    if not flag:
28        raise RuntimeError("photosynthesis: Failed to receive temperature.")
29    T = msg[0]
30    print("photosynthesis: T = %f" % T)
31    flag, msg = in_co2.recv()
32    if not flag:
33        raise RuntimeError("photosynthesis: Failed to receive CO2 concentration.")
34    CO2 = msg[0]
35    print("photosynthesis: CO2 = %f" % CO2)
36
37    # Loop over light intensities
38    while True:
39        flag, msg = in_light.recv()
40        if not flag:
41            print("photosynthesis: No more input.")
42            break
43        LI = msg[0]
44        PR = calc_photosynthesis_rate(T, CO2, LI)
45        print("photosynthesis: light intensity = %f " % LI
46              + "--> photosynthesis rate = %f" % PR)
47        flag = out_photo.send(PR)
48        if not flag:
49            raise RuntimeError("photosynthesis: Failed to send output.")

Model YAML:

 1model:
 2  name: PhotosynthesisModel
 3  language: python
 4  args: ./src/photosynthesis.py
 5  inputs:
 6    - name: light_intensity
 7      default_file:
 8        name: ./Input/light_intensity.txt
 9        filetype: table
10    - name: temperature
11      default_file:
12        name: ./Input/temperature.txt
13        filetype: table
14    - name: co2
15      default_file:
16        name: ./Input/co2.txt
17        filetype: table
18  outputs:
19    - name: photosynthesis_rate
20      default_file:
21        name: ./Output/photosynthesis_rate.txt
22        filetype: table
23        field_names: photosynthesis_rate