Exemple #1
0
def test_load_model_df():

    verbose = True
    df_i = pn.DataFrame(np.random.randn(6, 3), columns='X Y Z'.split())
    df_i['formation'] = ['surface_1'
                         for _ in range(3)] + ['surface_2' for _ in range(3)]

    df_o = pn.DataFrame(np.random.randn(6, 6),
                        columns='X Y Z azimuth dip polarity'.split())
    df_o['formation'] = ['surface_1'
                         for _ in range(3)] + ['surface_2' for _ in range(3)]

    geo_model = gp.create_model('test')
    # Importing the data directly from the dataframes
    gp.init_data(geo_model, [0, 2000., 0, 2000., 0, 2000.], [50, 50, 50],
                 surface_points_df=df_i,
                 orientations_df=df_o,
                 default_values=True)

    df_cmp_i = gp.get_data(geo_model, 'surface_points')
    df_cmp_o = gp.get_data(geo_model, 'orientations')

    if verbose:
        print(df_cmp_i.head())
        print(df_cmp_o.head())

    assert not df_cmp_i.empty, 'data was not set to dataframe'
    assert not df_cmp_o.empty, 'data was not set to dataframe'
    assert df_cmp_i.shape[0] == 6, 'data was not set to dataframe'
    assert df_cmp_o.shape[0] == 6, 'data was not set to dataframe'

    # try without the default_values command

    geo_model = gp.create_model('test')
    # Importing the data directly from the dataframes
    gp.init_data(geo_model, [0, 2000., 0, 2000., 0, 2000.], [50, 50, 50],
                 surface_points_df=df_i,
                 orientations_df=df_o)

    df_cmp_i2 = gp.get_data(geo_model, 'surface_points')
    df_cmp_o2 = gp.get_data(geo_model, 'orientations')

    if verbose:
        print(df_cmp_i2.head())
        print(df_cmp_o2.head())

    assert not df_cmp_i2.empty, 'data was not set to dataframe'
    assert not df_cmp_o2.empty, 'data was not set to dataframe'
    assert df_cmp_i2.shape[0] == 6, 'data was not set to dataframe'
    assert df_cmp_o2.shape[0] == 6, 'data was not set to dataframe'

    return geo_model
Exemple #2
0
def load_model():
    verbose = False
    geo_model = gp.create_model('Model_Tuto1-1')

    # Importing the data from CSV-files and setting extent and resolution
    gp.init_data(geo_model, [0, 2000., 0, 2000., 0, 2000.], [50, 50, 50],
                 path_o=input_path + "/simple_fault_model_orientations.csv",
                 path_i=input_path + "/simple_fault_model_points.csv",
                 default_values=True)

    df_cmp_i = gp.get_data(geo_model, 'surface_points')
    df_cmp_o = gp.get_data(geo_model, 'orientations')

    df_o = pn.read_csv(input_path + "/simple_fault_model_orientations.csv")
    df_i = pn.read_csv(input_path + "/simple_fault_model_points.csv")

    assert not df_cmp_i.empty, 'data was not set to dataframe'
    assert not df_cmp_o.empty, 'data was not set to dataframe'
    assert df_cmp_i.shape[0] == df_i.shape[0], 'data was not set to dataframe'
    assert df_cmp_o.shape[0] == df_o.shape[0], 'data was not set to dataframe'

    if verbose:
        gp.get_data(geo_model, 'surface_points').head()

    return geo_model
Exemple #3
0
def model_horizontal_two_layers():

    geo_model = gp.create_model('interpolator')

    # Importing the data from csv files and settign extent and resolution
    gp.init_data(geo_model, [0, 10, 0, 10, -10, 0], [50, 50, 50],
                 path_o=input_path + "/GeoModeller/test_a/test_a_Foliations.csv",
                 path_i=input_path + "/GeoModeller/test_a/test_a_Points.csv")

    return geo_model
