NASA Logo
Ocean Color Science Software

ocssw V2022
get_Cpicophyt.c
Go to the documentation of this file.
1 /*
2  * get_Cpicophyt.c
3  *
4  *This algorithm calculates cell abundances of Prochlorococcus, Synechococcus, and autotrophic picoeukaryotes in surface waters using principal
5  *component analysis (PCA) of hyperspectral and multispectral Rrs.
6  *
7  *
8  *Reference:
9  *Priscila Kienteca Lange, P. Jeremy Werdell, Zachary K. Erickson, Giorgio Dall’Olmo, Robert J. W. Brewin, Mikhail V. Zubkov,
10  *Glen A. Tarran, Heather A. Bouman, Wayne H. Slade, Susanne E. Craig, Nicole J. Poulton, Astrid Bracher, Michael W. Lomas,
11  *and Ivona Cetinić, "Radiometric approach for the detection of picophytoplankton assemblages across oceanic fronts," Opt. Express 28, 25682-25705 (2020)
12  *
13  * Created on: Sep 29, 2023
14  * Author: Minwei Zhang
15  */
16 
17 #include "l12_proto.h"
18 #include <hdf5.h>
19 #include <jansson.h>
20 
21 void rrs_standardize(float *rrs,int nwave)
22 {
23  int i;
24  float mean=0., std=0.;
25 
26  for(i=0;i<nwave;i++)
27  mean+=rrs[i];
28  mean/=nwave;
29 
30  for(i=0;i<nwave;i++)
31  std+=pow(rrs[i]-mean,2);
32  std=sqrt(std/(nwave-1));
33 
34  for(i=0;i<nwave;i++)
35  rrs[i]=(rrs[i]-mean)/std;
36 }
37 
38 void get_Cpicophyt(l2str *l2rec, l2prodstr *p, float *cell_abundance)
39 {
40  int32_t i,j,ip,ipb;
41  static int firstcall=1;
42  static int nbands, npix;
43  static float32 *pca_table;
44  static double *pro_coef, *syn_coef, *apeuk_coef;
45  static int nwave_pca, npc,npc_used;
46  static int *wave_pca;
47  static double *pc;
48  float *sst;
49  static int *bindx;
50  float *Rrs=l2rec->Rrs;
51  static float *interp_rrs;
52  static float *wave;
53  static float *pcc_all;
54 
55  if(firstcall){
56  firstcall=0;
57  nbands=l2rec->l1rec->l1file->nbands;
58  wave=l2rec->l1rec->l1file->fwave;
59  npix=l2rec->l1rec->npix;
60 
61  //read the pca components from the table
62  char filename[FILENAME_MAX];
63  char *filedir;
64 
65  if ((filedir = getenv("OCDATAROOT")) == NULL) {
66  printf("-E- %s: OCDATAROOT env variable undefined.\n", __FILE__);
67  exit(EXIT_FAILURE);
68  }
69  strcpy(filename, filedir);
70  strcat(filename, "/common/");
71 
72  strcat(filename, "pca_picophyto.h5");
73 
74  printf("Reading pca table for picophyto from: %s\n", filename);
75 
76  hid_t file_id,set_id, space_id;
77  hsize_t dims[2], maxdims[2];
78  hid_t mem_space_id;
79 
80  hsize_t start[2]= {(hsize_t) 0, (hsize_t) 0};
81  hsize_t stride[2]={(hsize_t) 1, (hsize_t) 1};
82  hsize_t count[2] ={(hsize_t) 1, (hsize_t) 1};
83 
84 
85  if( (file_id=H5Fopen(filename,H5F_ACC_RDONLY, H5P_DEFAULT))==-1){
86  printf("error in opening -%s-\n", filename);
87  exit(FATAL_ERROR);
88  }
89 
90  set_id=H5Dopen(file_id,"component", H5P_DEFAULT);
91  space_id=H5Dget_space(set_id);
92  H5Sget_simple_extent_dims(space_id, dims, maxdims);
93 
94  nwave_pca=dims[0];
95  npc=dims[1];
96 
97  pca_table=(float32 *)malloc(nwave_pca*npc*sizeof(float32));
98  pc=(double *)malloc(npc*sizeof(double));
99  wave_pca=(int *)malloc(nwave_pca*sizeof(int));
100  bindx=(int *)malloc(nwave_pca*sizeof(int));
101  pcc_all=(float *)malloc(3*npix*sizeof(float));
102 
103  count[0]=nwave_pca;
104  count[1]=npc;
105 
106  mem_space_id=H5Screate_simple(2, count, NULL);
107  H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, NULL);
108  H5Dread(set_id,H5T_NATIVE_FLOAT, mem_space_id, space_id, H5P_DEFAULT, (void *)pca_table);
109 
110  H5Sclose(space_id);
111  H5Dclose(set_id);
112 
113  set_id=H5Dopen(file_id,"wavelength", H5P_DEFAULT);
114  space_id=H5Dget_space(set_id);
115  mem_space_id=H5Screate_simple(1, count, NULL);
116  H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, NULL);
117  H5Dread(set_id,H5T_NATIVE_INT, mem_space_id, space_id, H5P_DEFAULT, (void *)wave_pca);
118 
119  H5Sclose(space_id);
120  H5Dclose(set_id);
121 
122  H5Fclose(file_id);
123 
124  for(i=0;i<nwave_pca;i++)
125  bindx[i]=windex(1.0*wave_pca[i],wave,nbands);
126 
127  //read the coefficients from msl12_default.par
128  filedir=strrchr(filename,'/');
129  filename[filedir-filename]='\0';
130  strcat(filename, "/picophyt.json");
131 
132  json_t *json,*wv;
133  json_error_t error;
134  const char *line;
135 
136  json = json_load_file(filename, 0, &error);
137  if (!json){
138  printf("the file %s not exist\n",filename);
139  exit(1);
140  }
141 
142  wv=json_object_get(json,"npc");
143  line=json_string_value(wv);
144  npc_used=atof(line);
145 
146  pro_coef=(double *)malloc((npc+2)*sizeof(double));
147  syn_coef=(double *)malloc((npc+1)*sizeof(double));
148  apeuk_coef=(double *)malloc((npc+1)*sizeof(double));
149  interp_rrs=(float *)malloc(nwave_pca*sizeof(float));
150 
151  wv=json_object_get(json,"pro_coef");
152  line=json_string_value(wv);
153  i=0;
154  while(line){
155  pro_coef[i++]=atof(line);
156  line=strchr(line,',');
157  if(line)
158  line++;
159  }
160 
161  wv=json_object_get(json,"syn_coef");
162  line=json_string_value(wv);
163  i=0;
164  while(line){
165  syn_coef[i++]=atof(line);
166  line=strchr(line,',');
167  if(line)
168  line++;
169  }
170 
171  wv=json_object_get(json,"apeuk_coef");
172  line=json_string_value(wv);
173  i=0;
174  while(line){
175  apeuk_coef[i++]=atof(line);
176  line=strchr(line,',');
177  if(line)
178  line++;
179  }
180 
181  }
182 
183  if (input->proc_sst)
184  sst = l2rec->sst;
185  else
186  sst=l2rec->l1rec->sstref;
187 
188  for(ip=0;ip<npix;ip++){
189 
190  ipb=ip*nbands;
191 
192  cell_abundance[ip]=BAD_FLT;
193  for(i=0;i<3;i++)
194  pcc_all[ip*3+i]=BAD_FLT;
195 
196  //interpolate input Rrs to the pca wavelength
197  for(i=0;i<nwave_pca;i++){
198  for(j=0;j<nbands;j++){
199  if(wave_pca[i]< wave[j])
200  break;
201  }
202  if(j==0)
203  j+=1;
204  else if(j==nbands)
205  j=nbands-1;
206 
207  //interpolate Rrs in pca wavelength using input Rrs at wavelengths j and j-1
208 
209  interp_rrs[i]=Rrs[ipb+j-1]+(Rrs[ipb+j]-Rrs[ipb+j-1])*(wave_pca[i]-wave[j-1])/(wave[j]-wave[j-1]);
210  }
211 
212  rrs_standardize(interp_rrs,nwave_pca);
213 
214  for(i=0;i<npc;i++){
215  pc[i]=0.;
216  for(j=0;j<nwave_pca;j++){
217  pc[i]+=pca_table[j*npc+i]*interp_rrs[j];
218  }
219  }
220 
221  pcc_all[ip*3]=pro_coef[0]+pro_coef[1]*log10(sst[ip]);
222  pcc_all[ip*3+1]=syn_coef[0];
223  pcc_all[ip*3+2]=apeuk_coef[0];
224  for(i=0;i<npc_used;i++){
225  pcc_all[ip*3]+=pro_coef[i+2]*pc[i];
226  pcc_all[ip*3+1]+=syn_coef[i+1]*pc[i];
227  pcc_all[ip*3+2]+=apeuk_coef[i+1]*pc[i];
228  }
229  pcc_all[ip*3+1]=pow(10.,pcc_all[ip*3+1]);
230  pcc_all[ip*3+2]=pow(10.,pcc_all[ip*3+2]);
231  if(pcc_all[ip*3+1]<0.)
232  pcc_all[ip*3+1]=BAD_FLT;
233  if(pcc_all[ip*3+2]<0.)
234  pcc_all[ip*3+2]=BAD_FLT;
235 
236  if(pcc_all[ip*3]<0 && pcc_all[ip*3+1]>0. && pcc_all[ip*3+2]>0.)
237  pcc_all[ip*3]=0.;
238 
239  switch(p->cat_ix){
240  case CAT_prochlorococcus:
241  cell_abundance[ip]=pcc_all[ip*3];
242  break;
243  case CAT_synechococcus:
244  cell_abundance[ip]=pcc_all[ip*3+1];
245  break;
247  cell_abundance[ip]=pcc_all[ip*3+2];
248  break;
249  default:
250  break;
251  }
252 
253  }
254 
255 }
256 
const int bindx[3]
Definition: DbLutNetcdf.cpp:28
#define CAT_prochlorococcus
Definition: l2prod.h:424
int j
Definition: decode_rs.h:73
float mean(float *xs, int sample_size)
Definition: numerical.c:81
void get_Cpicophyt(l2str *l2rec, l2prodstr *p, float *cell_abundance)
Definition: get_Cpicophyt.c:38
#define NULL
Definition: decode_rs.h:63
#define CAT_synechococcus
Definition: l2prod.h:425
void rrs_standardize(float *rrs, int nwave)
Definition: get_Cpicophyt.c:21
instr * input
a context in which it is NOT documented to do so subscript error
Definition: HISTORY.txt:53
#define FATAL_ERROR
Definition: swl0_parms.h:5
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
integer, parameter double
#define CAT_autotrophic_picoeukaryotes
Definition: l2prod.h:426
#define BAD_FLT
Definition: jplaeriallib.h:19
int32_t nbands
int windex(float wave, float twave[], int ntwave)
Definition: windex.c:73
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int npix
Definition: get_cmp.c:28
float p[MODELMAX]
Definition: atrem_corl1.h:131
int count
Definition: decode_rs.h:79