示例#1
0
 def test_addDataRow(self):
     """Test adding a new row to 'main' data."""
     # Create a factory and load the river unit
     ifactory = FmpUnitFactory()       
     i, river = ifactory.createUnitFromFile(self.input_contents, 0, 'RIVER', 1, 1)
     
     # Add with required only args
     args = {rdt.CHAINAGE: 6.0, rdt.ELEVATION: 37.2}
     river.addRow(args, index=1)
     row = river.row_data['main'].rowAsList(1)
     testrow = [6.0, 37.2, 0.039, False, 1.0, '', 0.0, 0.0, '', '~']
     self.assertListEqual(testrow, row)
     
     # Add with all args
     args = {rdt.CHAINAGE: 6.1, rdt.ELEVATION: 37.4, rdt.ROUGHNESS: 0.06,
             rdt.PANEL_MARKER: True, rdt.RPL: 1.1, rdt.BANKMARKER: 'BED',
             rdt.EASTING: 22.5, rdt.NORTHING: 32.5, rdt.DEACTIVATION: 'RIGHT',
             rdt.SPECIAL: '16'}
     river.addRow(args, index=2)
     row = river.row_data['main'].rowAsList(2)
     testrow = [6.1, 37.4, 0.06, True, 1.1, 'BED', 22.5, 32.5, 'RIGHT', '16']
     self.assertListEqual(testrow, row)
     
     # Check it fails without required args
     args = {rdt.CHAINAGE: 6.2}
     with self.assertRaises(AttributeError):
         river.addRow(args, index=3)
     args = {rdt.ELEVATION: 36.2}
     with self.assertRaises(AttributeError):
         river.addRow(args, index=3)
         
     # Check we catch non increasing chainage
     args = {rdt.CHAINAGE: 5.0, rdt.ELEVATION: 37.2}
     with self.assertRaises(ValueError):
         river.addRow(args, index=3)
示例#2
0
 def test_addDataRow(self):
     """Test adding a new row to 'main' data."""
     # Create a factory and load the river unit
     ifactory = FmpUnitFactory()       
     i, spill = ifactory.createUnitFromFile(self.spill_unitdata, 0, 'SPILL', 1, 1)
     
     # Add with required only args
     args = {rdt.CHAINAGE: 6.0, rdt.ELEVATION: 37.2}
     spill.addRow(args, index=1)
     row = spill.row_data['main'].rowAsList(1)
     testrow = [6.0, 37.2, 0.00, 0.00]
     self.assertListEqual(testrow, row)
     
     # Add with all args
     args = {rdt.CHAINAGE: 8.0, rdt.ELEVATION: 39.4,
             rdt.EASTING: 12.0, rdt.NORTHING: 40.0}
     spill.addRow(args)
     row = spill.row_data['main'].rowAsList(4)
     testrow = [8.0, 39.4, 12.0, 40.0]
     self.assertListEqual(testrow, row)
     
     # Check it fails without required args
     args = {rdt.CHAINAGE: 56.2}
     with self.assertRaises(AttributeError):
         spill.addRow(args)
     args = {rdt.ELEVATION: 36.2}
     with self.assertRaises(AttributeError):
         spill.addRow(args)
         
     # Check we catch non increasing chainage
     args = {rdt.CHAINAGE: 5.1, rdt.ELEVATION: 37.2}
     with self.assertRaises(ValueError):
         spill.addRow(args, index=1)
示例#3
0
    def test_getData(self):

        out_data = \
            ['JUNCTION Some comment stuff',
             'OPEN',
             'WOOD1530WDXXWOOD1530SUXXWOOD1530BU  WOOD1530CU  ']

        # Create a factory and load the river unit
        ifactory = FmpUnitFactory()
        i, junction = ifactory.createUnitFromFile(self.input_contents, 0,
                                                  'JUNCTION', 1, 1)

        # Get the data and check it against our template
        data = junction.getData()
        self.assertEquals(out_data, data, 'getData() formatting failed')