def test_reorder_series():

    geo_model = gp.create_model('Geological_Model1')
    geo_model = gp.init_data(geo_model,
                             extent=[0, 4000, 0, 2775, 200, 1200],
                             resolution=[100, 10, 100])
    # Adding a fault
    geo_model.rename_features(['Cycle1'])

    geo_model.add_features(['Fault1'])
    geo_model.set_is_fault(['Fault1'])
    geo_model.reorder_features(['Fault1', 'Cycle1'])
    assert (geo_model._stack.df['BottomRelation'] == ['Fault',
                                                      'Erosion']).all()
    assert (geo_model._stack.df.index == ['Fault1', 'Cycle1']).all()
    print(geo_model._stack.df)
def test_pile_geomodel_2():
    ve = 3
    extent = [451e3, 456e3, 6.7820e6, 6.7840e6, -2309 * ve, -1651 * ve]

    geo_model = gp.create_model('Topology-Gullfaks')

    gp.init_data(geo_model,
                 extent, [30, 30, 30],
                 path_o=input_path + "/filtered_orientations.csv",
                 path_i=input_path + "/filtered_surface_points.csv",
                 default_values=True)

    series_distribution = {
        "fault3": "fault3",
        "fault4": "fault4",
        "unconformity": "BCU",
        "sediments": ("tarbert", "ness", "etive"),
    }

    gp.map_stack_to_surfaces(geo_model,
                             series_distribution,
                             remove_unused_series=True)

    geo_model.reorder_features(
        ["unconformity", "fault3", "fault4", "sediments", "Basement"])

    geo_model.set_is_fault(["fault3"])
    geo_model.set_is_fault(["fault4"])

    rel_matrix = np.array([[0, 0, 0, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 1, 1],
                           [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])

    geo_model.set_fault_relation(rel_matrix)

    surf_groups = pd.read_csv(input_path +
                              "/filtered_surface_points.csv").group
    geo_model._surface_points.df["group"] = surf_groups
    orient_groups = pd.read_csv(input_path +
                                "/filtered_orientations.csv").group
    geo_model._orientations.df["group"] = orient_groups

    geo_model._surface_points.df.reset_index(inplace=True, drop=True)
    geo_model._orientations.df.reset_index(inplace=True, drop=True)

    return geo_model
Exemple #6
0
def test_add_point():
    extend = [0.0, 1.0, 0.0, 1.0, 0.0, 1.1]
    discretization = [5, 20, 20]

    x, y, z, f = 0.0, 0.0, 0.5, 'surface2'

    # %%
    geo_model = gp.create_model('test')
    gp.init_data(geo_model, extend, discretization)

    geo_model.set_default_surfaces()
    geo_model.set_default_orientation()

    strats = ['surface1', 'surface2', 'basement']

    gp.map_stack_to_surfaces(geo_model, {'Strat_Series': strats})

    geo_model.add_surface_points(x, y, z, f)
    geo_model.add_orientations(x, y, z, f, pole_vector=(1, 0, 0))
def test_complete_model(tmpdir):
    # ### Initializing the model:
    compute = True

    geo_model = gp.create_model('Geological_Model1')
    geo_model = gp.init_data(geo_model,
                             extent=[0, 4000, 0, 2775, 200, 1200],
                             resolution=[100, 10, 100])

    geo_model.add_surfaces(['D', 'C', 'B', 'A'])

    # surface B
    geo_model.add_surface_points(X=584, Y=285, Z=500, surface='B')
    geo_model.add_surface_points(X=494, Y=696, Z=500, surface='B')
    geo_model.add_surface_points(X=197, Y=1898, Z=500, surface='B')
    geo_model.add_surface_points(X=473, Y=2180, Z=400, surface='B')
    geo_model.add_surface_points(X=435, Y=2453, Z=400, surface='B')
    # surface C
    geo_model.add_surface_points(X=946, Y=188, Z=600, surface='C')
    geo_model.add_surface_points(X=853, Y=661, Z=600, surface='C')
    geo_model.add_surface_points(X=570, Y=1845, Z=600, surface='C')
    geo_model.add_surface_points(X=832, Y=2132, Z=500, surface='C')
    geo_model.add_surface_points(X=767, Y=2495, Z=500, surface='C')
    # Surface D
    geo_model.add_surface_points(X=967, Y=1638, Z=800, surface='D')
    geo_model.add_surface_points(X=1095, Y=996, Z=800, surface='D')

    geo_model.add_orientations(X=832,
                               Y=2132,
                               Z=500,
                               surface='C',
                               orientation=[98, 17.88, 1])
    # -----------
    # Adding a fault
    geo_model.rename_features(['Cycle1'])

    geo_model.add_features(['Fault1'])
    geo_model.set_is_fault(['Fault1'])

    geo_model.modify_order_features(1, 'Fault1')
    geo_model.add_surfaces(['F1'])
    gp.map_stack_to_surfaces(geo_model, {'Fault1': 'F1'})

    # Add input data of the fault
    geo_model.add_surface_points(X=1203, Y=138, Z=600, surface='F1')
    geo_model.add_surface_points(X=1250, Y=1653, Z=800, surface='F1')
    # Add orientation
    geo_model.add_orientations(X=1280,
                               Y=2525,
                               Z=500,
                               surface='F1',
                               orientation=[272, 90, -1])

    # surface B
    geo_model.add_surface_points(X=1447, Y=2554, Z=500, surface='B')
    geo_model.add_surface_points(X=1511, Y=2200, Z=500, surface='B')
    geo_model.add_surface_points(X=1549, Y=629, Z=600, surface='B')
    geo_model.add_surface_points(X=1630, Y=287, Z=600, surface='B')
    # surface C
    geo_model.add_surface_points(X=1891, Y=2063, Z=600, surface='C')
    geo_model.add_surface_points(X=1605, Y=1846, Z=700, surface='C')
    geo_model.add_surface_points(X=1306, Y=1641, Z=800, surface='C')
    geo_model.add_surface_points(X=1476, Y=979, Z=800, surface='C')
    geo_model.add_surface_points(X=1839, Y=962, Z=700, surface='C')
    geo_model.add_surface_points(X=2185, Y=893, Z=600, surface='C')
    geo_model.add_surface_points(X=2245, Y=547, Z=600, surface='C')
    # Surface D
    geo_model.add_surface_points(X=2809, Y=2567, Z=600, surface='D')
    geo_model.add_surface_points(X=2843, Y=2448, Z=600, surface='D')
    geo_model.add_surface_points(X=2873, Y=876, Z=700, surface='D')

    # ----------------
    # Second cycle
    geo_model.add_features(['Cycle2'])
    geo_model.add_surfaces(['G', 'H'])
    gp.map_stack_to_surfaces(geo_model, {'Cycle2': ['G', 'H']})
    geo_model.reorder_features(['Cycle2', 'Fault1', 'Cycle1'])

    # Surface G
    geo_model.add_surface_points(X=1012, Y=1493, Z=900, surface='G')
    geo_model.add_surface_points(X=1002, Y=1224, Z=900, surface='G')
    geo_model.add_surface_points(X=1996, Y=47, Z=800, surface='G')
    geo_model.add_surface_points(X=300, Y=907, Z=700, surface='G')
    # Surface H
    geo_model.add_surface_points(X=3053, Y=727, Z=800, surface='G')
    # Orientation
    geo_model.add_orientations(X=1996,
                               Y=47,
                               Z=800,
                               surface='G',
                               orientation=[272, 5.54, 1])

    # ----------------
    # Second Fault
    geo_model.add_features('Fault2')
    geo_model.set_is_fault('Fault2')
    geo_model.add_surfaces('F2')

    geo_model.reorder_features(['Cycle2', 'Fault1', 'Fault2', 'Cycle1'])
    gp.map_stack_to_surfaces(geo_model, {'Fault2': 'F2'})

    geo_model.add_surface_points(X=3232, Y=178, Z=1000, surface='F2')
    geo_model.add_surface_points(X=3132, Y=951, Z=700, surface='F2')
    # geo_model.add_surface_points(X=2962, Y=2184, Z=700, surface='F2')

    geo_model.add_orientations(X=3132,
                               Y=951,
                               Z=700,
                               surface='F2',
                               orientation=[95, 90, 1])

    geo_model.add_surface_points(X=3135, Y=1300, Z=700, surface='D')
    geo_model.add_surface_points(X=3190, Y=969, Z=700, surface='D')

    geo_model.add_surface_points(X=3031, Y=2725, Z=800, surface='G')
    geo_model.add_surface_points(X=3018, Y=1990, Z=800, surface='G')
    geo_model.add_surface_points(X=3194, Y=965, Z=700, surface='G')

    geo_model.add_surface_points(X=3218, Y=1818, Z=890, surface='H')
    geo_model.add_surface_points(X=3934, Y=1207, Z=810, surface='H')
Exemple #8
0
def loop2gempy(
        contacts_file: str,
        orientations_file: str,
        bbox: Iterable,
        groups_file: str,
        model_base: float,
        model_top: float, dtm_reproj_file: str = None,
        faults_contact: str = None,
        faults_orientations: str = None,
        faults_faults_rel: str = None,
        faults_groups_rel: str = None,
        faults_rel_matrix = None,
        model_name: str = None,
        compute: bool = True,
        vtk: bool = False,
        vtk_path: str = None,
        image_2d: bool = False,
        plot_3d_kwargs=None
):
    """ Calculate the model using gempy_lite as backend.

        At the moment there is not support for finite faults since gempy_lite does not
         accept passing the ellipsoid parameters directly.

        :param contacts_file (str): path of contacts file
        :param orientations_file: path of orientations file
        :param bbox: model bounding box
        :param groups_file: path of groups file
        :param model_base: z value of base of model
        :param model_top: z value of top of model
        :param dtm_reproj_file: path of dtm file
        :param faults_contact: path of contacts file with fault data
        :param faults_orientations: path of orientations file with fault data
        :param faults_rel_matrix: bool matrix describing the interaction between groups. Rows offset columns
        :param faults_groups_rel: bool matrix describing the interaction between faults and features
        :param faults_faults_rel: bool matrix describing the interaction between faults and faults
        :param model_name: name of the model
        :param compute (bool): Default True. Whether or not compute the model
        :param vtk (bool): Default False. Whether or not visualize the model
        :param vtk_path (str): Default None. Path of vtk output directory
        :param plot_3d_kwargs (dict): kwargs for `gempy_lite.plot_3d`
        :return: gempy_lite.Project
    """
    if plot_3d_kwargs is None:
        plot_3d_kwargs = {}

    contacts = []
    orientations = []

    contacts.append(
        pd.read_csv(
            contacts_file,
            sep=',',
            names=['X', 'Y', 'Z', 'formation'],
            header=1
        )
    )

    if faults_contact is not None:
        contacts.append(
            pd.read_csv(
                faults_contact,
                sep=',',
                names=['X', 'Y', 'Z', 'formation'],
                header=1
            )
        )

    orientations.append(
        pd.read_csv(
            orientations_file,
            sep=',',
            names=['X', 'Y', 'Z', 'azimuth', 'dip', 'polarity', 'formation'],
            header=1
        )
    )

    if faults_orientations is not None:
        orientations.append(
            pd.read_csv(
                faults_orientations,
                sep=',',
                names=['X', 'Y', 'Z', 'azimuth', 'dip', 'polarity', 'formation'],
                header=1
            )
        )

    if faults_faults_rel is not None and faults_groups_rel is not None:
        ff_ = pd.read_csv(faults_faults_rel).set_index('fault_id')
        fg_ = pd.read_csv(faults_groups_rel).set_index('group')
        p_ = pd.concat((ff_, fg_), axis=0, sort=True)
        faults_rel_matrix = pd.concat((p_, fg_.T), axis=1, sort=True).fillna(0).values

    surface_points_ready = pd.concat(contacts, sort=True)
    surface_points_ready.reset_index(inplace=True, drop=False)
    orientation_ready = pd.concat(orientations, sort=True)
    orientation_ready.reset_index(inplace=True, drop=False)

    if model_name is None:
        model_name = 'loop2gempy'

    geo_model = gp.create_model(model_name)
    gp.init_data(
        geo_model,
        extent=[bbox[0], bbox[2], bbox[1], bbox[3], model_base, model_top],
        resolution=[50, 50, 50],
        orientations_df=orientation_ready,
        surface_points_df=surface_points_ready
    )

    # Load Topology
    if dtm_reproj_file is not None:
        if type(dtm_reproj_file) is str:
            source = 'gdal'
            topo_kwarg = {'filepath': dtm_reproj_file}
        elif type(dtm_reproj_file) is np.ndarray:
            source = 'numpy'
            topo_kwarg = {'array': dtm_reproj_file}
        else:
            raise AttributeError('dtm_proj_file must be either a path to gdal or a'
                                 'numpy array with values')
        geo_model.set_topography(source=source, **topo_kwarg)

    # Stack Processing
    contents = np.genfromtxt(groups_file, delimiter=',', dtype='U100')[1:, 4:-1]

    map_series_to_surfaces = {}
    for pair in contents:
        map_series_to_surfaces.setdefault(pair[1], []).append(pair[0])

    gp.map_stack_to_surfaces(geo_model, map_series_to_surfaces,
                             remove_unused_series=False)

    order_formations = geo_model.stack.df.index.drop('Default series')

    # Get the unassigned series as faults
    if faults_contact is not None and faults_orientations is not None:
        faults_pair = geo_model._surfaces.df.groupby('series').get_group('Default series')[[
            'surface']].values[:, 0]
        faults_pair_dict = dict(zip(faults_pair, faults_pair))
        gp.map_stack_to_surfaces(geo_model, faults_pair_dict, remove_unused_series=True)
        # Grabbing the order of faults and Formations
        ordered_features = np.append(faults_pair, order_formations)
        # Sorting series
        geo_model.reorder_features(ordered_features)
        geo_model.set_is_fault(faults_pair)

        # Faults relation
        geo_model.set_fault_relation(faults_rel_matrix)

    geo_model.add_surfaces('basement')

    # Check if there is features without data and delete it
    try:
        f_ = geo_model.surfaces.df.groupby('isActive').get_group(False)
        features_without_data = f_['series']
        geo_model.delete_features(features_without_data, remove_surfaces=True, remove_data=True)
    except KeyError:
        pass

    if faults_contact is not None and faults_orientations is not None:
        get_fault_names = geo_model.stack.df.groupby(['isActive', 'isFault']).get_group(
            (True, True)).index
        geo_model._surfaces.colors.make_faults_black(get_fault_names)

    try:
        colours = pd.read_csv(groups_file).set_index('code')['colour']
        # Drop formations that do not exist in surfaces
        colours = colours.loc[colours.index.isin(geo_model.surfaces.df['surface'])].to_dict()

        geo_model._surfaces.colors.change_colors(colours)
    except KeyError:
        pass

    if compute is True:
        gp.set_interpolator(geo_model, dtype='float64',
                            # verbose=['solve_kriging']
                            )

        # Increasing nugget effect
        geo_model.modify_surface_points(
            geo_model.surface_points.df.index,
            smooth=0.1
        )

        geo_model.modify_orientations(
            geo_model.orientations.df.index,
            smooth=0.01
        )

        new_range = geo_model.get_additional_data().loc[('Kriging', 'range'), 'values'] * 0.5
        geo_model.modify_kriging_parameters('range', new_range)

        gp.compute_model(geo_model)

    if vtk is True:
        gp.plot_3d(geo_model, show_topography=True,
                   image=image_2d,
                   show_lith=True,
                   **plot_3d_kwargs
                   )

    if vtk_path is not None:
        gp._plot.export_to_vtk(geo_model, path=vtk_path, name=model_name + '.vtk',
                               voxels=False, block=None, surfaces=True)

    return geo_model
Exemple #9
0
def load_model(name=None, path=None, recompile=False):
    """
    Loading model saved with model.save_model function.

    Args:
        name: name of folder with saved files
        path (str): path to folder directory or the zip file
        recompile (bool): if true, theano functions will be recompiled

    Returns:
        :class:`Project`

    """
    # TODO: Divide each dataframe in its own function and move them as
    #  method of the class
    # TODO: Include try except in case some of the datafiles is missing
    #

    # Default path
    is_compressed = False
    if path is None:
        path = f'./{name}'

    p = pathlib.Path(path)

    # If the path includes .zip
    if p.suffix == '.zip':
        path = path[:-4]
        print("is path", path)
        try:
            shutil.unpack_archive(path + '.zip', extract_dir=path)
        except ValueError as e:
            raise ValueError(e)
        is_compressed = True

    # if the path does not include .zip but exist
    elif os.path.isfile(f'{path}.zip'):

        try:
            shutil.unpack_archive(path + '.zip', extract_dir=path)
        except ValueError as e:
            raise ValueError(e)
        is_compressed = True

    # create model with extent and resolution from csv - check
    geo_model = create_model()
    init_data(geo_model, np.load(f'{path}/{name}_extent.npy'),
              np.load(f'{path}/{name}_resolution.npy'))

    try:
        geo_model.set_topography(source='saved',
                                 filepath=f'{path}/{name}_topography.npy')
    except FileNotFoundError:
        pass

    geo_model._additional_data.kriging_data.df = pn.read_csv(
        f'{path}/{name}_kriging_data.csv',
        index_col=0,
        dtype={
            'range': 'float64',
            '$C_o$': 'float64',
            'drift equations': object,
            'nugget grad': 'float64',
            'nugget scalar': 'float64'
        })

    geo_model._additional_data.kriging_data.str2int_u_grade()

    geo_model._additional_data.options.df = pn.read_csv(
        f'{path}/{name}_options.csv',
        index_col=0,
        dtype={
            'dtype': 'category',
            'output': 'category',
            'theano_optimizer': 'category',
            'device': 'category',
            'verbosity': object
        })
    geo_model._additional_data.options.df['dtype'].cat.set_categories(
        ['float32', 'float64'], inplace=True)
    geo_model._additional_data.options.df[
        'theano_optimizer'].cat.set_categories(['fast_run', 'fast_compile'],
                                               inplace=True)
    geo_model._additional_data.options.df['device'].cat.set_categories(
        ['cpu', 'cuda'], inplace=True)
    geo_model._additional_data.options.df['output'].cat.set_categories(
        ['geology', 'gradients'], inplace=True)
    geo_model._additional_data.options.df.loc['values', 'verbosity'] = None
    # do series properly - this needs proper check

    # Load series
    s = pn.read_csv(f'{path}/{name}_series.csv',
                    index_col=0,
                    dtype={
                        'order_series': 'int32',
                        'BottomRelation': 'category'
                    })

    f = pn.read_csv(f'{path}/{name}_faults.csv',
                    index_col=0,
                    dtype={
                        'isFault': 'bool',
                        'isFinite': 'bool'
                    })

    stack = pn.concat([s, f], axis=1, sort=False)
    stack = stack.loc[:, ~stack.columns.duplicated()]
    geo_model._stack.df = stack
    series_index = pn.CategoricalIndex(geo_model._stack.df.index.values)
    # geo_model.series.df.index = pn.CategoricalIndex(series_index)
    geo_model._stack.df.index = series_index
    geo_model._stack.df['BottomRelation'].cat.set_categories(
        ['Erosion', 'Onlap', 'Fault'], inplace=True)
    try:
        geo_model._stack.df['isActive']
    except KeyError:
        geo_model._stack.df['isActive'] = False

    cat_series = geo_model._stack.df.index.values
    # # do faults relations properly - this is where I struggle
    geo_model._faults.faults_relations_df = pn.read_csv(
        f'{path}/{name}_faults_relations.csv', index_col=0)
    geo_model._faults.faults_relations_df.index = series_index
    geo_model._faults.faults_relations_df.columns = series_index

    geo_model._faults.faults_relations_df.fillna(False, inplace=True)

    # do surfaces properly
    surf_df = pn.read_csv(f'{path}/{name}_surfaces.csv',
                          index_col=0,
                          dtype={
                              'surface': 'str',
                              'series': 'category',
                              'order_surfaces': 'int64',
                              'isBasement': 'bool',
                              'id': 'int64',
                              'color': 'str'
                          })
    c_ = surf_df.columns[~(
        surf_df.columns.isin(geo_model._surfaces._columns_vis_drop))]
    geo_model._surfaces.df[c_] = surf_df[c_]
    geo_model._surfaces.df['series'].cat.reorder_categories(np.asarray(
        geo_model._stack.df.index),
                                                            ordered=False,
                                                            inplace=True)
    geo_model._surfaces.sort_surfaces()

    geo_model._surfaces.colors.generate_colordict()
    geo_model._surfaces.df['series'].cat.set_categories(cat_series,
                                                        inplace=True)

    try:
        geo_model._surfaces.df['isActive']
    except KeyError:
        geo_model._surfaces.df['isActive'] = False

    cat_surfaces = geo_model._surfaces.df['surface'].values

    # do orientations properly, reset all dtypes
    geo_model._orientations.df = pn.read_csv(f'{path}/{name}_orientations.csv',
                                             index_col=0,
                                             dtype={
                                                 'X': 'float64',
                                                 'Y': 'float64',
                                                 'Z': 'float64',
                                                 'X_r': 'float64',
                                                 'Y_r': 'float64',
                                                 'Z_r': 'float64',
                                                 'dip': 'float64',
                                                 'azimuth': 'float64',
                                                 'polarity': 'float64',
                                                 'surface': 'category',
                                                 'series': 'category',
                                                 'id': 'int64',
                                                 'order_series': 'int64'
                                             })
    geo_model._orientations.df['surface'].cat.set_categories(cat_surfaces,
                                                             inplace=True)
    geo_model._orientations.df['series'].cat.set_categories(cat_series,
                                                            inplace=True)

    # do surface_points properly, reset all dtypes
    geo_model._surface_points.df = pn.read_csv(
        f'{path}/{name}_surface_points.csv',
        index_col=0,
        dtype={
            'X': 'float64',
            'Y': 'float64',
            'Z': 'float64',
            'X_r': 'float64',
            'Y_r': 'float64',
            'Z_r': 'float64',
            'surface': 'category',
            'series': 'category',
            'id': 'int64',
            'order_series': 'int64'
        })
    geo_model._surface_points.df['surface'].cat.set_categories(cat_surfaces,
                                                               inplace=True)
    geo_model._surface_points.df['series'].cat.set_categories(cat_series,
                                                              inplace=True)

    # Code to add smooth columns for models saved before gempy_lite 2.0bdev4
    try:
        geo_model._surface_points.df['smooth']
    except KeyError:
        geo_model._surface_points.df['smooth'] = 1e-7

    try:
        geo_model._orientations.df['smooth']
    except KeyError:
        geo_model._orientations.df['smooth'] = 0.01

    # update structure from loaded input
    geo_model._additional_data.structure_data.update_structure_from_input()
    geo_model._rescaling.rescale_data()
    geo_model.update_from_series()
    geo_model.update_from_surfaces()
    geo_model.update_structure()

    if recompile is True:
        from gempy_lite.api_modules.setters import set_interpolator
        set_interpolator(geo_model, verbose=[0])

    # Cleaning temp files
    if is_compressed:
        shutil.rmtree(path)

    return geo_model
def test_colors_101_surfaces():
    """Tests if GemPy Colors class works with at least 101 surfaces."""
    geomodel = gp.create_model("ColorfulModel")
    for n in range(101):
        geomodel.add_surfaces(f"Surface {n}")
    assert np.all(geomodel.surfaces.df.color.values != np.nan)