Source code for gsshapy.orm.gpi

"""
********************************************************************************
* Name: StormDrainNetworkModel
* Author: Nathan Swain
* Created On: May 14, 2013
* Copyright: (c) Brigham Young University 2013
* License: BSD 2-Clause
********************************************************************************
"""
from __future__ import unicode_literals

__all__ = ['GridPipeCell',
           'GridPipeFile',
           'GridPipeNode']

from future.utils import iteritems
from sqlalchemy import ForeignKey, Column
from sqlalchemy.types import Integer, Float, String
from sqlalchemy.orm import relationship

from . import DeclarativeBase
from ..base.file_base import GsshaPyFileObjectBase
from ..lib import parsetools as pt


[docs]class GridPipeFile(DeclarativeBase, GsshaPyFileObjectBase): """ Object interface for the Grid Pipe File. The grid pipe file is used to map the grid pipe network for subsurface drainage to the model grid. The contents of the grid pipe file is abstracted into two types of objects including: :class:`.GridPipeCell` and :class:`.GridPipeNode`. Each cell lists the pipe nodes that are contained in the cell and each pipe node defines the percentage of a pipe that is contained inside a cell. See the documentation provided for each object for a more details. See: http://www.gsshawiki.com/Subsurface_Drainage:Subsurface_Drainage http://www.gsshawiki.com/images/d/d6/SUPERLINK_TN.pdf """ __tablename__ = 'gpi_grid_pipe_files' tableName = __tablename__ #: Database tablename # Primary and Foreign Keys id = Column(Integer, autoincrement=True, primary_key=True) #: PK # Relationship Properties gridPipeCells = relationship('GridPipeCell', back_populates='gridPipeFile') #: RELATIONSHIP projectFile = relationship('ProjectFile', uselist=False, back_populates='gridPipeFile') #: RELATIONSHIP # Value Columns pipeCells = Column(Integer, nullable=False) #: INTEGER fileExtension = Column(String, default='gpi') #: STRING def __init__(self): """ Constructor """ GsshaPyFileObjectBase.__init__(self) def _read(self, directory, filename, session, path, name, extension, spatial, spatialReferenceID, replaceParamFile): """ Grid Pipe File Read from File Method """ # Set file extension property self.fileExtension = extension # Keywords KEYWORDS = ('PIPECELLS', 'CELLIJ') # Parse file into chunks associated with keywords/cards with open(path, 'r') as f: chunks = pt.chunk(KEYWORDS, f) # Parse chunks associated with each key for key, chunkList in iteritems(chunks): # Parse each chunk in the chunk list for chunk in chunkList: # Cases if key == 'PIPECELLS': # PIPECELLS Handler schunk = chunk[0].strip().split() self.pipeCells = schunk[1] elif key == 'CELLIJ': # CELLIJ Handler # Parse CELLIJ Chunk result = self._cellChunk(chunk) # Create GSSHAPY object self._createGsshaPyObjects(result) def _write(self, session, openFile, replaceParamFile): """ Grid Pipe File Write to File Method """ # Write Lines openFile.write('GRIDPIPEFILE\n') openFile.write('PIPECELLS %s\n' % self.pipeCells) for cell in self.gridPipeCells: openFile.write('CELLIJ %s %s\n' % (cell.cellI, cell.cellJ)) openFile.write('NUMPIPES %s\n' % cell.numPipes) for node in cell.gridPipeNodes: openFile.write('SPIPE %s %s %.6f\n' % ( node.linkNumber, node.nodeNumber, node.fractPipeLength)) def _createGsshaPyObjects(self, cell): """ Create GSSHAPY GridPipeCell and GridPipeNode Objects Method """ # Initialize GSSHAPY GridPipeCell object gridCell = GridPipeCell(cellI=cell['i'], cellJ=cell['j'], numPipes=cell['numPipes']) # Associate GridPipeCell with GridPipeFile gridCell.gridPipeFile = self for spipe in cell['spipes']: # Create GSSHAPY GridPipeNode object gridNode = GridPipeNode(linkNumber=spipe['linkNumber'], nodeNumber=spipe['nodeNumber'], fractPipeLength=spipe['fraction']) # Associate GridPipeNode with GridPipeCell gridNode.gridPipeCell = gridCell def _cellChunk(self, lines): """ Parse CELLIJ Chunk Method """ KEYWORDS = ('CELLIJ', 'NUMPIPES', 'SPIPE') result = {'i': None, 'j': None, 'numPipes': None, 'spipes': []} chunks = pt.chunk(KEYWORDS, lines) # Parse chunks associated with each key for card, chunkList in iteritems(chunks): # Parse each chunk in the chunk list for chunk in chunkList: schunk = chunk[0].strip().split() # Cases if card == 'CELLIJ': # CELLIJ handler result['i'] = schunk[1] result['j'] = schunk[2] elif card == 'NUMPIPES': # NUMPIPES handler result['numPipes'] = schunk[1] elif card == 'SPIPE': # SPIPE handler pipe = {'linkNumber': schunk[1], 'nodeNumber': schunk[2], 'fraction': schunk[3]} result['spipes'].append(pipe) return result
[docs]class GridPipeCell(DeclarativeBase): """ Object containing the pipe data for a single grid cell. A cell can contain several pipe nodes. """ __tablename__ = 'gpi_grid_pipe_cells' tableName = __tablename__ #: Database tablename # Primary and Foreign Keys id = Column(Integer, autoincrement=True, primary_key=True) #: PK gridPipeFileID = Column(Integer, ForeignKey('gpi_grid_pipe_files.id')) #: FK # Value Columns cellI = Column(Integer) #: INTEGER cellJ = Column(Integer) #: INTEGER numPipes = Column(Integer) #: INTEGER # Relationship Properties gridPipeFile = relationship('GridPipeFile', back_populates='gridPipeCells') #: RELATIONSHIP gridPipeNodes = relationship('GridPipeNode', back_populates='gridPipeCell') #: RELATIONSHIP def __init__(self, cellI, cellJ, numPipes): """ Constructor """ self.cellI = cellI self.cellJ = cellJ self.numPipes = numPipes def __repr__(self): return '<GridPipeCell: CellI=%s, CellJ=%s, NumPipes=%s>' % ( self.cellI, self.cellJ, self.numPipes)
[docs]class GridPipeNode(DeclarativeBase): """ Object containing data for a single pipe. """ __tablename__ = 'gpi_grid_pipe_nodes' tableName = __tablename__ #: Database tablename # Primary and Foreign Keys id = Column(Integer, autoincrement=True, primary_key=True) #: PK gridPipeCellID = Column(Integer, ForeignKey('gpi_grid_pipe_cells.id')) #: FK # Value Columns linkNumber = Column(Integer) #: INTEGER nodeNumber = Column(Integer) #: INTEGER fractPipeLength = Column(Float) #: FLOAT # Relationship Properties gridPipeCell = relationship('GridPipeCell', back_populates='gridPipeNodes') #: RELATIONSHIP def __init__(self, linkNumber, nodeNumber, fractPipeLength): """ Constructor """ self.linkNumber = linkNumber self.nodeNumber = nodeNumber self.fractPipeLength = fractPipeLength def __repr__(self): return '<GridPipeNode: LinkNumber=%s, NodeNumber=%s, FractPipeLength=%s>' % ( self.linkNumber, self.nodeNumber, self.fractPipeLength)