Coverage for ibllib/pipes/scan_fix_passive_files.py: 97%

63 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-07-08 17:16 +0100

1#!/usr/bin/env python 

2# -*- coding:utf-8 -*- 

3# @Author: Niccolò Bonacchi 

4# @Date: Thursday, September 24th 2020, 2:10:29 pm 

5import json 

6import logging 

7import shutil 

8from pathlib import Path, PureWindowsPath 

9 

10from one.alf.files import get_session_path 

11 

12log = logging.getLogger("ibllib") 

13 

14 

15def load_settings_file(filepath, key=None): 

16 filepath = Path(filepath) 1cba

17 if filepath.stat().st_size == 0: 1cba

18 return 1cba

19 

20 with open(filepath, "r") as f: 1cba

21 settings = json.load(f) 1cba

22 return settings.get(key, None) if key else settings 1cba

23 

24 

25def find_pairs(root_data_folder): 

26 """Find all passive sessions that needs transfer and where to""" 

27 root_data_folder = Path(root_data_folder) 1cba

28 settings_files = list(root_data_folder.rglob("_iblrig_taskSettings.raw.json")) 1cba

29 n_settings_files = len(settings_files) 1cba

30 if n_settings_files == 0: 1cba

31 log.warning(f"Found {n_settings_files} sessions") 

32 else: 

33 log.info(f"Found {n_settings_files} sessions") 1cba

34 

35 # Load the corresponding ephys session path form settings file if exists 

36 pairs = [] 1cba

37 for sf in settings_files: 1cba

38 # Get session path form settings file 

39 source_spath = get_session_path(sf) 1cba

40 if source_spath is None: 1cba

41 continue 

42 # Find the root_data_path for session 

43 subjects_folder_path = Path(*Path(source_spath).parts[:-3]) 1cba

44 # Load reference to corresponding ephys session (ces) which comes in windows format 

45 ces = load_settings_file(sf, key="CORRESPONDING_EPHYS_SESSION") 1cba

46 # if CORRESPONDING_EPHYS_SESSION does not exist, it's not a passive session 

47 if ces is None: 1cba

48 continue 1cba

49 # Convert windows path to corresponding session name (csn) in native Path format 

50 csn = Path(*PureWindowsPath(ces).parts[-3:]) 1cba

51 target_spath = subjects_folder_path / csn 1cba

52 

53 pairs.append((source_spath, target_spath)) 1cba

54 # Remove sessions that are already transferred i.e. source and destination files are equal 

55 from_to_pairs = [(x, y) for x, y in pairs if x != y] 1cba

56 n_pairs = len(from_to_pairs) 1cba

57 if n_pairs == 0: 1cba

58 log.warning(f"Found {n_pairs} passive sessions to move") 1a

59 else: 

60 log.info(f"Found {n_pairs} passive sessions to move") 1cba

61 

62 return from_to_pairs 1cba

63 

64 

65def move_rename_pairs(from_to_pairs): 

66 """""" 

67 moved_ok = [] 1ba

68 for i, (src, dst) in enumerate(from_to_pairs): 1ba

69 src = Path(src) 1ba

70 dst = Path(dst) 1ba

71 log.info(f"Moving {i+1} of {len(from_to_pairs)}: \n{src}\n--> {dst}") 1ba

72 try: 1ba

73 shutil.move(str(src / "raw_behavior_data"), str(dst / "raw_passive_data")) 1ba

74 ffile = src.joinpath("passive_data_for_ephys.flag") 1ba

75 if ffile.exists(): 1ba

76 ffile.unlink() 1ba

77 ffile.parent.rmdir() 1ba

78 moved_ok.append(True) 1ba

79 except BaseException as e: 1b

80 log.error(f"Failed to move {src} to {dst}:\n {e}") 1b

81 moved_ok.append(False) 1b

82 continue 1b

83 log.info(f"Moved {sum(moved_ok)} of {len(from_to_pairs)}") 1ba

84 return moved_ok 1ba

85 

86 

87def execute(root_data_folder, dry=True): 

88 from_to_pairs = find_pairs(root_data_folder) 1a

89 if dry: 1a

90 return from_to_pairs, [False] * len(from_to_pairs) 1a

91 moved_ok = move_rename_pairs(from_to_pairs) 1a

92 return from_to_pairs, moved_ok 1a