28 static int numFlagMPHPixels = -1;
 
   29 static int numFlagHABSPixels = -1;
 
   30 static uint8_t *flags_mph = 
NULL;
 
   31 static uint8_t *flags_habs = 
NULL;
 
   35     if((numFlagMPHPixels != numPix) || !flags_mph) {
 
   36         numFlagMPHPixels = numPix;
 
   39         flags_mph = (uint8_t*) malloc(numPix);
 
   43     if((numFlagHABSPixels != numPix) || !flags_habs) {
 
   44         numFlagHABSPixels = numPix;
 
   47         flags_habs = (uint8_t*) malloc(numPix);
 
   52         float rhos620, 
float rhos665, 
float rhos709, 
float rhos865,
 
   53         float rhos885, 
float *ci) {
 
   55     float kd, kd_709, ss_560;
 
   57     kd = (0.7 * ((((rhos620 + rhos665) / 2.) - rhos885) / (((rhos443 + rhos490) / 2.) - rhos885)));
 
   60     kd_709 = (0.7 * ((rhos709 - rhos885) / (((rhos443 + rhos490) / 2.) - rhos885)));
 
   63     if (kd_709 > kd) kd = kd_709;
 
   66     ss_560 = rhos560 - rhos443 + (rhos443 - rhos620)*(560 - 443) / (620 - 443);
 
   69     if (((((rhos620 + rhos665) / 2.) - rhos885) > 0) &&
 
   70             ((((rhos443 + rhos490) / 2.) - rhos885) > 0)) {
 
   72             ((rhos865 <= rhos490) ||
 
   73             (rhos865 <= rhos665) ||
 
   74             (rhos865 <= rhos709)) &&
 
   79         if (rhos885 < 0.005) {
 
   87     int ib0, ib1, ib2, ib3, ib4, ib5, ib6, ib7, ib8;
 
   88     float wav0, wav1, wav2, wav3, wav4, wav5, wav6, wav7, wav8, 
fac, w681_fac;
 
   92     static productInfo_t* ci_product_info;
 
   94     switch (l2rec->l1rec->l1file->sensorID) {
 
  116         switch (l2rec->l1rec->l1file->sensorID) {
 
  144         if (l2rec->l1rec->l1file->sensorID != 
MERIS && 
 
  145                 l2rec->l1rec->l1file->sensorID != 
OLCIS3A && 
 
  146                 l2rec->l1rec->l1file->sensorID != 
OLCIS3B) {
 
  147             printf(
"MCI not supported for this sensor (%s).\n",
 
  157         printf(
"HABS_CI: Hmm, something's really messed up.\n");
 
  161     if (ci_product_info == 
NULL) {
 
  163         findProductInfo(
"CI_cyano", l2rec->l1rec->l1file->sensorID, ci_product_info);
 
  170     if (ib1 < 0 || ib2 < 0 || ib3 < 0) {
 
  171         printf(
"(M)CI_stumpf: incompatible sensor wavelengths for this algorithm\n");
 
  175     for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
 
  177         ipb = l2rec->l1rec->l1file->nbands*ip;
 
  180         if ((l2rec->l1rec->height[ip] == 0 && l2rec->l1rec->dem[ip] < -1 * 
input->shallow_water_depth) ||
 
  181                 (l2rec->l1rec->flags[ip] & 
mask) != 0 ||
 
  182                 l2rec->l1rec->rhos[ipb + ib1] <= 0.0 ||
 
  183                 l2rec->l1rec->rhos[ipb + ib2] <= 0.0 ||
 
  184                 l2rec->l1rec->rhos[ipb + ib3] <= 0.0) {
 
  186             l2rec->l1rec->flags[ip] |= 
PRODFAIL;
 
  193                 ci[ip] = 
fac * ((l2rec->l1rec->rhos[ipb + ib3] - l2rec->l1rec->rhos[ipb + ib1])*(wav2 - wav1) / (wav3 - wav1)
 
  194                         - (l2rec->l1rec->rhos[ipb + ib2]*w681_fac - l2rec->l1rec->rhos[ipb + ib1]));
 
  197                 if (l2rec->l1rec->l1file->sensorID == 
MERIS || l2rec->l1rec->l1file->sensorID == 
OLCIS3A  
  198                         || l2rec->l1rec->l1file->sensorID == 
OLCIS3B) {
 
  201                     if (l2rec->l1rec->rhos[ipb + ib0] - l2rec->l1rec->rhos[ipb + ib6]
 
  202                         + (l2rec->l1rec->rhos[ipb + ib6] - l2rec->l1rec->rhos[ipb + ib1]) * (wav0 - wav6) / (wav1 - wav6) > 0) {
 
  207                                        l2rec->l1rec->rhos[ipb + ib6], l2rec->l1rec->rhos[ipb + ib0],
 
  208                                        l2rec->l1rec->rhos[ipb + ib1], l2rec->l1rec->rhos[ipb + ib3],
 
  209                                        l2rec->l1rec->rhos[ipb + ib7], l2rec->l1rec->rhos[ipb + ib8], &ci[ip]);
 
  212                         if (l2rec->l1rec->rhos[ipb + ib1]
 
  213                                 - l2rec->l1rec->rhos[ipb + ib0]
 
  214                                 + (l2rec->l1rec->rhos[ipb + ib0]
 
  215                                 - l2rec->l1rec->rhos[ipb + ib2]*w681_fac)
 
  216                                 *(wav1 - wav0) / (wav2 - wav0) >= 0) {
 
  224                             l2rec->l1rec->flags[ip] |= 
PRODFAIL;
 
  228                                 if (nonci == 0) ci[ip] = 0;
 
  230                                 if (nonci == 1) ci[ip] = 0;
 
  237                 ci[ip] = 
fac * (l2rec->l1rec->rhos[ipb + ib2] - l2rec->l1rec->rhos[ipb + ib1]*w681_fac
 
  238                         - (l2rec->l1rec->rhos[ipb + ib3] - l2rec->l1rec->rhos[ipb + ib1]*w681_fac)*(wav2 - wav1) / (wav3 - wav1));
 
  246             if (ci[ip] < ci_product_info->validMin) {
 
  247                 ci[ip] = ci_product_info->validMin;
 
  253     for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
 
  254         if (flags_habs[ip] != 0){
 
  256             l2rec->l1rec->flags[ip] |= 
PRODFAIL;
 
  259     if (l2rec->l1rec->iscan == l2rec->l1rec->l1file->nscan) {
 
  276     float wav6, wav7, wav8, wav9, wav10, wav14;
 
  277     int ip, ipb, ib6, ib7, ib8, ib9, ib10, ib14;
 
  278     float Rmax0, Rmax1, wavmax0, wavmax1, ndvi;
 
  279     float sipf, sicf, bair, mph0, mph1;
 
  280     float *rhos = l2rec->l1rec->rhos;
 
  282     if ((l2rec->l1rec->l1file->sensorID != 
MERIS) && 
 
  283             (l2rec->l1rec->l1file->sensorID != 
OLCIS3A) &&
 
  284             (l2rec->l1rec->l1file->sensorID != 
OLCIS3B)) {
 
  285         printf(
"MPH not supported for this sensor (%s).\n",
 
  304     if (ib6 < 0 || ib7 < 0 || ib8 < 0 || ib9 < 0 || ib10 < 0 || ib14 < 0) {
 
  305         printf(
"MPH_stumpf: incompatible sensor wavelengths for this algorithm\n");
 
  309     for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
 
  310         ipb = l2rec->l1rec->l1file->nbands*ip;
 
  318         if (rhos[ipb + ib8] > rhos[ipb + ib9]) {
 
  320             Rmax0 = rhos[ipb + ib8];
 
  323             Rmax0 = rhos[ipb + ib9];
 
  325         if (Rmax0 > rhos[ipb + ib10]) {
 
  330             Rmax1 = rhos[ipb + ib10];
 
  334         sipf = rhos[ipb + ib7] - rhos[ipb + ib6] - (rhos[ipb + ib8] - rhos[ipb + ib6]) * (664 - 619) / (681 - 619);
 
  336         sicf = rhos[ipb + ib8] - rhos[ipb + ib7] - (rhos[ipb + ib9] - rhos[ipb + ib7]) * (681 - 664) / (709 - 664);
 
  338         ndvi = (rhos[ipb + ib14] - rhos[ipb + ib7]) / (rhos[ipb + ib14] + rhos[ipb + ib7]);
 
  340         bair = rhos[ipb + ib9] - rhos[ipb + ib7] - (rhos[ipb + ib14] - rhos[ipb + ib7]) * (709 - 664) / (885 - 664);
 
  341         mph0 = Rmax0 - rhos[ipb + ib7] - (rhos[ipb + ib14] - rhos[ipb + ib7]) * (wavmax0 - 664) / (885 - 664);
 
  342         mph1 = Rmax1 - rhos[ipb + ib7] - (rhos[ipb + ib14] - rhos[ipb + ib7]) * (wavmax1 - 664) / (885 - 664);
 
  344         if (wavmax1 != wav10) {
 
  346             if (sicf >= 0 || sipf <= 0 || bair <= 0.002) {
 
  347                 chl_mph[ip] = 5.24e9 * pow(mph0, 4) - 1.95e8 * pow(mph0, 3) + 2.46e6 * pow(mph0, 2) + 4.02e3 * mph0 + 1.97;
 
  349                 chl_mph[ip] = 22.44 * exp(35.79 * mph1);
 
  352             if (mph1 >= 0.02 || ndvi >= 0.2) {
 
  354                 if (sicf < 0 && sipf > 0) {
 
  355                     chl_mph[ip] = 22.44 * exp(35.79 * mph1);
 
  361                 chl_mph[ip] = 5.24e9 * pow(mph0, 4) - 1.95e8 * pow(mph0, 3) + 2.46e6 * pow(mph0, 2) + 4.02e3 * mph0 + 1.97;
 
  377     float wav6, wav7, wav8, wav9, wav10, wav14;
 
  378     int ip, ipb, ib6, ib7, ib8, ib9, ib10, ib14;
 
  379     float Rmax0, Rmax1, wavmax0, wavmax1, ndvi;
 
  380     float sipf, sicf, bair, mph1, chl_mph;
 
  381     float *rhos = l2rec->l1rec->rhos;
 
  382     static float thresh = 350;
 
  384     if ((l2rec->l1rec->l1file->sensorID != 
MERIS) && 
 
  385             (l2rec->l1rec->l1file->sensorID != 
OLCIS3A) &&
 
  386             (l2rec->l1rec->l1file->sensorID != 
OLCIS3B)) {
 
  387         printf(
"MPH not supported for this sensor (%s).\n",
 
  408     if (ib6 < 0 || ib7 < 0 || ib8 < 0 || ib9 < 0 || ib10 < 0 || ib14 < 0) {
 
  409         printf(
"MPH_stumpf: incompatible sensor wavelengths for this algorithm\n");
 
  413     for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
 
  416         ipb = l2rec->l1rec->l1file->nbands*ip;
 
  419         if (l2rec->l1rec->rhos[ipb + ib6] <= 0.0 ||
 
  420                 l2rec->l1rec->rhos[ipb + ib7] <= 0.0 ||
 
  421                 l2rec->l1rec->rhos[ipb + ib8] <= 0.0 ||
 
  422                 l2rec->l1rec->rhos[ipb + ib9] <= 0.0 ||
 
  423                 (l2rec->l1rec->flags[ip] & 
LAND) != 0 ||
 
  424                 (l2rec->l1rec->flags[ip] & 
NAVFAIL) != 0) {
 
  425             l2rec->l1rec->flags[ip] |= 
PRODFAIL;
 
  428             if (rhos[ipb + ib8] > rhos[ipb + ib9]) {
 
  430                 Rmax0 = rhos[ipb + ib8];
 
  433                 Rmax0 = rhos[ipb + ib9];
 
  435             if (Rmax0 > rhos[ipb + ib10]) {
 
  440                 Rmax1 = rhos[ipb + ib10];
 
  444             sipf = rhos[ipb + ib7] - rhos[ipb + ib6] - (rhos[ipb + ib8] - rhos[ipb + ib6]) * (664 - 619) / (681 - 619);
 
  446             sicf = rhos[ipb + ib8] - rhos[ipb + ib7] - (rhos[ipb + ib9] - rhos[ipb + ib7]) * (681 - 664) / (709 - 664);
 
  448             ndvi = (rhos[ipb + ib14] - rhos[ipb + ib7]) / (rhos[ipb + ib14] + rhos[ipb + ib7]);
 
  450             bair = rhos[ipb + ib9] - rhos[ipb + ib7] - (rhos[ipb + ib14] - rhos[ipb + ib7]) * (709 - 664) / (885 - 664);
 
  452             mph1 = Rmax1 - rhos[ipb + ib7] - (rhos[ipb + ib14] - rhos[ipb + ib7]) * (wavmax1 - 664) / (885 - 664);
 
  454             if (wavmax1 != wav10) {
 
  456                 if (sicf < 0 && sipf > 0 && bair > 0.002) {
 
  458                     chl_mph = 22.44 * exp(35.79 * mph1);
 
  459                     if (chl_mph > thresh)
 
  463                 if (mph1 >= 0.02 || ndvi >= 0.2) {
 
  466                     if (sicf < 0 && sipf > 0) {
 
  468                         chl_mph = 22.44 * exp(35.79 * mph1);
 
  469                         if (chl_mph > thresh)
 
  487     int ib443, ib490, ib510, ib560, ib620, ib665, ib681, ib709, ib754, ib865, ib885;
 
  489     float *rhos = l2rec->l1rec->rhos;
 
  490     float mdsi, cv, 
mean, sum, sdev, w681_fac;
 
  495     if (l2rec->l1rec->l1file->sensorID != 
MERIS && 
 
  496             l2rec->l1rec->l1file->sensorID != 
OLCIS3A &&
 
  497             l2rec->l1rec->l1file->sensorID != 
OLCIS3B) {
 
  498         printf(
"HABS flags not supported for this sensor (%s).\n",
 
  515     if (ib443 < 0 || ib490 < 0 || ib510 < 0 || ib560 < 0 || ib620 < 0 || ib665 < 0 || ib681 < 0 || ib709 < 0 || ib754 < 0 || ib865 < 0 || ib885 < 0) {
 
  516         printf(
"get_flags_habs: incompatible sensor wavelengths for this algorithm\n");
 
  520     if (l2rec->l1rec->l1file->sensorID == 
OLCIS3A ||
 
  521         l2rec->l1rec->l1file->sensorID == 
OLCIS3B) {
 
  527     for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
 
  529         ipb = l2rec->l1rec->l1file->nbands*ip;
 
  534             flags_habs[ip] = (uint8_t) l2rec->l1rec->cloud[ip];
 
  541         if (rhos[ipb + ib443] >= 0.0 &&
 
  542             rhos[ipb + ib490] >= 0.0 &&
 
  543             rhos[ipb + ib510] >= 0.0 &&
 
  544             rhos[ipb + ib560] >= 0.0 &&
 
  545             rhos[ipb + ib620] >= 0.0 &&
 
  546             rhos[ipb + ib665] >= 0.0 &&
 
  547             rhos[ipb + ib681] >= 0.0 &&
 
  548             rhos[ipb + ib709] >= 0.0 &&
 
  549             rhos[ipb + ib754] >= 0.0 &&
 
  550             rhos[ipb + ib885] >= 0.0) {
 
  552             if (rhos[ipb + ib885] > rhos[ipb + ib620] &&
 
  553                     rhos[ipb + ib885] > rhos[ipb + ib709] &&
 
  554                     rhos[ipb + ib885] > rhos[ipb + ib754] &&
 
  555                     rhos[ipb + ib885] > 0.01) {
 
  560             if ((rhos[ipb + ib620] > rhos[ipb + ib560]) &&
 
  561                 (rhos[ipb + ib560] > 0.15) &&
 
  562                 (rhos[ipb + ib885] > 0.15)){
 
  567             mdsi = (rhos[ipb + ib865] - rhos[ipb + ib885]) / (rhos[ipb + ib865] + rhos[ipb + ib885]);
 
  570             int b[7] = {ib443, ib490, ib510, ib560, ib620, ib665, ib681};
 
  572             for(
i = 0; 
i < n; ++
i) {
 
  573                 sum += rhos[ipb + 
b[
i]];
 
  578             for(
i = 0; 
i < n; ++
i) {
 
  579                 sdev += pow((rhos[ipb + 
b[
i]] - 
mean),2);
 
  581             cv = sqrt(sdev / (n - 1)) / 
mean;
 
  583             if ((mdsi > 0.01) && (rhos[ipb + ib885] > 0.15) && (cv < 0.1)) {
 
  587             float mci = 1.0 * (rhos[ipb + ib709] - rhos[ipb + ib681]*w681_fac
 
  588                 + (rhos[ipb + ib681]*w681_fac - rhos[ipb + ib754])*(709 - 681) / (754 - 681));
 
  589             float ci = 1.0 * ((rhos[ipb + ib709] - rhos[ipb + ib665])*(681 - 665) / (709 - 665)
 
  590                 - (rhos[ipb + ib681]*w681_fac - rhos[ipb + ib665]));
 
  593                     rhos[ipb + ib560], rhos[ipb + ib620],
 
  594                     rhos[ipb + ib665], rhos[ipb + ib709],
 
  595                     rhos[ipb + ib865], rhos[ipb + ib885], &ci);
 
  597             if ((mci < 0) && (ci > 0)) {
 
  601             if (rhos[ipb + ib620] < 0.0 ||
 
  602                 rhos[ipb + ib665] < 0.0 ||
 
  603                 rhos[ipb + ib681] < 0.0 ||
 
  604                 rhos[ipb + ib709] < 0.0) {
 
  615     int ib469, ib555, ib645, ib667, ib859, ib1240, ib2130;
 
  617     float *rhos = l2rec->l1rec->rhos, *
Rrs = l2rec->Rrs, *cloud_albedo = l2rec->l1rec->cloud_albedo;
 
  618     float ftemp, ftemp2, ftemp3;
 
  619     float cloudthr = 0.027;
 
  623     if (l2rec->l1rec->l1file->sensorID != 
MODISA && l2rec->l1rec->l1file->sensorID != 
MODIST) {
 
  624         printf(
"HABS flags not supported for this sensor (%s).\n",
 
  637     if (ib469 < 0 || ib555 < 0 || ib645 < 0 || ib667 < 0 || ib859 < 0 || ib1240 < 0 || ib2130 < 0) {
 
  638         printf(
"get_flags_habs: incompatible sensor wavelengths for this algorithm\n");
 
  642     for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
 
  644         ipb = l2rec->l1rec->l1file->nbands*ip;
 
  648         if (l2rec->chl[ip] < 0)
 
  649             ftemp = 
Rrs[ipb + ib667];
 
  651             ftemp = 
Rrs[ipb + ib667]*(0.45 + l2rec->chl[ip]*0.005) / 4.3;
 
  653         if (
Rrs[ipb + ib667] < 0.0) ftemp = 0.0;
 
  654         ftemp2 = cloud_albedo[ip] - ftemp;
 
  656         if (ftemp2 > 0.027) flags_habs[ip] |= 
HABS_CLOUD;
 
  660         if (rhos[ipb + ib1240] / rhos[ipb + ib859] > 0.5 && (rhos[ipb + ib1240] + rhos[ipb + ib2130]) > 0.10) flags_habs[ip] |= 
HABS_CLOUD;
 
  665         ftemp = rhos[ipb + ib645] - rhos[ipb + ib555] + (rhos[ipb + ib555] - rhos[ipb + ib859])*(645.0 - 555.0) / (859.0 - 555.0);
 
  666         ftemp2 = cloud_albedo[ip] + ftemp;
 
  667         if (ftemp2 < cloudthr) flags_habs[ip] = 0;
 
  668         if (rhos[ipb + ib859] / rhos[ipb + ib1240] > 4.0) flags_habs[ip] = 0;
 
  672         if ((rhos[ipb + ib859] - rhos[ipb + ib469]) > 0.01 && cloud_albedo[ip] < 0.30) flags_habs[ip] = 0;
 
  673         if ((rhos[ipb + ib859] - rhos[ipb + ib645]) > 0.01 && cloud_albedo[ip] < 0.15) flags_habs[ip] = 0;
 
  674         if (rhos[ipb + ib1240] < 0.2)
 
  675             ftemp2 = ftemp2 - (rhos[ipb + ib859] - rhos[ipb + ib1240]) * 
fabs(rhos[ipb + ib859] - rhos[ipb + ib1240]) / cloudthr;
 
  678         if (ftemp2 < cloudthr * 2) {
 
  679             if ((rhos[ipb + ib555] - rhos[ipb + ib1240]) > (rhos[ipb + ib469] - rhos[ipb + ib1240])) {
 
  680                 ftemp3 = ftemp2 - (rhos[ipb + ib555] - rhos[ipb + ib1240]);
 
  682                 ftemp3 = ftemp2 - (rhos[ipb + ib469] - rhos[ipb + ib1240]);
 
  686         if (ftemp3 < cloudthr) flags_habs[ip] = 0;
 
  688         if (rhos[ipb + ib555] >= 0 && rhos[ipb + ib1240] >= 0.0 && rhos[ipb + ib1240] > rhos[ipb + ib555])
 
  695     static int32_t currentLine = -1;
 
  697     if (currentLine == l2rec->l1rec->iscan )
 
  699     currentLine = l2rec->l1rec->iscan;
 
  700     switch (l2rec->l1rec->l1file->sensorID) {
 
  711         printf(
"HABS flags not supported for this sensor (%s).\n",