import pandas as pdimport pathlibfrom bsdd import Clientfrom bdns_plus.abbreviations import get_bdns_asset_abbreviations, get_asset_abbreviations_enum, get_asset_abbreviationsfrom itables import showimport pandas as pdimport reIFC4X3_URI ="https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3"def ifc_strip_enum(ifc_class):return re.sub(r"([A-Z0-9_]+_?)$", "", ifc_class) def ifc_class_is_enum(ifc_class):if ifc_strip_enum(ifc_class) == ifc_class:returnFalseelse:returnTruedef get_ifc_classes(client):def get_batch(i):return client.get_classes( IFC4X3_URI, use_nested_classes=False, class_type="Class", offset=i[0], limit=i[1], )["classes"] ifc_classes = {}for i in [(0, 1000), (1000, 2000)]: # 1418 classes in total. 1000 max request limit ifc_classes = ifc_classes | {x["code"]: x for x in get_batch(i)}return ifc_classesclient = Client()ifc_classes = get_ifc_classes(client)ifc_classes_core = {k:v for k, v in ifc_classes.items() ifnot ifc_class_is_enum(k)}bdns_abbreviations = get_bdns_asset_abbreviations()map_bdns_ifc = {x[1]: x[-2] for x in bdns_abbreviations[1:]}ifc_in_bdns =set([x[-2] for x in bdns_abbreviations[1:]])map_ifc_bdns = {}for ifc in ifc_in_bdns: map_ifc_bdns[ifc] = [k for k, v in map_bdns_ifc.items() if v == ifc]core_map_ifc_bdns = {k:v for k,v in map_ifc_bdns.items() ifnot ifc_class_is_enum(k)}_map_ifc_bdns = {k: [str(v)] for k, v in map_ifc_bdns.items()}df_ifc_map_bdns = pd.DataFrame.from_dict(_map_ifc_bdns).T.reset_index().rename(columns={"index":"ifc4_3", 0:"bdns_abbreviation"})# show(df_ifc_map_bdns)
Quantifying the task of adding at least 1no bdns abbreviation for every core IFC4x3 class
Code
print(f"len(ifc_classes) = {len(ifc_classes)} ")print(f"len(ifc_classes_core) = {len(ifc_classes_core)} (i.e. without the enum, e.g. IfcValve)")print(f"len(core_map_ifc_bdns) = {len(core_map_ifc_bdns)} (i.e. number of core Ifc classes with at least 1no mapping to an abbreviation)")
IfcClass’s that only have enums in BDNS, not the core class
Code
ifc_missing_core =sorted([x for x inlist(set([ifc_strip_enum(x) for x in ifc_in_bdns])) if x notin core_map_ifc_bdns])bdns_data = [x + [ifc_strip_enum(x[4])] for x in bdns_abbreviations[1:]] # add ifc core colprint(f"len(ifc_missing_core) = {len(ifc_missing_core)}")print(f"-----")for k, v in {x: [f"{b[4]} - {b[0]} - {b[1]}"for b in bdns_data if x == b[6]] for x in ifc_missing_core}.items():print(k)for _ in v:print(f" {_}")
Code
def add_descriptions(abbreviations): map_abbreviation_description = get_asset_abbreviations()return [f"{x} - {map_abbreviation_description[x]}"for x in abbreviations]core_map_ifc_bdns_descriptions = {k: add_descriptions(v) for k, v in core_map_ifc_bdns.items()}core_map_ifc_bdns_one_to_one = {k:v[0] for k, v in core_map_ifc_bdns.items() iflen(v) ==1}# br = """# """br ="<br>"updates = {'IfcDamper': 'DMP','IfcCableSegment': 'CA','IfcController': 'CNTRL','IfcCompressor': 'CMP','IfcLightFixture': 'LT','IfcChiller': 'CH','IfcWindow': 'WD','IfcOutlet': 'OUT','IfcTransformer': 'TXMR','IfcPump': 'PMP','IfcFlowMeter': 'MTR','IfcSpaceHeater': 'HTR','IfcFan': 'FAN','IfcFilter': 'FLT','IfcAirTerminal': 'AT'}core_map_ifc_bdns_descriptions_str = {k: [br.join(v)] for k,v in core_map_ifc_bdns_descriptions.items()}df = pd.DataFrame.from_dict(core_map_ifc_bdns_descriptions_str).T.reset_index().rename(columns={"index":"ifc_class", 0: "bdns_options"})df["bdns_core"] = df.ifc_class.map(core_map_ifc_bdns_one_to_one)df["bdns_suggested_updates"] = df.ifc_class.map(updates)# df.to_csv("map.csv")df.fillna("").style