Ejemplo n.º 1
0
/*+++++++++++++++++++++++++
.IDENTifer   SCIA_LV1C_RD_MDS
.PURPOSE     read SCIAMACHY level 1c MDS
.INPUT/OUTPUT
  call as   nr_mds = SCIA_LV1C_RD_MDS( fd, clus_mask, state, &mds );
     input:  
            FILE    *fd               : (open) stream pointer
	    ulong64 clus_mask         : mask for cluster selection
 in/output:  
	    struct state1_scia *state : structure with States of the product
    output:  
            struct mds1c_scia  **mds  : structure for level 1c MDS

.RETURNS     number of level 1c MDS read (unsigned int), 
             error status passed by global variable ``nadc_stat''
.COMMENTS    This routine allocates memory for the following variables:
              pixel_ids, pixel_wv, pixel_wv_err, pixel_val, pixel_err, 
              geoN/geoL/geoC
-------------------------*/
unsigned int SCIA_LV1C_RD_MDS( FILE *fd, unsigned long long clus_mask,
			       struct state1_scia *state,
			       struct mds1c_scia **mds_out )
     /*@globals  source;@*/
     /*@modifies source@*/
{
     register unsigned short nc, ncc, ni, nobs;
     register unsigned int   nr_mds = 0u;

     register unsigned short bcp_in_limb, bcp_deep_space;

     char    *mds_char, *mds_pntr;
     size_t  dsr_length_left, nr_byte;

     unsigned short ubuff;
     unsigned short num_clus_file, num_clus_out;

     struct mds1c_scia *mds = NULL;

     static unsigned short bcp_in_nadir = 0;

     const unsigned char uchar_one = 1;
     const size_t        DSR_Read  = sizeof(struct mjd_envi) + ENVI_UINT;
/*
 * set variable source (= type of MDS)
 */
     source = (int) state->type_mds;
/*
 * count number of cluster to be read
 */
     num_clus_out = 0;
     num_clus_file = state->num_clus;
     for ( nc = 0; nc < num_clus_file; nc++ ) {
	  if ( Get_Bit_LL( clus_mask, 
			   state->Clcon[nc].id - uchar_one  ) == 1ULL )
	       num_clus_out++;
     }
/*
 * check dimension of the output array mds_out
 */
     if ( num_clus_out == 0u || mds_out == NULL ) {
          if ( mds_out != NULL ) *mds_out = NULL;
          return 0u;
     }
/*
 * allocate memory to store output records
 */
     mds = (struct mds1c_scia *) 
	  malloc( num_clus_out * sizeof(struct mds1c_scia));
     if ( mds == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "mds1_scia" );
     *mds_out = mds;
/*
 * initialize MDS-structure
 */
     nc = 0;
     do {
	  mds[nc].num_obs = 0;
	  mds[nc].num_pixels = 0;
	  mds[nc].pixel_ids = NULL;
	  mds[nc].pixel_wv = NULL;
	  mds[nc].pixel_wv_err = NULL;
	  mds[nc].pixel_val = NULL;
	  mds[nc].pixel_err = NULL;
	  mds[nc].geoN = NULL;
	  mds[nc].geoL = NULL;
	  mds[nc].geoC = NULL;
     } while ( ++nc < num_clus_out );
/*
 * rewind/read input data file
 */
     (void) fseek( fd, (long) state->offset, SEEK_SET );
/*
 * read data set records
 */
     nc = 0;
     do {
	  mds->type_mds    = state->type_mds;
	  mds->state_index = (unsigned char) state->indx;
	  mds->dur_scan    = state->dur_scan;
/* 1 */
	  if ( fread( &mds->mjd, sizeof( struct mjd_envi ), 1, fd ) != 1 )
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "" );
/* 2 */
	  if ( fread( &mds->dsr_length, ENVI_UINT, 1, fd ) != 1 )
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "" );
#ifdef _SWAP_TO_LITTLE_ENDIAN
	  mds->dsr_length = byte_swap_u32( mds->dsr_length );
#endif
/*
 * now we know the size of this dsr, so read it in memory!
 */
	  dsr_length_left = mds->dsr_length - DSR_Read;
	  mds_char = (char *) malloc( dsr_length_left );
	  if ( mds_char == NULL )
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "mds_char" );
	  if ( fread( mds_char, dsr_length_left, 1, fd ) != 1 )
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "" );
/* 3 */
	  (void) memcpy( &mds->quality_flag, mds_char, ENVI_CHAR );
	  mds_pntr = mds_char + ENVI_CHAR;
/* 4 */
	  (void) memcpy( &mds->orbit_phase, mds_pntr, ENVI_FLOAT );
	  mds_pntr += ENVI_FLOAT;
/* 5 */
	  (void) memcpy( &ubuff, mds_pntr, ENVI_USHRT );
	  mds_pntr += ENVI_USHRT;
#ifdef _SWAP_TO_LITTLE_ENDIAN
	  ubuff = byte_swap_u16( ubuff );
#endif
	  mds->category = (unsigned char) ubuff;
