-
Notifications
You must be signed in to change notification settings - Fork 2
/
summerdata.py
197 lines (164 loc) · 9.01 KB
/
summerdata.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# dict keys are frame numbers
# frames are only reported when a fluent changes, and only for the fluent(s) that changed; fluents are considered to be on or off ("light" is treated as "light_on", and then "light_off" is calculated from that internally, for instance)
#TODO this is essentially redundant data and SHOULD come from causal_grammar_summerdata.py TODO
#TODO let's try to replace onsoffs (and actionPairings) with a more robust framework...yay...
groupings = dict()
from causal_grammar import TYPE_FLUENT, TYPE_ACTION, kNonActionPenaltyEnergy
import causal_grammar
import causal_grammar_summerdata # sets up causal_forest
# for 'detections' aka 'origdata' per CVPR 2017 workshop
#kActionDetections = 'results/CVPR2012_slidingwindow_50_150_action_detection_logspace_surroundsuppression'
# for 'sequential causal' aka 'origdata' per CVPR 2017 workshop
kActionDetections = 'results/CVPR2012_slidingwindow_50_150_action_detection_logspace_allowoverlaps'
# These thresholds tuned for this fluent data because it's not "flipping between on and off", it's
# flipping "did transition closed to on" and "didn't transition closed to on"
# 40/60
#causal_grammar.kFluentThresholdOnEnergy = 0.510825
#causal_grammar.kFluentThresholdOffEnergy = 0.91629
# 45/55
#causal_grammar.kFluentThresholdOnEnergy = 0.597837
#causal_grammar.kFluentThresholdOffEnergy = 0.798507
# 49.7997769 / 50.1977490468
causal_grammar.kFluentThresholdOnEnergy = 0.6892
causal_grammar.kFluentThresholdOffEnergy = 0.6972
# note that "negative" action must be the last one sepecified for proper P/R and there must be only one "no action"
# TODO: above note taken from analyzeData-nearesthuman-pr.py which still needs to be refactored appropriately
def addGrouping(groupings, fluent, related_fluents, related_actions):
groupings[fluent] = {
TYPE_FLUENT : related_fluents,
TYPE_ACTION : related_actions,
}
addGrouping(groupings, 'thirst',
{ 'thirst' : ["not_thirsty","thirsty_not","thirsty","not",] },
{ 'water_action' : ["act_drink","act_no_drink",], },
)
# TODO: maybe this is why we think we need 'cup' toplevel instead of 'water' (or vice-versa)???
addGrouping(groupings, 'cup',
{ 'cup' : ["more","less","same",], },
{
'water_action' : ["act_drink","act_no_drink",], # this. this is why we can't have nice things.
'dispense' : ["act_dispensed","act_no_dispense",], # also, this. even more, this.
},
)
addGrouping(groupings, 'waterstream',
{ 'waterstream' : ["water_on","water_off",], },
{
'water_action' : ["act_drink","act_no_drink",],
'dispense' : ["act_dispensed","act_no_dispense",],
},
)
addGrouping(groupings, 'door',
{ 'door' : ["closed_open","open_closed","open","closed",], },
{ 'door_action' : ["act_opened","act_closed","act_not_opened_closed",], },
)
addGrouping(groupings, 'doorlock',
{ 'doorlock' : ["lock_unlocked","unlocked_lock","locked","unlocked",], },
{ 'doorlock_action' : ["act_knock","act_none",],},
)
addGrouping(groupings, 'phone',
{ 'phone' : ["off_active","active_off","active","off",], 'ringer': ['ring', 'no_ring'], },
{ 'phone_action' : ["act_received_call","act_no_call",], },
)
addGrouping(groupings, 'trash',
{ 'trash' : ["more", "less", "same", ], },
{ 'trash_action' : ['act_benddown', 'act_no_benddown', ], },
)
addGrouping(groupings, 'screen',
{ 'screen' : ["off_on", "on_off", "on", "off", ], },
{ 'screen_action' : ['act_mousekeyboard', 'act_no_mousekeyboard', ], },
)
addGrouping(groupings, 'elevator',
{ 'elevator' : ["closed_open", "open_closed", "open", "closed", ], },
{ 'elevator_action' : ['act_pushbutton', 'act_no_pushbutton', ], },
)
addGrouping(groupings, 'light',
{ 'light' : ["off_on", "on_off", "on", "off", ], },
{ 'light_action' : ['act_pushbutton', 'act_no_pushbutton', ], },
)
def getActionsForMasterFluent(groupings, fluent):
return groupings[fluent][TYPE_ACTION].keys()
def getFluentsForMasterFluent(groupings, fluent):
return groupings[fluent][TYPE_FLUENT].keys()
def getMasterFluentsForPrefix(groupings, prefix):
return [i for i in groupings if prefix in groupings[i][TYPE_FLUENT] or prefix in groupings[i][TYPE_ACTION]]
def getPrefixType(groupings, prefix):
if [i for i in groupings if prefix in groupings[i][TYPE_FLUENT]]:
return TYPE_FLUENT
if [i for i in groupings if prefix in groupings[i][TYPE_ACTION]]:
return TYPE_ACTION
raise Exception("prefix not found in groupings: {}".format(prefix))
"""
onsoffs are used by:
dealWithDBResults ~ buildDictForFluentBetweenFramesIntoResults
plotResults ~ buildHeatmapForExample STAGE 3 READ CAUSALGRAMMAR RESULTS, seeing if our value changed or stayed the same
actionPairings are used by:
the same two culprits.
"""
onsoffs = { "door": ["open","closed"], "light": ["on","off"], "screen": ["on","off"], "phone": ["active","off"], "ringer": ["ring","no_ring"] } #ringer actions: act_received_call, act_no_call <- mean "used phone" or "not".
# filling in these, assuming they're the DB on/off values
onsoffs["thirst"] = ["thirsty", "not"] #actions: act_drink, act_no_drink, act_dispensed, act_no_dispense (maybe)
onsoffs["waterstream"] = ["water_on", "water_off"] #actions act_dispensed, act_no_dispense
onsoffs["doorlock"] = ["locked", "unlocked"] # TODO: uhoh, the change is lock_unlocked/unlocked_lock. need to catch. #actions act_knock, act_none
# and these below here are the lovely 3-case answer...
onsoffs["trash"] = ["on", "off"] # actions: act_benddown, act_no_benddown
#TODO: should not have/need both 'cup' and 'water' as top-levels. something here is wrong!
onsoffs["water"] = ["on","off"] # gleep; do we not need cup_MORE, cup_LESS? actions: act_drin, act_no_drink, act_dispensed, act_no_dispense...???
onsoffs["cup"] = ["on","off"] # gleep; do we not need cup_MORE, cup_LESS? actions: act_drin, act_no_drink, act_dispensed, act_no_dispense...???
actionPairings = {
"screen":(["usecomputer_START","usecomputer_END"],),
"cup":(["benddown_START","benddown_END"],["drink_START","drink_END"]),
"waterstream":(["benddown_START","benddown_END"],),
#"waterstream":(["benddown_START","benddown_END"],["drink_START","drink_END"]),
"door":(["standing_START","standing_END"],),
"light":(["pressbutton_START","pressbutton_END"],),
"trash":(["throwtrash_START","throwtrash_END"],),#["PICKUP TRASH]_START","[PICKUP TRASH]_END"],),
"phone":(["makecall_START","makecall_END"],),
"thirst":(["drink_START","drink_END"],),
"water":([],), # water on its own doesn't have an action. it's a combo of thirst action (drink subtracts from water level) and waterstream action (dispense adds to water level)
}
#water ~ wateraction_#_act_drink, wateraction_#_act_no_drink
#water ~ thirst_#_thirsty, thirst_#_not
#water ~ cup_#_less, cup_#_more, cup_#_same
#waterstream ~ waterstream_#_water_on, waterstream_#_water_off
#waterstream ~ thirst_#_thirsty, thirst_#_not
#waterstream ~ dispense_#_act_dispensed, dispense_#_act_no_dispense
#waterstream ~ cup_#_less, cup_#_more, cup_#_same
# for "file name"-level fluents, what other fluents are important to consider?
fluent_extensions = {
"water": ["thirst","cup","drink",], # thirst_on, thirst_off
"waterstream": ["thirst","cup","drink",], # thirst_on, thirst_off
"phone": ["PHONE_ACTIVE",],
}
if __name__ == '__main__':
### TODO: deal with trash_6_phone_11_screen_22 because it has timer/jump
#screen_1_lounge 7f05529dec6a03d3a459fc2ee1969f7f 580 780
#screen_2_lounge 9b644124fa1eafeb78b4d08652320384 800 800
#screen_31_9406 74a72568506774709d9c2f2cf3b75e0d 0 200
#screen_58_9404 5b9e2799293b6a2657582cc00cf7bbc8 360 200
#screen_7_lounge db522a17f579f477a82bfd694aad2378 0 400
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-s","--simplify", action="store_true", required=False, help="simplify the summerdata grammar to only include fluents that start with the example name[s]")
parser.add_argument("example", nargs="+", action="store", help="specific example[s] to run, such as screen_1_lounge, light_5_9406, or door_11_9406")
parser.add_argument('-i','--ignoreoverlaps', action='store_true', required=False, help='skip the "without overlaps" code')
args = parser.parse_args()
import_failed = list()
causal_forest_orig = causal_grammar_summerdata.causal_forest
withoutoverlaps = not args.ignoreoverlaps
for example in args.example:
try:
if args.simplify:
causal_grammar_summerdata.causal_forest = causal_grammar.get_simplified_forest_for_example(causal_forest_orig, example)
fluent_parses, temporal_parses = causal_grammar.import_summerdata(example,kActionDetections)
import pprint
pp = pprint.PrettyPrinter(indent=1)
pp.pprint(fluent_parses)
pp.pprint(temporal_parses)
except ImportError as ie:
print("IMPORT FAILED: {}".format(ie))
import_failed.append(example)
continue
fluent_and_action_xml = causal_grammar.process_events_and_fluents(causal_grammar_summerdata.causal_forest, fluent_parses, temporal_parses, causal_grammar.kFluentThresholdOnEnergy, causal_grammar.kFluentThresholdOffEnergy, causal_grammar.kReportingThresholdEnergy, suppress_output = False, handle_overlapping_events = withoutoverlaps)
if len(import_failed):
print("FAILED IMPORTING: {}".format(", ".join(import_failed)))
print groupings