Feature Request: Add header parameter to BData.save() method
Summary
Add an optional header parameter to the BData.save() method to allow users to control whether header information (creation time, call stack, code) is saved. This is particularly important when preparing data for public release.
Motivation
Currently, BData.save() automatically saves header information that may contain sensitive details such as:
- Absolute file paths from the call stack
- Source code contents
- User-specific directory structures
When preparing datasets for public release or sharing with collaborators, it is often necessary to exclude such metadata for:
- Public data repositories: Clean data for platforms like Figshare, OpenNeuro
- Privacy and security: Prevent leakage of internal paths and code
- Collaboration: Share data without exposing implementation details
- File size optimization: Reduce unnecessary metadata
Current Workaround
The only way to avoid saving header information is to use the private method:
bdata._BData__save_h5(filepath, header=None)
This violates Python conventions and is neither documented nor officially supported.
Proposed Solution
Add an optional header parameter to the BData.save() method:
def save(self, file_name: str, file_type: Optional[str] = None, header: bool = True) -> None:
"""
Save 'dataset' and 'metadata' to a file.
Parameters
----------
file_name : str
File name
file_type : str, optional
File type (currently only 'HDF5' is supported)
header : bool, optional (default: True)
If True (default), save header information (creation time, call stack, code).
If False, do not save header information.
Returns
-------
None
"""
Implementation Details
- Default behavior:
header=True (preserve backward compatibility)
- When
header=True: Current behavior - update self.__header with timestamp, call stack, and code, then pass to __save_h5()
- When
header=False: Skip header update and pass None to __save_h5()
- The conditional logic should be added before the header update section
Suggested Implementation
def save(self, file_name: str, file_type: Optional[str] = None, header: bool = True) -> None:
"""Save 'dataset' and 'metadata' to a file."""
# Store data creation information (only if header=True)
if header:
t_now = time.time()
t_now_str = datetime.datetime.fromtimestamp(t_now).strftime('%Y-%m-%d %H:%M:%S')
callstack = []
callstack_code = []
f = inspect.currentframe()
while True:
f = f.f_back
if f is None:
break
fname = os.path.abspath(f.f_code.co_filename)
fline = f.f_lineno
callstack.append('%s:%d' % (fname, fline))
if os.path.exists(fname):
with open(fname, 'r') as fl:
fcode = fl.read()
else:
fcode = ''
callstack_code.append(fcode)
self.__header.update({'ctime': t_now_str,
'ctime_epoch': t_now,
'callstack': callstack,
'callstack_code': callstack_code})
header_to_save = self.__header
else:
header_to_save = None
if file_type is None:
file_type = self.__get_filetype(file_name)
if file_type == "Matlab":
raise RuntimeError('Saving BData as a mat file is no longer supported. Please save the data as HDF5 (.h5).')
elif file_type == "HDF5":
self.__save_h5(file_name, header=header_to_save)
else:
raise ValueError("Unknown file type: %s" % (file_type))
Example Usage
# Save with header (current default behavior)
bdata.save('output.h5')
bdata.save('output.h5', header=True)
# Save without header (new feature)
bdata.save('output.h5', header=False)
Feature Request: Add
headerparameter toBData.save()methodSummary
Add an optional
headerparameter to theBData.save()method to allow users to control whether header information (creation time, call stack, code) is saved. This is particularly important when preparing data for public release.Motivation
Currently,
BData.save()automatically saves header information that may contain sensitive details such as:When preparing datasets for public release or sharing with collaborators, it is often necessary to exclude such metadata for:
Current Workaround
The only way to avoid saving header information is to use the private method:
This violates Python conventions and is neither documented nor officially supported.
Proposed Solution
Add an optional
headerparameter to theBData.save()method:Implementation Details
header=True(preserve backward compatibility)header=True: Current behavior - updateself.__headerwith timestamp, call stack, and code, then pass to__save_h5()header=False: Skip header update and passNoneto__save_h5()Suggested Implementation
Example Usage