/* 6 */
	  (void) memcpy( &ubuff, mds_pntr, ENVI_USHRT );
	  mds_pntr += ENVI_USHRT;
#ifdef _SWAP_TO_LITTLE_ENDIAN
	  ubuff = byte_swap_u16( ubuff );
#endif
	  mds->state_id = (unsigned char) ubuff;
/* 7 */
	  (void) memcpy( &ubuff, mds_pntr, ENVI_USHRT );
	  mds_pntr += ENVI_USHRT;
#ifdef _SWAP_TO_LITTLE_ENDIAN
	  ubuff = byte_swap_u16( ubuff );
#endif
	  mds->clus_id = (unsigned char) ubuff;
	  for ( ncc = 0; ncc < state->num_clus; ncc++ )
	       if ( state->Clcon[ncc].id == mds->clus_id ) break;
	  
	  mds->chan_id = state->Clcon[ncc].channel;
	  mds->coaddf  = (unsigned char) state->Clcon[ncc].coaddf;
	  mds->pet     = state->Clcon[ncc].pet;

	  if ( Get_Bit_LL(clus_mask,(unsigned char)(mds->clus_id-1)) != 0ULL ){
/* 8 */
	       (void) memcpy( &mds->num_obs, mds_pntr, ENVI_USHRT );
	       mds_pntr += ENVI_USHRT;
#ifdef _SWAP_TO_LITTLE_ENDIAN
	       mds->num_obs = byte_swap_u16( mds->num_obs );
#endif
/* 9 */
	       (void) memcpy( &mds->num_pixels, mds_pntr, ENVI_USHRT );
	       mds_pntr += ENVI_USHRT;
#ifdef _SWAP_TO_LITTLE_ENDIAN
	       mds->num_pixels = byte_swap_u16( mds->num_pixels );
#endif
/* 10 */
	       (void) memcpy( &mds->rad_units_flag, mds_pntr, ENVI_CHAR );
	       mds_pntr += ENVI_CHAR;
/* 11 */
	       nr_byte = mds->num_pixels * ENVI_USHRT;
	       mds->pixel_ids = (unsigned short *) malloc( nr_byte );
	       if ( mds->pixel_ids == NULL ) {
		    free( mds_char );
		    NADC_GOTO_ERROR( NADC_ERR_ALLOC, "pixel_ids" );
	       }
	       (void) memcpy( mds->pixel_ids, mds_pntr, nr_byte );
	       mds_pntr += nr_byte;
/* 12 */
	       nr_byte = mds->num_pixels * ENVI_FLOAT;
	       mds->pixel_wv = (float *) malloc( nr_byte );
	       if ( mds->pixel_wv == NULL ) {
		    free( mds_char );
		    NADC_GOTO_ERROR(NADC_ERR_ALLOC, "pixel_wv");
	       }
	       (void) memcpy( mds->pixel_wv, mds_pntr, nr_byte );
	       mds_pntr += nr_byte;
/* 13 */
	       mds->pixel_wv_err = (float *) malloc( nr_byte );
	       if ( mds->pixel_wv_err == NULL ) {
		    free( mds_char );
		    NADC_GOTO_ERROR( NADC_ERR_ALLOC, "pixel_wv_err" );
	       }
	       (void) memcpy( mds->pixel_wv_err, mds_pntr, nr_byte );
	       mds_pntr += nr_byte;
/* 14 */
	       nr_byte = mds->num_obs * mds->num_pixels * ENVI_FLOAT;
	       mds->pixel_val = (float *) malloc( nr_byte );
	       if ( mds->pixel_val == NULL ) {
		    free( mds_char );
		    NADC_GOTO_ERROR( NADC_ERR_ALLOC, "pixel_val" );
	       }
	       (void) memcpy( mds->pixel_val, mds_pntr, nr_byte );
	       mds_pntr += nr_byte;
/* 15 */
	       mds->pixel_err = (float *) malloc( nr_byte );
	       if ( mds->pixel_err == NULL ) {
		    free( mds_char );
		    NADC_GOTO_ERROR( NADC_ERR_ALLOC, "pixel_err" );
	       }
	       (void) memcpy( mds->pixel_err, mds_pntr, nr_byte );
	       mds_pntr += nr_byte;
/* 16 */
	       switch ( source ) {
	       case SCIA_NADIR:
		    mds->geoN = (struct geoN_scia *) 
			 malloc( mds->num_obs * sizeof( struct geoN_scia ));
		    if ( mds->geoN == NULL ) {
			 free( mds_char );
			 NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoN" );
		    }
		    mds_pntr += SCIA_LV1_RD_GeoN( mds_pntr, mds->num_obs, 
						  mds->geoN );
/*
 * set Rainbow/Sun glint flags and pixel type: 0 (= backscan) else 1
 */
		    for ( nobs = 0; nobs < mds->num_obs; nobs++ ) {
			 mds->geoN[nobs].glint_flag = 0;

			 bcp_in_nadir += state->Clcon[ncc].intg_time;
			 if ( bcp_in_nadir > 64 ) {
			      mds->geoN[nobs].pixel_type = BACK_SCAN;
			      if ( bcp_in_nadir == 80 ) bcp_in_nadir = 0;
			 } else
			      mds->geoN[nobs].pixel_type = FORWARD_SCAN;
		    }
		    break;
	       case SCIA_LIMB:
		    mds->geoL = (struct geoL_scia *) 
			 malloc( mds->num_obs * sizeof( struct geoL_scia ));
		    if ( mds->geoL == NULL ) {
			 free( mds_char );
			 NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoL" );
		    }
		    mds_pntr += SCIA_LV1_RD_GeoL( mds_pntr, mds->num_obs, 
						  mds->geoL );
/*
 * set Rainbow/Sun glint flags and pixel type
 */
		    bcp_in_limb = 0;
		    bcp_deep_space =
			 mds->num_obs * state->Clcon[ncc].intg_time - 24;
		    for ( nobs = 0; nobs < mds->num_obs; nobs++ ) {
			 mds->geoL[nobs].glint_flag = 0;
			 mds->geoL[nobs].pixel_type = ALONG_TANG_HGHT;

			 if ( nobs == mds->num_obs-1
			      || bcp_in_limb > bcp_deep_space )
			      mds->geoL[nobs].pixel_type = DEEP_SPACE;
			 else if ( (bcp_in_limb % 24) == 0 )
			      mds->geoL[nobs].pixel_type = NEW_TANG_HGHT;

			 bcp_in_limb += state->Clcon[ncc].intg_time;
		    }
		    break;
	       case SCIA_OCCULT:
		    mds->geoL = (struct geoL_scia *) 
			 malloc( mds->num_obs * sizeof( struct geoL_scia ));
		    if ( mds->geoL == NULL ) {
			 free( mds_char );
			 NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoL" );
		    }
		    mds_pntr += SCIA_LV1_RD_GeoL( mds_pntr, mds->num_obs, 
						  mds->geoL );
/*
 * set Rainbow/Sun glint flags and pixel type
 */
		    for ( nobs = 0; nobs < mds->num_obs; nobs++ ) {
			 mds->geoL[nobs].glint_flag = 0;
			 mds->geoL[nobs].pixel_type = ALONG_TANG_HGHT;
		    }
		    break;
	       case SCIA_MONITOR:
		    mds->geoC = (struct geoC_scia *) 
			 malloc( mds->num_obs * sizeof( struct geoC_scia ));
		    if ( mds->geoC == NULL ) {
			 free( mds_char );
			 NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoC" );
		    }
		    mds_pntr += SCIA_LV1_RD_GeoC( mds_pntr, mds->num_obs, 
						  mds->geoC );
		    break;
	       }
/*
 * check if we read the whole DSR
 */
	       if ( (size_t)(mds_pntr - mds_char) != dsr_length_left ) {
		    const char *dsd_names[] = { "UNKNOWN", "NADIR", "LIMB",
						"OCCULTATION", "MONITORING" };
		    free( mds_char );
		    NADC_GOTO_ERROR( NADC_ERR_PDS_SIZE, 
				     dsd_names[source] );
	       }
/*
 * byte swap data to local representation
 */
#ifdef _SWAP_TO_LITTLE_ENDIAN
	       Sun2Intel_L1C_MDS( mds );
#endif
	       if ( ++nr_mds == num_clus_out ) {
		    free( mds_char );
		    break;
	       }
/*
 * pixel_ids has a value in the range [0..8191]
 */
	       for ( ni = 0; ni < mds->num_pixels; ni++ )
		    mds->pixel_ids[ni] += (mds->chan_id - 1) * CHANNEL_SIZE;
	       mds++;
	  }
	  free( mds_char );
     } while ( ++nc < num_clus_file );
