Source code for meganorm.layouts.layouts

import json
import os


[docs] def get_relative_path(filename): """Function to get the path relative to the .py file Parameters ---------- filename : str Name of the file Returns ------- str Full path to the JSON file """ script_dir = os.path.dirname(__file__) # Get the directory of the current script return os.path.join(script_dir, filename + ".json")
[docs] def save_sensor_layouts(layout, filename): """Function to save the sensor layouts to a JSON file Parameters ---------- layout : dict Dictionary containing the sensor layout information filename : str Name of the JSON file Returns ------- str Prints the path to the saved JSON file. """ full_path = get_relative_path(filename) with open(full_path, "w") as f: json.dump(layout, f, indent=4) print(f"Sensor layouts saved to {full_path}")
[docs] def add_specific_layout(output_format, layout, layout_data): """Function to add a specific sensor layout to a JSON file Parameters ---------- output_format : str Extension of the 's output (used as filename) layout : str Name of the layout to add or update. layout_data : dict Dictionary containing the layout configuration Returns ------- str Prints the path to the updated JSON file. """ full_path = get_relative_path(output_format) try: # Load the existing data with open(full_path, "r") as f: data = json.load(f) except FileNotFoundError: # If the file doesn't exist, create a new dictionary data = {} # Add or update the specific layout data[layout] = layout_data # Save the updated data back to the file with open(full_path, "w") as f: json.dump(data, f, indent=4) print(f"Layout '{layout}' saved to {full_path}")
[docs] def load_specific_layout(output_format, layout): """Function to load a specific sensor layout from a JSON file Parameters ---------- output_format : str Extension of the device's output (used as filename) layout : str Name of the layout to retrieve. Returns ------- dict or None The layout data if found, otherwise None. """ full_path = get_relative_path(output_format) try: # Load the existing data with open(full_path, "r") as f: data = json.load(f) # Return the specific layout if it exists if layout in data: return data[layout] else: print(f"Layout '{layout}' not found in {full_path}") return None except FileNotFoundError: print(f"File '{full_path}' not found") return None
[docs] def create_layouts(modality, output_format): """ Function that creates predefined sensor layouts for a given modality and output format. This includes both whole-brain sensor configurations and for some formats also region-specific layouts (e.g., frontal, temporal, parietal, occipital). Parameters ---------- modality : str Type of recording modality (e.g., "MEG", "EEG"). output_format : str Specific devic's output type or file format (e.g., "FIF", "DS", "SET", "VHDR"). Returns ------- str or None Path to the saved layout file if created, otherwise None. """ if modality == "MEG" and output_format == "FIF": FIF_layouts = { "FIF_MAG_ALL": { "MAG_ALL": [ "MEG0121", "MEG0341", "MEG0311", "MEG0321", "MEG0511", "MEG0541", "MEG0331", "MEG0521", "MEG0531", "MEG0611", "MEG0641", "MEG0621", "MEG0821", "MEG1411", "MEG1221", "MEG1211", "MEG1231", "MEG0921", "MEG0931", "MEG1241", "MEG0911", "MEG0941", "MEG1021", "MEG1031", "MEG0811", "MEG1011", "MEG0111", "MEG0131", "MEG0211", "MEG0221", "MEG0141", "MEG1511", "MEG0241", "MEG0231", "MEG1541", "MEG1521", "MEG1611", "MEG1621", "MEG1531", "MEG1421", "MEG1311", "MEG1321", "MEG1441", "MEG1431", "MEG1341", "MEG1331", "MEG2611", "MEG2411", "MEG2421", "MEG2641", "MEG2621", "MEG2631", "MEG0411", "MEG0421", "MEG0631", "MEG0441", "MEG0431", "MEG0711", "MEG1811", "MEG1821", "MEG0741", "MEG1631", "MEG1841", "MEG1831", "MEG2011", "MEG1041", "MEG1111", "MEG1121", "MEG0721", "MEG1141", "MEG1131", "MEG0731", "MEG2211", "MEG2221", "MEG2241", "MEG2231", "MEG2441", "MEG2021", "MEG1641", "MEG1721", "MEG1711", "MEG1911", "MEG1941", "MEG1731", "MEG2041", "MEG1921", "MEG1931", "MEG1741", "MEG2111", "MEG2141", "MEG2431", "MEG2521", "MEG2531", "MEG2311", "MEG2321", "MEG2511", "MEG2031", "MEG2341", "MEG2331", "MEG2541", "MEG2121", "MEG2131", ], }, "FIF_MEG_LOBE": { "MAG_frontal_left": [ "MEG0121", "MEG0341", "MEG0311", "MEG0321", "MEG0511", "MEG0541", "MEG0331", "MEG0521", "MEG0531", "MEG0611", "MEG0641", "MEG0621", "MEG0821", ], "MAG_frontal_right": [ "MEG1411", "MEG1221", "MEG1211", "MEG1231", "MEG0921", "MEG0931", "MEG1241", "MEG0911", "MEG0941", "MEG1021", "MEG1031", "MEG0811", "MEG1011", ], "MAG_temporal_left": [ "MEG0111", "MEG0131", "MEG0211", "MEG0221", "MEG0141", "MEG1511", "MEG0241", "MEG0231", "MEG1541", "MEG1521", "MEG1611", "MEG1621", "MEG1531", ], "MAG_temporal_right": [ "MEG1421", "MEG1311", "MEG1321", "MEG1441", "MEG1431", "MEG1341", "MEG1331", "MEG2611", "MEG2411", "MEG2421", "MEG2641", "MEG2621", "MEG2631", ], "MAG_parietal_left": [ "MEG0411", "MEG0421", "MEG0631", "MEG0441", "MEG0431", "MEG0711", "MEG1811", "MEG1821", "MEG0741", "MEG1631", "MEG1841", "MEG1831", "MEG2011", ], "MAG_parietal_right": [ "MEG1041", "MEG1111", "MEG1121", "MEG0721", "MEG1141", "MEG1131", "MEG0731", "MEG2211", "MEG2221", "MEG2241", "MEG2231", "MEG2441", "MEG2021", ], "MAG_occipital_left": [ "MEG1641", "MEG1721", "MEG1711", "MEG1911", "MEG1941", "MEG1731", "MEG2041", "MEG1921", "MEG1931", "MEG1741", "MEG2111", "MEG2141", ], "MAG_occipital_right": [ "MEG2431", "MEG2521", "MEG2531", "MEG2311", "MEG2321", "MEG2511", "MEG2031", "MEG2341", "MEG2331", "MEG2541", "MEG2121", "MEG2131", ], "GRAD1_frontal_left": [ "MEG0122", "MEG0342", "MEG0312", "MEG0322", "MEG0512", "MEG0542", "MEG0332", "MEG0522", "MEG0532", "MEG0612", "MEG0642", "MEG0622", "MEG0822", ], "GRAD1_frontal_right": [ "MEG1412", "MEG1222", "MEG1212", "MEG1232", "MEG0922", "MEG0932", "MEG1242", "MEG0912", "MEG0942", "MEG1022", "MEG1032", "MEG0812", "MEG1012", ], "GRAD1_temporal_left": [ "MEG0112", "MEG0132", "MEG0212", "MEG0222", "MEG0142", "MEG1512", "MEG0242", "MEG0232", "MEG1542", "MEG1522", "MEG1612", "MEG1622", "MEG1532", ], "GRAD1_temporal_right": [ "MEG1422", "MEG1312", "MEG1322", "MEG1442", "MEG1432", "MEG1342", "MEG1332", "MEG2612", "MEG2412", "MEG2422", "MEG2642", "MEG2622", "MEG2632", ], "GRAD1_parietal_left": [ "MEG0412", "MEG0422", "MEG0632", "MEG0442", "MEG0432", "MEG0712", "MEG1812", "MEG1822", "MEG0742", "MEG1632", "MEG1842", "MEG1832", "MEG2012", ], "GRAD1_parietal_right": [ "MEG1042", "MEG1112", "MEG1122", "MEG0722", "MEG1142", "MEG1132", "MEG0732", "MEG2212", "MEG2222", "MEG2242", "MEG2232", "MEG2442", "MEG2022", ], "GRAD1_occipital_left": [ "MEG1642", "MEG1722", "MEG1712", "MEG1912", "MEG1942", "MEG1732", "MEG2042", "MEG1922", "MEG1932", "MEG1742", "MEG2112", "MEG2142", ], "GRAD1_occipital_right": [ "MEG2432", "MEG2522", "MEG2532", "MEG2312", "MEG2322", "MEG2512", "MEG2032", "MEG2342", "MEG2332", "MEG2542", "MEG2122", "MEG2132", ], "GRAD2_frontal_left": [ "MEG0123", "MEG0343", "MEG0313", "MEG0323", "MEG0513", "MEG0543", "MEG0333", "MEG0523", "MEG0533", "MEG0613", "MEG0643", "MEG0623", "MEG0823", ], "GRAD2_frontal_right": [ "MEG1413", "MEG1223", "MEG1213", "MEG1233", "MEG0923", "MEG0933", "MEG1243", "MEG0913", "MEG0943", "MEG1023", "MEG1033", "MEG0813", "MEG1013", ], "GRAD2_temporal_left": [ "MEG0113", "MEG0133", "MEG0213", "MEG0223", "MEG0143", "MEG1513", "MEG0243", "MEG0233", "MEG1543", "MEG1523", "MEG1613", "MEG1623", "MEG1533", ], "GRAD2_temporal_right": [ "MEG1423", "MEG1313", "MEG1323", "MEG1443", "MEG1433", "MEG1343", "MEG1333", "MEG2613", "MEG2413", "MEG2423", "MEG2643", "MEG2623", "MEG2633", ], "GRAD2_parietal_left": [ "MEG0413", "MEG0423", "MEG0633", "MEG0443", "MEG0433", "MEG0713", "MEG1813", "MEG1823", "MEG0743", "MEG1633", "MEG1843", "MEG1833", "MEG2013", ], "GRAD2_parietal_right": [ "MEG1043", "MEG1113", "MEG1123", "MEG0723", "MEG1143", "MEG1133", "MEG0733", "MEG2213", "MEG2223", "MEG2243", "MEG2233", "MEG2443", "MEG2023", ], "GRAD2_occipital_left": [ "MEG1643", "MEG1723", "MEG1713", "MEG1913", "MEG1943", "MEG1733", "MEG2043", "MEG1923", "MEG1933", "MEG1743", "MEG2113", "MEG2143", ], "GRAD2_occipital_right": [ "MEG2433", "MEG2523", "MEG2533", "MEG2313", "MEG2323", "MEG2513", "MEG2033", "MEG2343", "MEG2333", "MEG2543", "MEG2123", "MEG2133", ], }, "FIF_GRAD_ALL": { "GRAD_ALL": [ "MEG0122", "MEG0342", "MEG0312", "MEG0322", "MEG0512", "MEG0542", "MEG0332", "MEG0522", "MEG0532", "MEG0612", "MEG0642", "MEG0622", "MEG0822", "MEG1412", "MEG1222", "MEG1212", "MEG1232", "MEG0922", "MEG0932", "MEG1242", "MEG0912", "MEG0942", "MEG1022", "MEG1032", "MEG0812", "MEG1012", "MEG0112", "MEG0132", "MEG0212", "MEG0222", "MEG0142", "MEG1512", "MEG0242", "MEG0232", "MEG1542", "MEG1522", "MEG1612", "MEG1622", "MEG1532", "MEG1422", "MEG1312", "MEG1322", "MEG1442", "MEG1432", "MEG1342", "MEG1332", "MEG2612", "MEG2412", "MEG2422", "MEG2642", "MEG2622", "MEG2632", "MEG0412", "MEG0422", "MEG0632", "MEG0442", "MEG0432", "MEG0712", "MEG1812", "MEG1822", "MEG0742", "MEG1632", "MEG1842", "MEG1832", "MEG2012", "MEG1042", "MEG1112", "MEG1122", "MEG0722", "MEG1142", "MEG1132", "MEG0732", "MEG2212", "MEG2222", "MEG2242", "MEG2232", "MEG2442", "MEG2022", "MEG1642", "MEG1722", "MEG1712", "MEG1912", "MEG1942", "MEG1732", "MEG2042", "MEG1922", "MEG1932", "MEG1742", "MEG2112", "MEG2142", "MEG2432", "MEG2522", "MEG2532", "MEG2312", "MEG2322", "MEG2512", "MEG2032", "MEG2342", "MEG2332", "MEG2542", "MEG2122", "MEG2132", "MEG0123", "MEG0343", "MEG0313", "MEG0323", "MEG0513", "MEG0543", "MEG0333", "MEG0523", "MEG0533", "MEG0613", "MEG0643", "MEG0623", "MEG0823", "MEG1413", "MEG1223", "MEG1213", "MEG1233", "MEG0923", "MEG0933", "MEG1243", "MEG0913", "MEG0943", "MEG1023", "MEG1033", "MEG0813", "MEG1013", "MEG0113", "MEG0133", "MEG0213", "MEG0223", "MEG0143", "MEG1513", "MEG0243", "MEG0233", "MEG1543", "MEG1523", "MEG1613", "MEG1623", "MEG1533", "MEG1423", "MEG1313", "MEG1323", "MEG1443", "MEG1433", "MEG1343", "MEG1333", "MEG2613", "MEG2413", "MEG2423", "MEG2643", "MEG2623", "MEG2633", "MEG0413", "MEG0423", "MEG0633", "MEG0443", "MEG0433", "MEG0713", "MEG1813", "MEG1823", "MEG0743", "MEG1633", "MEG1843", "MEG1833", "MEG2013", "MEG1043", "MEG1113", "MEG1123", "MEG0723", "MEG1143", "MEG1133", "MEG0733", "MEG2213", "MEG2223", "MEG2243", "MEG2233", "MEG2443", "MEG2023", "MEG1643", "MEG1723", "MEG1713", "MEG1913", "MEG1943", "MEG1733", "MEG2043", "MEG1923", "MEG1933", "MEG1743", "MEG2113", "MEG2143", "MEG2433", "MEG2523", "MEG2533", "MEG2313", "MEG2323", "MEG2513", "MEG2033", "MEG2343", "MEG2333", "MEG2543", "MEG2123", "MEG2133", ] }, } save_sensor_layouts(FIF_layouts, "FIF") return get_relative_path("FIF") elif modality == "MEG" and output_format == "DS": DS_layouts = { "DS_MAG_ALL": { "GRAD_ALL": [ "MLC11-1609", "MLC12-1609", "MLC13-1609", "MLC14-1609", "MLC15-1609", "MLC16-1609", "MLC17-1609", "MLC21-1609", "MLC22-1609", "MLC23-1609", "MLC24-1609", "MLC25-1609", "MLC31-1609", "MLC32-1609", "MLC41-1609", "MLC42-1609", "MLC51-1609", "MLC52-1609", "MLC53-1609", "MLC54-1609", "MLC55-1609", "MLC61-1609", "MLC62-1609", "MLC63-1609", "MLF11-1609", "MLF12-1609", "MLF13-1609", "MLF14-1609", "MLF21-1609", "MLF22-1609", "MLF23-1609", "MLF24-1609", "MLF31-1609", "MLF32-1609", "MLF33-1609", "MLF34-1609", "MLF35-1609", "MLF41-1609", "MLF42-1609", "MLF43-1609", "MLF44-1609", "MLF45-1609", "MLF46-1609", "MLF51-1609", "MLF52-1609", "MLF53-1609", "MLF54-1609", "MLF55-1609", "MLF56-1609", "MLF61-1609", "MLF62-1609", "MLF63-1609", "MLF64-1609", "MLF65-1609", "MLF66-1609", "MLF67-1609", "MLO11-1609", "MLO12-1609", "MLO13-1609", "MLO14-1609", "MLO21-1609", "MLO22-1609", "MLO23-1609", "MLO24-1609", "MLO31-1609", "MLO32-1609", "MLO33-1609", "MLO34-1609", "MLO41-1609", "MLO42-1609", "MLO43-1609", "MLO44-1609", "MLO51-1609", "MLO52-1609", "MLO53-1609", "MLP11-1609", "MLP12-1609", "MLP21-1609", "MLP22-1609", "MLP23-1609", "MLP31-1609", "MLP32-1609", "MLP33-1609", "MLP34-1609", "MLP35-1609", "MLP41-1609", "MLP42-1609", "MLP43-1609", "MLP44-1609", "MLP45-1609", "MLP51-1609", "MLP52-1609", "MLP53-1609", "MLP54-1609", "MLP55-1609", "MLP56-1609", "MLP57-1609", "MLT11-1609", "MLT12-1609", "MLT13-1609", "MLT14-1609", "MLT15-1609", "MLT16-1609", "MLT21-1609", "MLT22-1609", "MLT23-1609", "MLT24-1609", "MLT25-1609", "MLT26-1609", "MLT27-1609", "MLT31-1609", "MLT32-1609", "MLT33-1609", "MLT34-1609", "MLT35-1609", "MLT36-1609", "MLT37-1609", "MLT41-1609", "MLT42-1609", "MLT43-1609", "MLT44-1609", "MLT45-1609", "MLT46-1609", "MLT47-1609", "MLT51-1609", "MLT52-1609", "MLT53-1609", "MLT54-1609", "MLT55-1609", "MLT56-1609", "MLT57-1609", "MRC11-1609", "MRC12-1609", "MRC13-1609", "MRC14-1609", "MRC15-1609", "MRC16-1609", "MRC17-1609", "MRC21-1609", "MRC22-1609", "MRC23-1609", "MRC24-1609", "MRC25-1609", "MRC31-1609", "MRC32-1609", "MRC41-1609", "MRC42-1609", "MRC51-1609", "MRC52-1609", "MRC53-1609", "MRC54-1609", "MRC55-1609", "MRC61-1609", "MRC62-1609", "MRC63-1609", "MRF11-1609", "MRF12-1609", "MRF13-1609", "MRF14-1609", "MRF21-1609", "MRF22-1609", "MRF23-1609", "MRF24-1609", "MRF25-1609", "MRF31-1609", "MRF32-1609", "MRF33-1609", "MRF34-1609", "MRF35-1609", "MRF41-1609", "MRF42-1609", "MRF44-1609", "MRF45-1609", "MRF46-1609", "MRF51-1609", "MRF52-1609", "MRF53-1609", "MRF54-1609", "MRF55-1609", "MRF56-1609", "MRF61-1609", "MRF62-1609", "MRF63-1609", "MRF64-1609", "MRF65-1609", "MRF66-1609", "MRF67-1609", "MRO11-1609", "MRO12-1609", "MRO14-1609", "MRO21-1609", "MRO22-1609", "MRO23-1609", "MRO24-1609", "MRO31-1609", "MRO32-1609", "MRO33-1609", "MRO34-1609", "MRO41-1609", "MRO42-1609", "MRO43-1609", "MRO44-1609", "MRO51-1609", "MRO52-1609", "MRO53-1609", "MRP11-1609", "MRP12-1609", "MRP21-1609", "MRP22-1609", "MRP23-1609", "MRP31-1609", "MRP32-1609", "MRP33-1609", "MRP34-1609", "MRP35-1609", "MRP41-1609", "MRP42-1609", "MRP43-1609", "MRP44-1609", "MRP45-1609", "MRP51-1609", "MRP52-1609", "MRP53-1609", "MRP54-1609", "MRP55-1609", "MRP56-1609", "MRP57-1609", "MRT11-1609", "MRT12-1609", "MRT13-1609", "MRT14-1609", "MRT15-1609", "MRT16-1609", "MRT21-1609", "MRT22-1609", "MRT23-1609", "MRT24-1609", "MRT25-1609", "MRT26-1609", "MRT27-1609", "MRT31-1609", "MRT32-1609", "MRT33-1609", "MRT34-1609", "MRT35-1609", "MRT36-1609", "MRT37-1609", "MRT41-1609", "MRT42-1609", "MRT43-1609", "MRT44-1609", "MRT45-1609", "MRT46-1609", "MRT47-1609", "MRT51-1609", "MRT52-1609", "MRT53-1609", "MRT54-1609", "MRT55-1609", "MRT56-1609", "MRT57-1609", "MZC01-1609", "MZC02-1609", "MZC03-1609", "MZC04-1609", "MZF01-1609", "MZF02-1609", "MZF03-1609", "MZO01-1609", "MZO02-1609", "MZO03-1609", "MZP01-1609", ] } } save_sensor_layouts(DS_layouts, "DS") return get_relative_path("DS") elif modality == "EEG" and output_format == "SET": SET_layouts = { "SET_EEG_ALL": { "EEG_ALL": [ "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "E10", "E11", "E12", "E13", "E14", "E15", "E16", "E17", "E18", "E19", "E20", "E21", "E22", "E23", "E24", "E25", "E26", "E27", "E28", "E29", "E30", "E31", "E32", "E33", "E34", "E35", "E36", "E37", "E38", "E39", "E40", "E41", "E42", "E43", "E44", "E45", "E46", "E47", "E48", "E49", "E50", "E51", "E52", "E53", "E54", "E55", "E56", "E57", "E58", "E59", "E60", "E61", "E62", "E63", "E64", "E65", "E66", "E67", "E68", "E69", "E70", "E71", "E72", "E73", "E74", "E75", "E76", "E77", "E78", "E79", "E80", "E81", "E82", "E83", "E84", "E85", "E86", "E87", "E88", "E89", "E90", "E91", "E92", "E93", "E94", "E95", "E96", "E97", "E98", "E99", "E100", "E101", "E102", "E103", "E104", "E105", "E106", "E107", "E108", "E109", "E110", "E111", "E112", "E113", "E114", "E115", "E116", "E117", "E118", "E119", "E120", "E121", "E122", "E123", "E124", "E125", "E126", "E127", "E128", "Cz", ] }, # The devision in layout is based on Rayson et al. (2019), Zora et al. (2016) "SET_EEG_LOBE": { "frontal_left": [ "E20", "E12", "E28", "E24", "E19", "E27", "E23", "E18", "E22", "E26", "E33", ], "frontal_right": [ "E5", "E118", "E4", "E124", "E117", "E10", "E3", "E123", "E9", "E2", "E122", ], "central_left": [ "E7", "E31" "E54", "E37", "E30", "E13", "E61", "E29", "E36", "E42", "E53", ], "central_right": [ "E106", "E80", "E112", "E105", "E87", "E79", "E78", "E111", "E104", "E93", "E86", ], "temporal_left": [ "E45", "E50", "E58", "E39", "E44", "E49", "E56", ], "temporal_right": [ "E115", "E108", "E101", "E96", "E114", "E113", "E107", ], "parietal_left": [ "E67", "E66", "E71", "E47", "E52", "E60", "E51", "E59", ], "parietal_right": [ "E77", "E76", "E84", "E85", "E92", "E98", "E91", "E97", ], "occipital_left": [ "E70", "E69", "E74", "E73", ], "occipital_right": [ "E83", "E82", "E89", "E88", ], }, } save_sensor_layouts(SET_layouts, "SET") return get_relative_path("SET") elif ( modality == "EEG" and output_format == "VHDR" ): # 26-channel EEG-recordings, based on the 10–10 electrode international system using a Compumedics Quickcap or ANT-Neuro Waveguard Cap with sintered Ag/AgCl electrode, file is .vhdr VHDR_layouts = { "VHDR_EEG_ALL": { "EEG_ALL": [ "Fp1", "Fp2", "F7", "F3", "Fz", "F4", "F8", "FC3", "FCz", "FC4", "T7", "C3", "Cz", "C4", "T8", "CP3", "CPz", "CP4", "P7", "P3", "Pz", "P4", "P8", "O1", "Oz", "O2", "VPVA", "VNVB", "HPHL", "HNHR", "Erbs", "OrbOcc", "Mass", ] }, "VHDR_EEG_LOBE": { "frontal_left": [ "Fp1", "F7", "F3", ], "frontal_right": [ "Fp2", "F4", "F8", ], "central_left": [ "FC3", "C3", "CP3", ], "central_right": [ "FC4", "C4", "CP4", ], "temporal_left": [ "T7", ], "temporal_right": [ "T8", ], "parietal_left": [ "P7", "P3", ], "parietal_right": [ "P4", "P8", ], "occipital_left": [ "O1", ], "occipital_right": [ "O2", ], }, } save_sensor_layouts(VHDR_layouts, "VHDR") return get_relative_path("VHDR") else: print( f"No predefined layout available for modality '{modality}' and output_format '{output_format}'." ) return None