RMS/Formats/FFfile.py
def reconstructFrame(ff, frame_no, avepixel=False):
    """ Reconstruct just a given frame from an FF file.
    
    Arguments:
        ff: [ff bin struct] FF file loaded in the FF structure.
        frame_no: [int] Frame index, from 0 to 255 (inclusive).

    Keyword arguments:
        avepixel: [bool] If True, the average pixel image will be the background. False by default, which
            will use a black background.
    
    Return:
        frame: [ndarray] Reconstructed frame.
    """

    # Init the empty frame
    if avepixel:
        frame = np.copy(ff.avepixel)
    else:
        frame = np.zeros_like(ff.maxpixel)

    # Find where the max values occured for this frame
    indices = np.where(ff.maxframe == int(frame_no))
    frame[indices] = ff.maxpixel[indices]

    return frame
RMS/Formats/FFfile.py
def read(directory, filename, fmt=None, array=False, full_filename=False, verbose=True):
    """ Read FF file from the specified directory and choose the proper format for reading.
    
    Arguments:
        directory: [str] Path to directory containing file
        filename: [str] Name of FF file (either with FF and extension or without)

    Keyword arguments:
        fmt: [str] Format for reading the file. It should either be 'bin' or 'fits'. If it is not given,
            the format will be guessed.
        array: [ndarray] True in order to populate structure's array element (default is False)
        full_filename: [bool] True if full file name is given explicitly, a name which may differ from the
            usual FF*.fits format. False by default.
        verbose: [bool] Print error verbose. True by default.
    
    Return:
        [ff structure]

    """


    # If the reading format was not given, try to guess the proper format
    if fmt is None:

        # Try to guess the format from the file extension
        extens = os.path.splitext(filename)[1]
        if (extens.lower() == '.bin') or (extens.lower() == '.fits'):
            fmt = extens.replace('.', '')

        else:
            # If the extension is not given, try to load the file in one of the formats

            # Try reading the file as FITS
            try:
                ff = readFFfits(directory, filename, array=array)
                fmt = 'fits'

            except IOError:

                # Try reading the file as a .bin file
                try:
                    ff = readFFbin(directory, filename, array=array)
                    fmt = 'bin'

                except:
                    ff = None
                    fmt = None


    if fmt == 'bin':

        # Read the file as bin
        ff = readFFbin(directory, filename, array=array, full_filename=full_filename)


    elif fmt == 'fits':

        try:
            # Read the file as FITS
            ff = readFFfits(directory, filename, array=array, full_filename=full_filename)

        except IOError:
            if verbose:
                print('File {:s} is corrupted!'.format(filename))

            return None

        except TypeError:
            if verbose:
                print('File {:s} is corrupted!'.format(filename))
                
            return None

    else:
        ff = None


    return ff
RMS/Routines/Image.py
    USING_SCIPY_IMREAD = True
    USING_SCIPY_IMREAD = False
def loadRaw(img_path):
def loadImage(img_path, flatten=-1):
def saveImage(img_path, img, add_timestamp=False):
def binImage(img, bin_factor, method='avg'):
def thresholdImg(img, avepixel, stdpixel, k1, j1, ff=False, mask=None, mask_ave_bright=True):
def thresholdFF(ff, k1, j1, mask=None, mask_ave_bright=False):
def gammaCorrection(intensity, gamma, bp=0, wp=255):
def applyBrightnessAndContrast(img, brightness, contrast):
def adjustLevels(img_array, minv, gamma, maxv, nbits=None, scaleto8bits=False):
    def __init__(self, flat_img, dark=None):
    def applyDark(self, dark):
    def computeAverage(self):
    def fixValues(self):
    def binFlat(self, binning_factor, binning_method):
