Exemple #1
0
/**
 * Routine to read in the DLD1P_?_PRANGE keyword ? for a specific beam
 * from the configuration file. This is only for a prismatic dispersion
 * solution
 *
 * @param  filename filename of the configuration file
 * @param  beamID   beamID of the beam of interest (A=0, B=1, etc...)
 *
 * @return v        gsl-vector [pmin, pmax]
 */
gsl_vector *
get_prange (char *filename, int beamID)
{
  char beam[MAXCHAR];

  gsl_vector *v = NULL;
  
  struct CfgStrings DispConfig[] = {
    {NULL, NULL},
    {NULL, NULL}
  };
  DispConfig[0].name = beam;

  sprintf (beam, "DLD1P_%c_PRANGE", BEAM (beamID));

  CfgRead (filename, DispConfig);

  if (DispConfig[0].data != NULL){
    v = string_to_gsl_array (DispConfig[0].data);
    if (v->size != 2)
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                   "get_prange: two items, PMIN and PMAX must be given, not %i\n", v->size);
    if (gsl_vector_get(v,0) > gsl_vector_get(v,1))
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                   "get_prange: PMIN must be smaller than PMAX, however PMIN: %f, PMAX %f\n",
                   gsl_vector_get(v,0), gsl_vector_get(v,1));
      
  }
  return v;
}
Exemple #2
0
/**
 * Function: get_fits_header
 * Returns the header of extension hdunum from a fits file filename
 *
 * Parameters:
 * @param filename The name of the FITS file
 * @param hdunum the number of the HDU to access
 *  
 * Returns:
 * @return a pointer to a newly allocated string containing the entire header
 */
char *
get_fits_header (char filename[], int hdunum)
{

  fitsfile *input;
  int f_status = 0, hdutype;
  int nkeys, i;
  char card[FLEN_CARD];
  
  char *header, *p;

  //  Open the file for creating/appending
  fits_open_file (&input, filename, READONLY, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_fits_header: Could not open" " file:", filename);
    }
  fits_movabs_hdu (input, hdunum, &hdutype, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_fits_header: "
		   "Could not read extention %d from file: %s", hdunum,
		   filename);
    }
  


  fits_get_hdrspace (input, &nkeys, NULL, &f_status);	/* get # of keywords */
  
  header = (char *) malloc ((nkeys + 1) * FLEN_CARD * sizeof (char));
  p = header;
  for (i = 0; i < nkeys; i++)
    {			/* Read and print each keywords */
      
      if (fits_read_record (input, i + 1, card, &f_status))
	break;
      
      sprintf(p,"%-80s", card);
      p = p + 80;
    }
  /* Add END keyword */
  
  sprintf (card, "END");
  sprintf(p,"%-80s", card);
  
  return header;
}
/**
 * The function creates and loads a fluximage structure
 * from an extention of a fluxcube file.
 *
 * @param  fcube_file - the file name of the fluxcube
 * @param  hdunum     - the extension number to load in a fluximage
 *
 * @return fimage     - pointer to the fluximage structure loaded
 */
flux_image *
load_fluximage(const char fcube_file[], int hdunum)
{
  flux_image *fimage;

  char tmp[MAXCHAR];

  double wavelength;

  strcpy(tmp, fcube_file);

  // allocate space for the fluximage structure
  fimage = (flux_image *)malloc(sizeof(flux_image));

  // load the array from the specified extension number
  fimage->flux = FITSimage_to_gsl(fcube_file, hdunum, 1);

  // get the keyword "WAVELENG' from the specified extension number
  wavelength = (double)get_float_from_keyword(tmp, hdunum, "WAVELENG");

  // report an error in case that the extension does not have that keyword.
  // Otherwise store its content in the fluximage structure
  if (isnan(wavelength))
    aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
                "aXe_PETCONT: " "Missing keyword WAVELENGTH in fluxcube %s, extension %i!\n",
                fcube_file, hdunum);
  else
    fimage->wavelength = wavelength;

  return fimage;
}
Exemple #4
0
/**
 * Parses a configuration file, computes and return the value
 * of the order^th dispersion polynomial coefficient at a given 
 * detector pixel.
 *
 * @param filename filename of the configuration file
 * @param beamID   beamID of the beam of interest (A=0, B=1, etc...)
 * @param order    order of the coefficient for which the 2D field dependent 
 * @param p        a d_point object containing the position to compute the
 *                 dispersion coefficient at.
 *
 * @return res     the value of the order6th coefficient of beamID computed at
 *                 detector pixel p.
 */
float
get_disp_coeff_at_pos (char *filename, const int for_grism, int beamID,
                       int order, d_point p)
{
  gsl_vector *v;
  float n, c, res;
  int i, j, k;
  
  v = get_beam_disp_order (filename, for_grism, beamID, order);
  n = 0.5 * (-1.0 + sqrt (1 + 8 * v->size));
  if ((floor (n) - n) != 0)
    {
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                   "get_disp_coeff_at_pos: "
                   "Order %d of Beam %d in %s does not contain a correct number of entries (i.e. "
                   "1,3,6,10,15...,n^2/2+n/2", order, beamID, filename);
    }
  
  i = 0;
  res = 0;
  for (j = 0; j < n; j++)
    {
      for (k = 0; k < (j + 1); k++)
        {
          c = gsl_vector_get (v, i);
          res = res + c * pow (p.x, (j - k)) * pow (p.y, k);
          i++;
        }
    }
  gsl_vector_free (v);
  return res;
}
Exemple #5
0
/**
 * Parses a configuration file and searches for DISP_ORDER_%c
 * keywords. Returns the order of the field dependent
 * dispersion relation for that order.
 *
 * @param  filename  filename of the configuration file
 * @param  beamID    beamID of the beam of interest (A=0, B=1, etc...)
 *
 * @return disporder the order of the dispersion relation for the beam
 *                   of interest
 */
int
get_beam_disp_norder (char *filename, int beamID)
{
  char beam[MAXCHAR];
  int disporder = -1, found = 0, i;
  
  struct CfgStrings DispConfig[] = {
    {NULL, NULL},
    {NULL, NULL}
  };
  DispConfig[0].name = beam;
  
  sprintf (beam, "DISP_ORDER_%c", BEAM (beamID));
  CfgRead (filename, DispConfig);
  if ((DispConfig[0].name == beam) && (DispConfig[0].data != NULL))
    {
      disporder = atoi (DispConfig[0].data);
      found = 1;
    }
  if (!found)
    {
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                   "get_beam_disp_norder: %s was not found in %s.\n",
                   beam, filename);
    }
  i = 0;
  while(DispConfig[i].name!=NULL){
    free(DispConfig[i++].data);
  }
  
  //free(DispConfig[0].data);
  return disporder;
  
}
Exemple #6
0
/**
 * Function: intpix_corr_pet
 * The function applies the intra-pixel sensitivity correction to
 * a list of PET pixels. The values in the pixels are corrected in
 * place using the correction function, gemoetrical parameters and
 * dispersion relation in the various parameters.
 *
 * Parameters:
 * @param actbeam        - the beam to correct
 * @param conf_file_path - full path to the axe configuration file
 * @param ipcorr         - the ipc correction function
 * @param PET            - the list of PET pixels to correct
 *
 * Returns:
 * -
 */
void
intpix_corr_pet(beam actbeam, char conf_file_path[],
		interpolator *ipcorr, ap_pixel *PET)
{
  interpolator *ipclambda;
  aperture_conf  *conf;

  int for_grism=0;

  // load the configuration file
  conf = get_aperture_descriptor(conf_file_path);

  // check whether it is grism (for_grism=1)
  // or prism (for_grism=0) data
  // give an error if there is a prism solution
  for_grism = check_for_grism (conf_file_path, actbeam.ID);
  if (!for_grism)
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "intpix_corr_beam: Only grism dispersion solution can be corrected.\n");

  // determine the correction factor versus wavelength
  ipclambda = get_ipclambda(actbeam, conf_file_path, ipcorr);

  print_interp(ipclambda);

  // apply the correction to the PET
  apply_corr_pet(ipclambda, PET);

  // free the configuration structure
  free_aperture_conf(conf);

  // free the memory in the interpolator
  free_interp(ipclambda);
}
Exemple #7
0
/**
 *  The function evaluates the a polynomial given in the input
 *  at a specific point, which also is given in the input.
 *  The polynomial follows the description of 2D vatriable
 *  quantities as given in the aXe manual.
 *
 *  @param coeffs - the coefficients of the polynomial
 *  @param p      - the point to evaluate the polynomial
 *  @param beamID - beamID of the beam of interest (A=0, B=1, etc...)
 *
 *  @return res   - of the polynomial at point p
 *
 */
float eval_trace_off_at_pos(gsl_vector *coeffs, d_point p, int beamID)
  {
    float n, c, res;
    int i, j, k;

    n = 0.5 * (-1.0 + sqrt(1 + 8 * coeffs->size));
    if ((floor(n) - n) != 0)
      {
        aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
        "get_trace_xoff_at_pos: "
        "Beam %d in configuration file does not contain a correct number of entries (i.e. "
        "1,3,6,10,15...,n^2/2+n/2", beamID);
      }

    i = 0;
    res = 0;
    for (j = 0; j < n; j++)
      {
        for (k = 0; k < (j + 1); k++)
          {
            c = gsl_vector_get(coeffs, i);
            res = res + c * pow(p.x, (j - k)) * pow(p.y, k);
            i++;
          }
      }

    return res;
  }
Exemple #8
0
/**
 * Function: get_lcolumn_from_SPC_opened
 * The function reads the values from a column with long specified
 * by its name into a array of type long. The array is returned.
 *
 * Parameters:
 * @param SPC_ptr   - pointer to the SPC extension
 * @param count_col - name of the column to load
 * @param nelems    - number of elements in the column
 *
 * Returns:
 * @return values - pointer to a filled array
 */
long *
get_lcolumn_from_SPC_opened(fitsfile *SPC_ptr, char colname[], int nelems)
{
  int colnum=0;
  int anynul;
  int f_status=0;
  long *values;

  // allocate the return array;
  // give an error if allocation fails
  values = (long *) malloc(nelems * sizeof(long));
  if (!values) {
    aXe_message (aXe_M_ERROR, __FILE__, __LINE__,
		 "Memory allocation failed");
  }

  // get the desired column number;
  // give an error if the column name
  // can not be read
  fits_get_colnum (SPC_ptr, CASEINSEN, colname, &colnum, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_dcolumn_from_SPC_opened: "
		   "Could not determine column %s in "
		   " table!\n", colname);
    }

  // read all data in the column
  fits_read_col (SPC_ptr, TLONG, colnum, 1, 1, nelems, NULL, values,
                    &anynul, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_dcolumn_from_SPC_opened: "
		   "Could not read column %s"
		   " from BINARY table!",colname);
    }

  // return the filled array
  return values;
}
Exemple #9
0
/**
 * Function: get_tlength_from_dispersion
 * The function computes and returnes the trace length for
 * a given diseprsion solution and wavelength. The tracelength
 * value is returned. Currently only linear and quadratic
 * dispersio solution are considered.
 *
 * Parameters:
 * @param cdisp  - the dispersion coefficient polynomial
 * @param lambda - the wavelength
 *
 * Returns:
 * @return tlength - the trace length
 */
