@@ -55,6 +55,9 @@ def _parse_header(self):
5555 marker_filename = self .filename .replace (bname , vhdr_header ["Common Infos" ]["MarkerFile" ])
5656 binary_filename = self .filename .replace (bname , vhdr_header ["Common Infos" ]["DataFile" ])
5757
58+ marker_filename = self ._ensure_filename (marker_filename , "marker" , "MarkerFile" )
59+ binary_filename = self ._ensure_filename (binary_filename , "data" , "DataFile" )
60+
5861 if vhdr_header ["Common Infos" ]["DataFormat" ] != "BINARY" :
5962 raise NeoReadWriteError (
6063 f"Only `BINARY` format has been implemented. Current Data Format is { vhdr_header ['Common Infos' ]['DataFormat' ]} "
@@ -236,6 +239,48 @@ def _rescale_event_timestamp(self, event_timestamps, dtype, event_channel_index)
236239 def _get_analogsignal_buffer_description (self , block_index , seg_index , buffer_id ):
237240 return self ._buffer_descriptions [block_index ][seg_index ][buffer_id ]
238241
242+ def _ensure_filename (self , filename , kind , entry_name ):
243+ if not os .path .exists (filename ):
244+ # file not found, subsequent import stage would fail
245+ ext = os .path .splitext (filename )[1 ]
246+ # Check if we can fall back to a file with the same prefix as the .vhdr.
247+ # This can happen when users rename their files but forget to edit the
248+ # .vhdr file to fix the path reference to the binary and marker files,
249+ # in which case import will fail. These files come in triples, like:
250+ # myfile.vhdr, myfile.eeg and myfile.vmrk; this code will thus pick
251+ # the next best alternative.
252+ alt_name = self .filename .replace (".vhdr" , ext )
253+ if os .path .exists (alt_name ):
254+ self .logger .warning (
255+ f"The { kind } file { filename } was not found, but found a file whose "
256+ f"prefix matched the .vhdr ({ os .path .basename (alt_name )} ). Using "
257+ f"this file instead." )
258+ filename = alt_name
259+ else :
260+ # we neither found the file referenced in the .vhdr file nor a file of
261+ # same name as header with the desired extension; most likely a file went
262+ # missing or was renamed in an inconsistent fashion; generate a useful
263+ # error message
264+ header_dname = os .path .dirname (self .filename )
265+ header_bname = os .path .basename (self .filename )
266+ referenced_bname = os .path .basename (filename )
267+ alt_bname = os .path .basename (alt_name )
268+ if alt_bname != referenced_bname :
269+ # this is only needed when the two candidate file names differ
270+ detail = (f" is named either as per the { entry_name } ={ referenced_bname } "
271+ f"line in the .vhdr file, or" )
272+ else :
273+ # we omit it if we can to make it less confusing
274+ detail = ""
275+ self .logger .error (
276+ f"Did not find the { kind } file associated with .vhdr (header) "
277+ f"file { header_bname !r} in folder { header_dname !r} .\n Please make "
278+ f"sure the file{ detail } is named the same way as the .vhdr file, but "
279+ f"ending in { ext } (i.e. { alt_bname } ).\n The import will likely fail, "
280+ f"but if it goes through, you can ignore this message (the check "
281+ f"can misfire on networked file systems)." )
282+ return filename
283+
239284
240285def read_brainvsion_soup (filename ):
241286 with open (filename , "r" , encoding = "utf8" ) as f :
0 commit comments