Example #1
0
def import_las(files_list, wells_dir):
    """
    Looks if well with appropriate name (name from las file) is in maincotext
      then parses this las file into this well
    else if there is no appropriate well
      then creates new well and parse las file into this well
    :param wells_dir: target dir to import in
    :type files_list: list of files paths
    """
    log.debug("i'm in import_las()")
    broken_files = str()

    for file_name in files_list:
        try:
            las = lasio.read(file_name)
            if las["DEPT"] is None:
                log.debug('las["DEPT"]={0}'.format(las["DEPT"]))
                raise ValueError('las file has no DEPT curve')
            # log.debug(las.well['WELL'].value)
            if all(str(las.well['WELL'].value) != well.name for well in main_context.wells_list):
                well = Well(str(las.well['WELL'].value))
                well.las = las
                main_context.wells_list.append(well)
                wells_dir.add_well(well)
            else:
                well_dict = {well.name: well for well in main_context.wells_list}
                well = well_dict.get(str(las.well['WELL'].value))
                assert well, well_dict
                well.las = las
        except Exception:
            broken_files += file_name + '\n'

    return broken_files
Example #2
0
 def read_head(self, lines):
     """ submethod for reading las file head information """
     try:
         self.name = re.search(r'# WELL NAME:\s*(?P<well_name>\S+)',
                               lines[1]).group('well_name')
         self.head_x = float(
             re.search(
                 r'# WELL HEAD X-COORDINATE:\s*(?P<head_x>[-+]?\d+\.\d+)',
                 lines[2]).group('head_x'))
         self.head_y = float(
             re.search(
                 r'# WELL HEAD Y-COORDINATE:\s*(?P<head_y>[-+]?\d+\.\d+)',
                 lines[3]).group('head_y'))
         self.offset = float(
             re.search(
                 r'# WELL OFFSET \(from MSL\):\s*(?P<offset>[-+]?\d+\.\d+)',
                 lines[4]).group('offset'))
         log.debug(
             'name={0}\t head_x={1}\t head_y={2}\t offset={3}'.
             format(self.name, self.head_x, self.head_y,
                    self.offset))
     except AttributeError as ex:
         log.warning(str(ex))
         return False
     return True
Example #3
0
def import_dev(files_list, wells_dir):
    """
    Looks if well with appropriate name (name from dev file) is in maincotext
      then parses this dev file into this well
    else if there is no appropriate well
      then creates new well and parse dev file into this well
    :param wells_dir: target dir to import to
    :param files_list: list of files paths
    """
    log.debug("i'm in import_dev()")
    broken_files = str()

    for file_name in files_list:
        well = Well()
        if not well.read_dev(file_name):
            broken_files += file_name + '\n'
            continue

        well_names = [well_in_list.name for well_in_list in main_context.wells_list]
        if well.name not in well_names:
            main_context.wells_list.append(well)
            wells_dir.add_well(well)

        else:
            exist_well = main_context.wells_list[well_names.index(well.name)]
            exist_well.read_dev(file_name)
    return broken_files
Example #4
0
    def on_actionImport_triggered(self, qt_invoker):
        """ executes from context menu
        :param qt_invoker: item where was context menu invoked
        """
        files_list, files_type = QFileDialog.getOpenFileNames(
            self, "Select one or more files to open", Config.default_dir_path,
            "dev files *.dev(*.dev);; las files *.las(*.las);; WellTops file *.txt(*.txt)"
        )

        log.debug("files_type = {0} \tfiles_list = {1}".format(
            files_type, files_list))

        func = {
            "dev files *.dev(*.dev)": imports.import_dev,
            " las files *.las(*.las)": imports.import_las,
            " WellTops file *.txt(*.txt)": imports.import_well_tops
        }.get(files_type)

        if not func:
            return

        broken_files = str()
        if not isinstance(qt_invoker, QTreeWidgetItem):
            broken_files = func(files_list, main_context.root_dir)
        else:
            broken_files = func(files_list, qt_invoker.source)

        if broken_files and len(broken_files) > 0:
            QMessageBox.warning(self, "Warning",
                                "Following files are broken:\n" + broken_files)

        self.reset_content()
