[GRASS-SVN] r32350 - in grass-addons/gipe: . i.qc.modis
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Jul 28 03:47:54 EDT 2008
Author: ychemin
Date: 2008-07-28 03:47:54 -0400 (Mon, 28 Jul 2008)
New Revision: 32350
Added:
grass-addons/gipe/i.qc.modis/
grass-addons/gipe/i.qc.modis/Makefile
grass-addons/gipe/i.qc.modis/description.html
grass-addons/gipe/i.qc.modis/main.c
grass-addons/gipe/i.qc.modis/qc250a.c
grass-addons/gipe/i.qc.modis/qc250b.c
grass-addons/gipe/i.qc.modis/qc250c.c
grass-addons/gipe/i.qc.modis/qc250d.c
grass-addons/gipe/i.qc.modis/qc250e.c
grass-addons/gipe/i.qc.modis/qc250f.c
grass-addons/gipe/i.qc.modis/qc500a.c
grass-addons/gipe/i.qc.modis/qc500c.c
grass-addons/gipe/i.qc.modis/qc500d.c
grass-addons/gipe/i.qc.modis/qc500e.c
Log:
Added MODIS QC extractor
Added: grass-addons/gipe/i.qc.modis/Makefile
===================================================================
--- grass-addons/gipe/i.qc.modis/Makefile (rev 0)
+++ grass-addons/gipe/i.qc.modis/Makefile 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,14 @@
+MODULE_TOPDIR = ../..
+
+PGM = i.qc.modis
+
+LIBES = $(GISLIB)
+DEPENDENCIES = $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+ifneq ($(USE_LARGEFILES),)
+ EXTRA_CFLAGS = -D_FILE_OFFSET_BITS=64
+endif
+
+default: cmd
Added: grass-addons/gipe/i.qc.modis/description.html
===================================================================
--- grass-addons/gipe/i.qc.modis/description.html (rev 0)
+++ grass-addons/gipe/i.qc.modis/description.html 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,63 @@
+<H2>DESCRIPTION</H2>
+
+<EM>i.qc.modis</EM> Extracts Requested Quality Assessment flags from Modis 09 A and Q products.
+
+<EM>MODLAND QA Bits 250m/500m bits[0-1]</EM>
+[00]= class 1: Corrected product produced at ideal quality -- all bands
+[01]= class 2: Corrected product produced at less than idel quality -- some or all bands
+[10]= class 3: Corrected product NOT produced due to cloud effect -- all bands
+[11]= class 4: Corrected product NOT produced due to other reasons -- some or all bands maybe be fill value (Note that a value of [11] overrides a value of [01])
+
+<EM> Cloud State 250m Unsigned Int bits[2-3] </EM>
+[00]= class 1: Clear -- No clouds
+[01]= class 2: Cloudy
+[10]= class 3: Mixed
+[11]= class 4: Not Set ; Assumed Clear
+
+<EM> Band-wise Data Quality 250m Unsigned Int bits[4-7][8-11]</EM>
+<EM> Band-wise Data Quality 500m long Int bits[2-5][6-9][10-13][14-17][18-21][22-25][26-29]</EM>
+[0000]= class 1: highest quality
+[0111]= class 2: noisy detector
+[1000]= class 3: dead detector; data interpolated in L1B
+[1001]= class 4: solar zenith ge 86 degrees
+[1010]= class 5: solar zenith ge 85 and lt 86 degrees
+[1011]= class 6: missing input
+[1100] class 7: internal constant used in place of climatological data for at least one atmospheric constant
+[1101]= class 8: correction out of bounds, pixel constrained to extreme allowable value
+[1110]= class 9: L1B data faulty
+[1111]= class 10: not processed due to deep ocean or cloud
+Class 11: Combination of bits unused
+
+<EM>Atmospheric correction 250m/500m bit[12]/[30]</EM>
+[00]= class 1: Not Corrected product
+[01]= class 2: Corrected product
+
+<EM>Adjacency correction 250m/500m bit[13][31]</EM>
+[00]= class 1: Not Corrected product
+[01]= class 2: Corrected product
+
+<EM>Different orbit from 500m product, 250m Unsigned Int bit[14]</EM>
+[00]= class 1: same orbit as 500m
+[01]= class 2: different orbit from 500m
+
+
+
+<H2>NOTES</H2>
+
+
+<H2>TODO</H2>
+Testing is required.
+
+<H2>SEE ALSO</H2>
+
+<em>
+<A HREF="i.vi.html">i.vi</A><br>
+</em>
+
+
+<H2>AUTHORS</H2>
+Yann Chemin, International Rice Research Institute, The Philippines.<BR>
+
+
+<p>
+<i>Last changed: $Date: 2008/07/28 15:33:42 $</i>
Added: grass-addons/gipe/i.qc.modis/main.c
===================================================================
--- grass-addons/gipe/i.qc.modis/main.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/main.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,264 @@
+/****************************************************************************
+ *
+ * MODULE: i.qc.modis
+ * AUTHOR(S): Yann Chemin - yann.chemin at gmail.com
+ * PURPOSE: Converts Quality Control indicators into human readable classes
+ * for Modis surface reflectance products 250m/500m
+ * (MOD09Q/MOD09A)
+ *
+ * COPYRIGHT: (C) 2008 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+/* 250m Products (MOD09Q) */
+int qc250a( unsigned int pixel );
+int qc250b( unsigned int pixel );
+int qc250c( unsigned int pixel, int bandno );
+int qc250d( unsigned int pixel );
+int qc250e( unsigned int pixel );
+int qc250f( unsigned int pixel );
+
+/* 500m Products (MOD09A) */
+int qc500a( long int pixel );
+int qc500c( long int pixel, int bandno );
+int qc500d( long int pixel );
+int qc500e( long int pixel );
+
+
+int main(int argc, char *argv[])
+{
+ struct Cell_head cellhd; //region+header info
+ char *mapset; // mapset name
+ int nrows, ncols;
+ int row,col;
+
+ char *qcflag;// Switch for particular index
+
+ struct GModule *module;
+ struct Option *input1, *input2, *input_band, *output;
+
+ struct Flag *flag1, *flag2;
+ struct History history; //metadata
+ struct Colors colors; //Color rules
+ /************************************/
+ /* FMEO Declarations*****************/
+ char *name; // input raster name
+ char *result; //output raster name
+ //File Descriptors
+ int infd;
+ int outfd;
+
+ char *qcchan;
+ int bandno;
+
+ int i=0,j=0;
+
+ void *inrast;
+ CELL *outrast;
+ RASTER_MAP_TYPE data_type_output=CELL_TYPE;
+ RASTER_MAP_TYPE data_type_qcchan;
+
+ /************************************/
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+ module->keywords = _("QC, Quality Control, surface reflectance, Modis");
+ module->description = _("Extract quality control parameters from Modis QC layers");
+
+ /* Define the different options */
+ input1 = G_define_option() ;
+ input1->key =_("qcname");
+ input1->type = TYPE_STRING;
+ input1->required = YES;
+ input1->gisprompt =_("Name of QC type to extract");
+ input1->description=_("Name of QC: modland_qa_bits, cloud, data_quality, atcorr, adjcorr, diff_orbit_from_500m");
+ input1->answer =_("modland_qa_bits");
+
+ input2 = G_define_standard_option(G_OPT_R_INPUT) ;
+ input2->key = _("input");
+ input2->description=_("Name of the surface reflectance QC map [bit array]");
+ input2->answer =_("qcchan");
+
+ input_band = G_define_option();
+ input_band->key = "band";
+ input_band->type = TYPE_INTEGER;
+ input_band->required = NO;
+ input_band->gisprompt = "old,value";
+ input_band->description = _("Band number of Modis product 250m=[1,2],500m=[1-7]");
+
+ output= G_define_standard_option(G_OPT_R_OUTPUT) ;
+ output->key =_("output");
+ output->description=_("Name of the output QC type classification layer");
+ output->answer =_("qc");
+
+ flag1 = G_define_flag() ;
+ flag1->key = 'A' ;
+ flag1->description = _("QC for MOD09A product @ 500m instead of default MOD09Q at 250m") ;
+
+ /********************/
+ if (G_parser(argc, argv))
+ exit (EXIT_FAILURE);
+ qcflag = input1->answer;
+ qcchan = input2->answer;
+
+ if(input_band->answer){
+ bandno = atoi(input_band->answer);
+ }
+ result = output->answer;
+ /***************************************************/
+ if ((!strcoll(qcflag,"cloud")&&flag1->answer)||
+ (!strcoll(qcflag,"diff_orbit_from_500m")&&flag1->answer)){
+ G_fatal_error("Those flags cannot work with MOD09A @ 500m products");
+ }
+ if (!strcoll(qcflag,"data_quality")){
+ if(bandno<1||bandno>7)
+ G_fatal_error("band number out of allowed range [1-7]");
+ if(!flag1->answer&&bandno>2)
+ G_fatal_error("250m band number is out of allowed range [1,2]");
+ }
+ /***************************************************/
+ mapset = G_find_cell2 (qcchan, "");
+ if (mapset == NULL) {
+ G_fatal_error(_("cell file [%s] not found"),qcchan);
+ }
+ data_type_qcchan = G_raster_map_type(qcchan,mapset);
+ if ( (infd = G_open_cell_old (qcchan,mapset)) < 0)
+ G_fatal_error(_("Cannot open cell file [%s]"), qcchan);
+ if (G_get_cellhd (qcchan, mapset, &cellhd) < 0)
+ G_fatal_error(_("Cannot read file header of [%s]"), qcchan);
+ inrast = G_allocate_raster_buf(data_type_qcchan);
+ /***************************************************/
+ G_debug(3, "number of rows %d",cellhd.rows);
+ nrows = G_window_rows();
+ ncols = G_window_cols();
+ outrast = G_allocate_raster_buf(data_type_output);
+ /* Create New raster files */
+ if ( (outfd = G_open_raster_new (result,data_type_output)) < 0)
+ G_fatal_error(_("Could not open <%s>"),result);
+ /* Process pixels */
+ for (row = 0; row < nrows; row++)
+ {
+ CELL c;
+ unsigned int qc250chan;
+ CELL qc500chan;
+
+ G_percent(row,nrows,2);
+// printf("row = %i/%i\n",row,nrows);
+ if(G_get_raster_row(infd,inrast,row,data_type_qcchan)<0)
+ G_fatal_error(_("Could not read from <%s>"),qcchan);
+ /*process the data */
+ for (col=0; col < ncols; col++)
+ {
+ switch(data_type_qcchan){
+ case CELL_TYPE:
+ c = (int) ((CELL *) inrast)[col];
+ break;
+ case FCELL_TYPE:
+ c = (int) ((FCELL *) inrast)[col];
+ break;
+ case DCELL_TYPE:
+ c = (int) ((DCELL *) inrast)[col];
+ break;
+ }
+ if(flag1->answer){
+ /* This is a MOD09A at 500m product, QC layer is 32-bit */
+ qc500chan = c;
+ } else {
+ /* This is a MOD09A at 250m product, QC layer is 16-bit */
+ qc250chan = (unsigned int) ((CELL *) inrast)[col];
+ }
+ if(G_is_c_null_value(&c)){
+ G_set_c_null_value(&outrast[col],1);
+ } else {
+ /*calculate modland QA bits extraction */
+ if (!strcoll(qcflag,"modland_qa_bits")){
+ if(flag1->answer){
+ /* 500m product */
+ c = qc500a( qc500chan );
+ } else {
+ /* 250m product */
+ c = qc250a( qc250chan );
+ }
+ outrast[col] = c;
+ } else
+ /*calculate cloud state */
+ if (!strcoll(qcflag,"cloud")){
+ /* ONLY 250m product! */
+ c = qc250b( qc250chan );
+ outrast[col] = c;
+ } else
+ /*calculate modland QA bits extraction */
+ if (!strcoll(qcflag,"data_quality")){
+ if(flag1->answer){
+ /* 500m product */
+ c = qc500c( qc500chan, bandno );
+ } else {
+ /* 250m product */
+ c = qc250c( qc250chan, bandno );
+ }
+ outrast[col] = c;
+ } else
+ /*calculate atmospheric correction flag */
+ if (!strcoll(qcflag,"atcorr")){
+ if(flag1->answer){
+ /* 500m product */
+ c = qc500d( qc500chan );
+ } else {
+ /* 250m product */
+ c = qc250d( qc250chan );
+ }
+ outrast[col] = c;
+ } else
+ /*calculate adjacency correction flag */
+ if (!strcoll(qcflag,"adjcorr")){
+ if(flag1->answer){
+ /* 500m product */
+ c = qc500e( qc500chan );
+ } else {
+ /* 250m product */
+ c = qc250e( qc250chan );
+ }
+ outrast[col] = c;
+ } else
+ /*calculate different orbit from 500m flag */
+ if (!strcoll(qcflag,"diff_orbit_from_500m")){
+ /* ONLY 250m product! */
+ c = qc250f( qc500chan );
+ outrast[col] = c;
+ } else {
+ /* Signal user that the flag name is badly written */
+ /* therefore not understood by the application*/
+ G_fatal_error("Unknown flag name, please check spelling");
+ }
+ }
+ }
+ if (G_put_raster_row (outfd, outrast, data_type_output) < 0)
+ G_fatal_error(_("Cannot write to output raster file"));
+ }
+
+
+ G_free(inrast);
+ G_close_cell(infd);
+ G_free(outrast);
+ G_close_cell(outfd);
+
+ /* Color from -1.0 to +1.0 in grey */
+ G_init_colors(&colors);
+ G_add_color_rule(0,0,0,0,10,255,255,255,&colors);
+ G_short_history(result, "raster", &history);
+ G_command_history(&history);
+ G_write_history(result,&history);
+
+ exit(EXIT_SUCCESS);
+}
+
Added: grass-addons/gipe/i.qc.modis/qc250a.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc250a.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc250a.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,32 @@
+// MODLAND QA Bits 250m Unsigned Int bits[0-1]
+// 00 -> class 1: Corrected product produced at ideal quality -- all bands
+// 01 -> class 2: Corrected product produced at less than idel quality -- some or all bands
+// 10 -> class 3: Corrected product NOT produced due to cloud effect -- all bands
+// 11 -> class 4: Corrected product NOT produced due to other reasons -- some or all bands mayb be fill value (Note that a value of [11] overrides a value of [01])
+
+int qc250a( unsigned int pixel )
+{
+ unsigned int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x02){
+ /* Non-Corrected product */
+ if(qctemp & 0x01){
+ class=4;/*other reasons*/
+ } else {
+ class=3;/*because of clouds*/
+ }
+ } else {
+ /* Corrected product */
+ if(qctemp & 0x01){
+ class=2;/*less than ideal quality*/
+ } else {
+ class=1;/*ideal quality*/
+ }
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc250b.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc250b.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc250b.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,31 @@
+// Cloud State 250m Unsigned Int bits[2-3]
+// 00 -> class 1: Clear -- No clouds
+// 01 -> class 2: Cloudy
+// 10 -> class 3: Mixed
+// 11 -> class 4: Not Set ; Assumed Clear
+
+int qc250b( unsigned int pixel )
+{
+ unsigned int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>2;/*bits [2-3] become [0-1]*/
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x02){ /* 1 ? */
+ if(qctemp & 0x01){
+ class=4;/*Not Set ; Assumed Clear*/
+ } else {
+ class=3;/*Mixed clouds*/
+ }
+ } else { /* 0 ? */
+ if(qctemp & 0x01){
+ class=2;/*Cloudy*/
+ } else {
+ class=1;/*Clear -- No Clouds*/
+ }
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc250c.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc250c.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc250c.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,87 @@
+// Band-wise Data Quality 250m Unsigned Int bits[0-1]
+// 0000 -> class 1: highest quality
+// 0111 -> class 2: noisy detector
+// 1000 -> class 3: dead detector; data interpolated in L1B
+// 1001 -> class 4: solar zenith >= 86 degrees
+// 1010 -> class 5: solar zenith >= 85 and < 86 degrees
+// 1011 -> class 6: missing input
+// 1100 -> class 7: internal constant used in place of climatological data for at least one atmospheric constant
+// 1101 -> class 8: correction out of bounds, pixel constrained to extreme allowable value
+// 1110 -> class 9: L1B data faulty
+// 1111 -> class 10: not processed due to deep ocean or cloud
+// Class 11: Combination of bits unused
+
+int qc250c( unsigned int pixel , int bandno )
+{
+ unsigned int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>4*bandno;/* bitshift [4-7] or [8-11] to [0-3] */
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x08){ /* 1??? */
+ if(qctemp & 0x04){ /* 11?? */
+ if(qctemp & 0x02){ /* 111? */
+ if(qctemp & 0x01){ /* 1111 */
+ class=10;/*Not proc.ocean/cloud*/
+ } else { /* 1110 */
+ class=9;/*L1B faulty data*/
+ }
+ } else { /* 110? */
+ if(qctemp & 0x01){ /* 1101 */
+ class=8;/*corr. out of bounds*/
+ } else { /* 1100 */
+ class=7;/*internal constant used*/
+ }
+ }
+ } else {
+ if(qctemp & 0x02){ /* 101? */
+ if(qctemp & 0x01){ /* 1011 */
+ class=6;/*missing input*/
+ } else { /* 1010 */
+ class=5;/*solarzen>=85&&<86*/
+ }
+ }else { /* 100? */
+ if(qctemp & 0x01){ /* 1001 */
+ class=4;/*solar zenith angle>=86*/
+ } else { /* 1000 */
+ class=3;/*Dead detector*/
+ }
+ }
+
+ }
+ } else { /* 0??? */
+ if(qctemp & 0x04){ /* 01?? */
+ if(qctemp & 0x02){ /* 011? */
+ if(qctemp & 0x01){ /* 0111 */
+ class=2;/*Noisy detector*/
+ } else { /* 0110 */
+ class=11;/*Unused*/
+ }
+ } else { /* 010? */
+ if(qctemp & 0x01){ /* 0101 */
+ class=11;/*Unused*/
+ } else { /* 0100 */
+ class=11;/*Unused*/
+ }
+ }
+ } else { /* 00?? */
+ if(qctemp & 0x02){ /* 001? */
+ if(qctemp & 0x01){ /* 0011 */
+ class=11;/*Unused*/
+ } else { /* 0010 */
+ class=11;/*Unused*/
+ }
+ } else { /* 000? */
+ if(qctemp & 0x01){ /* 0001 */
+ class=11;/*Unused*/
+ } else { /* 0000 */
+ class=1;/*Highest quality*/
+ }
+ }
+ }
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc250d.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc250d.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc250d.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,21 @@
+// Atmospheric correction 250m Unsigned Int bit[12]
+// 00 -> class 1: Not Corrected product
+// 01 -> class 2: Corrected product
+
+int qc250d( unsigned int pixel )
+{
+ unsigned int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>12; /* bit no 12 becomes 0 */
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x01){
+ class=2;/*Corrected*/
+ } else {
+ class=1;/*Not corrected*/
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc250e.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc250e.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc250e.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,21 @@
+// Adjacency correction 250m Unsigned Int bit[13]
+// 00 -> class 1: Not Corrected product
+// 01 -> class 2: Corrected product
+
+int qc250e( unsigned int pixel )
+{
+ unsigned int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>13; /* bit no 13 becomes 0 */
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x01){
+ class=2;/*Corrected*/
+ } else {
+ class=1;/*Not corrected*/
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc250f.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc250f.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc250f.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,21 @@
+// Different orbit from 500m product, 250m Unsigned Int bit[14]
+// 00 -> class 1: same orbit as 500m
+// 01 -> class 2: different orbit from 500m
+
+int qc250f( unsigned int pixel )
+{
+ unsigned int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>14; /* bit no 14 becomes 0 */
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x01){
+ class=2;/*different orbit*/
+ } else {
+ class=1;/*same orbit*/
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc500a.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc500a.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc500a.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,33 @@
+// MODLAND QA Bits 500m long int bits[0-1]
+// 00 -> class 1: Corrected product produced at ideal quality -- all bands
+// 01 -> class 2: Corrected product produced at less than idel quality -- some or all bands
+// 10 -> class 3: Corrected product NOT produced due to cloud effect -- all bands
+// 11 -> class 4: Corrected product NOT produced due to other reasons -- some or all bands mayb be fill value (Note that a value of [11] overrides a value of [01])
+
+int qc500a( long int pixel )
+{
+ long int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x02){
+ /* Non-Corrected product */
+ if(qctemp & 0x01){
+ class=4;/*other reasons*/
+ } else {
+ class=3;/*because of clouds*/
+ }
+ } else {
+ /* Corrected product */
+ if(qctemp & 0x01){
+ class=2;/*less than ideal quality*/
+ } else {
+ class=1;/*ideal quality*/
+ }
+ }
+ return class;
+
+}
+
Added: grass-addons/gipe/i.qc.modis/qc500c.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc500c.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc500c.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,88 @@
+// Band-wise Data Quality 500m long Int
+// bits[2-5][6-9][10-13][14-17][18-21][22-25][26-29]
+// 0000 -> class 1: highest quality
+// 0111 -> class 2: noisy detector
+// 1000 -> class 3: dead detector; data interpolated in L1B
+// 1001 -> class 4: solar zenith >= 86 degrees
+// 1010 -> class 5: solar zenith >= 85 and < 86 degrees
+// 1011 -> class 6: missing input
+// 1100 -> class 7: internal constant used in place of climatological data for at least one atmospheric constant
+// 1101 -> class 8: correction out of bounds, pixel constrained to extreme allowable value
+// 1110 -> class 9: L1B data faulty
+// 1111 -> class 10: not processed due to deep ocean or cloud
+// Class 11: Combination of bits unused
+
+int qc500c( long int pixel , int bandno )
+{
+ long int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>2+(4*bandno-1);/* bitshift [] to [0-3] etc. */
+ swab(&swabfrom,&swabto,4);
+ qctemp=swabto;
+ if(qctemp & 0x08){ /* 1??? */
+ if(qctemp & 0x04){ /* 11?? */
+ if(qctemp & 0x02){ /* 111? */
+ if(qctemp & 0x01){ /* 1111 */
+ class=10;/*Not proc.ocean/cloud*/
+ } else { /* 1110 */
+ class=9;/*L1B faulty data*/
+ }
+ } else { /* 110? */
+ if(qctemp & 0x01){ /* 1101 */
+ class=8;/*corr. out of bounds*/
+ } else { /* 1100 */
+ class=7;/*internal constant used*/
+ }
+ }
+ } else {
+ if(qctemp & 0x02){ /* 101? */
+ if(qctemp & 0x01){ /* 1011 */
+ class=6;/*missing input*/
+ } else { /* 1010 */
+ class=5;/*solarzen>=85&&<86*/
+ }
+ }else { /* 100? */
+ if(qctemp & 0x01){ /* 1001 */
+ class=4;/*solar zenith angle>=86*/
+ } else { /* 1000 */
+ class=3;/*Dead detector*/
+ }
+ }
+
+ }
+ } else { /* 0??? */
+ if(qctemp & 0x04){ /* 01?? */
+ if(qctemp & 0x02){ /* 011? */
+ if(qctemp & 0x01){ /* 0111 */
+ class=2;/*Noisy detector*/
+ } else { /* 0110 */
+ class=11;/*Unused*/
+ }
+ } else { /* 010? */
+ if(qctemp & 0x01){ /* 0101 */
+ class=11;/*Unused*/
+ } else { /* 0100 */
+ class=11;/*Unused*/
+ }
+ }
+ } else { /* 00?? */
+ if(qctemp & 0x02){ /* 001? */
+ if(qctemp & 0x01){ /* 0011 */
+ class=11;/*Unused*/
+ } else { /* 0010 */
+ class=11;/*Unused*/
+ }
+ } else { /* 000? */
+ if(qctemp & 0x01){ /* 0001 */
+ class=11;/*Unused*/
+ } else { /* 0000 */
+ class=1;/*Highest quality*/
+ }
+ }
+ }
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc500d.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc500d.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc500d.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,21 @@
+// Atmospheric correction 500m long Int bit[30]
+// 00 -> class 1: Not Corrected product
+// 01 -> class 2: Corrected product
+
+int qc500d( long int pixel )
+{
+ long int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>30; /* bit no 30 becomes 0 */
+ swab(&swabfrom,&swabto,1);
+ qctemp=swabto;
+ if(qctemp & 0x01){
+ class=2;/*Corrected*/
+ } else {
+ class=1;/*Not corrected*/
+ }
+ return class;
+}
+
Added: grass-addons/gipe/i.qc.modis/qc500e.c
===================================================================
--- grass-addons/gipe/i.qc.modis/qc500e.c (rev 0)
+++ grass-addons/gipe/i.qc.modis/qc500e.c 2008-07-28 07:47:54 UTC (rev 32350)
@@ -0,0 +1,21 @@
+// Adjacency correction 500m long Int bit[31]
+// 00 -> class 1: Not Corrected product
+// 01 -> class 2: Corrected product
+
+int qc500e( long int pixel )
+{
+ long int swabfrom, swabto, qctemp;
+ int class;
+
+ swabfrom=pixel;
+ swabfrom>>31; /* bit no 31 becomes 0 */
+ swab(&swabfrom,&swabto,1);
+ qctemp=swabto;
+ if(qctemp & 0x01){
+ class=2;/*Corrected*/
+ } else {
+ class=1;/*Not corrected*/
+ }
+ return class;
+}
+
More information about the grass-commit
mailing list