subsurface-terra 2025.1.0rc8__tar.gz → 2025.1.0rc11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. subsurface_terra-2025.1.0rc11/.teamcity/Subsurface/buildTypes/Subsurface_ReleaseSubsurface.xml +60 -0
  2. subsurface_terra-2025.1.0rc11/.teamcity/Subsurface/buildTypes/Subsurface_ReleaseSubsurface_2.xml +37 -0
  3. subsurface_terra-2025.1.0rc11/.teamcity/Subsurface/buildTypes/Subsurface_Testing.xml +129 -0
  4. subsurface_terra-2025.1.0rc11/.teamcity/Subsurface/project-config.xml +19 -0
  5. subsurface_terra-2025.1.0rc11/.teamcity/Subsurface/vcsRoots/Subsurface_HttpsGithubComTerranigmaSolutionsSubsurfaceRefsHeadsMain.xml +17 -0
  6. subsurface_terra-2025.1.0rc11/.teamcity/Subsurface/vcsRoots/Subsurface_HttpsGithubComTerranigmaSolutionsSubsurfaceRefsHeadsMain1.xml +16 -0
  7. subsurface_terra-2025.1.0rc11/.teamcity/Subsurface/vcsRoots/Subsurface_HttpsGithubComTerranigmaSolutionsSubsurfaceRefsHeadsMain2.xml +16 -0
  8. {subsurface_terra-2025.1.0rc8/subsurface_terra.egg-info → subsurface_terra-2025.1.0rc11}/PKG-INFO +1 -1
  9. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_wells.txt +1 -0
  10. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/_version.py +1 -1
  11. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/geological_formats/boreholes/survey.py +4 -2
  12. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/_trimesh_reader.py +3 -3
  13. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/mx_reader.py +2 -1
  14. subsurface_terra-2025.1.0rc11/subsurface/modules/reader/volume/read_volume.py +230 -0
  15. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/read_borehole_interface.py +10 -0
  16. subsurface_terra-2025.1.0rc11/subsurface/modules/tools/mocking_aux.py +104 -0
  17. subsurface_terra-2025.1.0rc11/subsurface/modules/writer/to_rex/__init__.py +0 -0
  18. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11/subsurface_terra.egg-info}/PKG-INFO +1 -1
  19. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface_terra.egg-info/SOURCES.txt +9 -0
  20. subsurface_terra-2025.1.0rc8/subsurface/modules/reader/volume/read_volume.py +0 -101
  21. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/.env.example +0 -0
  22. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/LICENSE +0 -0
  23. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/README.rst +0 -0
  24. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements.txt +0 -0
  25. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_all.txt +0 -0
  26. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_dev.txt +0 -0
  27. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_geospatial.txt +0 -0
  28. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_mesh.txt +0 -0
  29. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_opt.txt +0 -0
  30. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_plot.txt +0 -0
  31. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_traces.txt +0 -0
  32. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/requirements/requirements_volume.txt +0 -0
  33. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/setup.cfg +0 -0
  34. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/setup.py +0 -0
  35. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/__init__.py +0 -0
  36. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/api/__init__.py +0 -0
  37. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/api/interfaces/README.rst +0 -0
  38. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/api/interfaces/__init__.py +0 -0
  39. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/api/interfaces/stream.py +0 -0
  40. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/api/reader/__init__.py +0 -0
  41. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/api/reader/read_wells.py +0 -0
  42. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/__init__.py +0 -0
  43. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/geological_formats/__init__.py +0 -0
  44. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/geological_formats/boreholes/__init__.py +0 -0
  45. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/geological_formats/boreholes/_combine_trajectories.py +0 -0
  46. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/geological_formats/boreholes/boreholes.py +0 -0
  47. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/geological_formats/boreholes/collars.py +0 -0
  48. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/geological_formats/fault.py +0 -0
  49. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/reader_helpers/__init__.py +0 -0
  50. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/reader_helpers/reader_unstruct.py +0 -0
  51. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/reader_helpers/readers_data.py +0 -0
  52. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/reader_helpers/readers_wells.py +0 -0
  53. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/README.rst +0 -0
  54. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/__init__.py +0 -0
  55. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/base_structures/__init__.py +0 -0
  56. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/base_structures/_liquid_earth_mesh.py +0 -0
  57. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/base_structures/_unstructured_data_constructor.py +0 -0
  58. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/base_structures/base_structures_enum.py +0 -0
  59. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/base_structures/structured_data.py +0 -0
  60. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/base_structures/unstructured_data.py +0 -0
  61. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/structured_elements/__init__.py +0 -0
  62. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/structured_elements/octree_mesh.py +0 -0
  63. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/structured_elements/structured_grid.py +0 -0
  64. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/structured_elements/structured_mesh.py +0 -0
  65. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/unstructured_elements/__init__.py +0 -0
  66. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/unstructured_elements/line_set.py +0 -0
  67. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/unstructured_elements/point_set.py +0 -0
  68. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/unstructured_elements/tetrahedron_mesh.py +0 -0
  69. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/structs/unstructured_elements/triangular_surface.py +0 -0
  70. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/utils/__init__.py +0 -0
  71. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/core/utils/utils_core.py +0 -0
  72. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/__init__.py +0 -0
  73. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/README.rst +0 -0
  74. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/__init__.py +0 -0
  75. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/faults/__init__.py +0 -0
  76. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/faults/faults.py +0 -0
  77. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/from_binary.py +0 -0
  78. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/geo_object/__init__.py +0 -0
  79. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/NOTES.md +0 -0
  80. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/_GOCAD_mesh.py +0 -0
  81. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/__init__.py +0 -0
  82. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/csv_mesh_reader.py +0 -0
  83. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/dxf_reader.py +0 -0
  84. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/glb_reader.py +0 -0
  85. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/obj_reader.py +0 -0
  86. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/omf_mesh_reader.py +0 -0
  87. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/surface_reader.py +0 -0
  88. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/mesh/surfaces_api.py +0 -0
  89. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/petrel/__init__.py +0 -0
  90. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/profiles/__init__.py +0 -0
  91. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/profiles/profiles_core.py +0 -0
  92. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/read_netcdf.py +0 -0
  93. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/topography/__init__.py +0 -0
  94. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/topography/topo_core.py +0 -0
  95. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/volume/__init__.py +0 -0
  96. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/volume/segy_reader.py +0 -0
  97. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/volume/seismic.py +0 -0
  98. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/volume/volume_utils.py +0 -0
  99. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/DEP/__init__.py +0 -0
  100. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/DEP/_well_files_reader.py +0 -0
  101. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/DEP/_wells_api.py +0 -0
  102. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/DEP/_welly_reader.py +0 -0
  103. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/DEP/pandas_to_welly.py +0 -0
  104. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/README.rst +0 -0
  105. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/__init__.py +0 -0
  106. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/_read_to_df.py +0 -0
  107. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/reader/wells/wells_utils.py +0 -0
  108. {subsurface_terra-2025.1.0rc8/subsurface/modules/writer/to_liquid_earth → subsurface_terra-2025.1.0rc11/subsurface/modules/tools}/__init__.py +0 -0
  109. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/visualization/__init__.py +0 -0
  110. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/visualization/to_pyvista.py +0 -0
  111. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/__init__.py +0 -0
  112. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_binary.py +0 -0
  113. {subsurface_terra-2025.1.0rc8/subsurface/modules/writer/to_rex → subsurface_terra-2025.1.0rc11/subsurface/modules/writer/to_liquid_earth}/__init__.py +0 -0
  114. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/common.py +0 -0
  115. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/data_struct.py +0 -0
  116. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/doc/rex-spec-v1.md +0 -0
  117. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/doc/right-handed.png +0 -0
  118. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/doc/sketchup_example.jpg +0 -0
  119. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/gempy_to_rexfile.py +0 -0
  120. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/material_encoder.py +0 -0
  121. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/mesh_encoder.py +0 -0
  122. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/to_rex.py +0 -0
  123. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/modules/writer/to_rex/utils.py +0 -0
  124. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface/optional_requirements.py +0 -0
  125. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface_terra.egg-info/dependency_links.txt +0 -0
  126. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface_terra.egg-info/not-zip-safe +0 -0
  127. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface_terra.egg-info/requires.txt +0 -0
  128. {subsurface_terra-2025.1.0rc8 → subsurface_terra-2025.1.0rc11}/subsurface_terra.egg-info/top_level.txt +0 -0
