Skip to content

Commit

Permalink
Merge pull request #70 from StanfordVL/full-transition-rules
Browse files Browse the repository at this point in the history
Full transition rules
  • Loading branch information
cgokmen authored Aug 23, 2023
2 parents 6010011 + b9fb7c1 commit 068c97d
Show file tree
Hide file tree
Showing 12 changed files with 1,585 additions and 906 deletions.
11 changes: 8 additions & 3 deletions bddl/data_generation/generate_datafiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from bddl.data_generation.get_syn_prop_annots_canonical import create_get_save_annots_canonical, create_get_save_properties_to_synsets, create_get_save_synsets_to_descriptors
from bddl.data_generation.propagate_by_intersection import create_get_save_propagated_canonical
from bddl.data_generation.process_prop_param_annots import create_get_save_propagated_annots_params
from bddl.data_generation.get_implicit_transition_rules import create_get_save_implicit_transition_rules
from bddl.data_generation.get_explicit_transition_rules import create_save_explicit_transition_rules
import pandas as pd
import csv
import nltk
Expand Down Expand Up @@ -39,13 +41,16 @@ def main():
create_get_save_synsets_to_descriptors(propagated_canonical)

# Add parameter info to syns-to-props
create_get_save_propagated_annots_params(propagated_canonical)
syns_to_param_props = create_get_save_propagated_annots_params(propagated_canonical)

# Add prop-param info to hierarchy
create_get_save_hierarchy_with_properties(hierarchy)

# Add TM cleaning info to hierarchy
# parse_tm_cleaning_csv()
# Create and save implicit transition jsons
create_get_save_implicit_transition_rules(syns_to_param_props, props_to_syns)

# Create and save explicit transition jsons
create_save_explicit_transition_rules()

# # Create and save activity-specific hierarchies (no getting because that will get complicated)
# create_save_activity_specific_hierarchies()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
import json
import csv
import pandas as pd
import pathlib
import os
from collections import Counter
import re

from tm_submap_params import TM_SUBMAPS_TO_PARAMS

SHEETS_DIR = "tm_raw_data"
JSONS_DIR = "tm_jsons"
SHEETS_DIR = pathlib.Path(__file__).parents[1] / "generated_data" / "transition_map" / "tm_raw_data"
JSONS_DIR = pathlib.Path(__file__).parents[1] / "generated_data" / "transition_map" / "tm_jsons"

OBJECT_CAT_AND_INST_RE = r"[A-Za-z-_]+\.n\.[0-9]+"


def sheet_to_json(submap):
print()
print(submap)
params = TM_SUBMAPS_TO_PARAMS[submap]
raw_data = pd.read_csv(os.path.join(SHEETS_DIR, submap + ".csv"))[params].to_json(orient="records")
data = json.loads(raw_data)
reformatted_data = []
for rule in data:
# print(rule["rule_name"])
reformatted_rule = {}
for param, value in rule.items():
if TM_SUBMAPS_TO_PARAMS[submap][param]["type"] == "synset" and value is not None:
Expand Down Expand Up @@ -56,7 +54,6 @@ def sheet_to_json(submap):
reformatted_atoms[f"{synset1},{synset2}"].append((atom[-3], atom[0] != "not"))
else:
reformatted_atoms[f"{synset1},{synset2}"] = [(atom[-3], atom[0] != "not")]
print(reformatted_atoms)
value = reformatted_atoms
elif TM_SUBMAPS_TO_PARAMS[submap][param]["type"] == "string":
value = value
Expand All @@ -71,6 +68,13 @@ def sheet_to_json(submap):
json.dump(reformatted_data, f, indent=4)


def create_save_explicit_transition_rules():
print("Creating explicit transition rule jsons...")
for submap in TM_SUBMAPS_TO_PARAMS:
sheet_to_json(submap)
print("Created and saved explicit transition rule jsons.")


if __name__ == "__main__":
for submap in TM_SUBMAPS_TO_PARAMS:
sheet_to_json(submap)
179 changes: 179 additions & 0 deletions bddl/data_generation/get_implicit_transition_rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import json
import os
import pandas as pd
import pathlib


