示例#1
0
    def loadFile(self, file_path, arg_dict={}):
        """Loads the ISIS .DAT file.

        Splits it into objects for each unit type, initial conditions etc.

        This is an epic if-else section for each unit type currently 
        represented.

        Needs cleaning up and writing with a bit more style.

        Easy to add another unit type, if it's not currently covered then it 
        will just be collected in the universal 'UnknownUnit' and printed 
        back out the same as it came in.
        
        Args:
            file_path (str): path to the .dat file to load.
        
        Returns:
            units - UnitCollection containing the dat file units or False if 
                they couldn't be loaded.
        
        Raises:
            IOError: If the file cannot be loaded or is empty.
            AttributeError: if the file is not of an expected type (.dat/.ief).
        
        See Also:
            IsisUnitCollection
            FactoryClasses
        
        TODO: Decide if the observer style calls are ever going to be needed.
                If they aren't then remove them rather than have them
                cluttering up the file.
        """
        line = ''
        # Used to populate the data for the UnknownUnit
        self.unknown_data = []
        # Composite for all dat units
        path_holder = ftools.PathHolder(file_path)
        self.units = DatCollection(path_holder)
        #         self.units.file_dir, self.units.filename = os.path.split(file_path)
        #         self.units.filename = os.path.splitext(self.units.filename)[0]

        if not uf.checkFileType(file_path, ext=['.dat', '.DAT']):
            if not uf.checkFileType(file_path, ext=['.ied', '.IED']):
                logger.error(
                    'Illegal File Error: ' + file_path +
                    '\nDoes not have extension (.dat, .DAT, .ied, .IED)')
                raise AttributeError(
                    'Illegal File Error: ' + file_path +
                    '\nDoes not have extension (.dat, .DAT, .ied, .IED)')
            else:
                self.is_ied = True

        contents = self.__loadFile(file_path)
        if (contents == False):
            raise IOError('Unable to load file at: ' + file_path)

        return self.buildDat(contents, arg_dict)
示例#2
0
    def initialisedDat(cls, dat_path, units=[], **kwargs):
        """Create a new ISIS .dat file with basic header info and no units.
        
        Creates the equivelant of generating a new .dat unit in the software. The
        DatCollection returned can then be manipulated in the same way that any
        other one loaded from file would be.
        
        A single comment unit will be be added to the file stating that it was
        created by the SHIP library at timestamp.
        
        Example unit_kwargs. Note that first index is a placholder for no args::
            unit_kwargs== [{}, 
                {
                    'ics': {rdt.FLOW: 3.0, rdt.STAGE: 15.0, rdt.ELEVATION: 14.5},
                }
            ]
        
        **kwargs:
            unit_kwargs(list): contains a dict with the kwargs for each unit
                that is included in units. The list must be the same length
                as units, or not included. If no kwargs for a particular unit
                are to be given an empty dict should be used as a placholder in
                the list. 
        
        Args:
            dat_path(str): the path to set for the newly created .dat file.
            
        Return:
            DatCollection - setup as an empty ISIS .dat file.
        """
        unit_kwargs = kwargs.get('unit_kwargs', [{}] * len(units))
        if not len(unit_kwargs) == len(units):
            raise ValueError(
                'unit_kwargs kwarg must be the same length as unit or not be given'
            )

        path_holder = ft.PathHolder(dat_path)
        dat = cls(path_holder)
        hunit = iuf.FmpUnitFactory.createUnit('header')
        icunit = iuf.FmpUnitFactory.createUnit('initial_conditions')
        cunit = CommentUnit(text=('Created by SHIP library on %s' %
                                  datetime.now().strftime('%Y-%M-%d %H:%M')))
        dat.addUnit(hunit, update_node_count=False)
        dat.addUnit(cunit, update_node_count=False)
        dat.addUnit(icunit, update_node_count=False)
        for i, u in enumerate(units):
            dat.addUnit(u, **unit_kwargs[i])
        return dat
