Releases: NeurodataWithoutBorders/aqnwb
Releases · NeurodataWithoutBorders/aqnwb
Release list
0.3.0
Added
- Added
cppcheckstatic analysis integration (@copilot, @oruebel #270):- Added
.github/workflows/cppcheck.ymlCI workflow that runs cppcheck onsrc/andtests/, converts results to SARIF usingairtower-luna/convert-to-sarif, and uploads them to the GitHub Security tab viagithub/codeql-action/upload-sarif - Added
cmake/cppcheck.cmakestandalone script andcmake/cppcheck-targets.cmakefor running cppcheck locally viacmake --build --preset=dev --target=cppcheck - Updated developer documentation in
docs/pages/devdocs/testing.doxanddocs/pages/devdocs/install.doxwith cppcheck usage instructions
- Added
- Added
getDataType(),getChunking(), andtoLinkArrayDataSetConfig()functions toReadDataWrapper(@copilot, @oruebel #266) - Added support for creating soft-links to existing datasets to avoid data duplication (@copilot, @oruebel #257)
- Added
BaseArrayDataSetConfigabstract base class for polymorphic dataset configuration - Added
LinkArrayDataSetConfigclass for creating HDF5 soft-links to existing datasets - Updated
ArrayDataSetConfigto inherit fromBaseArrayDataSetConfig - Updated all NWB type
initialize()methods to acceptBaseArrayDataSetConfig(TimeSeries, ElectricalSeries, SpikeEventSeries, AnnotationSeries, Data, NWBData, VectorData) - Added user docs page on using links and processing modules
docs/pages/userdocs/links.dox - Added
BaseIO::getStorageObjectDataTypeandBaseIO::getStorageObjectChunkingand corresponding HDF5IO implementations - Updated
BaseIO::createArrayDataSetto raisestd::runtime_erroron failure (rather than returning nullptr) to make error handling more robust and to allow link creation to return nullptr without ambiguity. - Added
LinkArrayDataSetConfig::validateTarget()to validate that a link target is compliant with expected schema requirements and updated initialize methods of Data, VectorData, and TimeSeries accordingly to check that link targets are valid (@copilot, @oruebel #259)
- Added
- Added
AQNWB::IO::ConstMultiArrayView<DTYPE, NDIMS>as a lightweight, non-owning const multi-dimensional view over a buffer used to facilitate multi-dimensional array access in C++17/20 (@chittti , #250) - Added UUID/time/endian utilities in
src/Utils.hppto replace corresponding Boost utilities (@chittti, #250) - Added AQNWB_CXX_STANDARD option to the cmake build to allow configuration of the std C++ version to support 17, 20, and 23 to allow the use of
std::mdspanif C++23 is used (@oruebel, #250) - Added
ProcessingModuleclass insrc/nwb/base/to support creation of processed data groups in the/processing/hierarchy of NWB files (@oruebel, #255) - Added
.github/copilot-instructions.mdwith comprehensive onboarding documentation for GitHub Copilot coding agents (@copilot, @oruebel, #256) - Added
docs/pages/devdocs/github_release_workflow.doxwith instructions for how to make a release (@oruebel, #279)
Changed
- Replaced explicit
std::vector<SizeType>usages with theSizeArraytype alias throughout the codebase for consistency (@copilot, @oruebel #262) - Standardized naming of
initialize()parameters generated byschematype_to_aqnwbutility (@copilot, @oruebel #261): - Removed Boost as a dependency (@chittti, #250 )
- Updated
DataBlock::as_multi_array()to returnConstMultiArrayViewinstead ofboost::const_multi_array_refto remove the need Boost and for C++17/20 compatibility (@chittti, #250) - Updated the docs and examples to discuss the optional use of
std::mdspanif C++23 is used (@oruebel, #250) - Changed the dependency includes in CMake so the HDF5 C++ headers and libraries found via
${HDF5_INCLUDE_DIRS}/${HDF5_CXX_LIBRARIES}are exported to AqNWB consumers (@cboulay, #248). - Updated NWBFile to make common root path definitions (e.g., acquisition, processing, stimulus) public to make path generation easier (@oruebel, #257)
Fixed
- Fixed
HDF5IO::createAttributeto use base element type (typeSize=1) for numeric array attributes (instead of array-type with typeSize equal to the number of elements), to enhance compatibility with the NWB schema and PyNWB (@copilot, @oruebel #276) - Fixed a broad set of
cppcheckstatic analysis warnings (@copilot, @oruebel #274, #278; @oruebel #280):- Correctness: Fixed
BaseIO::stopRecordingto return the computed compositestatusinstead of hardcodedStatus::Success; initializedSpikeEventSeries::m_eventsRecordedto0in-class; removed deadchunk/DSetCreatPropListcode fromHDF5RecordingDataconstructor; updated~HDF5IO()to avoid calling the virtualclose()from the destructor; addedoverrideto virtual destructors - Performance: Changed
const std::string/const std::vectorpass-by-value parameters and return types toconst &acrossChannel,AnnotationSeries,ElectrodesTable,NWBFile,nwbio_utils.hpp,BaseIO,ReadIO,RegisteredTypeand test utilities - API hygiene: Added
explicitto single-arg constructors onHDF5IO,HDF5RecordingData,ElectrodesTable, andNWBFile; addedoverridetoHDF5RecordingData::writeDataBlockoverloads; markedBaseIO::getFullTypeNameconst; madeReadDataWrapper::getStorageObjectTypestatic; aligned constructor parameter names inHDF5IO,HDF5ArrayDataSetConfig, andDynamicTable::addReferenceColumn; declaredconst std::tm*pointers inUtils.hpp; removed unused variables in tests - STL modernization: Replaced raw loops with
std::any_of,std::accumulate,std::transform, andstd::find_ifinBaseIO.cpp,HDF5IO.cpp,RecordingObjects.cpp, andReadIO.hpp - cppcheck suppressions: Added
--suppress=duplInheritedMemberand--suppress=normalCheckLevelMaxBranchesglobally tocmake/cppcheck.cmakeand.github/workflows/cppcheck.yml; added inlinecppcheck-suppresscomments for intentional test patterns (duplicateExpression,knownConditionTrueFalse,useStlAlgorithm,variableScope)
- Correctness: Fixed
- Restricted code coverage report to
src/folder only (@copilot, @oruebel #262):- Updated
cmake/coverage.cmaketo use a two-step lcov approach: capture all coverage intocoverage_raw.info, then uselcov --extractto filter tosrc/*only, producing the finalcoverage.info - Added
.codecov.ymlto instruct the Codecov server to ignoretests/**, preventing Codecov-action from including test files it discovers via independentgcovscanning of the build directory
- Updated
- Removed redundant
resources/utils/requirements.txtand update CI accordingly. Dependencies are now defined inresources/utils/pyproject.toml(@copilot, @oruebel #260) - Added explicit
permissionsblocks to all GitHub Actions workflow files to restrictGITHUB_TOKENto least-privilege scopes (@copilot, @oruebel #269)
0.2.0
Added
- Python Utility enhancements:
- Added
aqnwb-utilsas a command-line utility to provide a common interface for aqnwb command line tools, e.g.,schematype_to_aqnwb.pyandgenerate_spec_files.py. (@oruebel, #227) - Added inline script metadata (PEP 723) to Python utilities to enable direct execution with
uv runwithout installation (@oruebel, #229) - Added
pyproject.tomlfor modern Python packaging support (@oruebel, #229)
- Added
- Added
RegisteredType::DEFINE_UNNAMED_REGISTERED_FIELDto simplify creation of read/write methods for RegisteredTypes that do not have a set name in the schema (@oruebel, #231) - Added new
NWBData,NWBDataInterface, andNWBContainerdata types and updated existing classes to match inheritance with NWB schema (@oruebel, #232) - Automated tracking and harmonized memory management of
RegisteredTypeobjects (@oruebel, #209)- Added
BaseIO.m_recording_objectsto track allRegisteredTypeobjects used for recording - Modified
RegisteredTypeto automatically register withRecordingObjectsinstance of the IO - Updated
RegisteredTypeto usestd::weak_ptrto the IO to avoid circular referencing - Made the constructor of
RegisteredTypeand all its subclassesprotectedto prevent direct stack or raw pointer creation.RegisteredTypeobjects must now always be created via theRegisteredType.createfactory, ensuring that all objects are being created asstd::smart_ptrand registered with them_recording_objectsRecordingContainers object of the I/O object - Updated
RegisteredTypeto inherit frompublic std::enable_shared_from_this<RegisteredType> - Updated the
REGISTER_SUBCLASSmacro to add acreatefactory method for all classes
- Added
- Harmonized finalization and clean-up of
RegisteredTypeobjects (@oruebel, #209)- Added
RegisteredType.finalizeto finalize all neurodata_type classes - Added
RecordingObjects.finalizeandRecordingObjects.clearRecordingDataCacheto finalize and clean up all objects in a single call - Updated
BaseIO.stopRecordingto callm_recording_objects.finalize()andm_recording_objects.clearRecordingDataCache()
- Added
Changed
- Updated documentation to refer to the new
aqnwb-utilscommand-line utility (@oruebel, #227) - Updated Python utilities to use
uvinstead ofpipfor dependency management and updated docs and github workflows to use uv (@oruebel, #227 - Enhanced the
schematype_to_aqnwbutility script:- Generated source files are now placed into a folder hierarchy based on the name of the namespace and schemafile of the neurodata_type (@oruebel, #224)
- Added functionality to optionally create a simple example app that instantiates all generated classes to help test that all generated classes can be compiled (@oruebel, #225)
- Updated generation of header files to ensure proper compilation, e.g.: i) identify and include the headers of all neurodata_types that are being used, ii) fixed formatting of comments to avoid nested multi-line comments, iii) fixed issues with incomplete typenames (@oruebel, #225)
- Added GitHub action to test that all sources files generated by the
schematype_to_aqnwbutility for the nwb-schema and LabMetaDataExtension example can be compiled (@oruebel, #225) - Updated the rendering of initialize methods to ensure inclusion of all owned parameters (including those in subgroups), add rendering of default values, and add rendering of suggested initialization code (@oruebel, #230)
- Updated the rendering of initialize cpp source to create the correct call to the parents initialize method @oruebel, #230)
- Updated rendering of read/record methods via DEFINE_FIELD macros to ensure inclusion of all owned parameters (including those in subgroups), consistent with the updates to the initialize methods (@oruebel, #230)
- Refactored code to generated initialize methods to centralize logic and make the code more robust. E.g., created new
get_initialize_method_parametersto compile parameter details in one place and split therender_initialize_methodinto two functions. (@oruebel, #230) - Enhanced the new
get_initialize_method_parametersmethod and rendering functions to correctly track the full path of objects (@oruebel, #230) - Added support for rendering
DEFINE_REFERENCED_REGISTERED_FIELDmacros for attributes that are references (@oruebel, #230) - Added rendering of virtual destructor in the header source (@oruebel, #230)
- Updated generated initialize methods to always return a Status (@oruebel, #230)
- Updated new
get_initialize_method_parametersto ensure for neurodata_types that are Datasets that we include the dataset itself as a custom parameter that needs initialization (@oruebel, #230) - Added support for
DEFINE_UNNAMED_REGISTERED_FIELDmacros for RegisteredTypes that are unnamed in the schema (@oruebel, #231 - Simplify the required signature of the generated initialize methods by placing optional RegisteredType arguments in comment blocks as these are usually created afterward initialize by the user (@oruebel, #231)
- Added support for attributes/datasets with fixed values, which are now created only inside the generated initialize method but no longer setable as a parameter (@oruebel, #231)
- Enhanced handling of finalization and columns for
DynamicTable(@oruebel, #209)- Updated NWBFile::createElectrodesTable to return the created ElectrodesTable and added a
finalizeTableparameter to make it configurable whether the table should be finalized. - Updated
DynamicTableandElectrodeTableto handle finalization and columns more robustly to make sure that repeated calls to finalize do not corrupt the data.- NOTE: The meaning of the
m_groupReferences,m_locationNames,m_groupNamesvariables has changed slightly in that they now only track new row values that have not been added via finalize.
- NOTE: The meaning of the
- Added
std::unique_ptr<IO::RecordingObjects> m_recordingColumnsandstd::shared_ptr<ElementIdentifiers> m_rowElementIdentifierstoDynamicTableto track the columns added for recording in the table directly.
- Updated NWBFile::createElectrodesTable to return the created ElectrodesTable and added a
- Renamed
RecordingContainerstoRecordingObjectsand updated it to support tracking of allRegisteredTypeobjects for recording (@oruebel, #209)- Added
RecordingObjects.clear,RecordingObjects.size, andRecordingObjects.getRecordingIndexmethods - Updated
RecordingObjects.addRecordingObjectto prevent adding of duplicate objects - Added RecordingObjects.getRecordingIndex function to find the index to allow search for a recording object
- Moved RecordingObjects from the AQNWB::NWBnamespace to the ANWB::IO namespace
- Moved NWB I/O utility functions (e.g.,
writeTimeSeriesData) fromRecordingObjectsto their ownsrc/io/nwbio_utils.hppheader - Added RecordingObjects::
getRecordingObject(const std::string& path)to simplify lookup of objects based on path - Added RecordingObjects::toString method for convenient printing
- Added
- Updated
initializefunctions of allRegisteredTypeclasses to return aStatus#209) - Changed the value of
Status::SUCCESSto 1 instead of 0 #209) - Added
Types.SizeTypeNotSetandUtils.isValidIndexto centralize definition and checking for invalid indices #209)
Fixed
0.1.0
This release of AqNWB provides the initial C++ interface for reading and writing Neurodata Without Borders (NWB) files
Added
- Initial implementation of NWB file creation and management with HDF5 backend
- Introduced Device, ElectrodeGroup, and DynamicTable classes for HDMF/NWB data types
- RecordingContainers for managing TimeSeries objects
- NWB data types for ecephys acquisition: ElectrodesTable, ElectricalSeries, and TimeSeries (@stephprince, #161)
- NWB data type for annotation: AnnotationSeries (@stephprince, #141)
- NWB data type for spike detection: SpikeEventSeries (@stephprince, #92)
- BaseRecordingData management system for data acquisition (@oruebel, #190)
- SWMR (Single Writer Multiple Readers) mode for concurrent file access (@stephprince, #45)
- Namespace registry for extension management (@oruebel, #181)
- Support for reading arbitrary RegisteredTypes, reference attributes and links (@oruebel, #143, #158)
- Multi-dimensional data blocks with std::variant support (@oruebel, #177)
- HDF5 filters and compression for array datasets (@oruebel, #163, #165)
- Schema generation script from NWB specifications (@oruebel, #199)
- Demo applications and extension implementation examples (@oruebel, #171, #183)
- NWB file validation using nwbinspector (@stephprince, #122)
- Cross-platform CI/CD with GitHub Actions (Linux, macOS, Windows) (@stephprince, #99)
- Code coverage reporting with codecov (@stephprince, #120, #135)
- Doxygen documentation with GitHub Pages deployment (@oruebel, #74)
Changed
- Refactored BaseRecordingData object management for acquisition (@oruebel, #190)
- Updated ElectrodesTable type definitions (@oruebel, #214)
- Restructured documentation with separate user and developer sections (@oruebel, #159)
Fixed
- ElectrodesTable reading for NWB <=2.8 compatibility (@oruebel, #216)
- ElectricalSeries electrode dataset write functionality (@stephprince, #156)
- Channel conversion axis attribute for ElectricalSeries (@oruebel, #109)
- Memory management with smart pointers (@stephprince, #42)
- Build warnings with Doxygen 1.14 (@oruebel, #202)