-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 18 #54
Merged
Merged
Issue 18 #54
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
3f5be09
add config.py and read_data_from_file.py
ed63666
finalize dump_data_to_file
4b0a640
update cli args
254f410
add capability to export raw data to file when additional parameters …
9cb24ee
successfully replicate behavior of SpecDetails, handle duplicate spec…
ec28776
significant refactors + add fill transitions functionality
d78e497
create v2 based on new ServerSpecDetails class and refactored PhoneVi…
06b8185
finish script refactor, create general structure for dumping based on…
6b909cf
move read_until_done to spec_details
ffa5d27
add FileSpecDetails, configure proper output from PhoneView map
c0eb143
Add simple unit test with a mocking example
shankari e8c9fe0
add in code review changes aside from read_until_done
5746c99
Merge pull request #10 from MobilityNet/add_simple_unit_test
80c8638
add documentation to parser for dump_data_to_file
9a7ff44
fix PhoneView to use time series keys from emission
1821b87
mostly working FileSpecDetails, constants added to PhoneView
bee4c2a
fully working FileSpecDetails
1252e2d
updated notebooks + incorporated changes on PR
24832dc
Restore full tree display
shankari e942ab8
remove outputs from Evaluations_power_boxplots
0cf5836
Merge branch 'issue18' of https://github.com/singhish/mobilitynet-ana…
46c67c8
revert _master notebooks
e2d72f8
remove .DS_Store
550ea7a
remove .DS_Store from subfolders
fb7007d
Add quotes around the `DATASTORE_LOC` as well
shankari File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
import json | ||
import os | ||
import math | ||
import requests | ||
import time | ||
import arrow | ||
import argparse | ||
import sys; sys.path.append("..") | ||
from emeval.input.spec_details import ServerSpecDetails | ||
from emeval.input.phone_view import PhoneView | ||
|
||
|
||
def dump_data_to_file(data, spec_id, user, key, start_ts, end_ts, out_dir): | ||
""" | ||
Accepts serializable data (e.g. dict, array of dicts) and dumps it into an output file. | ||
Dumped file are created recursively in the folder name specified by `out_dir` as such: | ||
|
||
out_dir | ||
└── user | ||
└── spec_id | ||
└── key | ||
└── {start_ts}_{end_ts}.json | ||
""" | ||
# key could have a slash if it corresponds to a key_list argument in SpecDetails::retrieve_data | ||
# slashes are invalid in directory names, so replace with tilde | ||
out_path = os.path.join(out_dir, user, spec_id, key.replace("/", "~")) | ||
os.makedirs(out_path, exist_ok=True) | ||
|
||
out_file = os.path.join(out_path, f"{math.floor(start_ts)}_{math.ceil(end_ts)}.json") | ||
print(f"Creating {out_file=}...") | ||
with open(out_file, "w") as f: | ||
json.dump(data, f, indent=4) | ||
|
||
|
||
def get_all_spec_ids(datastore_url, spec_user): | ||
""" | ||
Retrieves list of all spec_id's on E-Mission Server instance being used by script. | ||
""" | ||
spec_data = ServerSpecDetails(datastore_url, spec_user).retrieve_data(spec_user, ["config/evaluation_spec"], 0, arrow.get().timestamp) | ||
spec_ids = [s["data"]["label"]["id"] for s in spec_data] | ||
|
||
return set(spec_ids) | ||
|
||
|
||
def parse_args(): | ||
""" | ||
Defines command line arguments for script. | ||
""" | ||
parser = argparse.ArgumentParser( | ||
description="Script that retrieves data from an E-Mission Server instance and dumps it into a hierarchical collection of JSON files.") | ||
|
||
parser.add_argument("--out-dir", | ||
type=str, | ||
default="data", | ||
help="The name of the directory that data will be dumped to. Will be created if not already present. " | ||
"[default: data]") | ||
|
||
parser.add_argument("--datastore-url", | ||
type=str, | ||
default="http://localhost:8080", | ||
help="The URL of the E-Mission Server instance from which data will be pulled. " | ||
"[default: http://localhost:8080]") | ||
|
||
parser.add_argument("--spec-user", | ||
type=str, | ||
default="[email protected]", | ||
help="The user associated with retrieving specs. " | ||
"[default: [email protected]]") | ||
|
||
parser.add_argument("--spec-id", | ||
type=str, | ||
help="The particular spec to retrieve data for. " | ||
"If not specified, data will be retrieved for all specs on the specified datastore instance.") | ||
|
||
# if one of these arguments is specified, the others in this group must also be specified | ||
parser.add_argument("--key", | ||
type=str, | ||
help="The time series key to be used if a single call to the E-Mission Server instance is to be made. " | ||
"--user, --start-ts, and --end-ts must also be specified.") | ||
|
||
parser.add_argument("--user", | ||
type=str, | ||
help="The user to be used if a single call to the E-Mission Server instance is to be made. " | ||
"--key, --start-ts, and --end-ts must also be specified.") | ||
|
||
parser.add_argument("--start-ts", | ||
type=float, | ||
help="The starting timestamp from which to pull data if a single call to the E-Mission Server instance is to be made. " | ||
"--key, --user, and --end-ts must also be specified.") | ||
|
||
parser.add_argument("--end-ts", | ||
type=float, | ||
help="The ending timestamp from which to pull data if a single call to the E-Mission Server instance is to be made. " | ||
"--key, --user, and --start-ts must also be specified.") | ||
|
||
return parser.parse_args() | ||
|
||
|
||
def run_full_pipeline(datastore_url, spec_user, spec_ids, out_dir): | ||
print(f"Running full pipeline for {spec_ids[0] if len(spec_ids) == 1 else 'all specs in datastore'}...") | ||
|
||
# collect ServerSpecDetails objects, dump specs | ||
sds = [] | ||
for s_id in spec_ids: | ||
sd = ServerSpecDetails(datastore_url, spec_user, s_id) | ||
sds.append(sd) | ||
dump_data_to_file( | ||
sd.curr_spec_entry, | ||
sd.CURR_SPEC_ID, | ||
spec_user, | ||
"config/evaluation_spec", | ||
0, | ||
sys.maxsize, | ||
out_dir) | ||
|
||
# build and dump phone view maps | ||
for sd in sds: | ||
pv = PhoneView(sd) | ||
for phone_os, phone_map in pv.map().items(): | ||
for phone_label, phone_detail_map in phone_map.items(): | ||
for key in [k for k in phone_detail_map.keys() if "/" in k]: | ||
dump_data_to_file( | ||
phone_detail_map[key], | ||
sd.CURR_SPEC_ID, | ||
phone_label, | ||
key, | ||
sd.eval_start_ts, | ||
sd.eval_end_ts, | ||
out_dir) | ||
for ranges in [phone_detail_map["calibration_ranges"], phone_detail_map["evaluation_ranges"]]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so we need two levels of |
||
for r in ranges: | ||
for key in [k for k in r.keys() if "/" in k]: | ||
dump_data_to_file( | ||
r[key], | ||
sd.CURR_SPEC_ID, | ||
phone_label, | ||
key, | ||
r["start_ts"], | ||
r["end_ts"], | ||
out_dir) | ||
|
||
|
||
if __name__ == "__main__": | ||
args = parse_args() | ||
|
||
# verify spec_id is valid if specified | ||
spec_ids = get_all_spec_ids(args.datastore_url, args.spec_user) | ||
if args.spec_id: | ||
assert args.spec_id in spec_ids, f"spec_id `{args.spec_id}` not found within current datastore instance" | ||
spec_ids = [args.spec_id] | ||
|
||
# enforce that --key, --user, --start-ts, and --end-ts are all specifed if one of these arguments is specified | ||
cond_req_args = ["--key", "--user", "--start-ts", "--end-ts"] | ||
for arg in cond_req_args: | ||
if arg in sys.argv: | ||
assert set(a for a in cond_req_args if a != arg) <= set(sys.argv), "all of --key --user, --start-ts, and --end-ts must be specified" | ||
|
||
# if --key, etc are specified, just call retrieve_data from an anonymous ServerSpecDetails instance | ||
if "--key" in sys.argv: | ||
for s_id in spec_ids: | ||
data = ServerSpecDetails(args.datastore_url, args.user).retrieve_data(args.user, [args.key], args.start_ts, args.end_ts) | ||
dump_data_to_file(data, s_id, args.user, args.key, args.start_ts, args.end_ts, args.out_dir) | ||
else: | ||
run_full_pipeline(args.datastore_url, args.spec_user, spec_ids, args.out_dir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as part of your documentation, you should highlight that this is how you identify that a particular key needs to be saved to a file