/*
 * update state-record to reflect the actual clusters to be read
 * note that the dimension of 'mds_out' equals 'num_clus_out'
 */
     num_clus_out = 0;
     for ( nc = 0; nc < num_clus_file; nc++ ) {
	  if ( Get_Bit_LL( clus_mask, 
			   state->Clcon[nc].id - uchar_one ) == 1ULL ) {
	       if ( num_clus_out < nc )
		    (void) memmove( &state->Clcon[num_clus_out], 
				    &state->Clcon[nc],
				    sizeof( struct Clcon_scia ) );
	       num_clus_out++;
	  }
     }
     state->num_clus = num_clus_out;
/*
 * set return values
 */
     return nr_mds;
 done:
     *mds_out = NULL;
     if ( (mds -= nr_mds) != NULL ) SCIA_LV1C_FREE_MDS( source, nr_mds, mds );
     return 0u;
}
Ejemplo n.º 2
0
/*+++++++++++++++++++++++++
.IDENTifer   SCIA_LV1_RD_ONE_MDS
.PURPOSE     General function to read one Measurement Data Set
.INPUT/OUTPUT
  call as   SCIA_LV1_RD_ONE_MDS( fd, clus_mask, state, mds ); 
     input:  
            FILE    *fd               : (open) stream pointer
	    ulong64 clus_mask         : mask for cluster selection
 in/output:  
	    struct state1_scia *state : structure with States of the product
    output:  
            struct mds1_scia   **mds  : structure for level 1b MDS

.RETURNS     exits on failure
.COMMENTS    static function
-------------------------*/
static
void SCIA_LV1_RD_ONE_MDS( FILE *fd, unsigned long long clus_mask,
			  const struct state1_scia *state,
			  /*@partial@*/ struct mds1_scia *mds )
       /*@globals  errno, nadc_stat, nadc_err_stack, source;@*/
       /*@modifies errno, nadc_stat, nadc_err_stack, fd, mds@*/
{
     register char           *mds_pntr;
     register unsigned short na, nc, ncc, ni, nr;

     char   *mds_char;
     char   msg[64];
     size_t nr_byte;

     unsigned char *glint_flags;

     const int intg_per_sec = 16 / state->intg_times[state->num_intg-1];
     const unsigned short indx_deep_space = state->num_aux 
	  - (state->intg_times[0] / state->intg_times[state->num_intg-1]);
/*
 * allocate memory for the Sun glint/Rainbow flags
 */
     glint_flags = (unsigned char *) malloc( (size_t) mds->n_aux );
     if ( glint_flags == NULL ) 
	  NADC_RETURN_ERROR( NADC_ERR_ALLOC, "glint_flags" );
/*
 * allocate memory to temporary store data for output structure
 */
     mds_char = (char *) malloc( (size_t) state->length_dsr );
     if ( mds_char == NULL ) {
	  free( glint_flags );
          NADC_RETURN_ERROR( NADC_ERR_ALLOC, "mds_char" );
     }
/*
 * read all MDS parameters of this state
 */
     if ( fread( mds_char, (size_t) state->length_dsr, 1, fd ) != 1 ) {
	  (void) snprintf( msg, 64, "MDS[%-u]: read failed", state->indx );
	  NADC_GOTO_ERROR( NADC_ERR_FILE_RD, msg );
     }
/*
 * read data buffer to MDS structure
 */
     mds_pntr = mds_char;
     (void) memcpy( &mds->mjd, mds_pntr, sizeof( struct mjd_envi ) );
     mds_pntr += sizeof( struct mjd_envi );
     (void) memcpy( &mds->dsr_length, mds_pntr, ENVI_UINT );
     mds_pntr += ENVI_UINT;
#ifdef _SWAP_TO_LITTLE_ENDIAN
     mds->dsr_length = byte_swap_u32( mds->dsr_length );
#endif
     if ( mds->dsr_length != state->length_dsr ) {
	  (void) snprintf( msg, 64, 
			   "MDS[%-u]: Size according to State/DSR = %-u/%-u",
			   state->indx, state->length_dsr, mds->dsr_length );
	  NADC_GOTO_ERROR( NADC_ERR_PDS_SIZE, msg );
     }
     (void) memcpy( &mds->quality_flag, mds_pntr, ENVI_CHAR );
     mds_pntr += ENVI_CHAR;
/*
 * read scale factor [SCIENCE_CHANNELS]
 */
     nr_byte = (size_t) SCIENCE_CHANNELS * ENVI_UCHAR;
     (void) memcpy( mds->scale_factor, mds_pntr, nr_byte );
     mds_pntr += nr_byte;
/*
 * read satellite flags
 */
     nr_byte = mds->n_aux * ENVI_UCHAR;
     if ( (mds->sat_flags = (unsigned char *) malloc( nr_byte )) == NULL )
	  NADC_GOTO_ERROR( NADC_ERR_ALLOC, "sat_flags" );
     (void) memcpy( mds->sat_flags, mds_pntr, nr_byte );
     mds_pntr += nr_byte;
/*
 * read red grass flags
 */
     nr_byte = (size_t) state->num_clus * mds->n_aux;
     if ( (mds->red_grass = (unsigned char *) malloc( nr_byte )) == NULL )
	  NADC_GOTO_ERROR( NADC_ERR_ALLOC, "red_grass" );
     (void) memcpy( mds->red_grass, mds_pntr, nr_byte );
     mds_pntr += nr_byte;
/*
 * read Sun glint flags
 */
     if ( source != SCIA_MONITOR ) {
	  (void) memcpy( glint_flags, mds_pntr, (size_t) mds->n_aux );
	  mds_pntr += (size_t) mds->n_aux;
     }
/*
 * read geolocation
 */
     switch ( source ) {
     case SCIA_NADIR:
	  mds->geoN = (struct geoN_scia *) 
	       malloc( mds->n_aux * sizeof( struct geoN_scia ) );
	  if ( mds->geoN == NULL )
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoN" );
	  mds_pntr += SCIA_LV1_RD_GeoN( mds_pntr, mds->n_aux, mds->geoN );

          /* set Rainbow/Sun glint flag and pixel type: 0 (= backscan) or 1 */
	  for ( na = 0; na < mds->n_aux; na++ ) {
	       mds->geoN[na].glint_flag = glint_flags[na];

	       if ( sec_in_scan == 5 ) sec_in_scan = 0;

	       if ( sec_in_scan == 0 )
		    mds->geoN[na].pixel_type = BACK_SCAN;
	       else
		    mds->geoN[na].pixel_type = FORWARD_SCAN;

	       if ( (na+1) % intg_per_sec == 0 ) sec_in_scan++;
	  }
	  break;
     case SCIA_LIMB:
	  mds->geoL = (struct geoL_scia *) 
	       malloc( mds->n_aux * sizeof( struct geoL_scia ) );
	  if ( mds->geoL == NULL )
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoL" );
	  mds_pntr += SCIA_LV1_RD_GeoL( mds_pntr, mds->n_aux, mds->geoL );

          /* set Rainbow/Sun glint flags and pixel type */
	  for ( na = 0; na < mds->n_aux; na++ ) {
	       mds->geoL[na].glint_flag = glint_flags[na];
	       mds->geoL[na].pixel_type = ALONG_TANG_HGHT;

	       if ( indx_limb >= indx_deep_space )
		    mds->geoL[na].pixel_type |= DEEP_SPACE;
	       if ( ++indx_limb >= state->num_aux ) indx_limb = 0;
	  }
	  mds->geoL[0].pixel_type |= NEW_TANG_HGHT;
	  break;
     case SCIA_OCCULT:
	  mds->geoL = (struct geoL_scia *) 
	       malloc( mds->n_aux * sizeof( struct geoL_scia ) );
	  if ( mds->geoL == NULL )
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoL" );
	  mds_pntr += SCIA_LV1_RD_GeoL( mds_pntr, mds->n_aux, mds->geoL );

          /* set Rainbow/Sun glint flags and pixel type */
	  for ( na = 0; na < mds->n_aux; na++ ) {
	       mds->geoL[na].glint_flag = glint_flags[na];
	       mds->geoL[na].pixel_type = ALONG_TANG_HGHT;
	  }
	  break;
     case SCIA_MONITOR:
	  mds->geoC = (struct geoC_scia *) 
	       malloc( mds->n_aux * sizeof( struct geoC_scia ) );
	  if ( mds->geoC == NULL )
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoC" );
	  mds_pntr += SCIA_LV1_RD_GeoC( mds_pntr, mds->n_aux, mds->geoC );
	  break;
     }
/*
 * level 0 header
 */
     mds->lv0 = (struct lv0_hdr *) 
	  malloc( mds->n_aux * sizeof( struct lv0_hdr ) );
     if ( mds->lv0 == NULL )
	  NADC_GOTO_ERROR( NADC_ERR_ALLOC, "lv0" );
     mds_pntr += SCIA_LV1_RD_LV0Hdr( mds_pntr, mds->n_aux, mds->lv0 );
/*
 * PMD values
 */
     if ( source != SCIA_MONITOR ) {
	  nr_byte = mds->n_pmd * ENVI_FLOAT;
	  mds->int_pmd = (float *) malloc( nr_byte );
	  if ( mds->int_pmd == NULL )
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "int_pmd" );
	  (void) memcpy( mds->int_pmd, mds_pntr, nr_byte );
	  mds_pntr += nr_byte;
/*
 * Fractional polarisation values
 */
	  mds->polV = (struct polV_scia *) 
	       malloc( mds->n_pol * sizeof( struct polV_scia ) );
	  if ( mds->polV == NULL )
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "mds->polV" );
	  mds_pntr += SCIA_LV1_RD_PolV( mds_pntr, mds->n_pol, mds->polV );
