Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
/**
 * 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;
}
Beispiel #5
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);
}
Beispiel #6
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;
}
/**
 * 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;
}
Beispiel #8
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);
}