def loadFlat(dir_path, file_name, dtype=None, byteswap=False, dark=None):
def applyFlat(img, flat_struct):
def loadDark(dir_path, file_name, dtype=None, byteswap=False):
def applyDark(img, dark_img):
def deinterlaceOdd(img):
def deinterlaceEven(img):
def blendLighten(arr1, arr2):
def deinterlaceBlend(img):
def fillCircle(photom_mask, x_cent, y_cent, radius):
def thickLine(img_h, img_w, x_cent, y_cent, length, rotation, radius):
class FlatStruct(object):
RMS/Formats/FFfile.py
def getMiddleTimeFF(ff_name, fps, ret_milliseconds=True, ff_frames=256):
    """ Converts a CAMS format FF file name to datetime object of its recording time. 

    Arguments:
        ff_name: [str] name of the FF file
        fps: [float] Frames per second of the video compressed in the FF file.

    Keyword arguments:
        ret_milliseconds: [bool] If True, the last number returned will be in milliseconds. Otverwise, it will
            be in microseconds.
        ff_frames: [int] Number of frames that were compressed in the FF file.
        UT_corr: [float] UT correction (hours).
    
    Return:
        [tuple] (year, month, day, hour, minute, second, microsecond/millisecond)

    """

    # Extract date and time of the FF file from its name
    dt_obj = filenameToDatetime(ff_name)

    # Time in seconds from the middle of the FF file
    middle_diff = datetime.timedelta(seconds=ff_frames/2.0/fps)

    # Add the difference in time
    dt_obj = dt_obj + middle_diff

    # Unpack datetime to individual values
    year, month, day, hour, minute, second, microsecond = (dt_obj.year, dt_obj.month, dt_obj.day, dt_obj.hour, 
        dt_obj.minute, dt_obj.second, dt_obj.microsecond)

    if ret_milliseconds:
        return (year, month, day, hour, minute, second, microsecond/1000)
    else:
        return (year, month, day, hour, minute, second, microsecond)
