Exemplo n.º 1
0
    def setUp(self) -> None:
        self.mat_name = AequilibraeMatrix().random_name()
        self.g = Graph()
        self.g.load_from_disk(test_graph)
        self.g.set_graph(cost_field="distance")

        # Creates the matrix for assignment
        args = {
            "file_name": os.path.join(gettempdir(), self.mat_name),
            "zones": self.g.num_zones,
            "matrix_names": ["cars", "trucks"],
            "index_names": ["my indices"],
        }

        matrix = AequilibraeMatrix()
        matrix.create_empty(**args)

        matrix.index[:] = self.g.centroids[:]
        matrix.cars.fill(1.1)
        matrix.trucks.fill(2.2)

        # Exports matrix to OMX in order to have two matrices to work with
        matrix.export(os.path.join(gettempdir(), "my_matrix.omx"))
        matrix.close()
Exemplo n.º 2
0
    def save_skims(self, matrix_name: str, which_ones="final", format="omx") -> None:
        """Saves the skims (if any) to the skim folder and registers in the matrix list

        Args:
            name (:obj:`str`): Name of the matrix record to hold this matrix (same name used for file name)
            which_ones (:obj:`str`,optional): {'final': Results of the final iteration, 'blended': Averaged results for
            all iterations, 'all': Saves skims for both the final iteration and the blended ones} Default is 'final'
            *format* (:obj:`str`, `Optional`): File format ('aem' or 'omx'). Default is 'omx'
        """

        mat_format = format.lower()
        if mat_format not in ["omx", "aem"]:
            raise ValueError("Matrix needs to be either OMX or native AequilibraE")
        if mat_format == "omx" and not has_omx:
            raise ImportError("OpenMatrix is not available on your system")

        file_name = f"{matrix_name}.{mat_format}"

        mats = Matrices()
        export_name = path.join(mats.fldr, file_name)

        if path.isfile(export_name):
            raise FileExistsError(f"{file_name} already exists. Choose a different name or matrix format")

        if mats.check_exists(matrix_name):
            raise FileExistsError(f"{matrix_name} already exists. Choose a different name")

        avg_skims = self.classes[0].results.skims  # type: AequilibraeMatrix

        # The ones for the last iteration are here
        last_skims = self.classes[0]._aon_results.skims  # type: AequilibraeMatrix

        names = []
        if which_ones in ["final", "all"]:
            for core in last_skims.names:
                names.append(f"{core}_final")

        if which_ones in ["blended", "all"]:
            for core in avg_skims.names:
                names.append(f"{core}_blended")

        if not names:
            raise ValueError("No skims to save")
        # Assembling a single final skim file can be done like this
        # We will want only the time for the last iteration and the distance averaged out for all iterations
        working_name = export_name if mat_format == "aem" else AequilibraeMatrix().random_name()

        kwargs = {"file_name": working_name, "zones": self.classes[0].graph.centroids.shape[0], "matrix_names": names}

        # Create the matrix to manipulate
        out_skims = AequilibraeMatrix()
        out_skims.create_empty(**kwargs)

        out_skims.index[:] = self.classes[0].graph.centroids[:]
        out_skims.description = f"Assignment skim from procedure ID {self.procedure_id}"

        if which_ones in ["final", "all"]:
            for core in last_skims.names:
                out_skims.matrix[f"{core}_final"][:, :] = last_skims.matrix[core][:, :]

        if which_ones in ["blended", "all"]:
            for core in avg_skims.names:
                out_skims.matrix[f"{core}_blended"][:, :] = avg_skims.matrix[core][:, :]

        out_skims.matrices.flush()  # Make sure that all data went to the disk

        # If it were supposed to be an OMX, we export to one
        if mat_format == "omx":
            out_skims.export(export_name)

        # Now we create the appropriate record
        record = mats.new_record(matrix_name, file_name)
        record.procedure_id = self.procedure_id
        record.timestamp = self.procedure_date
        record.procedure = "Traffic Assignment"
        record.description = "Skimming for assignment procedure"
        record.save()
