def _plotUsingLgFormats(self, theFi, theLpIdx, thePrs, theFpOut): """Plots a LogPass from a LIS file using the LgFormat XML files specify the plot. theFi - the LIS File object. theLpIdx - integer for the LogPass in the LIS File. thePrs - a PlotRecord Set that holds the seek positions of the appropriate LIS Logical Records (we only use CONS records here for the API header). theFpOut - Output file path for the SVG file(s), one per FILM ID. """ assert(len(self._lgFormatS) > 0) _p, myLogPass, myCONSRecS = self._retPlotFromPlotRecordSet(theFi, thePrs) myFilm = FILMCfgXML.FilmCfgXMLRead() for aUniqueId in self._lgFormatS: logging.info('PlotLogPasses._plotUsingLgFormats(): UniqueId={:s}.'.format(aUniqueId)) # Create a PRES like object from the UniqueId myRoot = myFilm.rootNode(aUniqueId) if myRoot is not None: myPres = PRESCfgXML.PresCfgXMLRead(myRoot, myFilm) myPlot = Plot.PlotReadXML(myFilm, myPres) if myPlot.hasDataToPlotLIS(myLogPass, aUniqueId): # Create output path and plot it myOutFilePath = '{:s}_{:04d}_{:s}.svg'.format(theFpOut, theLpIdx, aUniqueId) myCurvIDs, numPoints = myPlot.plotLogPassLIS( theFi, myLogPass, myLogPass.xAxisFirstEngVal, myLogPass.xAxisLastEngVal, aUniqueId, open(myOutFilePath, 'w'), frameStep=1, title="Plot: {:s} LogPass: {:d} FILM ID={:s}".format( os.path.abspath(myOutFilePath), theLpIdx, aUniqueId, ), lrCONS=myCONSRecS, ) assert(myCurvIDs is not None and numPoints is not None) # So here the essential data that we have to put in the index.html is: # Key: myOutFilePath or input file fp, lpIdx, aFilmId, # Value: (myPlot.xScale(aFilmId), myLogPass.xAxisFirstEngVal, myLogPass.xAxisLastEngVal, myCurvIDs) self.plotLogInfo.addPlotResult( theFi.fileId, myOutFilePath, theLpIdx, aUniqueId, myPlot.xScale(aUniqueId), myLogPass.xAxisFirstEngVal, myLogPass.xAxisLastEngVal, theCurveS=myCurvIDs, ptsPlotted=numPoints) else: logging.error('PlotLogPasses._plotUsingLgFormats(): No root node for UniqueId: "{:s}"'.format(aUniqueId)) else: logging.info('PlotLogPasses._plotUsingLgFormats(): No data to plot for FILM ID {:s}'.format(aUniqueId))
def _plotLISUsingLgFormats(self, theFi, theLpIdx, thePrs, theFpOut): """Plots a LogPass from a LIS file using the LgFormat XML files specify the plot. theFi - the LIS File object. theLpIdx - integer for the LogPass in the LIS File. thePrs - a PlotRecord Set that holds the seek positions of the appropriate LIS Logical Records (we only use CONS records here for the API header). theFpOut - Output file path for the SVG file(s), one per FILM ID. """ assert (not self.usesInternalRecords) logging.debug( 'PlotLogPasses._plotLISUsingLgFormats(): PlotRecords={:s}.'.format( str(thePrs))) myCONSRecS = self._retCONSRecS(theFi, thePrs) for aUniqueId in self._retUniqueIdS(thePrs.logPass): logging.info( 'PlotLogPasses._plotLISUsingLgFormats(): UniqueId={:s}.'. format(aUniqueId)) myPlot = Plot.PlotReadXML(aUniqueId, self._scale) if myPlot.hasDataToPlotLIS(thePrs.logPass, aUniqueId): # Create output path and plot it myOutFilePath, myTitle = self._retOutPathTitle( theFpOut, theLpIdx, aUniqueId) myCurvIDs, numPoints = myPlot.plotLogPassLIS( theFi, thePrs.logPass, thePrs.logPass.xAxisFirstEngVal, thePrs.logPass.xAxisLastEngVal, aUniqueId, myOutFilePath, frameStep=1, title=myTitle, lrCONS=myCONSRecS, ) assert (myCurvIDs is not None and numPoints is not None) # So here the essential data that we have to put in the index.html is: # Key: myOutFilePath or input file fp, lpIdx, aFilmId, # Value: (myPlot.xScale(aFilmId), myLogPass.xAxisFirstEngVal, myLogPass.xAxisLastEngVal, myCurvIDs) self.plotLogInfo.addPlotResult(theFi.fileId, myOutFilePath, theLpIdx, aUniqueId, myPlot.xScale(aUniqueId), thePrs.logPass.xAxisFirstEngVal, thePrs.logPass.xAxisLastEngVal, theCurveS=myCurvIDs, ptsPlotted=numPoints) else: logging.info( 'PlotLogPasses._plotLISUsingLgFormats(): No data to plot for FILM ID {:s}' .format(aUniqueId))
def _retPlotFromPlotRecordSet(self, theFi, thePrs): """Returns a Plot.PlotReadLIS, a LogPass and a list of CONS records from the PlotRecordSet.""" assert (thePrs) theFi.seekLr(thePrs.tellFilm) myLrFilm = LogiRec.LrTableRead(theFi) theFi.seekLr(thePrs.tellPres) myLrPres = LogiRec.LrTableRead(theFi) if thePrs.tellArea is not None: theFi.seekLr(thePrs.tellArea) myLrArea = LogiRec.LrTableRead(theFi) else: myLrArea = None if thePrs.tellPip is not None: theFi.seekLr(thePrs.tellPip) myLrPip = LogiRec.LrTableRead(theFi) else: myLrPip = None myPlot = Plot.PlotReadLIS(myLrFilm, myLrPres, myLrArea, myLrPip) return myPlot, thePrs.logPass, self._retCONSRecS(theFi, thePrs)
def _retPlotFromIntPlotRecordSet(self, theFi, thePrs): """Returns a Plot.PlotReadLIS, a LogPass and a list of CONS records from the PlotRecordSet. This creates the plot using internal records such as FILM and PRES records.""" assert(thePrs) assert(self.usesInternalRecords) theFi.seekLr(thePrs.tellFilm) myLrFilm = TotalDepth.LIS.core.LogiRec.LrTableRead(theFi) theFi.seekLr(thePrs.tellPres) myLrPres = TotalDepth.LIS.core.LogiRec.LrTableRead(theFi) if thePrs.tellArea is not None: theFi.seekLr(thePrs.tellArea) myLrArea = TotalDepth.LIS.core.LogiRec.LrTableRead(theFi) else: myLrArea = None if thePrs.tellPip is not None: theFi.seekLr(thePrs.tellPip) myLrPip = TotalDepth.LIS.core.LogiRec.LrTableRead(theFi) else: myLrPip = None myPlot = Plot.PlotReadLIS(myLrFilm, myLrPres, myLrArea, myLrPip, self._scale) return myPlot, thePrs.logPass, self._retCONSRecS(theFi, thePrs)
def _plotLASUsingLgFormats(self, theLasFile, theFpOut): """Plots a LogPass from a LAS file using the LgFormat XML files specify the plot. theFi - the LASFile object. theFpOut - Output file path for the SVG file(s), one per XML UniqueId. """ assert (not self.usesInternalRecords) for aUniqueId in self._retUniqueIdS(theLasFile): logging.info( 'PlotLogPasses._plotLASUsingLgFormats(): UniqueId={:s}.'. format(aUniqueId)) # Note: Only one log pass per LAS file so index 0 myOutFilePath, myTitle = self._retOutPathTitle( theFpOut, 0, aUniqueId) myPlot = Plot.PlotReadXML(aUniqueId, self._scale) if myPlot.hasDataToPlotLAS(theLasFile, aUniqueId): myCurvIDs, numPoints = myPlot.plotLogPassLAS( theLasFile, theLasFile.xAxisStart, theLasFile.xAxisStop, aUniqueId, myOutFilePath, frameStep=1, title=myTitle, plotHeader=self._apiHeader, ) # logging.fatal('Plot curves: {:s} and points: {:s}'.format(str(myCurvIDs), str(numPoints))) assert (myCurvIDs is not None and numPoints is not None) # So here the essential data that we have to put in the index.html is: # Key: myOutFilePath or input file fp, lpIdx, aFilmId, # Value: (myPlot.xScale(aFilmId), myLogPass.xAxisFirstEngVal, myLogPass.xAxisLastEngVal, myCurvIDs) self.plotLogInfo.addPlotResult(theLasFile.id, myOutFilePath, 0, aUniqueId, myPlot.xScale(aUniqueId), theLasFile.xAxisStart, theLasFile.xAxisStop, theCurveS=myCurvIDs, ptsPlotted=numPoints)
def _retPlotFromXML(self, theFi, theIdxLogPass, theUniqueId): assert (len(self._lgFormatS) > 0) assert (theUniqueId in self._lgFormatS) myFcfg = FILMCfgXML.FilmCfgXMLRead() return Plot.PlotReadXML(myFcfg[theUniqueId], self._scale), theIdxLogPass.logPass
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())