/*
 * add integration times
 */
	  for ( ncc = ni = 0; ni < state->num_intg; ni++ ) {
	       unsigned short n_pol_intg = 
		    state->num_polar[ni] / state->num_dsr;

	       for ( nr = 0; nr < n_pol_intg; nr++ )
		    mds->polV[ncc + nr].intg_time = state->intg_times[ni];
	       ncc += n_pol_intg;
	  }
     }
/*
 * cluster data
 */
     (void) strcpy( msg, "" );
     nc = ncc = 0;
     do {
	  unsigned short num = 
	       state->Clcon[nc].length * state->Clcon[nc].n_read;

	  switch ( state->Clcon[nc].type ) {
	  case RSIG:
	  case ESIG:
	       if ( Get_Bit_LL( clus_mask, (unsigned char) nc ) == 0ULL ){
		    size_t byte_dest = ncc * mds->n_aux;
		    size_t byte_src  = (ncc + 1) * mds->n_aux;
		    size_t bytes_to_move = 
			 (state->num_clus - ncc - 1) * mds->n_aux;

		    (void) memmove( mds->red_grass + byte_dest, 
				    mds->red_grass + byte_src, bytes_to_move );
		    mds_pntr += num * (2 * ENVI_CHAR + ENVI_USHRT);
	       } else {
		    /* mds->clus[ncc].id = state->Clcon[nc].id; */
		    mds->clus[ncc].sig = (struct Sig_scia *)
			 malloc( (size_t) num * SCIA_SIG );
		    if ( mds->clus[ncc].sig == NULL ) {
			 (void) snprintf( msg, 25, "clus[%-hu].sig", nc );
			 NADC_GOTO_ERROR( NADC_ERR_ALLOC, msg );
		    }
		    nr = 0;
		    do {
			 (void) memcpy( &mds->clus[ncc].sig[nr].corr,
					mds_pntr, ENVI_CHAR );
			 mds_pntr += ENVI_CHAR;
			 (void) memcpy( &mds->clus[ncc].sig[nr].sign,
					mds_pntr, ENVI_USHRT );
#ifdef _SWAP_TO_LITTLE_ENDIAN
			 mds->clus[ncc].sig[nr].sign = 
			      byte_swap_u16( mds->clus[ncc].sig[nr].sign );
#endif
			 mds_pntr += ENVI_USHRT;
			 (void) memcpy( &mds->clus[ncc].sig[nr].stray,
					mds_pntr, ENVI_CHAR );
			 mds_pntr += ENVI_CHAR;
		    } while ( ++nr < num );
		    mds->clus[ncc++].n_sig = num;
	       }
	       break;
	  case RSIGC:
	  case ESIGC:
	       if ( Get_Bit_LL( clus_mask, (unsigned char) nc ) == 0ULL ){
		    size_t byte_dest = ncc * mds->n_aux;
		    size_t byte_src  = (ncc + 1) * mds->n_aux;
		    size_t bytes_to_move = 
			 (state->num_clus - ncc - 1) * mds->n_aux;

		    (void) memmove( mds->red_grass + byte_dest, 
				    mds->red_grass + byte_src, bytes_to_move );
		    mds_pntr += num * (ENVI_CHAR + ENVI_UINT);
	       } else {
		    /* mds->clus[ncc].id = state->Clcon[nc].id; */
		    mds->clus[ncc].sigc = (struct Sigc_scia *)
			 malloc( (size_t) num * SCIA_SIGC );
		    if ( mds->clus[ncc].sigc == NULL ) {
			 (void) snprintf( msg, 25, "clus[%-hu].sigc", nc );
			 NADC_GOTO_ERROR( NADC_ERR_ALLOC, msg );
		    }
		    nr = 0;
		    do {
			 (void) memcpy( 
			      &mds->clus[ncc].sigc[nr].det.four_byte,
			      mds_pntr, ENVI_UINT );
#ifdef _SWAP_TO_LITTLE_ENDIAN
			 mds->clus[ncc].sigc[nr].det.four_byte = 
			      byte_swap_u32( 
				   mds->clus[ncc].sigc[nr].det.four_byte );
#endif
			 mds_pntr += ENVI_UINT;
			 (void) memcpy( &mds->clus[ncc].sigc[nr].stray,
					mds_pntr, ENVI_CHAR );
			 mds_pntr += ENVI_CHAR;
		    } while ( ++nr < num );
		    mds->clus[ncc++].n_sigc = num;
	       }
	       break;
	  default:
	       (void) snprintf( msg, 25, "unknown reticon type: %02hu",
				(unsigned short) state->Clcon[nc].type );
	       NADC_GOTO_ERROR( NADC_ERR_FATAL, msg );
	  }
     } while ( ++nc < state->num_clus );
     mds->n_clus = ncc;