TRANSITION_MAP_DIR = pathlib.Path(__file__).parents[1] / "generated_data" / "transition_map" / "tm_jsons"


def generate_slicing_rules(syns_to_param_props, props_to_syns):
"""
Generates transition rules for slicing of sliceable objects.
Form:
{
"rule_name": <non-unique string>,
"input_objects": {
<sliceable>: 1
},
"output_objects": {
<sliceable_derivative_synset>: 2
}
}
Assumptions not listed in rule:
- Slicer is present and slicing region of slicer is touching sliceable - this is required for the rule to fire
"""

rules = []
sliceables = props_to_syns["sliceable"]
for sliceable in sliceables:
assert "sliceable_derivative_synset" in syns_to_param_props[sliceable]["sliceable"], f"Synset {sliceable} has no sliceable derivative synset. Add one in the parameter annotations or handle otherwise."
assert syns_to_param_props[sliceable]["sliceable"]["sliceable_derivative_synset"] in syns_to_param_props, f"Synset {sliceable} has sliceable derivative synset {syns_to_param_props[sliceable]['sliceable_derivative_synset']} that is not a valid synset. Please check."
sliceable_derivative_synset = syns_to_param_props[sliceable]["sliceable"]["sliceable_derivative_synset"]

rule = {
"rule_name": f"{sliceable}-slicing",
"input_objects": {
sliceable: 1
},
"output_objects": {
sliceable_derivative_synset: 2
}
}

rules.append(rule)

return rules


def generate_dicing_rules(syns_to_param_props, props_to_syns):
"""
Generates transition rules for dicing of diceable objects.
Form:
{
"rule_name": <non-unique string>,
"input_objects": {
<diceable>: 1
},
"input_states": {
<diceable>: [
[
"cooked",
<bool>
]
]
}
"output_objects": {
<cooked_diceable_derivative_synset> if cooked else <uncooked_diceable_derivative_synset>: 1
}
}
Assumptions not listed in rule:
- Slicer is present and slicing region of slicer is touching diceable - this is required for the rule to fire
"""

rules = []
diceables = props_to_syns["diceable"]
cookables = set(props_to_syns["cookable"])
for diceable in diceables:
assert "uncooked_diceable_derivative_synset" in syns_to_param_props[diceable]["diceable"], f"Synset {diceable} has no uncooked diceable derivative synset. Add one in the parameter annotations."
assert syns_to_param_props[diceable]["diceable"]["uncooked_diceable_derivative_synset"] in syns_to_param_props, f"Synset {diceable} has uncooked diceable derivative synset {syns_to_param_props[diceable]['uncooked_diceable_derivative_synset']} that is not a valid synset. Please check."
uncooked_diceable_derivative_synset = syns_to_param_props[diceable]["diceable"]["uncooked_diceable_derivative_synset"]

uncooked_rule = {
"rule_name": f"uncooked-{diceable}-dicing",
"input_objects": {
diceable: 1
},
"input_states": {
diceable: [
[
"cooked",
False
]
]
},
"output_objects": {
uncooked_diceable_derivative_synset: 1
}
}
rules.append(uncooked_rule)

if diceable in cookables:
assert "cooked_diceable_derivative_synset" in syns_to_param_props[diceable]["diceable"], f"Synset {diceable} has no cooked diceable derivative synset. Add one in the parameter annotations."
assert syns_to_param_props[diceable]["diceable"]["cooked_diceable_derivative_synset"] in syns_to_param_props, f"Synset {diceable} has cooked diceable derivative synset {syns_to_param_props[diceable]['cooked_diceable_derivative_synset']} that is not a valid synset. Please check."
cooked_diceable_derivative_synset = syns_to_param_props[diceable]["diceable"]["cooked_diceable_derivative_synset"]

cooked_rule = {
"rule_name": f"cooked-{diceable}-dicing",
"input_objects": {
diceable: 1
},
"input_states": {
diceable: [
[
"cooked",
True
]
]
},
"output_objects": {
cooked_diceable_derivative_synset: 1
}
}
rules.append(cooked_rule)