示例#4
0
    def test_getData(self):
        '''Test to check the suitability of the getData() method.
        '''
        # Create a factory and load the river unit
        ifactory = FmpUnitFactory()       
        i, river = ifactory.createUnitFromFile(self.input_contents, 0, 'RIVER', 1, 1)
         
        # Setup the list that we expect to be returned from the getData() method 
        out_data = \
        ['RIVER (Culvert Exit) CH:7932 - Trimmed to BT',
         'SECTION',
         '1.069',
         '    15.078              1.1111      1000',
         '        18',
         '     5.996    37.560     0.080     1.000LEFT       291391.67  86582.61LEFT      16        ',
         '     6.936    37.197     0.035*    1.000           291391.43  86581.70          ',
         '     7.446    36.726     0.035     1.000           291391.30  86581.21          ',
         '     7.635    35.235     0.035     1.000           291391.25  86581.03          ',
         '     8.561    35.196     0.035     1.000           291391.01  86580.13          ',
         '     9.551    35.190     0.035     1.000BED        291390.75  86579.18          ',
         '    10.323    35.229     0.035     1.000           291390.55  86578.43          ',
         '    10.904    35.319     0.035     1.000           291390.40  86577.87          ',
         '    12.542    35.637     0.035     1.000           291389.98  86576.29          ',
         '    13.740    35.593     0.035     1.000           291389.67  86575.13          ',
         '    13.788    35.592     0.035     1.000           291389.66  86575.09          ',
         '    13.944    36.148     0.035     1.000           291389.62  86574.93          ',
         '    15.008    36.559     0.080*    1.000           291389.34  86573.91          ',
         '    16.355    37.542     0.080     1.000           291389.00  86572.60          ',
         '    17.424    38.518     0.080     1.000           291388.72  86571.57          ',
         '    18.449    39.037     0.080     1.000           291388.46  86570.58          ',
         '    19.416    39.146     0.080     1.000           291388.21  86569.65          ',
         '    19.420    39.133     0.080     1.000RIGHT      291388.21  86569.65RIGHT     4095      ']

            
        # Get the data and check it against our template
        data = river.getData()
        self.assertEquals(out_data, data, 'getData() formatting failed')
示例#5
0
    def buildDat(self, contents, arg_dict={}):
        """
        """
        self.contents = contents
                
        # Counter for the number of rows that have been read from the 
        # file contents list.
        i = 0
        # Get an instance of the unit factory with the number of nodes in the file.
        unit_factory = FmpUnitFactory()

        # Dictionary containing the keys to identify units in the dat file 
        unit_vars = unit_factory.getUnitIdentifiers()

        # Create a unit from the header data in the first few lines of the dat file.
        if not self.is_ied:
            i, self.temp_unit = unit_factory.createUnitFromFile(self.contents, 0, 'HEADER', 0)
            in_unknown_section = False

            # Now we can update the HeaderUnit subContents 
            self.updateSubContents()  
        
        in_unknown_section = False
        while i < len(self.contents):
            
            # Get the line and then split it to retrieve the first word. 
            # Check this word against the # unit_type keys we set above to see 
            line = self.contents[i]
            temp_line = line.strip()
            if temp_line: 
                first_word = line.split()[0].strip()
            else:
                first_word = 'Nothing'

            if first_word in unit_vars:               
                
                # If building an UnknownUnit then create and reset
                if(in_unknown_section == True):
                    self.createUnknownSection()
                    self.updateSubContents()
                    
                    # Reset the reach for the UnknownUnit
                    unit_factory.same_reach = False
                
                '''Call the unit creator function and get back the unit and the
                updated contents list index.
                Most of these variables are self explanatory, but 
                unit_vars[first_word] is the key for the unit type to make.
                '''
