Changeset 17978


Ignore:
Timestamp:
10/02/14 17:16:43 (10 years ago)
Author:
dneise
Message:
more convenient way of opening Fits files and better __str__ and __repr__ functions
File:
1 edited

Legend:

Unmodified
Added
Removed
  • fact/tools/pyscripts/new_pyfact/pyfact.py

    r17975 r17978  
    88import numpy as np
    99import ROOT
     10ROOT.gROOT.SetBatch(True)
    1011
    1112########## BUILDING OF THE SHARED OBJECT FILES ###############################
     
    6566del path
    6667
     68raw_base = '/fact/raw'
     69aux_base = '/fact/aux'
     70
     71
     72def stub_to_auxfile(s, s2=None, basep=aux_base, basen="*"):
     73    """ FIXME :-)
     74        It's not yet clear how to generate aux file names from stubs, or iterables
     75    """
     76    if s2 is not None:
     77        s = "{0}_{1:03d}".format(s,s2)
     78    y = s[0:4]
     79    m = s[4:6]
     80    d = s[6:8]
     81    date = s[0:8]
     82    r = s[9:12]
     83    return os.path.join(basep,y,m,d,date+'.'+basen+'.fits')
     84
     85
     86def make_path(s):
     87    """ make path to fits file
     88       
     89        s : string or iterable
     90       
     91        Fits files in pyfact do not need to be specified by full paths
     92        A so called stub path is sufficient. A valid stub path looks like:
     93        yyyymmdd_rrr
     94        or in case of a drs calibration file like
     95        yyyymmdd_rrr.drs
     96
     97        In addition a file can be specified by a 2-element integer iterable,
     98        e.g. a list or a tuple, whose first element is the integer denoting the
     99        'night' : yyyymmdd
     100        the 2nd integer is the 'run' : rrr
     101        so valid specifiers are also:
     102        (yyyymmdd, rrr) or [yyyymmdd, rrr]
     103
     104        the pyfact.Fits class can handle .fits, .fits.gz, and .fits.fz files.
     105        stubs dont's specify which one should be used, so we need to check
     106        which one exists, if more than one file exists fitting to the stub,
     107        the order of precendence is:
     108            * .fits    -- since access should be pretty fast
     109            * .fits.fz -- newer format should be mostly the case
     110            * .fits.gz -- still possible
     111    """
     112    import re
     113    import os
     114    if not isinstance(s, (str, unicode)):
     115        # s is (hopefully) some kind of iterable, so we read out two integers
     116        night = int(s[0])
     117        run = int(s[1])
     118        _s = "{0:08d}_{1:03d}".format(night,run)
     119    else:
     120        _s = s
     121
     122    # so now s is some kind of string
     123    # maybe it is already a path:
     124    if os.path.isabs( _s ):
     125        # s is already an absolute path.
     126        # maybe the file is not there, but we don't care about that
     127        return _s
     128
     129    # it was not an absolute path, maybe it's a relative path, let's check if
     130    # it points to a file.
     131    elif os.path.exists( _s ):
     132        # s is certainly a path, it even points to a file :-)
     133        return os.path.abspath(_s)
     134
     135    # okay ... s was not a path, so let's generate a nice absolute path
     136    # from the stub, in case it is a stub ..
     137    elif re.match('\d{8}_\d{3}', _s):
     138        # s is a stub, so we can make a full path from it
     139        y = _s[0:4]
     140        m = _s[4:6]
     141        d = _s[6:8]
     142        r = _s[9:12]
     143        start = os.path.join(raw_base,y,m,d,_s[:12]+'.fits')
     144        candidates = [start, start+'.fz', start+'.gz']
     145        for c in candidates:
     146            if os.path.exists(c):
     147                return c
     148        # if we reached this point, s was a stub, but we were not
     149        # able to find a file on the file system...
     150        # let's return our best guess, the '.fz' file path
     151        # the Fits.__init__() will complain, if it can't find the file.
     152        return candidates[1]
     153    else:
     154        raise IOError("{0} can't be used for path generation".format(s))
     155
    67156class Fits( object ):
    68157    """ General FITS file access
     
    74163    __module__ = 'pyfact'
    75164    def __init__(self, path):
    76         """
    77         """
     165        """ Open fits file, parse header and setup table colums
     166
     167        path : string : path to the fits file (.fits, .fits.gz, .zfits)
     168        """
     169        path = make_path(path)
     170        self._path = path
     171        self._current_row = None
    78172        if not os.path.exists(path):
    79173            raise IOError(path+' was not found')
     
    81175        self._make_header()
    82176        self._setup_columns()
     177
     178    def __repr__(self):
     179        return '{s.__class__.__name__}(path="{s._path}")'.format(s=self)
     180   
     181    def __str__(self):
     182        s = """Fits object:
     183        path = {s._path}
     184        row = {s._current_row}
     185        self.cols.keys = {col_names}
     186        """.format(s=self, col_names=self.cols.keys())
     187        return s
     188
    83189
    84190    def __len__(self):
     
    121227        """
    122228        if row is None:
     229            if self._current_row is None:
     230                self._current_row = 0
     231            else:
     232                self._current_row += 1
    123233            if self.f.GetNextRow() == False:
     234                self._current_row = None
    124235                raise StopIteration
    125236        else:
    126237            row = int(row)
     238            self._current_row = row
    127239            if self.f.GetRow(row) == False:
     240                self._current_row = None
    128241                raise StopIteration
    129242        return self
     
    162275            for key in self._cols:
    163276                self.cols[key][i,:] = self._cols[key]
    164 
    165 
    166277
    167278
Note: See TracChangeset for help on using the changeset viewer.