English
tinymyo
emg
bio-signals
foundation-model
MatteoFasulo commited on
Commit
03ce43c
·
unverified ·
1 Parent(s): 808a02d

Update emg2pose with s3 AWS CLI download

Browse files
scripts/README.md CHANGED
@@ -36,4 +36,4 @@ This guide provides commands to process raw EMG data into HDF5 format using slid
36
  | **NinaPro DB8** | Regression | 200 (0.1s) | 200 | `python scripts/db8.py --data_dir $DATA_PATH/ninapro/DB8/ --save_dir $DATA_PATH/ninapro/DB8/h5_100/ --seq_len 200 --stride 200` |
37
  | **NinaPro DB8** | Regression | 1000 (0.5s) | 1000 | `python scripts/db8.py --data_dir $DATA_PATH/ninapro/DB8/ --save_dir $DATA_PATH/ninapro/DB8/h5_500/ --seq_len 1000 --stride 1000` |
38
 
39
- >Note: For DB5, we used the `--data-augment` flag to augment the training data by a factor of 3 (see `--augment-factor` in `scripts/db5.py`).
 
36
  | **NinaPro DB8** | Regression | 200 (0.1s) | 200 | `python scripts/db8.py --data_dir $DATA_PATH/ninapro/DB8/ --save_dir $DATA_PATH/ninapro/DB8/h5_100/ --seq_len 200 --stride 200` |
37
  | **NinaPro DB8** | Regression | 1000 (0.5s) | 1000 | `python scripts/db8.py --data_dir $DATA_PATH/ninapro/DB8/ --save_dir $DATA_PATH/ninapro/DB8/h5_500/ --seq_len 1000 --stride 1000` |
38
 
39
+ >Note: For DB5, we used the `--data-augment` flag to augment the training data by a factor of 3 (see `--augment-factor` in `scripts/db5.py`).
scripts/emg2pose.py CHANGED
@@ -1,5 +1,8 @@
1
  import os
2
  import gc
 
 
 
3
  from pathlib import Path
4
  from typing import Tuple, List, Optional, Union, Dict, Any
5
 
@@ -11,6 +14,80 @@ from joblib import Parallel, delayed
11
  from scipy.signal import iirnotch
