@@ -276,6 +276,7 @@ def create(
276276 return_scaled = True ,
277277 backend_options = None ,
278278 ):
279+ assert recording is not None , "To create a SortingAnalyzer you need to specify the recording"
279280 # some checks
280281 if sorting .sampling_frequency != recording .sampling_frequency :
281282 if math .isclose (sorting .sampling_frequency , recording .sampling_frequency , abs_tol = 1e-2 , rel_tol = 1e-5 ):
@@ -388,8 +389,6 @@ def create_memory(cls, sorting, recording, sparsity, return_scaled, rec_attribut
388389 def create_binary_folder (cls , folder , sorting , recording , sparsity , return_scaled , rec_attributes , backend_options ):
389390 # used by create and save_as
390391
391- assert recording is not None , "To create a SortingAnalyzer you need to specify the recording"
392-
393392 folder = Path (folder )
394393 if folder .is_dir ():
395394 raise ValueError (f"Folder already exists { folder } " )
@@ -405,26 +404,34 @@ def create_binary_folder(cls, folder, sorting, recording, sparsity, return_scale
405404 json .dump (check_json (info ), f , indent = 4 )
406405
407406 # save a copy of the sorting
408- # NumpyFolderSorting.write_sorting(sorting, folder / "sorting")
409407 sorting .save (folder = folder / "sorting" )
410408
411- # save recording and sorting provenance
412- if recording .check_serializability ("json" ):
413- recording .dump (folder / "recording.json" , relative_to = folder )
414- elif recording .check_serializability ("pickle" ):
415- recording .dump (folder / "recording.pickle" , relative_to = folder )
409+ if recording is not None :
410+ # save recording and sorting provenance
411+ if recording .check_serializability ("json" ):
412+ recording .dump (folder / "recording.json" , relative_to = folder )
413+ elif recording .check_serializability ("pickle" ):
414+ recording .dump (folder / "recording.pickle" , relative_to = folder )
415+ else :
416+ warnings .warn ("The Recording is not serializable! The recording link will be lost for future load" )
417+ else :
418+ assert rec_attributes is not None , "recording or rec_attributes must be provided"
419+ warnings .warn ("Recording not provided, instntiating SortingAnalyzer in recordingless mode." )
416420
417421 if sorting .check_serializability ("json" ):
418422 sorting .dump (folder / "sorting_provenance.json" , relative_to = folder )
419423 elif sorting .check_serializability ("pickle" ):
420424 sorting .dump (folder / "sorting_provenance.pickle" , relative_to = folder )
425+ else :
426+ warnings .warn (
427+ "The sorting provenance is not serializable! The sorting provenance link will be lost for future load"
428+ )
421429
422430 # dump recording attributes
423431 probegroup = None
424432 rec_attributes_file = folder / "recording_info" / "recording_attributes.json"
425433 rec_attributes_file .parent .mkdir ()
426434 if rec_attributes is None :
427- assert recording is not None
428435 rec_attributes = get_rec_attributes (recording )
429436 rec_attributes_file .write_text (json .dumps (check_json (rec_attributes ), indent = 4 ), encoding = "utf8" )
430437 probegroup = recording .get_probegroup ()
@@ -565,21 +572,21 @@ def create_zarr(cls, folder, sorting, recording, sparsity, return_scaled, rec_at
565572 zarr_root .attrs ["settings" ] = check_json (settings )
566573
567574 # the recording
568- rec_dict = recording .to_dict (relative_to = folder , recursive = True )
569-
570- if recording .check_serializability ("json" ):
571- # zarr_root.create_dataset("recording", data=rec_dict, object_codec=numcodecs.JSON())
572- zarr_rec = np .array ([check_json (rec_dict )], dtype = object )
573- zarr_root .create_dataset ("recording" , data = zarr_rec , object_codec = numcodecs .JSON ())
574- elif recording .check_serializability ("pickle" ):
575- # zarr_root.create_dataset("recording", data=rec_dict, object_codec=numcodecs.Pickle())
576- zarr_rec = np .array ([rec_dict ], dtype = object )
577- zarr_root .create_dataset ("recording" , data = zarr_rec , object_codec = numcodecs .Pickle ())
575+ if recording is not None :
576+ rec_dict = recording .to_dict (relative_to = folder , recursive = True )
577+ if recording .check_serializability ("json" ):
578+ # zarr_root.create_dataset("recording", data=rec_dict, object_codec=numcodecs.JSON())
579+ zarr_rec = np .array ([check_json (rec_dict )], dtype = object )
580+ zarr_root .create_dataset ("recording" , data = zarr_rec , object_codec = numcodecs .JSON ())
581+ elif recording .check_serializability ("pickle" ):
582+ # zarr_root.create_dataset("recording", data=rec_dict, object_codec=numcodecs.Pickle())
583+ zarr_rec = np .array ([rec_dict ], dtype = object )
584+ zarr_root .create_dataset ("recording" , data = zarr_rec , object_codec = numcodecs .Pickle ())
585+ else :
586+ warnings .warn ("The Recording is not serializable! The recording link will be lost for future load" )
578587 else :
579- warnings .warn (
580- "SortingAnalyzer with zarr : the Recording is not json serializable, "
581- "the recording link will be lost for future load"
582- )
588+ assert rec_attributes is not None , "recording or rec_attributes must be provided"
589+ warnings .warn ("Recording not provided, instntiating SortingAnalyzer in recordingless mode." )
583590
584591 # sorting provenance
585592 sort_dict = sorting .to_dict (relative_to = folder , recursive = True )
@@ -589,14 +596,14 @@ def create_zarr(cls, folder, sorting, recording, sparsity, return_scaled, rec_at
589596 elif sorting .check_serializability ("pickle" ):
590597 zarr_sort = np .array ([sort_dict ], dtype = object )
591598 zarr_root .create_dataset ("sorting_provenance" , data = zarr_sort , object_codec = numcodecs .Pickle ())
592-
593- # else:
594- # warnings.warn("SortingAnalyzer with zarr : the sorting provenance is not json serializable, the sorting provenance link will be lost for futur load")
599+ else :
600+ warnings .warn (
601+ "The sorting provenance is not serializable! The sorting provenance link will be lost for future load"
602+ )
595603
596604 recording_info = zarr_root .create_group ("recording_info" )
597605
598606 if rec_attributes is None :
599- assert recording is not None
600607 rec_attributes = get_rec_attributes (recording )
601608 probegroup = recording .get_probegroup ()
602609 else :
@@ -651,11 +658,13 @@ def load_from_zarr(cls, folder, recording=None, backend_options=None):
651658
652659 # load recording if possible
653660 if recording is None :
654- rec_dict = zarr_root ["recording" ][0 ]
655- try :
656- recording = load_extractor (rec_dict , base_folder = folder )
657- except :
658- recording = None
661+ rec_field = zarr_root .get ("recording" )
662+ if rec_field is not None :
663+ rec_dict = rec_field [0 ]
664+ try :
665+ recording = load_extractor (rec_dict , base_folder = folder )
666+ except :
667+ recording = None
659668 else :
660669 # TODO maybe maybe not??? : do we need to check attributes match internal rec_attributes
661670 # Note this will make the loading too slow
@@ -2083,7 +2092,7 @@ def copy(self, new_sorting_analyzer, unit_ids=None):
20832092 new_extension .data = self .data
20842093 else :
20852094 new_extension .data = self ._select_extension_data (unit_ids )
2086- new_extension .run_info = self .run_info . copy ( )
2095+ new_extension .run_info = copy ( self .run_info )
20872096 new_extension .save ()
20882097 return new_extension
20892098
@@ -2101,7 +2110,7 @@ def merge(
21012110 new_extension .data = self ._merge_extension_data (
21022111 merge_unit_groups , new_unit_ids , new_sorting_analyzer , keep_mask , verbose = verbose , ** job_kwargs
21032112 )
2104- new_extension .run_info = self .run_info . copy ( )
2113+ new_extension .run_info = copy ( self .run_info )
21052114 new_extension .save ()
21062115 return new_extension
21072116
@@ -2319,15 +2328,16 @@ def _save_importing_provenance(self):
23192328 extension_group .attrs ["info" ] = info
23202329
23212330 def _save_run_info (self ):
2322- run_info = self .run_info .copy ()
2323-
2324- if self .format == "binary_folder" :
2325- extension_folder = self ._get_binary_extension_folder ()
2326- run_info_file = extension_folder / "run_info.json"
2327- run_info_file .write_text (json .dumps (run_info , indent = 4 ), encoding = "utf8" )
2328- elif self .format == "zarr" :
2329- extension_group = self ._get_zarr_extension_group (mode = "r+" )
2330- extension_group .attrs ["run_info" ] = run_info
2331+ if self .run_info is not None :
2332+ run_info = self .run_info .copy ()
2333+
2334+ if self .format == "binary_folder" :
2335+ extension_folder = self ._get_binary_extension_folder ()
2336+ run_info_file = extension_folder / "run_info.json"
2337+ run_info_file .write_text (json .dumps (run_info , indent = 4 ), encoding = "utf8" )
2338+ elif self .format == "zarr" :
2339+ extension_group = self ._get_zarr_extension_group (mode = "r+" )
2340+ extension_group .attrs ["run_info" ] = run_info
23312341
23322342 def get_pipeline_nodes (self ):
23332343 assert (
0 commit comments