mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-14 16:27:14 +02:00
use clang-tidy (#59)
* use clang-tidy for Frame.cpp * fixes for defs.cpp * clang-tidy 6/45 * clang-tidy for core * clang-tidy fixes: for hpp File,FileInterface,SubFile.cpp * ci fixes * fix build errors * fix clang-tidy command ci * fix clang-tidy ci * clang-tidy for rawfile.cpp * clang-tidy numpy helpers * fix ci * clang-tidy file_io * clang-tidy file_io and core working * zmqheader * clagn-tidy: network_io,file_io,core * clang-tidy working * format --------- Co-authored-by: Bechir <bechir.brahem420@gmail.com>
This commit is contained in:
493
.clang-tidy
Normal file
493
.clang-tidy
Normal file
@ -0,0 +1,493 @@
|
||||
---
|
||||
Checks: '
|
||||
|
||||
|
||||
|
||||
# DISABLE CHECKS:
|
||||
# readability-magic-numbers
|
||||
# - misc-include-cleaner (issues with includes from associated header files)
|
||||
# (should fixed in 18.1.0 release)
|
||||
# - cppcoreguidelines-avoid-magic-numbers
|
||||
# - cppcoreguidelines-owning-memory
|
||||
# - bugprone-easily-swappable-parameters
|
||||
# - cppcoreguidelines-non-private-member-variables-in-classes
|
||||
# abseil-cleanup-ctad
|
||||
# abseil-duration-addition
|
||||
# abseil-duration-comparison
|
||||
# abseil-duration-conversion-cast
|
||||
# abseil-duration-division
|
||||
# abseil-duration-factory-float
|
||||
# abseil-duration-factory-scale
|
||||
# abseil-duration-subtraction
|
||||
# abseil-duration-unnecessary-conversion
|
||||
# abseil-faster-strsplit-delimiter
|
||||
# abseil-no-internal-dependencies
|
||||
# abseil-no-namespace
|
||||
# abseil-redundant-strcat-calls
|
||||
# abseil-str-cat-append
|
||||
# abseil-string-find-startswith
|
||||
# abseil-string-find-str-contains
|
||||
# abseil-time-comparison
|
||||
# abseil-time-subtraction
|
||||
# abseil-upgrade-duration-conversions
|
||||
android-cloexec-accept
|
||||
cppcoreguidelines-special-member-functions
|
||||
hicpp-special-member-functions
|
||||
android-cloexec-accept4
|
||||
android-cloexec-creat
|
||||
android-cloexec-dup
|
||||
android-cloexec-epoll-create
|
||||
android-cloexec-epoll-create1
|
||||
android-cloexec-inotify-init
|
||||
android-cloexec-inotify-init1
|
||||
android-cloexec-memfd-create
|
||||
android-cloexec-open
|
||||
android-cloexec-pipe
|
||||
android-cloexec-pipe2
|
||||
android-cloexec-socket
|
||||
android-comparison-in-temp-failure-retry
|
||||
boost-use-to-string
|
||||
bugprone-argument-comment
|
||||
bugprone-assert-side-effect
|
||||
bugprone-assignment-in-if-condition
|
||||
bugprone-bad-signal-to-kill-thread
|
||||
bugprone-bool-pointer-implicit-conversion
|
||||
bugprone-branch-clone
|
||||
bugprone-copy-constructor-init
|
||||
bugprone-dangling-handle
|
||||
bugprone-dynamic-static-initializers
|
||||
bugprone-empty-catch
|
||||
bugprone-exception-escape
|
||||
bugprone-fold-init-type
|
||||
bugprone-forward-declaration-namespace
|
||||
bugprone-forwarding-reference-overload
|
||||
bugprone-implicit-widening-of-multiplication-result
|
||||
bugprone-inaccurate-erase
|
||||
bugprone-incorrect-roundings
|
||||
bugprone-infinite-loop
|
||||
bugprone-integer-division
|
||||
bugprone-lambda-function-name
|
||||
bugprone-macro-parentheses
|
||||
bugprone-macro-repeated-side-effects
|
||||
bugprone-misplaced-operator-in-strlen-in-alloc
|
||||
bugprone-misplaced-pointer-arithmetic-in-alloc
|
||||
bugprone-misplaced-widening-cast
|
||||
bugprone-move-forwarding-reference
|
||||
bugprone-multiple-new-in-one-expression
|
||||
bugprone-multiple-statement-macro
|
||||
bugprone-narrowing-conversions
|
||||
bugprone-no-escape
|
||||
bugprone-non-zero-enum-to-bool-conversion
|
||||
bugprone-not-null-terminated-result
|
||||
bugprone-parent-virtual-call
|
||||
bugprone-posix-return
|
||||
bugprone-redundant-branch-condition
|
||||
bugprone-reserved-identifier
|
||||
bugprone-shared-ptr-array-mismatch
|
||||
bugprone-signal-handler
|
||||
bugprone-signed-char-misuse
|
||||
bugprone-sizeof-container
|
||||
bugprone-sizeof-expression
|
||||
bugprone-spuriously-wake-up-functions
|
||||
bugprone-standalone-empty
|
||||
bugprone-string-constructor
|
||||
bugprone-string-integer-assignment
|
||||
bugprone-string-literal-with-embedded-nul
|
||||
bugprone-stringview-nullptr
|
||||
bugprone-suspicious-enum-usage
|
||||
bugprone-suspicious-include
|
||||
bugprone-suspicious-memory-comparison
|
||||
bugprone-suspicious-memset-usage
|
||||
bugprone-suspicious-missing-comma
|
||||
bugprone-suspicious-realloc-usage
|
||||
bugprone-suspicious-semicolon
|
||||
bugprone-suspicious-string-compare
|
||||
bugprone-swapped-arguments
|
||||
bugprone-switch-missing-default-case
|
||||
bugprone-terminating-continue
|
||||
bugprone-throw-keyword-missing
|
||||
bugprone-too-small-loop-variable
|
||||
bugprone-unchecked-optional-access
|
||||
bugprone-undefined-memory-manipulation
|
||||
bugprone-undelegated-constructor
|
||||
bugprone-unhandled-exception-at-new
|
||||
bugprone-unhandled-self-assignment
|
||||
bugprone-unique-ptr-array-mismatch
|
||||
bugprone-unsafe-functions
|
||||
bugprone-unused-raii
|
||||
bugprone-unused-return-value
|
||||
bugprone-use-after-move
|
||||
bugprone-virtual-near-miss
|
||||
cert-con36-c
|
||||
cert-con54-cpp
|
||||
cert-dcl03-c
|
||||
cert-dcl16-c
|
||||
cert-dcl21-cpp
|
||||
cert-dcl37-c
|
||||
cert-dcl50-cpp
|
||||
cert-dcl51-cpp
|
||||
cert-dcl54-cpp
|
||||
cert-dcl58-cpp
|
||||
cert-dcl59-cpp
|
||||
cert-env33-c
|
||||
cert-err09-cpp
|
||||
cert-err33-c
|
||||
cert-err34-c
|
||||
cert-err52-cpp
|
||||
cert-err58-cpp
|
||||
cert-err60-cpp
|
||||
cert-err61-cpp
|
||||
cert-exp42-c
|
||||
cert-fio38-c
|
||||
cert-flp30-c
|
||||
cert-flp37-c
|
||||
cert-mem57-cpp
|
||||
cert-msc24-c
|
||||
cert-msc30-c
|
||||
cert-msc32-c
|
||||
cert-msc33-c
|
||||
cert-msc50-cpp
|
||||
cert-msc51-cpp
|
||||
cert-msc54-cpp
|
||||
cert-oop11-cpp
|
||||
cert-oop54-cpp
|
||||
cert-oop57-cpp
|
||||
cert-oop58-cpp
|
||||
cert-pos44-c
|
||||
cert-pos47-c
|
||||
cert-sig30-c
|
||||
cert-str34-c
|
||||
clang-analyzer-apiModeling.Errno
|
||||
clang-analyzer-apiModeling.TrustNonnull
|
||||
clang-analyzer-apiModeling.TrustReturnsNonnull
|
||||
clang-analyzer-apiModeling.google.GTest
|
||||
clang-analyzer-apiModeling.llvm.CastValue
|
||||
clang-analyzer-apiModeling.llvm.ReturnValue
|
||||
clang-analyzer-core.CallAndMessage
|
||||
clang-analyzer-core.CallAndMessageModeling
|
||||
clang-analyzer-core.DivideZero
|
||||
clang-analyzer-core.DynamicTypePropagation
|
||||
clang-analyzer-core.NonNullParamChecker
|
||||
clang-analyzer-core.NonnilStringConstants
|
||||
clang-analyzer-core.NullDereference
|
||||
clang-analyzer-core.StackAddrEscapeBase
|
||||
clang-analyzer-core.StackAddressEscape
|
||||
clang-analyzer-core.UndefinedBinaryOperatorResult
|
||||
clang-analyzer-core.VLASize
|
||||
clang-analyzer-core.builtin.BuiltinFunctions
|
||||
clang-analyzer-core.builtin.NoReturnFunctions
|
||||
clang-analyzer-core.uninitialized.ArraySubscript
|
||||
clang-analyzer-core.uninitialized.Assign
|
||||
clang-analyzer-core.uninitialized.Branch
|
||||
clang-analyzer-core.uninitialized.CapturedBlockVariable
|
||||
clang-analyzer-core.uninitialized.NewArraySize
|
||||
clang-analyzer-core.uninitialized.UndefReturn
|
||||
clang-analyzer-cplusplus.InnerPointer
|
||||
clang-analyzer-cplusplus.Move
|
||||
clang-analyzer-cplusplus.NewDelete
|
||||
clang-analyzer-cplusplus.NewDeleteLeaks
|
||||
clang-analyzer-cplusplus.PlacementNew
|
||||
clang-analyzer-cplusplus.PureVirtualCall
|
||||
clang-analyzer-cplusplus.SelfAssignment
|
||||
clang-analyzer-cplusplus.SmartPtrModeling
|
||||
clang-analyzer-cplusplus.StringChecker
|
||||
clang-analyzer-cplusplus.VirtualCallModeling
|
||||
clang-analyzer-deadcode.DeadStores
|
||||
clang-analyzer-fuchsia.HandleChecker
|
||||
clang-analyzer-nullability.NullPassedToNonnull
|
||||
clang-analyzer-nullability.NullReturnedFromNonnull
|
||||
clang-analyzer-nullability.NullabilityBase
|
||||
clang-analyzer-nullability.NullableDereferenced
|
||||
clang-analyzer-nullability.NullablePassedToNonnull
|
||||
clang-analyzer-nullability.NullableReturnedFromNonnull
|
||||
clang-analyzer-optin.cplusplus.UninitializedObject
|
||||
clang-analyzer-optin.cplusplus.VirtualCall
|
||||
clang-analyzer-optin.mpi.MPI-Checker
|
||||
clang-analyzer-optin.osx.OSObjectCStyleCast
|
||||
clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker
|
||||
clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker
|
||||
clang-analyzer-optin.performance.GCDAntipattern
|
||||
clang-analyzer-optin.performance.Padding
|
||||
clang-analyzer-optin.portability.UnixAPI
|
||||
clang-analyzer-osx.API
|
||||
clang-analyzer-osx.MIG
|
||||
clang-analyzer-osx.NSOrCFErrorDerefChecker
|
||||
clang-analyzer-osx.NumberObjectConversion
|
||||
clang-analyzer-osx.OSObjectRetainCount
|
||||
clang-analyzer-osx.ObjCProperty
|
||||
clang-analyzer-osx.SecKeychainAPI
|
||||
clang-analyzer-osx.cocoa.AtSync
|
||||
clang-analyzer-osx.cocoa.AutoreleaseWrite
|
||||
clang-analyzer-osx.cocoa.ClassRelease
|
||||
clang-analyzer-osx.cocoa.Dealloc
|
||||
clang-analyzer-osx.cocoa.IncompatibleMethodTypes
|
||||
clang-analyzer-osx.cocoa.Loops
|
||||
clang-analyzer-osx.cocoa.MissingSuperCall
|
||||
clang-analyzer-osx.cocoa.NSAutoreleasePool
|
||||
clang-analyzer-osx.cocoa.NSError
|
||||
clang-analyzer-osx.cocoa.NilArg
|
||||
clang-analyzer-osx.cocoa.NonNilReturnValue
|
||||
clang-analyzer-osx.cocoa.ObjCGenerics
|
||||
clang-analyzer-osx.cocoa.RetainCount
|
||||
clang-analyzer-osx.cocoa.RetainCountBase
|
||||
clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak
|
||||
clang-analyzer-osx.cocoa.SelfInit
|
||||
clang-analyzer-osx.cocoa.SuperDealloc
|
||||
clang-analyzer-osx.cocoa.UnusedIvars
|
||||
clang-analyzer-osx.cocoa.VariadicMethodTypes
|
||||
clang-analyzer-osx.coreFoundation.CFError
|
||||
clang-analyzer-osx.coreFoundation.CFNumber
|
||||
clang-analyzer-osx.coreFoundation.CFRetainRelease
|
||||
clang-analyzer-osx.coreFoundation.containers.OutOfBounds
|
||||
clang-analyzer-osx.coreFoundation.containers.PointerSizedValues
|
||||
clang-analyzer-security.FloatLoopCounter
|
||||
clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
|
||||
clang-analyzer-security.insecureAPI.SecuritySyntaxChecker
|
||||
clang-analyzer-security.insecureAPI.UncheckedReturn
|
||||
clang-analyzer-security.insecureAPI.bcmp
|
||||
clang-analyzer-security.insecureAPI.bcopy
|
||||
clang-analyzer-security.insecureAPI.bzero
|
||||
clang-analyzer-security.insecureAPI.decodeValueOfObjCType
|
||||
clang-analyzer-security.insecureAPI.getpw
|
||||
clang-analyzer-security.insecureAPI.gets
|
||||
clang-analyzer-security.insecureAPI.mkstemp
|
||||
clang-analyzer-security.insecureAPI.mktemp
|
||||
clang-analyzer-security.insecureAPI.rand
|
||||
clang-analyzer-security.insecureAPI.strcpy
|
||||
clang-analyzer-security.insecureAPI.vfork
|
||||
clang-analyzer-unix.API
|
||||
clang-analyzer-unix.DynamicMemoryModeling
|
||||
clang-analyzer-unix.Malloc
|
||||
clang-analyzer-unix.MallocSizeof
|
||||
clang-analyzer-unix.MismatchedDeallocator
|
||||
clang-analyzer-unix.Vfork
|
||||
clang-analyzer-unix.cstring.BadSizeArg
|
||||
clang-analyzer-unix.cstring.CStringModeling
|
||||
clang-analyzer-unix.cstring.NullArg
|
||||
clang-analyzer-valist.CopyToSelf
|
||||
clang-analyzer-valist.Uninitialized
|
||||
clang-analyzer-valist.Unterminated
|
||||
clang-analyzer-valist.ValistBase
|
||||
clang-analyzer-webkit.NoUncountedMemberChecker
|
||||
clang-analyzer-webkit.RefCntblBaseVirtualDtor
|
||||
clang-analyzer-webkit.UncountedLambdaCapturesChecker
|
||||
concurrency-mt-unsafe
|
||||
concurrency-thread-canceltype-asynchronous
|
||||
cppcoreguidelines-avoid-c-arrays
|
||||
cppcoreguidelines-avoid-capturing-lambda-coroutines
|
||||
cppcoreguidelines-avoid-const-or-ref-data-members
|
||||
cppcoreguidelines-avoid-do-while
|
||||
cppcoreguidelines-avoid-goto
|
||||
cppcoreguidelines-avoid-non-const-global-variables
|
||||
cppcoreguidelines-avoid-reference-coroutine-parameters
|
||||
cppcoreguidelines-c-copy-assignment-signature
|
||||
cppcoreguidelines-explicit-virtual-functions
|
||||
cppcoreguidelines-init-variables
|
||||
cppcoreguidelines-interfaces-global-init
|
||||
cppcoreguidelines-macro-usage
|
||||
cppcoreguidelines-misleading-capture-default-by-value
|
||||
cppcoreguidelines-missing-std-forward
|
||||
cppcoreguidelines-narrowing-conversions
|
||||
cppcoreguidelines-no-malloc
|
||||
cppcoreguidelines-noexcept-destructor
|
||||
cppcoreguidelines-noexcept-move-operations
|
||||
cppcoreguidelines-noexcept-swap
|
||||
cppcoreguidelines-prefer-member-initializer
|
||||
cppcoreguidelines-pro-type-const-cast
|
||||
cppcoreguidelines-pro-type-cstyle-cast
|
||||
cppcoreguidelines-pro-type-member-init
|
||||
cppcoreguidelines-pro-type-static-cast-downcast
|
||||
cppcoreguidelines-pro-type-union-access
|
||||
cppcoreguidelines-pro-type-vararg
|
||||
cppcoreguidelines-rvalue-reference-param-not-moved
|
||||
cppcoreguidelines-slicing
|
||||
cppcoreguidelines-use-default-member-init
|
||||
cppcoreguidelines-virtual-class-destructor
|
||||
darwin-avoid-spinlock
|
||||
darwin-dispatch-once-nonstatic
|
||||
google-build-explicit-make-pair
|
||||
google-build-namespaces
|
||||
google-build-using-namespace
|
||||
google-default-arguments
|
||||
google-explicit-constructor
|
||||
google-global-names-in-headers
|
||||
google-objc-avoid-nsobject-new
|
||||
google-objc-avoid-throwing-exception
|
||||
google-objc-function-naming
|
||||
google-objc-global-variable-declaration
|
||||
google-readability-avoid-underscore-in-googletest-name
|
||||
google-readability-casting
|
||||
google-readability-function-size
|
||||
google-readability-namespace-comments
|
||||
google-runtime-int
|
||||
google-runtime-operator
|
||||
google-upgrade-googletest-case
|
||||
hicpp-avoid-c-arrays
|
||||
hicpp-avoid-goto
|
||||
hicpp-deprecated-headers
|
||||
hicpp-exception-baseclass
|
||||
hicpp-explicit-conversions
|
||||
hicpp-function-size
|
||||
hicpp-invalid-access-moved
|
||||
hicpp-member-init
|
||||
hicpp-move-const-arg
|
||||
hicpp-multiway-paths-covered
|
||||
hicpp-named-parameter
|
||||
hicpp-new-delete-operators
|
||||
hicpp-no-assembler
|
||||
hicpp-no-malloc
|
||||
hicpp-noexcept-move
|
||||
hicpp-static-assert
|
||||
hicpp-undelegated-constructor
|
||||
hicpp-uppercase-literal-suffix
|
||||
hicpp-use-auto
|
||||
hicpp-use-emplace
|
||||
hicpp-use-equals-default
|
||||
hicpp-use-equals-delete
|
||||
hicpp-use-noexcept
|
||||
hicpp-use-nullptr
|
||||
hicpp-use-override
|
||||
hicpp-vararg
|
||||
linuxkernel-must-check-errs
|
||||
llvm-else-after-return
|
||||
llvm-include-order
|
||||
llvm-namespace-comment
|
||||
llvm-prefer-isa-or-dyn-cast-in-conditionals
|
||||
llvm-prefer-register-over-unsigned
|
||||
llvm-qualified-auto
|
||||
llvm-twine-local
|
||||
misc-confusable-identifiers
|
||||
misc-const-correctness
|
||||
misc-definitions-in-headers
|
||||
misc-header-include-cycle
|
||||
misc-misleading-bidirectional
|
||||
misc-misleading-identifier
|
||||
misc-misplaced-const
|
||||
misc-new-delete-overloads
|
||||
misc-no-recursion
|
||||
misc-non-copyable-objects
|
||||
misc-redundant-expression
|
||||
misc-static-assert
|
||||
misc-throw-by-value-catch-by-reference
|
||||
misc-unconventional-assign-operator
|
||||
misc-uniqueptr-reset-release
|
||||
misc-unused-alias-decls
|
||||
misc-unused-parameters
|
||||
misc-unused-using-decls
|
||||
misc-use-anonymous-namespace
|
||||
modernize-avoid-bind
|
||||
modernize-avoid-c-arrays
|
||||
modernize-concat-nested-namespaces
|
||||
modernize-deprecated-headers
|
||||
modernize-deprecated-ios-base-aliases
|
||||
modernize-loop-convert
|
||||
modernize-macro-to-enum
|
||||
modernize-make-shared
|
||||
modernize-make-unique
|
||||
modernize-pass-by-value
|
||||
modernize-raw-string-literal
|
||||
modernize-redundant-void-arg
|
||||
modernize-replace-auto-ptr
|
||||
modernize-replace-disallow-copy-and-assign-macro
|
||||
modernize-replace-random-shuffle
|
||||
modernize-return-braced-init-list
|
||||
modernize-shrink-to-fit
|
||||
modernize-type-traits
|
||||
modernize-unary-static-assert
|
||||
modernize-use-auto
|
||||
modernize-use-bool-literals
|
||||
modernize-use-default-member-init
|
||||
modernize-use-emplace
|
||||
modernize-use-equals-default
|
||||
modernize-use-equals-delete
|
||||
modernize-use-noexcept
|
||||
modernize-use-nullptr
|
||||
modernize-use-override
|
||||
modernize-use-std-print
|
||||
modernize-use-transparent-functors
|
||||
modernize-use-uncaught-exceptions
|
||||
modernize-use-using
|
||||
mpi-buffer-deref
|
||||
mpi-type-mismatch
|
||||
objc-assert-equals
|
||||
objc-avoid-nserror-init
|
||||
objc-dealloc-in-category
|
||||
objc-forbidden-subclassing
|
||||
objc-missing-hash
|
||||
objc-nsdate-formatter
|
||||
objc-nsinvocation-argument-lifetime
|
||||
objc-property-declaration
|
||||
objc-super-self
|
||||
openmp-exception-escape
|
||||
openmp-use-default-none
|
||||
performance-avoid-endl
|
||||
performance-faster-string-find
|
||||
performance-for-range-copy
|
||||
performance-implicit-conversion-in-loop
|
||||
performance-inefficient-algorithm
|
||||
performance-inefficient-string-concatenation
|
||||
performance-inefficient-vector-operation
|
||||
performance-move-const-arg
|
||||
performance-move-constructor-init
|
||||
performance-no-automatic-move
|
||||
performance-no-int-to-ptr
|
||||
performance-noexcept-destructor
|
||||
performance-noexcept-move-constructor
|
||||
performance-noexcept-swap
|
||||
performance-trivially-destructible
|
||||
performance-type-promotion-in-math-fn
|
||||
performance-unnecessary-copy-initialization
|
||||
performance-unnecessary-value-param
|
||||
portability-restrict-system-includes
|
||||
portability-simd-intrinsics
|
||||
portability-std-allocator-const
|
||||
readability-avoid-unconditional-preprocessor-if
|
||||
readability-const-return-type
|
||||
readability-container-contains
|
||||
readability-container-data-pointer
|
||||
readability-container-size-empty
|
||||
readability-convert-member-functions-to-static
|
||||
readability-delete-null-pointer
|
||||
readability-duplicate-include
|
||||
readability-function-cognitive-complexity
|
||||
readability-function-size
|
||||
readability-inconsistent-declaration-parameter-name
|
||||
readability-make-member-function-const
|
||||
readability-misleading-indentation
|
||||
readability-misplaced-array-index
|
||||
readability-named-parameter
|
||||
readability-non-const-parameter
|
||||
readability-operators-representation
|
||||
readability-qualified-auto
|
||||
readability-redundant-access-specifiers
|
||||
readability-redundant-control-flow
|
||||
readability-redundant-declaration
|
||||
readability-redundant-function-ptr-dereference
|
||||
readability-redundant-member-init
|
||||
readability-redundant-preprocessor
|
||||
readability-redundant-smartptr-get
|
||||
readability-redundant-string-cstr
|
||||
readability-redundant-string-init
|
||||
readability-simplify-boolean-expr
|
||||
readability-simplify-subscript-expr
|
||||
readability-static-definition-in-anonymous-namespace
|
||||
readability-string-compare
|
||||
readability-suspicious-call-argument
|
||||
readability-uniqueptr-delete-release
|
||||
readability-uppercase-literal-suffix
|
||||
readability-use-anyofallof
|
||||
zircon-temporary-objects
|
||||
'
|
||||
|
||||
HeaderFilterRegex: \.h
|
||||
AnalyzeTemporaryDtors: false
|
||||
FormatStyle: none
|
||||
CheckOptions:
|
||||
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
|
||||
# - { key: readability-identifier-naming.FunctionCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
||||
# - { key: readability-identifier-naming.MethodCase, value: CamelCase }
|
||||
# - { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||
# - { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||
...
|
30
.github/workflows/clang-tidy.yml
vendored
Normal file
30
.github/workflows/clang-tidy.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
name: clang-tidy
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
clang-tidy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mamba-org/setup-micromamba@v1
|
||||
if: ${{ contains(inputs.use-system-libraries, 'ON')}}
|
||||
with:
|
||||
micromamba-version: '1.5.6-0' # any version from https://github.com/mamba-org/micromamba-releases
|
||||
environment-file: aare-environment.yml
|
||||
init-shell: bash
|
||||
cache-environment: true
|
||||
post-cleanup: 'all'
|
||||
- name: cmake
|
||||
shell: bash -el {0}
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_LIBRARIES=ON ..
|
||||
- name: linting checks
|
||||
shell: bash -el {0}
|
||||
run: |
|
||||
# find all examples in build/examples and run them
|
||||
cd build
|
||||
cmake --build . --target clang-tidy
|
||||
|
2
.github/workflows/common-workflow.yml
vendored
2
.github/workflows/common-workflow.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
build-and-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mamba-org/setup-micromamba@v1
|
||||
if: ${{ contains(inputs.use-system-libraries, 'ON')}}
|
||||
with:
|
||||
|
23
.github/workflows/format.yml
vendored
23
.github/workflows/format.yml
vendored
@ -6,14 +6,27 @@ jobs:
|
||||
test-formatting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: check if files are formatted
|
||||
# find all examples in build/examples and run them
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mamba-org/setup-micromamba@v1
|
||||
if: ${{ contains(inputs.use-system-libraries, 'ON')}}
|
||||
with:
|
||||
micromamba-version: '1.5.6-0' # any version from https://github.com/mamba-org/micromamba-releases
|
||||
environment-file: aare-environment.yml
|
||||
init-shell: bash
|
||||
cache-environment: true
|
||||
post-cleanup: 'all'
|
||||
- name: cmake
|
||||
shell: bash -el {0}
|
||||
run: |
|
||||
pwd
|
||||
mkdir build
|
||||
cd build
|
||||
find \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./build/*" | xargs -I {} -n 1 -P 10 bash -c "clang-format -i -style=\"file:.clang-format\" {}"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_LIBRARIES=ON ..
|
||||
- name: linting checks
|
||||
shell: bash -el {0}
|
||||
run: |
|
||||
# find all examples in build/examples and run them
|
||||
cd build
|
||||
cmake --build . --target=check-format
|
||||
|
||||
|
||||
|
||||
|
@ -206,3 +206,12 @@ add_custom_target(
|
||||
COMMENT "Formatting with clang-format"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
clang-tidy
|
||||
COMMAND find \( -path "./core/*" -o -path "./file_io/*" -path "./network_io/*" -path "./utils/*" \) \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./python/*" -not -name "*.test.cpp" -not -name "CircularFifo.hpp" -not -name "ProducerConsumerQueue.hpp" -not -name "VariableSizeClusterFinder.hpp" | xargs -I {} -n 1 -P 10 bash -c "clang-tidy --config-file=.clang-tidy -p build {}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "linting with clang-tidy"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
|
@ -26,7 +26,7 @@ enum class endian {
|
||||
*/
|
||||
class DType {
|
||||
// TODO! support for non native endianess?
|
||||
static_assert(sizeof(long) == sizeof(int64_t), "long should be 64bits");
|
||||
static_assert(sizeof(long) == sizeof(int64_t), "long should be 64bits"); // NOLINT
|
||||
|
||||
public:
|
||||
enum TypeIndex { INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT, DOUBLE, ERROR };
|
||||
@ -37,7 +37,7 @@ class DType {
|
||||
explicit DType(std::string_view sv);
|
||||
|
||||
// not explicit to allow conversions form enum to DType
|
||||
DType(DType::TypeIndex ti);
|
||||
DType(DType::TypeIndex ti); // NOLINT
|
||||
|
||||
bool operator==(const DType &other) const noexcept;
|
||||
bool operator!=(const DType &other) const noexcept;
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <sys/types.h>
|
||||
#include <vector>
|
||||
|
||||
namespace aare {
|
||||
@ -15,59 +14,73 @@ namespace aare {
|
||||
* should be able to work with streams coming from files or network
|
||||
*/
|
||||
class Frame {
|
||||
ssize_t m_rows;
|
||||
ssize_t m_cols;
|
||||
ssize_t m_bitdepth;
|
||||
size_t m_rows;
|
||||
size_t m_cols;
|
||||
size_t m_bitdepth;
|
||||
std::byte *m_data;
|
||||
|
||||
public:
|
||||
Frame(ssize_t rows, ssize_t cols, ssize_t m_bitdepth);
|
||||
Frame(std::byte *fp, ssize_t rows, ssize_t cols, ssize_t m_bitdepth);
|
||||
std::byte *get(int row, int col);
|
||||
Frame(size_t rows, size_t cols, size_t m_bitdepth);
|
||||
Frame(std::byte *bytes, size_t rows, size_t cols, size_t m_bitdepth);
|
||||
std::byte *get(size_t row, size_t col);
|
||||
|
||||
// TODO! can we, or even want to remove the template?
|
||||
template <typename T> void set(int row, int col, T data) {
|
||||
template <typename T> void set(size_t row, size_t col, T data) {
|
||||
assert(sizeof(T) == m_bitdepth / 8);
|
||||
if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) {
|
||||
if (row >= m_rows or col >= m_cols) {
|
||||
throw std::out_of_range("Invalid row or column index");
|
||||
}
|
||||
std::memcpy(m_data + (row * m_cols + col) * (m_bitdepth / 8), &data, m_bitdepth / 8);
|
||||
}
|
||||
|
||||
ssize_t rows() const { return m_rows; }
|
||||
ssize_t cols() const { return m_cols; }
|
||||
ssize_t bitdepth() const { return m_bitdepth; }
|
||||
ssize_t size() const { return m_rows * m_cols * m_bitdepth / 8; }
|
||||
size_t rows() const { return m_rows; }
|
||||
size_t cols() const { return m_cols; }
|
||||
size_t bitdepth() const { return m_bitdepth; }
|
||||
size_t size() const { return m_rows * m_cols * m_bitdepth / 8; }
|
||||
std::byte *data() const { return m_data; }
|
||||
|
||||
Frame &operator=(Frame &other) {
|
||||
Frame &operator=(const Frame &other) {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
m_rows = other.rows();
|
||||
m_cols = other.cols();
|
||||
m_bitdepth = other.bitdepth();
|
||||
m_data = new std::byte[m_rows * m_cols * m_bitdepth / 8];
|
||||
if (m_data == nullptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
std::memcpy(m_data, other.m_data, m_rows * m_cols * m_bitdepth / 8);
|
||||
return *this;
|
||||
}
|
||||
// add move constructor
|
||||
Frame(Frame &&other) {
|
||||
|
||||
Frame &operator=(Frame &&other) noexcept {
|
||||
m_rows = other.rows();
|
||||
m_cols = other.cols();
|
||||
m_bitdepth = other.bitdepth();
|
||||
m_data = other.m_data;
|
||||
other.m_data = nullptr;
|
||||
other.m_rows = other.m_cols = other.m_bitdepth = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// add move constructor
|
||||
Frame(Frame &&other) noexcept
|
||||
: m_rows(other.rows()), m_cols(other.cols()), m_bitdepth(other.bitdepth()), m_data(other.m_data) {
|
||||
|
||||
other.m_data = nullptr;
|
||||
other.m_rows = other.m_cols = other.m_bitdepth = 0;
|
||||
}
|
||||
// copy constructor
|
||||
Frame(const Frame &other) {
|
||||
m_rows = other.rows();
|
||||
m_cols = other.cols();
|
||||
m_bitdepth = other.bitdepth();
|
||||
m_data = new std::byte[m_rows * m_cols * m_bitdepth / 8];
|
||||
Frame(const Frame &other)
|
||||
: m_rows(other.rows()), m_cols(other.cols()), m_bitdepth(other.bitdepth()),
|
||||
m_data(new std::byte[m_rows * m_cols * m_bitdepth / 8]) {
|
||||
|
||||
std::memcpy(m_data, other.m_data, m_rows * m_cols * m_bitdepth / 8);
|
||||
}
|
||||
|
||||
template <typename T> NDView<T> view() {
|
||||
std::vector<ssize_t> shape = {m_rows, m_cols};
|
||||
std::vector<ssize_t> shape = {static_cast<ssize_t>(m_rows), static_cast<ssize_t>(m_cols)};
|
||||
T *data = reinterpret_cast<T *>(m_data);
|
||||
return NDView<T>(data, shape);
|
||||
}
|
||||
|
@ -22,25 +22,25 @@ namespace aare {
|
||||
|
||||
template <typename T, ssize_t Ndim = 2> class NDArray {
|
||||
public:
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), size_(0), data_(nullptr){};
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr){};
|
||||
|
||||
explicit NDArray(std::array<ssize_t, Ndim> shape)
|
||||
: shape_(shape), strides_(c_strides<Ndim>(shape_)),
|
||||
size_(std::accumulate(shape_.begin(), shape_.end(), 1, std::multiplies<ssize_t>())), data_(new T[size_]){};
|
||||
size_(std::accumulate(shape_.begin(), shape_.end(), 1, std::multiplies<>())), data_(new T[size_]){};
|
||||
|
||||
NDArray(std::array<ssize_t, Ndim> shape, T value) : NDArray(shape) { this->operator=(value); }
|
||||
|
||||
/* When constructing from a NDView we need to copy the data since
|
||||
NDArray expect to own its data, and span is just a view*/
|
||||
NDArray(NDView<T, Ndim> span) : NDArray(span.shape()) {
|
||||
explicit NDArray(NDView<T, Ndim> span) : NDArray(span.shape()) {
|
||||
std::copy(span.begin(), span.end(), begin());
|
||||
// fmt::print("NDArray(NDView<T, Ndim> span)\n");
|
||||
}
|
||||
|
||||
// Move constructor
|
||||
NDArray(NDArray &&other)
|
||||
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(nullptr) {
|
||||
data_ = other.data_;
|
||||
NDArray(NDArray &&other) noexcept
|
||||
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(other.data_) {
|
||||
|
||||
other.reset();
|
||||
// fmt::print("NDArray(NDArray &&other)\n");
|
||||
}
|
||||
@ -59,7 +59,7 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
|
||||
|
||||
using value_type = T;
|
||||
|
||||
NDArray &operator=(NDArray &&other); // Move assign
|
||||
NDArray &operator=(NDArray &&other) noexcept; // Move assign
|
||||
NDArray &operator=(const NDArray &other); // Copy assign
|
||||
|
||||
NDArray operator+(const NDArray &other);
|
||||
@ -77,9 +77,8 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
|
||||
data_[i] /= other(i);
|
||||
}
|
||||
return *this;
|
||||
} else {
|
||||
throw(std::runtime_error("Shape of NDArray must match"));
|
||||
}
|
||||
throw(std::runtime_error("Shape of NDArray must match"));
|
||||
}
|
||||
|
||||
NDArray<bool, Ndim> operator>(const NDArray &other);
|
||||
@ -87,17 +86,17 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
|
||||
bool operator==(const NDArray &other) const;
|
||||
bool operator!=(const NDArray &other) const;
|
||||
|
||||
NDArray &operator=(const T &);
|
||||
NDArray &operator+=(const T &);
|
||||
NDArray operator+(const T &);
|
||||
NDArray &operator-=(const T &);
|
||||
NDArray operator-(const T &);
|
||||
NDArray &operator*=(const T &);
|
||||
NDArray operator*(const T &);
|
||||
NDArray &operator/=(const T &);
|
||||
NDArray operator/(const T &);
|
||||
NDArray &operator=(const T & /*value*/);
|
||||
NDArray &operator+=(const T & /*value*/);
|
||||
NDArray operator+(const T & /*value*/);
|
||||
NDArray &operator-=(const T & /*value*/);
|
||||
NDArray operator-(const T & /*value*/);
|
||||
NDArray &operator*=(const T & /*value*/);
|
||||
NDArray operator*(const T & /*value*/);
|
||||
NDArray &operator/=(const T & /*value*/);
|
||||
NDArray operator/(const T & /*value*/);
|
||||
|
||||
NDArray &operator&=(const T &);
|
||||
NDArray &operator&=(const T & /*mask*/);
|
||||
|
||||
void sqrt() {
|
||||
for (int i = 0; i < size_; ++i) {
|
||||
@ -107,15 +106,15 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
|
||||
|
||||
NDArray &operator++(); // pre inc
|
||||
|
||||
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) {
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) {
|
||||
return data_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) const {
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) const {
|
||||
return data_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T>::type value(Ix... index) {
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T> value(Ix... index) {
|
||||
return data_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
@ -153,12 +152,12 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
|
||||
private:
|
||||
std::array<ssize_t, Ndim> shape_;
|
||||
std::array<ssize_t, Ndim> strides_;
|
||||
ssize_t size_;
|
||||
ssize_t size_{};
|
||||
T *data_;
|
||||
};
|
||||
|
||||
// Move assign
|
||||
template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) {
|
||||
template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) noexcept {
|
||||
if (this != &other) {
|
||||
delete[] data_;
|
||||
data_ = other.data_;
|
||||
@ -182,9 +181,8 @@ template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
data_[i] += other.data_[i];
|
||||
}
|
||||
return *this;
|
||||
} else {
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
|
||||
template <typename T, ssize_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const NDArray &other) {
|
||||
@ -200,9 +198,8 @@ template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
data_[i] -= other.data_[i];
|
||||
}
|
||||
return *this;
|
||||
} else {
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
template <typename T, ssize_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const NDArray &other) {
|
||||
NDArray result = *this;
|
||||
@ -217,9 +214,8 @@ template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
|
||||
data_[i] *= other.data_[i];
|
||||
}
|
||||
return *this;
|
||||
} else {
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
|
||||
template <typename T, ssize_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const NDArray &other) {
|
||||
@ -256,9 +252,8 @@ template <typename T, ssize_t Ndim> NDArray<bool, Ndim> NDArray<T, Ndim>::operat
|
||||
result(i) = (data_[i] > other.data_[i]);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
throw(std::runtime_error("Shape of ImageDatas must match"));
|
||||
}
|
||||
|
||||
template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const NDArray<T, Ndim> &other) {
|
||||
@ -364,7 +359,7 @@ template <typename T, ssize_t Ndim> void NDArray<T, Ndim>::Print_some() {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, ssize_t Ndim> void save(NDArray<T, Ndim> &img, std::string pathname) {
|
||||
template <typename T, ssize_t Ndim> void save(NDArray<T, Ndim> &img, std::string &pathname) {
|
||||
std::ofstream f;
|
||||
f.open(pathname, std::ios::binary);
|
||||
f.write(img.buffer(), img.size() * sizeof(T));
|
||||
|
@ -20,7 +20,7 @@ template <ssize_t Ndim> Shape<Ndim> make_shape(const std::vector<size_t> &shape)
|
||||
return arr;
|
||||
}
|
||||
|
||||
template <ssize_t Dim = 0, typename Strides> ssize_t element_offset(const Strides &) { return 0; }
|
||||
template <ssize_t Dim = 0, typename Strides> ssize_t element_offset(const Strides & /*unused*/) { return 0; }
|
||||
|
||||
template <ssize_t Dim = 0, typename Strides, typename... Ix>
|
||||
ssize_t element_offset(const Strides &strides, ssize_t i, Ix... index) {
|
||||
@ -28,7 +28,7 @@ ssize_t element_offset(const Strides &strides, ssize_t i, Ix... index) {
|
||||
}
|
||||
|
||||
template <ssize_t Ndim> std::array<ssize_t, Ndim> c_strides(const std::array<ssize_t, Ndim> &shape) {
|
||||
std::array<ssize_t, Ndim> strides;
|
||||
std::array<ssize_t, Ndim> strides{};
|
||||
std::fill(strides.begin(), strides.end(), 1);
|
||||
for (ssize_t i = Ndim - 1; i > 0; --i) {
|
||||
strides[i - 1] = strides[i] * shape[i];
|
||||
@ -38,42 +38,36 @@ template <ssize_t Ndim> std::array<ssize_t, Ndim> c_strides(const std::array<ssi
|
||||
|
||||
template <ssize_t Ndim> std::array<ssize_t, Ndim> make_array(const std::vector<ssize_t> &vec) {
|
||||
assert(vec.size() == Ndim);
|
||||
std::array<ssize_t, Ndim> arr;
|
||||
std::array<ssize_t, Ndim> arr{};
|
||||
std::copy_n(vec.begin(), Ndim, arr.begin());
|
||||
return arr;
|
||||
}
|
||||
|
||||
template <typename T, ssize_t Ndim = 2> class NDView {
|
||||
public:
|
||||
NDView(){};
|
||||
NDView() = default;
|
||||
~NDView() = default;
|
||||
NDView(const NDView &) = default;
|
||||
NDView(NDView &&) = default;
|
||||
|
||||
NDView(T *buffer, std::array<ssize_t, Ndim> shape) {
|
||||
buffer_ = buffer;
|
||||
strides_ = c_strides<Ndim>(shape);
|
||||
shape_ = shape;
|
||||
size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
|
||||
}
|
||||
NDView(T *buffer, std::array<ssize_t, Ndim> shape)
|
||||
: buffer_(buffer), strides_(c_strides<Ndim>(shape)), shape_(shape),
|
||||
size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
|
||||
|
||||
NDView(T *buffer, const std::vector<ssize_t> &shape) {
|
||||
buffer_ = buffer;
|
||||
strides_ = c_strides<Ndim>(make_array<Ndim>(shape));
|
||||
shape_ = make_array<Ndim>(shape);
|
||||
size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
|
||||
}
|
||||
NDView(T *buffer, const std::vector<ssize_t> &shape)
|
||||
: buffer_(buffer), strides_(c_strides<Ndim>(make_array<Ndim>(shape))), shape_(make_array<Ndim>(shape)),
|
||||
size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
|
||||
|
||||
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) {
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) {
|
||||
return buffer_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) const {
|
||||
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) const {
|
||||
return buffer_[element_offset(strides_, index...)];
|
||||
}
|
||||
|
||||
ssize_t size() const { return size_; }
|
||||
|
||||
NDView(const NDView &) = default;
|
||||
NDView(NDView &&) = default;
|
||||
|
||||
T *begin() { return buffer_; }
|
||||
T *end() { return buffer_ + size_; }
|
||||
T &operator()(ssize_t i) { return buffer_[i]; }
|
||||
@ -103,12 +97,26 @@ template <typename T, ssize_t Ndim = 2> class NDView {
|
||||
}
|
||||
|
||||
NDView &operator=(const NDView &other) {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
shape_ = other.shape_;
|
||||
strides_ = other.strides_;
|
||||
size_ = other.size_;
|
||||
buffer_ = other.buffer_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
NDView &operator=(NDView &&other) noexcept {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
shape_ = std::move(other.shape_);
|
||||
strides_ = std::move(other.strides_);
|
||||
size_ = other.size_;
|
||||
buffer_ = other.buffer_;
|
||||
other.buffer_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto &shape() { return shape_; }
|
||||
auto shape(ssize_t i) const { return shape_[i]; }
|
||||
|
||||
|
@ -28,7 +28,7 @@ struct sls_detector_header {
|
||||
uint16_t roundRNumber;
|
||||
uint8_t detType;
|
||||
uint8_t version;
|
||||
uint8_t packetMask[64];
|
||||
std::array<uint8_t, 64> packetMask;
|
||||
};
|
||||
|
||||
struct xy {
|
||||
@ -44,14 +44,14 @@ enum class DetectorType { Jungfrau, Eiger, Mythen3, Moench, ChipTestBoard };
|
||||
|
||||
enum class TimingMode { Auto, Trigger };
|
||||
|
||||
template <class T> T StringTo(std::string sv) { return T(sv); }
|
||||
template <class T> T StringTo(const std::string &arg) { return T(arg); }
|
||||
|
||||
template <class T> std::string toString(T sv) { return T(sv); }
|
||||
template <class T> std::string toString(T arg) { return T(arg); }
|
||||
|
||||
template <> DetectorType StringTo(std::string);
|
||||
template <> std::string toString(DetectorType type);
|
||||
template <> DetectorType StringTo(const std::string & /*name*/);
|
||||
template <> std::string toString(DetectorType arg);
|
||||
|
||||
template <> TimingMode StringTo(std::string);
|
||||
template <> TimingMode StringTo(const std::string & /*mode*/);
|
||||
|
||||
using DataTypeVariants = std::variant<uint16_t, uint32_t>;
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
#include "aare/core/DType.hpp"
|
||||
#include "aare/utils/logger.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/core.h>
|
||||
|
||||
namespace aare {
|
||||
|
||||
@ -26,9 +25,7 @@ DType::DType(const std::type_info &t) {
|
||||
m_type = TypeIndex::INT32;
|
||||
else if (t == typeid(uint32_t))
|
||||
m_type = TypeIndex::UINT32;
|
||||
else if (t == typeid(int64_t))
|
||||
m_type = TypeIndex::INT64;
|
||||
else if (t == typeid(long))
|
||||
else if (t == typeid(int64_t) || t == typeid(long)) // NOLINT
|
||||
m_type = TypeIndex::INT64;
|
||||
else if (t == typeid(uint64_t))
|
||||
m_type = TypeIndex::UINT64;
|
||||
@ -130,7 +127,7 @@ DType::DType(std::string_view sv) {
|
||||
*/
|
||||
std::string DType::str() const {
|
||||
|
||||
char ec;
|
||||
char ec{};
|
||||
if (endian::native == endian::little)
|
||||
ec = '<';
|
||||
else
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include "aare/core/Frame.hpp"
|
||||
#include "aare/utils/logger.hpp"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace aare {
|
||||
|
||||
@ -12,9 +13,9 @@ namespace aare {
|
||||
* @param cols number of columns
|
||||
* @param bitdepth bitdepth of the pixels
|
||||
*/
|
||||
Frame::Frame(std::byte *bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth)
|
||||
: m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) {
|
||||
m_data = new std::byte[rows * cols * bitdepth / 8];
|
||||
Frame::Frame(std::byte *bytes, size_t rows, size_t cols, size_t bitdepth)
|
||||
: m_rows(rows), m_cols(cols), m_bitdepth(bitdepth), m_data(new std::byte[rows * cols * bitdepth / 8]) {
|
||||
|
||||
std::memcpy(m_data, bytes, rows * cols * bitdepth / 8);
|
||||
}
|
||||
|
||||
@ -25,8 +26,9 @@ Frame::Frame(std::byte *bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth)
|
||||
* @param bitdepth bitdepth of the pixels
|
||||
* @note the data is initialized to zero
|
||||
*/
|
||||
Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth) : m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) {
|
||||
m_data = new std::byte[rows * cols * bitdepth / 8];
|
||||
Frame::Frame(size_t rows, size_t cols, size_t bitdepth)
|
||||
: m_rows(rows), m_cols(cols), m_bitdepth(bitdepth), m_data(new std::byte[rows * cols * bitdepth / 8]) {
|
||||
|
||||
std::memset(m_data, 0, rows * cols * bitdepth / 8);
|
||||
}
|
||||
|
||||
@ -37,10 +39,10 @@ Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth) : m_rows(rows), m_col
|
||||
* @return pointer to the pixel
|
||||
* @note the user should cast the pointer to the appropriate type
|
||||
*/
|
||||
std::byte *Frame::get(int row, int col) {
|
||||
if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) {
|
||||
std::cerr << "Invalid row or column index" << std::endl;
|
||||
return 0;
|
||||
std::byte *Frame::get(size_t row, size_t col) {
|
||||
if (row >= m_rows or col >= m_cols) {
|
||||
std::cerr << "Invalid row or column index" << '\n';
|
||||
return nullptr;
|
||||
}
|
||||
return m_data + (row * m_cols + col) * (m_bitdepth / 8);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "aare/core/defs.hpp"
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace aare {
|
||||
|
||||
@ -7,8 +9,8 @@ namespace aare {
|
||||
* @param type DetectorType
|
||||
* @return string representation of the DetectorType
|
||||
*/
|
||||
template <> std::string toString(DetectorType type) {
|
||||
switch (type) {
|
||||
template <> std::string toString(DetectorType arg) {
|
||||
switch (arg) {
|
||||
case DetectorType::Jungfrau:
|
||||
return "Jungfrau";
|
||||
case DetectorType::Eiger:
|
||||
@ -30,20 +32,18 @@ template <> std::string toString(DetectorType type) {
|
||||
* @return DetectorType
|
||||
* @throw runtime_error if the string does not match any DetectorType
|
||||
*/
|
||||
template <> DetectorType StringTo(std::string name) {
|
||||
if (name == "Jungfrau")
|
||||
template <> DetectorType StringTo(const std::string &arg) {
|
||||
if (arg == "Jungfrau")
|
||||
return DetectorType::Jungfrau;
|
||||
else if (name == "Eiger")
|
||||
if (arg == "Eiger")
|
||||
return DetectorType::Eiger;
|
||||
else if (name == "Mythen3")
|
||||
if (arg == "Mythen3")
|
||||
return DetectorType::Mythen3;
|
||||
else if (name == "Moench")
|
||||
if (arg == "Moench")
|
||||
return DetectorType::Moench;
|
||||
else if (name == "ChipTestBoard")
|
||||
if (arg == "ChipTestBoard")
|
||||
return DetectorType::ChipTestBoard;
|
||||
else {
|
||||
throw std::runtime_error("Could not decode dector from: \"" + name + "\"");
|
||||
}
|
||||
throw std::runtime_error("Could not decode dector from: \"" + arg + "\"");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,14 +52,12 @@ template <> DetectorType StringTo(std::string name) {
|
||||
* @return TimingMode
|
||||
* @throw runtime_error if the string does not match any TimingMode
|
||||
*/
|
||||
template <> TimingMode StringTo(std::string mode) {
|
||||
if (mode == "auto")
|
||||
template <> TimingMode StringTo(const std::string &arg) {
|
||||
if (arg == "auto")
|
||||
return TimingMode::Auto;
|
||||
else if (mode == "trigger")
|
||||
if (arg == "trigger")
|
||||
return TimingMode::Trigger;
|
||||
else {
|
||||
throw std::runtime_error("Could not decode timing mode from: \"" + mode + "\"");
|
||||
}
|
||||
throw std::runtime_error("Could not decode timing mode from: \"" + arg + "\"");
|
||||
}
|
||||
|
||||
// template <> TimingMode StringTo<TimingMode>(std::string mode);
|
||||
|
@ -4,9 +4,9 @@
|
||||
using aare::Frame;
|
||||
|
||||
TEST_CASE("Construct a frame") {
|
||||
ssize_t rows = 10;
|
||||
ssize_t cols = 10;
|
||||
ssize_t bitdepth = 8;
|
||||
size_t rows = 10;
|
||||
size_t cols = 10;
|
||||
size_t bitdepth = 8;
|
||||
|
||||
Frame frame(rows, cols, bitdepth);
|
||||
|
||||
@ -16,8 +16,8 @@ TEST_CASE("Construct a frame") {
|
||||
REQUIRE(frame.size() == rows * cols * bitdepth / 8);
|
||||
|
||||
// data should be initialized to 0
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
for (size_t i = 0; i < rows; i++) {
|
||||
for (size_t j = 0; j < cols; j++) {
|
||||
uint8_t *data = (uint8_t *)frame.get(i, j);
|
||||
REQUIRE(data != nullptr);
|
||||
REQUIRE(*data == 0);
|
||||
@ -26,9 +26,9 @@ TEST_CASE("Construct a frame") {
|
||||
}
|
||||
|
||||
TEST_CASE("Set a value in a 8 bit frame") {
|
||||
ssize_t rows = 10;
|
||||
ssize_t cols = 10;
|
||||
ssize_t bitdepth = 8;
|
||||
size_t rows = 10;
|
||||
size_t cols = 10;
|
||||
size_t bitdepth = 8;
|
||||
|
||||
Frame frame(rows, cols, bitdepth);
|
||||
|
||||
@ -37,8 +37,8 @@ TEST_CASE("Set a value in a 8 bit frame") {
|
||||
frame.set(5, 7, value);
|
||||
|
||||
// only the value we did set should be non-zero
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
for (size_t i = 0; i < rows; i++) {
|
||||
for (size_t j = 0; j < cols; j++) {
|
||||
uint8_t *data = (uint8_t *)frame.get(i, j);
|
||||
REQUIRE(data != nullptr);
|
||||
if (i == 5 && j == 7) {
|
||||
@ -51,9 +51,9 @@ TEST_CASE("Set a value in a 8 bit frame") {
|
||||
}
|
||||
|
||||
TEST_CASE("Set a value in a 64 bit frame") {
|
||||
ssize_t rows = 10;
|
||||
ssize_t cols = 10;
|
||||
ssize_t bitdepth = 64;
|
||||
size_t rows = 10;
|
||||
size_t cols = 10;
|
||||
size_t bitdepth = 64;
|
||||
|
||||
Frame frame(rows, cols, bitdepth);
|
||||
|
||||
@ -62,8 +62,8 @@ TEST_CASE("Set a value in a 64 bit frame") {
|
||||
frame.set(5, 7, value);
|
||||
|
||||
// only the value we did set should be non-zero
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
for (size_t i = 0; i < rows; i++) {
|
||||
for (size_t j = 0; j < cols; j++) {
|
||||
uint64_t *data = (uint64_t *)frame.get(i, j);
|
||||
REQUIRE(data != nullptr);
|
||||
if (i == 5 && j == 7) {
|
||||
@ -76,9 +76,9 @@ TEST_CASE("Set a value in a 64 bit frame") {
|
||||
}
|
||||
|
||||
TEST_CASE("Move construct a frame") {
|
||||
ssize_t rows = 10;
|
||||
ssize_t cols = 10;
|
||||
ssize_t bitdepth = 8;
|
||||
size_t rows = 10;
|
||||
size_t cols = 10;
|
||||
size_t bitdepth = 8;
|
||||
|
||||
Frame frame(rows, cols, bitdepth);
|
||||
std::byte *data = frame.data();
|
||||
|
@ -9,18 +9,18 @@ using aare::File;
|
||||
using aare::Frame;
|
||||
|
||||
void test(File &f, int frame_number) {
|
||||
std::cout << "frame number: " << frame_number << std::endl;
|
||||
std::cout << "frame number: " << frame_number << '\n';
|
||||
Frame frame = f.iread(frame_number);
|
||||
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(511, 1023)) << std::endl;
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(1, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(511, 1023))) << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR));
|
||||
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_single_master_0.json");
|
||||
std::cout << fpath << std::endl;
|
||||
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_single_master_0.json");
|
||||
std::cout << fpath << '\n';
|
||||
|
||||
File file(fpath, "r");
|
||||
test(file, 0);
|
||||
|
@ -9,19 +9,19 @@ using aare::File;
|
||||
using aare::Frame;
|
||||
|
||||
void test(File &f, int frame_number) {
|
||||
std::cout << "frame number: " << frame_number << std::endl;
|
||||
std::cout << "frame number: " << frame_number << '\n';
|
||||
Frame frame = f.iread(frame_number);
|
||||
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(255, 1023)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(511, 1023)) << std::endl;
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(255, 1023))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(511, 1023))) << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR));
|
||||
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_double_master_0.json");
|
||||
std::cout << fpath << std::endl;
|
||||
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_double_master_0.json");
|
||||
std::cout << fpath << '\n';
|
||||
|
||||
File file(fpath, "r");
|
||||
test(file, 0);
|
||||
|
@ -9,14 +9,14 @@ using aare::File;
|
||||
using aare::Frame;
|
||||
|
||||
void test1(File &f, int frame_number) {
|
||||
std::cout << "frame number: " << frame_number << std::endl;
|
||||
std::cout << "frame number: " << frame_number << '\n';
|
||||
Frame frame = f.iread(frame_number);
|
||||
std::cout << *((uint32_t *)frame.get(0, 0)) << std::endl;
|
||||
std::cout << *((uint32_t *)frame.get(0, 1)) << std::endl;
|
||||
std::cout << *((uint32_t *)frame.get(0, 3839)) << std::endl;
|
||||
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 3839))) << '\n';
|
||||
|
||||
for (int i = 0; i < 3840; i++) {
|
||||
uint16_t x = *((uint32_t *)frame.get(0, i));
|
||||
uint16_t const x = *(reinterpret_cast<uint32_t *>(frame.get(0, i)));
|
||||
if (x != i) {
|
||||
aare::logger::error("error at i", i, "x", x);
|
||||
}
|
||||
@ -24,11 +24,11 @@ void test1(File &f, int frame_number) {
|
||||
}
|
||||
|
||||
void test2(File &f, int frame_number) {
|
||||
std::cout << "frame number: " << frame_number << std::endl;
|
||||
std::cout << "frame number: " << frame_number << '\n';
|
||||
Frame frame = f.iread(frame_number);
|
||||
std::cout << *((uint32_t *)frame.get(0, 0)) << std::endl;
|
||||
std::cout << *((uint32_t *)frame.get(0, 1)) << std::endl;
|
||||
std::cout << *((uint32_t *)frame.get(0, 1280 * 4 - 1)) << std::endl;
|
||||
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1280 * 4 - 1))) << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
@ -8,19 +8,19 @@ using aare::File;
|
||||
using aare::Frame;
|
||||
|
||||
void test(File &f, int frame_number) {
|
||||
std::cout << "frame number: " << frame_number << std::endl;
|
||||
std::cout << "frame number: " << frame_number << '\n';
|
||||
Frame frame = f.iread(frame_number);
|
||||
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(49, 49)) << std::endl;
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(1, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(49, 49))) << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR));
|
||||
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "numpy" / "test_numpy_file.npy");
|
||||
std::cout << fpath << std::endl;
|
||||
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "numpy" / "test_numpy_file.npy");
|
||||
std::cout << fpath << '\n';
|
||||
|
||||
File file(fpath, "r");
|
||||
test(file, 0);
|
||||
|
@ -12,7 +12,7 @@ using aare::Frame;
|
||||
int main() {
|
||||
auto path = std::filesystem::path("/tmp/test.npy");
|
||||
auto dtype = aare::DType(typeid(uint32_t));
|
||||
FileConfig cfg = {dtype, 100, 100};
|
||||
FileConfig const cfg = {dtype, 100, 100};
|
||||
File npy(path, "w", cfg);
|
||||
Frame f(100, 100, dtype.bitdepth());
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
|
@ -9,11 +9,11 @@ using aare::File;
|
||||
using aare::Frame;
|
||||
|
||||
void test(File &f, int frame_number) {
|
||||
std::cout << "frame number: " << frame_number << std::endl;
|
||||
std::cout << "frame number: " << frame_number << '\n';
|
||||
Frame frame = f.iread(frame_number);
|
||||
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
|
||||
std::cout << *((uint16_t *)frame.get(0, 95)) << std::endl;
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
|
||||
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 95))) << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
@ -21,7 +21,7 @@ int main() {
|
||||
if (PROJECT_ROOT_DIR.empty()) {
|
||||
throw std::runtime_error("environment variable PROJECT_ROOT_DIR is not set");
|
||||
}
|
||||
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "moench" /
|
||||
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "moench" /
|
||||
"moench04_noise_200V_sto_both_100us_no_light_thresh_900_master_0.raw");
|
||||
File file(fpath, "r");
|
||||
test(file, 0);
|
||||
|
@ -35,7 +35,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
auto port = vm["port"].as<uint16_t>();
|
||||
|
||||
std::string endpoint = "udp://127.0.0.1:" + std::to_string(port);
|
||||
std::string const endpoint = "udp://127.0.0.1:" + std::to_string(port);
|
||||
aare::ZmqSocketReceiver socket(endpoint);
|
||||
socket.connect();
|
||||
while (true) {
|
||||
|
@ -48,10 +48,10 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string path = vm["file"].as<string>();
|
||||
uint16_t port = vm["port"].as<uint16_t>();
|
||||
bool loop = vm.count("loop") == 1 ? true : false;
|
||||
uint16_t fps = vm["fps"].as<uint16_t>();
|
||||
std::string const path = vm["file"].as<string>();
|
||||
uint16_t const port = vm["port"].as<uint16_t>();
|
||||
bool const loop = vm.count("loop") == 1;
|
||||
uint16_t const fps = vm["fps"].as<uint16_t>();
|
||||
|
||||
aare::logger::debug("ARGS: file:", path, "port:", port, "fps:", fps, "loop:", loop);
|
||||
auto d = round<std::chrono::milliseconds>(std::chrono::duration<double>{1. / fps});
|
||||
@ -62,17 +62,17 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::filesystem::path tmp(path);
|
||||
std::filesystem::path const tmp(path);
|
||||
|
||||
File file(tmp, "r");
|
||||
string endpoint = "tcp://*:" + std::to_string(port);
|
||||
string const endpoint = "tcp://*:" + std::to_string(port);
|
||||
ZmqSocketSender sender(endpoint);
|
||||
sender.bind();
|
||||
std::this_thread::sleep_for(d); // slow joiner problem should fix this
|
||||
|
||||
for (size_t frameidx = 0; frameidx < file.total_frames(); frameidx++) {
|
||||
|
||||
Frame frame = file.read();
|
||||
Frame const frame = file.read();
|
||||
ZmqHeader header;
|
||||
header.frameNumber = frameidx;
|
||||
header.data = true;
|
||||
|
@ -12,7 +12,7 @@ using namespace aare;
|
||||
|
||||
int main() {
|
||||
std::srand(std::time(nullptr));
|
||||
std::string endpoint = "tcp://*:5555";
|
||||
std::string const endpoint = "tcp://*:5555";
|
||||
aare::ZmqSocketSender socket(endpoint);
|
||||
socket.bind();
|
||||
Frame frame(1024, 1024, sizeof(uint32_t) * 8);
|
||||
@ -34,7 +34,7 @@ int main() {
|
||||
while (true) {
|
||||
zmq_frames.clear();
|
||||
header.acqIndex = acqid++;
|
||||
size_t n_frames = std::rand() % 10 + 1;
|
||||
size_t const n_frames = std::rand() % 10 + 1;
|
||||
|
||||
aare::logger::info("acquisition:", header.acqIndex);
|
||||
aare::logger::info("Header size:", header.to_string().size());
|
||||
@ -44,7 +44,7 @@ int main() {
|
||||
for (size_t i = 0; i < n_frames; i++) {
|
||||
zmq_frames.push_back({header, frame});
|
||||
}
|
||||
size_t rc = socket.send(zmq_frames);
|
||||
size_t const rc = socket.send(zmq_frames);
|
||||
aare::logger::info("Sent bytes", rc);
|
||||
sleep(1);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class File {
|
||||
* @throws std::invalid_argument if the file mode is not supported
|
||||
*
|
||||
*/
|
||||
File(std::filesystem::path fname, std::string mode, FileConfig cfg = {});
|
||||
File(const std::filesystem::path &fname, const std::string &mode, FileConfig cfg = {});
|
||||
void write(Frame &frame);
|
||||
Frame read();
|
||||
Frame iread(size_t frame_number);
|
||||
@ -31,19 +31,19 @@ class File {
|
||||
void read_into(std::byte *image_buf, size_t n_frames);
|
||||
size_t frame_number(size_t frame_index);
|
||||
size_t bytes_per_frame();
|
||||
size_t pixels();
|
||||
size_t pixels_per_frame();
|
||||
void seek(size_t frame_number);
|
||||
size_t tell() const;
|
||||
size_t total_frames() const;
|
||||
ssize_t rows() const;
|
||||
ssize_t cols() const;
|
||||
ssize_t bitdepth() const;
|
||||
size_t rows() const;
|
||||
size_t cols() const;
|
||||
size_t bitdepth() const;
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
* @param other File object to move from
|
||||
*/
|
||||
File(File &&other);
|
||||
File(File &&other) noexcept;
|
||||
|
||||
/**
|
||||
* @brief destructor: will only delete the FileInterface object
|
||||
|
@ -16,8 +16,8 @@ namespace aare {
|
||||
*/
|
||||
struct FileConfig {
|
||||
aare::DType dtype = aare::DType(typeid(uint16_t));
|
||||
uint64_t rows;
|
||||
uint64_t cols;
|
||||
uint64_t rows{};
|
||||
uint64_t cols{};
|
||||
xy geometry{1, 1};
|
||||
bool operator==(const FileConfig &other) const {
|
||||
return dtype == other.dtype && rows == other.rows && cols == other.cols && geometry == other.geometry;
|
||||
@ -92,7 +92,7 @@ class FileInterface {
|
||||
* @brief get the number of pixels in one frame
|
||||
* @return number of pixels in one frame
|
||||
*/
|
||||
virtual size_t pixels() = 0;
|
||||
virtual size_t pixels_per_frame() = 0;
|
||||
|
||||
/**
|
||||
* @brief seek to the given frame number
|
||||
@ -116,17 +116,17 @@ class FileInterface {
|
||||
* @brief get the number of rows in the file
|
||||
* @return number of rows in the file
|
||||
*/
|
||||
virtual ssize_t rows() const = 0;
|
||||
virtual size_t rows() const = 0;
|
||||
/**
|
||||
* @brief get the number of columns in the file
|
||||
* @return number of columns in the file
|
||||
*/
|
||||
virtual ssize_t cols() const = 0;
|
||||
virtual size_t cols() const = 0;
|
||||
/**
|
||||
* @brief get the bitdepth of the file
|
||||
* @return bitdepth of the file
|
||||
*/
|
||||
virtual ssize_t bitdepth() const = 0;
|
||||
virtual size_t bitdepth() const = 0;
|
||||
|
||||
/**
|
||||
* @brief read one frame from the file at the given frame number
|
||||
@ -158,23 +158,21 @@ class FileInterface {
|
||||
// function to query the data type of the file
|
||||
/*virtual DataType dtype = 0; */
|
||||
|
||||
virtual ~FileInterface(){
|
||||
|
||||
};
|
||||
virtual ~FileInterface() = default;
|
||||
|
||||
protected:
|
||||
std::string m_mode;
|
||||
std::filesystem::path m_fname;
|
||||
std::filesystem::path m_base_path;
|
||||
std::string m_base_name, m_ext;
|
||||
int m_findex;
|
||||
std::string m_mode{};
|
||||
std::filesystem::path m_fname{};
|
||||
std::filesystem::path m_base_path{};
|
||||
std::string m_base_name{}, m_ext{};
|
||||
int m_findex{};
|
||||
size_t m_total_frames{};
|
||||
size_t max_frames_per_file{};
|
||||
std::string version;
|
||||
DetectorType m_type;
|
||||
ssize_t m_rows{};
|
||||
ssize_t m_cols{};
|
||||
ssize_t m_bitdepth{};
|
||||
std::string version{};
|
||||
DetectorType m_type{};
|
||||
size_t m_rows{};
|
||||
size_t m_cols{};
|
||||
size_t m_bitdepth{};
|
||||
size_t current_frame{};
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "aare/core/defs.hpp"
|
||||
#include "aare/file_io/FileInterface.hpp"
|
||||
#include "aare/file_io/NumpyHelpers.hpp"
|
||||
#include "aare/utils/logger.hpp"
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
@ -24,7 +25,7 @@ class NumpyFile : public FileInterface {
|
||||
* @param mode file mode (r, w)
|
||||
* @param cfg file configuration
|
||||
*/
|
||||
NumpyFile(const std::filesystem::path &fname, const std::string &mode = "r", FileConfig cfg = {});
|
||||
explicit NumpyFile(const std::filesystem::path &fname, const std::string &mode = "r", FileConfig cfg = {});
|
||||
|
||||
void write(Frame &frame) override;
|
||||
Frame read() override { return get_frame(this->current_frame++); }
|
||||
@ -34,13 +35,13 @@ class NumpyFile : public FileInterface {
|
||||
void read_into(std::byte *image_buf, size_t n_frames) override;
|
||||
size_t frame_number(size_t frame_index) override { return frame_index; };
|
||||
size_t bytes_per_frame() override;
|
||||
size_t pixels() override;
|
||||
size_t pixels_per_frame() override;
|
||||
void seek(size_t frame_number) override { this->current_frame = frame_number; }
|
||||
size_t tell() override { return this->current_frame; }
|
||||
size_t total_frames() const override { return m_header.shape[0]; }
|
||||
ssize_t rows() const override { return m_header.shape[1]; }
|
||||
ssize_t cols() const override { return m_header.shape[2]; }
|
||||
ssize_t bitdepth() const override { return m_header.dtype.bitdepth(); }
|
||||
size_t rows() const override { return m_header.shape[1]; }
|
||||
size_t cols() const override { return m_header.shape[2]; }
|
||||
size_t bitdepth() const override { return m_header.dtype.bitdepth(); }
|
||||
|
||||
/**
|
||||
* @brief get the data type of the numpy file
|
||||
@ -62,12 +63,17 @@ class NumpyFile : public FileInterface {
|
||||
*/
|
||||
template <typename T, size_t NDim> NDArray<T, NDim> load() {
|
||||
NDArray<T, NDim> arr(make_shape<NDim>(m_header.shape));
|
||||
fseek(fp, header_size, SEEK_SET);
|
||||
fread(arr.data(), sizeof(T), arr.size(), fp);
|
||||
if (fseek(fp, static_cast<int64_t>(header_size), SEEK_SET)) {
|
||||
throw std::runtime_error(LOCATION + "Error seeking to the start of the data");
|
||||
}
|
||||
size_t rc = fread(arr.data(), sizeof(T), arr.size(), fp);
|
||||
if (rc != static_cast<size_t>(arr.size())) {
|
||||
throw std::runtime_error(LOCATION + "Error reading data from file");
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
~NumpyFile();
|
||||
~NumpyFile() noexcept override;
|
||||
|
||||
private:
|
||||
FILE *fp = nullptr;
|
||||
@ -79,9 +85,11 @@ class NumpyFile : public FileInterface {
|
||||
NumpyHeader m_header;
|
||||
uint8_t major_ver_{};
|
||||
uint8_t minor_ver_{};
|
||||
size_t m_bytes_per_frame{};
|
||||
size_t m_pixels_per_frame{};
|
||||
|
||||
void load_metadata();
|
||||
void get_frame_into(size_t, std::byte *);
|
||||
void get_frame_into(size_t /*frame_number*/, std::byte * /*image_buf*/);
|
||||
Frame get_frame(size_t frame_number);
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,7 @@ template <typename T, size_t N> bool in_array(T val, const std::array<T, N> &arr
|
||||
bool is_digits(const std::string &str);
|
||||
|
||||
aare::DType parse_descr(std::string typestring);
|
||||
size_t write_header(std::filesystem::path fname, const NumpyHeader &header);
|
||||
size_t write_header(const std::filesystem::path &fname, const NumpyHeader &header);
|
||||
size_t write_header(std::ostream &out, const NumpyHeader &header);
|
||||
|
||||
} // namespace NumpyHelpers
|
||||
|
@ -18,13 +18,13 @@ class RawFile : public FileInterface {
|
||||
* @param mode file mode (r, w)
|
||||
* @param cfg file configuration
|
||||
*/
|
||||
RawFile(const std::filesystem::path &fname, const std::string &mode = "r", const FileConfig &cfg = {});
|
||||
explicit RawFile(const std::filesystem::path &fname, const std::string &mode = "r", const FileConfig &config = {});
|
||||
|
||||
/**
|
||||
* @brief write function is not implemented for RawFile
|
||||
* @param frame frame to write
|
||||
*/
|
||||
void write(Frame &frame) override { throw std::runtime_error("Not implemented"); };
|
||||
void write(Frame & /*frame*/) override { throw std::runtime_error("Not implemented"); };
|
||||
Frame read() override { return get_frame(this->current_frame++); };
|
||||
std::vector<Frame> read(size_t n_frames) override;
|
||||
void read_into(std::byte *image_buf) override { return get_frame_into(this->current_frame++, image_buf); };
|
||||
@ -41,7 +41,7 @@ class RawFile : public FileInterface {
|
||||
* @brief get the number of pixels in the frame
|
||||
* @return number of pixels
|
||||
*/
|
||||
size_t pixels() override { return m_rows * m_cols; }
|
||||
size_t pixels_per_frame() override { return m_rows * m_cols; }
|
||||
|
||||
// goto frame number
|
||||
void seek(size_t frame_number) override { this->current_frame = frame_number; };
|
||||
@ -53,7 +53,7 @@ class RawFile : public FileInterface {
|
||||
* @brief check if the file is a master file
|
||||
* @param fpath path to the file
|
||||
*/
|
||||
static bool is_master_file(std::filesystem::path fpath);
|
||||
static bool is_master_file(const std::filesystem::path &fpath);
|
||||
|
||||
/**
|
||||
* @brief set the module gap row and column
|
||||
@ -83,17 +83,17 @@ class RawFile : public FileInterface {
|
||||
* @param file_id file id
|
||||
* @return path to the data file
|
||||
*/
|
||||
inline std::filesystem::path data_fname(int mod_id, int file_id);
|
||||
inline std::filesystem::path data_fname(size_t mod_id, size_t file_id);
|
||||
|
||||
/**
|
||||
* @brief destructor: will delete the subfiles
|
||||
*/
|
||||
~RawFile();
|
||||
~RawFile() override;
|
||||
|
||||
size_t total_frames() const override { return m_total_frames; }
|
||||
ssize_t rows() const override { return m_rows; }
|
||||
ssize_t cols() const override { return m_cols; }
|
||||
ssize_t bitdepth() const override { return m_bitdepth; }
|
||||
size_t rows() const override { return m_rows; }
|
||||
size_t cols() const override { return m_cols; }
|
||||
size_t bitdepth() const override { return m_bitdepth; }
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -101,7 +101,7 @@ class RawFile : public FileInterface {
|
||||
* @param frame_number frame number to read
|
||||
* @param image_buf buffer to store the frame
|
||||
*/
|
||||
void get_frame_into(size_t frame_number, std::byte *image_buf);
|
||||
void get_frame_into(size_t frame_number, std::byte *frame_buffer);
|
||||
|
||||
/**
|
||||
* @brief get the frame at the given frame number
|
||||
@ -140,22 +140,21 @@ class RawFile : public FileInterface {
|
||||
* @param fname path to the data subfile
|
||||
* @return sls_detector_header
|
||||
*/
|
||||
sls_detector_header read_header(const std::filesystem::path &fname);
|
||||
static sls_detector_header read_header(const std::filesystem::path &fname);
|
||||
|
||||
/**
|
||||
* @brief open the subfiles
|
||||
*/
|
||||
void open_subfiles();
|
||||
|
||||
private:
|
||||
size_t n_subfiles;
|
||||
size_t n_subfile_parts;
|
||||
size_t n_subfiles{};
|
||||
size_t n_subfile_parts{};
|
||||
std::vector<std::vector<SubFile *>> subfiles;
|
||||
int subfile_rows, subfile_cols;
|
||||
xy geometry;
|
||||
size_t subfile_rows{}, subfile_cols{};
|
||||
xy geometry{};
|
||||
std::vector<xy> positions;
|
||||
RawFileConfig cfg{0, 0};
|
||||
TimingMode timing_mode;
|
||||
TimingMode timing_mode{};
|
||||
bool quad{false};
|
||||
};
|
||||
|
||||
|
@ -45,7 +45,7 @@ class SubFile {
|
||||
* @param bitdepth bitdepth of the subfile
|
||||
* @throws std::invalid_argument if the detector,type pair is not supported
|
||||
*/
|
||||
SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth);
|
||||
SubFile(const std::filesystem::path &fname, DetectorType detector, size_t rows, size_t cols, size_t bitdepth);
|
||||
|
||||
/**
|
||||
* @brief read the subfile into a buffer
|
||||
@ -74,20 +74,20 @@ class SubFile {
|
||||
* @param frame_number frame number to read
|
||||
* @return number of bytes read
|
||||
*/
|
||||
size_t get_part(std::byte *buffer, int frame_number);
|
||||
size_t frame_number(int frame_index);
|
||||
size_t get_part(std::byte *buffer, size_t frame_number);
|
||||
size_t frame_number(size_t frame_index);
|
||||
|
||||
// TODO: define the inlines as variables and assign them in constructor
|
||||
inline size_t bytes_per_part() { return (m_bitdepth / 8) * m_rows * m_cols; }
|
||||
inline size_t pixels_per_part() { return m_rows * m_cols; }
|
||||
inline size_t bytes_per_part() const { return (m_bitdepth / 8) * m_rows * m_cols; }
|
||||
inline size_t pixels_per_part() const { return m_rows * m_cols; }
|
||||
|
||||
protected:
|
||||
FILE *fp = nullptr;
|
||||
ssize_t m_bitdepth;
|
||||
size_t m_bitdepth;
|
||||
std::filesystem::path m_fname;
|
||||
ssize_t m_rows{};
|
||||
ssize_t m_cols{};
|
||||
ssize_t n_frames{};
|
||||
size_t m_rows{};
|
||||
size_t m_cols{};
|
||||
size_t n_frames{};
|
||||
int m_sub_file_index_{};
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
namespace aare {
|
||||
|
||||
File::File(std::filesystem::path fname, std::string mode, FileConfig cfg) {
|
||||
File::File(const std::filesystem::path &fname, const std::string &mode, FileConfig cfg) {
|
||||
if (mode != "r" && mode != "w" && mode != "a") {
|
||||
throw std::invalid_argument("Unsupported file mode");
|
||||
}
|
||||
@ -36,20 +36,17 @@ void File::read_into(std::byte *image_buf) { file_impl->read_into(image_buf); }
|
||||
void File::read_into(std::byte *image_buf, size_t n_frames) { file_impl->read_into(image_buf, n_frames); }
|
||||
size_t File::frame_number(size_t frame_index) { return file_impl->frame_number(frame_index); }
|
||||
size_t File::bytes_per_frame() { return file_impl->bytes_per_frame(); }
|
||||
size_t File::pixels() { return file_impl->pixels(); }
|
||||
size_t File::pixels_per_frame() { return file_impl->pixels_per_frame(); }
|
||||
void File::seek(size_t frame_number) { file_impl->seek(frame_number); }
|
||||
size_t File::tell() const { return file_impl->tell(); }
|
||||
ssize_t File::rows() const { return file_impl->rows(); }
|
||||
ssize_t File::cols() const { return file_impl->cols(); }
|
||||
ssize_t File::bitdepth() const { return file_impl->bitdepth(); }
|
||||
size_t File::rows() const { return file_impl->rows(); }
|
||||
size_t File::cols() const { return file_impl->cols(); }
|
||||
size_t File::bitdepth() const { return file_impl->bitdepth(); }
|
||||
File::~File() { delete file_impl; }
|
||||
|
||||
Frame File::iread(size_t frame_number) { return file_impl->iread(frame_number); }
|
||||
|
||||
File::File(File &&other) {
|
||||
file_impl = other.file_impl;
|
||||
other.file_impl = nullptr;
|
||||
}
|
||||
File::File(File &&other) noexcept : file_impl(other.file_impl) { other.file_impl = nullptr; }
|
||||
|
||||
// write move assignment operator
|
||||
|
||||
|
@ -26,6 +26,9 @@ NumpyFile::NumpyFile(const std::filesystem::path &fname, const std::string &mode
|
||||
}
|
||||
initial_header_len = aare::NumpyHelpers::write_header(std::filesystem::path(m_fname.c_str()), m_header);
|
||||
}
|
||||
m_pixels_per_frame = std::accumulate(m_header.shape.begin() + 1, m_header.shape.end(), 1, std::multiplies<>());
|
||||
|
||||
m_bytes_per_frame = m_header.dtype.bitdepth() / 8 * m_pixels_per_frame;
|
||||
}
|
||||
|
||||
void NumpyFile::write(Frame &frame) {
|
||||
@ -33,10 +36,14 @@ void NumpyFile::write(Frame &frame) {
|
||||
throw std::runtime_error("File not open");
|
||||
}
|
||||
if (not(m_mode == "w" or m_mode == "a")) {
|
||||
throw std::runtime_error("File not open for writing");
|
||||
throw std::invalid_argument("File not open for writing");
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_END))
|
||||
throw std::runtime_error("Could not seek to end of file");
|
||||
size_t const rc = fwrite(frame.data(), frame.size(), 1, fp);
|
||||
if (rc != 1) {
|
||||
throw std::runtime_error("Error writing frame to file");
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fwrite(frame.data(), frame.size(), 1, fp);
|
||||
}
|
||||
|
||||
Frame NumpyFile::get_frame(size_t frame_number) {
|
||||
@ -49,16 +56,19 @@ void NumpyFile::get_frame_into(size_t frame_number, std::byte *image_buf) {
|
||||
throw std::runtime_error("File not open");
|
||||
}
|
||||
if (frame_number > m_header.shape[0]) {
|
||||
throw std::runtime_error("Frame number out of range");
|
||||
throw std::invalid_argument("Frame number out of range");
|
||||
}
|
||||
if (fseek(fp, header_size + frame_number * m_bytes_per_frame, SEEK_SET)) // NOLINT
|
||||
throw std::runtime_error("Could not seek to frame");
|
||||
|
||||
size_t const rc = fread(image_buf, m_bytes_per_frame, 1, fp);
|
||||
if (rc != 1) {
|
||||
throw std::runtime_error("Error reading frame from file");
|
||||
}
|
||||
fseek(fp, header_size + frame_number * bytes_per_frame(), SEEK_SET);
|
||||
fread(image_buf, bytes_per_frame(), 1, fp);
|
||||
}
|
||||
|
||||
size_t NumpyFile::pixels() {
|
||||
return std::accumulate(m_header.shape.begin() + 1, m_header.shape.end(), 1, std::multiplies<uint64_t>());
|
||||
};
|
||||
size_t NumpyFile::bytes_per_frame() { return m_header.dtype.bitdepth() / 8 * pixels(); };
|
||||
size_t NumpyFile::pixels_per_frame() { return m_pixels_per_frame; };
|
||||
size_t NumpyFile::bytes_per_frame() { return m_bytes_per_frame; };
|
||||
|
||||
std::vector<Frame> NumpyFile::read(size_t n_frames) {
|
||||
// TODO: implement this in a more efficient way
|
||||
@ -73,30 +83,39 @@ void NumpyFile::read_into(std::byte *image_buf, size_t n_frames) {
|
||||
// TODO: implement this in a more efficient way
|
||||
for (size_t i = 0; i < n_frames; i++) {
|
||||
get_frame_into(current_frame++, image_buf);
|
||||
image_buf += bytes_per_frame();
|
||||
image_buf += m_bytes_per_frame;
|
||||
}
|
||||
}
|
||||
|
||||
NumpyFile::~NumpyFile() {
|
||||
NumpyFile::~NumpyFile() noexcept {
|
||||
if (m_mode == "w" or m_mode == "a") {
|
||||
// determine number of frames
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t file_size = ftell(fp);
|
||||
size_t data_size = file_size - initial_header_len;
|
||||
size_t n_frames = data_size / bytes_per_frame();
|
||||
if (fseek(fp, 0, SEEK_END)) {
|
||||
aare::logger::error("Could not seek to end of file");
|
||||
}
|
||||
size_t const file_size = ftell(fp);
|
||||
size_t const data_size = file_size - initial_header_len;
|
||||
size_t const n_frames = data_size / m_bytes_per_frame;
|
||||
// update number of frames in header (first element of shape)
|
||||
m_header.shape[0] = n_frames;
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
if (fseek(fp, 0, SEEK_SET)) {
|
||||
aare::logger::error("Could not seek to beginning of file");
|
||||
}
|
||||
// create string stream to contain header
|
||||
std::stringstream ss;
|
||||
aare::NumpyHelpers::write_header(ss, m_header);
|
||||
std::string header_str = ss.str();
|
||||
std::string const header_str = ss.str();
|
||||
// write header
|
||||
fwrite(header_str.c_str(), header_str.size(), 1, fp);
|
||||
size_t const rc = fwrite(header_str.c_str(), header_str.size(), 1, fp);
|
||||
if (rc != 1) {
|
||||
aare::logger::error("Error writing header to numpy file in destructor");
|
||||
}
|
||||
}
|
||||
|
||||
if (fp != nullptr) {
|
||||
fclose(fp);
|
||||
if (fclose(fp)) {
|
||||
aare::logger::error("Error closing file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,17 +123,23 @@ void NumpyFile::load_metadata() {
|
||||
|
||||
// read magic number
|
||||
std::array<char, 6> tmp{};
|
||||
fread(tmp.data(), tmp.size(), 1, fp);
|
||||
size_t rc = fread(tmp.data(), tmp.size(), 1, fp);
|
||||
if (rc != 1) {
|
||||
throw std::runtime_error("Error reading magic number");
|
||||
}
|
||||
if (tmp != aare::NumpyHelpers::magic_str) {
|
||||
for (auto item : tmp)
|
||||
fmt::print("{}, ", int(item));
|
||||
fmt::print("{}, ", static_cast<int>(item));
|
||||
fmt::print("\n");
|
||||
throw std::runtime_error("Not a numpy file");
|
||||
}
|
||||
|
||||
// read version
|
||||
fread(reinterpret_cast<char *>(&major_ver_), sizeof(major_ver_), 1, fp);
|
||||
fread(reinterpret_cast<char *>(&minor_ver_), sizeof(minor_ver_), 1, fp);
|
||||
rc = fread(reinterpret_cast<char *>(&major_ver_), sizeof(major_ver_), 1, fp);
|
||||
rc += fread(reinterpret_cast<char *>(&minor_ver_), sizeof(minor_ver_), 1, fp);
|
||||
if (rc != 2) {
|
||||
throw std::runtime_error("Error reading numpy version");
|
||||
}
|
||||
|
||||
if (major_ver_ == 1) {
|
||||
header_len_size = 2;
|
||||
@ -125,7 +150,10 @@ void NumpyFile::load_metadata() {
|
||||
}
|
||||
|
||||
// read header length
|
||||
fread(reinterpret_cast<char *>(&header_len), header_len_size, 1, fp);
|
||||
rc = fread(reinterpret_cast<char *>(&header_len), header_len_size, 1, fp);
|
||||
if (rc != 1) {
|
||||
throw std::runtime_error("Error reading header length");
|
||||
}
|
||||
header_size = aare::NumpyHelpers::magic_string_length + 2 + header_len_size + header_len;
|
||||
if (header_size % 16 != 0) {
|
||||
fmt::print("Warning: header length is not a multiple of 16\n");
|
||||
@ -133,31 +161,34 @@ void NumpyFile::load_metadata() {
|
||||
|
||||
// read header
|
||||
std::string header(header_len, '\0');
|
||||
fread(header.data(), header_len, 1, fp);
|
||||
rc = fread(header.data(), header_len, 1, fp);
|
||||
if (rc != 1) {
|
||||
throw std::runtime_error("Error reading header");
|
||||
}
|
||||
|
||||
// parse header
|
||||
std::vector<std::string> keys{"descr", "fortran_order", "shape"};
|
||||
std::vector<std::string> const keys{"descr", "fortran_order", "shape"};
|
||||
aare::logger::debug("original header: \"header\"");
|
||||
|
||||
auto dict_map = aare::NumpyHelpers::parse_dict(header, keys);
|
||||
if (dict_map.size() == 0)
|
||||
if (dict_map.empty())
|
||||
throw std::runtime_error("invalid dictionary in header");
|
||||
|
||||
std::string descr_s = dict_map["descr"];
|
||||
std::string fortran_s = dict_map["fortran_order"];
|
||||
std::string shape_s = dict_map["shape"];
|
||||
std::string const descr_s = dict_map["descr"];
|
||||
std::string const fortran_s = dict_map["fortran_order"];
|
||||
std::string const shape_s = dict_map["shape"];
|
||||
|
||||
std::string descr = aare::NumpyHelpers::parse_str(descr_s);
|
||||
aare::DType dtype = aare::NumpyHelpers::parse_descr(descr);
|
||||
std::string const descr = aare::NumpyHelpers::parse_str(descr_s);
|
||||
aare::DType const dtype = aare::NumpyHelpers::parse_descr(descr);
|
||||
|
||||
// convert literal Python bool to C++ bool
|
||||
bool fortran_order = aare::NumpyHelpers::parse_bool(fortran_s);
|
||||
bool const fortran_order = aare::NumpyHelpers::parse_bool(fortran_s);
|
||||
|
||||
// parse the shape tuple
|
||||
auto shape_v = aare::NumpyHelpers::parse_tuple(shape_s);
|
||||
shape_t shape;
|
||||
for (auto item : shape_v) {
|
||||
auto dim = static_cast<unsigned long>(std::stoul(item));
|
||||
for (const auto &item : shape_v) {
|
||||
auto dim = static_cast<size_t>(std::stoul(item));
|
||||
shape.push_back(dim);
|
||||
}
|
||||
m_header = {dtype, fortran_order, shape};
|
||||
|
@ -41,7 +41,7 @@ namespace NumpyHelpers {
|
||||
|
||||
std::unordered_map<std::string, std::string> parse_dict(std::string in, const std::vector<std::string> &keys) {
|
||||
std::unordered_map<std::string, std::string> map;
|
||||
if (keys.size() == 0)
|
||||
if (keys.empty())
|
||||
return map;
|
||||
|
||||
in = trim(in);
|
||||
@ -55,12 +55,12 @@ std::unordered_map<std::string, std::string> parse_dict(std::string in, const st
|
||||
std::vector<std::pair<size_t, std::string>> positions;
|
||||
|
||||
for (auto const &key : keys) {
|
||||
size_t pos = in.find("'" + key + "'");
|
||||
size_t const pos = in.find("'" + key + "'");
|
||||
|
||||
if (pos == std::string::npos)
|
||||
throw std::runtime_error("Missing '" + key + "' key.");
|
||||
|
||||
std::pair<size_t, std::string> position_pair{pos, key};
|
||||
std::pair<size_t, std::string> const position_pair{pos, key};
|
||||
positions.push_back(position_pair);
|
||||
}
|
||||
|
||||
@ -69,10 +69,10 @@ std::unordered_map<std::string, std::string> parse_dict(std::string in, const st
|
||||
|
||||
for (size_t i = 0; i < positions.size(); ++i) {
|
||||
std::string raw_value;
|
||||
size_t begin{positions[i].first};
|
||||
size_t const begin{positions[i].first};
|
||||
size_t end{std::string::npos};
|
||||
|
||||
std::string key = positions[i].second;
|
||||
std::string const key = positions[i].second;
|
||||
|
||||
if (i + 1 < positions.size())
|
||||
end = positions[i + 1].first;
|
||||
@ -104,7 +104,7 @@ aare::DType parse_descr(std::string typestring) {
|
||||
|
||||
const char byteorder_c = typestring[0];
|
||||
const char kind_c = typestring[1];
|
||||
std::string itemsize_s = typestring.substr(2);
|
||||
std::string const itemsize_s = typestring.substr(2);
|
||||
|
||||
if (!in_array(byteorder_c, endian_chars)) {
|
||||
throw std::runtime_error("invalid typestring (byteorder)");
|
||||
@ -130,11 +130,11 @@ bool parse_bool(const std::string &in) {
|
||||
}
|
||||
|
||||
std::string get_value_from_map(const std::string &mapstr) {
|
||||
size_t sep_pos = mapstr.find_first_of(":");
|
||||
size_t const sep_pos = mapstr.find_first_of(':');
|
||||
if (sep_pos == std::string::npos)
|
||||
return "";
|
||||
|
||||
std::string tmp = mapstr.substr(sep_pos + 1);
|
||||
std::string const tmp = mapstr.substr(sep_pos + 1);
|
||||
return trim(tmp);
|
||||
}
|
||||
|
||||
@ -180,12 +180,12 @@ std::string parse_str(const std::string &in) {
|
||||
|
||||
void write_magic(std::ostream &ostream, int version_major, int version_minor) {
|
||||
ostream.write(magic_str.data(), magic_string_length);
|
||||
ostream.put(version_major);
|
||||
ostream.put(version_minor);
|
||||
ostream.put(static_cast<char>(version_major));
|
||||
ostream.put(static_cast<char>(version_minor));
|
||||
}
|
||||
template <typename T> inline std::string write_tuple(const std::vector<T> &v) {
|
||||
|
||||
if (v.size() == 0)
|
||||
if (v.empty())
|
||||
return "()";
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale("C"));
|
||||
@ -211,36 +211,35 @@ template <typename T> inline std::string write_tuple(const std::vector<T> &v) {
|
||||
inline std::string write_boolean(bool b) {
|
||||
if (b)
|
||||
return "True";
|
||||
else
|
||||
return "False";
|
||||
}
|
||||
|
||||
inline std::string write_header_dict(const std::string &descr, bool fortran_order, const shape_t &shape) {
|
||||
std::string s_fortran_order = write_boolean(fortran_order);
|
||||
std::string shape_s = write_tuple(shape);
|
||||
std::string const s_fortran_order = write_boolean(fortran_order);
|
||||
std::string const shape_s = write_tuple(shape);
|
||||
|
||||
return "{'descr': '" + descr + "', 'fortran_order': " + s_fortran_order + ", 'shape': " + shape_s + ", }";
|
||||
}
|
||||
|
||||
size_t write_header(std::filesystem::path fname, const NumpyHeader &header) {
|
||||
size_t write_header(const std::filesystem::path &fname, const NumpyHeader &header) {
|
||||
std::ofstream out(fname, std::ios::binary | std::ios::out);
|
||||
return write_header(out, header);
|
||||
}
|
||||
|
||||
size_t write_header(std::ostream &out, const NumpyHeader &header) {
|
||||
std::string header_dict = write_header_dict(header.dtype.str(), header.fortran_order, header.shape);
|
||||
std::string const header_dict = write_header_dict(header.dtype.str(), header.fortran_order, header.shape);
|
||||
|
||||
size_t length = magic_string_length + 2 + 2 + header_dict.length() + 1;
|
||||
|
||||
int version_major = 1;
|
||||
int version_minor = 0;
|
||||
if (length >= 255 * 255) {
|
||||
if (length >= static_cast<size_t>(255) * 255) {
|
||||
length = magic_string_length + 2 + 4 + header_dict.length() + 1;
|
||||
version_major = 2;
|
||||
version_minor = 0;
|
||||
}
|
||||
size_t padding_len = 16 - length % 16;
|
||||
std::string padding(padding_len, ' ');
|
||||
size_t const padding_len = 16 - length % 16;
|
||||
std::string const padding(padding_len, ' ');
|
||||
|
||||
// write magic
|
||||
write_magic(out, version_major, version_minor);
|
||||
|
@ -30,7 +30,7 @@ void RawFile::open_subfiles() {
|
||||
for (size_t i = 0; i != n_subfiles; ++i) {
|
||||
auto v = std::vector<SubFile *>(n_subfile_parts);
|
||||
for (size_t j = 0; j != n_subfile_parts; ++j) {
|
||||
v[j] = new SubFile(data_fname(i, j), m_type, subfile_rows, subfile_cols, bitdepth());
|
||||
v[j] = new SubFile(data_fname(i, j), m_type, subfile_rows, subfile_cols, m_bitdepth);
|
||||
}
|
||||
subfiles.push_back(v);
|
||||
}
|
||||
@ -42,18 +42,18 @@ sls_detector_header RawFile::read_header(const std::filesystem::path &fname) {
|
||||
if (!fp)
|
||||
throw std::runtime_error(fmt::format("Could not open: {} for reading", fname.c_str()));
|
||||
|
||||
size_t rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
|
||||
fclose(fp);
|
||||
size_t const rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
|
||||
if (rc != 1)
|
||||
throw std::runtime_error("Could not read header from file");
|
||||
throw std::runtime_error(LOCATION + "Could not read header from file");
|
||||
if (fclose(fp)) {
|
||||
throw std::runtime_error(LOCATION + "Could not close file");
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
bool RawFile::is_master_file(std::filesystem::path fpath) {
|
||||
std::string stem = fpath.stem();
|
||||
if (stem.find("_master_") != std::string::npos)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
bool RawFile::is_master_file(const std::filesystem::path &fpath) {
|
||||
std::string const stem = fpath.stem();
|
||||
return stem.find("_master_") != std::string::npos;
|
||||
}
|
||||
|
||||
void RawFile::find_number_of_subfiles() {
|
||||
@ -62,7 +62,7 @@ void RawFile::find_number_of_subfiles() {
|
||||
;
|
||||
n_subfiles = n_mod;
|
||||
}
|
||||
inline std::filesystem::path RawFile::data_fname(int mod_id, int file_id) {
|
||||
inline std::filesystem::path RawFile::data_fname(size_t mod_id, size_t file_id) {
|
||||
return this->m_base_path / fmt::format("{}_d{}_f{}_{}.raw", this->m_base_name, file_id, mod_id, this->m_findex);
|
||||
}
|
||||
|
||||
@ -86,10 +86,10 @@ void RawFile::find_geometry() {
|
||||
r++;
|
||||
c++;
|
||||
|
||||
m_rows = r * subfile_rows;
|
||||
m_cols = c * subfile_cols;
|
||||
m_rows = (r * subfile_rows);
|
||||
m_cols = (c * subfile_cols);
|
||||
|
||||
m_rows += (r - 1) * cfg.module_gap_row;
|
||||
m_rows += static_cast<size_t>((r - 1) * cfg.module_gap_row);
|
||||
}
|
||||
|
||||
void RawFile::parse_metadata() {
|
||||
@ -109,7 +109,7 @@ void RawFile::parse_metadata() {
|
||||
} else {
|
||||
throw std::runtime_error(LOCATION + "Unsupported file type");
|
||||
}
|
||||
n_subfile_parts = geometry.row * geometry.col;
|
||||
n_subfile_parts = static_cast<size_t>(geometry.row) * geometry.col;
|
||||
}
|
||||
|
||||
void RawFile::parse_json_metadata() {
|
||||
@ -141,7 +141,7 @@ void RawFile::parse_raw_metadata() {
|
||||
for (std::string line; std::getline(ifs, line);) {
|
||||
if (line == "#Frame Header")
|
||||
break;
|
||||
auto pos = line.find(":");
|
||||
auto pos = line.find(':');
|
||||
auto key_pos = pos;
|
||||
while (key_pos != std::string::npos && std::isspace(line[--key_pos]))
|
||||
;
|
||||
@ -183,7 +183,7 @@ void RawFile::parse_fname() {
|
||||
m_base_path = m_fname.parent_path();
|
||||
m_base_name = m_fname.stem();
|
||||
m_ext = m_fname.extension();
|
||||
auto pos = m_base_name.rfind("_");
|
||||
auto pos = m_base_name.rfind('_');
|
||||
m_findex = std::stoi(m_base_name.substr(pos + 1));
|
||||
pos = m_base_name.find("_master_");
|
||||
m_base_name.erase(pos);
|
||||
@ -200,7 +200,7 @@ void RawFile::get_frame_into(size_t frame_number, std::byte *frame_buffer) {
|
||||
if (frame_number > this->m_total_frames) {
|
||||
throw std::runtime_error(LOCATION + "Frame number out of range");
|
||||
}
|
||||
int subfile_id = frame_number / this->max_frames_per_file;
|
||||
size_t const subfile_id = frame_number / this->max_frames_per_file;
|
||||
// create frame and get its buffer
|
||||
|
||||
if (this->geometry.col == 1) {
|
||||
@ -214,11 +214,11 @@ void RawFile::get_frame_into(size_t frame_number, std::byte *frame_buffer) {
|
||||
} else {
|
||||
// create a buffer that will hold a the frame part
|
||||
auto bytes_per_part = this->subfile_rows * this->subfile_cols * this->m_bitdepth / 8;
|
||||
std::byte *part_buffer = new std::byte[bytes_per_part];
|
||||
auto *part_buffer = new std::byte[bytes_per_part];
|
||||
|
||||
for (size_t part_idx = 0; part_idx != this->n_subfile_parts; ++part_idx) {
|
||||
this->subfiles[subfile_id][part_idx]->get_part(part_buffer, frame_number % this->max_frames_per_file);
|
||||
for (int cur_row = 0; cur_row < (this->subfile_rows); cur_row++) {
|
||||
for (size_t cur_row = 0; cur_row < (this->subfile_rows); cur_row++) {
|
||||
auto irow = cur_row + (part_idx / this->geometry.col) * this->subfile_rows;
|
||||
auto icol = (part_idx % this->geometry.col) * this->subfile_cols;
|
||||
auto dest = (irow * this->m_cols + icol);
|
||||
@ -252,13 +252,13 @@ size_t RawFile::frame_number(size_t frame_index) {
|
||||
if (frame_index > this->m_total_frames) {
|
||||
throw std::runtime_error(LOCATION + "Frame number out of range");
|
||||
}
|
||||
int subfile_id = frame_index / this->max_frames_per_file;
|
||||
size_t const subfile_id = frame_index / this->max_frames_per_file;
|
||||
return this->subfiles[subfile_id][0]->frame_number(frame_index % this->max_frames_per_file);
|
||||
}
|
||||
|
||||
RawFile::~RawFile() {
|
||||
for (auto &vec : subfiles) {
|
||||
for (auto subfile : vec) {
|
||||
for (auto *subfile : vec) {
|
||||
delete subfile;
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,10 @@
|
||||
|
||||
namespace aare {
|
||||
|
||||
SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth) {
|
||||
this->m_rows = rows;
|
||||
this->m_cols = cols;
|
||||
this->m_fname = fname;
|
||||
this->m_bitdepth = bitdepth;
|
||||
this->n_frames = std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8);
|
||||
SubFile::SubFile(const std::filesystem::path &fname, DetectorType detector, size_t rows, size_t cols, size_t bitdepth)
|
||||
: m_bitdepth(bitdepth), m_fname(fname), m_rows(rows), m_cols(cols),
|
||||
n_frames(std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8)) {
|
||||
|
||||
if (read_impl_map.find({detector, bitdepth}) == read_impl_map.end()) {
|
||||
auto error_msg = LOCATION + "No read_impl function found for detector: " + toString(detector) +
|
||||
" and bitdepth: " + std::to_string(bitdepth);
|
||||
@ -21,8 +19,8 @@ SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t row
|
||||
this->read_impl = read_impl_map.at({detector, bitdepth});
|
||||
}
|
||||
|
||||
size_t SubFile::get_part(std::byte *buffer, int frame_number) {
|
||||
if (frame_number >= n_frames or frame_number < 0) {
|
||||
size_t SubFile::get_part(std::byte *buffer, size_t frame_number) {
|
||||
if (frame_number >= n_frames) {
|
||||
throw std::runtime_error("Frame number out of range");
|
||||
}
|
||||
// TODO: find a way to avoid opening and closing the file for each frame
|
||||
@ -31,9 +29,11 @@ size_t SubFile::get_part(std::byte *buffer, int frame_number) {
|
||||
if (!fp) {
|
||||
throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str()));
|
||||
}
|
||||
fseek(fp, sizeof(sls_detector_header) + (sizeof(sls_detector_header) + bytes_per_part()) * frame_number, SEEK_SET);
|
||||
fseek(fp, sizeof(sls_detector_header) + (sizeof(sls_detector_header) + bytes_per_part()) * frame_number, // NOLINT
|
||||
SEEK_SET);
|
||||
auto ret = (this->*read_impl)(buffer);
|
||||
fclose(fp);
|
||||
if (fclose(fp))
|
||||
throw std::runtime_error(LOCATION + "Could not close file");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -42,24 +42,24 @@ size_t SubFile::read_impl_normal(std::byte *buffer) { return fread(buffer, this-
|
||||
template <typename DataType> size_t SubFile::read_impl_reorder(std::byte *buffer) {
|
||||
|
||||
std::vector<DataType> tmp(this->pixels_per_part());
|
||||
size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_part(), 1, this->fp);
|
||||
size_t const rc = fread(reinterpret_cast<char *>(tmp.data()), this->bytes_per_part(), 1, this->fp);
|
||||
|
||||
int adc_nr[32] = {300, 325, 350, 375, 300, 325, 350, 375, 200, 225, 250, 275, 200, 225, 250, 275,
|
||||
std::array<int, 32> const adc_nr = {300, 325, 350, 375, 300, 325, 350, 375, 200, 225, 250, 275, 200, 225, 250, 275,
|
||||
100, 125, 150, 175, 100, 125, 150, 175, 0, 25, 50, 75, 0, 25, 50, 75};
|
||||
int sc_width = 25;
|
||||
int nadc = 32;
|
||||
int pixels_per_sc = 5000;
|
||||
int const sc_width = 25;
|
||||
int const nadc = 32;
|
||||
int const pixels_per_sc = 5000;
|
||||
|
||||
auto dst = reinterpret_cast<DataType *>(buffer);
|
||||
int pixel = 0;
|
||||
for (int i = 0; i != pixels_per_sc; ++i) {
|
||||
for (int i_adc = 0; i_adc != nadc; ++i_adc) {
|
||||
int col = adc_nr[i_adc] + (i % sc_width);
|
||||
int row;
|
||||
int const col = adc_nr[i_adc] + (i % sc_width);
|
||||
int row = 0;
|
||||
if ((i_adc / 4) % 2 == 0)
|
||||
row = 199 - int(i / sc_width);
|
||||
row = 199 - (i / sc_width);
|
||||
else
|
||||
row = 200 + int(i / sc_width);
|
||||
row = 200 + (i / sc_width);
|
||||
|
||||
dst[col + row * 400] = tmp[pixel];
|
||||
pixel++;
|
||||
@ -72,15 +72,15 @@ template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
|
||||
// read to temporary buffer
|
||||
// TODO! benchmark direct reads
|
||||
std::vector<std::byte> tmp(this->bytes_per_part());
|
||||
size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_part(), 1, this->fp);
|
||||
size_t const rc = fread(reinterpret_cast<char *>(tmp.data()), this->bytes_per_part(), 1, this->fp);
|
||||
|
||||
// copy to place
|
||||
const size_t start = this->m_cols * (this->m_rows - 1) * sizeof(DataType);
|
||||
const size_t row_size = this->m_cols * sizeof(DataType);
|
||||
auto dst = buffer + start;
|
||||
auto src = &tmp[0];
|
||||
auto *dst = buffer + start;
|
||||
auto *src = tmp.data();
|
||||
|
||||
for (int i = 0; i != this->m_rows; ++i) {
|
||||
for (size_t i = 0; i != this->m_rows; ++i) {
|
||||
std::memcpy(dst, src, row_size);
|
||||
dst -= row_size;
|
||||
src += row_size;
|
||||
@ -89,16 +89,18 @@ template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
|
||||
return rc;
|
||||
};
|
||||
|
||||
size_t SubFile::frame_number(int frame_index) {
|
||||
size_t SubFile::frame_number(size_t frame_index) {
|
||||
sls_detector_header h{};
|
||||
fp = fopen(this->m_fname.c_str(), "r");
|
||||
if (!fp)
|
||||
throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str()));
|
||||
fseek(fp, (sizeof(sls_detector_header) + bytes_per_part()) * frame_index, SEEK_SET);
|
||||
size_t rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
|
||||
fclose(fp);
|
||||
throw std::runtime_error(LOCATION + fmt::format("Could not open: {} for reading", m_fname.c_str()));
|
||||
fseek(fp, (sizeof(sls_detector_header) + bytes_per_part()) * frame_index, SEEK_SET); // NOLINT
|
||||
size_t const rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
|
||||
if (rc != 1)
|
||||
throw std::runtime_error("Could not read header from file");
|
||||
throw std::runtime_error(LOCATION + "Could not read header from file");
|
||||
if (fclose(fp)) {
|
||||
throw std::runtime_error(LOCATION + "Could not close file");
|
||||
}
|
||||
|
||||
return h.frameNumber;
|
||||
}
|
||||
|
@ -18,16 +18,16 @@ template <> simdjson_inline simdjson::simdjson_result<std::array<int, 4>> simdjs
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
std::array<int, 4> arr;
|
||||
std::array<int, 4> arr{};
|
||||
int i = 0;
|
||||
for (auto v : array) {
|
||||
int64_t val;
|
||||
int64_t val = 0;
|
||||
error = v.get_int64().get(val);
|
||||
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
arr[i++] = val;
|
||||
arr[i++] = static_cast<int>(val);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
@ -37,7 +37,7 @@ template <> simdjson_inline simdjson::simdjson_result<std::array<int, 4>> simdjs
|
||||
* adds a check for 32bit overflow
|
||||
*/
|
||||
template <> simdjson_inline simdjson::simdjson_result<uint32_t> simdjson::ondemand::value::get() noexcept {
|
||||
size_t val;
|
||||
size_t val = 0;
|
||||
auto error = get_uint64().get(val);
|
||||
if (error) {
|
||||
return error;
|
||||
@ -70,9 +70,9 @@ simdjson::ondemand::value::get() noexcept {
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
std::string_view key_view = field.unescaped_key();
|
||||
std::string key_str(key_view.data(), key_view.size());
|
||||
std::string_view value_view = field.value().get_string();
|
||||
std::string_view const key_view = field.unescaped_key();
|
||||
std::string const key_str(key_view.data(), key_view.size());
|
||||
std::string_view const value_view = field.value().get_string();
|
||||
map[key_str] = {value_view.data(), value_view.size()};
|
||||
}
|
||||
return map;
|
||||
@ -122,7 +122,7 @@ struct ZmqHeader {
|
||||
uint8_t detType{0};
|
||||
uint8_t version{0};
|
||||
/** if rows of image should be flipped */
|
||||
int flipRows{0};
|
||||
int64_t flipRows{0};
|
||||
/** quad type (eiger hardware specific) */
|
||||
uint32_t quad{0};
|
||||
/** true if complete image, else missing packets */
|
||||
|
@ -32,7 +32,7 @@ class ZmqSocket {
|
||||
std::string m_endpoint;
|
||||
int m_zmq_hwm{1000};
|
||||
int m_timeout_ms{1000};
|
||||
size_t m_potential_frame_size{1024 * 1024};
|
||||
size_t m_potential_frame_size{static_cast<size_t>(1024) * 1024};
|
||||
constexpr static size_t m_max_header_size = 1024;
|
||||
char *m_header_buffer = new char[m_max_header_size];
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ namespace aare {
|
||||
*/
|
||||
class ZmqSocketReceiver : public ZmqSocket {
|
||||
public:
|
||||
ZmqSocketReceiver(const std::string &endpoint);
|
||||
explicit ZmqSocketReceiver(const std::string &endpoint);
|
||||
void connect();
|
||||
std::vector<ZmqFrame> receive_n();
|
||||
|
||||
|
@ -12,7 +12,7 @@ namespace aare {
|
||||
*/
|
||||
class ZmqSocketSender : public ZmqSocket {
|
||||
public:
|
||||
ZmqSocketSender(const std::string &endpoint);
|
||||
explicit ZmqSocketSender(const std::string &endpoint);
|
||||
void bind();
|
||||
size_t send(const ZmqHeader &header, const std::byte *data, size_t size);
|
||||
size_t send(const ZmqFrame &zmq_frame);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace aare {
|
||||
|
||||
/**
|
||||
* @brief ZmqFrame structure
|
||||
* wrapper class to contain a ZmqHeader and a Frame
|
||||
@ -24,9 +25,9 @@ class NetworkError : public std::runtime_error {
|
||||
const char *m_msg;
|
||||
|
||||
public:
|
||||
NetworkError(const char *msg) : std::runtime_error(msg), m_msg(msg) {}
|
||||
NetworkError(const std::string msg) : std::runtime_error(msg) { m_msg = strdup(msg.c_str()); }
|
||||
virtual const char *what() const noexcept override { return m_msg; }
|
||||
explicit NetworkError(const char *msg) : std::runtime_error(msg), m_msg(msg) {}
|
||||
explicit NetworkError(const std::string &msg) : std::runtime_error(msg), m_msg(strdup(msg.c_str())) {}
|
||||
const char *what() const noexcept override { return m_msg; }
|
||||
};
|
||||
|
||||
} // namespace network_io
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#include "simdjson.h"
|
||||
|
||||
using namespace simdjson;
|
||||
|
||||
// helper functions to write json
|
||||
// append to string for better performance (not tested)
|
||||
|
||||
@ -37,11 +35,11 @@ void write_map(std::string &s, const std::string &key, const std::map<std::strin
|
||||
s += "\"";
|
||||
s += key;
|
||||
s += "\": {";
|
||||
for (auto &kv : value) {
|
||||
for (const auto &kv : value) {
|
||||
write_str(s, kv.first, kv.second);
|
||||
}
|
||||
// remove last comma or trailing spaces
|
||||
for (int i = s.size() - 1; i >= 0; i--) {
|
||||
for (size_t i = s.size() - 1; i > 0; i--) {
|
||||
if (s[i] == ',' or s[i] == ' ') {
|
||||
s.pop_back();
|
||||
} else
|
||||
@ -66,7 +64,7 @@ void write_array(std::string &s, const std::string &key, const std::array<int, 4
|
||||
namespace aare {
|
||||
|
||||
std::string ZmqHeader::to_string() const {
|
||||
std::string s = "";
|
||||
std::string s;
|
||||
s.reserve(1024);
|
||||
s += "{";
|
||||
write_digit(s, "data", data ? 1 : 0);
|
||||
@ -108,78 +106,79 @@ std::string ZmqHeader::to_string() const {
|
||||
return s;
|
||||
}
|
||||
|
||||
void ZmqHeader::from_string(std::string &s) {
|
||||
void ZmqHeader::from_string(std::string &s) { // NOLINT
|
||||
|
||||
simdjson::padded_string ps(s.c_str(), s.size());
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc = parser.iterate(ps);
|
||||
ondemand::object object = doc.get_object();
|
||||
simdjson::padded_string const ps(s.c_str(), s.size());
|
||||
simdjson::ondemand::parser parser;
|
||||
simdjson::ondemand::document doc = parser.iterate(ps);
|
||||
simdjson::ondemand::object object = doc.get_object();
|
||||
|
||||
for (auto field : object) {
|
||||
std::string_view key = field.unescaped_key();
|
||||
std::string_view const key = field.unescaped_key();
|
||||
|
||||
if (key == "data") {
|
||||
data = uint64_t(field.value()) ? true : false;
|
||||
data = static_cast<uint64_t>(field.value()) != 0;
|
||||
} else if (key == "jsonversion") {
|
||||
jsonversion = uint32_t(field.value());
|
||||
jsonversion = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "dynamicRange") {
|
||||
dynamicRange = uint32_t(field.value());
|
||||
dynamicRange = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "fileIndex") {
|
||||
fileIndex = uint64_t(field.value());
|
||||
fileIndex = static_cast<uint64_t>(field.value());
|
||||
} else if (key == "ndetx") {
|
||||
ndetx = uint32_t(field.value());
|
||||
ndetx = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "ndety") {
|
||||
ndety = uint32_t(field.value());
|
||||
ndety = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "npixelsx") {
|
||||
npixelsx = uint32_t(field.value());
|
||||
npixelsx = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "npixelsy") {
|
||||
npixelsy = uint32_t(field.value());
|
||||
npixelsy = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "size") {
|
||||
size = uint32_t(field.value());
|
||||
size = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "acqIndex") {
|
||||
acqIndex = uint64_t(field.value());
|
||||
acqIndex = static_cast<uint64_t>(field.value());
|
||||
} else if (key == "frameIndex") {
|
||||
frameIndex = uint64_t(field.value());
|
||||
frameIndex = static_cast<uint64_t>(field.value());
|
||||
} else if (key == "progress") {
|
||||
progress = field.value().get_double();
|
||||
} else if (key == "fname") {
|
||||
std::string_view tmp = field.value().get_string();
|
||||
std::string_view const tmp = field.value().get_string();
|
||||
fname = {tmp.begin(), tmp.end()};
|
||||
} else if (key == "frameNumber") {
|
||||
frameNumber = uint64_t(field.value());
|
||||
frameNumber = static_cast<uint64_t>(field.value());
|
||||
} else if (key == "expLength") {
|
||||
expLength = uint32_t(field.value());
|
||||
expLength = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "packetNumber") {
|
||||
packetNumber = uint32_t(field.value());
|
||||
packetNumber = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "detSpec1") {
|
||||
detSpec1 = uint64_t(field.value());
|
||||
detSpec1 = static_cast<uint64_t>(field.value());
|
||||
} else if (key == "timestamp") {
|
||||
timestamp = uint64_t(field.value());
|
||||
timestamp = static_cast<uint64_t>(field.value());
|
||||
} else if (key == "modId") {
|
||||
modId = uint32_t(field.value());
|
||||
modId = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "row") {
|
||||
row = uint32_t(field.value());
|
||||
row = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "column") {
|
||||
column = uint32_t(field.value());
|
||||
column = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "detSpec2") {
|
||||
detSpec2 = uint32_t(field.value());
|
||||
detSpec2 = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "detSpec3") {
|
||||
detSpec3 = uint32_t(field.value());
|
||||
detSpec3 = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "detSpec4") {
|
||||
detSpec4 = uint32_t(field.value());
|
||||
detSpec4 = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "detType") {
|
||||
detType = uint32_t(field.value());
|
||||
detType = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "version") {
|
||||
version = uint32_t(field.value());
|
||||
version = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "flipRows") {
|
||||
flipRows = uint32_t(field.value());
|
||||
flipRows = static_cast<int64_t>(field.value());
|
||||
} else if (key == "quad") {
|
||||
quad = uint32_t(field.value());
|
||||
quad = static_cast<uint32_t>(field.value());
|
||||
} else if (key == "completeImage") {
|
||||
completeImage = uint64_t(field.value()) ? true : false;
|
||||
completeImage = static_cast<uint64_t>(field.value()) != 0;
|
||||
} else if (key == "addJsonHeader") {
|
||||
addJsonHeader = std::map<std::string, std::string>(field.value());
|
||||
addJsonHeader = static_cast<std::map<std::string, std::string>>(field.value());
|
||||
} else if (key == "rx_roi") {
|
||||
rx_roi = std::array<int, 4>(field.value());
|
||||
rx_roi = static_cast<std::array<int, 4>>(field.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,13 @@ void ZmqSocketReceiver::connect() {
|
||||
fmt::print("Setting ZMQ_RCVHWM to {}\n", m_zmq_hwm);
|
||||
int rc = zmq_setsockopt(m_socket, ZMQ_RCVHWM, &m_zmq_hwm, sizeof(m_zmq_hwm)); // should be set before connect
|
||||
if (rc)
|
||||
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVHWM: {}", strerror(errno)));
|
||||
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVHWM: {}", zmq_strerror(errno)));
|
||||
|
||||
int bufsize = m_potential_frame_size * m_zmq_hwm;
|
||||
fmt::print("Setting ZMQ_RCVBUF to: {} MB\n", bufsize / (1024 * 1024));
|
||||
size_t bufsize = m_potential_frame_size * m_zmq_hwm;
|
||||
fmt::print("Setting ZMQ_RCVBUF to: {} MB\n", bufsize / (static_cast<size_t>(1024) * 1024));
|
||||
rc = zmq_setsockopt(m_socket, ZMQ_RCVBUF, &bufsize, sizeof(bufsize));
|
||||
if (rc)
|
||||
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVBUF: {}", strerror(errno)));
|
||||
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVBUF: {}", zmq_strerror(errno)));
|
||||
|
||||
zmq_connect(m_socket, m_endpoint.c_str());
|
||||
zmq_setsockopt(m_socket, ZMQ_SUBSCRIBE, "", 0);
|
||||
@ -44,7 +44,7 @@ ZmqHeader ZmqSocketReceiver::receive_header() {
|
||||
|
||||
// receive string ZmqHeader
|
||||
aare::logger::debug("Receiving header");
|
||||
size_t header_bytes_received = zmq_recv(m_socket, m_header_buffer, m_max_header_size, 0);
|
||||
int const header_bytes_received = zmq_recv(m_socket, m_header_buffer, m_max_header_size, 0);
|
||||
aare::logger::debug("Bytes: ", header_bytes_received);
|
||||
|
||||
m_header_buffer[header_bytes_received] = '\0'; // make sure we zero terminate
|
||||
@ -71,9 +71,9 @@ ZmqHeader ZmqSocketReceiver::receive_header() {
|
||||
* @return ZmqHeader
|
||||
*/
|
||||
int ZmqSocketReceiver::receive_data(std::byte *data, size_t size) {
|
||||
int data_bytes_received = zmq_recv(m_socket, data, size, 0);
|
||||
int const data_bytes_received = zmq_recv(m_socket, data, size, 0);
|
||||
if (data_bytes_received == -1)
|
||||
network_io::NetworkError("Got half of a multipart msg!!!");
|
||||
throw network_io::NetworkError("Got half of a multipart msg!!!");
|
||||
aare::logger::debug("Bytes: ", data_bytes_received);
|
||||
|
||||
return data_bytes_received;
|
||||
@ -98,7 +98,7 @@ ZmqFrame ZmqSocketReceiver::receive_zmqframe() {
|
||||
if (bytes_received == -1) {
|
||||
throw network_io::NetworkError(LOCATION + "Error receiving frame");
|
||||
}
|
||||
if ((uint32_t)bytes_received != header.size) {
|
||||
if (static_cast<uint32_t>(bytes_received) != header.size) {
|
||||
throw network_io::NetworkError(
|
||||
fmt::format("{} Expected {} bytes but received {}", LOCATION, header.size, bytes_received));
|
||||
}
|
||||
@ -113,7 +113,7 @@ std::vector<ZmqFrame> ZmqSocketReceiver::receive_n() {
|
||||
std::vector<ZmqFrame> frames;
|
||||
while (true) {
|
||||
// receive header and frame
|
||||
ZmqFrame zmq_frame = receive_zmqframe();
|
||||
ZmqFrame const zmq_frame = receive_zmqframe();
|
||||
if (!zmq_frame.header.data) {
|
||||
break;
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ ZmqSocketSender::ZmqSocketSender(const std::string &endpoint) { m_endpoint = end
|
||||
void ZmqSocketSender::bind() {
|
||||
m_context = zmq_ctx_new();
|
||||
m_socket = zmq_socket(m_context, ZMQ_PUB);
|
||||
size_t rc = zmq_bind(m_socket, m_endpoint.c_str());
|
||||
size_t const rc = zmq_bind(m_socket, m_endpoint.c_str());
|
||||
if (rc != 0) {
|
||||
std::string error = zmq_strerror(zmq_errno());
|
||||
std::string const error = zmq_strerror(zmq_errno());
|
||||
throw network_io::NetworkError("zmq_bind failed: " + error);
|
||||
}
|
||||
}
|
||||
@ -31,11 +31,11 @@ void ZmqSocketSender::bind() {
|
||||
* @return number of bytes sent
|
||||
*/
|
||||
size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, size_t size) {
|
||||
size_t rc;
|
||||
size_t rc = 0;
|
||||
// if (serialize_header) {
|
||||
// rc = zmq_send(m_socket, &header, sizeof(ZmqHeader), ZMQ_SNDMORE);
|
||||
// assert(rc == sizeof(ZmqHeader));
|
||||
std::string header_str = header.to_string();
|
||||
std::string const header_str = header.to_string();
|
||||
aare::logger::debug("Header :", header_str);
|
||||
rc = zmq_send(m_socket, header_str.c_str(), header_str.size(), ZMQ_SNDMORE);
|
||||
assert(rc == header_str.size());
|
||||
@ -43,7 +43,7 @@ size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, siz
|
||||
return rc;
|
||||
}
|
||||
|
||||
size_t rc2 = zmq_send(m_socket, data, size, 0);
|
||||
size_t const rc2 = zmq_send(m_socket, data, size, 0);
|
||||
assert(rc2 == size);
|
||||
return rc + rc2;
|
||||
}
|
||||
@ -56,11 +56,11 @@ size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, siz
|
||||
size_t ZmqSocketSender::send(const ZmqFrame &zmq_frame) {
|
||||
const Frame &frame = zmq_frame.frame;
|
||||
// send frame
|
||||
size_t rc = send(zmq_frame.header, frame.data(), frame.size());
|
||||
size_t const rc = send(zmq_frame.header, frame.data(), frame.size());
|
||||
// send end of message header
|
||||
ZmqHeader end_header = zmq_frame.header;
|
||||
end_header.data = false;
|
||||
size_t rc2 = send(end_header, nullptr, 0);
|
||||
size_t const rc2 = send(end_header, nullptr, 0);
|
||||
|
||||
return rc + rc2;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
template <typename T> std::ostream &operator<<(std::ostream &out, const std::vector<T> &v) {
|
||||
out << "[";
|
||||
size_t last = v.size() - 1;
|
||||
size_t const last = v.size() - 1;
|
||||
for (size_t i = 0; i < v.size(); ++i) {
|
||||
out << v[i];
|
||||
if (i != last)
|
||||
@ -71,9 +71,7 @@ template <typename K, typename V> std::ostream &operator<<(std::ostream &out, co
|
||||
return out;
|
||||
}
|
||||
|
||||
namespace aare {
|
||||
|
||||
namespace logger {
|
||||
namespace aare::logger {
|
||||
/**
|
||||
* @brief enum to define the logging level
|
||||
*/
|
||||
@ -96,17 +94,14 @@ class Logger {
|
||||
/**
|
||||
* @brief get the instance of the logger
|
||||
*/
|
||||
Logger() {
|
||||
standard_output = new std::ostream(standard_buf);
|
||||
error_output = new std::ostream(error_buf);
|
||||
}
|
||||
Logger() : standard_output(new std::ostream(standard_buf)), error_output(new std::ostream(error_buf)) {} // NOLINT
|
||||
|
||||
/**
|
||||
* @brief set the output file for the logger by filename
|
||||
* @param filename name of the file to log to
|
||||
* @return void
|
||||
*/
|
||||
void set_output_file(std::string filename) {
|
||||
void set_output_file(const std::string &filename) {
|
||||
if (out_file.is_open())
|
||||
out_file.close();
|
||||
out_file.open(filename);
|
||||
@ -152,6 +147,10 @@ class Logger {
|
||||
delete standard_output;
|
||||
delete error_output;
|
||||
}
|
||||
Logger(Logger &&) noexcept = default;
|
||||
Logger(const Logger &) = delete;
|
||||
Logger &operator=(Logger &&) noexcept = default;
|
||||
Logger &operator=(const Logger &) = delete;
|
||||
|
||||
/**
|
||||
* @brief log a message
|
||||
@ -199,9 +198,9 @@ class Logger {
|
||||
*/
|
||||
template <LOGGING_LEVEL level> void log_() {
|
||||
if (level == LOGGING_LEVEL::ERROR) {
|
||||
*error_output << std::endl;
|
||||
*error_output << std::endl; // NOLINT
|
||||
} else {
|
||||
*standard_output << std::endl;
|
||||
*standard_output << std::endl; // NOLINT
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,10 +216,8 @@ class Logger {
|
||||
template <LOGGING_LEVEL level, typename First, typename... Strings> void log_(First arg, const Strings... s) {
|
||||
if (level == LOGGING_LEVEL::ERROR) {
|
||||
*error_output << (arg) << ' ';
|
||||
error_output->flush();
|
||||
} else {
|
||||
*standard_output << (arg) << ' ';
|
||||
standard_output->flush();
|
||||
}
|
||||
log_<level>(s...);
|
||||
}
|
||||
@ -230,7 +227,7 @@ namespace internal {
|
||||
/**
|
||||
* @brief global instance of the logger
|
||||
*/
|
||||
extern aare::logger::Logger logger_instance;
|
||||
extern aare::logger::Logger logger_instance; // NOLINT
|
||||
} // namespace internal
|
||||
|
||||
/**
|
||||
@ -270,9 +267,7 @@ template <typename... Strings> void error(const Strings... s) { internal::logger
|
||||
extern void set_streams(std::streambuf *out, std::streambuf *err);
|
||||
extern void set_streams(std::streambuf *out);
|
||||
extern void set_verbosity(LOGGING_LEVEL level);
|
||||
extern void set_output_file(std::string filename);
|
||||
extern void set_output_file(const std::string &filename);
|
||||
extern Logger &get_logger_instance();
|
||||
|
||||
} // namespace logger
|
||||
|
||||
} // namespace aare
|
||||
} // namespace aare::logger
|
||||
|
@ -1,14 +1,12 @@
|
||||
#include "aare/utils/logger.hpp"
|
||||
|
||||
namespace aare {
|
||||
namespace logger {
|
||||
namespace aare::logger {
|
||||
namespace internal {
|
||||
aare::logger::Logger logger_instance = aare::logger::Logger();
|
||||
aare::logger::Logger logger_instance = aare::logger::Logger(); // NOLINT
|
||||
} // namespace internal
|
||||
void set_streams(std::streambuf *out, std::streambuf *err) { internal::logger_instance.set_streams(out, err); }
|
||||
void set_streams(std::streambuf *out) { internal::logger_instance.set_streams(out); }
|
||||
void set_verbosity(LOGGING_LEVEL level) { internal::logger_instance.set_verbosity(level); }
|
||||
Logger &get_logger_instance() { return internal::logger_instance; }
|
||||
void set_output_file(std::string filename) { internal::logger_instance.set_output_file(filename); }
|
||||
} // namespace logger
|
||||
} // namespace aare
|
||||
void set_output_file(const std::string &filename) { internal::logger_instance.set_output_file(filename); }
|
||||
} // namespace aare::logger
|
||||
|
Reference in New Issue
Block a user