|
| 1 | +import os |
| 2 | +import sys |
| 3 | +import logging |
| 4 | +from energyml.utils.epc_stream import EpcStreamReader, RelsUpdateMode |
| 5 | +from energyml.eml.v2_3.commonv2 import Citation |
| 6 | +from energyml.resqml.v2_2.resqmlv2 import ( |
| 7 | + TriangulatedSetRepresentation, |
| 8 | + BoundaryFeatureInterpretation, |
| 9 | + BoundaryFeature, |
| 10 | + HorizonInterpretation, |
| 11 | +) |
| 12 | +from energyml.utils.introspection import epoch_to_date, epoch |
| 13 | +from energyml.utils.epc import as_dor, gen_uuid, get_obj_identifier |
| 14 | +from energyml.utils.constants import EPCRelsRelationshipType |
| 15 | + |
| 16 | + |
| 17 | +def sample_objects(): |
| 18 | + """Create sample EnergyML objects for testing.""" |
| 19 | + # Create a BoundaryFeature |
| 20 | + bf = BoundaryFeature( |
| 21 | + citation=Citation( |
| 22 | + title="Test Boundary Feature", |
| 23 | + originator="Test", |
| 24 | + creation=epoch_to_date(epoch()), |
| 25 | + ), |
| 26 | + uuid="25773477-ffee-4cc2-867d-000000000001", |
| 27 | + object_version="1.0", |
| 28 | + ) |
| 29 | + |
| 30 | + # Create a BoundaryFeatureInterpretation |
| 31 | + bfi = BoundaryFeatureInterpretation( |
| 32 | + citation=Citation( |
| 33 | + title="Test Boundary Feature Interpretation", |
| 34 | + originator="Test", |
| 35 | + creation=epoch_to_date(epoch()), |
| 36 | + ), |
| 37 | + uuid="25773477-ffee-4cc2-867d-000000000002", |
| 38 | + object_version="1.0", |
| 39 | + interpreted_feature=as_dor(bf), |
| 40 | + ) |
| 41 | + |
| 42 | + # Create a HorizonInterpretation (independent object) |
| 43 | + horizon_interp = HorizonInterpretation( |
| 44 | + citation=Citation( |
| 45 | + title="Test HorizonInterpretation", |
| 46 | + originator="Test", |
| 47 | + creation=epoch_to_date(epoch()), |
| 48 | + ), |
| 49 | + interpreted_feature=as_dor(bf), |
| 50 | + uuid="25773477-ffee-4cc2-867d-000000000003", |
| 51 | + object_version="1.0", |
| 52 | + domain="depth", |
| 53 | + ) |
| 54 | + |
| 55 | + # Create a TriangulatedSetRepresentation |
| 56 | + trset = TriangulatedSetRepresentation( |
| 57 | + citation=Citation( |
| 58 | + title="Test TriangulatedSetRepresentation", |
| 59 | + originator="Test", |
| 60 | + creation=epoch_to_date(epoch()), |
| 61 | + ), |
| 62 | + uuid="25773477-ffee-4cc2-867d-000000000004", |
| 63 | + object_version="1.0", |
| 64 | + represented_object=as_dor(horizon_interp), |
| 65 | + ) |
| 66 | + |
| 67 | + return { |
| 68 | + "bf": bf, |
| 69 | + "bfi": bfi, |
| 70 | + "trset": trset, |
| 71 | + "horizon_interp": horizon_interp, |
| 72 | + } |
| 73 | + |
| 74 | + |
| 75 | +def main(epc_file_path: str): |
| 76 | + epc = EpcStreamReader( |
| 77 | + epc_file_path=epc_file_path, enable_parallel_rels=True, rels_update_mode=RelsUpdateMode.UPDATE_AT_MODIFICATION |
| 78 | + ) |
| 79 | + |
| 80 | + # logging.info(epc.get_statistics()) |
| 81 | + |
| 82 | + for obj in epc.list_objects(): |
| 83 | + logging.info(f"Object: {obj}") |
| 84 | + |
| 85 | + |
| 86 | +def test_create_epc(path: str): |
| 87 | + # delete file if exists |
| 88 | + if os.path.exists(path): |
| 89 | + os.remove(path) |
| 90 | + logging.info(f"==> Creating new EPC at {path}...") |
| 91 | + epc = EpcStreamReader(epc_file_path=path, rels_update_mode=RelsUpdateMode.UPDATE_AT_MODIFICATION) |
| 92 | + |
| 93 | + data = sample_objects() |
| 94 | + |
| 95 | + logging.info("==> Creating sample objects and adding to EPC...") |
| 96 | + |
| 97 | + logging.info("==> Adding horizon interpretation") |
| 98 | + epc.add_object(data["horizon_interp"]) |
| 99 | + logging.info(f"horizon rels : {epc.get_obj_rels(data['horizon_interp'])}") |
| 100 | + |
| 101 | + logging.info("==> Adding boundary feature") |
| 102 | + epc.add_object(data["bf"]) |
| 103 | + logging.info(f"boundary feature rels : {epc.get_obj_rels(data['bf'])}") |
| 104 | + |
| 105 | + logging.info("==> Adding boundary feature interpretation") |
| 106 | + epc.add_object(data["bfi"]) |
| 107 | + logging.info("==> Adding triangulated set representation") |
| 108 | + epc.add_object(data["trset"]) |
| 109 | + |
| 110 | + # Debug: Print all metadata identifiers |
| 111 | + logging.info(f"==> All metadata identifiers: {list(epc._metadata_mgr._metadata.keys())}") |
| 112 | + |
| 113 | + logging.info("==> All objects added. Closing EPC to write to disk.") |
| 114 | + |
| 115 | + horizon_id = get_obj_identifier(data["horizon_interp"]) |
| 116 | + logging.info(f"==> Horizon identifier: {horizon_id}") |
| 117 | + logging.info(f"==> Horizon in metadata: {horizon_id in epc._metadata_mgr._metadata}") |
| 118 | + |
| 119 | + # Debug: Test _id_from_uri_or_identifier |
| 120 | + resolved_id = epc._id_from_uri_or_identifier(data["horizon_interp"]) |
| 121 | + logging.info(f"==> Resolved ID from object: {resolved_id}") |
| 122 | + logging.info( |
| 123 | + f"==> Resolved ID in metadata: {resolved_id in epc._metadata_mgr._metadata if resolved_id else 'ID is None'}" |
| 124 | + ) |
| 125 | + |
| 126 | + horizon_rels = epc.get_obj_rels(data["horizon_interp"]) |
| 127 | + assert ( |
| 128 | + len(horizon_rels) == 2 |
| 129 | + ), f"Expected 2 relationships in horizon rels since both bfi and trset should refer to horizon as interpreted feature {horizon_rels}" |
| 130 | + epc.close() |
| 131 | + |
| 132 | + epc_reopen = EpcStreamReader(epc_file_path=path, rels_update_mode=RelsUpdateMode.UPDATE_AT_MODIFICATION) |
| 133 | + |
| 134 | + horizon_rels = epc_reopen.get_obj_rels(data["horizon_interp"]) |
| 135 | + assert ( |
| 136 | + len(horizon_rels) == 2 |
| 137 | + ), f"Expected 2 relationships in horizon rels since both bfi and trset should refer to horizon as interpreted feature {horizon_rels}" |
| 138 | + |
| 139 | + logging.info("==> Reopened EPC, listing objects:") |
| 140 | + for obj in epc_reopen.list_objects(): |
| 141 | + logging.info(f"Object: {obj}") |
| 142 | + obj_rels = epc_reopen.get_obj_rels(obj) |
| 143 | + logging.info(f"\tObject rels: {obj_rels}") |
| 144 | + dest_rels = [r for r in obj_rels if r.type_value == str(EPCRelsRelationshipType.DESTINATION_OBJECT)] |
| 145 | + logging.info(f"\tObject DESTINATION rels: {dest_rels}") |
| 146 | + |
| 147 | + # remove trset to check if horizon has no more source rels |
| 148 | + epc_reopen.remove_object(data["trset"]) |
| 149 | + |
| 150 | + horizon_rels_after_removal = epc_reopen.get_obj_rels(data["horizon_interp"]) |
| 151 | + logging.info(f"Horizon interpretation rels after removing trset: {horizon_rels_after_removal}") |
| 152 | + source_rels_after_removal = [ |
| 153 | + r for r in horizon_rels_after_removal if r.type_value == str(EPCRelsRelationshipType.SOURCE_OBJECT) |
| 154 | + ] |
| 155 | + logging.info(f"Horizon interpretation SOURCE rels after removing trset: {source_rels_after_removal}") |
| 156 | + assert ( |
| 157 | + len(source_rels_after_removal) == 0 |
| 158 | + ), "Expected no SOURCE relationships in horizon rels after removing trset since trset was the only destination referring to horizon" |
| 159 | + |
| 160 | + assert ( |
| 161 | + len(horizon_rels_after_removal) == 1 |
| 162 | + ), "Expected 1 relationship in horizon rels after removing trset since bfi should still refer to horizon as interpreted feature" |
| 163 | + |
| 164 | + epc_reopen.close() |
| 165 | + |
| 166 | + |
| 167 | +def test_create_epc_v2(path: str): |
| 168 | + |
| 169 | + if os.path.exists(path): |
| 170 | + os.remove(path) |
| 171 | + logging.info(f"==> Creating new EPC at {path}...") |
| 172 | + epc = EpcStreamReader(epc_file_path=path, rels_update_mode=RelsUpdateMode.UPDATE_AT_MODIFICATION) |
| 173 | + |
| 174 | + data = sample_objects() |
| 175 | + |
| 176 | + epc.add_object(data["bf"]) |
| 177 | + # epc.add_object(data["bfi"]) |
| 178 | + epc.add_object(data["horizon_interp"]) |
| 179 | + epc.add_object(data["trset"]) |
| 180 | + |
| 181 | + hi_rels = epc.get_obj_rels(data["horizon_interp"]) |
| 182 | + |
| 183 | + logging.info(f"Horizon interpretation rels: {hi_rels}") |
| 184 | + |
| 185 | + |
| 186 | +if __name__ == "__main__": |
| 187 | + logging.basicConfig(level=logging.DEBUG) |
| 188 | + |
| 189 | + # main((sys.argv[1] if len(sys.argv) > 1 else None) or "wip/80wells_surf.epc") |
| 190 | + |
| 191 | + # test_create_epc("wip/test_create.epc") |
| 192 | + test_create_epc_v2("wip/test_create.epc") |
0 commit comments