Classes

SAS is a pure python package containing specialized data containers as well as grahical tools to ease the visualization of Sams data.

SamsLog

from sas import samslog

The SamsLog() class provides a data container capable of consolidating a number of logs file of the same type into one structure.

class samslog.SamsLog(filenames, suffix=None, verbose=False)

The input variable filenames must be a list of valid log file names and/or a list of valid day names. If the names are not appended with a suffix, then the suffix parameter will be used. If the first filename has a suffix and no suffix parameter is given, then the first suffix will be used for the other files. Valid strings for the suffix are deg, ebi, gap, sen, sum, tsn, and ttp. c.f. Log Files.

Since the Sams log files contain only four hours of data you are allowed to use a syntax like,

allday_shear = SamsLog(['sams20170813'], suffix='sen')

where sams20170813 will be expanded to a list with the six files for that day. The suffix .sen will be appended. For example,

allday_shear.files()
['sams201708130000.sen', 'sams201708130400.sen', 'sams201708130800.sen',
 'sams201708131200.sen', 'sams201708131600.sen', 'sams201708132000.sen']

You may also pass in a list of files to read from,

allday_shear = SamsLog(['sams201708130000.sen','sams201708130400.sen',
                          'sams201708130800.sen','sams201708131200.sen',
                          'sams201708131600.sen','sams201708132000.sen'])

Or you may do a combination of both,

allday_shear = SamsLog(['sams201708131600.sen','sams201708132000.sen',
                          'sams20170814',
                          'sams201708150000.sen','sams201708150400.sen'])

Note that the class will pick up the .sen suffix from the first file name and will apply it to any file name that doesn’t have a suffix yet.

Also be aware that the data files are read into the data container in the order in which they are lists. No attempt is made to sort the resulting data by time stamp.

Methods

Once the filename(s) are parsed and the files are open, the class then reads the file(s), works out whether it has sensor data (480 column), segment date (273 columns), or summary data (9 columns). It can then work out the proper address scheme from segment or segment:sensor to a data column.

classmethod samslog.append(filenames, suffix)

Like the class constructor filenames should be a list of file you want to append to the existing data. Again, these data are not sorted by date/time. The input variable, suffix, has the same connotation as in the class initialization.

classmethod samslog.data(segsens)

This method returns two or more lists; the first list contains the time stamps in Unix time format; the remaining lists depend on whether a segment number of a segment-sensor number was sent as the input argument Segment Numbering Scheme. If only a segment number is passed in, then all the data relevant to that segment will be returned. For .sen files, this would be six lists of sensor data. For .ttp files, this would be 3 lists containing the tip/tilt/piston values for the segment. If a segment-sensor value is passed in, then any sensor related file will return a single column with just that sensor’s values.

For example,

shear = SamsLog('sams201708130000.sen')
tstamp, shear23_2 = shear.data('M23:2')