#                 i, self.temp_unit = unit_factory.createUnit(self.contents, i, 
#                         unit_vars[first_word], self.cur_no_of_units)
                i, self.temp_unit = unit_factory.createUnitFromFile(self.contents, i, 
                                                            first_word, 
                                                            self.cur_no_of_units)
                
                '''In case we got in but found something wasn't supported.
                it's i-1 because we can't return onto the same line that was
                read or it will loop forever, so store it here and move on
                '''
                if self.temp_unit == False:
                    self.unknown_data.append(self.contents[i].rstrip('\n'))
                    i += 1
                    self.unknown_data.append(self.contents[i].rstrip('\n'))
                    in_unknown_section = True
                else:
                    self.updateSubContents()
                    in_unknown_section = False       
             
            else: 
                in_unknown_section = True
                self.unknown_data.append(self.contents[i].rstrip('\n'))

            i += 1
        
        line = None 
        del self.unknown_data
        return self.units 
示例#6
0
def createModelExample():
    """Create a new FMP model and add a couple of river units to it.
    
    Generates a new DatCollection and adds some units with data to it. Note that
    the 'initialisedDat()' method that's used is a classmethod of DatCollection.
    It will automatically create the AUnit types that are required by Flood
    Modeller. These include:
        - HeaderUnit: the data at the top of the file.
        - InitialConditionsUnit: the data at/near the bottom of the file that
            stores all of the initial conditions for nodes.
            
    It also adds a CommentUnit as the first unit.
    """

    # Create some data to prepopulate our RiverUnit's with. You can do it this
    # way (as one big dict)
    riv1_data = {
        'name': 'riv1',
        'head_data': {
            'distance': 10.5
        },
        'row_data': {
            'main': [
                {
                    rdt.CHAINAGE: 0.0,
                    rdt.ELEVATION: 10.0,
                    rdt.ROUGHNESS: 0.035
                },
                {
                    rdt.CHAINAGE: 2.0,
                    rdt.ELEVATION: 7.0,
                    rdt.ROUGHNESS: 0.035
                },
                {
                    rdt.CHAINAGE: 4.0,
                    rdt.ELEVATION: 4.0,
                    rdt.ROUGHNESS: 0.035
                },
                {
                    rdt.CHAINAGE: 6.0,
                    rdt.ELEVATION: 4.0,
                    rdt.ROUGHNESS: 0.035
                },
                {
                    rdt.CHAINAGE: 8.0,
                    rdt.ELEVATION: 7.0,
                    rdt.ROUGHNESS: 0.035
                },
                {
                    rdt.CHAINAGE: 10.0,
                    rdt.ELEVATION: 10.0,
                    rdt.ROUGHNESS: 0.035
                },
            ],
        }
    }
    river1 = factory.createUnit('river', **riv1_data)

    # Or this way (separate variables)
    head_data = {'distance': 12.0}
    row_data = {
        'main': [
            {
                rdt.CHAINAGE: 0.0,
                rdt.ELEVATION: 9.0,
                rdt.ROUGHNESS: 0.035
            },
            {
                rdt.CHAINAGE: 2.0,
                rdt.ELEVATION: 6.0,
                rdt.ROUGHNESS: 0.035
            },
            {
                rdt.CHAINAGE: 4.0,
                rdt.ELEVATION: 3.0,
                rdt.ROUGHNESS: 0.035
            },
            {
                rdt.CHAINAGE: 6.0,
                rdt.ELEVATION: 3.0,
                rdt.ROUGHNESS: 0.035
            },
            {
                rdt.CHAINAGE: 8.0,
                rdt.ELEVATION: 6.0,
                rdt.ROUGHNESS: 0.035
            },
            {
                rdt.CHAINAGE: 10.0,
                rdt.ELEVATION: 9.0,
                rdt.ROUGHNESS: 0.035
            },
        ],
    }
    river2 = factory.createUnit('river',
                                name='riv2',
                                head_data=head_data,
                                row_data=row_data)

    # The path we'll save our new model to.
    new_path = "C:/path/to/fmp/model.dat"
    '''
    Then create a new DatCollection and give it units river1 and river2.
    
    Note that you can provide kwargs to be used when adding the units under
    the keyword 'unit_kwargs'. An example is given with the unit_kw setup
    below. When this is supplied you must provide either some kwargs, or an 
    empty dict as a placeholder for each entry in units. The kwargs at 
    unit_kwargs index i will be used for the unit at units index i.
    '''
    unit_kw = [{}, {
        'ics': {
            rdt.FLOW: 3.0,
            rdt.STAGE: 5.0,
            rdt.ELEVATION: 4.5
        }
    }]
    dat = DatCollection.initialisedDat(new_path,
                                       units=[river1, river2],
                                       unit_kwargs=unit_kw)
    '''
    A different approach.
    
    You can also creat a unit with it's constructor and populate the rows after
    if you prefer. It's then added to the DatCollection
    '''
    # You'll need to import the unit specific module
    from ship.fmp.datunits import riverunit as riv

    # Instantiate the unit (if name is not given it will get a default)
    river3 = riv.RiverUnit(name='riv3')

    # Set some head_data
    river3.head_data['distance'].value = 15.0

    # Create some row_data and add it to the unit
    rows = [
        {
            rdt.CHAINAGE: 0.0,
            rdt.ELEVATION: 8.0,
            rdt.ROUGHNESS: 0.035
        },
        {
            rdt.CHAINAGE: 2.0,
            rdt.ELEVATION: 5.0,
            rdt.ROUGHNESS: 0.035
        },
        {
            rdt.CHAINAGE: 4.0,
            rdt.ELEVATION: 2.0,
            rdt.ROUGHNESS: 0.035
        },
        {
            rdt.CHAINAGE: 6.0,
            rdt.ELEVATION: 2.0,
            rdt.ROUGHNESS: 0.035
        },
        {
            rdt.CHAINAGE: 8.0,
            rdt.ELEVATION: 5.0,
            rdt.ROUGHNESS: 0.035
        },
        {
            rdt.CHAINAGE: 10.0,
            rdt.ELEVATION: 8.0,
            rdt.ROUGHNESS: 0.035
        },
    ]
    for r in rows:
        river3.addRow(r)
    '''
    If you call addUnit without an index it will be appended to the end of the
    units. Here we find the index of river2 and put river3 there. This will 
    push river2 back up by one (i.e. order is now river1, river3, river2).
    Note that we can hand initial conditions in as a kwarg here like before.
    '''
    riv2_index = dat.index(river2)
    dat.addUnit(river3,
                index=riv2_index,
                ics={
                    rdt.FLOW: 3.0,
                    rdt.STAGE: 5.0,
                    rdt.ELEVATION: 4.5
                })

    # Write the new fmp .dat file to disk
    dat.write()
    '''
    It's worth noting that if you're not worried about populating the units with
    data from the outset it can be a very simple operation.
    '''
    # Just get a blank DatCollection with no units (except header and ics)
    new_path2 = "C:/path/to/fmp/model2.dat"
    dat2 = DatCollection.initialisedDat(new_path2)
    dat2.write()
    '''
    Final go.
    
    Create a new DatCollection but add a few empty units to it
    The units below will be added to the DatCollection in the order of the list.
    '''
    units = [
        factory.createUnit('refh', name='riv1'),
        factory.createUnit('river', name='riv2'),
        factory.createUnit('river', name='riv3'),
        factory.createUnit('arch', name='brg1'),
        factory.createUnit('river', name='riv4'),
        factory.createUnit('river', name='riv5'),
        factory.createUnit('htbdy', name='htbdy'),
    ]
    new_path3 = "C:/path/to/fmp/model3.dat"
    dat3 = DatCollection.initialisedDat(new_path3, units=units)
    dat3.write()