12
  from tqdm import tqdm
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def sequence_to_seconds(seq_len: int, fs: float) -> float:
15
  """Converts a sequence length in samples to time in seconds.
16
 
@@ -135,6 +212,13 @@ def main():
135
  args = argparse.ArgumentParser(description="Process EMG data from DB5.")
136
  args.add_argument("--data_dir", type=str)
137
  args.add_argument("--save_dir", type=str)
 
 
 
 
 
 
 
138
  args.add_argument(
139
  "--seq_len", type=int, help="Size of the window in samples for segmentation."
140
  )
@@ -165,6 +249,17 @@ def main():
165
  save_dir = args.save_dir
166
  os.makedirs(save_dir, exist_ok=True)
167
 
 
 
 
 
 
 
 
 
 
 
 
168
  fs = 2000.0 # original sampling rate
169
  window_size, stride = args.seq_len, args.stride
170
 
@@ -230,4 +325,4 @@ def main():
230
 
231
 
232
  if __name__ == "__main__":
233
- main()
 
1
  import os
2
  import gc
3
+ import subprocess
4
+ import tarfile
5
+ import tempfile
6
  from pathlib import Path
7
  from typing import Tuple, List, Optional, Union, Dict, Any
8
 
 
14
  from scipy.signal import iirnotch
15
  from tqdm import tqdm
16
 
17
+
18
+ EMG2POSE_S3_URI = "s3://fb-ctrl-oss/emg2pose/emg2pose_dataset.tar"
19
+
20
+
21
+ def download_emg2pose(
22
+ data_dir: str,
23
+ archive_path: Optional[str] = None,
24
+ max_concurrent_requests: int = 64,
25
+ multipart_chunksize: str = "128MB",
26
+ io_chunksize: str = "64MB",
27
+ max_queue_size: int = 1000,
28
+ keep_archive: bool = False,
29
+ ) -> None:
30
+ """Download and extract the public EMG2Pose S3 archive.
31
+
32
+ AWS CLI S3 tuning is kept in a temporary config file so this script does
33
+ not modify the user's global AWS configuration. The public object is
34
+ downloaded without credentials and can be resumed by AWS CLI when a
35
+ partial file is present.
36
+ """
37
+ data_path = Path(data_dir).expanduser().resolve()
38
+ data_path.mkdir(parents=True, exist_ok=True)
39
+ archive = (
40
+ Path(archive_path).expanduser().resolve()
41
+ if archive_path
42
+ else data_path.parent / "emg2pose_dataset.tar"
43
+ )
44
+ archive.parent.mkdir(parents=True, exist_ok=True)
45
+
46
+ aws_config = (
47
+ "[default]\n"
48
+ "s3 =\n"
49
+ f" max_concurrent_requests = {max_concurrent_requests}\n"
50
+ f" max_queue_size = {max_queue_size}\n"
51
+ f" multipart_chunksize = {multipart_chunksize}\n"
52
+ f" io_chunksize = {io_chunksize}\n"
53
+ )
54
+
55
+ print(f"Downloading EMG2Pose to {archive}")
56
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".aws-config", delete=False) as config_file:
57
+ config_file.write(aws_config)
58
+ config_path = config_file.name
59
+
60
+ env = os.environ.copy()
61
+ env["AWS_CONFIG_FILE"] = config_path
62
+ try:
63
+ subprocess.run(
64
+ [
65
+ "aws",
66
+ "s3",
67
+ "cp",
68
+ EMG2POSE_S3_URI,
69
+ str(archive),
70
+ "--no-sign-request",
71
+ ],
72
+ check=True,
73
+ env=env,
74
+ )
75
+ finally:
76
+ os.unlink(config_path)
77
+
78
+ print(f"Extracting {archive} into {data_path}")
79
+ with tarfile.open(archive, "r") as tar:
80
+ root = data_path.resolve()
81
+ for member in tar.getmembers():
82
+ target = (data_path / member.name).resolve()
83
+ if target != root and root not in target.parents:
84
+ raise RuntimeError(f"Unsafe archive member: {member.name}")
85
+ tar.extractall(data_path)
86
+
87
+ if not keep_archive:
88
+ archive.unlink()
89
+ print("Removed downloaded archive")
90
+
91
  def sequence_to_seconds(seq_len: int, fs: float) -> float:
92
  """Converts a sequence length in samples to time in seconds.
93
 
 
212
  args = argparse.ArgumentParser(description="Process EMG data from DB5.")
213
  args.add_argument("--data_dir", type=str)
214
  args.add_argument("--save_dir", type=str)
215
+ args.add_argument("--download_data", action="store_true")
216
+ args.add_argument("--archive_path", type=str, default=None)
217
+ args.add_argument("--keep_archive", action="store_true")
218
+ args.add_argument("--aws_max_concurrent_requests", type=int, default=64)
219
+ args.add_argument("--aws_multipart_chunksize", type=str, default="128MB")
220
+ args.add_argument("--aws_io_chunksize", type=str, default="64MB")
221
+ args.add_argument("--aws_max_queue_size", type=int, default=1000)
222
  args.add_argument(
223
  "--seq_len", type=int, help="Size of the window in samples for segmentation."
224
  )
 
249
  save_dir = args.save_dir
250
  os.makedirs(save_dir, exist_ok=True)
251
 
252
+ if args.download_data:
253
+ download_emg2pose(
254
+ data_dir=data_dir,
255
+ archive_path=args.archive_path,
256
+ max_concurrent_requests=args.aws_max_concurrent_requests,
257
+ multipart_chunksize=args.aws_multipart_chunksize,
258
+ io_chunksize=args.aws_io_chunksize,
259
+ max_queue_size=args.aws_max_queue_size,
260
+ keep_archive=args.keep_archive,
261
+ )
262
+
263
  fs = 2000.0 # original sampling rate
264
  window_size, stride = args.seq_len, args.stride
265
 
 
325
 
326
 
327
  if __name__ == "__main__":
328
+ main()
scripts/requirements.txt CHANGED
@@ -3,4 +3,5 @@ numpy
3
  scipy
4
  joblib
5
  tqdm
6
- pandas
 
 
3
  scipy
4
  joblib
5
  tqdm
6
+ pandas
7
+ awscli