gap = SamsLog('sams201708130000.gap')
tstamp, gap23_1, gap23_2, gap23_3, gap23_4, gap23_5, gap23_6 = gap.data('M23")

Note that for any edge segments, if you ask for all the sensors or a non-existant segment-sensor combinartion then None will be returned for the non-existant sensors.

It is not an error to pass a segment-sensor value as an input to a .ttp data set, but the sensor value will meaningless.

The return values are of type <class ‘numpy.ndarry’> and are one-dimensional row vectors.

classmethod samslog.starttime()
classmethod samslog.endtime()

The class also has instance variables with the start and end time of the file(s) that have been read in. These may be accessed though the methods as follows

gap.starttime()
1502582400.0
classmethod samslog.files()

This method returns the complete list of files that have been read into the data set. Thus it represents the expansion of the file list passed in during intialization and append functions.

classmethod samslog.suffix()

Return the suffix or type of file with out the dot.

gap = SamsLog([sams20170813', suffix='gap')
gap.suffix()
'gap'
classmethod samslog.size()

Returns the size of the data contains as the value rows:columns.

gap.size()
'32614:481'

SamsCmdLog

from sas import samcmdlog

The SamsCmdLog() class is very similar to the SamsLog() class in that it provides a data container for the log files. These files list the commands received by the Sams server.

class segments.SamsCmdLog(filenames, suffix='log', verbose=False)

The input variable filenames must be a list of valid log file names and/or a list of valid day names. If the names are not appended with a suffix, then the suffix parameter log will be used. The suffix argument is still in the calling pattern for the class but it is ignored. However, the class will generate an error if the suffix argument is passed in with anything other than 'log' as the argument. This is done only for consistency with the class SamsLog.

The usage of the filenames variable is the same as in the SamsLog class. You may use an abbreviated file name to include all the files for a full day. Or you may use the explicit list of files, with or with out the suffix.

allcmds = SamsCmdLog([‘sams20170813’])

morning_cmds = SamsCmdLog([‘sams201708130000’, ‘sams201708130400’, ‘sams201708130800.log’])

Methods

Once the files are read into the container, various methods are available to work with the data

classmethod segments.append(filenames, suffix='log')

Like the class constructor filenames should be a list of file you want to append to the existing data. Again, these data are not sorted by date/time. The input variable, suffix, has the same connotation as in the class initialization.

classmethod segments.find_command(command=None, starttime=None, endtime=None)

Return all instances of command found between starttime and endtime. An instance is a tuple of the form (time, commandStr). If starttime/endtime are None then the entire list is searched otherwise only the tuples found between startime and endtime are returned. If command is None, then all commands between starttime/endtime are returned. If all three are None, then the entire list is returned.

allcmds.find_command('installsen')
[(15345678901, 'installsen 85 3'),
(12456789012, 'installsen 32 1')]
classmethod segments.starttime()
classmethod segments.endtime()

The class also has instance variables with the start and end time of the file(s) that have been read in. These may be accessed though the methods as follows

allcmds.starttime()
1502582400.0
classmethod segments.files()

This method returns the complete list of files that have been read into the data set. Thus it represents the expansion of the file list passed in during intialization and append functions.

classmethod segments.suffix()

Return the suffix or type of file with out the dot. In this particular class the suffix will always be log

cmds = SamsCmdLog([sams20170813'])
cmds.suffix()
'log'
classmethod segments.size()

Returns the number of entries in the data container.

cmds.size()
3261

segments.py

from sas import segments

The file segments.py contains the conversion tables between segment number schemes. These conversion tables are simply dictionaries with keys in the relevant mirror numbering scheme, c.f. Segment Numbering Scheme.

segments.Mn2Sn
segments.Sn2Mn

Convert to/from the Mirror number of Frank Ray to the Sams number scheme from Blueline Engineering.

Mn2Sn['M02']
'S78'

Sn2Mn['S78']
'M02'
segments.CR2Sn
segments.Sn2CR

Convert to/from the Column:Row numbering scheme of Phillip McQueen and the Sams number scheme from Blueline Engineering.

CR2Sn['7:01']
'S78'

Cn2CR['S78']
'7:01'
segments.Mn2CR
segments.CR2Mn

Convert to/from the Mirror number of Frank Ray to the Column:Row of Phillip McQueen.

Mn2CR['M02']
'7:01'

CR2Mn['7:01']
'M02'
segments.m_re
segments.s_re
segments.cr_re

This are regular expession object as described in the regular expression package re. They are build with re.compile(), c.f. re for more information. There is one each for the Mnumbers, the Snumbers, and the CRnumbers.

The regular expression used to create the objects are

  • M_re = r’^(M(\d\d))(-(\d))?\Z’
  • S_re = r’^(S(\d\d))(-(\d))?\Z’
  • CR_re = r’^((\d{1,2}):(\d{1,2}))(-(\d))?\Z’
segments.SnSen_column

This array converts from segment-sensor number in the Sams numbering scheme to column number in the data array for ‘sen’, ‘gap’, ‘tsn’, or ‘deg’ files. It may also be used to see it a sensor exists by testing for a Snum-sen key value and seeing if you get a return value.

segments.get_seg_sen_type(segsen)

Parse a segment-sensor string and return the type of numbering system used. The functions returns a tuple of five values;

  • segment name in string form, i.e. M54 or S23
  • segment number or the column number if this is a CRnum as an integer
  • row number as an integer of this is a CRnum, otherwise None
  • sensor number if provided, otherwise None
  • type of number as ‘Mnum’, ‘Snum’, ‘CRNum’, or None

For example:

get_seg_sen_type('M43-2')
('M43', 43, None, 2, 'Mnum')

A CRnum may have leading zero in either the columm or the row but the number may only be two digits. The returned string however, will not have any leading zeros and may be used to index into the CR2Sn or CR2Mn arrays.

get_seg_sen_type('05:04-6')
('5:4', 5, 4, 6, 'CRnum')

get_seg_sen_type('05:04')
('5:4', 5, 4, None, 'CRnum')
segments.get_sams_num(segsen)
segments.get_mir_num(segsen)

These two functions return the S number or the M number given any valid numbering scheme as input. Two values are returned, the S or M number as a string and the S or M number as an integer:

get_sams_num('M42')
('S11', 11)

get_sams_num('2:4-6')
('S44', 44)

get_mir_num('S11')
('M42', 42')

get_mir_num('5:4')
('M26', 26)
row_cols = [7, 8, 9, 10, 11, 12, 11, 10, 9, 8, 7]

A list with the number of rows in each column, 1-11. This list is useful if you wish to do looping over the column:row order, e.g.

for c = range(0,11):
  row = row_cols[c-1]
  for r in range(0, row):
segments.gen_col_row()

Generate a list of the column:row strings for the segments in the array. This is useful for running loops in column:row index and is used extensively in the plotting routines, e.g.

for cr in gen_col_row():
  m_num, empty = get_mir_num(cr)
  x, y = plot.segment_position[cr]
  plot_something_clever(m_num, x, y)

plot.py

from sas import plot

The file plot.py contains some useful plotting routines. Plotting of the full array or a single segment is based on a unit sized hexagon where the distance from the edge to edge is set to one unit.

As we work out other items that need to be be routinely plotted, they can be added to this file.

Classes

class plot.Hexagon(size = 1.0, offset=(0.0, 0.0))

The unit hexagon. The create vertices for a hexagon with a 1.0 meter distance from edge to edge. Note that this means that the vertices fall outside the unit cell so watch out for overlap when plotting. The offset (x, y) are added to each vertex and will offset the hexagon from a (0, 0) center position. Useful for plotting routines that want to draw a hexagon.

plot.x
plot.y

These are the lists of the x, y position of the vertices. They can be access as

h = Hexagon()
plt.plot(h.x, h.y)

Note that this syntax may change. I would like to make Hexagon a derived class from a parent class Polygon but haven’t figured out how to make things work yet.

plot.vertices()

Returns a list of tuples of the (x, y) positions of the vertices.

h = Hexagon()
h.vertices()
[(,)
]

Functions

plot.make_seg_pos()

Make a dictionary with CRnums as keys and values as a tuple of the (x, y) position of the segment in the array based on a unit hexagon. This means the plot will be 11.0 units high and 11.15 units wide.

plot.segment_position

A dictionary with keys of CRnum and values of (x, y) for the segment positions based on a unit hexagon. This dictionary was initially create with make_seg_pos().

This is useful in loops like

from sas import segments as sg
from sas import plot as sp

for cr in sg.gen_col_row():
  x, y = sp.segment_position[cr]
  plot_something_clever(x, y)
plot.plot_array(ax, color='grey')

Plots 91 unit hexagons in their proper positions. See segment locations for an example. ax is a reference to a matplotlib.axes instance. color is any valid matplotlib color, e.g.

fig = plt.figure(figsize=(7,7))
ax = fig.add_subplot(111)
plot_array(ax, color='red')
plot.plot_ttp_summary(ttplog)

Plot the Tilt/Tilt vectors agains an array of segments

plot.plot_sum_summary(sumlog)

Plot the data from a summary files. Three plots are created; the sensor error as RSE and TRSE; the gap and groc; and the average sensor temperature.

More functions as we think of them.

Table Of Contents

Previous topic

Tutorial

This Page