return rules


def generate_substance_cooking_rules(syns_to_param_props, props_to_syns):
"""
Generates transition rules for dicing of diceable objects.
Form:
{
"rule_name": <non-unique string>,
"input_objects": {
<cookable,substance>: 1
},
"output_objects": {
<substance_cooking_derivative_synset>: 1
}
}
Assumptions not listed in rule:
TODO is the below accurate?
- Cookable substance must be filling a fillable and the fillable must be hot for the rule to fire
"""

rules = []
cookable_substances = set(props_to_syns["cookable"]).intersection(set(props_to_syns["substance"]))
for cookable_substance in cookable_substances:
assert "substance_cooking_derivative_synset" in syns_to_param_props[cookable_substance]["cookable"], f"Synset {cookable_substance} has no substance cooking derivative synset. Add one in the parameter annotations or handle otherwise."
assert syns_to_param_props[cookable_substance]["cookable"]["substance_cooking_derivative_synset"] in syns_to_param_props, f"Synset {cookable_substance} has substance cooking derivative synset {syns_to_param_props[cookable_substance]['substance_cooking_derivative_synset']} that is not a valid synset. Please check."
substance_cooking_derivative_synset = syns_to_param_props[cookable_substance]["cookable"]["substance_cooking_derivative_synset"]

rule = {
"rule_name": f"{cookable_substance}-cooking",
"input_objects": {
cookable_substance: 1
},
"output_objects": {
substance_cooking_derivative_synset: 1
}
}
rules.append(rule)

return rules


def create_get_save_implicit_transition_rules(syns_to_param_props, props_to_syns):
print("Creating implicit transition rule jsons...")
slicing_rules = generate_slicing_rules(syns_to_param_props, props_to_syns)
dicing_rules = generate_dicing_rules(syns_to_param_props, props_to_syns)
substance_cooking_rules = generate_substance_cooking_rules(syns_to_param_props, props_to_syns)

with open(os.path.join(TRANSITION_MAP_DIR, "slicing.json"), "w") as f:
json.dump(slicing_rules, f)
with open(os.path.join(TRANSITION_MAP_DIR, "dicing.json"), "w") as f:
json.dump(dicing_rules, f)
with open(os.path.join(TRANSITION_MAP_DIR, "substance_cooking.json"), "w") as f:
json.dump(substance_cooking_rules, f)
print("Created and saved implicit transition rule jsons.")
18 changes: 17 additions & 1 deletion bddl/data_generation/process_prop_param_annots.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,22 @@ def create_get_save_propagated_annots_params(syns_to_props):

if param_name == "synset": continue

# Params that can have NaN values
if param_name in [
"substance_cooking_derivative_synset",
"sliceable_derivative_synset",
"uncooked_diceable_derivative_synset",
"cooked_diceable_derivative_synset"
]:
if not pd.isna(param_value):
formatted_param_value = param_value
syns_to_props[param_record["synset"]][prop][param_name] = formatted_param_value
continue

# Params that should not have NaN values

# NaN values
if pd.isna(param_value):
elif pd.isna(param_value):
if prop == "coldSource":
raise ValueError(f"synset {param_record['synset']} coldSource annotation has NaN value for parameter {param_name}. Either handle NaN or annotate parameter value.")
elif prop == "cookable":
Expand Down Expand Up @@ -199,6 +213,8 @@ def create_get_save_propagated_annots_params(syns_to_props):
json.dump(syns_to_props, f, indent=4)

print("Params parsed and added to flat and hierarchical files, saved.")
return syns_to_props



if __name__ == "__main__":
Expand Down
27 changes: 17 additions & 10 deletions bddl/data_generation/pull_sheets.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,29 @@

