def __init__(self, root): assert (root.tag == self.tagInNs('LgFormat') ), 'Wrong root element {:s}'.format(root.tag) myName = self.elemID(root) # Tracks, create a list of Track.Track objects # NOTE: This is not quite like the LIS track buildup where the tracks are single # and in order so when we encounter T23 we span tracks T2 and T3 (by ordinal). # Here we get a separate track description 'track23' which has the width and grid # generator, 'track2' and 'track3' may be blank. # I suppose also that the order of tracks in the XML file is not significant but # we treat is so here. myTrackS = [] # Make an additional data structure that maps the track name to ordinal self._trackNameOrdinalMap = {} for t, aT in enumerate(root.findall(self.tagInNs('LgTrack'))): l = Coord.Dim(self.float(aT, self.tagInNs('LeftPosition'), 0.0), 'in') r = Coord.Dim(self.float(aT, self.tagInNs('RightPosition'), 0.0), 'in') myTrackS.append( Track.Track( leftPos=l, rightPos=r, # Figure out track grid function gridGn=self._retGridGen(aT), plotXLines=self.bool(aT, self.tagInNs('IndexLinesVisible'), True), plotXAlpha=self.bool(aT, self.tagInNs('IndexNumbersVisible'), False), )) trackID = self.elemID(aT) if trackID is None: raise ExceptionFILMCfgXMLRead( 'PhysFilmCfgXMLRead.__init__(): Missing track UniqueId'. format(trackID)) if trackID in self._trackNameOrdinalMap: raise ExceptionFILMCfgXMLRead( 'PhysFilmCfgXMLRead.__init__(): Duplicate track UniqueId="{:s}"' .format(trackID)) # Add the track ordinal self._trackNameOrdinalMap[trackID] = t # myXPath = self.tagsInNs('LgFormat', 'LgVerticalScale', 'IndexScaler') # myElem = root.find(myXPath) # myX = self.int(root, self.tagsInNs('LgVerticalScale', 'IndexScaler')) # print() # print('TRACE:', myXPath, myElem, myX) myXScale = self.int(root, self.tagsInNs('LgVerticalScale', 'IndexScaler'), None) assert (myXScale is not None) super().__init__( theName=myName, theTracks=myTrackS, # This does not seem to be used by the parent class theDest=None, theX=myXScale, )
def test_05(self): """TestPlotTrack.test_05(): Construct a blank track without failure.""" myT = Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=None) self.assertEqual(Coord.Dim(3.2, 'in'), myT.left) self.assertEqual(Coord.Dim(5.6, 'in'), myT.right) self.assertFalse(myT.hasGrid)
def test_11(self): """TestPlotTrack.test_11(): Construct a linear track with left edge < right edge - fails.""" try: Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=Track.genLinear10) self.fail('Track.ExceptionTotalDepthLISPlotTrack not raised') except Track.ExceptionTotalDepthLISPlotTrack: pass
def test_01(self): """TestPlotTrack.test_01(): Construct a linear track without failure and check default values.""" myT = Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLinear10) self.assertEqual(Coord.Dim(3.2, 'in'), myT.left) self.assertEqual(Coord.Dim(5.6, 'in'), myT.right) self.assertTrue(myT.hasGrid) self.assertTrue(myT.plotXLines) self.assertFalse(myT.plotXAlpha)
def test_03(self): """TestPlotTrack.test_03(): Construct a log track and plot it in SVG.""" myT = Track.Track( leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade2 ) # myCnv = Plot.Canvas(Coord.Dim(6, 'in'), Coord.Dim(8, 'in'), Plot.MarginQtrInch) # myViewPort = Coord.Box( # width=myCnv.width, # depth=myCnv.depth, # ) myViewPort = Coord.Box( width=Coord.Dim(6, 'in'), depth=Coord.Dim(8, 'in'), ) myTl = Coord.Pt(Coord.Dim(0.25, 'in'), Coord.Dim(0.25, 'in')) myF = io.StringIO() with SVGWriter.SVGWriter(myF, myViewPort) as xS: myT.plotSVG(myTl, Coord.Dim(7.5, 'in'), xS) # print() # print(myF.getvalue()) # self.maxDiff = None self.assertEqual("""<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="8.000in" version="1.1" width="6.000in" xmlns="http://www.w3.org/2000/svg"> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="3.450in" x2="3.450in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="3.811in" x2="3.811in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.023in" x2="4.023in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.172in" x2="4.172in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.289in" x2="4.289in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.384in" x2="4.384in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.464in" x2="4.464in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.534in" x2="4.534in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.595in" x2="4.595in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="4.650in" x2="4.650in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.011in" x2="5.011in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.223in" x2="5.223in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.372in" x2="5.372in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.489in" x2="5.489in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.584in" x2="5.584in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.664in" x2="5.664in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.734in" x2="5.734in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.795in" x2="5.795in" y1="0.250in" y2="7.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="5.850in" x2="5.850in" y1="0.250in" y2="7.750in"/> </svg> """, myF.getvalue() )
def test_04(self): """TestPlotTrack.test_04(): Construct a lin/log/log track and plot it in SVG.""" myTracks = [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade2Start2), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLog10Decade2Start2), ] # myCnv = Plot.Canvas(Coord.Dim(8.5, 'in'), Coord.Dim(6, 'in'), Plot.MarginQtrInch) # myViewPort = Coord.Box( # width=myCnv.width, # depth=myCnv.depth, # ) myViewPort = Coord.Box( width=Coord.Dim(6, 'in'), depth=Coord.Dim(8, 'in'), ) myTl = Coord.Pt(Coord.Dim(0.25, 'in'), Coord.Dim(0.25, 'in')) myF = io.StringIO() with SVGWriter.SVGWriter(myF, myViewPort) as xS: for t in myTracks: #xS.comment(str(t)) t.plotSVG(myTl, Coord.Dim(5.5, 'in'), xS) # print() # print(myF.getvalue()) # self.maxDiff = None self.assertEqual( """<?xml version='1.0' encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="8.000in" version="1.1" width="6.000in" xmlns="http://www.w3.org/2000/svg"> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="0.250in" x2="0.250in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="0.490in" x2="0.490in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="0.730in" x2="0.730in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="0.970in" x2="0.970in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="1.210in" x2="1.210in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.500" x1="1.450in" x2="1.450in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="1.690in" x2="1.690in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="1.930in" x2="1.930in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="2.170in" x2="2.170in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="2.410in" x2="2.410in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="2.650in" x2="2.650in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="3.450in" x2="3.450in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="3.661in" x2="3.661in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="3.811in" x2="3.811in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="3.928in" x2="3.928in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.023in" x2="4.023in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.103in" x2="4.103in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.172in" x2="4.172in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.234in" x2="4.234in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="4.289in" x2="4.289in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.650in" x2="4.650in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="4.861in" x2="4.861in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.011in" x2="5.011in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.128in" x2="5.128in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.223in" x2="5.223in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.303in" x2="5.303in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.372in" x2="5.372in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="5.434in" x2="5.434in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="5.489in" x2="5.489in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="5.850in" x2="5.850in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="5.850in" x2="5.850in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="6.061in" x2="6.061in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="6.211in" x2="6.211in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="6.328in" x2="6.328in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="6.423in" x2="6.423in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="6.503in" x2="6.503in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="6.572in" x2="6.572in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="6.634in" x2="6.634in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="6.689in" x2="6.689in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.050in" x2="7.050in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.261in" x2="7.261in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.411in" x2="7.411in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.528in" x2="7.528in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.623in" x2="7.623in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.703in" x2="7.703in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.772in" x2="7.772in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.250" x1="7.834in" x2="7.834in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="7.889in" x2="7.889in" y1="0.250in" y2="5.750in"/> <line stroke="black" stroke-opacity="1.000" stroke-width="0.750" x1="8.250in" x2="8.250in" y1="0.250in" y2="5.750in"/> </svg> """, myF.getvalue())
def test_00(self): """TestPlotTrack.test_00(): Construct a lin/log/log track with FEET 1/200 and plot it in SVG.""" myCnv = Plot.Canvas(Coord.Dim(8.5, 'in'), Coord.Dim(12, 'in'), PlotConstants.MarginQtrInch) myViewPort = Coord.Box( width=myCnv.width, depth=myCnv.depth, ) myTopLeft = Coord.Pt(Coord.Dim(0.25, 'in'), Coord.Dim(0.25, 'in')) myF = io.StringIO() myTracks = [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXAxis=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade2Start2), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLog10Decade2Start2), ] with SVGWriter.SVGWriter(myF, myViewPort) as xS: # Do tracks first for t in myTracks: #xS.comment(str(t)) if t.hasGrid: t.plotSVG( myTopLeft, myCnv.depth - myCnv.margins.top - myCnv.margins.bottom, xS, ) # Now XGrid # We are plotting up so xPosStart is at bottom myXposStart = myCnv.depth - myCnv.margins.bottom myXposStop = myCnv.margins.top myXg = XGrid.XGrid(200) # Plot depth lines for pos, stroke in myXg.genXPosStroke(xFrom=4307.5, xInc=False, units=b'FEET'): myXpos = myXposStart + pos if myXpos < myXposStop: break for t in myTracks: if t.hasGrid: with SVGWriter.SVGLine( xS, Coord.Pt(t.left + myCnv.margins.left, myXpos), Coord.Pt(t.right + myCnv.margins.left, myXpos), attrs=Stroke.retSVGAttrsFromStroke(stroke)): pass # Plot depth text textAttrs = { 'text-anchor': 'end', 'dominant-baseline': 'middle', } for pos, val in myXg.genXPosText(xFrom=4307.5, xInc=False, units=b'FEET'): myXpos = myXposStart + pos if myXpos < myXposStop: break for t in myTracks: if t.plotXAxis: myPt = Coord.Pt( t.right + myCnv.margins.left - Coord.Dim(0.05, 'in'), myXpos) with SVGWriter.SVGText(xS, myPt, 'Courier', 16, textAttrs): xS.characters(str(val)) print() print(myF.getvalue())
class PhysFilmCfgLISRead(PhysFilmCfg): """Tracks from a LIS FILM table, essentially the pair of GCOD and GDEC defines the left-to-right layout of the plot. Grid codes from analysis above: b'BBB ', b'E1E ', b'E20 ', b'E2E ', b'E3E ', b'E40 ', b'E4E ', b'EB0 ', b'EEB ', b'EEE ', b'LLLL' The DSCA defines the top-to-bottom nature of the plot. DSCA codes from analysis above: b'D200', b'D500', b'DM ', b'S5 ' But we can guess some others... """ # The map of FILM track descriptions [pair of (name, decades)] to internal track representations GCOD_GDEC_MAP = { # T23 is 4 decades (b'E20 ', b'-4--'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade2Start2), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLog10Decade2Start2), ], (b'E2E ', b'-1--'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade1Start2), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLinear10), ], (b'E2E ', b'-2--'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade2Start2), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLinear10), ], (b'E3E ', b'-3--'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade3), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLinear10), ], (b'E4E ', b'-4--'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLog10Decade4), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLinear10), ], (b'EEE ', b'----'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLinear10), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLinear10), ], (b'EEB ', b'----'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=Track.genLinear10), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=None), ], (b'EBE ', b'----'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=Track.genLinear10), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=None), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLinear10), ], # All blank (b'BBB ', b'----'): [ Track.Track(leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(2.4, 'in'), gridGn=None), Track.Track( leftPos=Coord.Dim(2.4, 'in'), rightPos=Coord.Dim(3.2, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(3.2, 'in'), rightPos=Coord.Dim(5.6, 'in'), gridGn=None), Track.Track(leftPos=Coord.Dim(5.6, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=None), ], # Four track. Depth 1in, 4 tracks at 1.75in # Alternate could be depth 0.5in, 4 tracks at 1.875in (b'LLLL', b'1111'): [ Track.Track( leftPos=Coord.Dim(0.0, 'in'), rightPos=Coord.Dim(1.0, 'in'), gridGn=None, plotXLines=False, plotXAlpha=True, ), Track.Track(leftPos=Coord.Dim(1.0, 'in'), rightPos=Coord.Dim(2.75, 'in'), gridGn=Track.genLinear10), Track.Track(leftPos=Coord.Dim(2.75, 'in'), rightPos=Coord.Dim(4.5, 'in'), gridGn=Track.genLinear10), Track.Track(leftPos=Coord.Dim(4.5, 'in'), rightPos=Coord.Dim(6.25, 'in'), gridGn=Track.genLinear10), Track.Track(leftPos=Coord.Dim(6.25, 'in'), rightPos=Coord.Dim(8, 'in'), gridGn=Track.genLinear10), ], } # Alternate mappings that are deemed 'equivalent' GCOD_GDEC_ALT_MAP = { # Read from 2953.S13 (b'EEE ', b'EEE-'): GCOD_GDEC_MAP[(b'EEE ', b'----')], # Read from 12988.S3 (b'EEB ', b'EEE-'): GCOD_GDEC_MAP[(b'EEB ', b'----')], # Read from 200099.S07 - ignore for the moment (b'EB0 ', b'----'): GCOD_GDEC_MAP[(b'EBE ', b'----')], # (b'E1E ', b'-4--'): GCOD_GDEC_MAP[(b'E4E ', b'-4--')], # Read from 300026.S01 (b'E40 ', b'-4--'): GCOD_GDEC_MAP[(b'E20 ', b'-4--')], } #: X axis scale from a LIS FILM table #: DSCA codes from analysis above: #: b'D200', b'D500', b'DM ', b'S5 ' #: But we can guess some others... DSCA_MAP = { b'D20 ': 20, b'D40 ': 40, b'D200': 200, b'D240 ': 240, b'D500': 500, b'DM ': 1000, # 5 inches per 100 feet b'S5 ': 12 * 100 // 5, # 2 inches per 100 feet b'S2 ': 12 * 100 // 2, } def __init__(self, theRow): """Reads a LogiRec.TableRow object and populates a CurveCfg. Example:: MNEM GCOD GDEC DEST DSCA ----------------------------- 1 E20 -4-- PF1 D200 """ myName = Mnem.Mnem(theRow[b'MNEM'].value) myTrackS = self._retTracks(theRow[b'GCOD'].value, theRow[b'GDEC'].value) myDest = theRow[b'DEST'].value myDscaleKey = theRow[b'DSCA'].value super().__init__(theName=myName, theTracks=myTrackS, theDest=myDest, theX=self.DSCA_MAP[myDscaleKey]) def _retTracks(self, theGCOD, theGDEC): """Given a GCOD, GDEC pair this returns a list of Track.Track() objects or None.""" # Kludge: Replace a trailing ' ' with a '-' so that the key look up works # when the '-' is missing. if len(theGDEC) == 4 and theGDEC[3:] == b' ': theGDEC = theGDEC[:3] + b'-' try: return self.GCOD_GDEC_MAP[(theGCOD, theGDEC)] except KeyError: # Try the alternate map logging.warning( 'PhysFilmCfgLISRead._retTracks():' ' No key for GCOD={!r:s} GDEC={!r:s}, falling back to alternate.' .format(theGCOD, theGDEC)) try: return self.GCOD_GDEC_ALT_MAP[(theGCOD, theGDEC)] except KeyError: pass raise ExceptionFILMCfg( 'PhysFilmCfgLISRead._retTracks(): No key for GCOD={!r:s} GDEC={!r:s}' .format(theGCOD, theGDEC)) def supportedFilmTracks(self): """A list of supported film (name, decade) pairs.""" return sorted(self.GCOD_GDEC_MAP.keys())