/*
 * check if we read the whole DSR
 */
     if ( (nr_byte = mds_pntr - mds_char) != (size_t) state->length_dsr ) {
	  (void) snprintf( msg, 64, "MDS[%-u]: expected: %6u - read: %6zd",
			   state->indx, state->length_dsr, nr_byte );
	  NADC_GOTO_ERROR( NADC_ERR_PDS_SIZE, msg );
     }
/*
 * deallocate memory
 */
 done:
     free( glint_flags );
     free( mds_char );
     return;
}
Ejemplo n.º 3
0
/*+++++++++++++++++++++++++
.IDENTifer   SCIA_LV1_RD_MDS
.PURPOSE     read MDS of one state from a SCIAMACHY level 1b product
.INPUT/OUTPUT
  call as   nr_mds = SCIA_LV1_RD_MDS( fd, clus_mask, state, &mds );
     input:  
            FILE    *fd               : (open) stream pointer
	    ulong64 clus_mask         : mask for cluster selection
 in/output:  
	    struct state1_scia *state : structure with States of the product
    output:  
            struct mds1_scia **mds    : structure for level 1b MDS records

.RETURNS     number of level 1b MDS read (unsigned int), 
             error status passed by global variable ``nadc_stat''
.COMMENTS    This routine allocates memory for the following variables:
               sat_flags, red_grass, glint_flags, geoN/geoL/geoC, lvl0_header,
	       int_pmd, polV
	     and depending up on the cluster configuration:
	       clus[].sig, clus[].sigc
-------------------------*/
unsigned int SCIA_LV1_RD_MDS( FILE *fd, unsigned long long clus_mask,
			      struct state1_scia *state,
			      struct mds1_scia **mds_out )
     /*@globals  source;@*/
     /*@modifies source@*/
{
     register unsigned short nc, ncc;
     register unsigned int   nr_mds = 0;

     unsigned int num_mds = state->num_dsr;

     struct mds1_scia *mds = NULL;

     if ( num_mds == 0 || mds_out == NULL ) {
	  if ( mds_out != NULL ) *mds_out = NULL;
	  return 0u;
     }
/*
 * set variable source (= type of MDS)
 */
     source = (int) state->type_mds;
/*
 * allocate memory to store output records
 */
     mds = (struct mds1_scia *) malloc( num_mds * sizeof(struct mds1_scia));
     if ( mds == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "mds1_scia" );
     *mds_out = mds;
/*
 * rewind/read input data file
 */
     (void) fseek( fd, (long) state->offset, SEEK_SET );
/*
 * initialize the MDS record and read MDS data of the selected state
 */
     sec_in_scan = 1;
     indx_limb = 0;
     do {
	  mds->type_mds = state->type_mds;
	  mds->state_id = (unsigned char) state->state_id;
	  mds->state_index = (unsigned char) state->indx;
	  mds->n_clus = 0;
	  mds->n_aux = state->num_aux / state->num_dsr;
	  if ( source != SCIA_MONITOR ) {
	       mds->n_pmd = PMD_NUMBER * state->num_pmd / state->num_dsr;
	       mds->n_pol = state->total_polar / state->num_dsr;
	  } else {
	       mds->n_pmd = 0u;
	       mds->n_pol = 0u;
	  }
	  mds->sat_flags = NULL;
	  mds->red_grass = NULL;
	  mds->lv0 = NULL;
	  mds->geoC = NULL;
	  mds->geoL = NULL;
	  mds->geoN = NULL;
	  mds->int_pmd = NULL;
	  mds->polV = NULL;
	  for ( nc = 0; nc < MAX_CLUSTER; nc++ ) {
	       mds->clus[nc].n_sig  = 0u;
	       mds->clus[nc].sig = NULL;
	       mds->clus[nc].n_sigc = 0u;
	       mds->clus[nc].sigc = NULL;
	  }
	  SCIA_LV1_RD_ONE_MDS( fd, clus_mask, state, mds );
	  if ( IS_ERR_STAT_FATAL ) 
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "ONE_MDS" );
/*
 * byte swap data to local representation
 */
#ifdef _SWAP_TO_LITTLE_ENDIAN
	  Sun2Intel_L1B_MDS( mds );
#endif
     } while ( mds++, ++nr_mds < num_mds );
