[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