Example #5
0
def import_well_tops(files_list, wells_dir):
    """
    If there is well with appropriate name (name from tops file)
    then add this top to this well
    else ignore this top
    :type files_list: list of files paths
    """
    log.debug("i'm in import_well_tops()")
    broken_files = str()

    for file_name in files_list:
        try:
            f = open(file_name)
            lines = f.readlines()

            well_names = [well_in_list.name for well_in_list in main_context.wells_list]

            if not re.match(r'[-+]?\d+\.\d+', lines[0].split()[2]):
                lines.remove(lines[0])

            try:
                for line in lines:
                    m = re.match('\s*(?P<well_name>\S+)\s+(?P<surface_id>\S+)\s+(?P<md>[-+]?\d+\.\d+)\s*', line)
                    if not m:
                        log.warning('not match: %s' % line)
                        broken_files += file_name + '\n'
                        continue

                    well_name, surface_id, md = m.groups()

                    top = Top(well_name=well_name, surface_id=surface_id, md=float(md))
                    if top.well_name in well_names:
                        well = main_context.wells_list[well_names.index(top.well_name)]
                        if well.add_top(top):
                            top.add_well(well)
                            main_context.tops_list.append(top)
                            top.calculate_addition_fields()
            except ValueError as ex:
                log.error(line + '  ' + str(ex))
                broken_files += file_name + '\n'
        except Exception:
            broken_files += file_name + '\n'
    return broken_files
Example #6
0
    def read_dev(self, dev_file):
        """ reads las file using the following parser
        :param dev_file: path to target file
        """
        try:
            f = open(dev_file, 'r')
            lines = f.readlines()

            # check for file length validity
            if len(lines) < 17:
                log.warning('Too short file: "%s"' % dev_file)
                return False

            def read_head(self, lines):
                """ submethod for reading las file head information """
                try:
                    self.name = re.search(r'# WELL NAME:\s*(?P<well_name>\S+)',
                                          lines[1]).group('well_name')
                    self.head_x = float(
                        re.search(
                            r'# WELL HEAD X-COORDINATE:\s*(?P<head_x>[-+]?\d+\.\d+)',
                            lines[2]).group('head_x'))
                    self.head_y = float(
                        re.search(
                            r'# WELL HEAD Y-COORDINATE:\s*(?P<head_y>[-+]?\d+\.\d+)',
                            lines[3]).group('head_y'))
                    self.offset = float(
                        re.search(
                            r'# WELL OFFSET \(from MSL\):\s*(?P<offset>[-+]?\d+\.\d+)',
                            lines[4]).group('offset'))
                    log.debug(
                        'name={0}\t head_x={1}\t head_y={2}\t offset={3}'.
                        format(self.name, self.head_x, self.head_y,
                               self.offset))
                except AttributeError as ex:
                    log.warning(str(ex))
                    return False
                return True

            # reads the head information
            if not read_head(self, lines):
                return False, '*.dev file header format not valid'

            # reads the list of available columns
            columns = re.findall(r'\s*(\b\w+)\s*', lines[13])
            columns = [column.lower() for column in columns]
            for column in columns:
                getattr(self, column).clear()

            log.debug('columns=' + str(columns))

            # reads coordinates information by each column
            for line in lines[15:]:
                values = re.findall(r'\s*([-+]?\d+\.\d+)\s*', line)
                for i in range(len(columns)):
                    getattr(self, columns[i]).append(float(values[i]))

            self.check_coordinate_columns_validity(
            )  # verify validity of the columns coordinates
        except Exception as ex:
            log.error(str(ex))
            return False
        return True