示例#7
0
def createModelExample():
    """Create a new FMP model and add a couple of river units to it.
    
    Generates a new DatCollection and adds some units with data to it. Note that
    the 'initialisedDat()' method that's used is a classmethod of DatCollection.
    It will automatically create the AUnit types that are required by Flood
    Modeller. These include:
        - HeaderUnit: the data at the top of the file.
        - InitialConditionsUnit: the data at/near the bottom of the file that
            stores all of the initial conditions for nodes.
            
    It also adds a CommentUnit as the first unit.
    """
    
    # Create some data to prepopulate our RiverUnit's with. You can do it this
    # way (as one big dict)
    riv1_data = {
        'name': 'riv1',
        'head_data': {'distance': 10.5},
        'row_data': {
            'main': [
                {rdt.CHAINAGE: 0.0, rdt.ELEVATION: 10.0, rdt.ROUGHNESS: 0.035},
                {rdt.CHAINAGE: 2.0, rdt.ELEVATION: 7.0, rdt.ROUGHNESS: 0.035},
                {rdt.CHAINAGE: 4.0, rdt.ELEVATION: 4.0, rdt.ROUGHNESS: 0.035},
                {rdt.CHAINAGE: 6.0, rdt.ELEVATION: 4.0, rdt.ROUGHNESS: 0.035},
                {rdt.CHAINAGE: 8.0, rdt.ELEVATION: 7.0, rdt.ROUGHNESS: 0.035},
                {rdt.CHAINAGE: 10.0, rdt.ELEVATION: 10.0, rdt.ROUGHNESS: 0.035},
            ],
        }
    }
    river1 = factory.createUnit('river', **riv1_data)
    
    # Or this way (separate variables)
    head_data = {'distance': 12.0}
    row_data = {
        'main': [
            {rdt.CHAINAGE: 0.0, rdt.ELEVATION: 9.0, rdt.ROUGHNESS: 0.035},
            {rdt.CHAINAGE: 2.0, rdt.ELEVATION: 6.0, rdt.ROUGHNESS: 0.035},
            {rdt.CHAINAGE: 4.0, rdt.ELEVATION: 3.0, rdt.ROUGHNESS: 0.035},
            {rdt.CHAINAGE: 6.0, rdt.ELEVATION: 3.0, rdt.ROUGHNESS: 0.035},
            {rdt.CHAINAGE: 8.0, rdt.ELEVATION: 6.0, rdt.ROUGHNESS: 0.035},
            {rdt.CHAINAGE: 10.0, rdt.ELEVATION: 9.0, rdt.ROUGHNESS: 0.035},
        ],
    }
    river2 = factory.createUnit('river', name='riv2', head_data=head_data,
                                row_data=row_data)
    
    
    # The path we'll save our new model to.
    new_path = "C:/path/to/fmp/model.dat"
    
    '''
    Then create a new DatCollection and give it units river1 and river2.
    
    Note that you can provide kwargs to be used when adding the units under
    the keyword 'unit_kwargs'. An example is given with the unit_kw setup
    below. When this is supplied you must provide either some kwargs, or an 
    empty dict as a placeholder for each entry in units. The kwargs at 
    unit_kwargs index i will be used for the unit at units index i.
    '''
    unit_kw = [{}, 
        {
            'ics': {rdt.FLOW: 3.0, rdt.STAGE: 5.0, rdt.ELEVATION: 4.5}
        }
    ]
    dat = DatCollection.initialisedDat(new_path, units=[river1, river2],
                                       unit_kwargs=unit_kw)
    
    '''
    A different approach.
    
    You can also creat a unit with it's constructor and populate the rows after
    if you prefer. It's then added to the DatCollection
    '''
    # You'll need to import the unit specific module
    from ship.fmp.datunits import riverunit as riv
    
    # Instantiate the unit (if name is not given it will get a default)
    river3 = riv.RiverUnit(name='riv3')
    
    # Set some head_data
    river3.head_data['distance'].value = 15.0
    
    # Create some row_data and add it to the unit
    rows = [ 
        {rdt.CHAINAGE: 0.0, rdt.ELEVATION: 8.0, rdt.ROUGHNESS: 0.035},
        {rdt.CHAINAGE: 2.0, rdt.ELEVATION: 5.0, rdt.ROUGHNESS: 0.035},
        {rdt.CHAINAGE: 4.0, rdt.ELEVATION: 2.0, rdt.ROUGHNESS: 0.035},
        {rdt.CHAINAGE: 6.0, rdt.ELEVATION: 2.0, rdt.ROUGHNESS: 0.035},
        {rdt.CHAINAGE: 8.0, rdt.ELEVATION: 5.0, rdt.ROUGHNESS: 0.035},
        {rdt.CHAINAGE: 10.0, rdt.ELEVATION: 8.0, rdt.ROUGHNESS: 0.035},
    ]
    for r in rows:
        river3.addRow(r)
    
    '''
    If you call addUnit without an index it will be appended to the end of the
    units. Here we find the index of river2 and put river3 there. This will 
    push river2 back up by one (i.e. order is now river1, river3, river2).
    Note that we can hand initial conditions in as a kwarg here like before.
    '''
    riv2_index = dat.index(river2)
    dat.addUnit(river3, index=riv2_index, ics={rdt.FLOW: 3.0, 
                                               rdt.STAGE: 5.0,
                                               rdt.ELEVATION: 4.5})
    
    # Write the new fmp .dat file to disk
    dat.write()
    
    
    '''
    It's worth noting that if you're not worried about populating the units with
    data from the outset it can be a very simple operation.
    '''
    # Just get a blank DatCollection with no units (except header and ics)
    new_path2 = "C:/path/to/fmp/model2.dat"
    dat2 = DatCollection.initialisedDat(new_path2)
    dat2.write()
    
    
    '''
    Final go.
    
    Create a new DatCollection but add a few empty units to it
    The units below will be added to the DatCollection in the order of the list.
    '''
    units = [
        factory.createUnit('refh', name='riv1'),
        factory.createUnit('river', name='riv2'),
        factory.createUnit('river', name='riv3'),
        factory.createUnit('arch', name='brg1'),
        factory.createUnit('river', name='riv4'),
        factory.createUnit('river', name='riv5'),
        factory.createUnit('htbdy', name='htbdy'),
    ]
    new_path3 = "C:/path/to/fmp/model3.dat"
    dat3 = DatCollection.initialisedDat(new_path3, units=units)
    dat3.write()
    
    
    
    
