1

I am using Python 3.8.10 in IDLE on Ubuntu 20.10.
In a few words, I have several .fits files from which I have to read some parameters. I already have my readfits function for this: it opens the file and adds the values that I need to a list. Now I need to make a function that applies readfits to some files in the current directory (not a problem) and then prints them in a table. The problem is that each of the lists that I have would be one of the columns of the table, so I do not know how to do that. I want to make it recursively, because there are actually 104 .fits file so it's quite a long thing to do manually.
Here's the code for now:

#import needed packages
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
import os
from tabulate import tabulate

#make empty lists where rquantities will be added
rv = []
date = []
rv_errors = []
airmass = []
BIS = []
normal_dates = []
names = []
instrument = []


#create function which reads .fits files and adds values to global lists
def readfits(filename):

    #open files and give names to data and header
    with fits.open(filename) as hdu:
        data = hdu[0].data
        head = hdu[0].header

    #Useful quantities
    
    #Contrast of CCF in %
    contrast = head['HIERARCH TNG DRS CCF CONTRAST']

    #FWHM of CCF in km/s
    fwhm_ccf = head['HIERARCH TNG DRS CCF FWHM']

    #Number of lines used
    nr_lines = head['HIERARCH TNG DRS CCF LINES']

    #Mask type
    mask = head['HIERARCH TNG DRS CCF MASK']

    #Right ascension and declination in radians
    ra = head['RA']
    dec = head['DEC']

    #Air mass
    air_mass = head['AIRMASS']

    #Mean Julian Date of observation
    jd = head['MJD-OBS']

    #Mean BJD subtracted for plotting reasons
    bjd = head['HIERARCH TNG DRS BJD'] - 2450000

    #Exposure time in s
    exp_time = head['EXPTIME']

    #Estimated RV uncertainty in m/s
    err_rv = head['HIERARCH TNG DRS DVRMS']

    #Noise at order 46 where the stellar peak is
    #sn46 = head['HIERARCH TNG DRS SPE EXT SN46']

    #Half-window of the CCF
    half_wind = head['HIERARCH IA2 YABI WIDTHCCF']

    #Step of the CCF
    ccf_step = head['HIERARCH IA2 YABI STEPCCF']

    #Apparent magnitude
    mag = head['HIERARCH TNG TEL TARG MAG']

    #Th-lamp drift
    th_drift = head['HIERARCH TNG DRS DRIFT SPE RV']

    #RV of the system (YABI input)
    #rv_sys = head['HIERARCH TNG TEL TARG RADVEL']

    #BIS
    bis = head['HIERARCH TNG DRS BIS SPAN']

    #CCF noise from km/s to m/s
    ccf_noise = head['HIERARCH TNG DRS CCF NOISE']*1000

    #Measured RV for this target in this night in km/s
    rv_mis = head['HIERARCH TNG DRS CCF RVC']

    #RV in m/s
    rv_true = rv_mis*1000

    #readable date
    dates = head['DATE-OBS']

    #instrument used
    strum = head['INSTRUME']

    #name of target
    name = head['HIERARCH TNG OBS TARG NAME']

    #add quantities to the initial lists
    global rv
    rv.append(rv_true)
    global date
    date.append(bjd)
    global rv_errors
    rv_errors.append(ccf_noise)
    global airmass
    airmass.append(air_mass)
    global BIS
    BIS.append(bis)
    global normal_dates
    normal_dates.append(dates)
    global instrument
    instrument.append(strum)
    global names
    names.append(name)


#writes values from fits files to txt table
def writetable():

    #list with all files in directory
    list_all = os.listdir()
    list_data = []

    #take only files with 'bis' in the name
    for i in range(0, len(list_all)):
        if 'bis' in list_all[i]:
            list_data.append(list_all[i])

    #sort elements in alphabetical order
    list_data.sort()

    #apply readfits to all 'bis' files
    n = len(list_data)
    for i in range(0,n):
        readfits(list_data[i])
    
    global names
    global normal_dates
    global instrument
    global rv
    global rv_errors
    global date
    global BIS
    global airmass
    
    #headers for table
    headers = ['Target', 'Date of observation', 'Instrument', 'RV',
               'RV error', 'BJD', 'BIS', 'Air mass']

    
    param_table = tabulate([], headers = headers)
    
    print(param_table)
Shunya
  • 2,344
  • 4
  • 16
  • 28

1 Answers1

0

Since I figured it out by myself, I'll leave the answer here in case someone else needs it. It was way easier than I thought. Basically I made a matrix as a list of list, then I transposed it. In this way, I have rows and columns as I wanted them. Then you simply give it to tabulate with the right headers and that's it. Here's the code:

    #make matrix as list of lists and transpose it
    A = np.array([names, normal_dates, instrument, rv, rv_errors,
                       date, BIS, airmass])
    B = np.transpose(A)
    
    #headers for table
    headers = ['Target', 'Date of observation', 'Instrument', 'RV',
               'RV error', 'BJD', 'BIS', 'Air mass']

    
    param_table = tabulate(B, headers = headers)
    
    print(param_table)

  • What is `tabulate()`?? I don't think that's a built-in function in Astropy. – Iguananaut Oct 19 '21 at 13:20
  • No, it's another module. You need to install it (pip install tabulate on Ubuntu) and then "from tabulate import tabulate" (see the beginning of my code). Shortly, it makes you print nice tables quick. Here's the info: https://pypi.org/project/tabulate/ – Alessandro Ruggieri Oct 19 '21 at 13:28
  • I see, thank you for clarifying. When you wrote of "making a table" I thought you meant `astropy.table.Table`, so the question is confusing. By the way, unrelated, but you don't need to explicitly declare `global` on all those global variables. This is only necessary if you intend to assign to a global variable from within a function (setting aside whether global variables should be used at all, though for small research scripts I think it's fine). – Iguananaut Oct 19 '21 at 13:57
  • Allright, thanks for the suggestion! – Alessandro Ruggieri Oct 19 '21 at 14:28