ASSETS_SHEET_KEY = "10L8wjNDvr1XYMMHas4IYYP9ZK7TfQHu--Kzoi0qhAe4"
SYNSETS_SHEET_KEY = "1eIQn1HzUJV15nCP4MqsHvrdWAV9VrKoxOqSnQxF0_1A"
SYMSET_PARAMS_SHEET_KEY = "1jQomcQS3DSMLctEOElafCPj_v498gwtb57NC9eNwu-4"
SYNSET_PARAMS_SHEET_KEY = "1jQomcQS3DSMLctEOElafCPj_v498gwtb57NC9eNwu-4"
EXPLICIT_TRANSITION_RULES_SHEET_KEY = "1q3MqvnT_bOVbkMit1c7dhbzsOvd3KUQhJGx3aaJiH04"

ALL_SHEETS = [
(ASSETS_SHEET_KEY, "Object Category Mapping", "category_mapping.csv"),
(ASSETS_SHEET_KEY, "Allowed Room Types", "allowed_room_types.csv"),
(ASSETS_SHEET_KEY, "Substance Hyperparams", "substance_hyperparams.csv"),
(SYNSETS_SHEET_KEY, "Synsets", "synsets.csv"),
(SYMSET_PARAMS_SHEET_KEY, "heatSource", "prop_param_annots/heatSource.csv"),
(SYMSET_PARAMS_SHEET_KEY, "coldSource", "prop_param_annots/coldSource.csv"),
(SYMSET_PARAMS_SHEET_KEY, "cookable", "prop_param_annots/cookable.csv"),
(SYMSET_PARAMS_SHEET_KEY, "flammable", "prop_param_annots/flammable.csv"),
(SYMSET_PARAMS_SHEET_KEY, "heatable", "prop_param_annots/heatable.csv"),
(SYMSET_PARAMS_SHEET_KEY, "particleApplier", "prop_param_annots/particleApplier.csv"),
(SYMSET_PARAMS_SHEET_KEY, "particleSource", "prop_param_annots/particleSource.csv"),
(SYMSET_PARAMS_SHEET_KEY, "particleRemover", "prop_param_annots/particleRemover.csv"),
(SYMSET_PARAMS_SHEET_KEY, "particleSink", "prop_param_annots/particleSink.csv")
(SYNSET_PARAMS_SHEET_KEY, "heatSource", "prop_param_annots/heatSource.csv"),
(SYNSET_PARAMS_SHEET_KEY, "coldSource", "prop_param_annots/coldSource.csv"),
(SYNSET_PARAMS_SHEET_KEY, "cookable", "prop_param_annots/cookable.csv"),
(SYNSET_PARAMS_SHEET_KEY, "flammable", "prop_param_annots/flammable.csv"),
(SYNSET_PARAMS_SHEET_KEY, "heatable", "prop_param_annots/heatable.csv"),
(SYNSET_PARAMS_SHEET_KEY, "particleApplier", "prop_param_annots/particleApplier.csv"),
(SYNSET_PARAMS_SHEET_KEY, "particleSource", "prop_param_annots/particleSource.csv"),
(SYNSET_PARAMS_SHEET_KEY, "particleRemover", "prop_param_annots/particleRemover.csv"),
(SYNSET_PARAMS_SHEET_KEY, "particleSink", "prop_param_annots/particleSink.csv"),
(SYNSET_PARAMS_SHEET_KEY, "diceable", "prop_param_annots/diceable.csv"),
(SYNSET_PARAMS_SHEET_KEY, "sliceable", "prop_param_annots/sliceable.csv"),
(EXPLICIT_TRANSITION_RULES_SHEET_KEY, "electric_mixer", "transition_map/tm_raw_data/electric_mixer.csv"),
(EXPLICIT_TRANSITION_RULES_SHEET_KEY, "heat_cook", "transition_map/tm_raw_data/heat_cook.csv"),
(EXPLICIT_TRANSITION_RULES_SHEET_KEY, "mixing_stick", "transition_map/tm_raw_data/mixing_stick.csv"),
(EXPLICIT_TRANSITION_RULES_SHEET_KEY, "single_toggleable_machine", "transition_map/tm_raw_data/single_toggleable_machine.csv")
]

def main():
Expand Down
File renamed without changes.
Loading

0 comments on commit 068c97d

Please sign in to comment.