gnuastro-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[task #16073] --copykeys of Fits program takes keyword names also


From: Jash Shah
Subject: [task #16073] --copykeys of Fits program takes keyword names also
Date: Fri, 25 Mar 2022 09:40:58 -0400 (EDT)

Follow-up Comment #3, task #16073 (project gnuastro):

Hey @makhlaghi, I've come with a crude solution to this for now, wanted to get
your thoughts on it.


I've tried to follow a similar flow as --copykeys=INT:INT does currently.
=== Changes ===
1. Add a _gal_list_str_t *keystocopy_ to the _fitsparams_ struct.
2. Update the _ui_check_copykeys()_ fuction in _/bin/fits/ui.c_ to check
whether the first character of the entered value of --copykeys is a capital
letter(maybe we can instead check if it's a number or not as suggested in your
original comment.)
==== ui_check_copykeys() ====

static void
ui_check_copykeys(struct fitsparams *p)
{
  ....

  /* Initialize the values. */
  p->copykeysrange[0]=p->copykeysrange[1]=GAL_BLANK_LONG;
  
  /* Check if first char of copykeys is a capital letter or number */
  if(*pt >=65 && *pt<= 90){
    /* Parse the copykeys string and store name of each keyword in keystocopy
list*/
    char *first = strtok(p->copykeys, ",");

    while(first != NULL){
      gal_list_str_add(&p->keystocopy, first, 0);
      first = strtok(NULL,",");
    }
  }
  else{
    ...Perform steps as normal for INT:INT input...
}


1. So here, the _copykeysrange_ array elements stay as _GAL_BLANK_LONG_
2. In _/bin/fits/keywords.c_ I've added this to the part in main function
where, _char *inkeys_ was being set.
==== keywords() ====

/*
   If a list of keys are to be copied then call keywords_copykeys_str
   If a range of keywords must be copied, get all the keywords as a
     single string. */
  if(p->copykeys)
    {
      if (p->keystocopy){
        keywords_copykeys_str(p);
      }
      else{
      keywords_open(p, &fptr, READONLY);
      if( fits_convert_hdr2str(fptr, 0, NULL, 0, &inkeys, &numinkeys,
                               &status) )
        gal_fits_io_error(status, NULL);
      status=0;
      }
    }


        1. Also, I've updated the condition for when _keywords_copykeys()_ will 
be
called to avoid calling it if _keystocopy_ exists.

  /* Write desired keywords into output when they are given in range. */
  if(p->copykeys && !p->keystocopy)
    {
      keywords_copykeys(p, inkeys, numinkeys);
      free(inkeys);
    }


1.  This is the main _keywords_copykeys_str()_ function used for copying data
from input file to output.
==== keywords_copykeys_str() ====

/*
To copy keys to output file when --copykeys are given in STR,STR,STR format
*/
static void
keywords_copykeys_str(struct fitsparams *p)
{
  fitsfile *fptr=NULL; /* File pointer used for accessing input and output
files*/
  gal_list_str_t *input, *tmp;
  size_t i, nkeys;
  gal_data_t *keysll=NULL;
  int status=0, updatechecksum=0, checksumexists=0;


  printf("Keys to Copy :\n");
  gal_list_str_print(p->keystocopy);
  nkeys=gal_list_str_number(p->keystocopy);

/* Parse  input file, read the keywords and put them in the output (keysll)
  list. */
  input=p->input;

  /* Open the input FITS file. */
  fptr=gal_fits_hdu_open(input->v, p->cp.hdu, READONLY);

  /* Allocate the array to keep the keys. */
  i=0;
  keysll=gal_data_array_calloc(nkeys);
  for(tmp=p->keystocopy; tmp!=NULL; tmp=tmp->next)
    {
      if(tmp->next) keysll[i].next=&keysll[i+1];
      keysll[i].name=tmp->v;
      ++i;
    }

  /* Read the keys.*/
  gal_fits_key_read_from_ptr(fptr, keysll,1,1);

  /* Close the input FITS file. */
  status=0;
  if(fits_close_file(fptr, &status))
    gal_fits_io_error(status, NULL);

    /* Open the output HDU. */
  fptr=gal_fits_hdu_open(p->cp.output, p->outhdu, READWRITE);

  /* See if a 'CHECKSUM' key exists in the HDU or not (to update in case we
     wrote anything). */
  checksumexists=gal_fits_key_exists_fptr(fptr, "CHECKSUM");

  /* Copy the requested headers into the output files header. */
  for(int i=0;i<nkeys;++i)
    {
      char inkey[80];
      char *keyname = keysll[i].name;

      if(fits_read_card(fptr,keyname, inkey, &status))
      gal_fits_io_error(status,NULL);

      if( fits_write_record(fptr, inkey, &status ) )
        gal_fits_io_error(status, NULL);
      else updatechecksum=1;

    }

  /* If a checksum existed, and we made changes in the file, we should
     update the checksum. */
  if(checksumexists && updatechecksum)
    if( fits_write_chksum(fptr, &status) )
      gal_fits_io_error(status, NULL);

  /* Close the output FITS file. */
  status=0;
  if(fits_close_file(fptr, &status))
    gal_fits_io_error(status, NULL);

  /* Clean Up */
  // gal_data_free(keysll[i].next);
}


== Build ==
1. I've built it on my local bootstraped repo as mentioned here
<https://www.gnu.org/savannah-checkouts/gnu/gnuastro/manual/html_node/Bootstrapping.html>.
2. also, I've tested it out on the examples given here
<https://www.gnu.org/software/gnuastro/manual/html_node/Setup-and-data-download.html>.

PS :- Sorry for such a long message. This is my first *proper* opensource
project. So I wanted to be as comprehensive as possible (^_^)/


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/task/?16073>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]