NASA Logo
Ocean Color Science Software

ocssw V2022
get_poc_hybrid.c
Go to the documentation of this file.
1 /*
2  * get_poc_hybrid.c
3  *
4  * Created on: May 30, 2023
5  * Author: mzhang11
6  */
7 
8 #include <stdlib.h>
9 #include <math.h>
10 #include "l12_proto.h"
11 #include <jansson.h>
12 
13 
14 float range_brdi (float x)
15 {
16  return 1-log10(0.9*x-12.5);
17 }
18 float range_mbr (float x)
19 {
20  return log10(0.9*x-12.5);
21 }
22 float poc_stramski_hybrid(float *Rrs, int32_t sensorID) {
23  static int firstCall = 1;
24  static int ib[4]={-1,-1,-1,-1};
25  static int nwave;
26  int i;
27  float ratio[3];
28  static float virtual_coef_A[2],virtual_coef_B[2],virtual_rat;
29  static int ifvirtual;
30  int32_t wave[4];
31 
32  float poc = BAD_FLT;
33  float Rrs510A,Rrs510B,mbr,brdi,poc_mbr,poc_brdi,w_mbr,w_brdi;
34  float Rrs_temp[4];
35  static float mbr_coef[4],brdi_coef[6];
36 
37 
38  if (firstCall) {
39 
40  firstCall = 0;
41  ifvirtual=0;
42 
43  char filename[FILENAME_MAX];
44  char *filedir;
45  const char *subsensorDir;
46 
47  if ((filedir = getenv("OCDATAROOT")) == NULL) {
48  printf("-E- %s: OCDATAROOT env variable undefined.\n", __FILE__);
49  exit(EXIT_FAILURE);
50  }
51  strcpy(filename, filedir);
52  strcat(filename, "/");
54  strcat(filename, "/");
55 
57  if(subsensorDir) {
58  strcat(filename, subsensorDir);
59  strcat(filename, "/");
60  }
61  strcat(filename, "poc_stramski_hybrid.json");
62  json_t *json,*wv;
63  json_error_t error;
64  const char *line;
65 
66  json = json_load_file(filename, 0, &error);
67  if (!json){
68  printf("the file %s not exist\n",filename);
69  exit(1);
70  }
71 
72  /* size_t size=json_dumpb(json,NULL,0,0);
73 
74  buffer=(char *)malloc(size);
75  size=json_dumpb(json,buffer,size,0);
76  line=json_dumps(json,0);*/
77 
78  wv=json_object_get(json,"poc_wave");
79  line=json_string_value(wv);
80 
81  i=0;
82  while(line){
83  wave[i++]=atof(line);
84  line=strchr(line,',');
85  if(line)
86  line++;
87  }
88  nwave=i;
89 
90 
91  wv=json_object_get(json,"poc_mbr_coef");
92  line=json_string_value(wv);
93  i=0;
94  while(line){
95  mbr_coef[i++]=atof(line);
96  line=strchr(line,',');
97  if(line)
98  line++;
99  }
100 
101  wv=json_object_get(json,"poc_brdi_coef");
102  line=json_string_value(wv);
103  i=0;
104  while(line){
105  brdi_coef[i++]=atof(line);
106  line=strchr(line,',');
107  if(line)
108  line++;
109  }
110 
111  for(i=0;i<nwave;i++)
112  ib[i]=bindex_get(wave[i]);
113 
114  switch(sensorID){
115  case MODISA: case MODIST: case VIIRSJ1:case VIIRSN:
116  ifvirtual=1;
117  break;
118  default:
119  break;
120  }
121  if(ifvirtual){
122  switch(sensorID){
123  case MODISA: case MODIST:
124  virtual_coef_A[0]=-0.00008;
125  virtual_coef_A[1]= 1.085;
126  virtual_coef_B[0]=-0.00041 ;
127  virtual_coef_B[1]= 1.104;
128  virtual_rat=0.5;
129  break;
130  case VIIRSJ1:
131  virtual_coef_A[0]=-0.0000004 ;
132  virtual_coef_A[1]= 1.068;
133  virtual_coef_B[0]=-0.00130;
134  virtual_coef_B[1]= 1.291;
135  virtual_rat=0.69;
136  break;
137  case VIIRSN:
138  virtual_coef_A[0]=-0.000070;
139  virtual_coef_A[1]= 1.096 ;
140  virtual_coef_B[0]=-0.00094;
141  virtual_coef_B[1]= 1.221;
142  virtual_rat=0.63;
143  break;
144  default:
145  printf("-E- %s line %d: coefficients to calculate virtual Rrs(510) are not defined for Stramski hybrid POC\n",
146  __FILE__, __LINE__);
147  exit(1);
148  break;
149  }
150  }
151 
152 
153  if(nwave==3){
154  ib[3]=ib[2];
155  ib[2]=-1;
156  }
157  if (ib[0] < 0 || ib[1] < 0|| ib[3] < 0) {
158  printf("-E- %s line %d: required bands not available for Stramski hybrid POC\n",
159  __FILE__, __LINE__);
160  exit(1);
161  }
162  }
163 
164  for(i=0;i<nwave;i++){
165  if(ib[i]>0 && Rrs[ib[i]]<0)
166  return BAD_FLT;
167  }
168 
169  if(nwave==4){
170  for(i=0;i<4;i++)
171  Rrs_temp[i]=Rrs[ib[i]];
172  }else if(nwave==3){
173  for(i=0;i<2;i++)
174  Rrs_temp[i]=Rrs[ib[i]];
175  Rrs_temp[3]=Rrs[ib[3]];
176  }
177 
178  if(ifvirtual){
179  Rrs510A=virtual_coef_A[0]+virtual_coef_A[1]*Rrs_temp[1];
180  if(nwave==4)
181  Rrs510B=virtual_coef_B[0]+virtual_coef_B[1]*Rrs_temp[2];
182  else if(nwave==3)
183  Rrs510B=virtual_coef_B[0]+virtual_coef_B[1]*Rrs_temp[3];
184 
185  Rrs_temp[2]=virtual_rat*Rrs510A+(1-virtual_rat)*Rrs510B;
186  }
187 
188  for(i=0;i<3;i++)
189  ratio[i]=Rrs_temp[i]/Rrs_temp[3];
190 
191  if(ifvirtual){
192  if(isnan(ratio[0])||isnan(ratio[1])||isnan(ratio[2]))
193  mbr=MAX(MAX(ratio[0],ratio[1]),ratio[2]);
194  else if(ratio[2]<1.2 && Rrs_temp[2]>Rrs_temp[1]&&Rrs_temp[2]>Rrs_temp[0])
195  mbr=MAX(MAX(ratio[0],ratio[1]),ratio[2]);
196  else
197  mbr=MAX(ratio[0],ratio[1]);
198  }
199  else
200  mbr=MAX(MAX(ratio[0],ratio[1]),ratio[2]);
201 
202  mbr=log10(mbr);
203  poc_mbr=0.;
204  for(i=0;i<4;i++)
205  poc_mbr+=mbr_coef[i]*pow(mbr,i);
206  poc_mbr=pow(10.,poc_mbr);
207 
208  brdi=(Rrs_temp[0]-Rrs_temp[3])/Rrs_temp[1];
209  poc_brdi=0.;
210  for(i=0;i<6;i++)
211  poc_brdi+=brdi_coef[i]*pow(brdi,i);
212  poc_brdi=pow(10.,poc_brdi);
213 
214  if(isnan(poc_brdi))
215  w_brdi=-1;
216  else if(poc_brdi<15.)
217  w_brdi=1.0;
218  else if(poc_brdi>25.)
219  w_brdi=0.0;
220  else
221  w_brdi=range_brdi(poc_brdi);
222 
223  if(isnan(poc_mbr))
224  w_mbr=-1;
225  else if(poc_mbr<15.)
226  w_mbr=0.0;
227  else if(poc_mbr>25.)
228  w_mbr=1.0;
229  else
230  w_mbr=range_mbr(poc_mbr);
231 
232 
233  w_mbr=(w_mbr+(1-w_brdi))*0.5;
234  w_brdi=1-w_mbr;
235 
236  if(isnan(brdi))
237  poc=poc_mbr;
238  else if(brdi<1.)
239  poc=poc_mbr;
240  else
241  poc=poc_brdi*w_brdi+poc_mbr*w_mbr;
242 
243  return (poc);
244 }
#define MAX(A, B)
Definition: swl0_utils.h:25
const char * sensorId2SensorDir(int sensorId)
Definition: sensorInfo.c:315
#define NULL
Definition: decode_rs.h:63
#define VIIRSN
Definition: sensorDefs.h:23
#define MODIST
Definition: sensorDefs.h:18
int sensorId2SubsensorId(int sensorId)
Definition: sensorInfo.c:438
a context in which it is NOT documented to do so subscript error
Definition: HISTORY.txt:53
int bindex_get(int32_t wave)
Definition: windex.c:45
float range_mbr(float x)
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
#define BAD_FLT
Definition: jplaeriallib.h:19
const char * subsensorId2SubsensorDir(int subsensorId)
Definition: sensorInfo.c:329
float poc_stramski_hybrid(float *Rrs, int32_t sensorID)
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")
int32_t sensorID[MAXNFILES]
Definition: l2bin.cpp:91
#define MODISA
Definition: sensorDefs.h:19
#define VIIRSJ1
Definition: sensorDefs.h:37
float range_brdi(float x)