double
get_tlength_from_dispersion(gsl_vector *cdisp, float lambda)
{
  double tlength=0.0;
  //double tlength_a=0.0;
  double det;

  // check whether the polynomial is linear
  if (cdisp->size == 2)
    {
      // compute the tracelength for linear dispersion
      tlength = (lambda-gsl_vector_get(cdisp, 0))/gsl_vector_get(cdisp, 1);
    }
  // check whether the polynomial is quadratic
  else if (cdisp->size == 3)
    {
      // compute the determinante
      det = gsl_vector_get(cdisp, 1) * gsl_vector_get(cdisp, 1)
		 - 4.0 * gsl_vector_get(cdisp, 0) * gsl_vector_get(cdisp, 2);

      // gove error if det < 0.0
      if (det < 0.0)
	aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		     "get_tlength_from_dispersion: Can not determine the tracelength since det < 0.0!\n");

      // compute the tracelength
      tlength   = (-gsl_vector_get(cdisp, 1)+sqrt(det))/(2.0*gsl_vector_get(cdisp, 2));
      //    tlength_a = (-gsl_vector_get(cdisp, 1)-sqrt(det))/(2.0*gsl_vector_get(cdisp, 2));
      //    fprintf(stdout, "plus: %f, minus: f\n", tlength, tlength_a);
    }
  else
    {
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_tlength_from_dispersion: The dispersion solution has %i coefficients and can not be inverted!\n", cdisp->size);
    }

  // return the tracelength
  return tlength;
}
/*
 * Function: get_crossdisp_matrix
 * The function extracts the drizzle coefficients stored in the
 * keyword headers of an image extension and creates a matrix
 * to store those coefficients. The matrix is returned.
 * Currently the drizzle coefficients are ALWAYS stored in the
 * primary header of the grism images. For this reason
 * all keywords are read from extension '1' (hardcoded).
 *
 * Parameters:
 * @param  filename   - the image filename
 * @param  sci_numext - the extension number
 *
 * Returns:
 * @return ret - the matrix with the drizzle coefficients
 */
gsl_matrix  *
get_crossdisp_matrix(char * filename, int sci_numext)
{
  int ncoeffs;
  int i;
  gsl_matrix * ret;
  px_point    pixmax;
  char templt[FLEN_CARD];
  float acoeff, tmp;

  // get the number of coefficients
  tmp = get_float_from_keyword(filename, 1, "DRZCNUM");
  //  tmp = get_float_from_keyword(filename, sci_numext, "DRZCNUM");
  if (isnan(tmp)){
    // in case that the keyword does not exist,
    // find a nice way out of the door
    aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
                "Could not find drizzle keywords in: %s\n", filename); 
    ret = gsl_matrix_alloc(1,1);    
    gsl_matrix_set(ret, 0,0,GSL_NAN);
    return ret;
  }
  else {
    // cast the value to int
    ncoeffs = (int)tmp;
  }

  // allocate the matrix, set it to the default
  ret = gsl_matrix_alloc(2,ncoeffs);
  gsl_matrix_set_all (ret, 0.0);
  
  // go over the number of coefficients
  for (i=0; i<ncoeffs; i++){

    // set the name for the x-coefficient, get it and store it
    sprintf (templt, "DRZ%1iX%02i", sci_numext, i+1);
    //    acoeff = get_float_from_keyword(filename, sci_numext, templt);
    acoeff = get_float_from_keyword(filename, 1, templt);
    gsl_matrix_set(ret, 0,i,acoeff);

    // set the name for the y-coefficient, get it and store it
    sprintf (templt, "DRZ%1iY%02i", sci_numext, i+1);
    //    acoeff = get_float_from_keyword(filename, sci_numext, templt);
    acoeff = get_float_from_keyword(filename, 1, templt);
    gsl_matrix_set(ret, 1,i,acoeff);

  }

  // return the matrix
  return ret;
}
Exemple #11
0
/**
 * Parses a configuration file and searches for DYDX_ORDER_%c
 * keywords. Returns the order of the field dependent
 * trace relation for that order.
 * @param filename filename of the configuration file
 * @param beamID beamID of the beam of interest (A=0, B=1, etc...)
 *
 * @return disporder the order of the dispersion relation for the beam of interest
 */
int get_beam_trace_norder(char *filename, int beamID)
  {
    char beam[MAXCHAR];
    int disporder = -1;
    int found = 0;
    int i=0;

    struct CfgStrings DispConfig[] =
      {
        { NULL, NULL },
        { NULL, NULL } };
    DispConfig[0].name = beam;
    sprintf(beam, "DYDX_ORDER_%c", BEAM (beamID));
    CfgRead(filename, DispConfig);
    if ((DispConfig[0].name == beam) && (DispConfig[0].data != NULL))
      {
        disporder = atoi(DispConfig[0].data);
        found = 1;
      }
    if (!found)
      {
        aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
        "get_beam_trace_norder: %s was not found in %s.\n",
        beam, filename);
      }
    if (disporder<0)
      aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
      "Trace polynomial must at least have one coefficients (i.e. zeroth order).\n");

    // release memory
    i=0;
    while (DispConfig[i].name!=NULL)
      free(DispConfig[i++].data);

    return disporder;
  }
/**
 * Function: get_model_sed
 * Extracts and returns the desired model spectrum from th model structure.
 * Translates from the object index [1, n_models] to the spectral model
 * structure index [0, n_model-1].
 *
 * Parameters:
 * @param  spectral_models - the spectral models structure
 * @param  modspec         - the index of the desired SED
 *
 * Returns:
 * @return - 
 */
energy_distrib *
get_model_sed(const spectral_models *spec_mod, const int modspec)
{
  energy_distrib *sed;

  if (modspec >  spec_mod->n_models)
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "aXe_PETCONT: " "Model number %i does NOT exist!",
		 modspec);

  // extract the desired SED
  sed = spec_mod->SEDlist[modspec-1];

  // return the SED
  return sed;
}
/**
 * Function: get_dirim_emission
 * The function returns from a direct object model the direct emission
 * object addressed by the index. The function translates from the
 * object index, which is in [1, n_model] to the structure index
 * in [0, n_model-1]
 *
 * Parameters:
 * @param objmodels - the object model structure 
 * @param objspec   - the 'index' of the desired direct emission model
 *
 * Returns:
 * @return dirim - the desired direct emission model
 */
dirim_emission *
get_dirim_emission(const object_models *objmodels, const int objspec)
{
  dirim_emission *dirim;

  if (objspec >  objmodels->n_models || objspec < 1)
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "aXe_PETCONT: " "Direct emission model number %i does NOT exist!",
		 objspec);

  // extract the desired SED
  dirim = objmodels->obj_list[objspec-1];

  // return the SED
  return dirim;
}
Exemple #14
0
int
check_disp_order(const gsl_vector *tmp, const int beamID, const int order)
{

  int n;
  
  n = 0.5 * (-1.0 + sqrt (1 + 8 * tmp->size));
  if ((floor (n) - n) != 0)
    {
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                   "get_disp_coeff_at_pos: "
                   "Order %d of Beam %d does not contain a correct number of entries (i.e. "
                   "1,3,6,10,15...,n^2/2+n/2", order, beamID);
    }

  return 1;
}
/**
 * The function creates and loads a new flux_cube structure
 * The data is taken from the file specified in the input.
 *
 * @param  fcube_file - the file name of the fluxcube
 *
 * @return ret        - the new flux_cube structure
 */
flux_cube *
load_fluxcube(const char fcube_file[])
{
  flux_cube *fcube;

  gsl_matrix *test;

  int nflux, n_ext=0;
  int i;


  // get the number of extensions
  n_ext = FITSextnum(fcube_file);
  if (n_ext <3)
    aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
                "aXe_PETCONT: " "the fluxcube file %s has only %i extensions!\n",
                fcube_file, n_ext);

  // determine the number of flux images and allocate
  // the space for the fluxcube structure
  nflux = n_ext-2;
  fcube = alloc_fluxcube(nflux);

  // load XOFFS and YOFFS
  load_offsets(fcube_file, fcube);

  // load the segmentation image into the structure
  fcube->segmentation = load_segmentation(fcube_file);
  //  gsl_to_FITSimage (fcube->segmentation, "gogo.fits", 1, "MOO");

  // load the fluximages
  for (i=0; i < nflux; i++)
    {
      fcube->fluxims[i] = load_fluximage(fcube_file, i+3);
    }

  // fill the number of fluximages
  fcube->n_fimage = nflux;

  // order the fluximages and store the
  // vector with the ordered indices
  fcube->fimage_order = order_fluxims(fcube);

  return fcube;
}
Exemple #16
0
/**
 * The program checks if the dispersion relation of a certain beam
 * is given in "grism" form (polynomial) or in "prism" form
 * (inverse polynomial)
 *
 * @param  filename filename of the configuration file
 * @param  beamID   beamID of the beam of interest (A=0, B=1, etc...)
 *
 * @return c        integer to declare grism (=1) or prism (=0)
 */
int
check_for_grism (char *filename, int beamID)
{
  int norder, i;
  int c=0;

  // get the order of the dispersion solution
  norder = get_beam_disp_norder (filename, beamID);

  // go over all orders and check the assumption
  // that it is a grism
  for (i = 0; i < norder + 1; i++)
    c += check_disp_coeff (filename, 1, beamID, i);

  // if the assumption is right,
  // set the return value for grism
  if (c == 0)
    {
      c = 1;
    }
  // if the assumption is wrong
  else
    {
      // reset the variable
      c = 0;

      // check the assumption that it is a grism
      for (i = 0; i < norder + 1; i++)
        c += check_disp_coeff (filename, 0, beamID, i);

      // if also this assumption is wrong,
      // raise an error that the configuration file 
      // is inconsistent
      if (c != 0)
        aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                     "check_for_grism: "
                     "The dispersion coefficients for beam %c in file",
                     "%s are inconsistent.", beamID, filename);
    }

  // return the result
  return c;
}
Exemple #17
0
/**
 * Function: get_SPC_opened
 * The function opens an existing SPC file and returns the pointer
 * to it.
 * As of now, the mode of opening it is automatically READWRITE.
 * Later on a differentiation using the free parameter "mode"
 * might be added  to generalize the function.
 *
 * Parameters:
 * @param SPCname - name of the SPC file
 * @param mode    - mode to open it (not yet used)
 *
 * Returns:
 * @return SPC_ptr - pointer to the opened fits file
 *
 */
fitsfile *
get_SPC_opened(char SPCname[], int mode)
{
    fitsfile *SPC_ptr;
    int f_status=0;

  // Open the OPET file for reading/writing
  fits_open_file (&SPC_ptr, SPCname, READWRITE, &f_status);
  if (f_status)
    {
      ffrprt (stdout, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "aXe_INTPIXCORR: Could not open file: %s\n",
		   SPCname);
    }

  // return the pointer to the fits file
  return SPC_ptr;
}
Exemple #18
0
/**
 * Parses a configuration file and returns a gsl vector
 * containing the 2D polynomial coefficient allowing one to compute
 * a given dispersion relation coefficient anywhere on the detector.
 *
 * @param  filename filename of the configuration file
 * @param  beamID   beamID of the beam of interest (A=0, B=1, etc...)
 * @param  order    order of the coefficient for which the 2D field dependent 
 *                  coefficients are queried.
 *
 * @return v        a gsl_vector() containing all of the 2D field
 *                  dependent polynomial coeffiecient
 */