@@ -0,0 +1,60 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <template xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="671f325d-03f3-4855-994a-eb6080da9084" xsi:noNamespaceSchemaLocation="https://www.jetbrains.com/teamcity/schemas/2021.1/project-config.xsd">
3
+ <name>Release Subsurface</name>
4
+ <settings>
5
+ <parameters>
6
+ <param name="env.PACKAGE_VERSION" value="" spec="text description='The version that I want to release' label='Package version' validationMode='any' display='prompt'" />
7
+ <param name="env.TWINE_PASSWORD" value="credentialsJSON:e9a0b402-f8b3-4f86-978c-9c88c456dc9c" spec="password display='normal'" />
8
+ </parameters>
9
+ <build-runners>
10
+ <runner id="Git_Tagging" name="Git Tagging" type="simpleRunner">
11
+ <parameters>
12
+ <param name="script.content"><![CDATA[git tag v%env.PACKAGE_VERSION%
13
+ git push origin v%env.PACKAGE_VERSION%]]></param>
14
+ <param name="teamcity.step.mode" value="default" />
15
+ <param name="use.custom.script" value="true" />
16
+ </parameters>
17
+ </runner>
18
+ <runner id="Build" name="Build" type="simpleRunner">
19
+ <parameters>
20
+ <param name="script.content"><![CDATA[python -m pip install --upgrade build
21
+ python -m build]]></param>
22
+ <param name="teamcity.kubernetes.executor.pull.policy" value="IfNotPresent" />
23
+ <param name="teamcity.step.mode" value="default" />
24
+ <param name="use.custom.script" value="true" />
25
+ </parameters>
26
+ </runner>
27
+ <runner id="Push_to_PyPi" name="Push to PyPi" type="simpleRunner">
28
+ <parameters>
29
+ <param name="script.content"><![CDATA[python -m pip install --upgrade twine
30
+ python -m twine upload dist/* -u __token__ -p %env.TWINE_PASSWORD%]]></param>
31
+ <param name="teamcity.kubernetes.executor.pull.policy" value="IfNotPresent" />
32
+ <param name="teamcity.step.mode" value="default" />
33
+ <param name="use.custom.script" value="true" />
34
+ </parameters>
35
+ </runner>
36
+ <runner id="Push_To_GitHub" name="Push To GitHub" type="simpleRunner">
37
+ <parameters>
38
+ <param name="script.content" value="gh release create %env.PACKAGE_VERSION% dist/* --title &quot;%env.PACKAGE_VERSION%&quot; --notes &quot;Release notes here&quot;" />
39
+ <param name="teamcity.kubernetes.executor.pull.policy" value="IfNotPresent" />
40
+ <param name="teamcity.step.mode" value="default" />
41
+ <param name="use.custom.script" value="true" />
42
+ </parameters>
43
+ </runner>
44
+ </build-runners>
45
+ <vcs-settings>
46
+ <vcs-entry-ref root-id="Subsurface_HttpsGithubComTerranigmaSolutionsSubsurfaceRefsHeadsMain" />
47
+ </vcs-settings>
48
+ <requirements />
49
+ <build-triggers />
50
+ <build-extensions>
51
+ <extension id="BUILD_EXT_1" type="perfmon">
52
+ <parameters>
53
+ <param name="teamcity.perfmon.feature.enabled" value="true" />
54
+ </parameters>
55
+ </extension>
56
+ </build-extensions>
57
+ <cleanup />
58
+ </settings>
59
+ </template>
60
+
@@ -0,0 +1,37 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <build-type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="c15fb876-7044-47cd-a3b0-676767e4ca63" xsi:noNamespaceSchemaLocation="https://www.jetbrains.com/teamcity/schemas/2021.1/project-config.xsd">
3
+ <name>Release Subsurface</name>
4
+ <description />
5
+ <settings ref="ReleasePythonPackage">
6
+ <parameters />
7
+ <build-runners order="Git_Tagging, Build, Push_to_PyPi, Push_To_GitHub">
8
+ <runner id="Build" name="Build" type="simpleRunner">
9
+ <parameters>
10
+ <param name="script.content"><![CDATA[echo Cleaning build artifacts...
11
+ rmdir /s /q dist
12
+ rmdir /s /q build
13
+ echo Clean complete.
14
+
15
+ python -m pip install --upgrade build
16
+ python -m build]]></param>
17
+ <param name="teamcity.step.mode" value="default" />
18
+ <param name="use.custom.script" value="true" />
19
+ </parameters>
20
+ </runner>
21
+ <runner id="Push_To_GitHub" name="Push To GitHub" type="simpleRunner">
22
+ <parameters>
23
+ <param name="script.content" value="gh release create %env.PACKAGE_VERSION% dist/* --notes &quot;Release notes here&quot; --repo terranigma-solutions/subsurface" />
24
+ <param name="teamcity.step.mode" value="default" />
25
+ <param name="use.custom.script" value="true" />
26
+ </parameters>
27
+ </runner>
28
+ </build-runners>
29
+ <vcs-settings>
30
+ <vcs-entry-ref root-id="Subsurface_HttpsGithubComTerranigmaSolutionsSubsurfaceRefsHeadsMain1" />
31
+ </vcs-settings>
32
+ <requirements />
33
+ <build-triggers />
34
+ <cleanup />
35
+ </settings>
36
+ </build-type>
37
+
@@ -0,0 +1,129 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <build-type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="ed495f4f-4df2-4a37-bbfe-2489430a46e8" xsi:noNamespaceSchemaLocation="https://www.jetbrains.com/teamcity/schemas/2021.1/project-config.xsd">
3
+ <name>Testing</name>
4
+ <description />
5
+ <settings>
6
+ <parameters>
7
+ <param name="REQUIREMENT_LEVEL" value="READ_MESH" />
8
+ <param name="env.MPLBACKEND" value="Agg" />
9
+ <param name="env.PATH_TO_ASCII_DRILLHOLES" value="%env.TERRA_PATH_DEVOPS%/boreholes/ASCII_drillholes/" />
10
+ <param name="env.PATH_TO_BGR" value="%env.TERRA_PATH_DEVOPS%/boreholes/" />
11
+ <param name="env.PATH_TO_BOLIDEN" value="%env.TERRA_PATH_DEVOPS%/combined/Leapfrog_OMF/Garpenberg_global_20220715.omf" />
12
+ <param name="env.PATH_TO_GLB" value="%env.TERRA_PATH_DEVOPS%/meshes/GLB - GLTF/Duck.glb" />
13
+ <param name="env.PATH_TO_GLB_COMPLEX" value="%env.TERRA_PATH_DEVOPS%/meshes/GLB - GLTF/GlbFile.glb" />
14
+ <param name="env.PATH_TO_INTERPRETATION" value="%env.TERRA_PATH_DEVOPS%/meshes/Seismic/Anl2-1.tif" />
15
+ <param name="env.PATH_TO_MAGNETIC_INTERPRETATION" value="%env.TERRA_PATH_DEVOPS%/meshes/Magnetic/Plate 2a - Profile 1 2D inversion.pdf" />
16
+ <param name="env.PATH_TO_MTL" value="%env.TERRA_PATH_DEVOPS%/meshes/OBJ/Broadhaven_Obj/model/model.mtl" />
17
+ <param name="env.PATH_TO_OBJ" value="%env.TERRA_PATH_DEVOPS%/meshes/OBJ/Broadhaven_Obj/model/model.obj" />
18
+ <param name="env.PATH_TO_OBJ_FACE_I" value="%env.TERRA_PATH_DEVOPS%/meshes/OBJ/Faces/face1.obj" />
19
+ <param name="env.PATH_TO_OBJ_FACE_II" value="%env.TERRA_PATH_DEVOPS%/meshes/OBJ/Faces/Lapp_458_Rum_19_2_2024-02-21_0820_scan5_geoim4.obj" />
20
+ <param name="env.PATH_TO_OBJ_GALLERIES_I" value="%env.TERRA_PATH_DEVOPS%/meshes/OBJ/Galleries/Solid1.obj" />
21
+ <param name="env.PATH_TO_OBJ_MULTIMATERIAL_II" value="%env.TERRA_PATH_DEVOPS%/meshes/OBJ/MultiMaterialObj/MultiMaterialObj.obj" />
22
+ <param name="env.PATH_TO_OBJ_SCANS" value="%env.TERRA_PATH_DEVOPS%/meshes/OBJ/Core scans Boliden/rsrbF9l2zc/model.obj" />
23
+ <param name="env.PATH_TO_OMF" value="%env.TERRA_PATH_DEVOPS%/combined/Leapfrog_OMF/Collinstown.omf" />
24
+ <param name="env.PATH_TO_SECTION" value="%env.TERRA_PATH_DEVOPS%/meshes/Seismic/L1_CDP-Coords.txt" />
25
+ <param name="env.PATH_TO_SEISMIC" value="%env.TERRA_PATH_DEVOPS%/meshes/Seismic/Linie01.segy" />
26
+ <param name="env.PATH_TO_SEISMIC_FINAL" value="%env.TERRA_PATH_DEVOPS%/meshes/Seismic/L1_final-mig.sgy" />
27
+ <param name="env.PATH_TO_SPREMBERG_ASSAY" value="%env.TERRA_PATH_DEVOPS%/boreholes/Spremberg/Spremberg_assay.csv" />
28
+ <param name="env.PATH_TO_SPREMBERG_COLLAR" value="%env.TERRA_PATH_DEVOPS%/boreholes/Spremberg/Spremberg_collar_updated.csv" />
29
+ <param name="env.PATH_TO_SPREMBERG_STRATIGRAPHY" value="%env.TERRA_PATH_DEVOPS%/boreholes/Spremberg/Spremberg_stratigraphy.csv" />
30
+ <param name="env.PATH_TO_SPREMBERG_SURVEY" value="%env.TERRA_PATH_DEVOPS%/boreholes/Spremberg/Spremberg_survey.csv" />
31
+ <param name="env.PATH_TO_WEISWEILER" value="%env.TERRA_PATH_DEVOPS%/meshes/Weisweiler/" />
32
+ <param name="env.TERRA_PATH_DEVOPS" value="D:\OneDrive - Terranigma Solutions GmbH/Documents - Terranigma Base/DevOps/SubsurfaceTestData/" />
33
+ </parameters>
34
+ <build-runners>
35
+ <runner id="Setup" name="Setup" type="simpleRunner">
36
+ <parameters>
37
+ <param name="script.content"><![CDATA[@echo on
38
+ python -m venv venv
39
+ call venv\Scripts\activate
40
+ venv\Scripts\python -m pip install --upgrade pip
41
+
42
+ echo Checking directory...
43
+ dir
44
+ dir .requirements
45
+
46
+ venv\Scripts\pip install --verbose -r requirements/requirements_dev.txt
47
+ venv\Scripts\pip install --verbose teamcity-messages]]></param>
48
+ <param name="teamcity.step.mode" value="default" />
49
+ <param name="use.custom.script" value="true" />
50
+ </parameters>
51
+ </runner>
52
+ <runner id="Run_Test" name="Run Test: Core" type="simpleRunner">
53
+ <parameters>
54
+ <param name="script.content"><![CDATA[venv\Scripts\pip install --verbose -r requirements/requirements_plot.txt
55
+
56
+ @echo on
57
+ set REQUIREMENT_LEVEL=READ_MESH
58
+ echo REQUIREMENT_LEVEL is %REQUIREMENT_LEVEL%
59
+ venv\Scripts\python -m pytest --teamcity -v -m core]]></param>
60
+ <param name="teamcity.step.mode" value="default" />
61
+ <param name="use.custom.script" value="true" />
62
+ </parameters>
63
+ </runner>
64
+ <runner id="Run_Test_2" name="Run Test: Mesh" type="simpleRunner">
65
+ <parameters>
66
+ <param name="script.content"><![CDATA[venv\Scripts\pip install --verbose -r requirements/requirements_mesh.txt
67
+
68
+ @echo on
69
+ set REQUIREMENT_LEVEL=READ_MESH
70
+ echo REQUIREMENT_LEVEL is %REQUIREMENT_LEVEL%
71
+ venv\Scripts\python -m pytest --teamcity -v]]></param>
72
+ <param name="teamcity.step.mode" value="execute_if_failed" />
73
+ <param name="use.custom.script" value="true" />
74
+ </parameters>
75
+ </runner>
76
+ <runner id="Run_Test_wells" name="Run Test: Wells" type="simpleRunner">
77
+ <parameters>
78
+ <param name="script.content"><![CDATA[venv\Scripts\pip install --verbose -r requirements/requirements_wells.txt
79
+
80
+ @echo on
81
+ set REQUIREMENT_LEVEL=READ_WELL
82
+ echo REQUIREMENT_LEVEL is %REQUIREMENT_LEVEL%
83
+ venv\Scripts\python -m pytest --teamcity -v]]></param>
84
+ <param name="teamcity.step.mode" value="execute_if_failed" />
85
+ <param name="use.custom.script" value="true" />
86
+ </parameters>
87
+ </runner>
88
+ </build-runners>
89
+ <vcs-settings>
90
+ <vcs-entry-ref root-id="Subsurface_HttpsGithubComTerranigmaSolutionsSubsurfaceRefsHeadsMain2" />
91
+ </vcs-settings>
92
+ <requirements />
93
+ <build-triggers>
94
+ <build-trigger id="TRIGGER_4" type="vcsTrigger">
95
+ <parameters>
96
+ <param name="branchFilter"><![CDATA[+pr:draft=false
97
+ +:refs/heads/main]]></param>
98
+ <param name="enableQueueOptimization" value="true" />
99
+ <param name="quietPeriodMode" value="DO_NOT_USE" />
100
+ </parameters>
101
+ </build-trigger>
102
+ </build-triggers>
103
+ <build-extensions>
104
+ <extension id="perfmon" type="perfmon">
105
+ <parameters>
106
+ <param name="teamcity.perfmon.feature.enabled" value="true" />
107
+ </parameters>
108
+ </extension>
109
+ <extension id="BUILD_EXT_5" type="commit-status-publisher">
110
+ <parameters>
111
+ <param name="github_authentication_type" value="token" />
112
+ <param name="github_host" value="https://api.github.com" />
113
+ <param name="publisherId" value="githubStatusPublisher" />
114
+ <param name="secure:github_access_token" value="credentialsJSON:4df4bdb0-1278-4834-a702-18ae3a286003" />
115
+ </parameters>
116
+ </extension>
117
+ <extension id="BUILD_EXT_6" type="pullRequests">
118
+ <parameters>
119
+ <param name="authenticationType" value="token" />
120
+ <param name="filterAuthorRole" value="MEMBER" />
121
+ <param name="providerType" value="github" />
122
+ <param name="secure:accessToken" value="credentialsJSON:4df4bdb0-1278-4834-a702-18ae3a286003" />
123
+ </parameters>
124
+ </extension>
125
+ </build-extensions>
126
+ <cleanup />
127
+ </settings>
128
+ </build-type>
129
+
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="02a92682-f6c2-4edf-af46-08d095b0ce77" xsi:noNamespaceSchemaLocation="https://www.jetbrains.com/teamcity/schemas/2021.1/project-config.xsd">
3
+ <name>Subsurface</name>
4
+ <parameters />
5
+ <project-extensions>
6
+ <extension id="PROJECT_EXT_15" type="versionedSettings">
7
+ <parameters>
8
+ <param name="buildSettings" value="ALWAYS_USE_CURRENT" />
9
+ <param name="credentialsStorageType" value="credentialsJSON" />
10
+ <param name="enabled" value="true" />
11
+ <param name="ignoreChangesInDependenciesAndVcsSettings" value="false" />
12
+ <param name="rootId" value="Subsurface_HttpsGithubComTerranigmaSolutionsSubsurfaceRefsHeadsMain" />
13
+ <param name="showChanges" value="false" />
14
+ </parameters>
15
+ </extension>
16
+ </project-extensions>
17
+ <cleanup />
18
+ </project>
19
+
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <vcs-root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="b5c00aa4-356b-4c94-8113-009cde53f17b" type="jetbrains.git" xsi:noNamespaceSchemaLocation="https://www.jetbrains.com/teamcity/schemas/2021.1/project-config.xsd">
3
+ <name>https://github.com/terranigma-solutions/subsurface#refs/heads/main</name>
4
+ <param name="agentCleanFilesPolicy" value="ALL_UNTRACKED" />
5
+ <param name="agentCleanPolicy" value="ON_BRANCH_CHANGE" />
6
+ <param name="authMethod" value="PASSWORD" />
7
+ <param name="branch" value="refs/heads/main" />
8
+ <param name="ignoreKnownHosts" value="true" />
9
+ <param name="secure:password" value="credentialsJSON:4df4bdb0-1278-4834-a702-18ae3a286003" />
10
+ <param name="submoduleCheckout" value="CHECKOUT" />
11
+ <param name="teamcity:branchSpec" value="refs/heads/*" />
12
+ <param name="url" value="https://github.com/terranigma-solutions/subsurface" />
13
+ <param name="useAlternates" value="AUTO" />
14
+ <param name="username" value="Leguark" />
15
+ <param name="usernameStyle" value="USERID" />
16
+ </vcs-root>
17
+
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <vcs-root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="e9cb014a-3f5f-4e33-8d40-9c5cb180a9d6" type="jetbrains.git" xsi:noNamespaceSchemaLocation="https://www.jetbrains.com/teamcity/schemas/2021.1/project-config.xsd">
3
+ <name>https://github.com/terranigma-solutions/subsurface#refs/heads/main (1)</name>
4
+ <param name="agentCleanFilesPolicy" value="ALL_UNTRACKED" />
5
+ <param name="agentCleanPolicy" value="ON_BRANCH_CHANGE" />
6
+ <param name="authMethod" value="PASSWORD" />
7
+ <param name="branch" value="refs/heads/main" />
8
+ <param name="ignoreKnownHosts" value="true" />
9
+ <param name="secure:password" value="credentialsJSON:4df4bdb0-1278-4834-a702-18ae3a286003" />
10
+ <param name="submoduleCheckout" value="CHECKOUT" />
11
+ <param name="url" value="https://github.com/terranigma-solutions/subsurface" />
12
+ <param name="useAlternates" value="AUTO" />
13
+ <param name="username" value="Leguark" />
14
+ <param name="usernameStyle" value="USERID" />
15
+ </vcs-root>
16
+
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <vcs-root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" uuid="a5d752d7-0d2a-4197-b779-2049040d97ba" type="jetbrains.git" xsi:noNamespaceSchemaLocation="https://www.jetbrains.com/teamcity/schemas/2021.1/project-config.xsd">
3
+ <name>https://github.com/terranigma-solutions/subsurface#refs/heads/main (2)</name>
4
+ <param name="agentCleanFilesPolicy" value="ALL_UNTRACKED" />
5
+ <param name="agentCleanPolicy" value="ON_BRANCH_CHANGE" />
6
+ <param name="authMethod" value="PASSWORD" />
7
+ <param name="branch" value="refs/heads/main" />
8
+ <param name="ignoreKnownHosts" value="true" />
9
+ <param name="secure:password" value="credentialsJSON:4df4bdb0-1278-4834-a702-18ae3a286003" />
10
+ <param name="submoduleCheckout" value="CHECKOUT" />
11
+ <param name="url" value="https://github.com/terranigma-solutions/subsurface" />
12
+ <param name="useAlternates" value="AUTO" />
13
+ <param name="username" value="Leguark" />
14
+ <param name="usernameStyle" value="USERID" />
15
+ </vcs-root>
16
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: subsurface_terra
3
- Version: 2025.1.0rc8
3
+ Version: 2025.1.0rc11
4
4
  Summary: Subsurface data types and utilities. This version is the one used by Terranigma Solutions. Please feel free to take anything in this repository for the original one.
5
5
  Home-page: https://softwareunderground.github.io/subsurface
6
6
  Author: Software Underground
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2025.1.0rc8'
20
+ __version__ = version = '2025.1.0rc11'
21
21
  __version_tuple__ = version_tuple = (2025, 1, 0)
@@ -111,9 +111,11 @@ def _map_attrs_to_measured_depths(attrs: pd.DataFrame, survey: Survey) -> pd.Dat
111
111
 
112
112
  # Start with a copy of the existing attributes DataFrame
113
113
  new_attrs = survey.survey_trajectory.data.points_attributes.copy()
114
- if 'component lith' in attrs.columns:
114
+ if 'component lith' in attrs.columns and 'lith_ids' not in attrs.columns:
115
115
  # Factorize lith components directly in-place
116
116
  attrs['lith_ids'], _ = pd.factorize(attrs['component lith'], use_na_sentinel=True)
117
+ else:
118
+ pass
117
119
 
118
120
  # Add missing columns from attrs, preserving their dtypes
119
121
  for col in attrs.columns.difference(new_attrs.columns):
@@ -152,7 +154,7 @@ def _map_attrs_to_measured_depths(attrs: pd.DataFrame, survey: Survey) -> pd.Dat
152
154
  continue
153
155
  attr_to_interpolate = attrs_well[col]
154
156
  # make sure the attr_to_interpolate is not a string
155
- if attr_to_interpolate.dtype == 'O':
157
+ if attr_to_interpolate.dtype == 'O' or isinstance(attr_to_interpolate.dtype, pd.CategoricalDtype):
156
158
  continue
157
159
  if col in ['lith_ids', 'component lith']:
158
160
  interp_kind = 'nearest'
@@ -37,9 +37,9 @@ def load_with_trimesh(path_to_file_or_buffer, file_type: Optional[str] = None,
37
37
  # Old Z axis → New -Y axis
38
38
  # Old X axis → Remains as X axis
39
39
  transform = np.array([
40
- [1, 0, 0, 0], # X → X
41
- [0, 0, 1, 0], # Y → Z
42
- [0, 1, 0, 0], # Z → -Y
40
+ [1, 0, 0, 0],
41
+ [0, 0, -1, 0],
42
+ [0, 1, 0, 0],
43
43
  [0, 0, 0, 1]
44
44
  ])
45
45
 
@@ -157,7 +157,7 @@ def _process_mesh(mesh_lines) -> Optional[GOCADMesh]:
157
157
  continue
158
158
 
159
159
  if in_tface:
160
- if line.startswith('VRTX'):
160
+ if line.startswith('VRTX') or line.startswith('PVRTX'):
161
161
  # Parse vertex line
162
162
  parts = line.split()
163
163
  if len(parts) >= 5:
@@ -167,6 +167,7 @@ def _process_mesh(mesh_lines) -> Optional[GOCADMesh]:
167
167
  vertex_indices.append(vid)
168
168
  vertex_list.append([x, y, z])
169
169
  vid_to_index[vid] = len(vertex_list) - 1
170
+ # If PVRTX then there could be more columns with property values. For now, we are just parsing the vertex coordinates.
170
171
  continue
171
172
  elif line.startswith('ATOM'):
172
173
  # Parse ATOM line
@@ -0,0 +1,230 @@
1
+ import os
2
+ from io import BytesIO
3
+ from typing import Union
4
+
5
+ from subsurface.core.structs import StructuredData
6
+
7
+ from .... import optional_requirements
8
+ from ....core.structs import UnstructuredData
9
+ from subsurface.core.reader_helpers.readers_data import GenericReaderFilesHelper
10
+ import numpy as np
11
+ import pandas as pd
12
+
13
+
14
+ def read_VTK_structured_grid(file_or_buffer: Union[str, BytesIO], active_scalars: str) -> StructuredData:
15
+ pv = optional_requirements.require_pyvista()
16
+
17
+ if isinstance(file_or_buffer, BytesIO):
18
+ # If file_or_buffer is a BytesIO, write it to a temporary file
19
+ from tempfile import NamedTemporaryFile
20
+ with NamedTemporaryFile('wb', suffix='.vtk', delete=False) as temp_file:
21
+ # Write the BytesIO content to the temporary file
22
+ getvalue: bytes = file_or_buffer.getvalue()
23
+ temp_file.write(getvalue)
24
+ temp_file.flush() # Make sure all data is written
25
+ temp_file_name = temp_file.name # Store the temporary file name
26
+ try:
27
+ # Use pyvista.read() to read from the temporary file
28
+ pyvista_obj = pv.read(temp_file_name)
29
+ finally:
30
+ # Ensure the temporary file is deleted after reading
31
+ os.remove(temp_file_name)
32
+ else:
33
+ # If it's a file path, read directly
34
+ pyvista_obj = pv.read(file_or_buffer)
35
+ try:
36
+ pyvista_struct: pv.ExplicitStructuredGrid = pv_cast_to_explicit_structured_grid(pyvista_obj)
37
+ except Exception as e:
38
+ raise f"The file is not a structured grid: {e}"
39
+
40
+ if PLOT := False:
41
+ pyvista_struct.set_active_scalars(active_scalars)
42
+ pyvista_struct.plot()
43
+
44
+ struct: StructuredData = StructuredData.from_pyvista_structured_grid(
45
+ grid=pyvista_struct,
46
+ data_array_name=active_scalars
47
+ )
48
+
49
+ return struct
50
+
51
+
52
+ def read_volumetric_mesh_to_subsurface(reader_helper_coord: GenericReaderFilesHelper,
53
+ reader_helper_attr: GenericReaderFilesHelper) -> UnstructuredData:
54
+ df_coord = read_volumetric_mesh_coord_file(reader_helper_coord)
55
+ if len(df_coord.columns) == 1:
56
+ raise ValueError(
57
+ "The attributes file has only one column, probably the columns are not being separated correctly. Use 'sep' in Additional Reader Arguments"
58
+ )
59
+
60
+ df_attr = read_volumetric_mesh_attr_file(reader_helper_attr)
61
+ # Check if there are more than one column and if it is only one raise an error that probably the columns have not been properly separated. Use "sep" in Additional Reader Arguments
62
+ if len(df_attr.columns) == 1:
63
+ raise ValueError(
64
+ "The attributes file has only one column, probably the columns are not being separated correctly. Use 'sep' in Additional Reader Arguments"
65
+ )
66
+
67
+ combined_df = df_coord.merge(df_attr, left_index=True, right_index=True)
68
+ ud = UnstructuredData.from_array(
69
+ vertex=combined_df[['x', 'y', 'z']], cells="points",
70
+ attributes=combined_df[['pres', 'temp', 'sg', 'xco2']]
71
+ )
72
+ return ud
73
+
74
+
75
+ def read_volumetric_mesh_coord_file(reader_helper: GenericReaderFilesHelper) -> pd.DataFrame:
76
+ df = pd.read_csv(
77
+ filepath_or_buffer=reader_helper.file_or_buffer,
78
+ **reader_helper.pandas_reader_kwargs
79
+ )
80
+ if reader_helper.columns_map is not None:
81
+ df.rename(
82
+ mapper=reader_helper.columns_map,
83
+ axis="columns",
84
+ inplace=True
85
+ )
86
+
87
+ df.dropna(axis=0, inplace=True)
88
+
89
+ df.x = df.x.astype(float)
90
+ df.y = df.y.astype(float)
91
+ df.z = df.z.astype(float)
92
+ # Throw error if empty
93
+ if df.empty:
94
+ raise ValueError("The file is empty")
95
+
96
+ return df
97
+
98
+
99
+ def read_volumetric_mesh_attr_file(reader_helper: GenericReaderFilesHelper) -> pd.DataFrame:
100
+ df = pd.read_table(reader_helper.file_or_buffer, **reader_helper.pandas_reader_kwargs)
101
+ df.columns = df.columns.astype(str).str.strip()
102
+ return df
103
+
104
+
105
+ def pv_cast_to_explicit_structured_grid(pyvista_object: 'pv.DataSet') -> 'pv.ExplicitStructuredGrid':
106
+ pv = optional_requirements.require_pyvista()
107
+
108
+ match pyvista_object:
109
+ case pv.RectilinearGrid() as rectl_grid:
110
+ return __pv_convert_rectilinear_to_explicit(rectl_grid)
111
+ case pv.UnstructuredGrid() as unstr_grid:
112
+ return __pv_convert_unstructured_to_explicit(unstr_grid)
113
+ case _:
114
+ return pyvista_object.cast_to_explicit_structured_grid()
115
+
116
+
117
+ def __pv_convert_unstructured_to_explicit(unstr_grid):
118
+ """
119
+ Convert a PyVista UnstructuredGrid to an ExplicitStructuredGrid if possible.
120
+ """
121
+ pv = optional_requirements.require_pyvista()
122
+
123
+ # First check if the grid has the necessary attributes to be treated as structured
124
+ if not hasattr(unstr_grid, 'n_cells') or unstr_grid.n_cells == 0:
125
+ raise ValueError("The unstructured grid has no cells.")
126
+
127
+ # Try to detect if the grid has a structured topology
128
+ # Check if the grid has cell type 11 (VTK_VOXEL) or 12 (VTK_HEXAHEDRON)
129
+ cell_types = unstr_grid.celltypes
130
+
131
+ # Voxels (11) and hexahedra (12) are the cell types used in structured grids
132
+ if not all(ct in [11, 12] for ct in cell_types):
133
+ raise ValueError("The unstructured grid contains non-hexahedral cells and cannot be converted to explicit structured.")
134
+
135
+ # Try to infer dimensions from the grid
136
+ try:
137
+ # Method 1: Try PyVista's built-in conversion if available
138
+ return unstr_grid.cast_to_explicit_structured_grid()
139
+ except (AttributeError, TypeError):
140
+ pass
141
+
142
+ try:
143
+ # Method 2: If the grid has dimensions stored as field data
144
+ if "dimensions" in unstr_grid.field_data:
145
+ dims = unstr_grid.field_data["dimensions"]
146
+ if len(dims) == 3:
147
+ nx, ny, nz = dims
148
+ # Verify that dimensions match the number of cells
149
+ if (nx-1)*(ny-1)*(nz-1) != unstr_grid.n_cells:
150
+ raise ValueError("Stored dimensions do not match the number of cells.")
151
+
152
+ # Extract points and reorder if needed
153
+ points = unstr_grid.points.reshape((nx, ny, nz, 3))
154
+
155
+ # Create explicit structured grid
156
+ explicit_grid = pv.ExplicitStructuredGrid((nx, ny, nz), points.reshape((-1, 3)))
157
+ explicit_grid.compute_connectivity()
158
+
159
+ # Transfer data arrays
160
+ for name, array in unstr_grid.cell_data.items():
161
+ explicit_grid.cell_data[name] = array.copy()
162
+ for name, array in unstr_grid.point_data.items():
163
+ explicit_grid.point_data[name] = array.copy()
164
+ for name, array in unstr_grid.field_data.items():
165
+ if name != "dimensions": # Skip dimensions field
166
+ explicit_grid.field_data[name] = array.copy()
167
+
168
+ return explicit_grid
169
+ except (ValueError, KeyError):
170
+ pass
171
+
172
+ # If none of the above methods work, use PyVista's extract_cells function
173
+ # to reconstruct the structured grid if possible
174
+ try:
175
+ # This is a best-effort approach that tries multiple strategies
176
+ return pv.core.filters.convert_unstructured_to_structured_grid(unstr_grid)
177
+ except Exception as e:
178
+ raise ValueError(f"Failed to convert unstructured grid to explicit structured grid: {e}")
179
+
180
+ def __pv_convert_rectilinear_to_explicit(rectl_grid):
181
+
182
+ pv = optional_requirements.require_pyvista()
183
+
184
+ # Extract the coordinate arrays from the input RectilinearGrid.
185
+ x = np.asarray(rectl_grid.x)
186
+ y = np.asarray(rectl_grid.y)
187
+ z = np.asarray(rectl_grid.z)
188
+
189
+ # Helper function: "double" the coordinates to produce an expanded set
190
+ # that, when processed internally via np.unique, returns the original nodal values.
191
+ def doubled_coords(arr):
192
+ return np.repeat(arr, 2)[1:-1]
193
+
194
+ # Double the coordinate arrays.
195
+ xcorn = doubled_coords(x)
196
+ ycorn = doubled_coords(y)
197
+ zcorn = doubled_coords(z)
198
+
199
+ # Build a complete grid of corner points via meshgrid. Fortran ('F') order ensures
200
+ # the connectivity ordering aligns with VTK's expectations.
201
+ xx, yy, zz = np.meshgrid(xcorn, ycorn, zcorn, indexing='ij')
202
+ corners = np.column_stack((xx.ravel(order='F'),
203
+ yy.ravel(order='F'),
204
+ zz.ravel(order='F')))
205
+
206
+ # The dimensions to pass to the ExplicitStructuredGrid constructor should be
207
+ # the counts of unique coordinates in each direction.
208
+ dims = (len(np.unique(xcorn)),
209
+ len(np.unique(ycorn)),
210
+ len(np.unique(zcorn)))
211
+
212
+ # Create the ExplicitStructuredGrid.
213
+ explicit_grid = pv.ExplicitStructuredGrid(dims, corners)
214
+ explicit_grid.compute_connectivity()
215
+
216
+ # --- Copy associated data arrays ---
217
+
218
+ # Transfer all cell data arrays.
219
+ for name, array in rectl_grid.cell_data.items():
220
+ explicit_grid.cell_data[name] = array.copy()
221
+
222
+ # Transfer all point data arrays.
223
+ for name, array in rectl_grid.point_data.items():
224
+ explicit_grid.point_data[name] = array.copy()
225
+
226
+ # (Optional) Transfer field data as well.
227
+ for name, array in rectl_grid.field_data.items():
228
+ explicit_grid.field_data[name] = array.copy()
229
+
230
+ return explicit_grid
@@ -100,6 +100,16 @@ def _validate_lith_data(d: pd.DataFrame, reader_helper: GenericReaderFilesHelper
100
100
  raise AttributeError('If wells attributes represent lithology, `component lith` column must be present in the file. '
101
101
  'Use columns_map to assign column names to these fields. Maybe you are marking as lithology'
102
102
  'the wrong file?')
103
+ else:
104
+ # TODO: Add categories to reader helper
105
+ categories = sorted(d['component lith'].dropna().unique())
106
+ d['component lith'] = pd.Categorical(
107
+ d['component lith'],
108
+ categories=categories,
109
+ ordered=True
110
+ )
111
+
112
+ d['lith_ids'] = d['component lith'].cat.codes + 1
103
113
 
104
114
  given_top = np.isin(['top', 'base'], d.columns).all()
105
115
  given_altitude_and_base = np.isin(['altitude', 'base'], d.columns).all()