added all info
This commit is contained in:
commit
e0c40da5d0
94 changed files with 5197859 additions and 0 deletions
38
ontology_guidance/get_onto_guidance_actions_per_asset.py
Normal file
38
ontology_guidance/get_onto_guidance_actions_per_asset.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
"""
|
||||
Static actions-per-asset lookup (the inverse of assets-per-action).
|
||||
|
||||
Served from a hardcoded dict that is the inverse of ASSETS_PER_ACTION in
|
||||
get_onto_guidance_assets_per_action. If the ontology changes, update
|
||||
ASSETS_PER_ACTION (the single source of truth); this module inverts it
|
||||
automatically at import time.
|
||||
"""
|
||||
|
||||
# --- invert ASSETS_PER_ACTION (single source of truth) ---
|
||||
try:
|
||||
from ontology_guidance.get_onto_guidance_assets_per_action import ASSETS_PER_ACTION
|
||||
except ImportError: # when run as a script from inside the ontology_guidance/ dir
|
||||
from get_onto_guidance_assets_per_action import ASSETS_PER_ACTION
|
||||
|
||||
|
||||
def _normalize(name: str) -> str:
|
||||
"""Normalize an asset/action string for matching (strip + lowercase)."""
|
||||
return name.strip().lower()
|
||||
|
||||
|
||||
# normalized asset name -> list of valid action names (as they appear in ASSETS_PER_ACTION)
|
||||
ACTIONS_PER_ASSET: dict[str, list[str]] = {}
|
||||
for _action, _assets in ASSETS_PER_ACTION.items():
|
||||
for _asset in _assets:
|
||||
_key = _normalize(_asset)
|
||||
ACTIONS_PER_ASSET.setdefault(_key, [])
|
||||
if _action not in ACTIONS_PER_ASSET[_key]:
|
||||
ACTIONS_PER_ASSET[_key].append(_action)
|
||||
|
||||
|
||||
def get_ontology_info_actions_per_asset(asset_search_name: str) -> list[str]:
|
||||
"""Return the actions valid for an asset name.
|
||||
|
||||
Case-insensitive / whitespace-insensitive match against the inverted
|
||||
ASSETS_PER_ACTION mapping. Returns [] if the asset is unknown.
|
||||
"""
|
||||
return ACTIONS_PER_ASSET.get(_normalize(asset_search_name), [])
|
||||
30
ontology_guidance/get_onto_guidance_assets_per_action.py
Normal file
30
ontology_guidance/get_onto_guidance_assets_per_action.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"""
|
||||
Static assets-per-action lookup: the valid asset types for each action, used as
|
||||
the ontology's single source of truth. Case-insensitive prefix match on the
|
||||
action name.
|
||||
"""
|
||||
|
||||
ASSETS_PER_ACTION = {'Feeder schoongemaakt': ["BAMBU LAB P1S", "BAMBU LAB X1 CARBON", "Bambu Lab P1S Combo", "UM2+ Connect"],
|
||||
'Nieuwe nozzle': ["BAMBU LAB P1S", "BAMBU LAB X1 CARBON", "UM2+ Connect"],
|
||||
'Vervangen Bambu Lab Hotend met geharde staal nozzle': ["BAMBU LAB P1S", "BAMBU LAB X1 CARBON", "Bambu Lab P1S Combo"],
|
||||
'Nieuwe TFM Coupler': ["BAMBU LAB P1S", "UM2+ Connect"],
|
||||
'Assen gesmeerd': ["Build Chamber", "BAMBU LAB P1S", "BAMBU LAB X1 CARBON", "UM2+ Connect"],
|
||||
'Vervangen Bambu Lab Compleet hotend met geharde staal nozzle': ["BAMBU LAB P1S", "BAMBU LAB X1 CARBON", "Bambu Lab P1S Combo", "BigRep Studio G2"],
|
||||
}
|
||||
|
||||
|
||||
def get_ontology_info_assets_per_action(action_search_name: str) -> list[str] | None:
|
||||
"""Return the valid asset types for an action name, or None if the action is
|
||||
unknown to the ontology.
|
||||
|
||||
Case-insensitive prefix match on the action name. None (not []) signals
|
||||
"unknown action" so callers can stay silent; build_invalid_row_mask treats
|
||||
None as "no guidance signal".
|
||||
"""
|
||||
needle = action_search_name.lower().strip()
|
||||
for key, assets in ASSETS_PER_ACTION.items():
|
||||
# case-insensitive on BOTH sides: keys here are Title-case, needle is lowered,
|
||||
# so comparing raw would never match (this silently disabled all guidance).
|
||||
if key.lower().startswith(needle):
|
||||
return assets
|
||||
return None
|
||||
68
ontology_guidance/ontology_guidance.py
Normal file
68
ontology_guidance/ontology_guidance.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
"""
|
||||
Ontology-guided rule learning: compute violations for MDL-Bayes prior placement.
|
||||
|
||||
Placement 3 (compute_ruleset_dl): penalty on description length
|
||||
- min total_DL ≡ max P(theory) · P(data | theory)
|
||||
- Adding λ · viol to the theory DL is equivalent to placing an ontology-informed prior
|
||||
- MDL ↔ Bayes correspondence (Rissanen, Grünwald 2007)
|
||||
|
||||
Violation: when a rule for action type covers data with an invalid asset type.
|
||||
Use get_ontology_info_assets_per_action() to determine valid (action, asset) pairs.
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from helper_functions.build_invalid_row_mask import build_invalid_row_mask
|
||||
|
||||
|
||||
def compute_rule_viol(rule, action_type, data, invalid_row_mask=None):
|
||||
"""
|
||||
Count ontology violations for a single rule (list of conjuncts).
|
||||
Returns the number of rows the rule covers whose assetType is invalid
|
||||
for action_type. invalid_row_mask can be precomputed on a superset
|
||||
(e.g. all_data) — it's sliced to data.index here.
|
||||
"""
|
||||
if not rule:
|
||||
return 0 # grow always starts non-empty; treat empty rule as 0 violations
|
||||
|
||||
if invalid_row_mask is None:
|
||||
invalid_row_mask = build_invalid_row_mask(action_type, data)
|
||||
if invalid_row_mask is None:
|
||||
return 0
|
||||
else:
|
||||
# Align to the active subset — the mask may have been built on a superset.
|
||||
invalid_row_mask = invalid_row_mask.loc[data.index]
|
||||
|
||||
mask = pd.Series(True, index=data.index)
|
||||
for cond in rule:
|
||||
if cond.startswith('!'):
|
||||
mask &= data[cond[1:]] == False
|
||||
else:
|
||||
mask &= data[cond] == True
|
||||
return int((mask & invalid_row_mask).sum())
|
||||
|
||||
|
||||
def compute_ontology_viol(rules, action_type, data):
|
||||
"""
|
||||
Count ontology violations: rows covered by rules that have invalid (asset, action) pairs.
|
||||
|
||||
Vectorized: builds one boolean mask per rule, intersects with an
|
||||
"invalid-asset" row mask precomputed once for the action type.
|
||||
"""
|
||||
invalid_row_mask = build_invalid_row_mask(action_type, data)
|
||||
if invalid_row_mask is None:
|
||||
return 0
|
||||
|
||||
covered = pd.Series(False, index=data.index)
|
||||
for rule in rules:
|
||||
if not rule:
|
||||
continue
|
||||
mask = pd.Series(True, index=data.index)
|
||||
for cond in rule:
|
||||
if cond.startswith('!'):
|
||||
mask &= data[cond[1:]] == False
|
||||
else:
|
||||
mask &= data[cond] == True
|
||||
covered |= mask
|
||||
|
||||
return int((covered & invalid_row_mask).sum())
|
||||
Loading…
Add table
Add a link
Reference in a new issue