/*
 * update state-record to reflect the actual cluster stored in the MDS record
 */
     for ( nc = ncc = 0; nc < state->num_clus; nc++ ) {
	  if ( Get_Bit_LL( clus_mask, (unsigned char) nc ) == 1ULL ) {
	       if ( ncc < nc )
		    (void) memmove( &state->Clcon[ncc], &state->Clcon[nc],
				    sizeof( struct Clcon_scia ) );
	       ncc++;
	  }
     }
     state->num_clus = ncc;
/*
 * set return values
 */
     return nr_mds;
 done:
     *mds_out = NULL;
     if ( (mds -= nr_mds) != NULL ) SCIA_LV1_FREE_MDS( source, nr_mds, mds );
     return 0u;
}
Ejemplo n.º 4
0
/*+++++++++++++++++++++++++ Main Program or Function +++++++++++++++*/
unsigned int SCIA_LV1_SELECT_MDS( int source, 
				  const struct param_record param,
				  FILE *fp, unsigned int num_dsd, 
				  const struct dsd_envi *dsd,
				  struct state1_scia **mds_state )
{
     register unsigned int ni = 0;
     register unsigned int num_not = 0;
     register unsigned int num_select = 0;

     int          mjd2000;
     unsigned int secnd, mu_sec;
     unsigned int num_state;