Exemplo n.º 3
0
class TestAequilibraeMatrix(TestCase):
    matrix = None

    def setUp(self) -> None:
        self.sf_skims = f"/Aequilibrae_matrix_{uuid.uuid4()}.omx"
        copyfile(siouxfalls_skims, self.sf_skims)
        temp_folder = gettempdir()
        self.name_test = temp_folder + f"/Aequilibrae_matrix_{uuid.uuid4()}.aem"
        self.copy_matrix_name = temp_folder + f"/Aequilibrae_matrix_{uuid.uuid4()}.aem"
        self.csv_export_name = temp_folder + f"/Aequilibrae_matrix_{uuid.uuid4()}.csv"
        self.omx_export_name = temp_folder + f"/Aequilibrae_matrix_{uuid.uuid4()}.omx"

        if self.matrix is not None:
            return
        args = {
            "file_name": self.name_test,
            "zones": zones,
            "matrix_names": ["mat", "seed", "dist"],
            "index_names": ["my indices"],
        }

        self.matrix = AequilibraeMatrix()
        self.matrix.create_empty(**args)

        self.matrix.index[:] = np.arange(self.matrix.zones) + 100
        self.matrix.mat[:, :] = np.random.rand(self.matrix.zones, self.matrix.zones)[:, :]
        self.matrix.mat[:, :] = self.matrix.mat[:, :] * (1000 / np.sum(self.matrix.mat[:, :]))
        self.matrix.setName("Test matrix - " + str(random.randint(1, 10)))
        self.matrix.setDescription("Generated at " + datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y"))
        self.new_matrix = self.matrix

    def tearDown(self) -> None:
        try:
            del self.matrix
            os.remove(self.name_test) if os.path.exists(self.name_test) else None
            os.remove(self.csv_export_name) if os.path.exists(self.csv_export_name) else None
            os.remove(self.copy_matrix_name) if os.path.exists(self.copy_matrix_name) else None
            os.remove(self.omx_export_name) if os.path.exists(self.omx_export_name) else None
        except Exception as e:
            print(f"Could not delete.  {e.args}")

    def test_load(self):
        self.new_matrix = AequilibraeMatrix()
        # Cannot load OMX file with no indices
        with self.assertRaises(LookupError):
            self.new_matrix.load(no_index_omx)

        self.new_matrix = AequilibraeMatrix()
        self.new_matrix.load(self.name_test)
        del self.new_matrix

    def test_computational_view(self):
        self.new_matrix.computational_view(["mat", "seed"])
        self.new_matrix.mat.fill(0)
        self.new_matrix.seed.fill(0)
        if self.new_matrix.matrix_view.shape[2] != 2:
            self.fail("Computational view returns the wrong number of matrices")

        self.new_matrix.computational_view(["mat"])
        self.new_matrix.matrix_view[:, :] = np.arange(zones ** 2).reshape(zones, zones)
        if np.sum(self.new_matrix.mat) != np.sum(self.new_matrix.matrix_view):
            self.fail("Assigning to matrix view did not work")
        self.new_matrix.setName("Test matrix - " + str(random.randint(1, 10)))
        self.new_matrix.setDescription("Generated at " + datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y"))
        del self.new_matrix

    def test_computational_view_with_omx(self):
        self.new_matrix = AequilibraeMatrix()
        self.new_matrix.load(omx_example)

        arrays = ["m1", "m2"]
        self.new_matrix.computational_view(arrays)
        total_mats = np.sum(self.new_matrix.matrix_view)

        self.new_matrix.computational_view([arrays[0]])
        total_m1 = np.sum(self.new_matrix.matrix_view)

        self.new_matrix.close()

        omx_file = omx.open_file(omx_example, "r")

        m1 = np.array(omx_file["m1"]).sum()
        m2 = np.array(omx_file["m2"]).sum()

        self.assertEqual(m1 + m2, total_mats)
        self.assertEqual(m1, total_m1)

        omx_file.close()
        del omx_file

    def test_copy(self):
        # test in-memory matrix_procedures copy

        matrix_copy = self.new_matrix.copy(self.copy_matrix_name, cores=["mat"])

        if not np.array_equal(matrix_copy.mat, self.new_matrix.mat):
            self.fail("Matrix copy was not perfect")
        matrix_copy.close()
        del matrix_copy

    def test_export_to_csv(self):
        self.new_matrix.export(self.csv_export_name)
        df = pd.read_csv(self.csv_export_name)
        df.fillna(0, inplace=True)
        self.assertEqual(df.shape[0], 2500, "Exported wrong size")
        self.assertEqual(df.shape[1], 5, "Exported wrong size")
        self.assertAlmostEqual(df.mat.sum(), np.nansum(self.new_matrix.matrices), 5, "Exported wrong matrix total")

    def test_export_to_omx(self):
        self.new_matrix.export(self.omx_export_name)

        omxfile = omx.open_file(self.omx_export_name, "r")

        # Check if matrices values are compatible
        for m in self.new_matrix.names:
            sm = np.nansum(self.new_matrix.matrix[m])
            sm2 = np.nansum(np.array(omxfile[m]))

            self.assertEqual(sm, sm2, "Matrix {} was exported with the wrong value".format(m))
        del omxfile

    def test_nan_to_num(self):
        m = self.new_matrix.mat.sum() - self.new_matrix.mat[1, 1]
        self.new_matrix.computational_view(["mat", "seed"])
        self.new_matrix.nan_to_num()
        self.new_matrix.mat[1, 1] = np.nan
        self.new_matrix.computational_view(["mat"])
        self.new_matrix.nan_to_num()

        if abs(m - self.new_matrix.mat.sum()) > 0.000000000001:
            self.fail("Total for mat matrix not maintained")
        del self.new_matrix

    def test_copy_from_omx(self):
        temp_file = AequilibraeMatrix().random_name()
        a = AequilibraeMatrix()
        a.create_from_omx(temp_file, omx_example)

        omxfile = omx.open_file(omx_example, "r")

        # Check if matrices values are compatible
        for m in ["m1", "m2", "m3"]:
            sm = a.matrix[m].sum()
            sm2 = np.array(omxfile[m]).sum()
            if sm != sm2:
                self.fail("Matrix {} was copied with the wrong value".format(m))

        if np.any(a.index[:] != np.array(list(omxfile.mapping("taz").keys()))):
            self.fail("Index was not created properly")
        a.close()
        del a
        del omxfile

    def test_copy_from_omx_long_name(self):

        temp_file = AequilibraeMatrix().random_name()
        a = AequilibraeMatrix()

        with self.assertRaises(ValueError):
            a.create_from_omx(temp_file, omx_example, robust=False)
        del a

    def test_copy_omx_wrong_content(self):
        # Check if we get a result if we try to copy non-existing cores
        temp_file = AequilibraeMatrix().random_name()
        a = AequilibraeMatrix()

        with self.assertRaises(ValueError):
            a.create_from_omx(temp_file, omx_example, cores=["m1", "m2", "m3", "m4"])

        with self.assertRaises(ValueError):
            a.create_from_omx(temp_file, omx_example, mappings=["wrong index"])
        del a

    def test_get_matrix(self):
        a = AequilibraeMatrix()
        a.load(self.sf_skims)

        with self.assertRaises(AttributeError):
            a.get_matrix("does not exist")

        q = a.get_matrix("distance")
        self.assertEqual(q.shape[0], 24)

        a = AequilibraeMatrix()
        a.load(self.name_test)
        print(np.array_equal(a.get_matrix("seed"), a.matrix["seed"]))

        del a

    def test_save(self):
        a = AequilibraeMatrix()
        a.load(self.sf_skims)

        a.computational_view(["distance"])
        new_mat = np.random.rand(a.zones, a.zones)
        a.matrix_view *= new_mat

        res = a.matrix_view.sum()

        a.save("new_name_for_matrix")
        self.assertEqual(res, a.matrix_view.sum(), "Saved wrong result")

        a.save(["new_name_for_matrix2"])
        self.assertEqual(a.view_names[0], "new_name_for_matrix2", "Did not update computational view")
        self.assertEqual(len(a.view_names), 1, "computational view with the wrong number of matrices")

        a.computational_view(["distance", "new_name_for_matrix"])

        with self.assertRaises(ValueError):
            a.save(["just_one_name"])

        a.save(["one_name", "two_names"])

        with self.assertRaises(ValueError):
            a.save("distance")

        b = AequilibraeMatrix()
        b.load(self.name_test)
        b.computational_view("seed")
        b.save()
        b.computational_view(["mat", "seed", "dist"])
        b.save()
Exemplo n.º 4
0
    def produce_all_outputs(self):
        fn = os.path.join(self.output_path, "skims.aem")

        fn_omx = os.path.join(self.output_path, "skims.omx")
        if self.cb_choose_algorithm.currentText() == 'all-or-nothing':
            cls = [x for x in self.traffic_classes.values()
                   if x is not None][0]
            cls.results.save_to_disk(os.path.join(
                self.output_path, f"link_flows_{cls.graph.mode}.csv"),
                                     output="loads")
            cls.results.save_to_disk(os.path.join(
                self.output_path, f"link_flows_{cls.graph.mode}.aed"),
                                     output="loads")
            if has_omx:
                cls.results.skims.export(fn_omx)
            else:
                cls.results.skims.export(fn)
            return

        table = self.skim_list_table
        skim_names = []
        for i in range(table.rowCount()):
            mode = self.all_modes[table.item(i, 0).text()]
            field = table.item(i, 1).text()
            last_iter = table.cellWidget(i, 2).isChecked()
            blended = table.cellWidget(i, 3).isChecked()
            if last_iter:
                skim_names.append(f'{field}_{mode}_final')
            if blended:
                skim_names.append(f'{field}_{mode}_blended')

        for cls in self.assignment.classes:
            cls.results.save_to_disk(os.path.join(
                self.output_path, f"link_flows_{cls.graph.mode}.csv"),
                                     output="loads")
            cls.results.save_to_disk(os.path.join(
                self.output_path, f"link_flows_{cls.graph.mode}.aed"),
                                     output="loads")

        # cls.results.skims.export(os.path.join(self.output_path, f'blended_skims_{cls.graph.mode}.aed'))
        if skim_names:
            args = {
                'file_name': fn,
                'zones': self.project.network.count_centroids(),
                'matrix_names': skim_names
            }
            skims = AequilibraeMatrix()
            skims.create_empty(**args)

            for i in range(table.rowCount()):
                mode_name = table.item(i, 0).text()
                mode = self.all_modes[mode_name]
                field = table.item(i, 1).text()
                last_iter = table.cellWidget(i, 2).isChecked()
                blended = table.cellWidget(i, 3).isChecked()

                cls = self.traffic_classes[mode_name]

                if last_iter:
                    mat_name = f'{field}_{mode}_final'
                    skims.matrix[
                        mat_name][:, :] = cls._aon_results.skims.matrix[
                            field][:, :]
                if blended:
                    mat_name = f'{field}_{mode}_blended'
                    skims.matrix[mat_name][:, :] = cls.results.skims.matrix[
                        field][:, :]

            skims.index[:] = cls.matrix.index[:]
            if has_omx:
                skims.export(fn_omx)
                skims.close()
                del skims
                os.unlink(fn)
Exemplo n.º 5
0
class TestAequilibraeMatrix(TestCase):
    def test___init__(self):
        os.remove(name_test) if os.path.exists(name_test) else None
        args = {'file_name': name_test,
                'zones': zones,
                'matrix_names': ['mat', 'seed', 'dist'],
                'index_names': ['my indices']}

        matrix = AequilibraeMatrix()
        matrix.create_empty(**args)

        matrix.index[:] = np.arange(matrix.zones) + 100
        matrix.mat[:, :] = np.random.rand(matrix.zones, matrix.zones)[:, :]
        matrix.mat[:, :] = matrix.mat[:, :] * (1000 / np.sum(matrix.mat[:, :]))
        matrix.setName('Test matrix - ' + str(random.randint(1, 10)))
        matrix.setDescription('Generated at ' + datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y"))
        matrix.close(True)
        del (matrix)

    def test_load(self):
        # self.test___init__()
        self.new_matrix = AequilibraeMatrix()
        self.new_matrix.load(name_test)

    def test_computational_view(self):
        self.test_load()
        self.new_matrix.computational_view(['mat', 'seed'])
        self.new_matrix.mat.fill(0)
        self.new_matrix.seed.fill(0)
        if self.new_matrix.matrix_view.shape[2] != 2:
            self.fail('Computational view returns the wrong number of matrices')

        self.new_matrix.computational_view(['mat'])
        self.new_matrix.matrix_view[:, :] = np.arange(zones ** 2).reshape(zones, zones)
        if np.sum(self.new_matrix.mat) != np.sum(self.new_matrix.matrix_view):
            self.fail('Assigning to matrix view did not work')
        self.new_matrix.setName('Test matrix - ' + str(random.randint(1, 10)))
        self.new_matrix.setDescription('Generated at ' + datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y"))
        self.new_matrix.close(True)

    def test_copy(self):
        self.test_load()

        # test in-memory matrix_procedures copy

        matrix_copy = self.new_matrix.copy(copy_matrix_name, cores=['mat'])

        if not np.array_equal(matrix_copy.mat, self.new_matrix.mat):
            self.fail('Matrix copy was not perfect')
        matrix_copy.close(True)
        self.new_matrix.close(True)

    def test_export(self):
        self.test_load()
        self.new_matrix.export(csv_export_name)
        self.new_matrix.close(True)

    def test_nan_to_num(self):
        self.test_load()
        s = self.new_matrix.seed.sum() - self.new_matrix.seed[1, 1]
        m = self.new_matrix.mat.sum() - self.new_matrix.mat[1, 1]
        self.new_matrix.seed[1,1] = np.nan
        self.new_matrix.computational_view(['mat', 'seed'])
        self.new_matrix.nan_to_num()
        self.new_matrix.mat[1,1] = np.nan
        self.new_matrix.computational_view(['mat'])
        self.new_matrix.nan_to_num()

        if s != self.new_matrix.seed.sum():
            self.fail('Total for seed matrix not maintained')

        if m != self.new_matrix.mat.sum():
            self.fail('Total for mat matrix not maintained')
class TestAequilibraeMatrix(TestCase):
    def test___init__(self):
        os.remove(name_test) if os.path.exists(name_test) else None
        args = {
            "file_name": name_test,
            "zones": zones,
            "matrix_names": ["mat", "seed", "dist"],
            "index_names": ["my indices"],
        }

        matrix = AequilibraeMatrix()
        matrix.create_empty(**args)

        matrix.index[:] = np.arange(matrix.zones) + 100
        matrix.mat[:, :] = np.random.rand(matrix.zones, matrix.zones)[:, :]
        matrix.mat[:, :] = matrix.mat[:, :] * (1000 / np.sum(matrix.mat[:, :]))
        matrix.setName("Test matrix - " + str(random.randint(1, 10)))
        matrix.setDescription(
            "Generated at " +
            datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y"))
        matrix.close()
        del matrix

    def test_load(self):
        # self.test___init__()
        self.new_matrix = AequilibraeMatrix()
        # Cannot load OMX file with no indices
        with self.assertRaises(LookupError):
            self.new_matrix.load(no_index_omx)

        self.new_matrix = AequilibraeMatrix()
        self.new_matrix.load(name_test)

    def test_computational_view(self):
        self.test_load()
        self.new_matrix.computational_view(["mat", "seed"])
        self.new_matrix.mat.fill(0)
        self.new_matrix.seed.fill(0)
        if self.new_matrix.matrix_view.shape[2] != 2:
            self.fail(
                "Computational view returns the wrong number of matrices")

        self.new_matrix.computational_view(["mat"])
        self.new_matrix.matrix_view[:, :] = np.arange(zones**2).reshape(
            zones, zones)
        if np.sum(self.new_matrix.mat) != np.sum(self.new_matrix.matrix_view):
            self.fail("Assigning to matrix view did not work")
        self.new_matrix.setName("Test matrix - " + str(random.randint(1, 10)))
        self.new_matrix.setDescription(
            "Generated at " +
            datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y"))
        self.new_matrix.close()

    def test_computational_view_with_omx(self):
        self.new_matrix = AequilibraeMatrix()
        self.new_matrix.load(omx_example)

        arrays = ["m1", "m2"]
        self.new_matrix.computational_view(arrays)
        total_mats = np.sum(self.new_matrix.matrix_view)

        self.new_matrix.computational_view([arrays[0]])
        total_m1 = np.sum(self.new_matrix.matrix_view)

        self.new_matrix.close()

        omx_file = omx.open_file(omx_example, "r")

        m1 = np.array(omx_file["m1"]).sum()
        m2 = np.array(omx_file["m2"]).sum()

        self.assertEqual(m1 + m2, total_mats)
        self.assertEqual(m1, total_m1)

        omx_file.close()

    def test_copy(self):
        self.test_load()

        # test in-memory matrix_procedures copy

        matrix_copy = self.new_matrix.copy(copy_matrix_name, cores=["mat"])

        if not np.array_equal(matrix_copy.mat, self.new_matrix.mat):
            self.fail("Matrix copy was not perfect")
        matrix_copy.close()
        self.new_matrix.close()

    def test_export_to_csv(self):
        self.test_load()
        self.new_matrix.export(csv_export_name)
        self.new_matrix.close()

    def test_export_to_omx(self):
        self.test_load()
        self.new_matrix.export(omx_export_name)

        omxfile = omx.open_file(omx_export_name, "r")

        # Check if matrices values are compatible
        for m in self.new_matrix.names:
            sm = np.nansum(self.new_matrix.matrix[m])
            sm2 = np.nansum(np.array(omxfile[m]))

            self.assertEqual(
                sm, sm2,
                "Matrix {} was exported with the wrong value".format(m))

        self.new_matrix.close()

    def test_nan_to_num(self):
        self.test_load()
        s = self.new_matrix.seed.sum() - self.new_matrix.seed[1, 1]
        m = self.new_matrix.mat.sum() - self.new_matrix.mat[1, 1]
        self.new_matrix.seed[1, 1] = np.nan
        self.new_matrix.computational_view(["mat", "seed"])
        self.new_matrix.nan_to_num()
        self.new_matrix.mat[1, 1] = np.nan
        self.new_matrix.computational_view(["mat"])
        self.new_matrix.nan_to_num()

        if s != self.new_matrix.seed.sum():
            self.fail("Total for seed matrix not maintained")

        if m != self.new_matrix.mat.sum():
            self.fail("Total for mat matrix not maintained")

    def test_copy_from_omx(self):
        temp_file = AequilibraeMatrix().random_name()
        a = AequilibraeMatrix()
        a.create_from_omx(temp_file, omx_example)

        omxfile = omx.open_file(omx_example, "r")

        # Check if matrices values are compatible
        for m in ["m1", "m2", "m3"]:
            sm = a.matrix[m].sum()
            sm2 = np.array(omxfile[m]).sum()
            if sm != sm2:
                self.fail(
                    "Matrix {} was copied with the wrong value".format(m))

        if np.any(a.index[:] != np.array(list(omxfile.mapping("taz").keys()))):
            self.fail("Index was not created properly")
        a.close()

    def test_copy_from_omx_long_name(self):

        temp_file = AequilibraeMatrix().random_name()
        a = AequilibraeMatrix()

        with self.assertRaises(ValueError):
            a.create_from_omx(temp_file, omx_example, robust=False)

    def test_copy_omx_wrong_content(self):
        # Check if we get a result if we try to copy non-existing cores
        temp_file = AequilibraeMatrix().random_name()
        a = AequilibraeMatrix()

        with self.assertRaises(ValueError):
            a.create_from_omx(temp_file,
                              omx_example,
                              cores=["m1", "m2", "m3", "m4"])

        with self.assertRaises(ValueError):
            a.create_from_omx(temp_file, omx_example, mappings=["wrong index"])
class DisplayAequilibraEFormatsDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, iface):
        QtWidgets.QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)

        self.error = None

        self.error = None
        self.data_path, self.data_type = GetOutputFileName(
            self, 'AequilibraE custom formats',
            ["Aequilibrae dataset(*.aed)", "Aequilibrae matrix(*.aem)"],
            '.aed', standard_path())

        if self.data_type is None:
            self.error = 'Path provided is not a valid dataset'
            self.exit_with_error()

        self.data_type = self.data_type.upper()

        if self.data_type == 'AED':
            self.data_to_show = AequilibraEData()
        elif self.data_type == 'AEM':
            self.data_to_show = AequilibraeMatrix()

        try:
            self.data_to_show.load(self.data_path)
        except:
            self.error = 'Could not load dataset'
            self.exit_with_error()

        # Elements that will be used during the displaying
        self._layout = QVBoxLayout()
        self.table = QTableView()
        self._layout.addWidget(self.table)

        # Settings for displaying
        self.show_layout = QHBoxLayout()

        # Thousand separator
        self.thousand_separator = QCheckBox()
        self.thousand_separator.setChecked(True)
        self.thousand_separator.setText('Thousands separator')
        self.thousand_separator.toggled.connect(self.format_showing)
        self.show_layout.addWidget(self.thousand_separator)

        self.spacer = QSpacerItem(5, 0, QtWidgets.QSizePolicy.Expanding,
                                  QtWidgets.QSizePolicy.Minimum)
        self.show_layout.addItem(self.spacer)

        # Decimals
        txt = QLabel()
        txt.setText('Decimal places')
        self.show_layout.addWidget(txt)
        self.decimals = QSpinBox()
        self.decimals.valueChanged.connect(self.format_showing)
        self.decimals.setMinimum(0)
        self.decimals.setValue(4)
        self.decimals.setMaximum(10)

        self.show_layout.addWidget(self.decimals)
        self._layout.addItem(self.show_layout)

        # differentiates between matrix and dataset
        if self.data_type == 'AEM':
            self.data_to_show.computational_view([self.data_to_show.names[0]])
            # Matrices need cores and indices to be set as well
            self.mat_layout = QHBoxLayout()
            self.mat_list = QComboBox()
            for n in self.data_to_show.names:
                self.mat_list.addItem(n)

            self.mat_list.currentIndexChanged.connect(self.change_matrix_cores)
            self.mat_layout.addWidget(self.mat_list)

            self.idx_list = QComboBox()
            for i in self.data_to_show.index_names:
                self.idx_list.addItem(i)
            self.idx_list.currentIndexChanged.connect(self.change_matrix_cores)
            self.mat_layout.addWidget(self.idx_list)
            self._layout.addItem(self.mat_layout)
            self.change_matrix_cores()

        self.but_export = QPushButton()
        self.but_export.setText('Export')
        self.but_export.clicked.connect(self.export)

        self.but_close = QPushButton()
        self.but_close.clicked.connect(self.exit_procedure)
        self.but_close.setText('Close')

        self.but_layout = QHBoxLayout()
        self.but_layout.addWidget(self.but_export)
        self.but_layout.addWidget(self.but_close)

        self._layout.addItem(self.but_layout)

        # We chose to use QTableView. However, if we want to allow the user to edit the dataset
        # The we need to allow them to switch to the slower QTableWidget
        # Code below

        # self.table = QTableWidget(self.data_to_show.entries, self.data_to_show.num_fields)
        # self.table.setHorizontalHeaderLabels(self.data_to_show.fields)
        # self.table.setObjectName('data_viewer')
        #
        # self.table.setVerticalHeaderLabels([str(x) for x in self.data_to_show.index[:]])
        # self.table.clearContents()
        #
        # for i in range(self.data_to_show.entries):
        #     for j, f in enumerate(self.data_to_show.fields):
        #         item1 = QTableWidgetItem(str(self.data_to_show.data[f][i]))
        #         item1.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
        #         self.table.setItem(i, j, item1)

        self.resize(700, 500)
        self.setLayout(self._layout)
        self.format_showing()

    def format_showing(self):
        decimals = self.decimals.value()
        separator = self.thousand_separator.isChecked()
        if isinstance(self.data_to_show, AequilibraeMatrix):
            m = NumpyModel(self.data_to_show, separator, decimals)
        else:
            m = DatabaseModel(self.data_to_show, separator, decimals)
        self.table.clearSpans()
        self.table.setModel(m)

    def change_matrix_cores(self):
        self.data_to_show.computational_view([self.mat_list.currentText()])
        self.data_to_show.set_index(self.data_to_show.index_names[0])
        self.format_showing()

    def export(self):
        new_name, file_type = GetOutputFileName(
            self, self.data_type, ["Comma-separated file(*.csv)"], ".csv",
            self.data_path)
        if new_name is not None:
            self.data_to_show.export(new_name)

    def exit_with_error(self):
        qgis.utils.iface.messageBar().pushMessage("Error:",
                                                  self.error,
                                                  level=1)
        self.exit_procedure()

    def exit_procedure(self):
        self.close()