|
ocssw
1.0
|
00001 00090 #include <stdlib.h> 00091 #include <math.h> 00092 #include <stdarg.h> 00093 #include <assert.h> 00094 #include "qaa.h" 00095 00096 static int idx410 = -1; 00097 static int idx440 = -1; 00098 static int idx490 = -1; 00099 static int idx555 = -1; 00100 static int idx670 = -1; 00101 static int initialized = 0; 00102 static int aph_check = 1; 00103 static double S = 0.015; 00104 static double chl = -1; 00105 static double acoefs[3]; 00106 00112 int 00113 qaa_is_initialized( void ) 00114 { 00115 return initialized; 00116 } 00117 00132 int 00133 qaa_init( int i410, int i440, int i490, int i555, int i670 ) 00134 { 00135 idx410 = i410; 00136 idx440 = i440; 00137 idx490 = i490; 00138 idx555 = i555; 00139 idx670 = i670; 00140 00141 // SeaWiFS coefficients 00142 00143 acoefs[0] = -1.146; 00144 acoefs[1] = -1.366; 00145 acoefs[2] = -0.469; 00146 00147 initialized = 1; 00148 00149 return 0; 00150 } 00151 00164 int 00165 qaa_set_param( int param, ... ) 00166 { 00167 va_list ap; 00168 va_start( ap, param ); 00169 switch (param) { 00170 case QAA_S_PARAM: 00171 S = va_arg(ap,double); 00172 break; 00173 case QAA_CHL_PARAM: 00174 chl = va_arg(ap,double); 00175 break; 00176 case QAA_COEFS_PARAM: 00177 acoefs[0] = va_arg(ap,double); 00178 acoefs[1] = va_arg(ap,double); 00179 acoefs[2] = va_arg(ap,double); 00180 break; 00181 case QAA_APH_CHECK: 00182 aph_check = va_arg(ap,int); 00183 break; 00184 } 00185 va_end(ap); 00186 return 0; 00187 } 00188 00205 int 00206 qaa_v6( int nbands, double *wavel, double *Rrs, double *aw, double *bbw, 00207 double *rrs, double *u, double *a, double *bb, unsigned char *flags ) 00208 { 00209 00210 const double g0 = 0.08945; 00211 const double g1 = 0.1247; 00212 00213 int i, idxref; 00214 00215 double rat, aref; 00216 double bbpref; 00217 double Y; 00218 double rho, numer, denom; 00219 00220 assert( idx440 >= 0 ); 00221 assert( idx490 >= 0 ); 00222 assert( idx555 >= 0 ); 00223 assert( nbands >= 0 ); 00224 00225 /* pre-test 670 */ 00226 if ( (Rrs[idx670] > 20.0*pow(Rrs[idx555],1.5)) || 00227 (Rrs[idx670] < 0.9*pow(Rrs[idx555],1.7)) ) { 00228 Rrs[idx670] = 1.27*pow(Rrs[idx555],1.47) + 0.00018*pow(Rrs[idx490]/Rrs[idx555],-3.19); 00229 if ( flags ) *flags |= 0x02; 00230 } 00231 00232 /* Step 0 */ 00233 for ( i = 0; i < nbands; i++ ) { 00234 rrs[i] = Rrs[i] / (0.52 + 1.7 * Rrs[i] ); 00235 if ( Rrs[i] < 0.0 ) 00236 if ( flags ) *flags |= 0x01; 00237 } 00238 00239 /* Step 1 */ 00240 for ( i = 0; i < nbands; i++ ) 00241 u[i] = (sqrt(g0*g0 + 4.0*g1*rrs[i]) - g0) / (2.0 * g1); 00242 00243 /* Step 2 */ 00244 if ( Rrs[idx670] >= 0.0015 ) { 00245 aref = aw[idx670] + 0.07*pow(Rrs[idx670]/Rrs[idx440],1.1); 00246 idxref = idx670; 00247 } else { 00248 numer = Rrs[idx440] + Rrs[idx490]; 00249 denom = Rrs[idx555] + 5*Rrs[idx670]*(Rrs[idx670]/Rrs[idx490]); 00250 rho = log10( numer / denom ); 00251 rho = acoefs[0] + acoefs[1]*rho + acoefs[2]*rho*rho; 00252 aref = aw[idx555] + pow(10.0,rho); 00253 idxref = idx555; 00254 } 00255 00256 /* Step 3 */ 00257 bbpref = ((u[idxref] * aref) / (1.0 - u[idxref])) - bbw[idxref]; 00258 00259 /* Step 4 */ 00260 rat = rrs[idx440] / rrs[idx555]; 00261 Y = 2.0 * (1.0 - 1.2 * exp( -0.9*rat) ); 00262 00263 /* Step 5 */ 00264 for ( i = 0; i < nbands; i++ ) { 00265 bb[i] = bbpref * pow((wavel[idxref]/wavel[i]),Y) + bbw[i]; 00266 if ( bb[i] < 0.0 ) 00267 if ( flags ) *flags |= 0x04; 00268 } 00269 00270 /* Step 6 */ 00271 for ( i = 0; i < nbands; i++ ) { 00272 a[i] = ((1.0 - u[i]) * bb[i]) / u[i]; 00273 if ( a[i] < 0.0 ) 00274 if ( flags ) *flags |= 0x08; 00275 } 00276 00277 return 0; 00278 } 00279 00285 int 00286 qaaf_v6( int nbands, float *wavel, float *Rrs, float *aw, float *bbw, 00287 float *rrs, float *u, float *a, float *bb, 00288 unsigned char *flags ) 00289 { 00290 00291 const float g0 = 0.08945; 00292 const float g1 = 0.1247; 00293 00294 float rho, numer, denom; 00295 00296 float rat, aref; 00297 float bbpref; 00298 float Y; 00299 00300 int i, idxref; 00301 00302 assert( idx440 >= 0 ); 00303 assert( idx490 >= 0 ); 00304 assert( idx555 >= 0 ); 00305 assert( idx670 >= 0 ); 00306 assert( nbands >= 0 ); 00307 00308 /* Test for bad Rrs at idx555 */ 00309 if ( Rrs[idx555] <= 0.0 ) 00310 Rrs[idx555] = 0.001; 00311 00312 /* pre-test 670 */ 00313 if ( (Rrs[idx670] > 20.0*powf(Rrs[idx555],1.5)) || 00314 (Rrs[idx670] < 0.9*powf(Rrs[idx555],1.7)) ) { 00315 Rrs[idx670] = 1.27*powf(Rrs[idx555],1.47) + 0.00018*powf(Rrs[idx490]/Rrs[idx555],-3.19); 00316 if ( flags ) *flags |= 0x02; 00317 } 00318 00319 /* Step 0 */ 00320 for ( i = 0; i < nbands; i++ ) { 00321 rrs[i] = Rrs[i] / (0.52 + 1.7 * Rrs[i] ); 00322 if ( Rrs[i] < 0.0 ) 00323 if ( flags ) *flags |= 0x01; 00324 } 00325 00326 /* Step 1 */ 00327 for ( i = 0; i < nbands; i++ ) 00328 u[i] = (sqrt(g0*g0 + 4.0*g1*rrs[i]) - g0) / (2.0 * g1); 00329 00330 /* Step 2 */ 00331 if ( Rrs[idx670] >= 0.0015 ) { 00332 aref = aw[idx670] + 0.07*pow(Rrs[idx670]/Rrs[idx440],1.1); 00333 idxref = idx670; 00334 } else { 00335 numer = Rrs[idx440] + Rrs[idx490]; 00336 denom = Rrs[idx555] + 5*Rrs[idx670]*(Rrs[idx670]/Rrs[idx490]); 00337 rho = log10f( numer / denom ); 00338 rho = acoefs[0] + acoefs[1]*rho + acoefs[2]*rho*rho; 00339 aref = aw[idx555] + powf(10.0,rho); 00340 idxref = idx555; 00341 } 00342 00343 /* Step 3 */ 00344 bbpref = ((u[idxref] * aref) / (1.0 - u[idxref])) - bbw[idxref]; 00345 00346 /* Step 4 */ 00347 rat = rrs[idx440] / rrs[idx555]; 00348 Y = 2.0 * (1.0 - 1.2 * expf( -0.9*rat) ); 00349 00350 /* Step 5 */ 00351 for ( i = 0; i < nbands; i++ ) { 00352 bb[i] = bbpref * pow((wavel[idxref]/wavel[i]),Y) + bbw[i]; 00353 if ( bb[i] < 0.0 ) 00354 if ( flags ) *flags |= 0x04; 00355 } 00356 00357 /* Step 6 */ 00358 for ( i = 0; i < nbands; i++ ) { 00359 a[i] = ((1.0 - u[i]) * bb[i]) / u[i]; 00360 if ( a[i] < 0.0 ) 00361 if ( flags ) *flags |= 0x08; 00362 } 00363 00364 return 0; 00365 } 00366 00387 int 00388 qaa_decomp( int nbands, double *wavel, double *rrs, double *a, double *aw, 00389 double *adg, double *aph, unsigned char *flags ) 00390 { 00391 int i; 00392 double symbol, x1, x2; 00393 double zeta, denom, dif1, dif2; 00394 double rat, ag440; 00395 double Sr; 00396 00397 assert( idx410 >= 0 ); 00398 assert( idx440 >= 0 ); 00399 assert( idx555 >= 0 ); 00400 assert( nbands >= 0 ); 00401 00402 /* step 7 */ 00403 rat = rrs[idx440] / rrs[idx555]; 00404 symbol = 0.74 + ( 0.2 / ( 0.8 + rat ) ); 00405 00406 /* step 8 */ 00407 Sr = S + 0.002 / ( 0.6 + rat ); 00408 zeta = exp( Sr * (wavel[idx440] - wavel[idx410]) ); 00409 00410 /* step 9 */ 00411 denom = zeta - symbol; 00412 dif1 = a[idx410] - symbol * a[idx440]; 00413 dif2 = aw[idx410] - symbol * aw[idx440]; 00414 ag440 = (dif1 - dif2) / denom; 00415 00416 for ( i = 0; i < nbands; i++ ) { 00417 adg[i] = ag440 * exp( Sr * (wavel[idx440] - wavel[i])); 00418 aph[i] = a[i] - adg[i] - aw[i]; 00419 } 00420 00421 /* check aph443 range */ 00422 00423 if ( aph_check ) { 00424 00425 x1 = aph[idx440] / a[idx440]; 00426 if ( x1 < 0.15 || x1 > 0.6 ) { 00427 00428 if ( flags ) *flags |= 0x10; 00429 00430 x2 = -0.8 + 1.4 * (a[idx440] - aw[idx440])/(a[idx410] - aw[idx410]); 00431 if ( x2 < 0.15 ) { 00432 x2 = 0.15; 00433 if ( flags ) *flags |= 0x20; 00434 } 00435 if ( x2 > 0.6 ) { 00436 x2 = 0.6; 00437 if ( flags ) *flags |= 0x40; 00438 } 00439 00440 aph[idx440] = a[idx440] * x2; 00441 ag440 = a[idx440] - aph[idx440] - aw[idx440]; 00442 00443 for ( i = 0; i < nbands; i++ ) { 00444 adg[i] = ag440 * exp( Sr * (wavel[idx440] - wavel[i])); 00445 aph[i] = a[i] - adg[i] - aw[i]; 00446 } 00447 00448 } 00449 } 00450 return 0; 00451 } 00452 00458 int 00459 qaaf_decomp( int nbands, float *wavel, float *rrs, float *a, float *aw, 00460 float *adg, float *aph, unsigned char *flags ) 00461 { 00462 int i; 00463 float symbol, x1, x2; 00464 float zeta, denom, dif1, dif2; 00465 float rat, ag440; 00466 float Sr; 00467 00468 assert( idx410 >= 0 ); 00469 assert( idx440 >= 0 ); 00470 assert( idx555 >= 0 ); 00471 assert( nbands >= 0 ); 00472 00473 /* step 7 */ 00474 rat = rrs[idx440] / rrs[idx555]; 00475 symbol = 0.74 + ( 0.2 / ( 0.8 + rat ) ); 00476 00477 /* step 8 */ 00478 Sr = S + 0.002 / ( 0.6 + rat ); 00479 zeta = expf( Sr * (wavel[idx440] - wavel[idx410]) ); 00480 00481 /* step 9 */ 00482 denom = zeta - symbol; 00483 dif1 = a[idx410] - symbol * a[idx440]; 00484 dif2 = aw[idx410] - symbol * aw[idx440]; 00485 ag440 = (dif1 - dif2) / denom; 00486 00487 for ( i = 0; i < nbands; i++ ) { 00488 adg[i] = ag440 * expf( Sr * (wavel[idx440] - wavel[i])); 00489 aph[i] = a[i] - adg[i] - aw[i]; 00490 } 00491 00492 /* check aph443 range */ 00493 00494 if ( aph_check ) { 00495 00496 x1 = aph[idx440] / a[idx440]; 00497 if ( x1 < 0.15 || x1 > 0.6 ) { 00498 00499 if ( flags ) *flags |= 0x10; 00500 00501 x2 = -0.8 + 1.4 * (a[idx440] - aw[idx440])/(a[idx410] - aw[idx410]); 00502 if ( x2 < 0.15 ) { 00503 x2 = 0.15; 00504 if ( flags ) *flags |= 0x20; 00505 } 00506 if ( x2 > 0.6 ) { 00507 x2 = 0.6; 00508 if ( flags ) *flags |= 0x40; 00509 } 00510 00511 aph[idx440] = a[idx440] * x2; 00512 ag440 = a[idx440] - aph[idx440] - aw[idx440]; 00513 00514 for ( i = 0; i < nbands; i++ ) { 00515 adg[i] = ag440 * expf( Sr * (wavel[idx440] - wavel[i])); 00516 aph[i] = a[i] - adg[i] - aw[i]; 00517 } 00518 00519 } 00520 00521 } 00522 00523 return 0; 00524 } 00525 00526 #ifdef TEST_QAA 00527 00528 #include <stdio.h> 00529 00530 /* 00531 * to compile: 00532 * cc -o qaa -g -DTEST_QAA -I. qaa.c -lm 00533 * ./qaa 00534 */ 00535 00536 00537 00538 static void print_out( int n, float *fwl, float *Rrs, float *rrs, float *u, 00539 float *a, float *aph, float *adg, float *aw, float *bb, float *bbw ) 00540 { 00541 00542 int i; 00543 00544 printf("lamda "); 00545 for ( i = 0; i < n; i++ ) 00546 printf("%9.0f ", fwl[i]); 00547 printf("\n"); 00548 00549 printf("Rrs : "); 00550 for ( i = 0; i < n; i++ ) 00551 printf("%9.6f ", Rrs[i]); 00552 printf("\n"); 00553 00554 printf("rrs : "); 00555 for ( i = 0; i < n; i++ ) 00556 printf("%9.6f ", rrs[i]); 00557 printf("\n"); 00558 00559 printf("u : "); 00560 for ( i = 0; i < n; i++ ) 00561 printf("%9.6f ", u[i]); 00562 printf("\n"); 00563 00564 printf("a : "); 00565 for ( i = 0; i < n; i++ ) 00566 printf("%9.6f ", a[i]); 00567 printf("\n"); 00568 00569 printf("aph : "); 00570 for ( i = 0; i < n; i++ ) 00571 printf("%9.6f ", aph[i]); 00572 printf("\n"); 00573 00574 printf("adg : "); 00575 for ( i = 0; i < n; i++ ) 00576 printf("%9.6f ", adg[i]); 00577 printf("\n"); 00578 00579 printf("aw : "); 00580 for ( i = 0; i < n; i++ ) 00581 printf("%9.6f ", aw[i]); 00582 printf("\n"); 00583 00584 printf("bb : "); 00585 for ( i = 0; i < n; i++ ) 00586 printf("%9.6f ", bb[i]); 00587 printf("\n"); 00588 00589 printf("bbw : "); 00590 for ( i = 0; i < n; i++ ) 00591 printf("%9.6f ", bbw[i]); 00592 printf("\n"); 00593 00594 } 00595 00596 int 00597 main( int argc, char *argv[] ) 00598 { 00599 00600 /* the 5th position here will be changed for 640nm later down in code */ 00601 00602 #define NBANDS 6 00603 #define NUM_SPECTRA 24 00604 float Rrs_insitu[NUM_SPECTRA][NBANDS] = { 00605 /* 412 443 490 510 555 670 */ 00606 { 0.001919, 0.002297, 0.004420, 0.005547, 0.009138, 0.004110}, 00607 { 0.001753, 0.002657, 0.004348, 0.005212, 0.007641, 0.003950}, 00608 { 0.003968, 0.003374, 0.002932, 0.002142, 0.001214, 0.000136}, 00609 { 0.001332, 0.001414, 0.002116, 0.002464, 0.003891, 0.001669}, 00610 { 0.001572, 0.001537, 0.002132, 0.002504, 0.004157, 0.001909}, 00611 { 0.004830, 0.004084, 0.003540, 0.002648, 0.001584, 0.000194}, 00612 { 0.001145, 0.001457, 0.002501, 0.002945, 0.004180, 0.001524}, 00613 { 0.000921, 0.001004, 0.001465, 0.001456, 0.001363, 0.000252}, 00614 { 0.003120, 0.003226, 0.003530, 0.002857, 0.001882, 0.000196}, 00615 { 0.005170, 0.004682, 0.003794, 0.002535, 0.001343, 0.000131}, 00616 { 0.004718, 0.004378, 0.003763, 0.002627, 0.001472, 0.000151}, 00617 { 0.003503, 0.003394, 0.003358, 0.002510, 0.001507, 0.000181}, 00618 { 0.001005, 0.001131, 0.001879, 0.002219, 0.003316, 0.001100}, 00619 { 0.007704, 0.006917, 0.005540, 0.003721, 0.002129, 0.000389}, 00620 { 0.003311, 0.003071, 0.002920, 0.002315, 0.001508, 0.000285}, 00621 { 0.003476, 0.003285, 0.003073, 0.002347, 0.001436, 0.000200}, 00622 { 0.004661, 0.005739, 0.008028, 0.007809, 0.006632, 0.001035}, 00623 { 0.004212, 0.004859, 0.006455, 0.006117, 0.004895, 0.000676}, 00624 { 0.002090, 0.002280, 0.003091, 0.002780, 0.002177, 0.000444}, 00625 { 0.003237, 0.003042, 0.002947, 0.002317, 0.001440, 0.000166}, 00626 { 0.003125, 0.003444, 0.004119, 0.003777, 0.002875, 0.000413}, 00627 { 0.002637, 0.002896, 0.003477, 0.002987, 0.002085, 0.000251}, 00628 { 0.003472, 0.003596, 0.003834, 0.003067, 0.001969, 0.000331}, 00629 { 0.004554, 0.003772, 0.002074, 0.002082, 0.001338, 0.000120} 00630 }; 00631 00632 float fwl[NBANDS] ={ 412, 443, 490, 510, 555, 670 }; 00633 float aw[NBANDS] ={ 0.004994, 0.007512, 0.025010, 0.040020, 0.077080, 0.445600 }; 00634 float bbw[NBANDS] ={ 0.003271, 0.002421, 0.001568, 0.001339, 0.000939, 0.000426 }; 00635 00636 int i, j; 00637 float Rrs[NBANDS]; 00638 float rrs[NBANDS]; 00639 float u[NBANDS]; 00640 float a[NBANDS]; 00641 float bb[NBANDS]; 00642 float aph[NBANDS]; 00643 float adg[NBANDS]; 00644 unsigned char flags; 00645 00646 int idx410 = 0; 00647 int idx440 = 1; 00648 int idx490 = 2; 00649 int idx555 = 4; 00650 int idx670 = 5; 00651 int nbands; 00652 00653 // Ping's bbw using 0.0038 * pow((400.0/lambda),4.32); 00654 // for ( i = 0; i< NBANDS; i++ ) 00655 // bbw[i] = 0.0038 * pow(400.0/fwl[i],4.32); 00656 00657 qaa_init( idx410, idx440, idx490, idx555, idx670 ); 00658 qaa_set_param( QAA_APH_CHECK, 0 ); 00659 00660 printf("QAA v6\n" ); 00661 for ( j = 0; j < NUM_SPECTRA; j++ ) { 00662 00663 flags = 0; 00664 nbands = NBANDS; 00665 /* 412 to 670 */ 00666 for ( i = 0; i < nbands; i++ ) 00667 Rrs[i] = Rrs_insitu[j][i]; 00668 00669 qaaf_v6( nbands, fwl, Rrs, aw, bbw, rrs, u, a, bb, NULL ); 00670 qaaf_decomp( nbands, fwl, rrs, a, aw, adg, aph, NULL ); 00671 00672 for ( i = 0; i < 6; i++ ) 00673 if ( a[i] < aw[i] ) 00674 flags |= 0x08; 00675 00676 for ( i = 0; i < 6; i++ ) 00677 if ( bb[i] < bbw[i] ) 00678 flags |= 0x80; 00679 00680 print_out( nbands, fwl, Rrs, rrs, u, a, aph, adg, aw, bb, bbw ); 00681 00682 if ( flags & 0x10 ) 00683 printf("original aph/a ratio was out of range (0.15 to 0.6)\n"); 00684 if ( flags & 0x20 ) 00685 printf(" and was forced to minimum (0.15)\n"); 00686 if ( flags & 0x40 ) 00687 printf(" and was forced to maximum (0.6)\n"); 00688 printf("\n"); 00689 } 00690 00691 return 0; 00692 } 00693 #endif
1.7.6.1