static void Sun2Intel_BIAS( struct bias_scia *bias ) { register unsigned short nc; unsigned int n_cross; bias->mjd.days = byte_swap_32( bias->mjd.days ); bias->mjd.secnd = byte_swap_u32( bias->mjd.secnd ); bias->mjd.musec = byte_swap_u32( bias->mjd.musec ); bias->dsrlen = byte_swap_u32( bias->dsrlen ); bias->intg_time = byte_swap_u16( bias->intg_time ); bias->numsegm = byte_swap_u16( bias->numsegm ); IEEE_Swap__FLT( &bias->hght ); IEEE_Swap__FLT( &bias->errhght ); IEEE_Swap__FLT( &bias->vcd ); IEEE_Swap__FLT( &bias->errvcd ); IEEE_Swap__FLT( &bias->closure ); IEEE_Swap__FLT( &bias->errclosure ); IEEE_Swap__FLT( &bias->rms ); IEEE_Swap__FLT( &bias->chi2 ); IEEE_Swap__FLT( &bias->goodness ); IEEE_Swap__FLT( &bias->cutoff ); bias->numiter = byte_swap_u16( bias->numiter ); n_cross = (bias->numfitp * (bias->numfitp - 1)) / 2; for ( nc = 0; nc < n_cross; nc++ ) IEEE_Swap__FLT( &bias->corrpar[nc] ); }
static void Sun2Intel_SMCD( struct smcd_gome *smcd ) { register int ni; smcd->indx_spec = byte_swap_16( smcd->indx_spec ); smcd->indx_leak = byte_swap_16( smcd->indx_leak ); ni = 0; do { smcd->indx_bands[ni] = byte_swap_16( smcd->indx_bands[ni] ); } while ( ++ni < NUM_SPEC_BANDS ); smcd->utc_date = byte_swap_u32( smcd->utc_date ); smcd->utc_time = byte_swap_u32( smcd->utc_time ); IEEE_Swap__FLT( &smcd->north_sun_zen ); IEEE_Swap__FLT( &smcd->north_sun_azim ); IEEE_Swap__FLT( &smcd->north_sm_zen ); IEEE_Swap__FLT( &smcd->north_sm_azim ); IEEE_Swap__FLT( &smcd->sun_or_moon ); IEEE_Swap__FLT( &smcd->dark_current ); IEEE_Swap__FLT( &smcd->noise_factor ); smcd->ihr.subsetcounter = byte_swap_u16( smcd->ihr.subsetcounter ); smcd->ihr.prism_temp = byte_swap_u16( smcd->ihr.prism_temp ); smcd->ihr.averagemode = byte_swap_u16( smcd->ihr.averagemode ); smcd->ihr.intg.two_byte = byte_swap_u16( smcd->ihr.intg.two_byte ); ni = 0; do { smcd->ihr.pmd[0][ni] = byte_swap_u16( smcd->ihr.pmd[0][ni] ); smcd->ihr.pmd[1][ni] = byte_swap_u16( smcd->ihr.pmd[1][ni] ); smcd->ihr.pmd[2][ni] = byte_swap_u16( smcd->ihr.pmd[2][ni] ); } while ( ++ni < PMD_IN_GRID ); ni = 0; do { smcd->ihr.peltier[ni] = byte_swap_u16( smcd->ihr.peltier[ni] ); } while ( ++ni < SCIENCE_CHANNELS ); }
static void Sun2Intel_SQADS( struct sqads2_meris *sqads ) { sqads->mjd.days = byte_swap_32( sqads->mjd.days ); sqads->mjd.secnd = byte_swap_u32( sqads->mjd.secnd ); sqads->mjd.musec = byte_swap_u32( sqads->mjd.musec ); }
static void Sun2Intel_DOAS( struct doas_scia *doas ) { register unsigned short nc; unsigned int n_cross; doas->mjd.days = byte_swap_32( doas->mjd.days ); doas->mjd.secnd = byte_swap_u32( doas->mjd.secnd ); doas->mjd.musec = byte_swap_u32( doas->mjd.musec ); doas->dsrlen = byte_swap_u32( doas->dsrlen ); doas->intg_time = byte_swap_u16( doas->intg_time ); IEEE_Swap__FLT( &doas->vcd ); IEEE_Swap__FLT( &doas->errvcd ); IEEE_Swap__FLT( &doas->esc ); IEEE_Swap__FLT( &doas->erresc ); IEEE_Swap__FLT( &doas->rms ); IEEE_Swap__FLT( &doas->chi2 ); IEEE_Swap__FLT( &doas->goodness ); IEEE_Swap__FLT( &doas->amfgnd ); IEEE_Swap__FLT( &doas->amfcld ); IEEE_Swap__FLT( &doas->reflgnd ); IEEE_Swap__FLT( &doas->reflcld ); IEEE_Swap__FLT( &doas->refl ); doas->numiter = byte_swap_u16( doas->numiter ); n_cross = (doas->numfitp * (doas->numfitp - 1)) / 2; for ( nc = 0; nc < n_cross; nc++ ) IEEE_Swap__FLT( &doas->corrpar[nc] ); }
static void Sun2Intel_MDS_14( struct mds_rr2_14_meris *mds_14 ) { mds_14->mjd.days = byte_swap_32( mds_14->mjd.days ); mds_14->mjd.secnd = byte_swap_u32( mds_14->mjd.secnd ); mds_14->mjd.musec = byte_swap_u32( mds_14->mjd.musec ); }
static void Sun2Intel_CLD( struct cld_sci_ol *cld ) { register unsigned short np; cld->mjd.days = byte_swap_32( cld->mjd.days ); cld->mjd.secnd = byte_swap_u32( cld->mjd.secnd ); cld->mjd.musec = byte_swap_u32( cld->mjd.musec ); cld->dsrlen = byte_swap_u32( cld->dsrlen ); cld->intg_time = byte_swap_u16( cld->intg_time ); IEEE_Swap__FLT( &cld->surfpress ); IEEE_Swap__FLT( &cld->cloudfrac ); IEEE_Swap__FLT( &cld->errcldfrac ); cld->numpmdpix = byte_swap_u16( cld->numpmdpix ); cld->fullfree[0] = byte_swap_u16( cld->fullfree[0] ); cld->fullfree[1] = byte_swap_u16( cld->fullfree[1] ); IEEE_Swap__FLT( &cld->toppress ); IEEE_Swap__FLT( &cld->errtoppress ); IEEE_Swap__FLT( &cld->cldoptdepth ); IEEE_Swap__FLT( &cld->errcldoptdep ); cld->cloudtype = byte_swap_u16( cld->cloudtype ); IEEE_Swap__FLT( &cld->cloudbrdf ); IEEE_Swap__FLT( &cld->errcldbrdf ); IEEE_Swap__FLT( &cld->effsurfrefl ); IEEE_Swap__FLT( &cld->erreffsrefl ); cld->cloudflag = byte_swap_u16( cld->cloudflag ); IEEE_Swap__FLT( &cld->aai ); IEEE_Swap__FLT( &cld->aaidiag ); cld->aaiflag = byte_swap_u16( cld->aaiflag ); for ( np = 0; np < cld->numaeropars; np++ ) IEEE_Swap__FLT( &cld->aeropars[np] ); }
static void Sun2Intel_PPGN( struct ppgn_scia *ppgn ) { register int ni = 0; ppgn->mjd.days = byte_swap_32( ppgn->mjd.days ); ppgn->mjd.secnd = byte_swap_u32( ppgn->mjd.secnd ); ppgn->mjd.musec = byte_swap_u32( ppgn->mjd.musec ); do { IEEE_Swap__FLT( &ppgn->gain_fact[ni] ); IEEE_Swap__FLT( &ppgn->etalon_fact[ni] ); IEEE_Swap__FLT( &ppgn->etalon_resid[ni] ); IEEE_Swap__FLT( &ppgn->avg_wls_spec[ni] ); IEEE_Swap__FLT( &ppgn->sd_wls_spec[ni] ); } while ( ++ni < (SCIENCE_PIXELS) ); }
static void Sun2Intel_GEO( struct geo_scia *geo ) { register unsigned short ni; geo->mjd.days = byte_swap_32( geo->mjd.days ); geo->mjd.secnd = byte_swap_u32( geo->mjd.secnd ); geo->mjd.musec = byte_swap_u32( geo->mjd.musec ); geo->intg_time = byte_swap_u16( geo->intg_time ); IEEE_Swap__FLT( &geo->sat_h ); IEEE_Swap__FLT( &geo->earth_rad ); for ( ni = 0; ni < 3; ni++ ) { IEEE_Swap__FLT( &geo->sun_zen_ang[ni] ); IEEE_Swap__FLT( &geo->los_zen_ang[ni] ); IEEE_Swap__FLT( &geo->rel_azi_ang[ni] ); } for ( ni = 0; ni < 4; ni++ ) { geo->corner[ni].lon = byte_swap_32( geo->corner[ni].lon ); geo->corner[ni].lat = byte_swap_32( geo->corner[ni].lat ); } geo->center.lon = byte_swap_32( geo->center.lon ); geo->center.lat = byte_swap_32( geo->center.lat ); }
static void Sun2Intel_LFIT( struct lfit_scia *lfit ) { register unsigned short ni, nj, np, nr; lfit->mjd.days = byte_swap_32( lfit->mjd.days ); lfit->mjd.secnd = byte_swap_u32( lfit->mjd.secnd ); lfit->mjd.musec = byte_swap_u32( lfit->mjd.musec ); lfit->dsrlen = byte_swap_u32( lfit->dsrlen ); lfit->intg_time = byte_swap_u16( lfit->intg_time ); IEEE_Swap__FLT( &lfit->refh ); IEEE_Swap__FLT( &lfit->refp ); for ( ni = nj = np = 0; np < lfit->num_rlevel; np++ ) { IEEE_Swap__FLT( &lfit->tangh[np] ); IEEE_Swap__FLT( &lfit->tangp[np] ); IEEE_Swap__FLT( &lfit->tangt[np] ); for ( nr = 0; nr < lfit->num_species; nr++, ni++ ) { IEEE_Swap__FLT( &lfit->mainrec[ni].tangvmr ); IEEE_Swap__FLT( &lfit->mainrec[ni].errtangvmr ); IEEE_Swap__FLT( &lfit->mainrec[ni].vertcol ); IEEE_Swap__FLT( &lfit->mainrec[ni].errvertcol ); } for ( nr = 0; nr < lfit->num_scale; nr++, nj++ ) { IEEE_Swap__FLT( &lfit->scaledrec[nj].tangvmr ); IEEE_Swap__FLT( &lfit->scaledrec[nj].errtangvmr ); IEEE_Swap__FLT( &lfit->scaledrec[nj].vertcol ); IEEE_Swap__FLT( &lfit->scaledrec[nj].errvertcol ); } } /* struct meas_grid */ for ( np = 0; np < lfit->num_mlevel; np++ ) { lfit->mgrid[np].mjd.days = byte_swap_32( lfit->mgrid[np].mjd.days ); lfit->mgrid[np].mjd.secnd = byte_swap_u32( lfit->mgrid[np].mjd.secnd ); lfit->mgrid[np].mjd.musec = byte_swap_u32( lfit->mgrid[np].mjd.musec ); IEEE_Swap__FLT( &lfit->mgrid[np].tangh ); IEEE_Swap__FLT( &lfit->mgrid[np].tangp ); IEEE_Swap__FLT( &lfit->mgrid[np].tangt ); IEEE_Swap__FLT( &lfit->mgrid[np].win_limits[0] ); IEEE_Swap__FLT( &lfit->mgrid[np].win_limits[1] ); } /* struct state_vec */ for ( np = 0; np < lfit->stvec_size; np++ ) { IEEE_Swap__FLT( &lfit->statevec[np].value ); IEEE_Swap__FLT( &lfit->statevec[np].error ); } for ( np = 0; np < lfit->cmatrixsize; np++ ) IEEE_Swap__FLT( &lfit->corrmatrix[np] ); IEEE_Swap__FLT( &lfit->rms ); IEEE_Swap__FLT( &lfit->chi2 ); IEEE_Swap__FLT( &lfit->goodness ); lfit->numiter = byte_swap_u16( lfit->numiter ); lfit->summary[0] = byte_swap_u16( lfit->summary[0] ); lfit->summary[1] = byte_swap_u16( lfit->summary[1] ); for ( np = 0; np < lfit->ressize; np++ ) IEEE_Swap__FLT( &lfit->residuals[np] ); for ( np = 0; np < lfit->num_adddiag; np++ ) IEEE_Swap__FLT( &lfit->adddiag[np] ); }
/*+++++++++++++++++++++++++ .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; }
/*+++++++++++++++++++++++++ .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; }
/*+++++++++++++++++++++++++ .IDENTifer SCIA_LV1C_RD_MDS_POLV .PURPOSE read SCIAMACHY level 1c POLV MDS .INPUT/OUTPUT call as nr_mds = SCIA_LV1C_RD_MDS_POLV( fd, state, &polV ); input: FILE *fd : (open) stream pointer struct state1_scia *state : structure with States of the product output: struct mds1c_polV **polV : structure for level 1c POLV MDS .RETURNS number of level 1c POLV MDS read (unsigned int), error status passed by global variable ``nadc_stat'' .COMMENTS This routine allocates memory for the following variables: polV, geoN/geoL/geoC -------------------------*/ unsigned int SCIA_LV1C_RD_MDS_POLV( FILE *fd, const struct state1_scia *state, struct mds1c_polV **polV_out ) /*@globals source;@*/ /*@modifies source@*/ { char *mds_char, *mds_pntr; size_t dsr_length_left, nr_byte; unsigned short ubuff; struct mds1c_polV *polV; const size_t DSR_Read = sizeof(struct mjd_envi) + ENVI_UINT; /* * set variable source (= type of MDS) */ source = (int) state->type_mds; /* * check type of MDS */ if ( (source != SCIA_NADIR && source != SCIA_LIMB && source != SCIA_OCCULT) || state->offs_polV == 0L ) { *polV_out = NULL; return 0u; } /* * allocate memory to store output records */ *polV_out = (struct mds1c_polV *) malloc( sizeof(struct mds1c_polV) ); if ( (polV = *polV_out) == NULL ) { NADC_GOTO_ERROR( NADC_ERR_ALLOC, "mds1c_polV" ); } /* * initialize MDS-structure */ polV->total_polV = 0u; polV->num_geo = 0u; polV->polV = NULL; polV->geoN = NULL; polV->geoL = NULL; /* * rewind/read input data file */ (void) fseek( fd, (long) state->offs_polV, SEEK_SET ); /* * read data set records */ polV->type_mds = state->type_mds; polV->state_index = (unsigned char) state->indx; /* 1 */ if ( fread( &polV->mjd, sizeof( struct mjd_envi ), 1 , fd ) != 1 ) NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "" ); /* 2 */ if ( fread( &polV->dsr_length, ENVI_UINT, 1 , fd ) != 1 ) NADC_GOTO_ERROR( NADC_ERR_PDS_RD, "" ); #ifdef _SWAP_TO_LITTLE_ENDIAN polV->dsr_length = byte_swap_u32( polV->dsr_length ); #endif /* * now we know the size of this dsr, so read it in memory! */ dsr_length_left = polV->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( &polV->quality_flag, mds_char, ENVI_CHAR ); mds_pntr = mds_char + ENVI_CHAR; /* 4 */ (void) memcpy( &polV->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 polV->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 polV->state_id = (unsigned char) ubuff; /* 7 */ (void) memcpy( &polV->dur_scan, mds_pntr, ENVI_USHRT ); mds_pntr += ENVI_USHRT; /* 8 */ (void) memcpy( &polV->num_geo, mds_pntr, ENVI_USHRT ); mds_pntr += ENVI_USHRT; #ifdef _SWAP_TO_LITTLE_ENDIAN polV->num_geo = byte_swap_u16( polV->num_geo ); #endif /* 9 */ (void) memcpy( &polV->total_polV, mds_pntr, ENVI_USHRT ); mds_pntr += ENVI_USHRT; #ifdef _SWAP_TO_LITTLE_ENDIAN polV->total_polV = byte_swap_u16( polV->total_polV ); #endif /* 10 */ (void) memcpy( &polV->num_diff_intg, mds_pntr, ENVI_USHRT ); mds_pntr += ENVI_USHRT; /* 11 */ nr_byte = MAX_CLUSTER * ENVI_USHRT; (void) memcpy( polV->intg_times, mds_pntr, nr_byte ); mds_pntr += nr_byte; /* 12 */ (void) memcpy( polV->num_polar, mds_pntr, nr_byte ); mds_pntr += nr_byte; /* 13 */ nr_byte = polV->total_polV * sizeof( struct polV_scia ); polV->polV = (struct polV_scia *) malloc( nr_byte ); if ( polV->polV == NULL ) { free( mds_char ); NADC_GOTO_ERROR( NADC_ERR_ALLOC, "polV" ); } mds_pntr += SCIA_LV1_RD_PolV( mds_pntr, polV->total_polV, polV->polV ); /* 14 */ switch ( source ) { case SCIA_NADIR: polV->geoN = (struct geoN_scia *) malloc( polV->num_geo * sizeof( struct geoN_scia ) ); if ( polV->geoN == NULL ) { free( mds_char ); NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoN" ); } mds_pntr += SCIA_LV1_RD_GeoN(mds_pntr, polV->num_geo, polV->geoN); break; case SCIA_LIMB: case SCIA_OCCULT: polV->geoL = (struct geoL_scia *) malloc( polV->num_geo * sizeof( struct geoL_scia ) ); if ( polV->geoL == NULL ) { free( mds_char ); NADC_GOTO_ERROR( NADC_ERR_ALLOC, "geoL" ); } mds_pntr += SCIA_LV1_RD_GeoL(mds_pntr, polV->num_geo, polV->geoL); break; } /* * check if we read the whole DSR */ if ( (size_t)(mds_pntr - mds_char) != dsr_length_left ) { const char *dsd_names[] = { "UNKNOWN", "NADIR_FRAC_POL", "LIMB_FRAC_POL", "OCCULTATION_FRAC_POL" }; free( mds_char ); NADC_GOTO_ERROR( NADC_ERR_PDS_SIZE, dsd_names[source] ); } free( mds_char ); /* * byte swap data to local representation */ #ifdef _SWAP_TO_LITTLE_ENDIAN Sun2Intel_L1C_MDS_POLV( polV ); #endif /* * set return values */ polV = NULL; return 1; done: if ( polV != NULL ) SCIA_LV1C_FREE_MDS_POLV( source, polV ); return 0; }