gsl_vector *
get_beam_disp_order (char *filename, const int for_grism, int beamID,
                     int order)
{
  char beam[MAXCHAR];
  
  int norder, found = 0;
  int i;
  gsl_vector *v = NULL;
  struct CfgStrings DispConfig[] = {
    {NULL, NULL},
    {NULL, NULL}
  };
  DispConfig[0].name = beam;
  norder = get_beam_disp_norder (filename, beamID);
  if (for_grism == 1)
    {
      sprintf (beam, "DLDP_%c_%d", BEAM (beamID), order);
    }
  else
    {
      sprintf (beam, "DLD1P_%c_%d", BEAM (beamID), order);
    }
  CfgRead (filename, DispConfig);
  if ((DispConfig[0].name == beam) && (DispConfig[0].data != NULL))
    {
      v = string_to_gsl_array (DispConfig[0].data);
      found = 1;
    }

  if (!found)
    {
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                   "get_beam_disp_order: %s was not found in %s.\n",
                   beam, filename);
    }
  i = 0;
  while(DispConfig[i].name!=NULL){
    free(DispConfig[i++].data);
  }
  return v;
}
/**
 * Function: get_num_extensions
 * The function determines the number of extensions in
 * the fits file. Here the primary extension does not count.
 *
 * Parameters:
 * @param  spectral_models_file - pathname to the spectral models file
 *
 * Returns:
 * @return n_models              - the number of spectral models
 */
int
get_num_extensions(const char spectral_models_file[])
{
  int n_ext=0;
  int n_models=0;
  int i;
  int f_status=0;


  fitsfile *s_models;

  // open the fits file
  // report any error
  fits_open_file (&s_models, spectral_models_file, READONLY, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "aXe_PETCONT: " "Could not open file: %s",
		   spectral_models_file);
    }

  // do until a fits error occurs
  while (!f_status)
    {
      // move one extension forward
      fits_movrel_hdu (s_models, 1, NULL, &f_status);

      // count up
      n_ext++;
    }
  
  // close the fits file
  fits_close_file (s_models, &f_status);

  // the zeroth extension
  // does nnot count!!
  n_models = n_ext - 1;
  
  // return the 
  return n_models;
}
Exemple #20
0
/**
   Generate and returns a trace structure that is
   computed at the given pixel p detector location.
   @param filename filename of the configuration file
   @param beamID beamID of the beam of interest (A=0, B=1, etc...)
   @param p A d_point object containing the position to compute the dispersion coefficients at.

   @return res A dispersion structure computed for beam beamID at detector pixel p.
*/
tracestruct * get_tracestruct_at_pos(char *filename, int beamID, d_point p)
  {
    tracestruct *res;

    res = malloc(sizeof(tracestruct));
    if (res == NULL)
      {
        aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
        "get_tracestruct_at_pos:"
        "Could not allocate tracestruct");
      }
    res->pol = get_trace_coeffs_at_pos(filename, beamID, p);
    res->offset.x = get_trace_xoff_at_pos(filename, beamID, p);
    res->offset.y = get_trace_yoff_at_pos(filename, beamID, p);
    res->ID = beamID;
    res->cpoint.x = p.x;
    res->cpoint.y = p.y;
    sprintf(res->file, "%s", filename);
    return res;
  }
Exemple #21
0
/**
 *  Parses a configuration file and returns a gsl vector
 *  containing the 2D polynomial coefficient allowing one to compute
 *  a given trace coefficient anywhere on the detector.
 *  @param filename filename of the configuration file
 *  @param beamID beamID of the beam of interest (A=0, B=1, etc...)
 *  @param order order of the coefficient for which the 2D field dependent
 *  coefficients are queried.
 *
 * @return v A gsl_vector() containing all of the 2D field dependent polynomial coeffiecient
 */
gsl_vector * get_beam_trace_order(char *filename, int beamID, int order)
  {
    char beam[MAXCHAR];

    int norder;
    int found = 0;
    int i=0;

    gsl_vector *v= NULL;
    struct CfgStrings DispConfig[] =
      {
        { NULL, NULL },
        { NULL, NULL } };
    DispConfig[0].name = beam;
    norder = get_beam_disp_norder(filename, beamID);
    sprintf(beam, "DYDX_%c_%d", BEAM (beamID), order);
    CfgRead(filename, DispConfig);
    if ((DispConfig[0].name == beam) && (DispConfig[0].data != NULL))
      {
        v = string_to_gsl_array(DispConfig[0].data);
        found = 1;
      }

    if (!found)
      {
        aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
        "get_beam_trace_order: %s was not found in %s.\n",
        beam, filename);
      }

    // release memory
    i=0;
    while (DispConfig[i].name!=NULL)
      free(DispConfig[i++].data);

    return v;
  }
/**
 * The function creates a a dirobject on the basis
 * of an object and the pixel coos of a point
 * which is part of that object.
 *
 * @param  flt_point - the fluxcube structure
 * @param  actobject - the object list
 *
 * @return dirobject - the dirobject created
 */
dirobject *
dirobject_from_segpoint(const px_point flt_point, const object  *actobject)
{

  dirobject  *actdir;

  // allocate space for the dirobject
  actdir = (dirobject *) malloc (sizeof (dirobject));
  if (actdir == NULL)
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                 "fill_dirobject:" " Could not allocate"
                 " memory for a dirobject object");

  // transfer refpoint and ID
  actdir->ID = actobject->ID;
  actdir->refpoint.x = actobject->beams[0].refpoint.x;
  actdir->refpoint.y = actobject->beams[0].refpoint.y;

  // derive and store min/max in x/y for the corners
  actdir->ix_min = flt_point.x;
  actdir->ix_max = flt_point.x;
  actdir->iy_min = flt_point.y;
  actdir->iy_max = flt_point.y;

  // derive the distortion scales along the major an minor axis
  actdir->drzscale.x = 1.0;
  actdir->drzscale.y = 1.0;

  // set the variable
  actdir->bb_sed = 0;

  // make it a dummy
  actdir->SED = NULL;

  // return the new dirobject
  return actdir;
}
Exemple #23
0
/**
 * Routine to read in the MMAG_MARK keyword for a specific beam
 * from the configuration file
 *
 * @param  filename     filename of the configuration file
 * @param  beamID       beamID of the beam of interest (A=0, B=1, etc...)
 *
 * @return mmag_mark mag_mark-value for that beam 
 */
float
get_beam_mmag_mark (char *filename, int beamID)
{
  char beam[MAXCHAR];
  float mmag_mark = -1;
  int found = 0;
  int i=0;
  
  struct CfgStrings DispConfig[] = {
    {NULL, NULL},
    {NULL, NULL}
  };
  DispConfig[0].name = beam;
  
  sprintf (beam, "MMAG_MARK_%c", BEAM (beamID));
  CfgRead (filename, DispConfig);
  if ((DispConfig[0].name == beam) && (DispConfig[0].data != NULL))
    {
      mmag_mark = atof (DispConfig[0].data);
      found = 1;
    }
  if (!found)
    {
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
                   "get_beam_mmag_mark: %s was not found in %s.\n",
                   beam, filename);
    }

  // release memory
  i=0;
  while(DispConfig[i].name!=NULL)
    free(DispConfig[i++].data);

  // return the value
  return mmag_mark;  
}
Exemple #24
0
/**
 * Function: get_ipclambda
 * The function creates an interpolator for the intra-pixel correction
 * as a function of wavelength based on this correction as function
 * of fractional y-pixel and the full calibration information
 * on a beam.
 * The interpolator is created after stepping along the beam trace
 * and combining the wavelength values with the correction values
 * at the trace positions.
 *
 * Parameters:
 * @param actbeam        - the beam to find the correction values for
 * @param conf_file_path - the full path to the aXe cofiguration file
 * @param ipcorr         - the correction values as function of y-fraction
 *
 * Returns:
 * @return ipclambda     - the correction values as function of wavelength
 */
interpolator *
get_ipclambda(beam actbeam, char conf_file_path[],
	      interpolator *ipcorr)
{
  gsl_vector *xvalues;
  gsl_vector *cvalues;
  gsl_vector *lambdas;

  double *cv;
  double *lv;

  interpolator *ipclambda;

  int i=0;
  int j=0;

  // get the x values around the reference point
  xvalues = get_ipc_xvalues(actbeam);

  // get the correction factors for these x-values
  cvalues = get_ipc_cvalues(actbeam, ipcorr, xvalues);

  // get the wavelength at the correction factors
  lambdas = get_ipc_lambdas(actbeam, conf_file_path, xvalues);

  // allocate memory for the dependent values
  cv = (double *) malloc(cvalues->size * sizeof(double));
  if (!cv) {
    aXe_message (aXe_M_ERROR, __FILE__, __LINE__,
		 "Memory allocation failed");
  }

  // allocate memory for the independent values
  lv = (double *) malloc(cvalues->size * sizeof(double));
  if (!lv) {
    aXe_message (aXe_M_ERROR, __FILE__, __LINE__,
		 "Memory allocation failed");
  }

  if (gsl_vector_get(lambdas, lambdas->size-1) > gsl_vector_get(lambdas, 0))
    {
      // transfer the values from the
      // gsl vectors to the c-vectors
      for (i = 0; i < cvalues->size; i++)
	{
	  cv[i] = gsl_vector_get(cvalues, i);
	  lv[i] = gsl_vector_get(lambdas, i);
	}
    }
  else
    {
      // transfer the values from the
      // gsl vectors to the c-vectors
      // invert the order from the
      // gsl-vectors
      j = cvalues->size - 1;
      for (i = 0; i < cvalues->size; i++)
	{
	  cv[j] = gsl_vector_get(cvalues, i);
	  lv[j] = gsl_vector_get(lambdas, i);
	  j--;
	}
    }

  // create the interpolator
  ipclambda = create_interp(cvalues->size, FILTER_INTERP_TYPE, lv, cv);


  // free the memory allocated to
  // the vectors
  gsl_vector_free(xvalues);
  gsl_vector_free(cvalues);
  gsl_vector_free(lambdas);

  // return the interpolator
  return ipclambda;
}
Exemple #25
0
/**
 * Function: intpix_corr_beam
 * The functio corrects a full spectrum for the intrapixel sensitivity
 * variations.
 * For every spectral element its fractional y-value is determined,
 * and then the correction factor for this y-value is computed
 * and applied to the appropriate elements of the spectral bin.
 *
 * Parameters:
 * @param actbeam        - the beam to examine
 * @param conf_file_path - the full pathname too the configuration file
 * @param ipcorr         - the interpolator with the correction factor
 * @param SPC            - the full spectrum to correct
 *
 * Returns:
 * @return -
 */