     unsigned int indx_dsd, *indx_state = NULL;

     double       bgn_jdate = 0.;
     double       end_jdate = 0.;

     struct lads_scia   *lads = NULL;
     struct state1_scia *state = NULL;

     const double SecPerDay = 24. * 60. * 60.;

     const bool Save_Extern_Alloc = Use_Extern_Alloc;
/*
 * initialize output array
 */
     *mds_state = NULL;
/*
 * first check type of selected MDS
 */
     switch ( source ) {
     case SCIA_NADIR:
	  if ( param.write_nadir != PARAM_SET ) return 0u;
	  indx_dsd = ENVI_GET_DSD_INDEX( num_dsd, dsd, "NADIR" );
	  if ( IS_ERR_STAT_FATAL )
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "NADIR" );
	  if ( dsd[indx_dsd].num_dsr == 0 ) return 0u;
	  break;
     case SCIA_LIMB:
	  if ( param.write_limb != PARAM_SET ) return 0u;
	  indx_dsd = ENVI_GET_DSD_INDEX( num_dsd, dsd, "LIMB" );
	  if ( IS_ERR_STAT_FATAL )
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "LIMB" );
	  if ( dsd[indx_dsd].num_dsr == 0 ) return 0u;
	  break;
     case SCIA_OCCULT:
	  if ( param.write_occ != PARAM_SET ) return 0u;
	  indx_dsd = ENVI_GET_DSD_INDEX( num_dsd, dsd, "OCCULTATION" );
	  if ( IS_ERR_STAT_FATAL )
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "OCCULTATION" );
	  if ( dsd[indx_dsd].num_dsr == 0 ) return 0u;
	  break;
     case SCIA_MONITOR:
	  if ( param.write_moni != PARAM_SET ) return 0u;
	  indx_dsd = ENVI_GET_DSD_INDEX( num_dsd, dsd, "MONITORING" );
	  if ( IS_ERR_STAT_FATAL )
	       NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "MONITORING" );
	  if ( dsd[indx_dsd].num_dsr == 0 ) return 0u;
	  break;
     default:
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, "unknown MDS state" );
     }
