void smf_calcmodel_pln( ThrWorkForce *wf, smfDIMMData *dat, int chunk, AstKeyMap *keymap, smfArray **allmodel, int flags __attribute__((unused)), int *status) { /* Local Variables */ size_t bstride; /* bolo stride */ size_t i; /* Loop counter */ dim_t idx=0; /* Index within subgroup */ AstKeyMap *kmap=NULL; /* Pointer to PLN-specific keys */ smfArray *model=NULL; /* Pointer to model at chunk */ double *model_data=NULL; /* Pointer to DATA component of model */ double *model_data_copy=NULL; /* Copy of model_data for one bolo */ int *lut_data = NULL; /* Lut data for one subarray */ dim_t nbolo=0; /* Number of bolometers */ dim_t ndata=0; /* Total number of data points */ int notfirst=0; /* flag for delaying until after 1st iter */ dim_t ntslice=0; /* Number of time slices */ smfArray *qua=NULL; /* Pointer to QUA at chunk */ smf_qual_t *qua_data=NULL; /* Pointer to quality data */ smfArray *res=NULL; /* Pointer to RES at chunk */ smfArray *lut=NULL; /* Pointer to LUT at chunk */ double *res_data=NULL; /* Pointer to DATA component of res */ size_t tstride; /* Time slice stride in data array */ /* Main routine */ if (*status != SAI__OK) return; /* Obtain pointer to sub-keymap containing PLN parameters. Something will always be available.*/ astMapGet0A( keymap, "PLN", &kmap ); /* Are we skipping the first iteration? */ astMapGet0I(kmap, "NOTFIRST", ¬first); if( notfirst && (flags & SMF__DIMM_FIRSTITER) ) { msgOutif( MSG__VERB, "", FUNC_NAME ": skipping PLN this iteration", status ); return; } /* Obtain pointers to relevant smfArrays for this chunk */ res = dat->res[chunk]; qua = dat->qua[chunk]; lut = dat->lut[chunk]; /* Assert ICD-ordered data */ smf_model_dataOrder( wf, dat, allmodel, chunk, SMF__RES|SMF__QUA|SMF__LUT, 1, status ); smf_get_dims( res->sdata[0], NULL, NULL, NULL, NULL, &ndata, NULL, NULL, status); model = allmodel[chunk]; /* Loop over index in subgrp (subarray) and put the previous iteration of the filtered component back into the residual before calculating and removing the new filtered component */ for( idx=0; (*status==SAI__OK)&&(idx<res->ndat); idx++ ) { /* Obtain dimensions of the data */ smf_get_dims( res->sdata[idx], NULL, NULL, &nbolo, &ntslice, &ndata, &bstride, &tstride, status); /* Get pointers to data/quality/model */ res_data = (res->sdata[idx]->pntr)[0]; qua_data = (qua->sdata[idx]->pntr)[0]; model_data = (model->sdata[idx]->pntr)[0]; lut_data = (lut->sdata[idx]->pntr)[0]; if( (res_data == NULL) || (model_data == NULL) || (qua_data == NULL) ) { *status = SAI__ERROR; errRep( "", FUNC_NAME ": Null data in inputs", status); } else { if( *status == SAI__OK ) { /* Place last iteration of plane signal back into residual */ for (i=0; i< nbolo*ntslice; i++) { if ( !(qua_data[i]&SMF__Q_MOD) && res_data[i] != VAL__BADD && model_data[i] != VAL__BADD ) { res_data[i] += model_data[i]; } } /* Copy the residual+old model into model_data where it will be fitted again in this iteration. */ memcpy( model_data, res_data, ndata*smf_dtype_size(res->sdata[idx],status) ); } /* Calculate the fit and subtract it*/ smf_subtract_plane3( wf, res->sdata[idx], dat->mdims, lut_data, status ); /* Store the difference between the plane-subtracted signal and the residual in the model container */ if( *status == SAI__OK ) { for (i=0; i< nbolo*ntslice; i++) { if ( !(qua_data[i]&SMF__Q_MOD) && res_data[i] != VAL__BADD && model_data[i] != VAL__BADD ) { model_data[i] -= res_data[i]; } else { model_data[i] = VAL__BADD; } } } } } if( kmap ) kmap = astAnnul( kmap ); model_data_copy = astFree( model_data_copy ); }
void smurf_smurfcopy ( int * status ) { smfData * data = NULL; /* input file struct */ size_t dtypsz; /* Number of bytes in data type */ Grp *fgrp = NULL; /* Filtered group, no darks */ size_t i; /* Loop counter */ smfFile * ifile = NULL; /* Input smfFile */ Grp *igrp = NULL; /* Input group */ unsigned char * inptr = NULL; /* Pointer to start of section to copy */ int islice; /* int time slice from parameter */ int lbnd[2]; /* Lower coordinate bounds of output file */ size_t nelem; /* Number of elements to copy */ smfData * odata = NULL; /* output file struct */ size_t offset; /* offset into data array */ smfFile * ofile = NULL; /* output smfFile */ Grp *ogrp = NULL; /* Output group */ size_t outsize; /* Total number of NDF names in the output group */ dim_t slice; /* Time index to extract */ size_t size; /* Number of files in input group */ int ubnd[2]; /* Upper coordinate bounds of output file */ if (*status != SAI__OK) return; ndfBegin(); /* Read the input file */ /* As a proof of concept do not allow multiple input files */ kpg1Rgndf( "IN", 1, 1, "", &igrp, &size, status ); /* Filter out darks */ smf_find_science( igrp, &fgrp, 1, NULL, NULL, 0, 0, SMF__NULL, NULL, NULL, NULL, NULL, status ); /* input group is now the filtered group so we can use that and free the old input group */ size = grpGrpsz( fgrp, status ); grpDelet( &igrp, status); igrp = fgrp; fgrp = NULL; if (size > 0) { /* Get output file(s) */ kpg1Wgndf( "OUT", igrp, size, size, "More output files required...", &ogrp, &outsize, status ); } else { msgOutif(MSG__NORM, " ","All supplied input frames were DARK," " nothing to extract", status ); } /* Allow the user to specify a text file containing a table of pointing corrections. Corresponding Mappings are created form the column data in this table and stored in the "igrp" group as items of metadata. */ smf_pread( igrp, "POINTING", status ); /* Use a loop so that we look like other routines and simplify the change if we support multiple input files */ for (i=1; i<=size; i++) { /* Open the input file using standard routine */ smf_open_and_flatfield( igrp, NULL, i, NULL, NULL, NULL, &data, status ); if (*status != SAI__OK) break; if (*status == SAI__OK) { if (!data->file->isTstream || data->ndims != 3) { smf_close_file( &data, status ); *status = SAI__ERROR; errRep(" ", "Input data do not represent time series", status); break; } } /* get the slice position - knowing the maximum allowed Somewhat problematic in a loop if we want to allow different slices per file. Best bet is to allow multiple slices in a single file but only one file. */ msgSeti( "MAX", (data->dims)[2] ); msgOutif( MSG__NORM, " ", "File has ^MAX slices.", status ); parGdr0i( "SLICE",1, 0, (data->dims)[2], 1, &islice, status); slice = islice; if (slice == 0) slice = (data->dims)[2]; /* construct output bounds */ lbnd[0] = (data->lbnd)[0]; lbnd[1] = (data->lbnd)[1]; ubnd[0] = lbnd[0] + (data->dims)[0] - 1; ubnd[1] = lbnd[1] + (data->dims)[1] - 1; /* Open an output file (losing history) but we do not want to propagate the full NDF size to the output file */ smf_open_newfile( ogrp, i, data->dtype, 2, lbnd, ubnd, 0, &odata, status ); ofile = odata->file; ifile = data->file; /* protect against null pointer smfFile */ if (*status == SAI__OK) { /* sort out provenance */ smf_accumulate_prov( data, igrp, i, ofile->ndfid, "SMURF:SMURFCOPY", NULL, status ); /* copy the slice in */ dtypsz = smf_dtype_size( odata, status ); nelem = (data->dims)[0] * (data->dims)[1]; offset = (slice - 1) * nelem * dtypsz; inptr = (data->pntr)[0]; memcpy( (odata->pntr)[0], inptr + offset, nelem * dtypsz ); /* World coordinates - note the 0 indexing relative to GRID */ smf_tslice_ast( data, slice-1, 1, status ); ndfPtwcs( data->hdr->wcs, ofile->ndfid, status ); /* Write the FITS header */ kpgPtfts( ofile->ndfid, data->hdr->fitshdr, status ); /* JCMTSTATE */ sc2store_writejcmtstate( ofile->ndfid, 1, &((data->hdr->allState)[slice-1]), status ); } /* cleanup */ smf_close_file( &data, status ); smf_close_file( &odata, status ); } /* tidy */ if (igrp) { smf_pread( igrp, NULL, status ); grpDelet( &igrp, status ); } if (ogrp) grpDelet( &ogrp, status ); ndfEnd(status); }