pythonfitstabulate

How can I make a table using lists as columns?


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)

Solution

  • 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)