/*
 * initialize begin and end julian date of time window
 */
     if ( param.flag_period == PARAM_SET ) {
	  ASCII_2_MJD( param.bgn_date, &mjd2000, &secnd, &mu_sec );
	  bgn_jdate = mjd2000 + (secnd + mu_sec / 1e6) / SecPerDay;
	  ASCII_2_MJD( param.end_date, &mjd2000, &secnd, &mu_sec );
	  end_jdate = mjd2000 + (secnd + mu_sec / 1e6) / SecPerDay;
     }
/*
 * read State of the Products (ADS)
 */
     Use_Extern_Alloc = FALSE;
     num_state = SCIA_LV1_RD_STATE( fp, num_dsd, dsd, &state );
     Use_Extern_Alloc = Save_Extern_Alloc;
     if ( IS_ERR_STAT_FATAL )
          NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "STATE" );
/*
 * read Geolocation of States (LADS)
 */
     Use_Extern_Alloc = FALSE;
     (void) SCIA_RD_LADS( fp, num_dsd, dsd, &lads );
     Use_Extern_Alloc = Save_Extern_Alloc;
     if ( IS_ERR_STAT_FATAL )
          NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "LADS" );
/*
 * allocate memory to store indices to selected MDS records
 */
     indx_state = (unsigned int *) malloc( num_state * sizeof( unsigned int ));
     if ( indx_state == NULL ) 
	  NADC_GOTO_ERROR( NADC_ERR_ALLOC, "indx_state" );
/*
 * go through all state-records
 */
     do {
	  if ( (int) state[ni].type_mds == source 
	       && state[ni].flag_mds == MDS_ATTACHED  ) {

	       if ( param.flag_period == PARAM_SET ) {
		    double mjd_date;

		    mjd_date = state[ni].mjd.days 
			 + (state[ni].mjd.secnd 
			    + state[ni].mjd.musec / 1e6) / SecPerDay;
		    if ( mjd_date < bgn_jdate ) goto Not_Selected;

		    mjd_date += (state[ni].dur_scan / 16.) / SecPerDay;
		    if ( mjd_date > end_jdate ) goto Not_Selected;
	       }

	       if ( ! IS_SELECTED_CAT( param, state[ni].category ) )
		    goto Not_Selected;

	       if ( ! IS_SELECTED_STATE( param, state[ni].state_id ) )
		    goto Not_Selected;

	       if ( param.clus_mask != ~0ULL ) {
		    register unsigned short nc = 0;

		    register bool found = FALSE;
		    do {
			 if ( Get_Bit_LL( param.clus_mask, 
					  (unsigned char) nc ) != 0ULL ){
			      found = TRUE;
			      break;
			 }
		    } while ( ++nc < state[ni].num_clus );
		    if ( ! found ) goto Not_Selected;
	       }

	       if ( param.chan_mask != BAND_ALL ) {
		    register unsigned short nc = 0;

		    register bool found = FALSE;
		    do {
			 if ( SELECTED_CHANNEL( param.chan_mask,
						state[ni].Clcon[nc].channel )){
			      found = TRUE;
			      break;
			 }
		    } while ( ++nc < state[ni].num_clus );
		    if ( ! found ) goto Not_Selected;
	       }

	       if ( param.flag_geoloc == PARAM_SET ) {
		    if ( ! IS_SELECTED_GEO( param, lads[ni].corner ) )
			 goto Not_Selected;
	       }

	       indx_state[num_select++] = ni;
	  Not_Selected:
	       num_not++;  /* FAKE counter, NOT used! */ 
	  }
     } while ( ++ni < num_state );
/*
 * copy selected state-records to output array
 */
     SCIA_LV1_EXPORT_NUM_STATE( source, (unsigned short) num_select );
     if ( num_select > 0u ) {
	  *mds_state = (struct state1_scia *) 
	       malloc( num_select * sizeof( struct state1_scia ));
	  if ( *mds_state == NULL ) {
	       num_select = 0u;
	       NADC_GOTO_ERROR( NADC_ERR_ALLOC, "mds_state" );
	  }
	  for ( ni = 0; ni < num_select; ni++ )
	       (void) memcpy( &(*mds_state)[ni], &state[indx_state[ni]],
			      sizeof( struct state1_scia ) );
     }
 done:
     if ( lads != NULL ) free( lads );
     if ( state != NULL ) free( state );
     if ( indx_state != NULL ) free( indx_state );
     return num_select;
}