void
intpix_corr_beam(beam actbeam, char conf_file_path[], interpolator *ipcorr,
		 full_spectr *SPC)
{
  int            index=0;
  int            for_grism=1;

  double         cfactor;

  double         lambda;

  gsl_vector     *cdisp;

  d_point        pixel;

  dispstruct     *beam_disp;

  aperture_conf  *conf;

  // load the configuration file
  conf = get_aperture_descriptor(conf_file_path);

  // check whether it is grism (for_grism=1)
  // or prism (for_grism=0) data
  // give an error if there is a prism solution
  for_grism = check_for_grism (conf_file_path, actbeam.ID);
  if (!for_grism)
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "intpix_corr_beam: Only grism dispersion solution can be corrected.\n");

  // get the wavelength dispersion relation at
  // position "refpoint". conf->refx and conf->refy
  // are used at this point to allow for a non (0,0) centered
  // 2D field dependence.
  pixel.x = actbeam.refpoint.x - conf->refx;
  pixel.y = actbeam.refpoint.y - conf->refy;

  // derive the dispersion at the object position
  beam_disp = get_dispstruct_at_pos(conf_file_path, for_grism,
				    actbeam.ID, pixel);

  // skipp high order zeroes in the dispersion solution
  cdisp = condense_dispersion(beam_disp->pol);

  for (index=0; index < SPC->nelems; index++)
    {
      lambda = SPC->fgr_spec->spec[index].lambda_mean;

      if (!gsl_isnan (lambda) && lambda)
	{
	  cfactor = get_intpix_corr(&actbeam, cdisp, ipcorr, lambda);

    	  fprintf(stdout, "lambda: %e, factor: %e\n", lambda, cfactor);
	  /*
	  SPC->fgr_spec->spec[index].count  = SPC->fgr_spec->spec[index].count / cfactor;
	  SPC->fgr_spec->spec[index].error  = SPC->fgr_spec->spec[index].error / cfactor;
	  SPC->fgr_spec->spec[index].flux   = SPC->fgr_spec->spec[index].flux / cfactor;
	  SPC->fgr_spec->spec[index].ferror = SPC->fgr_spec->spec[index].ferror / cfactor;

	  SPC->bck_spec->spec[index].count  = SPC->bck_spec->spec[index].count / cfactor;
	  SPC->bck_spec->spec[index].error  = SPC->bck_spec->spec[index].error / cfactor;
	  SPC->bck_spec->spec[index].flux   = SPC->bck_spec->spec[index].flux / cfactor;
	  SPC->bck_spec->spec[index].ferror = SPC->bck_spec->spec[index].ferror / cfactor;

	  SPC->obj_spec->spec[index].count  = SPC->obj_spec->spec[index].count / cfactor;
	  SPC->obj_spec->spec[index].error  = SPC->obj_spec->spec[index].error / cfactor;
	  SPC->obj_spec->spec[index].flux   = SPC->obj_spec->spec[index].flux / cfactor;
	  SPC->obj_spec->spec[index].ferror = SPC->obj_spec->spec[index].ferror / cfactor;

	  /* this is the wqrong version!!
	  SPC->fgr_spec->spec[index].count  = SPC->fgr_spec->spec[index].count * cfactor;
	  SPC->fgr_spec->spec[index].error  = SPC->fgr_spec->spec[index].error * cfactor;
	  SPC->fgr_spec->spec[index].flux   = SPC->fgr_spec->spec[index].flux * cfactor;
	  SPC->fgr_spec->spec[index].ferror = SPC->fgr_spec->spec[index].ferror * cfactor;

	  SPC->bck_spec->spec[index].count  = SPC->bck_spec->spec[index].count * cfactor;
	  SPC->bck_spec->spec[index].error  = SPC->bck_spec->spec[index].error * cfactor;
	  SPC->bck_spec->spec[index].flux   = SPC->bck_spec->spec[index].flux * cfactor;
	  SPC->bck_spec->spec[index].ferror = SPC->bck_spec->spec[index].ferror * cfactor;

	  SPC->obj_spec->spec[index].count  = SPC->obj_spec->spec[index].count * cfactor;
	  SPC->obj_spec->spec[index].error  = SPC->obj_spec->spec[index].error * cfactor;
	  SPC->obj_spec->spec[index].flux   = SPC->obj_spec->spec[index].flux * cfactor;
	  SPC->obj_spec->spec[index].ferror = SPC->obj_spec->spec[index].ferror * cfactor;
	  */
	}
    }

  // free the configuration structure
  free_aperture_conf(conf);

  // free the dispersion struct
  free_dispstruct(beam_disp);

  // free the memory for the dispersion
  gsl_vector_free(cdisp);
}
int
main (int argc, char *argv[])
{
  char *opt;
  char grism_image[MAXCHAR];
  char grism_image_path[MAXCHAR];

  char sex_catalog[MAXCHAR];
  char sex_catalog_path[MAXCHAR];

  char aper_file[MAXCHAR];
  char aper_file_path[MAXCHAR];

  char conf_file[MAXCHAR];
  char conf_file_path[MAXCHAR];

  float mmag_extract, mmag_mark, mfwhm, dmag;

  int leaveout_ignored = 1;
  int auto_reorient = 1;
  int no_orient = 0;
  int slitless_geom=0;
  int num;
  char ext[MAXCHAR];
  double lambda_mark=0.0;
  int bck_mode=0;

  aperture_conf *conf;
  SexObject **os;
  object **oblist;
  observation *obs;

  if ((argc < 3) || (opt = get_online_option ("help", argc, argv)))
    {
      fprintf (stdout,
               "ST-ECF European Coordinating Facility\n"
               "aXe_GOL2AF Version %s:\n"
               "            aXe task to create an Object Aperture File (OAF)\n"
               "            or a Background Aperture File (BAF) (-bck option)  using an\n"
               "            input Sextractor Grism Object List (GOL).\n"
               "            The AF files contain information about each object (aperture)\n"
               "            and information about the various beams (orders) in each of \n"
               "            these apertures. These are simple text files which can be\n"
               "            edited by hand. The IGNORE keywords can be set to 1 if a\n"
               "            particular beam (order) is to be ignored during the extraction\n"
               "            process. The MMAG_EXTRACT and MMAG_MARK keyword of each beam\n"
               "            listed in the aXe configuration file determine if a particluar\n "
               "            beam is flagged to be extracted or completely ignored.\n"
               "            The -dmag switch can be used to adjust these. See the aXe manual\n"
               "            for more details. An extraction width multiplicative factor can\n"
               "            be set with the -mfwhm option (e.g. to generate BAF containing\n"
               "            broader apertures).\n"
               "            By default, when the extraction angle is too close to the\n"
               "            dispersion direction, 90 degrees are added to the extraction\n"
               "            angle. This can be overwritten by using the -no_auto_orient\n"
               "            online parameter.\n"
               "\n"
               "            Input FITS mages are looked for in $AXE_IMAGE_PATH\n"
               "            aXe config file is looked for in $AXE_CONFIG_PATH\n"
               "            All outputs are writen to $AXE_OUTPUT_PATH\n"
               "\n"
               "Usage:\n"
               "        aXe_GOL2AF [g/prism image filename] [aXe filename] [options]\n"
               "\n"
               "Options:\n"
               "             -bck                - to generate a BAF instead of an OAF file\n"
               "             -SCI_hdu=[integer]  - overwrite the default from the \n"
               "                                   configuration file \n"
               "             -mfwhm=[float]      - an extraction width multiplicative factor.\n"
               "             -exclude_faint      - do not even list faint object in the result.\n"
               "             -out_AF=[string]    - overwrites the default output aper filename.\n"
               "             -in_GOL=[string]    - overwrites the default input catalog name.\n"
               "             -auto_orient=[0/1]  - set to 0 to disable the automatic extraction\n"
               "                                   orientation.\n"
               "             -no_orient          - disable tilted extraction (vertical\n"
               "                                   extraction only).\n"
               "             -dmag=[float]       - A number to add to the MMAG_EXTRACT and\n"
               "                                   MMAG_MARK values.\n"
               "\n"
               "Example: ./aXe_GOL2AF slim_grism.fits -bck -dmag=2 -mfwhm=2\n"
               "\n",RELEASE);
      exit (1);
    }

  fprintf (stdout, "aXe_GOL2AF: Starting...\n");

  /* Get the Grism/Prism image name */
  strcpy (grism_image, argv[1]);
  build_path (AXE_IMAGE_PATH, grism_image, grism_image_path);

  /* Get the name of the configuration file */
  strcpy (conf_file, argv[2]);
  build_path (AXE_CONFIG_PATH, conf_file, conf_file_path);

  /* Read the configuration file */
  conf = get_aperture_descriptor (conf_file_path);

  /* Determine where the various extensions are in the FITS file */
  get_extension_numbers(grism_image_path, conf,conf->optkey1,conf->optval1);

  if ((opt = get_online_option ("SCI_hdu", argc, argv)))
    {
      char str[MAXCHAR];
      strcpy(str,opt);
      conf->science_numext = atoi(str);
    }


  /* Get or set up the name of the output Aperture File */
  if ((opt = get_online_option ("out_AF", argc, argv)))
    {
      /* get it */
      strcpy (aper_file, opt);
      strcpy (aper_file_path, opt);
    }
  else
    {
      /* set the name automatically */
      /* Get the name of the aperture file type, OAF or BAF */
      if ((opt=get_online_option ("bck",argc,argv)))
        {
          strcpy (ext,".BAF");
          bck_mode=1;
        }
      else
        {
          strcpy (ext,".OAF");
        }
      strcpy (aper_file, argv[1]);
      replace_file_extension (grism_image, aper_file, ".fits", ext,
                              conf->science_numext);
      build_path (AXE_OUTPUT_PATH, aper_file, aper_file_path);
    }

     /* Set the option extraction width multiplicative factor */
  if ((opt = get_online_option ("mfwhm", argc, argv)))
    {
      {
        /*char str[MAXCHAR];
          strcpy (str, opt);
          sscanf (str, "%f", &mfwhm);*/
        mfwhm = atof(opt);
      }
    }
  else
    {
      mfwhm = 1.0;
    }

  if ((opt = get_online_option ("dmag", argc, argv)))
    {
      {
        /*char str[MAXCHAR];
          strcpy (str, opt);
          sscanf (str, "%f", &mfwhm);*/
        dmag = atof(opt);
      }
    }
  else
    {
      dmag = 0.0;
    }

  /* Set the option to include object that are too faint into the output
     aperture file.
  */
  if ((opt = get_online_option ("exclude_faint", argc, argv)))
    {
      leaveout_ignored = 1;
    }
  else
    {
      leaveout_ignored = 0;
    }

  /* Set the auto orientation mode for extraction on or off, default is on (=1)

  if ((opt = get_online_option ("auto_orient",argc,argv)))
    {
      if (!atof(opt))
        auto_reorient = 0;
    }
  else
    {
      auto_reorient = 1;
    }
  */

  // set the flag for using slitless geometry,
  // to say extraction parameters optimized for
  // slitless geometry
  if ((opt = get_online_option ("slitless_geom",argc,argv)))
      if (!atof(opt))
        //slitless_geom = 0;
        auto_reorient = 0;
  else
    //slitless_geom = 1;
    auto_reorient = 1;

  /* Set the option to disbale tilted extraction */
  if ((opt = get_online_option ("orient", argc, argv)))
    {
      if (!atof(opt))
        auto_reorient = 2;
    }

  /* Get or generate the name of the sextractor catalog to read */
  if ((opt = get_online_option ("in_GOL", argc, argv)))
    {
      strcpy (sex_catalog, opt);
      strcpy (sex_catalog_path, opt);
    }
  else
    {
      strcpy (sex_catalog, argv[1]);
      replace_file_extension (grism_image, sex_catalog, ".fits", ".cat",
                              conf->science_numext);
      build_path (AXE_OUTPUT_PATH, sex_catalog, sex_catalog_path);
    }

   if ((opt = get_online_option ("lambda_mark", argc, argv)))
    {
      lambda_mark = atof(opt);
    }
   else{
      lambda_mark = 800.0;
   }

   // check the configuration file for the smoothin keywords
   if (!check_conf_for_slitlessgeom(conf, auto_reorient))
   //if (!check_conf_for_slitlessgeom(conf, slitless_geom))
     aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
         "aXe_GOL2AF: Either the configuration file %s does not contain\n"
         "the necessary keywords for the slitless geometry: POBJSIZE,\n"
         "or this keyword has an unreasonable value < 0.0!\n",
         conf_file_path);

  fprintf (stdout,
           "aXe_GOL2AF: Main configuration file name:    %s\n",
           conf_file_path);
  fprintf (stdout,
           "aXe_GOL2AF: Input data file name:            %s\n",
           grism_image_path);
  fprintf (stdout,
           "aXe_GOL2AF: SCI extension number:            %d\n",
           conf->science_numext);
  fprintf (stdout,
           "aXe_GOL2AF: Input grism object list (GOL):   %s\n",
           sex_catalog_path);
  fprintf (stdout,
           "aXe_GOL2AF: Output aperture file name:       %s\n",
           aper_file_path);
  fprintf (stdout,
           "aXe_GOL2AF: FWHM multiplicative factor:      %f\n",
           mfwhm);
  fprintf (stdout,
           "aXe_GOL2AF: Dmag adjustment:      %f\n",
           dmag);
  if (leaveout_ignored)
    fprintf (stdout,
             "aXe_GOL2AF: Ignored object will not "
             "be included in the output aperture file\n");
  if (!leaveout_ignored)
    fprintf (stdout,
             "aXe_GOL2AF: Ignored object will be "
             "included in the output aperture file\n");
  if (auto_reorient != 2)
    fprintf (stdout,
             "aXe_GOL2AF: Tilted extraction will be performed.\n");
  if (auto_reorient == 0)
    fprintf (stdout,
             "aXe_GOL2AF: The extraction geometry follows the object\n");
  if (auto_reorient == 1)
    //if (slitless_geom)
    fprintf (stdout,
        "aXe_GOL2AF: Extraction geometry is optimized for slitless spectroscopy.\n");
    //else
    //  fprintf (stdout,
    //        "aXe_GOL2AF: The extraction geometry follows the object, but may switch.\n");
  if (auto_reorient==2)
    fprintf (stdout,
             "aXe_GOL2AF: NO tilted extraction will be performed (e.g. vertical only).\n");
  fprintf (stdout,
           "aXe_GOL2AF: Wavelength for object selection [nm]: %f\n",
           lambda_mark);
  fprintf(stdout,"\n\n");

  // extend the beams when creating
  // BAF's
  if (bck_mode)
    extend_config_beams(conf);

  fprintf (stdout, "aXe_GOL2AF: Loading object list...");
  os = get_SexObject_from_catalog (sex_catalog_path, lambda_mark);
  fprintf (stdout, "Done.\n");fflush(stdout);

  fprintf (stdout, "aXe_GOL2AF: Reading image...");
  obs = load_empty_image (grism_image_path, conf->science_numext);
  fprintf (stdout, "Done.\n");fflush(stdout);

  fprintf (stdout, "aXe_GOL2AF: Generating aperture list...");

  //if (!slitless_geom)
  //use the old, aXe-1.6  code
  //oblist = SexObjects_to_oblist(os, obs, conf, conf_file_path, mfwhm, dmag,
  //                               auto_reorient, bck_mode);
  // else

  // use the new aXe-1.7 code
  oblist = SexObjects_to_oblistII(os, obs, conf, conf_file_path, mfwhm, dmag, auto_reorient, bck_mode);

  fprintf (stdout, "Done.\n");fflush(stdout);

  fprintf (stdout, "aXe_GOL2AF: Writing aperture file...");fflush(stdout);
  num = object_list_to_file (oblist, aper_file_path, leaveout_ignored);
  fprintf (stdout, "%d beams written.\n", num);

  free_SexObjects (os);
  free_oblist (oblist);

  fprintf (stdout, "aXe_GOL2AF: Done...\n");

  exit (0);
}
/**
 * Function: load_SED_from_fitsext
 * The function creates a energy distribution from the data stored
 * in a fits file extension. The data must be stored in the columns
 * "wavelength" and "flux".
 *
 * Parameters:
 * @param  spectral_models_file - pathname to the spectral models file
 * @param  s_models             - pointer to the fits file extension
 *
 * Returns:
 * @return sed - the energy distribution created 
 */