Example #7
0
    def on_actionSpreadsheet_triggered(self, qt_invoker):
        """ executes from context menu
        :param qt_invoker: item where was context menu invoked
        """
        log.debug('action spreadsheet')

        if qt_invoker.UserType == 'well' and qt_invoker.text(1) != 'needs dev':
            text = \
                'well_name = {0}\n' \
                'head_x = {1}\n' \
                'head_y = {2}\n' \
                'offset = {3}\n' \
                '#======================================================================================================================================\n' \
                '      MD              X              Y             Z           TVD           DX           DY          AZIM          INCL          DLS\n' \
                '#======================================================================================================================================\n' \
                ''.format(qt_invoker.source.name, qt_invoker.source.head_x, qt_invoker.source.head_y,
                          qt_invoker.source.offset)
            for i in range(len(qt_invoker.source.md)):
                text += ' {0:0<12}   {1:0<12} {2:0<12} {3:0<12} {4:0<12} {5:0<12} {6:0<12} {7:0<12} {8:0<12} {9:0<12}\n'.format(
                    qt_invoker.source.md[i], qt_invoker.source.x[i],
                    qt_invoker.source.y[i], qt_invoker.source.z[i],
                    qt_invoker.source.tvd[i], qt_invoker.source.dx[i],
                    qt_invoker.source.dy[i], qt_invoker.source.azim[i],
                    qt_invoker.source.incl[i], qt_invoker.source.dls[i])

            layout = QtWidgets.QVBoxLayout(self)
            qt_text_edit = QtWidgets.QTextEdit(self)
            qt_text_edit.setReadOnly(True)
            qt_text_edit.setCurrentFont(QtGui.QFont("Liberation Mono", 10))
            layout.addWidget(qt_text_edit)
            qt_text_edit.setText(text)

            qt_dialog = QtWidgets.QDialog(self)
            qt_dialog.setWindowTitle('Spreadsheet')
            qt_dialog.setLayout(layout)
            qt_dialog.setMinimumWidth(1100)
            qt_dialog.setMinimumHeight(600)
            qt_dialog.show()

        if qt_invoker.UserType == 'tops_dir':
            well = qt_invoker.parent().source

            if len(well.tops_list) < 1:
                return

            text = 'Well       Surface_id      MD\n'
            for top in well.tops_list:
                text += '{0:<10} {1:<15} {2:<f}\n'.format(
                    top.well_name, top.surface_id, top.md)

            layout = QtWidgets.QVBoxLayout(self)
            qt_text_edit = QtWidgets.QTextEdit(self)
            qt_text_edit.setReadOnly(True)
            qt_text_edit.setCurrentFont(QtGui.QFont("Liberation Mono", 10))
            layout.addWidget(qt_text_edit)
            qt_text_edit.setText(text)

            qt_dialog = QtWidgets.QDialog(self)
            qt_dialog.setWindowTitle('Spreadsheet')
            qt_dialog.setLayout(layout)
            qt_dialog.setMinimumWidth(330)
            qt_dialog.setMinimumHeight(180)
            qt_dialog.show()

        if qt_invoker.UserType == 'curves_dir':
            well = qt_invoker.parent().source

            if not well.las:
                return
            text = StringIO()

            well.las.write(text, version=2.0, fmt="%10.5f")
            layout = QtWidgets.QVBoxLayout(self)
            qt_text_edit = QtWidgets.QTextEdit(self)
            qt_text_edit.setReadOnly(True)
            qt_text_edit.setCurrentFont(QtGui.QFont("Liberation Mono", 10))
            layout.addWidget(qt_text_edit)
            qt_text_edit.setText(text.getvalue())

            qt_dialog = QtWidgets.QDialog(self)
            qt_dialog.setWindowTitle('Spreadsheet')
            qt_dialog.setLayout(layout)
            qt_dialog.setMinimumWidth(1000)
            qt_dialog.setMinimumHeight(500)
            qt_dialog.show()
Example #8
0
    def check_changed(self, item, column):
        """ executes when some item in tree widget changed their state
        :param column: column where item state was changed
        :param item: item which state was changed
        """
        self.blockSignals(True)

        # not mark signal
        if item.checkState(0) == item.previous_state:
            return

        item.previous_state = item.checkState(0)
        log.debug('type="{0}"  name="{1}  signal={2}"'.format(
            item.UserType, item.text(0), item.previous_state))

        if item.UserType == 'wells_dir':

            def mark_sub_items(item):
                children = [item.child(i) for i in range(item.childCount())]
                for child in children:
                    if child.UserType == 'well':
                        child.setCheckState(0, item.checkState(0))
                        child.previous_state = item.checkState(0)
                        continue

                    if child.UserType == 'wells_dir':
                        child.setCheckState(0, item.checkState(0))
                        child.previous_state = item.checkState(0)
                        mark_sub_items(child)

            mark_sub_items(item)

        elif item.UserType == 'curve_aliases_dir':
            state = item.checkState(0)
            item = item.parent()

            def mark_sub_items(item):
                children = [item.child(i) for i in range(item.childCount())]
                for child in children:
                    if child.UserType in ['curve_alias', 'curve']:
                        child.setCheckState(0, state)
                        child.previous_state = state
                        continue
                    if child.UserType in ['curve_aliases_dir', 'curves_dir']:
                        child.setCheckState(0, state)
                        child.previous_state = state
                        mark_sub_items(child)
                        continue
                    if child.UserType in ['wells_dir', 'well']:
                        mark_sub_items(child)

            mark_sub_items(item)

        elif item.UserType == 'top_aliases_dir':
            state = item.checkState(0)
            item = item.parent()

            def mark_sub_items(item):
                children = [item.child(i) for i in range(item.childCount())]
                for child in children:
                    if child.UserType in ['top_alias', 'top']:
                        child.setCheckState(0, state)
                        child.previous_state = state
                        continue
                    if child.UserType in ['top_aliases_dir', 'tops_dir']:
                        child.setCheckState(0, state)
                        child.previous_state = state
                        mark_sub_items(child)
                        continue
                    if child.UserType in ['wells_dir', 'well']:
                        mark_sub_items(child)

            mark_sub_items(item)

        elif item.UserType == 'curve_alias':
            state = item.checkState(0)
            name = item.text(0)
            item = item.parent().parent()

            def mark_sub_items(item):
                children = [item.child(i) for i in range(item.childCount())]
                for child in children:
                    if child.UserType in ['curve', 'curve_alias'
                                          ] and child.text(0) == name:
                        child.setCheckState(0, state)
                        child.previous_state = state
                        continue
                    if child.UserType in [
                            'wells_dir', 'well', 'curve_aliases_dir',
                            'curves_dir'
                    ]:
                        mark_sub_items(child)

            mark_sub_items(item)

        elif item.UserType == 'top_alias':
            state = item.checkState(0)
            name = item.text(0)
            item = item.parent().parent()

            def mark_sub_items(item):
                children = [item.child(i) for i in range(item.childCount())]
                for child in children:
                    if child.UserType in ['top', 'top_alias'
                                          ] and child.text(0) == name:
                        child.setCheckState(0, state)
                        child.previous_state = state
                        continue
                    if child.UserType in [
                            'wells_dir', 'well', 'top_aliases_dir', 'tops_dir'
                    ]:
                        mark_sub_items(child)

            mark_sub_items(item)

        elif item.UserType in ['curves_dir', 'tops_dir']:
            children = [item.child(i) for i in range(item.childCount())]
            for child in children:
                child.setCheckState(0, item.checkState(0))
                child.previous_state = item.checkState(0)

        self.window().tab_2d_map.refresh()
        self.window().tab_sections.reset()
        self.blockSignals(False)
