gofio2ascii.py 6.31 KB
Newer Older
Monica Rainer's avatar
Monica Rainer committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
"""
Written by Monica Rainer
2019-05-22

gofio2ascii.py converts the GOFIO ms1d/s1d outputs in ASCII files with or without header
The ms1d file have and 4 column: wavelength (nm), flux, S/N, and number of the echelle order
It is written in python2, but if needed it may be run with python3 by
commenting and un-commenting the appropriate rows:
  "lista = raw_input/input ..."
  "for o in xrange/range(50):"

The header options are:
 - none: no header is written
 - simple (default): only two rows with the name of the FITS files and the columns definition
 - red: reduced header, with the keywords defined in the "keywords" list
        If the user wants different keywords to be saved in the header,
        the keywords list may be changed accordingly.
 - full: the whole header is written in the ASCII files


Usage:
    spa_gofio2ascii.py -h
    spa_gofio2ascii.py
    spa_gofio2ascii.py [--hea=<value> --split]
    spa_gofio2ascii.py <list> 
    spa_gofio2ascii.py <list> [--hea=<value> --split]

Options:
    -h,--help           : show this screen
    list                : list of ms1d FITS data files [Default: fits.lis]
    --hea=<value>       : write header, options: none/simple/red/full [Default: simple] (defined by the "keywords" list)
    --split             : split the orders of the ms1d files in different ASCII outputs
"""

from __future__ import (absolute_import, division, print_function, unicode_literals)
Monica Rainer's avatar
Monica Rainer committed
36
37
from astropy.io import fits,ascii
import numpy as np
Monica Rainer's avatar
Monica Rainer committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
from docopt import docopt
import os

docopt_args = docopt(__doc__)

keywords = ['HIERARCH TNG OBS PROG ID' , 'OBJECT' , 'HIERARCH TNG TEL TARG ALPHA' , \
   'HIERARCH TNG TEL TARG DELTA' , 'HIERARCH TNG TEL TARG EQUINOX' , 'EXPSTART' , 'MJD-OBS' , \
   'AIRMASS' , 'HIERARCH TNG DRS AIRMASS' , 'DIT' , 'HIERARCH TNG TPL NPAIRS' , \
   'HIERARCH TNG EXP NGROUPS' , 'NCOMBINE' , 'HIERARCH TNG DRS GAIN' , 'HIERARCH TNG DRS RON' , \
   'HIERARCH TNG INS GRAY FILTER' , 'HIERARCH TNG INS DEWAR TEMPDET' , 'HIERARCH TNG METEO HUMIDITY' , \
   'HIERARCH TNG DRS EXPTIME' , 'HIERARCH TNG DRS BJD' , 'HIERARCH TNG DRS BERV']

wave_fmt = '%10.3f'
flux_fmt = '%15.8f'
snr_fmt = '%10.3f'
order_fmt = '%i'

if not docopt_args['<list>']:
    lista = 'fits.lis'
    if not os.path.isfile(lista):
        lista = raw_input('List of ms1d/s1d FITS files to convert in ASCII (default = fits.lis):\n') #python2
        #lista = input('List of ms1d FITS files to convert in ASCII (default = fits.lis):\n') #python3
else:
    lista = docopt_args['<list>']

#print(docopt_args['--hea'])
Monica Rainer's avatar
Monica Rainer committed
64
65
66
with open(lista) as framelist:
    for frame in framelist:
        frame = frame.strip()
Monica Rainer's avatar
Monica Rainer committed
67
        calib_ascii = frame.replace('.fits','.txt')
Monica Rainer's avatar
Monica Rainer committed
68
69
70
71
72
73
74
        spettro = fits.open(frame)

        try:
            sdata = spettro[1].data
            wcalib = sdata.field(1)
            spec = sdata.field(2)
            snr = sdata.field(3)