示例#3
0
def readMatSubfile(main_datafile, filename, header_list, args_dict):
    """
    """
    value_separator = ','
    comment_types = ['#', '!']
    mat_subfile_enum = dataobj.SubfileMatEnum()
    path = os.path.join(main_datafile.root, filename)
    root = main_datafile.root

    header1 = 'None'
    header2 = 'None'
    if len(header_list) > 0:
        header1 = header_list[0]
        if len(header_list) > 1:
            header2 = header_list[1]

    def _scanfile(filepath):
        """Scans the file before we do any loading to identify the contents.
        Need to do this because the file can be setup in so many way that it
        becomes a headache to work it out in advance. Better to take a little
        bit of extra processing time and do some quick checks first.
         
        Arguments:
            file_path (str): the path to the subfile.
        
        Return:
            tuple:
                 list: booleans with whether the column contains
                       data that we want or not.
                 int:  length of the cols list.
                 list: containing all of the first row column data
                 int:  first row with usable data on.
        """
        logger.debug('Scanning Materials file - %s' % (filepath))

        with open(filepath, 'rb') as csv_file:

            csv_file = csv.reader(csv_file)

            cols = []
            head_list = []
            start_row = -1
            for i, row in enumerate(csv_file, 0):
                if "".join(row).strip() == "":
                    break

                for j, col in enumerate(row, 0):
                    if i == 0:
                        cols.append(False)
                        head_list = row
                    elif uuf.isNumeric(col):
                        cols[j] = True
                        if start_row == -1:
                            start_row = i
                    elif cols[j] == True:
                        break

        return cols, len(cols), head_list, start_row

    def _loadHeadData(row, row_collection, col_length):
        """
        """
        new_row = [None] * 12

        comment_indices, length = uuf.findSubstringInList('!', row)
        comment_lines.append(None)

        head1_location = -1
        head2_location = -1
        row_length = len(row)
        for i in range(0, col_length):
            if i < row_length:
                entry = row[i].strip()
                if entry == header1:
                    head1_location = i
                if entry == header2:
                    head2_location = i
                row_collection._addValue('actual_header', entry)

        return row_collection, head1_location, head2_location

    def _loadRowData(row, row_count, row_collection, comment_lines, col_length,
                     start_row):
        """Loads the data in a specific row of the file.
        
        Args:
            row(list): containing the row data.
            row_count(int): the current row number.
            required_headers(list): column names that must exist.

        Return:
            rowdatacollection: updated with header row details.
        """
        # Any lines that aren't headers, but are above the first row to contain
        # actual data will be stored as comment lines
        if row_count < start_row:
            comment_lines.append(row)
            return row_collection, comment_lines
        else:
            comment_lines.append(None)

        if '!' in row[-1] or '#' in row[-1]:
            row_collection._addValue('comment', row[-1])

        # Add the row data in the order that it appears in the file
        # from left to right.
        for i in range(col_length):
            if i < len(row):
                row_collection._addValue(i, row[i])

        return row_collection, comment_lines

    try:
        logger.info('Loading data file contents from disc - %s' % (path))
        with open(path, 'rb') as csv_file:
            csv_file = csv.reader(csv_file)

            # Do a quick check of the file setup
            cols, col_length, head_list, start_row = _scanfile(path)

            # First entry doesn't want to have a comma in front when formatting.
            # but all of the others do.
            row_collection = RowDataCollection()
            row_collection.addToCollection(
                do.FloatData(0, format_str=' {0}', default='', no_of_dps=6))
            for i in range(1, len(cols)):
                if cols[i] == True:
                    row_collection.addToCollection(
                        do.FloatData(i,
                                     format_str=', {0}',
                                     default='',
                                     no_of_dps=6))
                else:
                    row_collection.addToCollection(
                        do.StringData(i, format_str=', {0}', default=''))

            row_collection.addToCollection(do.StringData('actual_header',
                                                         format_str='{0}',
                                                         default=''),
                                           index=0)
            row_collection.addToCollection(
                do.IntData('row_no', format_str=None, default=''))

            # Stores the comments found in the file
            comment_lines = []
            first_data_line = False
            # Loop through the contents list loaded from file line-by-line.
            for i, line in enumerate(csv_file, 0):

                comment = hasCommentOnlyLine(''.join(line), comment_types)
                if comment or comment == '':
                    comment_lines.append([comment, i])

                # If we have a line that isn't a comment or a blank then it is going
                # to contain materials entries.
                else:
                    # First non-comment is the headers
                    if first_data_line == False:
                        first_data_line = True
                        row_collection, head1_loc, head2_loc = _loadHeadData(
                            line, row_collection, col_length)
                    else:
                        row_collection, comment_lines = _loadRowData(
                            line, i, row_collection, comment_lines, col_length,
                            start_row)

                    row_collection._addValue('row_no', i)

    except IOError:
        logger.warning('Cannot load file - IOError')
        raise IOError('Cannot load file at: ' + path)

    path_holder = filetools.PathHolder(path, root)
    mat_sub = dataobj.DataFileSubfileMat(path_holder, row_collection,
                                         comment_lines, path_holder.filename,
                                         head1_loc, head2_loc)
    return mat_sub