Example #9
0
    def refresh(self):
        """ executes every time when there was checked new well or new top """
        self.ax.clear()
        self.ax.set_ylabel("y-axis (m)", color="white")
        self.ax.set_xlabel("x-axis (m)", color="white")
        self.ax.set_axis_bgcolor("black")
        self.ax.tick_params(color='white', labelcolor='white')
        for spine in self.ax.spines.values():
            spine.set_color('white')
        self.ax.tick_params(axis='both', which='major', labelsize=8)
        self.ax.grid(color="gray")

        y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
        self.ax.yaxis.set_major_formatter(y_formatter)

        # ----получаем два списка  x и y координат скважин----
        checked_wells = [
            well for well in main_context.wells_list
            if (well.qt_item.checkState(0) and len(well.md) > 0)
        ]
        wells_x_list = [well.x[-1] for well in checked_wells]
        wells_y_list = [well.y[-1] for well in checked_wells]
        wells_names = [well.name for well in checked_wells]
        log.debug("(fileName, x, y) = {0}".format(
            list(zip(wells_names, wells_x_list, wells_y_list))))

        self.ax.scatter(wells_x_list,
                        wells_y_list,
                        marker=".",
                        c="#666600",
                        edgecolors="#666600")

        for x, y, name in zip(wells_x_list, wells_y_list, wells_names):
            self.ax.annotate('{}'.format(name),
                             xy=(x, y),
                             color='yellow',
                             fontsize=10)

        # ----получаем два списка  x и y координат well_tops----
        checked_tops = [
            top for top in main_context.tops_list if top.qt_item.checkState(0)
        ]
        tops_x_list = [top.x for top in checked_tops]
        tops_y_list = [top.y for top in checked_tops]
        tops_names = [
            top.well_name + ' ' + top.surface_id for top in checked_tops
        ]

        self.ax.scatter(tops_x_list,
                        tops_y_list,
                        marker=".",
                        c="#89060D",
                        edgecolors="#89060D")

        for x, y, name in zip(tops_x_list, tops_y_list, tops_names):
            self.ax.annotate('{}'.format(name),
                             xy=(x, y),
                             color='red',
                             fontsize=10)

        # ---------------- масштабируем --------------------------
        x_list = wells_x_list + tops_x_list
        y_list = wells_y_list + tops_y_list

        x_min = min(x_list, default=0)
        x_max = max(x_list, default=1)
        delta_x = x_max - x_min

        y_min = min(y_list, default=0)
        y_max = max(y_list, default=1)
        delta_y = y_max - y_min

        delta_max = max([delta_x, delta_y])

        self.ax.set_xlim(
            [x_min - delta_max / 10, x_min + delta_max + delta_max / 10])
        self.ax.set_ylim(
            [y_min - delta_max / 10, y_min + delta_max + delta_max / 10])
        start, end = self.ax.get_xlim()
        self.ax.xaxis.set_ticks(np.linspace(start, end, 13))
        start, end = self.ax.get_ylim()
        self.ax.yaxis.set_ticks(np.linspace(start, end, 13))

        self.draw()