energy_distrib *
load_SED_from_fitsext(const char spectral_models_file[], fitsfile *s_models)
{
  int f_status=0;
  int anynul;
  long nrows=0;
  int colnum1;
  int colnum2;
  
  energy_distrib *sed;
  double *sed_wavs;
  double *sed_flux;

  // allocate memory for the energy distribution
  sed = (energy_distrib *) malloc(sizeof(energy_distrib));

  // get number of rows
  fits_get_num_rows (s_models, &nrows, &f_status);
  if (f_status) {
    ffrprt (stderr, f_status);
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "load_SED_from_fitsext: "
		 "Could not determine the number of rows in"
		 " table %s",spectral_models_file);
  }

  // allocate memory for the data
  sed_wavs = (double *) malloc(nrows*sizeof(double));
  if (!sed_wavs) { 
    aXe_message (aXe_M_ERROR, __FILE__, __LINE__,
		 "Memory allocation failed");
  }
  sed_flux = (double *) malloc(nrows*sizeof(double));
  if (!sed_flux) {
    aXe_message (aXe_M_ERROR, __FILE__, __LINE__,
		 "Memory allocation failed");
  }

  // get the column number for the wavelength
  fits_get_colnum (s_models, CASEINSEN, "WAV_NM", &colnum1, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "create_interp_ftable: "
		   "Could not determine column %s in "
		   " table %s", "WAV_NM", spectral_models_file);
    }
  // read the wavelength
  fits_read_col (s_models, TDOUBLE, colnum1, 1, 1, nrows, NULL, sed_wavs,
                    &anynul, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "load_SED_from_fitsext: "
		   "Could not read content of WAVELENGTH column "
		   " from BINARY table %s", spectral_models_file);
    }

  // get the column number for the flux
  fits_get_colnum (s_models, CASEINSEN, "FLUX", &colnum2, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
  		   "create_interp_ftable: "
  		   "Could not determine column %s in "
  		   " table %s", "FLUX", spectral_models_file);
    }
  // read the flux column 
  fits_read_col (s_models, TDOUBLE, colnum2, 1, 1, nrows, NULL, sed_flux,
                    &anynul, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "load_SED_from_fitsext: "
		   "Could not read content of FLUX column "
		   " from BINARY table %s", spectral_models_file);
    }

  // transfer the vector and length information
  // to the SED object
  sed->npoints    = nrows;
  sed->wavelength = sed_wavs ;
  sed->flux       = sed_flux;

  // allocate some structures for the interpolator
  sed->interp     = gsl_interp_alloc (SMODEL_INTERP_TYPE, (size_t)sed->npoints );
  sed->accel      = gsl_interp_accel_alloc ();

  // initialize the iterpolator
  gsl_interp_init (sed->interp, sed->wavelength, sed->flux, (size_t)sed->npoints);

  // return the energy distribution
  return sed;
}
Exemple #28
0
/**
 * Function: get_ALL_from_next_in_SPC
 * The function creates and fills a full spectrum structure with
 * the content of a SPC table extension. This is only done when,
 * according to the beam ID, this beam should be corrected.
 * For extensions with higher order beams which are not corrected
 * an emply structure is returned.
 *
 * Parameters:
 * @param SPCn_ptr - pointer to the opened SPC file
 * @param aperID   - pointer to aperture identification number
 * @param beamID   - pointer to beam identification number
 *
 * Returns:
 * @return SPC - the full spectrum structure
 */