示例#8
0
    def buildDat(self, contents, arg_dict={}):
        """
        """
        self.contents = contents

        # Counter for the number of rows that have been read from the
        # file contents list.
        i = 0
        # Get an instance of the unit factory with the number of nodes in the file.
        unit_factory = FmpUnitFactory()

        # Dictionary containing the keys to identify units in the dat file
        unit_vars = unit_factory.getUnitIdentifiers()

        # Create a unit from the header data in the first few lines of the dat file.
        if not self.is_ied:
            i, self.temp_unit = unit_factory.createUnitFromFile(
                self.contents, 0, 'HEADER', 0)
            in_unknown_section = False

            # Now we can update the HeaderUnit subContents
            self.updateSubContents()

        in_unknown_section = False
        while i < len(self.contents):

            # Get the line and then split it to retrieve the first word.
            # Check this word against the # unit_type keys we set above to see
            line = self.contents[i]
            temp_line = line.strip()
            if temp_line:
                first_word = line.split()[0].strip()
            else:
                first_word = 'Nothing'

            if first_word in unit_vars:

                # If building an UnknownUnit then create and reset
                if (in_unknown_section == True):
                    self.createUnknownSection()
                    self.updateSubContents()

                    # Reset the reach for the UnknownUnit
                    unit_factory.same_reach = False
                '''Call the unit creator function and get back the unit and the
                updated contents list index.
                Most of these variables are self explanatory, but 
                unit_vars[first_word] is the key for the unit type to make.
                '''
                #                 i, self.temp_unit = unit_factory.createUnit(self.contents, i,
                #                         unit_vars[first_word], self.cur_no_of_units)
                i, self.temp_unit = unit_factory.createUnitFromFile(
                    self.contents, i, first_word, self.cur_no_of_units)
                '''In case we got in but found something wasn't supported.
                it's i-1 because we can't return onto the same line that was
                read or it will loop forever, so store it here and move on
                '''
                if self.temp_unit == False:
                    self.unknown_data.append(self.contents[i].rstrip('\n'))
                    i += 1
                    self.unknown_data.append(self.contents[i].rstrip('\n'))
                    in_unknown_section = True
                else:
                    self.updateSubContents()
                    in_unknown_section = False

            else:
                in_unknown_section = True
                self.unknown_data.append(self.contents[i].rstrip('\n'))

            i += 1

        line = None
        del self.unknown_data
        return self.units