[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/