示例#4
0
    def loadFile(self, file_path, arg_dict={}):
        """Loads the ief file at the given path.

        Args:
            file_path (str): The path to the ief file.

        Returns:
            Ief file object containing the contents loaded from file.
        """
        if not uf.checkFileType(file_path, ext=['.ief', '.IEF']):
            logger.error('File: ' + file_path +
                         '\nDoes not match ief extension (*.ief or *.IEF)')
            logger.error('Illegal File Error: %s is not of type ief' %
                         (file_path))
            raise AttributeError('Illegal File Error: %s is not of type ief' %
                                 (file_path))

        contents = self._loadFile(file_path)
        # if we couldn't load the file let them know.
        if contents == False:
            raise IOError('Unable to load file at: ' + file_path)

        event_header = {}
        event_details = {}
        snapshot = []
        ied_data = []
        description = []
        in_event_details = False

        index = 0
        while (index < len(contents)):
            c = contents[index]

            # If we're moving into the event details then mark it and skip the
            # next line, which tells us so.
            if c.strip('\n') == '[ISIS Event Details]':
                in_event_details = True
                index += 1
                continue

            # Collect the header data with the name as the key and the variable
            # as the value.
            if not in_event_details:
                if not c.strip('\n') == '[ISIS Event Header]':
                    self._addHeaderLine(event_header, c)

            else:

                # If it's a snapshot then get the time. We know that the next
                # line is a file reference so get that too then skip ahead by
                # one line in the contents.
                if c.split('=')[0] == 'SnapshotTime':
                    index = self._addSnapshotLine(snapshot, contents, index)

                # If the line starts with a ';' then it's an IED file so grab
                # the name and get the file file reference from the next line
                # and skip ahead.
                elif c[:1] == ';':
                    index = self._addIedLine(ied_data, contents, index)

                # Otherwise just populate the event_details.
                else:
                    # If the description bit is included its at the end so just grab the
                    # last few line and put them in it.
                    if c.strip() == '[Description]':
                        index = self._loadDescription(description, contents,
                                                      index)
                        break
                    else:
                        if not c.strip() == '':
                            self._addDetailsLine(event_details, contents,
                                                 index)

            index += 1

        path_holder = filetools.PathHolder(file_path)
        ief_file = Ief(path_holder, event_header, event_details, snapshot,
                       ied_data, description)
        return ief_file
示例#5
0
    def loadFile(self, file_path, arg_dict={}):
        """Loads the ISIS .DAT file.

        Splits it into objects for each unit type, initial conditions etc.

        This is an epic if-else section for each unit type currently 
        represented.

        Needs cleaning up and writing with a bit more style.

        Easy to add another unit type, if it's not currently covered then it 
        will just be collected in the universal 'UnknownSection' and printed 
        back out the same as it came in.
        
        Args:
            file_path (str): path to the .dat file to load.
        
        Returns:
            units - UnitCollection containing the dat file units or False if 
                they couldn't be loaded.
        
        Raises:
            IOError: If the file cannot be loaded or is empty.
            AttributeError: if the file is not of an expected type (.dat/.ief).
        
        See Also:
            IsisUnitCollection
            FactoryClasses
        
        TODO: Decide if the observer style calls are ever going to be needed.
                If they aren't then remove them rather than have them
                cluttering up the file.
        """
        line = ''
        # Used to populate the data for the UnknownSection
        self.unknown_data = []
        # Composite for all dat units
        path_holder = ftools.PathHolder(file_path)
        self.units = DatCollection(path_holder)
        self.units.file_dir, self.units.filename = os.path.split(file_path)
        self.units.filename = os.path.splitext(self.units.filename)[0]

        if not uf.checkFileType(file_path, ext=['.dat', '.DAT']):
            if not uf.checkFileType(file_path, ext=['.ied', '.IED']):
                logger.error(
                    'Illegal File Error: ' + file_path +
                    '\nDoes not have extension (.dat, .DAT, .ied, .IED)')
                raise AttributeError(
                    'Illegal File Error: ' + file_path +
                    '\nDoes not have extension (.dat, .DAT, .ied, .IED)')
            else:
                self.is_ied = True

        if (self.__loadFile(file_path) == False):
            raise IOError('Unable to load file at: ' + file_path)

        # 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 = IsisUnitFactory()

        # 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.createUnit(
                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 UnknownSection then create an reset
                if (in_unknown_section == True):
                    self.createUnknownSection()
                    self.updateSubContents()

                    # Reset the reach for the UnknownSection
                    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)
                '''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