bool Sr(Lut_t *lut, int nsamp, int il, int16 **line_in, int16 **line_out, Sr_stats_t *sr_stats) { int is; bool is_fill; int ib; Img_coord_int_t loc; float rho,tmpflt; atmos_t interpol_atmos_coef; allocate_mem_atmos_coeff(1,&interpol_atmos_coef); loc.l = il; for (is = 0; is < nsamp; is++) { loc.s = is; is_fill = false; /* NAZMI 6/2/04 : correct even cloudy pixels */ SrInterpAtmCoef(lut, &loc, &atmos_coef,&interpol_atmos_coef); for (ib = 0; ib < lut->nband; ib++) { if (line_in[ib][is] == lut->in_fill) { is_fill = true; line_out[ib][is] = lut->output_fill; sr_stats->nfill[ib]++; } else { /* BEGIN introduce correction to handle saturated data Fri-Sep-11-17:49:35-EDT-2009 EV */ if (line_in[ib][is] != lut->max_valid_sr) { rho=(float)line_in[ib][is]/10000.; rho=(rho/interpol_atmos_coef.tgOG[ib][0]-interpol_atmos_coef.rho_ra[ib][0]); tmpflt=(interpol_atmos_coef.tgH2O[ib][0]*interpol_atmos_coef.td_ra[ib][0]*interpol_atmos_coef.tu_ra[ib][0]); rho /= tmpflt; rho /= (1.+interpol_atmos_coef.S_ra[ib][0]*rho); line_out[ib][is] = (short)(rho*10000.); } else { line_out[ib][is] = lut->max_valid_sr; } /* END introduce correction to handle saturated data Fri-Sep-11-17:49:35-EDT-2009 EV */ if (line_out[ib][is] < lut->min_valid_sr) { sr_stats->nout_range[ib]++; line_out[ib][is] = lut->min_valid_sr; } if (line_out[ib][is] > lut->max_valid_sr) { sr_stats->nout_range[ib]++; line_out[ib][is] = lut->max_valid_sr; } } if (is_fill) continue; if (sr_stats->first[ib]) { sr_stats->sr_min[ib] = sr_stats->sr_max[ib] = line_out[ib][is]; sr_stats->first[ib] = false; } else { if (line_out[ib][is] < sr_stats->sr_min[ib]) sr_stats->sr_min[ib] = line_out[ib][is]; if (line_out[ib][is] > sr_stats->sr_max[ib]) sr_stats->sr_max[ib] = line_out[ib][is]; } } } free_mem_atmos_coeff(&interpol_atmos_coef); return true; }
bool cloud_detection_pass1(Lut_t *lut, int nsamp, int il, int **line_in, int8 *qa_line, int *b6_line,float *atemp_line, cld_diags_t *cld_diags) { int is; bool is_fill, not_fill; int ib; Img_coord_int_t loc; float tmpflt; float rho1,rho3,rho4,rho5,rho7,t6; atmos_t interpol_atmos_coef; int C1,C1p,C2,C2p,C3,C3p,C4,C5,water; int cld_row,cld_col; float vra,ndvi; allocate_mem_atmos_coeff(1,&interpol_atmos_coef); loc.l = il; cld_row=il/cld_diags->cellheight; for (is = 0; is < nsamp; is++) { loc.s = is; cld_col=is/cld_diags->cellwidth; /* if ((line_in[0][is]== lut->in_fill) || (line_in[1][is]== lut->in_fill) || (line_in[2][is]== lut->in_fill) || (line_in[3][is]== lut->in_fill) || (line_in[4][is]== lut->in_fill) || (line_in[5][is]== lut->in_fill) || (b6_line[is]== lut->in_fill)) */ if ((qa_line[is]&0x01)==0x01) is_fill=true; else is_fill=false; if (! is_fill) { if (((qa_line[is]&0x08)==0x00)||((lut->meta.inst==INST_TM)&&(line_in[2][is]<5000))) { /* no saturation in band 3 */ SrInterpAtmCoef(lut, &loc, &atmos_coef, &interpol_atmos_coef); rho1=line_in[0][is]/10000.; rho1=(rho1/interpol_atmos_coef.tgOG[0][0]-interpol_atmos_coef.rho_ra[0][0]); tmpflt=(interpol_atmos_coef.tgH2O[0][0]*interpol_atmos_coef.td_ra[0][0]*interpol_atmos_coef.tu_ra[0][0]); rho1 /= tmpflt; rho1 /= (1.+interpol_atmos_coef.S_ra[0][0]*rho1); rho3=line_in[2][is]/10000.; rho3=(rho3/interpol_atmos_coef.tgOG[2][0]-interpol_atmos_coef.rho_ra[2][0]); tmpflt=(interpol_atmos_coef.tgH2O[2][0]*interpol_atmos_coef.td_ra[2][0]*interpol_atmos_coef.tu_ra[2][0]); rho3 /= tmpflt; rho3 /= (1.+interpol_atmos_coef.S_ra[2][0]*rho3); rho4=line_in[3][is]/10000.; rho4=(rho4/interpol_atmos_coef.tgOG[3][0]-interpol_atmos_coef.rho_ra[3][0]); tmpflt=(interpol_atmos_coef.tgH2O[3][0]*interpol_atmos_coef.td_ra[3][0]*interpol_atmos_coef.tu_ra[3][0]); rho4 /= tmpflt; rho4 /= (1.+interpol_atmos_coef.S_ra[3][0]*rho4); rho5=line_in[4][is]/10000.; rho5=(rho5/interpol_atmos_coef.tgOG[4][0]-interpol_atmos_coef.rho_ra[4][0]); tmpflt=(interpol_atmos_coef.tgH2O[4][0]*interpol_atmos_coef.td_ra[4][0]*interpol_atmos_coef.tu_ra[4][0]); rho5 /= tmpflt; rho5 /= (1.+interpol_atmos_coef.S_ra[4][0]*rho5); rho7=line_in[5][is]/10000.; rho7=(rho7/interpol_atmos_coef.tgOG[5][0]-interpol_atmos_coef.rho_ra[5][0]); tmpflt=(interpol_atmos_coef.tgH2O[5][0]*interpol_atmos_coef.td_ra[5][0]*interpol_atmos_coef.tu_ra[5][0]); rho7 /= tmpflt; rho7 /= (1.+interpol_atmos_coef.S_ra[5][0]*rho7); t6=b6_line[is]/100.+273.; vra=rho1-rho3/2; C1=(int)(vra>VRA_THRESHOLD); C1p=!C1; /* C2=(t6 < (atemp_line[is]-10.)); C2p=(t6 > (atemp_line[is]-10.)); */ C2=(t6 < (atemp_line[is]-7.)); C2p=(t6 > (atemp_line[is]-7.)); tmpflt=rho4/rho3; C3=((tmpflt>=0.9)&&(tmpflt<=1.3)); C3p=!C3; C4=(rho7 > 0.03); C5=((rho3 > 0.6)||(rho4 > 0.6)); /** Water test : ndvi < 0 => water ((0<ndvi<0.1) or (b4<5%)) and b5 < 0.01 => turbid water **/ if ((rho4+rho3) != 0) ndvi=(rho4-rho3)/(rho4+rho3); else ndvi=0.01; water=(ndvi < 0)||((((ndvi>0)&&(ndvi<0.1))||(rho4<0.05))&&(rho5<0.02)); if (is_check_pixel(is,il)) { printf( " cld_pass1(%d,%d): water=%d, C1=%d,C2=%d,C3=%d,atemp=%.15g\n", is, il, water, C1, C2, C3, atemp_line[is] ); printf( " ndvi=%g, rho4=%g, rho5=%g\n", ndvi, rho4, rho5 ); printf( " line_in=%d, tgOG=%g, rho_ra=%g, tu_ra=%g, td_ra=%g, tgH2O=%g\n", line_in[0][is], interpol_atmos_coef.tgOG[0][0], interpol_atmos_coef.rho_ra[0][0], interpol_atmos_coef.tu_ra[0][0], interpol_atmos_coef.td_ra[0][0], interpol_atmos_coef.tgH2O[0][0]); } if (!water) { /* if not water */ if ((t6 > (atemp_line[is]-20.)) && (!C5)) { if (!((C1||C3)&&C2&&C4)) { /* clear */ cld_diags->avg_t6_clear[cld_row][cld_col] += t6; cld_diags->std_t6_clear[cld_row][cld_col] += (t6*t6); cld_diags->avg_b7_clear[cld_row][cld_col] += rho7; cld_diags->std_b7_clear[cld_row][cld_col] += (rho7*rho7); cld_diags->nb_t6_clear[cld_row][cld_col] ++; } } } } } } free_mem_atmos_coeff(&interpol_atmos_coef); return true; }
bool Sr(Lut_t *lut, int nsamp, int il, int **line_in, bool mask_flag, char* mask_line, int **line_out, Sr_stats_t *sr_stats) { int is; bool is_fill, not_fill; int ib; int iband_ar; Img_coord_int_t loc; float rho,tmpflt; int i_aot,j_aot,ipt; atmos_t interpol_atmos_coef; allocate_mem_atmos_coeff(1,&interpol_atmos_coef); iband_ar = lut->nband; loc.l = il; i_aot=il/lut->ar_region_size.l; for (is = 0; is < nsamp; is++) { loc.s = is; j_aot=is/lut->ar_region_size.s; ipt=i_aot*lut->ar_size.s+j_aot; not_fill = true; for (ib = 0; ib < lut->nband; ib++) { if (line_in[ib][is] == lut->in_fill) { not_fill = false; break; } } /* if (not_fill) / * line_out[iband_ar][is] = ArInterp(lut, &loc, line_ar); * / line_out[iband_ar][is] = line_ar[i_aot][j_aot]; else line_out[iband_ar][is] = lut->aerosol_fill; */ /* if (not_fill) { for (ib = 0; ib < lut->nband; ib++) { if (line_in[ib][is] == lut->in_fill) { is_fill = true; line_out[ib][is] = lut->output_fill; sr_stats->nfill[ib]++; } else line_out[ib][is] = line_in[ib][is]; } sr_stats->nfill[iband_ar]++; continue; } else { if (sr_stats->first[iband_ar]) { sr_stats->sr_min[iband_ar] = sr_stats->sr_max[iband_ar] = line_out[iband_ar][is]; sr_stats->first[iband_ar] = false; } else { if (line_out[iband_ar][is] < sr_stats->sr_min[iband_ar]) sr_stats->sr_min[iband_ar] = line_out[iband_ar][is]; if (line_out[iband_ar][is] > sr_stats->sr_max[iband_ar]) sr_stats->sr_max[iband_ar] = line_out[iband_ar][is]; } } */ is_fill = false; /* NAZMI 6/2/04 : correct even cloudy pixels if ( mask_flag && ( mask_line[is]==lut->cloud_snow || mask_line[is]==lut->cloud_cloud ) )is_fill= true; */ SrInterpAtmCoef(lut, &loc, &atmos_coef,&interpol_atmos_coef); /* TODO(warmerdam): debugging */ if (is_check_pixel(is,il)) { printf( "\n DEBUG(Sr) cp=%d:\n", is_check_pixel(is,il)); } for (ib = 0; ib < lut->nband; ib++) { if (line_in[ib][is] == lut->in_fill) { is_fill = true; line_out[ib][is] = lut->output_fill; sr_stats->nfill[ib]++; } else { /* BEGIN introduce correction to handle saturated data Fri-Sep-11-17:49:35-EDT-2009 EV */ if (line_in[ib][is] != lut->max_valid_sr) { rho=(float)line_in[ib][is]/10000.; rho=(rho/interpol_atmos_coef.tgOG[ib][0]-interpol_atmos_coef.rho_ra[ib][0]); tmpflt=(interpol_atmos_coef.tgH2O[ib][0]*interpol_atmos_coef.td_ra[ib][0]*interpol_atmos_coef.tu_ra[ib][0]); rho /= tmpflt; rho /= (1.+interpol_atmos_coef.S_ra[ib][0]*rho); line_out[ib][is] = (short)(rho*10000.); } else { line_out[ib][is] = lut->max_valid_sr; } /* END introduce correction to handle saturated data Fri-Sep-11-17:49:35-EDT-2009 EV */ if (line_out[ib][is] < lut->min_valid_sr) { sr_stats->nout_range[ib]++; line_out[ib][is] = lut->min_valid_sr; } if (line_out[ib][is] > lut->max_valid_sr) { sr_stats->nout_range[ib]++; line_out[ib][is] = lut->max_valid_sr; } } /* TODO(warmerdam): debugging */ if (is_check_pixel(is,il)) { printf( " ib=%d, in=%d, out=%d\n", ib, line_in[ib][is], line_out[ib][is] ); report_atmos_coef( &interpol_atmos_coef, ib, 0 ); } if (is_fill) continue; if (sr_stats->first[ib]) { sr_stats->sr_min[ib] = sr_stats->sr_max[ib] = line_out[ib][is]; sr_stats->first[ib] = false; } else { if (line_out[ib][is] < sr_stats->sr_min[ib]) sr_stats->sr_min[ib] = line_out[ib][is]; if (line_out[ib][is] > sr_stats->sr_max[ib]) sr_stats->sr_max[ib] = line_out[ib][is]; } } } free_mem_atmos_coeff(&interpol_atmos_coef); return true; }
bool cloud_detection_pass2(Lut_t *lut, int nsamp, int il, int **line_in, int8 *qa_line, int *b6_line, cld_diags_t *cld_diags,char *ddv_line) { /** use ddv_line to store internal cloud screening info bit 2 = adjacent cloud 1=yes 0=no bit 3 = fill value 1=fill 0=valid bit 4 = land/water mask 1=land 0=water bit 5 = cloud 0=clear 1=cloudy bit 6 = cloud shadow bit 7 = snow **/ int is; int il_ar,is_ar; bool is_fill, not_fill,thermal_band; int ib; Img_coord_int_t loc; float rho1,rho2,rho3,rho4,rho5,rho7,t6; atmos_t interpol_atmos_coef; int C1,C1p,C2,C2p,C3,C3p,C4,C5,water; int cld_row,cld_col; float vra,ndvi,ndsi,temp_snow_thshld; float temp_b6_clear,temp_thshld1,temp_thshld2,avg_b7_clear,atemp_ancillary; float tmpflt,tmpflt_arr[10]; thermal_band=true; if (b6_line == NULL) thermal_band=false; temp_snow_thshld=380.; /* now flag snow and possibly salt pan */ allocate_mem_atmos_coeff(1,&interpol_atmos_coef); loc.l = il; cld_row=il/cld_diags->cellheight; il_ar=il/lut->ar_region_size.l; if (il_ar >= lut->ar_size.l) il_ar=lut->ar_size.l-1; for (is = 0; is < nsamp; is++) { if (is_check_pixel(is, il)) { printf( "cloud_detection_pass2(%d,%d): line_in=%d,%d,%d,%d,%d, qa=%d, b6=%d, ddv=%x\n", is, il, line_in[0][is], line_in[1][is], line_in[2][is], line_in[3][is], line_in[4][is], qa_line[is], b6_line[is], ddv_line[is] ); } loc.s = is; cld_col=is/cld_diags->cellwidth; is_ar=is/lut->ar_region_size.s; if (is_ar >= lut->ar_size.s) is_ar=lut->ar_size.s-1; is_fill=false; if (thermal_band) { if (b6_line[is]== lut->in_fill) { is_fill=true; ddv_line[is] = 0x08; } } /* if ((line_in[0][is]== lut->in_fill) || (line_in[1][is]== lut->in_fill) || (line_in[2][is]== lut->in_fill) || (line_in[3][is]== lut->in_fill) || (line_in[4][is]== lut->in_fill) || (line_in[5][is]== lut->in_fill)) { */ if ((qa_line[is]&0x01)==0x01) { is_fill=true; ddv_line[is] = 0x08; } if (! is_fill) { ddv_line[is] &= 0x44; /* reset all bits except cloud shadow and adjacent cloud */ if (((qa_line[is]&0x08)==0x08)||((lut->meta.inst==INST_TM)&&(line_in[2][is]>=5000))) { /* saturated band 3 */ if (thermal_band) { t6=b6_line[is]/100.+273.; interpol_clddiags_1pixel(cld_diags, il,is,tmpflt_arr); temp_b6_clear=tmpflt_arr[0]; avg_b7_clear=tmpflt_arr[1]; atemp_ancillary=tmpflt_arr[2]; if (temp_b6_clear < 0.) { temp_thshld1=atemp_ancillary-20.; temp_thshld2=atemp_ancillary-20.; } else { if (cld_diags->std_t6_clear[cld_row][cld_col] > 0.) { temp_thshld1=temp_b6_clear-(cld_diags->std_t6_clear[cld_row][cld_col]+4.); temp_thshld2=temp_b6_clear-(cld_diags->std_t6_clear[cld_row][cld_col]); } else { temp_thshld1=temp_b6_clear-4.; temp_thshld2=temp_b6_clear-2.; } } if ((((qa_line[is]&0x20)==0x20)||((lut->meta.inst==INST_TM)&&(line_in[4][is]>=5000)))&&(t6 < temp_thshld1)) { /* saturated band 5 and t6 < threshold => cloudy */ ddv_line[is] &= 0xbf; /* reset shadow bit */ ddv_line[is] &= 0xfb; /* reset adjacent cloud bit */ ddv_line[is] |= 0x20; /* set cloud bit */ } else if ((line_in[4][is]<2000)&&(t6 < temp_snow_thshld)) { /* snow */ ddv_line[is] |= 0x80; } else { /* asuume cloudy */ ddv_line[is] &= 0xbf; /* reset shadow bit */ ddv_line[is] &= 0xfb; /* reset adjacent cloud bit */ ddv_line[is] |= 0x20; /* set cloud bit */ } } } else { SrInterpAtmCoef(lut, &loc, &atmos_coef, &interpol_atmos_coef); rho1=line_in[0][is]/10000.; rho1=(rho1/interpol_atmos_coef.tgOG[0][0]-interpol_atmos_coef.rho_ra[0][0]); tmpflt=(interpol_atmos_coef.tgH2O[0][0]*interpol_atmos_coef.td_ra[0][0]*interpol_atmos_coef.tu_ra[0][0]); rho1 /= tmpflt; rho1 /= (1.+interpol_atmos_coef.S_ra[0][0]*rho1); rho2=line_in[1][is]/10000.; rho2=(rho2/interpol_atmos_coef.tgOG[1][0]-interpol_atmos_coef.rho_ra[1][0]); tmpflt=(interpol_atmos_coef.tgH2O[1][0]*interpol_atmos_coef.td_ra[1][0]*interpol_atmos_coef.tu_ra[1][0]); rho2 /= tmpflt; rho2 /= (1.+interpol_atmos_coef.S_ra[1][0]*rho2); rho3=line_in[2][is]/10000.; rho3=(rho3/interpol_atmos_coef.tgOG[2][0]-interpol_atmos_coef.rho_ra[2][0]); tmpflt=(interpol_atmos_coef.tgH2O[2][0]*interpol_atmos_coef.td_ra[2][0]*interpol_atmos_coef.tu_ra[2][0]); rho3 /= tmpflt; rho3 /= (1.+interpol_atmos_coef.S_ra[2][0]*rho3); rho4=line_in[3][is]/10000.; rho4=(rho4/interpol_atmos_coef.tgOG[3][0]-interpol_atmos_coef.rho_ra[3][0]); tmpflt=(interpol_atmos_coef.tgH2O[3][0]*interpol_atmos_coef.td_ra[3][0]*interpol_atmos_coef.tu_ra[3][0]); rho4 /= tmpflt; rho4 /= (1.+interpol_atmos_coef.S_ra[3][0]*rho4); rho5=line_in[4][is]/10000.; rho5=(rho5/interpol_atmos_coef.tgOG[4][0]-interpol_atmos_coef.rho_ra[4][0]); tmpflt=(interpol_atmos_coef.tgH2O[4][0]*interpol_atmos_coef.td_ra[4][0]*interpol_atmos_coef.tu_ra[4][0]); rho5 /= tmpflt; rho5 /= (1.+interpol_atmos_coef.S_ra[4][0]*rho5); rho7=line_in[5][is]/10000.; rho7=(rho7/interpol_atmos_coef.tgOG[5][0]-interpol_atmos_coef.rho_ra[5][0]); tmpflt=(interpol_atmos_coef.tgH2O[5][0]*interpol_atmos_coef.td_ra[5][0]*interpol_atmos_coef.tu_ra[5][0]); rho7 /= tmpflt; rho7 /= (1.+interpol_atmos_coef.S_ra[5][0]*rho7); if (thermal_band) t6=b6_line[is]/100.+273.; interpol_clddiags_1pixel(cld_diags, il,is,tmpflt_arr); temp_b6_clear=tmpflt_arr[0]; /* printf("temp_b6_clear %f\n",temp_b6_clear);*/ avg_b7_clear=tmpflt_arr[1]; atemp_ancillary=tmpflt_arr[2]; if (temp_b6_clear < 0.) { temp_thshld1=atemp_ancillary-20.; temp_thshld2=atemp_ancillary-20.; } else { /** temp_thshld1=temp_b6_clear-5.; temp_thshld2=temp_b6_clear-5.; **/ if (cld_diags->std_t6_clear[cld_row][cld_col] > 0.) { temp_thshld1=temp_b6_clear-(cld_diags->std_t6_clear[cld_row][cld_col]+4.); temp_thshld2=temp_b6_clear-(cld_diags->std_t6_clear[cld_row][cld_col]); /*EV add the two following lines on 5-21/-07 and commented them on 5-22-07*/ /* temp_thshld1=temp_b6_clear+(cld_diags->std_t6_clear[cld_row][cld_col]+4.); temp_thshld2=temp_b6_clear+(cld_diags->std_t6_clear[cld_row][cld_col]); */ } else { temp_thshld1=temp_b6_clear-4.; temp_thshld2=temp_b6_clear-2.; } } if (thermal_band) { vra=rho1-rho3/2.; C1=(int)(vra>VRA_THRESHOLD); C1p=!C1; C2=(t6 < temp_thshld1); C2p=(t6 > temp_thshld1); tmpflt=rho4/rho3; C3=((tmpflt>=0.9)&&(tmpflt<=1.2)); C3p=!C3; C4=(rho7 > 0.03); C5=(t6 < temp_thshld2)&&C1; } /* printf ("PASS2: T6=%f THRESH=%f R7=%f C2=%d C4=%d\n",t6,temp_thshld1,rho7,C2,C4); */ /** Water test : ndvi < 0 => water ((0<ndvi<0.1) or (b4<5%)) and b5 < 0.01 => turbid water **/ if ((rho4+rho3) != 0) ndvi=(rho4-rho3)/(rho4+rho3); else ndvi=0.01; water=(ndvi < 0)||((((ndvi>0)&&(ndvi<0.1))||(rho4<0.05))&&(rho5<0.02)); if (is_check_pixel(is, il)) { printf(" rho=%.15g,%.15g,%.15g,%.15g,%.15g,%.15g\n", rho1, rho2, rho3, rho4, rho5, rho7 ); printf(" atemp_ancillary=%.15g, temp_b6_clean=%.15g, avg_b7_clear=%.15g\n", atemp_ancillary, temp_b6_clear, avg_b7_clear); } if (thermal_band) { if (!water) { /* if not water */ ddv_line[is] |= 0x10; if ((C2||C5)&&C4) { /* cloudy */ ddv_line[is] &= 0xbf; /* reset shadow bit */ ddv_line[is] &= 0xfb; /* reset adjacent cloud bit */ ddv_line[is] |= 0x20; /* set cloud bit */ } else { /* clear */ ddv_line[is] &= 0xdf; ndsi=(rho2-rho5)/(rho2+rho5); if ((ndsi > 0.3)&&(t6 < temp_snow_thshld)&&(rho4 > 0.2)) ddv_line[is] |= 0x80; } } else ddv_line[is] &= 0xef; } else { /* no thermal band - cannot run cloud mask */ ddv_line[is] &= 0xdf; /* assume clear */ if (!water) { /* if not water */ ddv_line[is] |= 0x10; } else { ddv_line[is] &= 0xef; } } } } } free_mem_atmos_coeff(&interpol_atmos_coef); return true; }