"""
Manipulating the ULT fridge Kelvinox logs.
IMPORTANT: Logs prior to Run 20 are not supported - information on daylight saving shifts
needs to be programmed in to add support.
"""

import os
import os.path
import time
import datetime
import numpy
import matplotlib.dates
import flib
import timelog
import ascii2numpy

class KelvinoxLog(timelog.TimeLog):
    """
    Represents a ULT Kelvinox log over a certain time.
    Two logs can be concatenated with a '&' sign

    log format:
    1  [:,0]  Time (sec, since 00:00 1 January 1970 GMT)
    2  [:,1]  G1 [mbar]
    3  [:,2]  G2 [mbar]
    4  [:,3]  T_MixCh [mK]
    5  [:,4]  R_s [Ohm]
    6  [:,5]  R_cp [Ohm]
    7  [:,6]  R_mc [Ohm]
    8  [:,7]  T_s [K]
    9  [:,8]  T_cp [K]
    10 [:,9]  T_mc [K]
    """

    @staticmethod
    def fieldcount(): "return number of columns in the self.data"; return 10
    
    def G1(self): "G1 [mbar]"; return self.data[:,1]
    def G2(self): "G2 [mbar]"; return self.data[:,2]
    def T_MixCh(self): "MixCh temperature [K]"; return self.data[:,3]
    def T_s(self): "Still temperature [K]"; return self.data[:,7]
    def T_cp(self): "Cold Plate temperature [K]"; return self.data[:,8]
    def T_mc(self): "Mixing Chamber temperature [K]"; return self.data[:,9]

    def __repr__(self): return "KelvinoxLog %s" % (self.datespan())

    @staticmethod
    def load(filename):
        """
        Load Kelvinox log from a given file
        The function determines file format from the date:
            1: modern format, since 21 December 2008
            2: old format, does not contain absolute time. winter/summer time changes are not handled correctly.
        """
        basename = os.path.basename(filename)
        
        if basename > '20081221' and basename.lower() != '20081221_kelvinoxmonitor-beforechange.dat':
            # Loads a new (Run 20+, since 21 December 2008) format log file
            #
            # 1  [:,0]  Time (sec, since midnight GMT)
            # 2  [:,1]  G1 [mbar]
            # 3  [:,2]  G2 [mbar]
            # 4  [:,3]  T_MixCh [mK]
            # 5  [:,4]  R_s [Ohm]
            # 6  [:,5]  R_cp [Ohm]
            # 7  [:,6]  R_mc [Ohm]
            # 8  [:,7]  T_s [K]
            # 9  [:,8]  T_cp [K]
            # 10 [:,9]  T_mc [K]
            # 11 [:,10] flow, always zero
            # 12  [:,11]  Time (sec, since 00:00 1 January 1904 GMT)
            
            data = ascii2numpy.loadascii(filename, cols=12)
            
            # timestamps in col 12 are stored as seconds since 00:00 1 Jan 1904.
            # Convert to seconds since 00:00 1 Jan 1970, C and UNIX time format.
            data[:,0] = flib.labview2tm(data[:,11])
            
            # convert T_MixCh into Kelvins
            data[:,3] /= 1e3
            data[:,7:9][data[:,7:9] <= 0] = numpy.NaN
            
            
            return KelvinoxLog(data[:,0:10])
        elif basename > '20080206':
            # Loads the old format (Run 20, before 21 December 2008) format log file
            # some ambiguity on the days when the daylight saving is changed
            #
            # in year 2008 the time was shifted on Sundays of 30 March and 26 October
            # NOTE: earlier years are not supported (you can do it by hand if you like)
            #
            # 1  [:,0]  Time (sec, since midnight GMT)
            # 2  [:,1]  G1 [mbar]
            # 3  [:,2]  G2 [mbar]
            # 4  [:,3]  T_MixCh [mK]
            # 5  [:,4]  R_s [Ohm]
            # 6  [:,5]  R_cp [Ohm]
            # 7  [:,6]  R_mc [Ohm]
            # 8  [:,7]  T_s [K]
            # 9  [:,8]  T_cp [K]
            # 10 [:,9]  T_mc [K]
            # 11 [:,10] flow, always zero
            
            data = ascii2numpy.loadascii(filename, cols=10)
            
            # date is encoded in the filename
            year = int(basename[0:4])
            month = int(basename[4:6])
            day = int(basename[6:8])
            
            if basename[:8] == '20080330':
                # Sunday 30 March 2008 01:00 summer time starts
                t = data[:,0]
                t[t > 60*60] -= 60*60
                data[:,0] = t
            elif (basename[:8] > '20080330') & (basename[:8] < '20081026'):
                # summer time 
                data[:,0] -= 60*60
            elif basename[:8] == '20081026':
                # Sunday 26 October 2008 01:00 summer time ends
                t = data[:,0]
                if len(t) > 0:
                    i = numpy.argwhere(numpy.diff(t) < 0)[0]
                    t[:i] -= 60*60
                    data[:,0] = t
                
            data[:,0] += flib.tm('%02d/%02d/%04d 00:00:00 UTC' % (day, month, year))
            
            # convert T_MixCh into Kelvins
            data[:,3] /= 1e3
            data[:,7:9][data[:,7:9] <= 0] = numpy.NaN
            
            return KelvinoxLog(data)
        else:
            return None
    
    @staticmethod
    def loadrun(run, start = None, end = None):
        """
        Return plm log for a given run, withing [start, end] period if boundaries are specified.
        """
        logdir = flib.smbpath('/data/archive/pc144/shared_data/KelvinoxMonitor/Run%d' % run)
        return KelvinoxLog.loaddir(logdir, start=start, end=end).period(start, end)
