Skip to content

Releases: NeurodataWithoutBorders/aqnwb

0.3.0

Choose a tag to compare

@oruebel oruebel released this 23 Feb 19:26
373271f

Added

  • Added cppcheck static analysis integration (@copilot, @oruebel #270):
    • Added .github/workflows/cppcheck.yml CI workflow that runs cppcheck on src/ and tests/, converts results to SARIF using airtower-luna/convert-to-sarif, and uploads them to the GitHub Security tab via github/codeql-action/upload-sarif
    • Added cmake/cppcheck.cmake standalone script and cmake/cppcheck-targets.cmake for running cppcheck locally via cmake --build --preset=dev --target=cppcheck
    • Updated developer documentation in docs/pages/devdocs/testing.dox and docs/pages/devdocs/install.dox with cppcheck usage instructions
  • Added getDataType(), getChunking(), and toLinkArrayDataSetConfig() functions to ReadDataWrapper (@copilot, @oruebel #266)
  • Added support for creating soft-links to existing datasets to avoid data duplication (@copilot, @oruebel #257)
    • Added BaseArrayDataSetConfig abstract base class for polymorphic dataset configuration
    • Added LinkArrayDataSetConfig class for creating HDF5 soft-links to existing datasets
    • Updated ArrayDataSetConfig to inherit from BaseArrayDataSetConfig
    • Updated all NWB type initialize() methods to accept BaseArrayDataSetConfig (TimeSeries, ElectricalSeries, SpikeEventSeries, AnnotationSeries, Data, NWBData, VectorData)
    • Added user docs page on using links and processing modules docs/pages/userdocs/links.dox
    • Added BaseIO::getStorageObjectDataType and BaseIO::getStorageObjectChunking and corresponding HDF5IO implementations
    • Updated BaseIO::createArrayDataSet to raise std::runtime_error on 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 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.hpp to 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::mdspan if C++23 is used (@oruebel, #250)
  • Added ProcessingModule class in src/nwb/base/ to support creation of processed data groups in the /processing/ hierarchy of NWB files (@oruebel, #255)
  • Added .github/copilot-instructions.md with comprehensive onboarding documentation for GitHub Copilot coding agents (@copilot, @oruebel, #256)
  • Added docs/pages/devdocs/github_release_workflow.dox with instructions for how to make a release (@oruebel, #279)

Changed

  • Replaced explicit std::vector<SizeType> usages with the SizeArray type alias throughout the codebase for consistency (@copilot, @oruebel #262)
  • Standardized naming of initialize() parameters generated by schematype_to_aqnwb utility (@copilot, @oruebel #261):
  • Removed Boost as a dependency (@chittti, #250 )
  • Updated DataBlock::as_multi_array() to return ConstMultiArrayView instead of boost::const_multi_array_ref to remove the need Boost and for C++17/20 compatibility (@chittti, #250)
  • Updated the docs and examples to discuss the optional use of std::mdspan if 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::createAttribute to 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 cppcheck static analysis warnings (@copilot, @oruebel #274, #278; @oruebel #280):
    • Correctness: Fixed BaseIO::stopRecording to return the computed composite status instead of hardcoded Status::Success; initialized SpikeEventSeries::m_eventsRecorded to 0 in-class; removed dead chunk/DSetCreatPropList code from HDF5RecordingData constructor; updated ~HDF5IO() to avoid calling the virtual close() from the destructor; added override to virtual destructors
    • Performance: Changed const std::string / const std::vector pass-by-value parameters and return types to const & across Channel, AnnotationSeries, ElectrodesTable, NWBFile, nwbio_utils.hpp, BaseIO, ReadIO, RegisteredType and test utilities
    • API hygiene: Added explicit to single-arg constructors on HDF5IO, HDF5RecordingData, ElectrodesTable, and NWBFile; added override to HDF5RecordingData::writeDataBlock overloads; marked BaseIO::getFullTypeName const; made ReadDataWrapper::getStorageObjectType static; aligned constructor parameter names in HDF5IO, HDF5ArrayDataSetConfig, and DynamicTable::addReferenceColumn; declared const std::tm* pointers in Utils.hpp; removed unused variables in tests
    • STL modernization: Replaced raw loops with std::any_of, std::accumulate, std::transform, and std::find_if in BaseIO.cpp, HDF5IO.cpp, RecordingObjects.cpp, and ReadIO.hpp
    • cppcheck suppressions: Added --suppress=duplInheritedMember and --suppress=normalCheckLevelMaxBranches globally to cmake/cppcheck.cmake and .github/workflows/cppcheck.yml; added inline cppcheck-suppress comments for intentional test patterns (duplicateExpression, knownConditionTrueFalse, useStlAlgorithm, variableScope)
  • Restricted code coverage report to src/ folder only (@copilot, @oruebel #262):
    • Updated cmake/coverage.cmake to use a two-step lcov approach: capture all coverage into coverage_raw.info, then use lcov --extract to filter to src/* only, producing the final coverage.info
    • Added .codecov.yml to instruct the Codecov server to ignore tests/**, preventing Codecov-action from including test files it discovers via independent gcov scanning of the build directory
  • Removed redundant resources/utils/requirements.txt and update CI accordingly. Dependencies are now defined in resources/utils/pyproject.toml (@copilot, @oruebel #260)
  • Added explicit permissions blocks to all GitHub Actions workflow files to restrict GITHUB_TOKEN to least-privilege scopes (@copilot, @oruebel #269)

0.2.0

Choose a tag to compare

@stephprince stephprince released this 22 Dec 21:33
e49fe8c

Added

  • Python Utility enhancements:
    • Added aqnwb-utils as a command-line utility to provide a common interface for aqnwb command line tools, e.g., schematype_to_aqnwb.py and generate_spec_files.py. (@oruebel, #227)
    • Added inline script metadata (PEP 723) to Python utilities to enable direct execution with uv run without installation (@oruebel, #229)
    • Added pyproject.toml for modern Python packaging support (@oruebel, #229)
  • Added RegisteredType::DEFINE_UNNAMED_REGISTERED_FIELD to simplify creation of read/write methods for RegisteredTypes that do not have a set name in the schema (@oruebel, #231)
  • Added new NWBData, NWBDataInterface, and NWBContainer data types and updated existing classes to match inheritance with NWB schema (@oruebel, #232)
  • Automated tracking and harmonized memory management of RegisteredType objects (@oruebel, #209)
    • Added BaseIO.m_recording_objects to track all RegisteredType objects used for recording
    • Modified RegisteredType to automatically register with RecordingObjects instance of the IO
    • Updated RegisteredType to use std::weak_ptr to the IO to avoid circular referencing
    • Made the constructor of RegisteredType and all its subclasses protected to prevent direct stack or raw pointer creation. RegisteredType objects must now always be created via the RegisteredType.create factory, ensuring that all objects are being created as std::smart_ptr and registered with the m_recording_objects RecordingContainers object of the I/O object
    • Updated RegisteredType to inherit from public std::enable_shared_from_this<RegisteredType>
    • Updated the REGISTER_SUBCLASS macro to add a create factory method for all classes
  • Harmonized finalization and clean-up of RegisteredType objects (@oruebel, #209)
    • Added RegisteredType.finalize to finalize all neurodata_type classes
    • Added RecordingObjects.finalize and RecordingObjects.clearRecordingDataCache to finalize and clean up all objects in a single call
    • Updated BaseIO.stopRecording to call m_recording_objects.finalize() and m_recording_objects.clearRecordingDataCache()

Changed

  • Updated documentation to refer to the new aqnwb-utils command-line utility (@oruebel, #227)
  • Updated Python utilities to use uv instead of pip for dependency management and updated docs and github workflows to use uv (@oruebel, #227
  • Enhanced the schematype_to_aqnwb utility 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_aqnwb utility 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_parameters to compile parameter details in one place and split the render_initialize_method into two functions. (@oruebel, #230)
    • Enhanced the new get_initialize_method_parameters method and rendering functions to correctly track the full path of objects (@oruebel, #230)
    • Added support for rendering DEFINE_REFERENCED_REGISTERED_FIELD macros 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_parameters to 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_FIELD macros 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 finalizeTable parameter to make it configurable whether the table should be finalized.
    • Updated DynamicTable and ElectrodeTable to 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_groupNames variables has changed slightly in that they now only track new row values that have not been added via finalize.
    • Added std::unique_ptr<IO::RecordingObjects> m_recordingColumns and std::shared_ptr<ElementIdentifiers> m_rowElementIdentifiers to DynamicTable to track the columns added for recording in the table directly.
  • Renamed RecordingContainers to RecordingObjects and updated it to support tracking of all RegisteredType objects for recording (@oruebel, #209)
    • Added RecordingObjects.clear, RecordingObjects.size, and RecordingObjects.getRecordingIndex methods
    • Updated RecordingObjects.addRecordingObject to 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) from RecordingObjects to their own src/io/nwbio_utils.hpp header
    • Added RecordingObjects::getRecordingObject(const std::string& path) to simplify lookup of objects based on path
    • Added RecordingObjects::toString method for convenient printing
  • Updated initialize functions of all RegisteredType classes to return a Status #209)
  • Changed the value of Status::SUCCESS to 1 instead of 0 #209)
  • Added Types.SizeTypeNotSet and Utils.isValidIndex to centralize definition and checking for invalid indices #209)

Fixed

  • Resolved various compiler warnings on Windows (-Wmaybe-uninitialized, -Wsign-conversion, -Wconversion, -Wshadow, -Wdeprecated-copy, -Wcatch-value) and fixed cross-platform build issues related to std::filesystem linkage. (@oruebel, #233)

0.1.0

Choose a tag to compare

@stephprince stephprince released this 04 Sep 16:51
c20786e

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