Ejemplo n.º 1
0
void smf_close_file( smfData ** data, int * status ) {

  void *buf=NULL;         /* Buffer pointer */
  size_t buflen=0;        /* Size of buffer */
  smfDA   * da;           /* pointer to smfDA in smfData */
  smfFts* fts;            /* pointer to smfFts in smfData */
  size_t datalen=0;       /* Size of data buffer in bytes */
  smfDream *dream = NULL; /* Pointer to smfDream in smfData */
  smfFile * file;         /* pointer to smfFile in smfData */
  int       freedata = 0; /* should the data arrays be freed? */
  smfHead * hdr;          /* pointer to smfHead in smfData */
  size_t headlen=0;       /* Size of header (mmap'd files) in bytes */
  size_t       i;         /* loop counter */
  smfDIMMHead *temphead=NULL; /* Pointer to DIMM header */


  /* we need to be able to clean up even if input status is bad -
     this requires some defensive programming. */

  if ( *data == NULL ) {
    if ( *status == SAI__OK ) {
      /* Status is good so we have a problem */
      *status = SAI__ERROR;
      errRep( ERRFUNC, "Attempt to close file when smfData pointer is NULL (possible programming error)",
              status );
    }
    /* null pointer so just return since there is nothing to free */
    return;
  }

  /* Process reference count */
  /* Only proceed if the decremented reference count is 0 */
  (*data)->refcount--;

  if ((*data)->refcount > 0 ) return;

  /* Get the header and file, since we need them for checking */
  hdr = (*data)->hdr;

  /* Before annulling close NDF try closing SCU2RED.MAPCOORD */
  smf_close_mapcoord( *data, status );

  /* Display any warnings generated by AST and stored in the FitsChan. */
  file = (*data)->file;
  if( hdr && hdr->fitshdr ) {
    fts1Astwn( hdr->fitshdr,
               file ? file->ndfid : NDF__NOID,
               status );
  }

  /* now file information */
  if (file != NULL) {

    if ( file->isSc2store ) {
      /* Nothing to free here except for data */
      freedata = 1;

    } else if ( file->ndfid != NDF__NOID ) {

      /* Handle quality as a special case */
      if ( (*data)->qual) {
        (*data)->qual = smf_qual_unmap( file->ndfid, (*data)->qfamily,
                                        (*data)->qual, status );
      }

      /* Annul the NDF (which will unmap things) */
      ndfAnnul( &(file->ndfid), status );

    } else if( file->fd ) {
      /* Array was mmap'd to a file, and must now be sync'd and unmapped,
         and the file descriptor closed */

      /* Get the size of the header and data section */
      smf_calc_mmapsize( sizeof(*temphead), *data, &headlen, &datalen,
                         &buflen, status );

      /* The header is in the same mapped array as the data array,
         but headlen bytes earlier. Point temphead to this location and
         update relevant header values before closing */

      buf = ((char*)((*data)->pntr[0]) - headlen);
      temphead = (smfDIMMHead *) buf;
      temphead->data.isTordered = (*data)->isTordered;
      temphead->data.dtype = (*data)->dtype;
      temphead->data.ndims = (*data)->ndims;
      memcpy( temphead->data.dims, (*data)->dims, sizeof( temphead->data.dims));

      if( msync( buf, buflen, MS_ASYNC ) == -1 ) {
        *status = SAI__ERROR;
        errRep( ERRFUNC, "Unable to synch model container file", status );
      } else if( munmap( buf, buflen ) == -1 ) {
        *status = SAI__ERROR;
        errRep( ERRFUNC, "Unable to unmap model container file", status );
      } else if( close( file->fd ) == -1 ) {
        *status = SAI__ERROR;
        errRep( ERRFUNC, "Unable to close model container file", status );
      } else {
        file->fd = 0;
      }

    } else {
      /* No file so free the data */
      freedata = 1;
    }

    (*data)->file = astFree( (*data)->file );
  } else {
    /* no file - data is ours to free */
    freedata = 1;
  }


  /* Tidy up the header */
  if (hdr != NULL) {
    if (hdr->wcs != NULL) hdr->wcs = astAnnul( hdr->wcs );
    if (hdr->tswcs != NULL) hdr->tswcs = astAnnul( hdr->tswcs );
    if (hdr->fitshdr != NULL) hdr->fitshdr = astAnnul( hdr->fitshdr );

    if( hdr->cache1 ) hdr->cache1 = sc2ast_createwcs2( SC2AST__NULLSUB, NULL, 0.0, NULL, NULL, NULL,
                                                       hdr->cache1, status );
    if( hdr->cache2 ) hdr->cache2 = smf_create_lutwcs( 1, NULL, NULL, 0, NULL, 0.0, NULL,
                                                       NULL, NULL, hdr->cache2, status );
    if( hdr->cache3 ) hdr->cache3 = smf_detpos_wcs( NULL, -1, 0.0, NULL, NULL, hdr->cache3,
                                                    status );

    if (!hdr->isCloned) {
      /* We are responsible for this memory - although what happens
         when we are cloned and the original is freed first? Need
         to think carefully about memory management. */
      if (hdr->allState != NULL) {
        hdr->allState = astFree( hdr->allState );
      }
      if (hdr->fplanex) hdr->fplanex = astFree( hdr->fplanex );
      if (hdr->fplaney) hdr->fplaney = astFree( hdr->fplaney );
      if (hdr->detpos) hdr->detpos = astFree( hdr->detpos );
      if (hdr->tsys) hdr->tsys = astFree( hdr->tsys );
      if (hdr->detname) hdr->detname = astFree( hdr->detname );
      if (hdr->ocsconfig) hdr->ocsconfig = astFree( hdr->ocsconfig );
    }
    hdr = astFree( hdr );
  }

  /* Now the smfDA itself */
  if ( (*data)->da != NULL ) {
    da = (*data)->da;
    da->flatcal = astFree( da->flatcal );
    da->flatpar = astFree( da->flatpar );
    if( da->dksquid) smf_close_file( &da->dksquid, status );
    da->heatval = astFree( da->heatval );
    da = astFree( da );
  }

  /* Free smfFts */
  if((*data)->fts != NULL) {
    fts = (*data)->fts;
    if(fts->zpd) { smf_close_file(&fts->zpd, status); }
    if(fts->fpm) { smf_close_file(&fts->fpm, status); }
    if(fts->sigma) { smf_close_file(&fts->sigma, status); }
    fts = astFree(fts);
  }

  /* Free smfDream */
  if ( (*data)->dream != NULL ) {
    dream = (*data)->dream;
    if ( dream->gridwts != NULL)
      dream->gridwts = astFree( dream->gridwts );
    if ( dream->invmatx != NULL)
      dream->invmatx = astFree( dream->invmatx );
    dream= astFree( dream );
  }

  /* Free up other pointers in the smfData: */
  if ( (*data)->poly ) {
    (*data)->poly = astFree( (*data)->poly );
  }
  if ( (*data)->lut ) {
    (*data)->lut = astFree( (*data)->lut );
  }
  if( (*data)->theta ) {
    (*data)->theta = astFree( (*data)->theta );
  }

  /* Free the data arrays if they are non-null (they should have been
     freed if they were mapped to a file but not if they were stored
     in a separate action as temp storage */
  if (freedata) {
    for (i = 0; i < 2; i++ ) {
      if ( ((*data)->pntr)[i] != NULL )
        ((*data)->pntr)[i] = astFree( ((*data)->pntr)[i] );
    }
    if ( (*data)->qual ) {
      (*data)->qual = astFree( (*data)->qual );
    }
  }

  /* finally free smfData */
  *data = astFree( *data );

}
Ejemplo n.º 2
0
int smf_initial_sky( ThrWorkForce *wf, AstKeyMap *keymap, smfDIMMData *dat,
                     int *iters, int *status ) {

/* Local Variables: */
   char refparam[ DAT__SZNAM ];/* Name for reference NDF parameter */
   const char *cval;          /* The IMPORTSKY string value */
   double *ptr;               /* Pointer to NDF Data array */
   double *vptr;              /* Pointer to NDF Variance array */
   int indf1;                 /* Id. for supplied reference NDF */
   int indf2;                 /* Id. for used section of reference NDF */
   int nel;                   /* Number of mapped NDF pixels */
   int result;                /* Returned flag */
   int there;                 /* Is there a smurf extension in the NDF? */
   int update;                /* Was NDF opened for UPDATE access? */
   size_t i;                  /* Loop count */
   size_t junk;               /* Unused value */

/* Initialise the returned value to indicate no sky has been subtractred. */
   result = 0;

/* Assume the sky map was not created by an interupted previous run of
   makemap. */
   *iters = -1;

/* Check inherited status. */
   if( *status != SAI__OK ) return result;

/* Begin an AST context. */
   astBegin;

/* The IMPORTSKY config parameter should have the name of the ADAM
   parameter to use for acquiring the NDF that contains the initial sky
   estimate. If IMPORTSKY is "1", use REF. */
   cval = NULL;
   astMapGet0C( keymap, "IMPORTSKY", &cval );
   if( cval ) {
      if( !astChrMatch( cval, "REF" ) &&
          !astChrMatch( cval, "MASK2" ) &&
          !astChrMatch( cval, "MASK3" ) ) {
         astMapGet0I( keymap, "IMPORTSKY", &result );
         cval = ( result > 0 ) ? "REF" : NULL;
      }
      if( cval ) {
         result = 1;
         strcpy( refparam, cval );
         astChrCase( NULL, refparam, 1, 0 );
      }
   }

/* Do nothing more if we are not subtracting an initial sky from the data. */
   if( result && *status == SAI__OK ) {

/* Begin an NDF context. */
      ndfBegin();

/* Get an identifier for the NDF using the associated ADAM parameter.
   First try UPDATE access. If this fails try READ access. */
      ndfAssoc( refparam, "UPDATE", &indf1, status );
      if( *status != SAI__OK ) {
         errAnnul( status );
         ndfAssoc( refparam, "READ", &indf1, status );
         update = 0;
      } else {
         update = 1;
      }

/* Tell the user what we are doing. */
      ndfMsg( "N", indf1 );
      msgOut( "", "Using ^N as the initial guess at the sky", status );

/* Get a section from this NDF that matches the bounds of the map. */
      ndfSect( indf1, 2, dat->lbnd_out, dat->ubnd_out, &indf2, status );

/* Ensure masked values are not set bad in the mapped data array. */
      ndfSbb( 0, indf2, status );

/* Map the data array section, and copy it into the map buffer. */
      ndfMap( indf2, "DATA", "_DOUBLE", "READ", (void **) &ptr, &nel, status );
      if( *status == SAI__OK ) {
         memcpy( dat->map, ptr, dat->msize*sizeof(*ptr));
      }

/* Map the variance array section, and copy it into the map buffer. */
      ndfState( indf2, "VARIANCE", &there, status );
      if( there ) {
         ndfMap( indf2, "VARIANCE", "_DOUBLE", "READ", (void **) &vptr, &nel, status );
         if( *status == SAI__OK ) {
            memcpy( dat->mapvar, vptr, dat->msize*sizeof(*vptr));
         }
      }

/* If the NDF was created by a previous run of makemap that was interupted
   using control-C, it will contain a NUMITER item in the smurf extension,
   which gives the number of iterations that were completed before the
   map was created. Obtain and return this value, if it exists. */
      ndfXstat( indf1, SMURF__EXTNAME, &there, status );
      if( there ) ndfXgt0i( indf1, SMURF__EXTNAME, "NUMITER", iters,
                            status );

/* If the NDF has a Quality component, import it and create initial AST,
   FLT, PCA, SSN and COM masks from it. These will often be over-ridden by
   new masks calculated with smf_calcmodel_ast below, but will not be
   over-written if the masks have been frozen by xxx.zero_freeze. */
      ndfState( indf2, "Quality", &there, status );
      if( there && dat->mapqual ) {
         smf_qual_t *qarray = smf_qual_map( wf, indf2, "Read", NULL, &junk,
                                            status );
         if( *status == SAI__OK ) {
            smf_qual_t *pq = qarray;
            for( i = 0; i < dat->msize; i++,pq++ ) {
               if( *pq & SMF__MAPQ_AST ) {
                  if( !dat->ast_mask ) dat->ast_mask = astCalloc( dat->msize,
                                                  sizeof( *(dat->ast_mask) ) );
                  (dat->ast_mask)[ i ] = 1;
               }
               if( *pq & SMF__MAPQ_FLT ) {
                  if( !dat->flt_mask ) dat->flt_mask = astCalloc( dat->msize,
                                                  sizeof( *(dat->flt_mask) ) );
                  (dat->flt_mask)[ i ] = 1;
               }
               if( *pq & SMF__MAPQ_COM ) {
                  if( !dat->com_mask ) dat->com_mask = astCalloc( dat->msize,
                                                  sizeof( *(dat->com_mask) ) );
                  (dat->com_mask)[ i ] = 1;
               }
               if( *pq & SMF__MAPQ_SSN ) {
                  if( !dat->ssn_mask ) dat->ssn_mask = astCalloc( dat->msize,
                                                  sizeof( *(dat->ssn_mask) ) );
                  (dat->ssn_mask)[ i ] = 1;
               }
               if( *pq & SMF__MAPQ_PCA ) {
                  if( !dat->pca_mask ) dat->pca_mask = astCalloc( dat->msize,
                                                  sizeof( *(dat->pca_mask) ) );
                  (dat->pca_mask)[ i ] = 1;
               }
            }
         }
         qarray = astFree( qarray );
      }

/* Indicate the map arrays within the supplied smfDIMMData structure now
   contain usable values. We need to do this before calling
   smf_calcmodel_ast below so that the right mask gets used in
   smf_calcmodel_ast. */
      dat->mapok = 1;

/* Apply any existinction correction to the cleaned bolometer data. */
      if( dat->ext ) smf_calcmodel_ext( wf, dat, 0, keymap, dat->ext, 0,
                                        status);

/* Sample the above map at the position of each bolometer sample and
   subtract the sampled value from the cleaned bolometer value. */
      smf_calcmodel_ast( wf, dat, 0, keymap, NULL, SMF__DIMM_PREITER, status);

/* Remove any existinction correction to the modifed bolometer data. */
      if( dat->ext ) smf_calcmodel_ext( wf, dat, 0, keymap, dat->ext,
                                        SMF__DIMM_INVERT, status);

/* If the NDF was opened with UPDATE access, update the quality array in
   the NDF to reflect the AST mask created by smf_calcmodel_ast above. */
      if( update ) {
         smf_qual_t *qarray = astStore( NULL, dat->mapqual, dat->msize*sizeof(*qarray) );
         qarray = smf_qual_unmap( wf, indf2, SMF__QFAM_MAP, qarray, status );
      }

/* End the NDF context. */
      ndfEnd( status );
   }

/* End the AST context. */
   astEnd;

/* Return the pointer to the boolean mask. */
   return result;
}