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 datatype:
11 type: array
12 items:
13 type: number
14 allowSingular: true
15 - name: temperature
16 default_file:
17 name: ./Input/temperature.txt
18 filetype: table
19 datatype:
20 type: array
21 items:
22 type: number
23 allowSingular: true
24 - name: co2
25 default_file:
26 name: ./Input/co2.txt
27 filetype: table
28 # datatype:
29 # type: array
30 outputs:
31 - name: photosynthesis_rate
32 datatype:
33 type: array
34 items:
35 type: number
36 allowSingular: true
37 default_file:
38 name: ./Output/photosynthesis_rate.txt
39 filetype: table
40 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 datatype:
11 type: array
12 items:
13 type: number
14 allowSingular: true
15 - name: temperature
16 default_file:
17 name: ./Input/temperature.txt
18 filetype: table
19 datatype:
20 type: array
21 items:
22 type: number
23 allowSingular: true
24 - name: co2
25 default_file:
26 name: ./Input/co2.txt
27 filetype: table
28 # datatype:
29 # type: array
30 outputs:
31 - name: photosynthesis_rate
32 datatype:
33 type: array
34 items:
35 type: number
36 allowSingular: true
37 default_file:
38 name: ./Output/photosynthesis_rate.txt
39 filetype: table
40 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 datatype:
11 type: array
12 items:
13 type: number
14 allowSingular: true
15 - name: temperature
16 default_file:
17 name: ./Input/temperature.txt
18 filetype: table
19 datatype:
20 type: array
21 items:
22 type: number
23 allowSingular: true
24 - name: co2
25 default_file:
26 name: ./Input/co2.txt
27 filetype: table
28 # datatype:
29 # type: array
30 outputs:
31 - name: photosynthesis_rate
32 datatype:
33 type: array
34 items:
35 type: number
36 allowSingular: true
37 default_file:
38 name: ./Output/photosynthesis_rate.txt
39 filetype: table
40 field_names: photosynthesis_rate