Monica Rainer's avatar
Monica Rainer committed
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
            order = np.zeros(wcalib.shape)
            hea1 = '\n'.join(( os.path.basename(frame) ,'1. wavelength (nm) - 2. flux - 3. S/N - 4. echelle order\n'))
            hea2 = spettro[0].header.tostring(sep='\n')
            if docopt_args['--hea'] == 'full':
                hea = ''.join((hea1,hea2))
            elif docopt_args['--hea'] == 'red':
                heasel = []
                hea3 = hea2.split('\n')
                for row in hea3:
                    for key in keywords:
                        if key in row:
                            heasel.append(row)
                            break
                heasel = '\n'.join(heasel)
                hea = ''.join((hea1,heasel))
            else:
                hea = hea1
            for o in xrange(50): #python2
            #for o in range(50): #python3
Monica Rainer's avatar
Monica Rainer committed
94
95
96
97

                wcalib[o] = wcalib[o][::-1]
                spec[o] = spec[o][::-1]
                snr[o] = snr[o][::-1]
Monica Rainer's avatar
Monica Rainer committed
98
99
100
                order[o] = o+32

                if docopt_args['--split']:
Monica Rainer's avatar
Monica Rainer committed
101
102
                    txt = '_' + str(o+32) + '.txt'
                    order_ascii = frame.replace('.fits',txt)
Monica Rainer's avatar
Monica Rainer committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
                    order = np.vstack((wcalib[o],spec[o],snr[o],order[o]))
                    if docopt_args['--hea'] == 'none':
                        ascii.write(np.transpose(order),order_ascii, fmt=[wave_fmt, flux_fmt , snr_fmt , order_fmt])
                    else:
                        ascii.write(np.transpose(order),order_ascii, fmt=[wave_fmt, flux_fmt , snr_fmt , order_fmt], header=hea)
                    print('Saved %s' % (order_ascii))

            if not docopt_args['--split']:
                output = np.vstack( ( np.concatenate(np.flipud(wcalib)), np.concatenate(np.flipud(spec)), np.concatenate(np.flipud(snr)) , np.concatenate(np.flipud(order)) ) )
            #ascii.write(np.transpose(optCal),calib_ascii, format='no_header')
                if docopt_args['--hea'] == 'none':
                    np.savetxt(calib_ascii,np.transpose(output), fmt=[wave_fmt, flux_fmt , snr_fmt , order_fmt])
                else:
                    np.savetxt(calib_ascii,np.transpose(output), fmt=[wave_fmt, flux_fmt , snr_fmt , order_fmt], header=hea)

                print('Saved %s' % (calib_ascii))
Monica Rainer's avatar
Monica Rainer committed
119
120

        except:
Monica Rainer's avatar
Monica Rainer committed
121
            head = spettro[0].header
Monica Rainer's avatar
Monica Rainer committed
122
123
124
            data = spettro[0].data


Monica Rainer's avatar
Monica Rainer committed
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
            hea1 = '\n'.join(( os.path.basename(frame) ,'1. wavelength (nm) - 2. flux\n'))
            hea2 = spettro[0].header.tostring(sep='\n')
            if docopt_args['--hea'] == 'full':
                hea = ''.join((hea1,hea2))
            elif docopt_args['--hea'] == 'red':
                heasel = []
                hea3 = hea2.split('\n')
                for row in hea3:
                    for key in keywords:
                        if key in row:
                            heasel.append(row)
                            break
                heasel = '\n'.join(heasel)
                hea = ''.join((hea1,heasel))
            else:
                hea = hea1

            start = head['CRVAL1']
            step = head['CDELT1']
            length = head['NAXIS1']
            end = start + (step*length) - step

            waves = np.linspace(start, end, length)
            output = np.vstack( (waves, data ) )
            if docopt_args['--hea'] == 'none':
                np.savetxt(calib_ascii,np.transpose(output), fmt=[wave_fmt, flux_fmt ])
            else:
                np.savetxt(calib_ascii,np.transpose(output), fmt=[wave_fmt, flux_fmt ], header=hea)

            print('Saved %s' % (calib_ascii))
Monica Rainer's avatar
Monica Rainer committed
155
156