"""Module for reading data not supported by other tools"""from__future__importannotationsimporthashlibimportjsonfromdataclassesimportdataclass,fieldfrompathlibimportPath
[docs]defread_faultroom_file(filename:str|Path)->FaultRoomSurface:"""Faultroom surface data are (geo)JSON file or dicts; needs separate handling. Faultroom data are quite propriatary data and is not supported by e.g. xtgeo currently. Hence it is read locally. As input, both a dict and a file with extension .json og .geojson can be applied """filename=Path(filename)if"json"infilename.suffix.lower():# try read the (geo)json filewithopen(filename,encoding="utf-8")asstream:dict_obj=json.load(stream)if("metadata"indict_objand"source"indict_obj["metadata"]and"FaultRoom"indict_obj["metadata"]["source"]):returnFaultRoomSurface(dict_obj)raiseValueError(f"Cannot read faultroom file. Check if file <{filename}> really is ""on FaultRoom format, and has extension 'json' or 'geojson'")
[docs]@dataclassclassFaultRoomSurface:"""Parse the requested props from FaultRoom plugin output format."""storage:dicthorizons:list=field(default_factory=list,init=False)faults:list=field(default_factory=list,init=False)juxtaposition_fw:list=field(default_factory=list,init=False)juxtaposition_hw:list=field(default_factory=list,init=False)properties:list=field(default_factory=list,init=False)bbox:dict=field(default_factory=dict,init=False)name:str=field(default="",init=False)tagname:str=field(default="faultroom",init=False)def__post_init__(self)->None:self._set_horizons()self._set_faults()self._set_juxtaposition()self._set_properties()self._set_bbox()self._derive_names()def_set_horizons(self)->None:self.horizons=self.storage["metadata"].get("horizons")def_set_faults(self)->None:self.faults=self.storage["metadata"]["faults"].get("default")def_set_juxtaposition(self)->None:self.juxtaposition_fw=self.storage["metadata"]["juxtaposition"].get("fw")self.juxtaposition_hw=self.storage["metadata"]["juxtaposition"].get("hw")def_set_properties(self)->None:self.properties=self.storage["metadata"].get("properties")def_set_bbox(self)->None:"""To get the bounding box, need to scan data."""xmin=ymin=zmin=float("inf")xmax=ymax=zmax=float("-inf")forfeatureinself.storage["features"]:fortriangleinfeature["geometry"]["coordinates"]:forcoordsintriangle:xcoord,ycoord,zcoord=coordsxmin=min(xcoord,xmin)ymin=min(ycoord,ymin)zmin=min(zcoord,zmin)xmax=max(xcoord,xmax)ymax=max(ycoord,ymax)zmax=max(zcoord,zmax)self.bbox={"xmin":xmin,"xmax":xmax,"ymin":ymin,"ymax":ymax,"zmin":zmin,"zmax":zmax,}def_derive_names(self)->None:"""A descriptive name based on metadata for faultroom data. The name also includes as short ID based on hash, since there may possible ways to make a horizon with multiple (complex) juxtapositions. """self.name="_".join(self.horizons)file_name="_".join(self.horizons).lower()hash_input=(file_name+"_".join(self.juxtaposition_fw)+"_".join(self.juxtaposition_hw))short_hash=hashlib.sha1(hash_input.encode("utf-8")).hexdigest()[:7]self.tagname="faultroom"+"_"+short_hash