Applying PB-M3C2 in long term monitoring

In applications where data from the same observation site is acquired over a long period of time, it is desirable to carry out the training of the PB-M3C2 algorithm once and then apply the trained model to newly acquired epochs. This notebook explains how this process is implemented in py4dgeo. First, we are carrying out the training procedure like we did in the explanation of the base workflow:

[1]:
import py4dgeo
[2]:
py4dgeo.set_interactive_backend("vtk")
[3]:
epoch0, epoch1 = py4dgeo.read_from_xyz(
    "plane_horizontal_t1.xyz", "plane_horizontal_t2.xyz"
)
[2024-05-14 13:04:16][INFO] Reading point cloud from file '/home/docs/.cache/py4dgeo/./plane_horizontal_t1.xyz'
[2024-05-14 13:04:16][INFO] Reading point cloud from file '/home/docs/.cache/py4dgeo/./plane_horizontal_t2.xyz'
[4]:
alg = py4dgeo.PBM3C2()
[5]:
xyz_epoch0, xyz_epoch1, segment_id = alg.export_segmented_point_cloud_and_segments(
    epoch0=epoch0,
    epoch1=epoch1,
)
[2024-05-14 13:04:16][INFO] No pipeline parameter is overwritten
[2024-05-14 13:04:16][INFO] No pipeline parameter is overwritten
[2024-05-14 13:04:16][INFO] Transformer Fit
[2024-05-14 13:04:16][INFO] Transformer Transform
[2024-05-14 13:04:16][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:16][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Transformer Fit
[2024-05-14 13:04:17][INFO] Transformer Transform
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Transformer Fit
[2024-05-14 13:04:17][INFO] Transformer Transform
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Transformer Transform
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Transformer Transform
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Transformer Fit
[2024-05-14 13:04:17][INFO] Transformer Transform
[2024-05-14 13:04:17][INFO] ----
 The pipeline parameters after restoration are:
{'_Transform_PerPointComputation': PerPointComputation(),
 '_Transform_PerPointComputation__columns': <class 'py4dgeo.pbm3c2.LLSV_PCA_COLUMNS'>,
 '_Transform_PerPointComputation__output_file_name': None,
 '_Transform_PerPointComputation__radius': 10,
 '_Transform_PerPointComputation__skip': False,
 '_Transform_Second_Segmentation': Segmentation(with_previously_computed_segments=True),
 '_Transform_Second_Segmentation__angle_diff_threshold': 1,
 '_Transform_Second_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 '_Transform_Second_Segmentation__distance_3D_threshold': 1.5,
 '_Transform_Second_Segmentation__distance_orthogonal_threshold': 1.5,
 '_Transform_Second_Segmentation__llsv_threshold': 1,
 '_Transform_Second_Segmentation__max_nr_points_neighborhood': 100,
 '_Transform_Second_Segmentation__min_nr_points_per_segment': 5,
 '_Transform_Second_Segmentation__output_file_name': None,
 '_Transform_Second_Segmentation__radius': 2,
 '_Transform_Second_Segmentation__roughness_threshold': 5,
 '_Transform_Second_Segmentation__skip': False,
 '_Transform_Second_Segmentation__with_previously_computed_segments': True,
 '_Transform_Segmentation': Segmentation(),
 '_Transform_Segmentation__angle_diff_threshold': 1,
 '_Transform_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 '_Transform_Segmentation__distance_3D_threshold': 1.5,
 '_Transform_Segmentation__distance_orthogonal_threshold': 1.5,
 '_Transform_Segmentation__llsv_threshold': 1,
 '_Transform_Segmentation__max_nr_points_neighborhood': 100,
 '_Transform_Segmentation__min_nr_points_per_segment': 5,
 '_Transform_Segmentation__output_file_name': None,
 '_Transform_Segmentation__radius': 2,
 '_Transform_Segmentation__roughness_threshold': 5,
 '_Transform_Segmentation__skip': False,
 '_Transform_Segmentation__with_previously_computed_segments': False,
 'memory': None,
 'steps': [('_Transform_PerPointComputation', PerPointComputation()),
           ('_Transform_Segmentation', Segmentation()),
           ('_Transform_Second_Segmentation',
            Segmentation(with_previously_computed_segments=True))],
 'verbose': False}
----

[2024-05-14 13:04:17][INFO] ----
 The pipeline parameters after restoration are:
{'_Transform_ExtractSegments': ExtractSegments(),
 '_Transform_ExtractSegments__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 '_Transform_ExtractSegments__output_file_name': None,
 '_Transform_ExtractSegments__skip': False,
 'memory': None,
 'steps': [('_Transform_ExtractSegments', ExtractSegments())],
 'verbose': False}
----

[6]:
alg.training(
    extracted_segments_file_name="extracted_segments.seg",
    extended_y_file_name="testdata-labelling.csv",
)
[2024-05-14 13:04:17][INFO] Reading segments from file '/home/docs/checkouts/readthedocs.org/user_builds/py4dgeo/checkouts/latest/doc/extracted_segments.seg'
[2024-05-14 13:04:17][INFO] Reading tuples of (segment epoch0, segment epoch1, label) from file '/home/docs/.cache/py4dgeo/./testdata-labelling.csv'
[2024-05-14 13:04:17][INFO] Fit ClassifierWrapper

Having the pre-trained algorithm object alg, we would like to save it for reuse in later analysis sessions. We do use Python’s pickle module for that:

[7]:
import pickle
[8]:
with open("alg.pickle", "wb") as outfile:
    pickle.dump(alg, outfile)

Then, in a subsequent session, we can reload the algorithm using pickle:

[9]:
with open("alg.pickle", "rb") as infile:
    alg = pickle.load(infile)

We can then feed new epochs (here, we just use epoch0 again) into the algorithm. It will apply segmentation on the new epoch and then run the prediction for the new epoch

[10]:
(
    _0,
    _1,
    extracted_segments_epoch0,
) = alg.export_segmented_point_cloud_and_segments(
    # must be a new epoch
    epoch0=epoch0,
    # epoch1=None,
    x_y_z_id_epoch0_file_name=None,
    x_y_z_id_epoch1_file_name=None,
    extracted_segments_file_name=None,
)
[2024-05-14 13:04:17][INFO] No pipeline parameter is overwritten
[2024-05-14 13:04:17][INFO] No pipeline parameter is overwritten
[2024-05-14 13:04:17][INFO] Transformer Fit
[2024-05-14 13:04:17][INFO] Transformer Transform
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:17][INFO] Transformer Fit
[2024-05-14 13:04:17][INFO] Transformer Transform
[2024-05-14 13:04:17][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Fit
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Fit
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after restoration are:
{'_Transform_PerPointComputation': PerPointComputation(),
 '_Transform_PerPointComputation__columns': <class 'py4dgeo.pbm3c2.LLSV_PCA_COLUMNS'>,
 '_Transform_PerPointComputation__output_file_name': None,
 '_Transform_PerPointComputation__radius': 10,
 '_Transform_PerPointComputation__skip': False,
 '_Transform_Second_Segmentation': Segmentation(with_previously_computed_segments=True),
 '_Transform_Second_Segmentation__angle_diff_threshold': 1,
 '_Transform_Second_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 '_Transform_Second_Segmentation__distance_3D_threshold': 1.5,
 '_Transform_Second_Segmentation__distance_orthogonal_threshold': 1.5,
 '_Transform_Second_Segmentation__llsv_threshold': 1,
 '_Transform_Second_Segmentation__max_nr_points_neighborhood': 100,
 '_Transform_Second_Segmentation__min_nr_points_per_segment': 5,
 '_Transform_Second_Segmentation__output_file_name': None,
 '_Transform_Second_Segmentation__radius': 2,
 '_Transform_Second_Segmentation__roughness_threshold': 5,
 '_Transform_Second_Segmentation__skip': False,
 '_Transform_Second_Segmentation__with_previously_computed_segments': True,
 '_Transform_Segmentation': Segmentation(),
 '_Transform_Segmentation__angle_diff_threshold': 1,
 '_Transform_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 '_Transform_Segmentation__distance_3D_threshold': 1.5,
 '_Transform_Segmentation__distance_orthogonal_threshold': 1.5,
 '_Transform_Segmentation__llsv_threshold': 1,
 '_Transform_Segmentation__max_nr_points_neighborhood': 100,
 '_Transform_Segmentation__min_nr_points_per_segment': 5,
 '_Transform_Segmentation__output_file_name': None,
 '_Transform_Segmentation__radius': 2,
 '_Transform_Segmentation__roughness_threshold': 5,
 '_Transform_Segmentation__skip': False,
 '_Transform_Segmentation__with_previously_computed_segments': False,
 'memory': None,
 'steps': [('_Transform_PerPointComputation', PerPointComputation()),
           ('_Transform_Segmentation', Segmentation()),
           ('_Transform_Second_Segmentation',
            Segmentation(with_previously_computed_segments=True))],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after restoration are:
{'_Transform_ExtractSegments': ExtractSegments(),
 '_Transform_ExtractSegments__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 '_Transform_ExtractSegments__output_file_name': None,
 '_Transform_ExtractSegments__skip': False,
 'memory': None,
 'steps': [('_Transform_ExtractSegments', ExtractSegments())],
 'verbose': False}
----

We can then calculate distances for the new epoch. Note, that in order to disable those parts of the analysis pipeline that are already computed for the reference epoch, we pass the constant dictionary **py4dgeo.config_epoch0_as_segments. If you have customized the analysis pipeline, you should adapt the configuration settings accordingly and disable all those steps that are not required for the reference epoch:

[11]:
distances, uncertainties = alg.compute_distances(
    epoch0=extracted_segments_epoch0, epoch1=epoch1, **py4dgeo.config_epoch0_as_segments
)
[2024-05-14 13:04:18][INFO] PBM3C2.compute_distances(...)
[2024-05-14 13:04:18][INFO] PBM3C2._compute_distances(...)
[2024-05-14 13:04:18][INFO] ----
 The default parameters are:
 {'epoch0_Transform_ExtractSegments': ExtractSegments(),
 'epoch0_Transform_ExtractSegments__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 'epoch0_Transform_ExtractSegments__output_file_name': None,
 'epoch0_Transform_ExtractSegments__skip': False,
 'epoch0_Transform_PerPointComputation': PerPointComputation(),
 'epoch0_Transform_PerPointComputation__columns': <class 'py4dgeo.pbm3c2.LLSV_PCA_COLUMNS'>,
 'epoch0_Transform_PerPointComputation__output_file_name': None,
 'epoch0_Transform_PerPointComputation__radius': 10,
 'epoch0_Transform_PerPointComputation__skip': False,
 'epoch0_Transform_Second_Segmentation': Segmentation(with_previously_computed_segments=True),
 'epoch0_Transform_Second_Segmentation__angle_diff_threshold': 1,
 'epoch0_Transform_Second_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch0_Transform_Second_Segmentation__distance_3D_threshold': 1.5,
 'epoch0_Transform_Second_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch0_Transform_Second_Segmentation__llsv_threshold': 1,
 'epoch0_Transform_Second_Segmentation__max_nr_points_neighborhood': 100,
 'epoch0_Transform_Second_Segmentation__min_nr_points_per_segment': 5,
 'epoch0_Transform_Second_Segmentation__output_file_name': None,
 'epoch0_Transform_Second_Segmentation__radius': 2,
 'epoch0_Transform_Second_Segmentation__roughness_threshold': 5,
 'epoch0_Transform_Second_Segmentation__skip': False,
 'epoch0_Transform_Second_Segmentation__with_previously_computed_segments': True,
 'epoch0_Transform_Segmentation': Segmentation(),
 'epoch0_Transform_Segmentation__angle_diff_threshold': 1,
 'epoch0_Transform_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch0_Transform_Segmentation__distance_3D_threshold': 1.5,
 'epoch0_Transform_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch0_Transform_Segmentation__llsv_threshold': 1,
 'epoch0_Transform_Segmentation__max_nr_points_neighborhood': 100,
 'epoch0_Transform_Segmentation__min_nr_points_per_segment': 5,
 'epoch0_Transform_Segmentation__output_file_name': None,
 'epoch0_Transform_Segmentation__radius': 2,
 'epoch0_Transform_Segmentation__roughness_threshold': 5,
 'epoch0_Transform_Segmentation__skip': False,
 'epoch0_Transform_Segmentation__with_previously_computed_segments': False,
 'memory': None,
 'steps': [('epoch0_Transform_ExtractSegments', ExtractSegments())],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after overwriting are:
{'epoch0_Transform_PerPointComputation': PerPointComputation(skip=True),
 'epoch0_Transform_PerPointComputation__columns': <class 'py4dgeo.pbm3c2.LLSV_PCA_COLUMNS'>,
 'epoch0_Transform_PerPointComputation__output_file_name': None,
 'epoch0_Transform_PerPointComputation__radius': 10,
 'epoch0_Transform_PerPointComputation__skip': True,
 'epoch0_Transform_Second_Segmentation': Segmentation(skip=True, with_previously_computed_segments=True),
 'epoch0_Transform_Second_Segmentation__angle_diff_threshold': 1,
 'epoch0_Transform_Second_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch0_Transform_Second_Segmentation__distance_3D_threshold': 1.5,
 'epoch0_Transform_Second_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch0_Transform_Second_Segmentation__llsv_threshold': 1,
 'epoch0_Transform_Second_Segmentation__max_nr_points_neighborhood': 100,
 'epoch0_Transform_Second_Segmentation__min_nr_points_per_segment': 5,
 'epoch0_Transform_Second_Segmentation__output_file_name': None,
 'epoch0_Transform_Second_Segmentation__radius': 2,
 'epoch0_Transform_Second_Segmentation__roughness_threshold': 5,
 'epoch0_Transform_Second_Segmentation__skip': True,
 'epoch0_Transform_Second_Segmentation__with_previously_computed_segments': True,
 'epoch0_Transform_Segmentation': Segmentation(skip=True),
 'epoch0_Transform_Segmentation__angle_diff_threshold': 1,
 'epoch0_Transform_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch0_Transform_Segmentation__distance_3D_threshold': 1.5,
 'epoch0_Transform_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch0_Transform_Segmentation__llsv_threshold': 1,
 'epoch0_Transform_Segmentation__max_nr_points_neighborhood': 100,
 'epoch0_Transform_Segmentation__min_nr_points_per_segment': 5,
 'epoch0_Transform_Segmentation__output_file_name': None,
 'epoch0_Transform_Segmentation__radius': 2,
 'epoch0_Transform_Segmentation__roughness_threshold': 5,
 'epoch0_Transform_Segmentation__skip': True,
 'epoch0_Transform_Segmentation__with_previously_computed_segments': False,
 'memory': None,
 'steps': [('epoch0_Transform_PerPointComputation',
            PerPointComputation(skip=True)),
           ('epoch0_Transform_Segmentation', Segmentation(skip=True)),
           ('epoch0_Transform_Second_Segmentation',
            Segmentation(skip=True, with_previously_computed_segments=True))],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after overwriting are:
{'epoch0_Transform_ExtractSegments': ExtractSegments(skip=True),
 'epoch0_Transform_ExtractSegments__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 'epoch0_Transform_ExtractSegments__output_file_name': None,
 'epoch0_Transform_ExtractSegments__skip': True,
 'memory': None,
 'steps': [('epoch0_Transform_ExtractSegments', ExtractSegments(skip=True))],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after restoration are:
{'epoch0_Transform_PerPointComputation': PerPointComputation(),
 'epoch0_Transform_PerPointComputation__columns': <class 'py4dgeo.pbm3c2.LLSV_PCA_COLUMNS'>,
 'epoch0_Transform_PerPointComputation__output_file_name': None,
 'epoch0_Transform_PerPointComputation__radius': 10,
 'epoch0_Transform_PerPointComputation__skip': False,
 'epoch0_Transform_Second_Segmentation': Segmentation(with_previously_computed_segments=True),
 'epoch0_Transform_Second_Segmentation__angle_diff_threshold': 1,
 'epoch0_Transform_Second_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch0_Transform_Second_Segmentation__distance_3D_threshold': 1.5,
 'epoch0_Transform_Second_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch0_Transform_Second_Segmentation__llsv_threshold': 1,
 'epoch0_Transform_Second_Segmentation__max_nr_points_neighborhood': 100,
 'epoch0_Transform_Second_Segmentation__min_nr_points_per_segment': 5,
 'epoch0_Transform_Second_Segmentation__output_file_name': None,
 'epoch0_Transform_Second_Segmentation__radius': 2,
 'epoch0_Transform_Second_Segmentation__roughness_threshold': 5,
 'epoch0_Transform_Second_Segmentation__skip': False,
 'epoch0_Transform_Second_Segmentation__with_previously_computed_segments': True,
 'epoch0_Transform_Segmentation': Segmentation(),
 'epoch0_Transform_Segmentation__angle_diff_threshold': 1,
 'epoch0_Transform_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch0_Transform_Segmentation__distance_3D_threshold': 1.5,
 'epoch0_Transform_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch0_Transform_Segmentation__llsv_threshold': 1,
 'epoch0_Transform_Segmentation__max_nr_points_neighborhood': 100,
 'epoch0_Transform_Segmentation__min_nr_points_per_segment': 5,
 'epoch0_Transform_Segmentation__output_file_name': None,
 'epoch0_Transform_Segmentation__radius': 2,
 'epoch0_Transform_Segmentation__roughness_threshold': 5,
 'epoch0_Transform_Segmentation__skip': False,
 'epoch0_Transform_Segmentation__with_previously_computed_segments': False,
 'memory': None,
 'steps': [('epoch0_Transform_PerPointComputation', PerPointComputation()),
           ('epoch0_Transform_Segmentation', Segmentation()),
           ('epoch0_Transform_Second_Segmentation',
            Segmentation(with_previously_computed_segments=True))],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after restoration are:
{'epoch0_Transform_ExtractSegments': ExtractSegments(),
 'epoch0_Transform_ExtractSegments__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 'epoch0_Transform_ExtractSegments__output_file_name': None,
 'epoch0_Transform_ExtractSegments__skip': False,
 'memory': None,
 'steps': [('epoch0_Transform_ExtractSegments', ExtractSegments())],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The default parameters are:
 {'epoch1_Transform_ExtractSegments': ExtractSegments(),
 'epoch1_Transform_ExtractSegments__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 'epoch1_Transform_ExtractSegments__output_file_name': None,
 'epoch1_Transform_ExtractSegments__skip': False,
 'epoch1_Transform_PerPointComputation': PerPointComputation(),
 'epoch1_Transform_PerPointComputation__columns': <class 'py4dgeo.pbm3c2.LLSV_PCA_COLUMNS'>,
 'epoch1_Transform_PerPointComputation__output_file_name': None,
 'epoch1_Transform_PerPointComputation__radius': 10,
 'epoch1_Transform_PerPointComputation__skip': False,
 'epoch1_Transform_Second_Segmentation': Segmentation(with_previously_computed_segments=True),
 'epoch1_Transform_Second_Segmentation__angle_diff_threshold': 1,
 'epoch1_Transform_Second_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch1_Transform_Second_Segmentation__distance_3D_threshold': 1.5,
 'epoch1_Transform_Second_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch1_Transform_Second_Segmentation__llsv_threshold': 1,
 'epoch1_Transform_Second_Segmentation__max_nr_points_neighborhood': 100,
 'epoch1_Transform_Second_Segmentation__min_nr_points_per_segment': 5,
 'epoch1_Transform_Second_Segmentation__output_file_name': None,
 'epoch1_Transform_Second_Segmentation__radius': 2,
 'epoch1_Transform_Second_Segmentation__roughness_threshold': 5,
 'epoch1_Transform_Second_Segmentation__skip': False,
 'epoch1_Transform_Second_Segmentation__with_previously_computed_segments': True,
 'epoch1_Transform_Segmentation': Segmentation(),
 'epoch1_Transform_Segmentation__angle_diff_threshold': 1,
 'epoch1_Transform_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch1_Transform_Segmentation__distance_3D_threshold': 1.5,
 'epoch1_Transform_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch1_Transform_Segmentation__llsv_threshold': 1,
 'epoch1_Transform_Segmentation__max_nr_points_neighborhood': 100,
 'epoch1_Transform_Segmentation__min_nr_points_per_segment': 5,
 'epoch1_Transform_Segmentation__output_file_name': None,
 'epoch1_Transform_Segmentation__radius': 2,
 'epoch1_Transform_Segmentation__roughness_threshold': 5,
 'epoch1_Transform_Segmentation__skip': False,
 'epoch1_Transform_Segmentation__with_previously_computed_segments': False,
 'memory': None,
 'steps': [('epoch1_Transform_ExtractSegments', ExtractSegments())],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] No pipeline parameter is overwritten
[2024-05-14 13:04:18][INFO] No pipeline parameter is overwritten
[2024-05-14 13:04:18][INFO] Transformer Fit
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Fit
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Fit
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:18][INFO] Transformer Fit
[2024-05-14 13:04:18][INFO] Transformer Transform
[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after restoration are:
{'epoch1_Transform_PerPointComputation': PerPointComputation(),
 'epoch1_Transform_PerPointComputation__columns': <class 'py4dgeo.pbm3c2.LLSV_PCA_COLUMNS'>,
 'epoch1_Transform_PerPointComputation__output_file_name': None,
 'epoch1_Transform_PerPointComputation__radius': 10,
 'epoch1_Transform_PerPointComputation__skip': False,
 'epoch1_Transform_Second_Segmentation': Segmentation(with_previously_computed_segments=True),
 'epoch1_Transform_Second_Segmentation__angle_diff_threshold': 1,
 'epoch1_Transform_Second_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch1_Transform_Second_Segmentation__distance_3D_threshold': 1.5,
 'epoch1_Transform_Second_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch1_Transform_Second_Segmentation__llsv_threshold': 1,
 'epoch1_Transform_Second_Segmentation__max_nr_points_neighborhood': 100,
 'epoch1_Transform_Second_Segmentation__min_nr_points_per_segment': 5,
 'epoch1_Transform_Second_Segmentation__output_file_name': None,
 'epoch1_Transform_Second_Segmentation__radius': 2,
 'epoch1_Transform_Second_Segmentation__roughness_threshold': 5,
 'epoch1_Transform_Second_Segmentation__skip': False,
 'epoch1_Transform_Second_Segmentation__with_previously_computed_segments': True,
 'epoch1_Transform_Segmentation': Segmentation(),
 'epoch1_Transform_Segmentation__angle_diff_threshold': 1,
 'epoch1_Transform_Segmentation__columns': <class 'py4dgeo.pbm3c2.SEGMENTED_POINT_CLOUD_COLUMNS'>,
 'epoch1_Transform_Segmentation__distance_3D_threshold': 1.5,
 'epoch1_Transform_Segmentation__distance_orthogonal_threshold': 1.5,
 'epoch1_Transform_Segmentation__llsv_threshold': 1,
 'epoch1_Transform_Segmentation__max_nr_points_neighborhood': 100,
 'epoch1_Transform_Segmentation__min_nr_points_per_segment': 5,
 'epoch1_Transform_Segmentation__output_file_name': None,
 'epoch1_Transform_Segmentation__radius': 2,
 'epoch1_Transform_Segmentation__roughness_threshold': 5,
 'epoch1_Transform_Segmentation__skip': False,
 'epoch1_Transform_Segmentation__with_previously_computed_segments': False,
 'memory': None,
 'steps': [('epoch1_Transform_PerPointComputation', PerPointComputation()),
           ('epoch1_Transform_Segmentation', Segmentation()),
           ('epoch1_Transform_Second_Segmentation',
            Segmentation(with_previously_computed_segments=True))],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The pipeline parameters after restoration are:
{'epoch1_Transform_ExtractSegments': ExtractSegments(),
 'epoch1_Transform_ExtractSegments__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 'epoch1_Transform_ExtractSegments__output_file_name': None,
 'epoch1_Transform_ExtractSegments__skip': False,
 'memory': None,
 'steps': [('epoch1_Transform_ExtractSegments', ExtractSegments())],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] ----
 The default parameters are:
 {'Classifier': ClassifierWrapper(),
 'Classifier__classifier': RandomForestClassifier(),
 'Classifier__classifier__bootstrap': True,
 'Classifier__classifier__ccp_alpha': 0.0,
 'Classifier__classifier__class_weight': None,
 'Classifier__classifier__criterion': 'gini',
 'Classifier__classifier__max_depth': None,
 'Classifier__classifier__max_features': 'sqrt',
 'Classifier__classifier__max_leaf_nodes': None,
 'Classifier__classifier__max_samples': None,
 'Classifier__classifier__min_impurity_decrease': 0.0,
 'Classifier__classifier__min_samples_leaf': 1,
 'Classifier__classifier__min_samples_split': 2,
 'Classifier__classifier__min_weight_fraction_leaf': 0.0,
 'Classifier__classifier__monotonic_cst': None,
 'Classifier__classifier__n_estimators': 100,
 'Classifier__classifier__n_jobs': None,
 'Classifier__classifier__oob_score': False,
 'Classifier__classifier__random_state': None,
 'Classifier__classifier__verbose': 0,
 'Classifier__classifier__warm_start': False,
 'Classifier__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 'Classifier__diff_between_most_similar_2': 0.1,
 'Classifier__neighborhood_search_radius': 3,
 'Classifier__threshold_probability_most_similar': 0.8,
 'memory': None,
 'steps': [('Classifier', ClassifierWrapper())],
 'verbose': False}
----

[2024-05-14 13:04:18][INFO] No pipeline parameter is overwritten
[2024-05-14 13:04:18][INFO] Building KDTree structure with leaf parameter 10
[2024-05-14 13:04:20][INFO] ----
 The pipeline parameters after restoration are:
{'Classifier': ClassifierWrapper(),
 'Classifier__classifier': RandomForestClassifier(),
 'Classifier__classifier__bootstrap': True,
 'Classifier__classifier__ccp_alpha': 0.0,
 'Classifier__classifier__class_weight': None,
 'Classifier__classifier__criterion': 'gini',
 'Classifier__classifier__max_depth': None,
 'Classifier__classifier__max_features': 'sqrt',
 'Classifier__classifier__max_leaf_nodes': None,
 'Classifier__classifier__max_samples': None,
 'Classifier__classifier__min_impurity_decrease': 0.0,
 'Classifier__classifier__min_samples_leaf': 1,
 'Classifier__classifier__min_samples_split': 2,
 'Classifier__classifier__min_weight_fraction_leaf': 0.0,
 'Classifier__classifier__monotonic_cst': None,
 'Classifier__classifier__n_estimators': 100,
 'Classifier__classifier__n_jobs': None,
 'Classifier__classifier__oob_score': False,
 'Classifier__classifier__random_state': None,
 'Classifier__classifier__verbose': 0,
 'Classifier__classifier__warm_start': False,
 'Classifier__columns': <class 'py4dgeo.pbm3c2.SEGMENT_COLUMNS'>,
 'Classifier__diff_between_most_similar_2': 0.1,
 'Classifier__neighborhood_search_radius': 3,
 'Classifier__threshold_probability_most_similar': 0.8,
 'memory': None,
 'steps': [('Classifier', ClassifierWrapper())],
 'verbose': False}
----