full_spectr *
get_ALL_from_next_in_SPC(fitsfile *SPC_ptr, int *aperID, int *beamID)
{
  int f_status=0, hdutype;

  long tmp;
  //long nrows=0;
  char comment[FLEN_COMMENT];

  full_spectr *SPC;


  fits_movrel_hdu (SPC_ptr, 1, &hdutype, &f_status);

  if (f_status)
    {
      *aperID = -1;
      *beamID = -1;
      SPC = NULL;
      return SPC;
    }


  // read the beam ID number
  fits_read_key_lng (SPC_ptr, "BEAMID", &tmp, comment, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_ALL_from_next_in_SPC: Error getting index keyword OBJECTID");
    }
  *beamID = (int)tmp;

  // check whether this beam should be correct
  if (*beamID > CORRMAX)
    {
      // set it to NULL and return
      SPC = NULL;
      //      fprintf (stdout, "aXe_PETFF: Skipping beam: %c.\n", BEAM(*beamID));
      return SPC;
    }

  // the beam shall be corrected and
  // first must be read in
  SPC = (full_spectr *) malloc (sizeof (full_spectr ));

  // transfer the beam ID
  SPC->beamID = (int)tmp;

  // read the aperture number
  fits_read_key_lng (SPC_ptr, "OBJECTID", &tmp, comment, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_ALL_from_next_in_SPC: Error getting index keyword OBJECTID");
    }
  // transfer the aperture ID
  *aperID = (int)tmp;
  SPC->aperID = (int)tmp;


  // Get the number of rows
  fits_get_num_rows (SPC_ptr, &tmp, &f_status);
  if (f_status) {
    ffrprt (stderr, f_status);
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "get_ALL_from_next_in_SPC: "
		 "Could not determine the number of rows in"
		 " correction function table!");
  }
  SPC->nelems = (int)tmp;

  // load the background subtracted object spectrum
  SPC->obj_spec = get_spectrum_from_SPC(SPC_ptr, "COUNT", "ERROR", SPC->nelems);

  // load the total object spectrum
  SPC->fgr_spec = get_spectrum_from_SPC(SPC_ptr, "TCOUNT", "TERROR", SPC->nelems);

  // load the background spectrum
  SPC->bck_spec = get_spectrum_from_SPC(SPC_ptr, "BCOUNT", "BERROR", SPC->nelems);

  // return the filled structure
  return SPC;
}
Exemple #29
0
int
main (int argc, char *argv[])
{
  char *opt;

  char grism_file[MAXCHAR];
  char grism_file_path[MAXCHAR];

  char aper_file[MAXCHAR];
  char aper_file_path[MAXCHAR];

  char obj_PET_file[MAXCHAR];
  char obj_PET_file_path[MAXCHAR];

  char bck_PET_file[MAXCHAR];
  char bck_PET_file_path[MAXCHAR];

  char conf_file[MAXCHAR];
  char conf_file_path[MAXCHAR];

  char SPC_file[MAXCHAR];
  char SPC_file_path[MAXCHAR];

  char SPC_opt_file[MAXCHAR];
  char SPC_opt_file_path[MAXCHAR];

  char WHT_file[MAXCHAR];
  char WHT_file_path[MAXCHAR];

  char label[MAXCHAR];

  int i, index, dobck = 0, noflux = 1;

  object **oblist;

  FITScards      *cards;

  ap_pixel *obj_PET = NULL, *bck_PET = NULL;

  observation *obs;

  //tracestruct *trace;
  aperture_conf *conf;

  spectrum *obj_spec = NULL, *bck_spec = NULL, *sobj_spec = NULL;
  spectrum *resp;
  response_function *resp_func;
  calib_function *wl_calibration;

  fitsfile *OPET_ptr, *BPET_ptr;
  int f_status = 0;

  fitsfile *SPC_ptr, *SPC_opt_ptr, *WHT_ptr;

  gsl_matrix *weights;
  drzstamp     *modvar;

  int obj_aperID, obj_beamID, objindex;
  int bck_aperID, bck_beamID;

  char table[MAXCHAR], table_path[MAXCHAR];
  //char comment[FLEN_COMMENT];
  int empty;
  int drizzle;
  int quant_cont=0;
  int opt_weights=0;
  int for_grism=0;
  int smooth_conv=0;

  d_point smooth_params;

  double exptime;
  double sky_cps;

  drzstamp_dim  dimension;
  gsl_matrix *coverage;

  if (((argc < 3))
      || (opt = get_online_option ("help", argc, argv)))
    {
      fprintf (stdout,
	       "ST-ECF European Coordinating Facility\n"
	       "Copyright (C) 2002 Martin Kuemmel\n"
	       "aXe_PET2SPC Version %s:\n"
	       "             aXe task that produces 1-D, binned spectra using information\n"
	       "             contained in a OPET and a BPET. A 1-D spectrum is generated\n"
	       "             for each beam in each of both the OPET and the BPET files\n"
	       "             The binned background spectra of each beam (order) is then\n"
	       "             subtraced from the corresponding spectra form the OPET. Th\ne"
	       "             background subtraction (and reading a BPET altogether can be\n"
	       "             avoided by using the -noBPET option\n"
	       "             An SPC file, a multi-extension FITS file containing binned\n"
	       "             spectra is produced. Each extension (named after the beam ID,\n"
	       "             e.g. 11B for aperture (object) 11,beam (order) B) contains the\n"
	       "             following columns:\n"
	       "\n"
	       "              LAMBDA      ; the wavelength (in A)\n"
	       "              TCOUNT      ; the total number of counts (in DN)\n"
	       "              TERROR      ; the error in TERRORS (in DN)\n"
	       "              BCOUNT      ; the estimated number of counts from the\n"
	       "                            background (in DN)\n"
	       "              BERROR      ; the error in BCOUNTS (in DN)\n"
	       "              COUNT       ; the estimated number of counts from the\n"
	       "                            object (in DN)\n"
	       "              ERROR       ; the error in COUNTS (in DN)\n"
	       "              FLUX        ; the estimated flux (in erg/s/cm^2/A)\n"
	       "              FERROR      ; the error in FLUX (in erg/s/cm^s/A)\n"
	       "              WEIGHT      ; weight (in pixels)\n"
	       "\n"
	       "             Input FITS mages are looked for in $AXE_IMAGE_PATH\n"
	       "             aXe config file is looked for in $AXE_CONFIG_PATH\n"
	       "             All outputs are writen to $AXE_OUTPUT_PATH\n"
	       "\n"
	       "Usage:\n"
	       "     aXe_PET2SPC [g/prism image filename] [aXe config file name] [options]\n"
	       "\n"
	       "Options:\n"
	       "             -noBPET         - to disable the use of a BPET file\n"
	       "             -noflux         - to disable the flux calibration\n"
	       "             -drz            - use $AXE_DRIZZLE_PATH to locate the grism-, OAF-\n"
	       "                             - and PET-files instead of $AXE_IMAGE/OUTPUT_PATH\n"
	       "             -in_AF=[string] - overwrite the default input Aperture File name\n"
	       "             -OPET=[string]  - overwrite the default input Object PET file name\n"
	       "             -BPET=[string]  - overwrite the default input Background PET\n"
	       "                               file name\n"
	       "             -out_SPC=[string] - overwrite the default output SPC file name\n"
	       "\n"
	       "Example:\n"
	       "       ./aXe_PET2SPC slim_grism.fits SLIM.conf.A.0\n"
	       "\n",RELEASE);
      exit (1);
    }

  // make a general opening statement
  fprintf (stdout, "aXe_PET2SPC: Starting...\n");

  // get the name of the flt-file
  index = 0;
  strcpy (grism_file, argv[++index]);
  if ((opt = get_online_option ("drz", argc, argv)))
    {
      build_path (AXE_DRIZZLE_PATH, grism_file, grism_file_path);
      drizzle=1;
    }
  else
    {
      build_path (AXE_IMAGE_PATH, grism_file, grism_file_path);
      drizzle=0;
    }

  // get the name of the configuration file
  strcpy (conf_file, argv[++index]);
  build_path (AXE_CONFIG_PATH, conf_file, conf_file_path);

  // load the configuration file
  conf = get_aperture_descriptor (conf_file_path);

  // Determine where the various extensions are in the FITS file
  get_extension_numbers(grism_file_path, conf,conf->optkey1,conf->optval1);


  // Build aperture file name
  replace_file_extension (grism_file, aper_file, ".fits",
			  ".OAF", conf->science_numext);
  if (drizzle)
    build_path (AXE_DRIZZLE_PATH, aper_file, aper_file_path);
  else
    build_path (AXE_OUTPUT_PATH, aper_file, aper_file_path);

  // Build object PET file name
  replace_file_extension (grism_file, obj_PET_file, ".fits",
			  ".PET.fits", conf->science_numext);
  // make the total filename
  if (drizzle)
    build_path (AXE_DRIZZLE_PATH, obj_PET_file, obj_PET_file_path);
  else
    build_path (AXE_OUTPUT_PATH, obj_PET_file, obj_PET_file_path);


  // Build background PET file name
  replace_file_extension (grism_file, bck_PET_file, ".fits",
			  ".BCK.PET.fits", conf->science_numext);

  // make the total filename
  if (drizzle)
    build_path (AXE_DRIZZLE_PATH, bck_PET_file, bck_PET_file_path);
  else
    build_path (AXE_OUTPUT_PATH, bck_PET_file, bck_PET_file_path);

  // make a non-standard AF name if necessary
  if ((opt = get_online_option ("in_AF", argc, argv)))
    {
      strcpy(aper_file,opt);
      strcpy(aper_file_path,opt);
    }

  // make a non-standard PET name if necessary
  if ((opt = get_online_option ("OPET", argc, argv)))
    {
      strcpy(obj_PET_file,opt);
      strcpy(obj_PET_file_path,opt);
    }

  // make a non-standard BPET name if necessary
  if ((opt = get_online_option ("BPET", argc, argv)))
    {
      strcpy(bck_PET_file,opt);
      strcpy(bck_PET_file_path,opt);
    }

  // set the flagg for no background subtraction
  if ((opt = get_online_option ("noBPET",argc,argv)))
    {
      dobck = 0;
      strcpy(bck_PET_file,"None");
      strcpy(bck_PET_file_path, "None");
    }
  else
    {
      dobck = 1;
    }

  // set the flagg for flux
  if ((opt = get_online_option ("noflux",argc,argv)))
    noflux = 1;
  else
    noflux = 0;

  // check for the weights flagg,
  // set the file name if the flagg is set
  if ((opt = get_online_option ("opt_weights",argc,argv)))
    opt_weights = 1;
  else
    opt_weights = 0;

  // read the trigger for smoothing the sensitivity
  if ((opt = get_online_option ("smooth_conv",argc,argv)))
    smooth_conv = 1;
  else
    smooth_conv = 0;

  if ((opt = get_online_option ("out_SPC", argc, argv)))
    {
      strcpy (SPC_file, opt);
      strcpy (SPC_file_path, opt);

      if (opt_weights)
	{
	  replace_file_extension (SPC_file, SPC_opt_file, ".fits",
			      "_opt.SPC.fits", -1);
	  replace_file_extension (SPC_file_path, SPC_opt_file_path, ".fits",
			      "_opt.SPC.fits", -1);
	  replace_file_extension (SPC_opt_file, WHT_file, ".SPC.fits",
				  ".WHT.fits", -1);
	  replace_file_extension (SPC_opt_file_path, WHT_file_path, ".SPC.fits",
				  ".WHT.fits", -1);
	}
    }
  else
    {
      replace_file_extension (obj_PET_file, SPC_file, ".PET.fits",
			      ".SPC.fits", -1);
      if (drizzle)
	build_path (AXE_DRIZZLE_PATH, SPC_file, SPC_file_path);
      else
	build_path (AXE_OUTPUT_PATH, SPC_file, SPC_file_path);

      if (opt_weights)
	{
	  replace_file_extension (obj_PET_file, SPC_opt_file, ".PET.fits",
				  "_opt.SPC.fits", -1);
	  replace_file_extension (SPC_opt_file, WHT_file, ".SPC.fits",
				  ".WHT.fits", -1);
	  if (drizzle)
	    {
	      build_path (AXE_DRIZZLE_PATH, SPC_opt_file, SPC_opt_file_path);
	      build_path (AXE_DRIZZLE_PATH, WHT_file, WHT_file_path);
	    }
	  else
	    {
	      build_path (AXE_OUTPUT_PATH, SPC_opt_file, SPC_opt_file_path);
	      build_path (AXE_OUTPUT_PATH, WHT_file, WHT_file_path);
	    }
	}
    }

  // check the configuration file for the smoothin keywords
  if (!check_conf_for_smoothing(conf, smooth_conv))
    aXe_message(aXe_M_FATAL, __FILE__, __LINE__,
        "aXe_PET2SP: Either the configuration file %s does not contain\n"
        "the necessary keywords for the smoothing (POBJSIZE, SMFACTOR),\n"
        "or one of these keywords has an unreasonable value < 0.0!\n",
        conf_file_path);


  // give feedback onto the screen:
  // report on input and output
  // and also on specific parameter
  fprintf (stdout, "aXe_PET2SPC: Input configuration file name:   %s\n",
	   conf_file_path);
  fprintf (stdout, "aXe_PET2SPC: Input Object Aperture file name: %s\n",
	   aper_file_path);
  fprintf (stdout, "aXe_PET2SPC: Input Object PET file name:      %s\n",
	   obj_PET_file_path);
  if (dobck)
    fprintf (stdout, "aXe_PET2SPC: Input Background PET file name:  %s\n",
	     bck_PET_file_path);
  fprintf (stdout, "aXe_PET2SPC: Output SPC file name:            %s\n",
	   SPC_file_path);
  if (opt_weights)
    {
      fprintf (stdout, "aXe_PET2SPC: Computing optimal weights.\n");
      fprintf (stdout, "aXe_PET2SPC: Optimized SPC file name:         %s\n",
	       SPC_opt_file_path);
      fprintf (stdout, "aXe_PET2SPC: Output WHT file name:            %s\n",
	       WHT_file_path);
    }
  if (!noflux)
    {
      fprintf (stdout, "aXe_PET2SPC: Performing flux calibration.\n");
      if (smooth_conv)
	fprintf (stdout, "aXe_PET2SPC: Using smoothed sensitivity curves.\n");
    }
  fprintf (stdout, "\n\n");

  //
  // try to get the descriptor 'exptime' from the 'sci'-extension
  //
  exptime = (double)get_float_from_keyword(grism_file_path, conf->science_numext, conf->exptimekey);
  if (isnan(exptime))
    exptime = (double)get_float_from_keyword(grism_file_path, 1, conf->exptimekey);
  if (isnan(exptime))
    exptime = 1.0;

  //
  // try to get the descriptor 'SKY_CPS' from the 'sci'-extension
  //
  sky_cps = (double)get_float_from_keyword(grism_file_path, conf->science_numext, "SKY_CPS");
  if (isnan(sky_cps))
    sky_cps = 0.0;


  //  Open the OPET file for reading
  fits_open_file (&OPET_ptr, obj_PET_file_path, READONLY, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "aXe_PET2SPC: Could not open file: %s\n",
		   obj_PET_file_path);
    }

  // check whether the contamination is quantitative
  quant_cont = check_quantitative_contamination(OPET_ptr);

  if (opt_weights && !quant_cont)
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "aXe_PET2SPC: The optimal extractions needs quantitative contamination! "
		 " Please re-run aXe with Gauss or Fluxcube contamination!");

  obs = load_dummy_observation ();
  /* Loading the object list */
  fprintf (stdout, "aXe_PET2SPC: Loading object aperture list...");
  oblist = file_to_object_list_seq (aper_file_path, obs);
  fprintf (stdout,"%d objects loaded.\n",object_list_size(oblist));

  if (dobck)
    {
      //  Open the file for reading
      fits_open_file (&BPET_ptr, bck_PET_file_path, READONLY, &f_status);
      if (f_status)
	{
	  ffrprt (stderr, f_status);
	  aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		       "aXe_PET2SP: Could not open file: %s\n",
		       bck_PET_file_path);
	}
    }


  /* Copy the header info from the grism image */
  SPC_ptr = create_SPC_opened (SPC_file_path,1);
  cards = get_FITS_cards_opened(OPET_ptr);
  put_FITS_cards_opened(SPC_ptr, cards);
  free_FITScards(cards);

  if (opt_weights)
    {
      cards = get_FITS_cards_opened(OPET_ptr);

      // open the WHT file and add the header keywords
      WHT_ptr = create_FITSimage_opened (WHT_file_path, 1);
      put_FITS_cards_opened(WHT_ptr, cards);

      // open the opt_SPC and add the header keywords
      SPC_opt_ptr = create_SPC_opened (SPC_opt_file_path,1);
      put_FITS_cards_opened(SPC_opt_ptr, cards);

      // delete the header keywords
      free_FITScards(cards);
    }

  // do something only if there
  // exist valid objects
  i = 0;
  if (oblist!=NULL)
    {

      // turn until the end of the PET is reached
      while (1)
	{
	  empty=0;

	  // Get the PET for this object
	  obj_PET = get_ALL_from_next_in_PET(OPET_ptr, &obj_aperID, &obj_beamID);

	  // load the background PET if requested
	  if (dobck)
	    {
	      bck_PET = get_ALL_from_next_in_PET(BPET_ptr, &bck_aperID, &bck_beamID);
	      if ((bck_aperID!=obj_aperID)||(bck_beamID!=obj_beamID))
		aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
			     "Background PET and Object PET extensions are not"
			     " in the same order and cannot be combined.\n");
	    }

	  // end of PET reached: the break condition
	  if ((obj_aperID==-1) && (obj_beamID==-1))
	    break;

	  // signal an empty PET
	  if (obj_PET==NULL)
	    empty=1;

	  // give feedback to the screen
	  fprintf (stdout, "aXe_PET2SPC: BEAM %d; %d%c\n", i, obj_aperID, BEAM(obj_beamID));fflush(stdout);

	  // identify the object which matches the PET
	  objindex =  find_object_in_object_list(oblist,obj_aperID);

	  // look whether we are for grisms or prisms
	  for_grism = check_for_grism (conf_file_path, obj_beamID);
	  wl_calibration  = get_calfunc_for_beam(oblist[objindex]->beams[obj_beamID], for_grism, conf_file_path, conf);

	  // compute the object spectrum
	  obj_spec = bin_naive (obj_PET, oblist[objindex]->beams[obj_beamID].width,
				oblist[objindex]->beams[obj_beamID].orient,	quant_cont);

	  // check for the existence of a background PET
	  if (dobck)
	    {
	      // compute the background spectrum
	      bck_spec = bin_naive (bck_PET,
				    oblist[objindex]->beams[bck_beamID].width,
				    oblist[objindex]->beams[bck_beamID].orient, quant_cont);
	    }
	  else
	    {
	      // create a dummy background spectrum
	      bck_spec = empty_counts_spectrum_copy(obj_spec);
	    }


	  // subtract the background spectrum from the
	  // object (or forground) spectrum
	  sobj_spec = subtract_spectra (obj_spec, bck_spec);

	  if(!noflux)
	    {
	      get_troughput_table_name(conf_file_path,
				       oblist[objindex]->beams[obj_beamID].ID,
				       table);
	      if (strcmp(table,"None"))
		{
		  build_path (AXE_CONFIG_PATH, table, table_path);
		  resp=get_response_function_from_FITS(table_path,2);
		  resp_func = create_response_function(table_path);
		  if (resp->spec_len <2)
		    {
		      aXe_message (aXe_M_WARN1, __FILE__, __LINE__,
				   "Throughput table %s contains only %d"
				   " values. No sensitivity curve was applied.\n",
				   table_path,resp->spec_len);
		    }
		  else
		    {
		      fprintf(stdout,"aXe_PET2SPC: Applying sensitivity contained in %s\n",table_path);
		      smooth_params = get_smooth_pars_for_beam(conf, smooth_conv, oblist[objindex]->beams[obj_beamID]);
		      if (smooth_params.x > 0.0)
		        {
		          // apply a smoothed flux conversion
			  apply_smoothed_response(wl_calibration, for_grism, quant_cont, resp_func, smooth_params, sobj_spec);
			}
		      else
			{
			  // apply a normal flux conversion
			  apply_response_function(sobj_spec,resp, quant_cont);
			}
		    }
		  // free the memory of the
		  // response functions
		  free_spectrum(resp);
		  free_response_function(resp_func);
		}
	    }
	  if (empty!=1)
	    {
	      add_spectra_to_SPC_opened (SPC_ptr, obj_spec, bck_spec,
					 sobj_spec, oblist[objindex]->ID, oblist[objindex]->beams[obj_beamID].ID);


	      /* Copy header from OPET extension into this SPC extension */
	      cards = get_FITS_cards_opened(OPET_ptr);
	      put_FITS_cards_opened(SPC_ptr,cards);
	      free_FITScards(cards);

	    }

	  free_spectrum (bck_spec);
	  free_spectrum (sobj_spec);
	  free_spectrum (obj_spec);


	  if (opt_weights)
	    {
	      // get the dimension in trace length
	      // and crossdispersion
	      dimension = get_all_dims(obj_PET, bck_PET,
				       oblist[objindex]->beams[obj_beamID], dobck);

	      // check for empty PET
	      if (!dimension.resolution)
		{
		  // create dummies in case of empty PET's
		  weights = get_default_weight();
		  modvar  = get_default_modvar();
		}
	      else
		{
		  // prepare the PET's by computing the inverse variance.
		  // Also the trace distances are shifted by 0.5
		  // to get a sampling comparable to the unweighted
		  // extraction
		  prepare_inv_variance(obj_PET, bck_PET, dobck, conf, exptime, sky_cps, 0.0);

		  // compute the inverse variance and the profile
		  // image in the trace distance - crossdispersion plane
		  modvar = compute_modvar(obj_PET, oblist[objindex]->beams[obj_beamID], dimension);

		  // compute the optimal weights
		  weights = comp_allweight(modvar);

		}

	      if (dimension.resolution && empty != 1)
		{
		  sprintf (label, "WHT_%d%c", obj_aperID, BEAM (obj_beamID));
		  gsl_to_FITSimage_opened (weights, WHT_ptr ,0,label);

		  // make and store the default header
		  cards = beam_to_FITScards(oblist[objindex],obj_beamID);
		  put_FITS_cards_opened(WHT_ptr,cards);
		  free_FITScards(cards);
		}

	      // create the optimal weighted
	      // foreground spectrum
	      obj_spec = bin_optimal (obj_PET,oblist[objindex]->beams[obj_beamID],
				      quant_cont, weights, dimension, coverage);



	      // check for the presence of a background PET
	      if (dobck)
		{
		  // create the optimal weighted
		  // background spectrum
		  bck_spec = bin_optimal (bck_PET,oblist[objindex]->beams[obj_beamID],
					  quant_cont, weights, dimension, coverage);
		}
	      else
		{
		  // make a dummy background spectrum
		  bck_spec = empty_counts_spectrum_copy(obj_spec);
		}

	      // release memory
	      gsl_matrix_free(weights);
	      free_drzstamp(modvar);


	  // subtract the background spectrum from the
	  // object (or forground) spectrum
	  sobj_spec = subtract_spectra (obj_spec, bck_spec);

	  if(!noflux)
	    {
	      get_troughput_table_name(conf_file_path,
				       oblist[objindex]->beams[obj_beamID].ID,
				       table);
	    if (strcmp(table,"None"))
	      {
		build_path (AXE_CONFIG_PATH, table, table_path);
		resp=get_response_function_from_FITS(table_path,2);
		resp_func = create_response_function(table_path);
		if (resp->spec_len <2)
		  {
		    aXe_message (aXe_M_WARN1, __FILE__, __LINE__,
				 "Throughput table %s contains only %d"
				 " values. No sensitivity curve was applied.\n",
				 table_path,resp->spec_len);
		  }
		else
		  {
		    fprintf(stdout,"aXe_PET2SPC: Applying sensitivity contained in %s\n",table_path);
		    smooth_params = get_smooth_pars_for_beam(conf, smooth_conv, oblist[objindex]->beams[obj_beamID]);
                    if (smooth_params.x > 0.0)
                      {
                        apply_smoothed_response(wl_calibration, for_grism, quant_cont, resp_func, smooth_params, sobj_spec);
                      }
		    else
		      {
			apply_response_function(sobj_spec,resp, quant_cont);
		      }
		  }
		// free the memory
		free_spectrum(resp);
		free_response_function(resp_func);
	      }
	    }
	  if (empty!=1)
	    {
	      add_spectra_to_SPC_opened (SPC_opt_ptr, obj_spec, bck_spec,
					 sobj_spec, oblist[objindex]->ID, oblist[objindex]->beams[obj_beamID].ID);


	      /* Copy header from OPET extension into this SPC extension */
	      cards = get_FITS_cards_opened(OPET_ptr);
	      put_FITS_cards_opened(SPC_opt_ptr,cards);
	      free_FITScards(cards);

	    }

	  free_spectrum (bck_spec);
	  free_spectrum (sobj_spec);
	  free_spectrum (obj_spec);
	    }

	  // free memory
	  free_calib (wl_calibration);
	  if (bck_PET!=NULL)
	    free (bck_PET);
	  if (obj_PET!=NULL)
	    free (obj_PET);
	  i++;
        }
    }

  fits_close_file (SPC_ptr, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "aXe_PET2SPC: " "Error closing SPC: %s\n",
		   SPC_file_path);
    }

  if (opt_weights)
    {
      fits_close_file (WHT_ptr, &f_status);
      if (f_status)
	{
	  ffrprt (stderr, f_status);
	  aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		       "aXe_PET2SPC: " "Error closing WHT: %s\n",
		       WHT_file_path);
	}
      fits_close_file (SPC_opt_ptr, &f_status);
      if (f_status)
	{
	  ffrprt (stderr, f_status);
	  aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		       "aXe_PET2SPC: " "Error closing PSC: %s\n",
		       SPC_opt_file_path);
	}
    }

  if (oblist!=NULL)
    free_oblist (oblist);

  fprintf (stdout, "aXe_PET2SPC: Done...\n");
  exit (0);
}
Exemple #30
0
int
main (int argc, char *argv[])
{
  char *opt;
  char aper_file[MAXCHAR];
  char aper_file_path[MAXCHAR];

  char conf_file[MAXCHAR];
  char conf_file_path[MAXCHAR];

  char grism_file[MAXCHAR];
  char grism_file_path[MAXCHAR];

  char PET_file[MAXCHAR];
  char PET_file_path[MAXCHAR];

  //  char outputroot[MAXCHAR];
  //  char outputroot_path[MAXCHAR];
  char STP_file[MAXCHAR];
  char STP_file_path[MAXCHAR];

  //  char output_path[MAXCHAR];

  aperture_conf *conf;

  object **oblist;
  observation *obs;

  ap_pixel *PET;

  int index, i;
  char label[MAXCHAR];

  fitsfile *PET_ptr, *STP_ptr;
  int f_status = 0;

  int aperID, beamID, objindex;
  FITScards *cards;
  FITScards *xymin_cards;

  gsl_matrix *rstamp;
  drzstamp *drzstmp;
  drzstamp_dim dim;

  int rectified = 0;
  //int drizzled = 0;
  int drizzle=0;
  int drzstamp=0;
  int for_grism=0;

  d_point stp_min;

  if ((argc < 3) || (opt = get_online_option ("help", argc, argv)))
    {
      fprintf (stdout,
	       "ST-ECF European Coordinating Facility\n"
	       "aXe_STAMPS Version %s:\n"
	       "           Task that generates some Postscript stamp images from the\n"
	       "           content of a Pixel Extraction Table (PET)\n"
	       "           The trace is overplotted and is generated from the group\n"
	       "           of pixels in the PET which have the smallest projected distance\n"
	       "           to the trace in the PET. No analytical a-priori trace function \n"
	       "           is used.\n"
	       "\n"
	       "Usage:\n"
	       "      aXe_STAMPS g/prism_filename configuration_filename [options]\n"
	       "\n"
	       "Options:\n"
	       "      -rectified            - produces rectified stamp image following the\n"
	       "                              direction of the extraction process\n"
	       "      -drz                  - use $AXE_DRIZZLE_PATH to locate the grism-, OAF-\n"
	       "                              and PET-files instead of $AXE_IMAGE/OUTPUT_PATH\n"
	       "      -in_AF=[string]       - overwrite the automatically generated name\n"
	       "                              of the input aperture file\n"
	       "      -in_PET=[string]      - overwrite the automatically generated name\n"
	       "                              of the input PET file\n"
	       "      -out_STP=[string]     - overwrite the automatically generated name\n"
	       "                              of the output stamp FITS image\n"
	       "\n",RELEASE);
      exit (1);
    }

  fprintf (stdout, "aXe_STAMPS: Starting...\n");

  index = 0;
  strcpy (grism_file, argv[++index]);
  if ((opt = get_online_option ("drz", argc, argv))){
    build_path (AXE_DRIZZLE_PATH, grism_file, grism_file_path);
    drizzle=1;
  }
  else{
    build_path (AXE_IMAGE_PATH, grism_file, grism_file_path);
    drizzle=0;
  }

  strcpy (conf_file, argv[++index]);
  build_path (AXE_CONFIG_PATH, conf_file, conf_file_path);


  conf = get_aperture_descriptor (conf_file_path);

  /* Determine where the various extensions are in the FITS file */
  get_extension_numbers(grism_file_path, conf,conf->optkey1,conf->optval1);

  /* Build aperture file name */
  if ((opt = get_online_option("in_AF", argc, argv))){
    /* get it */
    strcpy (aper_file, opt);
    strcpy (aper_file_path, opt);
  }
  else {
    replace_file_extension (grism_file, aper_file, ".fits",
			    ".OAF", conf->science_numext);
    if (drizzle)
      build_path (AXE_DRIZZLE_PATH, aper_file, aper_file_path);
    else
      build_path (AXE_OUTPUT_PATH, aper_file, aper_file_path);
  }

  if ((opt = get_online_option("in_PET", argc, argv))){
    /* get it */
    strcpy (PET_file, opt);
    strcpy (PET_file_path, opt);
  }
  else{
    /* Build object PET file name */
    replace_file_extension (grism_file, PET_file, ".fits",
			    ".PET.fits", conf->science_numext);
    if (drizzle)
      build_path (AXE_DRIZZLE_PATH, PET_file, PET_file_path);
    else
      build_path (AXE_OUTPUT_PATH, PET_file, PET_file_path);
  }

  if ( (opt = get_online_option ("out_STP", argc, argv)) )
    {
      strcpy (STP_file, opt);
      //      strcpy (STP_file_PATH, opt);
    }
  else
    {
      //      replace_file_extension (PET_file, STP_file, ".PET.fits", ".STP.fits",-1);
      replace_file_extension (grism_file, STP_file, ".fits", ".STP.fits",conf->science_numext);
    }


  if (drizzle)
    build_path (AXE_DRIZZLE_PATH, STP_file, STP_file_path);
  else
    build_path (AXE_OUTPUT_PATH, STP_file, STP_file_path);

  if ((opt=get_online_option("rectified",argc,argv)))
    rectified = 1;
  else if ((opt = get_online_option ("drzstamp", argc, argv)))
    drzstamp=1;


  // give feedback onto the screen:
  // report on input and output
  // and also on specific parameters
  fprintf (stdout, "aXe_STAMPS: Input Image file name:               %s\n",
	   grism_file_path);
  fprintf (stdout, "aXe_STAMPS: Input Aperture file name:            %s\n",
	   aper_file_path);
  fprintf (stdout, "aXe_STAMPS: Input PET file name:                 %s\n",
	   PET_file_path);
  fprintf (stdout, "aXe_STAMPS: Name of STP file :                   %s\n",
	   STP_file_path);
  if (rectified)
    fprintf (stdout, "aXe_STAMPS: Producing rectified stamp images.\n");
  else if (drzstamp)
    fprintf (stdout, "aXe_STAMPS: Producing drizzled stamp images.\n");
  else
    fprintf (stdout, "aXe_STAMPS: Producing trace stamp images.\n");


  // Loading the object list
  obs = load_dummy_observation ();
  fprintf (stdout, "\naXe_STAMPS: Loading object aperture list...");
  oblist = file_to_object_list_seq (aper_file_path, obs);
  fprintf (stdout,"%d objects loaded.\n\n",object_list_size(oblist));

  //  Open the OPET file for reading
  fits_open_file (&PET_ptr, PET_file_path, READONLY, &f_status);
  if (f_status)
    {
      ffrprt (stdout, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "aXe_STAMPS: Could not open file: %s\n",
		   PET_file_path);
    }

  STP_ptr = create_FITSimage_opened (STP_file_path, 1);

  i = 0;
  if (oblist!=NULL)
    {
      while (1)
	{

	  /* Get the PET for this object */
	  PET = get_ALL_from_next_in_PET(PET_ptr, &aperID, &beamID);
	  if ((aperID==-1) && (beamID==-1)) break;
	  fprintf (stdout, "aXe_STAMPS: BEAM %d%c.", aperID, BEAM(beamID));
	  objindex =  find_object_in_object_list(oblist,aperID);

	  sprintf (label, "%s.%d%c.ps/CPS", STP_file_path,
		   oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID));

	  // determine the minimum in x and y
	  stp_min.x = -1.0;
	  stp_min.y = -1.0;

	  // special treatment for FORS2: dirzzled stamp images
	  if (drzstamp)
	    {

	      for_grism = check_for_grism (conf_file_path, beamID);
	      if (!for_grism)
		aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
			     "aXe_STAMPS: Drizzled stamp images are not\n"
			     "supported for prism images. Please choose a different option!\n");

	      // get the dimensions of the drizzled stamp
	      dim = get_stamp_dim(PET, oblist[objindex]->beams[beamID].width, conf, beamID, &stp_min);

	      // fill the drzstamp structure (counts plus weight matrix)
	      drzstmp = drizzled_stamp_img (PET,oblist[objindex]->beams[beamID].width,
					    oblist[objindex]->beams[beamID].orient,  dim);

	      // does this make sense
	      interpolate_over_NaN (drzstmp->counts);

	      // give the extension name and store the counts
	      sprintf (label, "BEAM_%d%c",oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID));
	      gsl_to_FITSimage_opened (drzstmp->counts, STP_ptr ,0,label);

	      // in case that the stamp is no dummy, make and store the WCS header
	      if (dim.resolution)
		{
		  cards = get_WCS_FITScards(dim.xstart*dim.resolution, dim.resolution, dim.ystart);
                  put_FITS_cards_opened(STP_ptr,cards);
                  free_FITScards(cards);
		}

	      // make and store the default header
	      cards = beam_to_FITScards(oblist[objindex],beamID);
              xymin_cards = stpmin_to_FITScards(stp_min);
	      put_FITS_cards_opened(STP_ptr,cards);
              put_FITS_cards_opened(STP_ptr,xymin_cards);
	      free_FITScards(cards);
              free_FITScards(xymin_cards);

	      // give the extension name and store the weight image
	      sprintf (label, "WEIG_%d%c",oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID));
	      gsl_to_FITSimage_opened (drzstmp->weight, STP_ptr ,0,label);

	      // in case that the stamp is no dummy, make and store the WCS header
	      if (dim.resolution)
		{
		  cards = get_WCS_FITScards(dim.xstart*dim.resolution, dim.resolution, dim.ystart);
		  put_FITS_cards_opened(STP_ptr,cards);
		  free_FITScards(cards);
		}

	      // make and store the default header
	      cards = beam_to_FITScards(oblist[objindex],beamID);
              xymin_cards = stpmin_to_FITScards(stp_min);
	      put_FITS_cards_opened(STP_ptr,cards);
              put_FITS_cards_opened(STP_ptr,xymin_cards);
	      free_FITScards(cards);
              free_FITScards(xymin_cards);

	      // free the structure with the count and weight matrix
	      free_drzstamp(drzstmp);
	    }
	  else
	    {
	      if (rectified)
		{
		  rstamp = rectified_stamp_img (PET,oblist[objindex]->beams[beamID].width, &stp_min);
		}
	      else
		{
		  rstamp = stamp_img (PET,oblist[objindex]->beams[beamID].width, &stp_min);
		}
	      sprintf (label, "BEAM_%d%c",oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID));
	      interpolate_over_NaN (rstamp);
	      gsl_to_FITSimage_opened (rstamp, STP_ptr ,0,label);
	      cards = beam_to_FITScards(oblist[objindex],beamID);
              xymin_cards = stpmin_to_FITScards(stp_min);
	      put_FITS_cards_opened(STP_ptr,cards);
              put_FITS_cards_opened(STP_ptr,xymin_cards);
	      free_FITScards(cards);
              free_FITScards(xymin_cards);

	      free_stamp_img(rstamp);
	    }

	  if (PET!=NULL)
	    free(PET);

	  fprintf (stdout, " Done.\n");
	  i++;
	}

    }
  if (oblist!=NULL) free_oblist (oblist);

  fits_close_file (STP_ptr, &f_status);
  if (f_status)
    {
      ffrprt (stdout, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "aXe_STAMPS: Could not" " close STP file: %s\n", STP_file_path);
    }

  fprintf (stdout, "aXe_STAMPS: Done...\n");

  /* Copy the header info from the grism image */
  {
    FITScards *cards;
    cards = get_FITS_cards (PET_file_path, 1);
    put_FITS_cards(STP_file_path,1,cards);
    free_FITScards(cards);
  }
  exit (0);
}