RMS/Formats/Vid.py
def readFrame(st, fid, metadata_only=False):
    """ Read in the information from the next frame, save them to the given structure and return the image 
        data.

    Arguments:
        st: [Vid structure]
        fid: [file handle] File handle to the vid file. Make sure it was open in the 'rb' mode.

    Keyword arguments:
        metadata_only: [bool] Only read the metadata, but not the whole frame. False by default
    """

    # Get the current position in the file
    file_pos = fid.tell()

    # Check if the end of file (EOF) is reached
    if not fid.read(1):
        return None

    fid.seek(file_pos)


    #### Read the header ###
    ##########################################################################################################

    st.magic = int(np.fromfile(fid, dtype=np.uint32, count=1))

    # Size of one frame in bytes
    st.seqlen = int(np.fromfile(fid, dtype=np.uint32, count=1))

    # Header length in bytes
    st.headlen = int(np.fromfile(fid, dtype=np.uint32, count=1))

    st.flags = int(np.fromfile(fid, dtype=np.uint32, count=1))
    st.seq = int(np.fromfile(fid, dtype=np.uint32, count=1))

    # Beginning UNIX time
    st.ts = int(np.fromfile(fid, dtype=np.int32, count=1))
    st.tu = int(np.fromfile(fid, dtype=np.int32, count=1))

    # Station number
    st.station_id = int(np.fromfile(fid, dtype=np.int16, count=1))

    # Image dimensions
    st.wid = int(np.fromfile(fid, dtype=np.int16, count=1))
    st.ht = int(np.fromfile(fid, dtype=np.int16, count=1))

    # Image depth
    st.depth = int(np.fromfile(fid, dtype=np.int16, count=1))

    st.hx = int(np.fromfile(fid, dtype=np.uint16, count=1))
    st.hy = int(np.fromfile(fid, dtype=np.uint16, count=1))

    # Camera stream identifier, where 0 = 'A', 1 = 'B', etc
    st.str_num = int(np.fromfile(fid, dtype=np.uint16, count=1))

    st.reserved0 = int(np.fromfile(fid, dtype=np.uint16, count=1))
    st.exposure = int(np.fromfile(fid, dtype=np.uint32, count=1))
    st.reserved2 = int(np.fromfile(fid, dtype=np.uint32, count=1))
    
    st.text = np.fromfile(fid, dtype=np.uint8, count=64).tostring().decode("ascii").replace('\0', '')

    ##########################################################################################################

    if not metadata_only:

        # Rewind the file to the beginning of the frame
        fid.seek(file_pos)

        # Read one whole frame
        fr = np.fromfile(fid, dtype=np.uint16, count=st.seqlen//2)

        # Set the values of the first row to 0
        fr[:st.ht] = 0

        # Reshape the frame to the proper image size
        img = fr.reshape(st.ht, st.wid)

    else:

        # If only the metadata was read, set the image to None
        img = None


    return img
RMS/Formats/FRbin.py
def read(dir_path, filename):
    """ Read an FR*.bin file.
    
    Arguments:
        dir_path: [str] Path to directory containing file.
        filename: [str] Name of FR*.bin file (either with the FR prefix and the .bin suffix, or without).
    
    Return:
        fr: [fr_struct instance] 

    """
    if filename[:2] == "FR":
        fid = open(os.path.join(dir_path, filename), "rb")
    else:
        fid = open(os.path.join(dir_path, "FR_" + filename + ".bin"), "rb")

    fr = fr_struct()

    fr.lines = np.fromfile(fid, dtype=np.uint32, count=1)[0]

    for i in range(fr.lines):
        frameNum = np.fromfile(fid, dtype=np.uint32, count=1)[0]
        yc = []
        xc = []
        t = []
        size = []
        frames = []

        for z in range(frameNum):
            yc.append(int(np.fromfile(fid, dtype=np.uint32, count=1)))
            xc.append(int(np.fromfile(fid, dtype=np.uint32, count=1)))
            t.append(int(np.fromfile(fid, dtype=np.uint32, count=1)))
            size.append(int(np.fromfile(fid, dtype=np.uint32, count=1)))
            frames.append(np.reshape(np.fromfile(fid, dtype=np.uint8, count=size[-1]**2), (size[-1], size[-1])))

        fr.frameNum.append(frameNum)
        fr.yc.append(yc)
        fr.xc.append(xc)
        fr.t.append(t)
        fr.size.append(size)
        fr.frames.append(frames)

    return fr
RMS/Formats/FFfile.py
def filenameToDatetime(file_name):
    """ Converts FF bin file name to a datetime object.

    Arguments:
        file_name: [str] Name of a FF file.

    Return:
        [datetime object] Date and time of the first frame in the FF file.

    """

    # e.g.  FF499_20170626_020520_353_0005120.bin
    # or FF_CA0001_20170626_020520_353_0005120.fits

    file_name = file_name.split('_')

    # Check the number of list elements, and the new fits format has one more underscore
    i = 0
    if len(file_name[0]) == 2:
        i = 1

    date = file_name[i + 1]
    year = int(date[:4])
    month = int(date[4:6])
    day = int(date[6:8])

    time = file_name[i + 2]
    hour = int(time[:2])
    minute = int(time[2:4])
    seconds = int(time[4:6])

    ms = int(file_name[i + 3])


    return datetime.datetime(year, month, day, hour, minute, seconds, ms*1000)
RMS/Astrometry/Conversions.py
def unixTime2Date(ts, tu, dt_obj=False):
    """ Convert UNIX time given in ts and tu to date and time.

    Arguments:
        ts: [int] UNIX time, seconds part
        tu: [int] UNIX time, microsecond part
    Kwargs:
        dt_obj: [bool] default False, function returns a datetime object if True
    Return:
        if dt_obj == False (default): [tuple] (year, month, day, hours, minutes, seconds, milliseconds)
        else: [datetime object]
    """

    # Convert the UNIX timestamp to datetime object
    dt = datetime.utcfromtimestamp(float(ts) + float(tu)/1000000)

    if dt_obj:
        return dt

    else:
        return dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, float(tu)/1000
RMS/Formats/FFfile.py
def selectFFFrames(img_input, ff, frame_min, frame_max):
    """ Select only pixels in a given frame range. 
    
    Arguments:
        img_input: [2D ndarray] Input image.
        ff: [FF object] FF image object
        frame_min: [int] first frame in a range to take
        frame_max: [int] last frame in a range to take
    
    Return:
        [ndarray] image with pixels only from the given frame range
    """

    # Get the indices of image positions with times correspondng to the subdivision
    indices = np.where((ff.maxframe >= frame_min) & (ff.maxframe <= frame_max))

    # Reconstruct the image with given indices
    img = np.zeros_like(img_input)
    img[indices] = img_input[indices]

    return img
RMS/Formats/Vid.py
class VidStruct(object):
    """ Structure for storing vid file info. """

    def __init__(self):

        # List of video frames - this is used only in the parent Vid structure, while the child structures
        # have this empty, but they contain image data in the img_data variable
        self.frames = None

        self.magic = 0

        # Bytes for a single image
        self.seqlen = 0

        # Header length in bytes
        self.headlen = 0

        self.flags = 0
        self.seq = 0

        # UNIX time
        self.ts = 0
        self.tu = 0

        # Station number
        self.station_id = 0

        # Image dimensions in pixels
        self.wid = 0
        self.ht = 0

        # Image depth in bits
        self.depth = 0

        # Mirror pointing for centre of frame
        self.hx = 0
        self.hy = 0

        # Stream number
        self.str_num = 0
        self.reserved0 = 0

        # Exposure time in milliseconds
        self.exposure = 0

        self.reserved2 = 0

        self.text = 0

        # Image data
        self.img_data = None
RMS/Formats/FRbin.py
def validFRName(fr_name):
    """ Checks if the given file is an FR file. 
    
    Arguments:
        fr_name: [str] Name of the FR file
    """

    if fr_name.startswith('FR') and fr_name.endswith('.bin'):
        return True

    else:
        return False
RMS/Astrometry/Conversions.py
def datetime2UnixTime(dt):
    """ Convert the given datetime to UNIX time.

    Arguments:
        dt: [datetime]
    Return:
        [float] Unix time.
    """

    # UTC unix timestamp
    unix_timestamp = (dt - datetime(1970, 1, 1)).total_seconds()

    return unix_timestamp
RMS/Formats/FFfile.py
def validFFName(ff_file, fmt=None):
    """ Checks if the given file is an FF file. 
    
    Arguments:
        ff_file: [str] Name of the FF file

    Keyword arguments:
        fmt: [str] Format of the FF file. If not given, it will tried to be determined from the file name.
    """

    if fmt is None:
        if ff_file.endswith('.bin'):
            fmt = 'bin'

        else:
            fmt = 'fits'

    # Make sure the file starts with FF
    if ff_file.startswith('FF'):

        # Check that the format corresponds to the given file
        if (fmt == 'bin') and (ff_file.endswith('.bin')):
            return True

        elif (fmt == 'fits') and (ff_file.endswith('.fits')):
            return True
            
        else:
            return False

        
    return False


Question: import os
import sys
import copy
import datetime
    import rawpy
import cv2
import numpy as np
        import tkMessageBox as messagebox
import pyximport
    import argparse
    import matplotlib.pyplot as plt
    import RMS.ConfigReader as cr
from astropy.io import fits
from RMS.Astrometry.Conversions import unixTime2Date, datetime2UnixTime
from RMS.Formats.FFfile import read as readFF
from RMS.Formats.FFfile import reconstructFrame as reconstructFrameFF
from RMS.Formats.FFfile import validFFName, filenameToDatetime
from RMS.Formats.FFfile import getMiddleTimeFF, selectFFFrames
from RMS.Formats.FRbin import read as readFR, validFRName
from RMS.Formats.Vid import readFrame as readVidFrame
from RMS.Formats.Vid import VidStruct
from RMS.GeoidHeightEGM96 import wgs84toMSLHeight
from RMS.Routines import Image
    from RMS.Routines.CustomPyqtgraphClasses import qmessagebox as messagebox
        from tkinter import messagebox
from RMS.Routines.DynamicFTPCompressionCy import FFMimickInterface
        ff_struct_fake.finish()

        # Store the FF struct to cache to avoid recomputing
        self.cache = {}

        self.cache[cache_id] = [ff_struct_fake, self.current_fr_chunk_size]

        # Set the computed chunk as the current FF
        self.ff = ff_struct_fake

        return ff_struct_fake

    def name(self, beginning=False):
        """ Return the name of the chunk, which is just the time of the middle of the current frame chunk. 
            Alternatively, the beginning of the whole file can be returned.

        Keyword arguments:
            beginning: [bool] If True, the beginning time of the file will be retunred instead of the middle
                time of the chunk.
        """

        if beginning:
            return str(self.beginning_datetime)
        else:
            return str(self.currentTime(dt_obj=True))

    def currentTime(self, dt_obj=False):
        """ Return the mean time of the current image. """

        # Compute number of seconds since the beginning of the video file to the mean time of the frame chunk
        seconds_since_beginning = (self.current_frame_chunk*self.fr_chunk_no
                                   + self.current_fr_chunk_size/2)/self.fps

        # Compute the absolute time
        dt = self.beginning_datetime + datetime.timedelta(seconds=seconds_since_beginning)

        if dt_obj:
            return dt

        else:
            return dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond/1000

    def loadFrame(self, avepixel=False):
        """ Load the current frame. """

        # Set the frame location
        self.cap.set(1, self.current_frame)

        # Read the frame
        ret, frame = self.cap.read()

        # Convert frame to grayscale
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # Bin the frame
        if self.detection and (self.config.detection_binning_factor > 1):
            frame = Image.binImage(frame, self.config.detection_binning_factor,
                                   self.config.detection_binning_method)

        return frame

    def currentFrameTime(self, frame_no=None, dt_obj=False):
        """ Return the time of the frame. """

        if frame_no is None:
            frame_no = self.current_frame

        # Compute the datetime of the current frame
        dt = self.beginning_datetime + datetime.timedelta(seconds=frame_no/self.fps)

        if dt_obj:
            return dt

        else:
            return dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond/1000


class InputTypeUWOVid(InputType):
    def __init__(self, file_path, config, detection=False):
        """ Input file type handle for UWO .vid files.
        
        Arguments:
            file_path: [str] Path to the vid file.
            config: [ConfigStruct object]

        Keyword arguments:
            detection: [bool] Indicates that the input is used for detection. False by default. This will
                control whether the binning is applied or not.

        """
        self.input_type = 'vid'

        # Separate directory path and file name
        self.vid_path = file_path
        self.dir_path, vid_file = os.path.split(file_path)

        self.config = config

        self.detection = detection

        self.ff = None

        # This type of input probably won't have any calstars files
        self.require_calstars = False

        # Byteswap the images
        self.byteswap = True

        print('Using vid file:', self.vid_path)

        # Open the vid file
        self.vid = VidStruct()
        self.vid_file = open(self.vid_path, 'rb', buffering=65536)

        # Read one video frame and rewind to beginning
        readVidFrame(self.vid, self.vid_file)
        self.vidinfo = copy.deepcopy(self.vid)
        self.vid_file.seek(0)

        # Try reading the beginning time of the video from the name

Answer:         self.beginning_datetime = unixTime2Date(self.vidinfo.ts, self.vidinfo.tu, dt_obj=True)