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:
Bechir Braham
2024-04-12 17:35:36 +02:00
committed by GitHub
parent eb7108b837
commit 9dfd388927
44 changed files with 1055 additions and 470 deletions

493
.clang-tidy Normal file
View 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
View 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

View File

@ -19,7 +19,7 @@ jobs:
build-and-test: build-and-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: mamba-org/setup-micromamba@v1 - uses: mamba-org/setup-micromamba@v1
if: ${{ contains(inputs.use-system-libraries, 'ON')}} if: ${{ contains(inputs.use-system-libraries, 'ON')}}
with: with:

View File

@ -6,14 +6,27 @@ jobs:
test-formatting: test-formatting:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: check if files are formatted - uses: mamba-org/setup-micromamba@v1
# find all examples in build/examples and run them 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: | run: |
pwd
mkdir build mkdir build
cd 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

View File

@ -206,3 +206,12 @@ add_custom_target(
COMMENT "Formatting with clang-format" COMMENT "Formatting with clang-format"
VERBATIM 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
)

View File

@ -26,7 +26,7 @@ enum class endian {
*/ */
class DType { class DType {
// TODO! support for non native endianess? // 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: public:
enum TypeIndex { INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT, DOUBLE, ERROR }; 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); explicit DType(std::string_view sv);
// not explicit to allow conversions form enum to DType // 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;
bool operator!=(const DType &other) const noexcept; bool operator!=(const DType &other) const noexcept;

View File

@ -4,7 +4,6 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <sys/types.h>
#include <vector> #include <vector>
namespace aare { namespace aare {
@ -15,59 +14,73 @@ namespace aare {
* should be able to work with streams coming from files or network * should be able to work with streams coming from files or network
*/ */
class Frame { class Frame {
ssize_t m_rows; size_t m_rows;
ssize_t m_cols; size_t m_cols;
ssize_t m_bitdepth; size_t m_bitdepth;
std::byte *m_data; std::byte *m_data;
public: public:
Frame(ssize_t rows, ssize_t cols, ssize_t m_bitdepth); Frame(size_t rows, size_t cols, size_t m_bitdepth);
Frame(std::byte *fp, ssize_t rows, ssize_t cols, ssize_t m_bitdepth); Frame(std::byte *bytes, size_t rows, size_t cols, size_t m_bitdepth);
std::byte *get(int row, int col); std::byte *get(size_t row, size_t col);
// TODO! can we, or even want to remove the template? // 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); 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"); 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); std::memcpy(m_data + (row * m_cols + col) * (m_bitdepth / 8), &data, m_bitdepth / 8);
} }
ssize_t rows() const { return m_rows; } size_t rows() const { return m_rows; }
ssize_t cols() const { return m_cols; } size_t cols() const { return m_cols; }
ssize_t bitdepth() const { return m_bitdepth; } size_t bitdepth() const { return m_bitdepth; }
ssize_t size() const { return m_rows * m_cols * m_bitdepth / 8; } size_t size() const { return m_rows * m_cols * m_bitdepth / 8; }
std::byte *data() const { return m_data; } 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_rows = other.rows();
m_cols = other.cols(); m_cols = other.cols();
m_bitdepth = other.bitdepth(); m_bitdepth = other.bitdepth();
m_data = new std::byte[m_rows * m_cols * m_bitdepth / 8]; 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); std::memcpy(m_data, other.m_data, m_rows * m_cols * m_bitdepth / 8);
return *this; return *this;
} }
// add move constructor
Frame(Frame &&other) { Frame &operator=(Frame &&other) noexcept {
m_rows = other.rows(); m_rows = other.rows();
m_cols = other.cols(); m_cols = other.cols();
m_bitdepth = other.bitdepth(); m_bitdepth = other.bitdepth();
m_data = other.m_data; m_data = other.m_data;
other.m_data = nullptr; other.m_data = nullptr;
other.m_rows = other.m_cols = other.m_bitdepth = 0; 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 // copy constructor
Frame(const Frame &other) { Frame(const Frame &other)
m_rows = other.rows(); : m_rows(other.rows()), m_cols(other.cols()), m_bitdepth(other.bitdepth()),
m_cols = other.cols(); m_data(new std::byte[m_rows * m_cols * m_bitdepth / 8]) {
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); std::memcpy(m_data, other.m_data, m_rows * m_cols * m_bitdepth / 8);
} }
template <typename T> NDView<T> view() { 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); T *data = reinterpret_cast<T *>(m_data);
return NDView<T>(data, shape); return NDView<T>(data, shape);
} }

View File

@ -22,25 +22,25 @@ namespace aare {
template <typename T, ssize_t Ndim = 2> class NDArray { template <typename T, ssize_t Ndim = 2> class NDArray {
public: 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) explicit NDArray(std::array<ssize_t, Ndim> shape)
: shape_(shape), strides_(c_strides<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); } 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 /* 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 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()); std::copy(span.begin(), span.end(), begin());
// fmt::print("NDArray(NDView<T, Ndim> span)\n"); // fmt::print("NDArray(NDView<T, Ndim> span)\n");
} }
// Move constructor // Move constructor
NDArray(NDArray &&other) NDArray(NDArray &&other) noexcept
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(nullptr) { : shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(other.data_) {
data_ = other.data_;
other.reset(); other.reset();
// fmt::print("NDArray(NDArray &&other)\n"); // fmt::print("NDArray(NDArray &&other)\n");
} }
@ -59,7 +59,7 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
using value_type = T; 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); // Copy assign
NDArray operator+(const NDArray &other); NDArray operator+(const NDArray &other);
@ -77,9 +77,8 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
data_[i] /= other(i); data_[i] /= other(i);
} }
return *this; 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); 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;
bool operator!=(const NDArray &other) const; bool operator!=(const NDArray &other) const;
NDArray &operator=(const T &); NDArray &operator=(const T & /*value*/);
NDArray &operator+=(const T &); NDArray &operator+=(const T & /*value*/);
NDArray operator+(const T &); NDArray operator+(const T & /*value*/);
NDArray &operator-=(const T &); NDArray &operator-=(const T & /*value*/);
NDArray operator-(const T &); NDArray operator-(const T & /*value*/);
NDArray &operator*=(const T &); NDArray &operator*=(const T & /*value*/);
NDArray operator*(const T &); NDArray operator*(const T & /*value*/);
NDArray &operator/=(const T &); NDArray &operator/=(const T & /*value*/);
NDArray operator/(const T &); NDArray operator/(const T & /*value*/);
NDArray &operator&=(const T &); NDArray &operator&=(const T & /*mask*/);
void sqrt() { void sqrt() {
for (int i = 0; i < size_; ++i) { for (int i = 0; i < size_; ++i) {
@ -107,15 +106,15 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
NDArray &operator++(); // pre inc 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...)]; 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...)]; 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...)]; return data_[element_offset(strides_, index...)];
} }
@ -153,12 +152,12 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
private: private:
std::array<ssize_t, Ndim> shape_; std::array<ssize_t, Ndim> shape_;
std::array<ssize_t, Ndim> strides_; std::array<ssize_t, Ndim> strides_;
ssize_t size_; ssize_t size_{};
T *data_; T *data_;
}; };
// Move assign // 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) { if (this != &other) {
delete[] data_; delete[] data_;
data_ = other.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]; data_[i] += other.data_[i];
} }
return *this; 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) { 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]; data_[i] -= other.data_[i];
} }
return *this; 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) { template <typename T, ssize_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const NDArray &other) {
NDArray result = *this; 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]; data_[i] *= other.data_[i];
} }
return *this; 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) { 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]); result(i) = (data_[i] > other.data_[i]);
} }
return result; 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) { 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; std::ofstream f;
f.open(pathname, std::ios::binary); f.open(pathname, std::ios::binary);
f.write(img.buffer(), img.size() * sizeof(T)); f.write(img.buffer(), img.size() * sizeof(T));

View File

@ -20,7 +20,7 @@ template <ssize_t Ndim> Shape<Ndim> make_shape(const std::vector<size_t> &shape)
return arr; 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> template <ssize_t Dim = 0, typename Strides, typename... Ix>
ssize_t element_offset(const Strides &strides, ssize_t i, Ix... index) { 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) { 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); std::fill(strides.begin(), strides.end(), 1);
for (ssize_t i = Ndim - 1; i > 0; --i) { for (ssize_t i = Ndim - 1; i > 0; --i) {
strides[i - 1] = strides[i] * shape[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) { template <ssize_t Ndim> std::array<ssize_t, Ndim> make_array(const std::vector<ssize_t> &vec) {
assert(vec.size() == Ndim); assert(vec.size() == Ndim);
std::array<ssize_t, Ndim> arr; std::array<ssize_t, Ndim> arr{};
std::copy_n(vec.begin(), Ndim, arr.begin()); std::copy_n(vec.begin(), Ndim, arr.begin());
return arr; return arr;
} }
template <typename T, ssize_t Ndim = 2> class NDView { template <typename T, ssize_t Ndim = 2> class NDView {
public: public:
NDView(){}; NDView() = default;
~NDView() = default;
NDView(const NDView &) = default;
NDView(NDView &&) = default;
NDView(T *buffer, std::array<ssize_t, Ndim> shape) { NDView(T *buffer, std::array<ssize_t, Ndim> shape)
buffer_ = buffer; : buffer_(buffer), strides_(c_strides<Ndim>(shape)), shape_(shape),
strides_ = c_strides<Ndim>(shape); size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
shape_ = shape;
size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
}
NDView(T *buffer, const std::vector<ssize_t> &shape) { NDView(T *buffer, const std::vector<ssize_t> &shape)
buffer_ = buffer; : buffer_(buffer), strides_(c_strides<Ndim>(make_array<Ndim>(shape))), shape_(make_array<Ndim>(shape)),
strides_ = c_strides<Ndim>(make_array<Ndim>(shape)); size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
shape_ = make_array<Ndim>(shape);
size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
}
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...)]; 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...)]; return buffer_[element_offset(strides_, index...)];
} }
ssize_t size() const { return size_; } ssize_t size() const { return size_; }
NDView(const NDView &) = default;
NDView(NDView &&) = default;
T *begin() { return buffer_; } T *begin() { return buffer_; }
T *end() { return buffer_ + size_; } T *end() { return buffer_ + size_; }
T &operator()(ssize_t i) { return buffer_[i]; } 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) { NDView &operator=(const NDView &other) {
if (this == &other)
return *this;
shape_ = other.shape_; shape_ = other.shape_;
strides_ = other.strides_; strides_ = other.strides_;
size_ = other.size_; size_ = other.size_;
buffer_ = other.buffer_; buffer_ = other.buffer_;
return *this; 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() { return shape_; }
auto shape(ssize_t i) const { return shape_[i]; } auto shape(ssize_t i) const { return shape_[i]; }

View File

@ -28,7 +28,7 @@ struct sls_detector_header {
uint16_t roundRNumber; uint16_t roundRNumber;
uint8_t detType; uint8_t detType;
uint8_t version; uint8_t version;
uint8_t packetMask[64]; std::array<uint8_t, 64> packetMask;
}; };
struct xy { struct xy {
@ -44,14 +44,14 @@ enum class DetectorType { Jungfrau, Eiger, Mythen3, Moench, ChipTestBoard };
enum class TimingMode { Auto, Trigger }; 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 <> DetectorType StringTo(const std::string & /*name*/);
template <> std::string toString(DetectorType type); 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>; using DataTypeVariants = std::variant<uint16_t, uint32_t>;

View File

@ -1,8 +1,7 @@
#include "aare/core/DType.hpp" #include "aare/core/DType.hpp"
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
#include <fmt/core.h>
#include <fmt/format.h>
namespace aare { namespace aare {
@ -26,9 +25,7 @@ DType::DType(const std::type_info &t) {
m_type = TypeIndex::INT32; m_type = TypeIndex::INT32;
else if (t == typeid(uint32_t)) else if (t == typeid(uint32_t))
m_type = TypeIndex::UINT32; m_type = TypeIndex::UINT32;
else if (t == typeid(int64_t)) else if (t == typeid(int64_t) || t == typeid(long)) // NOLINT
m_type = TypeIndex::INT64;
else if (t == typeid(long))
m_type = TypeIndex::INT64; m_type = TypeIndex::INT64;
else if (t == typeid(uint64_t)) else if (t == typeid(uint64_t))
m_type = TypeIndex::UINT64; m_type = TypeIndex::UINT64;
@ -130,7 +127,7 @@ DType::DType(std::string_view sv) {
*/ */
std::string DType::str() const { std::string DType::str() const {
char ec; char ec{};
if (endian::native == endian::little) if (endian::native == endian::little)
ec = '<'; ec = '<';
else else

View File

@ -1,7 +1,8 @@
#include "aare/core/Frame.hpp" #include "aare/core/Frame.hpp"
#include "aare/utils/logger.hpp" #include <cstddef>
#include <cassert> #include <cstring>
#include <iostream> #include <iostream>
#include <sys/types.h>
namespace aare { namespace aare {
@ -12,9 +13,9 @@ namespace aare {
* @param cols number of columns * @param cols number of columns
* @param bitdepth bitdepth of the pixels * @param bitdepth bitdepth of the pixels
*/ */
Frame::Frame(std::byte *bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth) Frame::Frame(std::byte *bytes, size_t rows, size_t cols, size_t bitdepth)
: m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) { : m_rows(rows), m_cols(cols), m_bitdepth(bitdepth), m_data(new std::byte[rows * cols * bitdepth / 8]) {
m_data = new std::byte[rows * cols * bitdepth / 8];
std::memcpy(m_data, bytes, 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 * @param bitdepth bitdepth of the pixels
* @note the data is initialized to zero * @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) { Frame::Frame(size_t rows, size_t cols, size_t bitdepth)
m_data = new std::byte[rows * cols * bitdepth / 8]; : 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); 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 * @return pointer to the pixel
* @note the user should cast the pointer to the appropriate type * @note the user should cast the pointer to the appropriate type
*/ */
std::byte *Frame::get(int row, int col) { std::byte *Frame::get(size_t row, size_t col) {
if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) { if (row >= m_rows or col >= m_cols) {
std::cerr << "Invalid row or column index" << std::endl; std::cerr << "Invalid row or column index" << '\n';
return 0; return nullptr;
} }
return m_data + (row * m_cols + col) * (m_bitdepth / 8); return m_data + (row * m_cols + col) * (m_bitdepth / 8);
} }

View File

@ -1,4 +1,6 @@
#include "aare/core/defs.hpp" #include "aare/core/defs.hpp"
#include <stdexcept>
#include <string>
namespace aare { namespace aare {
@ -7,8 +9,8 @@ namespace aare {
* @param type DetectorType * @param type DetectorType
* @return string representation of the DetectorType * @return string representation of the DetectorType
*/ */
template <> std::string toString(DetectorType type) { template <> std::string toString(DetectorType arg) {
switch (type) { switch (arg) {
case DetectorType::Jungfrau: case DetectorType::Jungfrau:
return "Jungfrau"; return "Jungfrau";
case DetectorType::Eiger: case DetectorType::Eiger:
@ -30,20 +32,18 @@ template <> std::string toString(DetectorType type) {
* @return DetectorType * @return DetectorType
* @throw runtime_error if the string does not match any DetectorType * @throw runtime_error if the string does not match any DetectorType
*/ */
template <> DetectorType StringTo(std::string name) { template <> DetectorType StringTo(const std::string &arg) {
if (name == "Jungfrau") if (arg == "Jungfrau")
return DetectorType::Jungfrau; return DetectorType::Jungfrau;
else if (name == "Eiger") if (arg == "Eiger")
return DetectorType::Eiger; return DetectorType::Eiger;
else if (name == "Mythen3") if (arg == "Mythen3")
return DetectorType::Mythen3; return DetectorType::Mythen3;
else if (name == "Moench") if (arg == "Moench")
return DetectorType::Moench; return DetectorType::Moench;
else if (name == "ChipTestBoard") if (arg == "ChipTestBoard")
return DetectorType::ChipTestBoard; return DetectorType::ChipTestBoard;
else { throw std::runtime_error("Could not decode dector from: \"" + arg + "\"");
throw std::runtime_error("Could not decode dector from: \"" + name + "\"");
}
} }
/** /**
@ -52,14 +52,12 @@ template <> DetectorType StringTo(std::string name) {
* @return TimingMode * @return TimingMode
* @throw runtime_error if the string does not match any TimingMode * @throw runtime_error if the string does not match any TimingMode
*/ */
template <> TimingMode StringTo(std::string mode) { template <> TimingMode StringTo(const std::string &arg) {
if (mode == "auto") if (arg == "auto")
return TimingMode::Auto; return TimingMode::Auto;
else if (mode == "trigger") if (arg == "trigger")
return TimingMode::Trigger; return TimingMode::Trigger;
else { throw std::runtime_error("Could not decode timing mode from: \"" + arg + "\"");
throw std::runtime_error("Could not decode timing mode from: \"" + mode + "\"");
}
} }
// template <> TimingMode StringTo<TimingMode>(std::string mode); // template <> TimingMode StringTo<TimingMode>(std::string mode);

View File

@ -4,9 +4,9 @@
using aare::Frame; using aare::Frame;
TEST_CASE("Construct a frame") { TEST_CASE("Construct a frame") {
ssize_t rows = 10; size_t rows = 10;
ssize_t cols = 10; size_t cols = 10;
ssize_t bitdepth = 8; size_t bitdepth = 8;
Frame frame(rows, cols, bitdepth); Frame frame(rows, cols, bitdepth);
@ -16,8 +16,8 @@ TEST_CASE("Construct a frame") {
REQUIRE(frame.size() == rows * cols * bitdepth / 8); REQUIRE(frame.size() == rows * cols * bitdepth / 8);
// data should be initialized to 0 // data should be initialized to 0
for (int i = 0; i < rows; i++) { for (size_t i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) { for (size_t j = 0; j < cols; j++) {
uint8_t *data = (uint8_t *)frame.get(i, j); uint8_t *data = (uint8_t *)frame.get(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
REQUIRE(*data == 0); REQUIRE(*data == 0);
@ -26,9 +26,9 @@ TEST_CASE("Construct a frame") {
} }
TEST_CASE("Set a value in a 8 bit frame") { TEST_CASE("Set a value in a 8 bit frame") {
ssize_t rows = 10; size_t rows = 10;
ssize_t cols = 10; size_t cols = 10;
ssize_t bitdepth = 8; size_t bitdepth = 8;
Frame frame(rows, cols, bitdepth); Frame frame(rows, cols, bitdepth);
@ -37,8 +37,8 @@ TEST_CASE("Set a value in a 8 bit frame") {
frame.set(5, 7, value); frame.set(5, 7, value);
// only the value we did set should be non-zero // only the value we did set should be non-zero
for (int i = 0; i < rows; i++) { for (size_t i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) { for (size_t j = 0; j < cols; j++) {
uint8_t *data = (uint8_t *)frame.get(i, j); uint8_t *data = (uint8_t *)frame.get(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
if (i == 5 && j == 7) { 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") { TEST_CASE("Set a value in a 64 bit frame") {
ssize_t rows = 10; size_t rows = 10;
ssize_t cols = 10; size_t cols = 10;
ssize_t bitdepth = 64; size_t bitdepth = 64;
Frame frame(rows, cols, bitdepth); Frame frame(rows, cols, bitdepth);
@ -62,8 +62,8 @@ TEST_CASE("Set a value in a 64 bit frame") {
frame.set(5, 7, value); frame.set(5, 7, value);
// only the value we did set should be non-zero // only the value we did set should be non-zero
for (int i = 0; i < rows; i++) { for (size_t i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) { for (size_t j = 0; j < cols; j++) {
uint64_t *data = (uint64_t *)frame.get(i, j); uint64_t *data = (uint64_t *)frame.get(i, j);
REQUIRE(data != nullptr); REQUIRE(data != nullptr);
if (i == 5 && j == 7) { 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") { TEST_CASE("Move construct a frame") {
ssize_t rows = 10; size_t rows = 10;
ssize_t cols = 10; size_t cols = 10;
ssize_t bitdepth = 8; size_t bitdepth = 8;
Frame frame(rows, cols, bitdepth); Frame frame(rows, cols, bitdepth);
std::byte *data = frame.data(); std::byte *data = frame.data();

View File

@ -9,18 +9,18 @@ using aare::File;
using aare::Frame; using aare::Frame;
void test(File &f, int frame_number) { 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); Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(1, 0))) << '\n';
std::cout << *((uint16_t *)frame.get(511, 1023)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(511, 1023))) << '\n';
} }
int main() { int main() {
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); 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::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_single_master_0.json");
std::cout << fpath << std::endl; std::cout << fpath << '\n';
File file(fpath, "r"); File file(fpath, "r");
test(file, 0); test(file, 0);

View File

@ -9,19 +9,19 @@ using aare::File;
using aare::Frame; using aare::Frame;
void test(File &f, int frame_number) { 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); Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *((uint16_t *)frame.get(255, 1023)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(255, 1023))) << '\n';
std::cout << *((uint16_t *)frame.get(511, 1023)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(511, 1023))) << '\n';
} }
int main() { int main() {
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); 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::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_double_master_0.json");
std::cout << fpath << std::endl; std::cout << fpath << '\n';
File file(fpath, "r"); File file(fpath, "r");
test(file, 0); test(file, 0);

View File

@ -9,14 +9,14 @@ using aare::File;
using aare::Frame; using aare::Frame;
void test1(File &f, int frame_number) { 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); Frame frame = f.iread(frame_number);
std::cout << *((uint32_t *)frame.get(0, 0)) << std::endl; std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 0))) << '\n';
std::cout << *((uint32_t *)frame.get(0, 1)) << std::endl; std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1))) << '\n';
std::cout << *((uint32_t *)frame.get(0, 3839)) << std::endl; std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 3839))) << '\n';
for (int i = 0; i < 3840; i++) { 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) { if (x != i) {
aare::logger::error("error at i", i, "x", x); 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) { 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); Frame frame = f.iread(frame_number);
std::cout << *((uint32_t *)frame.get(0, 0)) << std::endl; std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 0))) << '\n';
std::cout << *((uint32_t *)frame.get(0, 1)) << std::endl; std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1))) << '\n';
std::cout << *((uint32_t *)frame.get(0, 1280 * 4 - 1)) << std::endl; std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1280 * 4 - 1))) << '\n';
} }
int main() { int main() {

View File

@ -8,19 +8,19 @@ using aare::File;
using aare::Frame; using aare::Frame;
void test(File &f, int frame_number) { 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); Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(1, 0))) << '\n';
std::cout << *((uint16_t *)frame.get(49, 49)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(49, 49))) << '\n';
} }
int main() { int main() {
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); 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::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "numpy" / "test_numpy_file.npy");
std::cout << fpath << std::endl; std::cout << fpath << '\n';
File file(fpath, "r"); File file(fpath, "r");
test(file, 0); test(file, 0);

View File

@ -12,7 +12,7 @@ using aare::Frame;
int main() { int main() {
auto path = std::filesystem::path("/tmp/test.npy"); auto path = std::filesystem::path("/tmp/test.npy");
auto dtype = aare::DType(typeid(uint32_t)); auto dtype = aare::DType(typeid(uint32_t));
FileConfig cfg = {dtype, 100, 100}; FileConfig const cfg = {dtype, 100, 100};
File npy(path, "w", cfg); File npy(path, "w", cfg);
Frame f(100, 100, dtype.bitdepth()); Frame f(100, 100, dtype.bitdepth());
for (int i = 0; i < 10000; i++) { for (int i = 0; i < 10000; i++) {

View File

@ -9,11 +9,11 @@ using aare::File;
using aare::Frame; using aare::Frame;
void test(File &f, int frame_number) { 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); Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *((uint16_t *)frame.get(0, 95)) << std::endl; std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 95))) << '\n';
} }
int main() { int main() {
@ -21,7 +21,7 @@ int main() {
if (PROJECT_ROOT_DIR.empty()) { if (PROJECT_ROOT_DIR.empty()) {
throw std::runtime_error("environment variable PROJECT_ROOT_DIR is not set"); 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"); "moench04_noise_200V_sto_both_100us_no_light_thresh_900_master_0.raw");
File file(fpath, "r"); File file(fpath, "r");
test(file, 0); test(file, 0);

View File

@ -35,7 +35,7 @@ int main(int argc, char **argv) {
auto port = vm["port"].as<uint16_t>(); 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); aare::ZmqSocketReceiver socket(endpoint);
socket.connect(); socket.connect();
while (true) { while (true) {

View File

@ -48,10 +48,10 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
std::string path = vm["file"].as<string>(); std::string const path = vm["file"].as<string>();
uint16_t port = vm["port"].as<uint16_t>(); uint16_t const port = vm["port"].as<uint16_t>();
bool loop = vm.count("loop") == 1 ? true : false; bool const loop = vm.count("loop") == 1;
uint16_t fps = vm["fps"].as<uint16_t>(); uint16_t const fps = vm["fps"].as<uint16_t>();
aare::logger::debug("ARGS: file:", path, "port:", port, "fps:", fps, "loop:", loop); aare::logger::debug("ARGS: file:", path, "port:", port, "fps:", fps, "loop:", loop);
auto d = round<std::chrono::milliseconds>(std::chrono::duration<double>{1. / fps}); auto d = round<std::chrono::milliseconds>(std::chrono::duration<double>{1. / fps});
@ -62,17 +62,17 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
std::filesystem::path tmp(path); std::filesystem::path const tmp(path);
File file(tmp, "r"); File file(tmp, "r");
string endpoint = "tcp://*:" + std::to_string(port); string const endpoint = "tcp://*:" + std::to_string(port);
ZmqSocketSender sender(endpoint); ZmqSocketSender sender(endpoint);
sender.bind(); sender.bind();
std::this_thread::sleep_for(d); // slow joiner problem should fix this std::this_thread::sleep_for(d); // slow joiner problem should fix this
for (size_t frameidx = 0; frameidx < file.total_frames(); frameidx++) { for (size_t frameidx = 0; frameidx < file.total_frames(); frameidx++) {
Frame frame = file.read(); Frame const frame = file.read();
ZmqHeader header; ZmqHeader header;
header.frameNumber = frameidx; header.frameNumber = frameidx;
header.data = true; header.data = true;

View File

@ -12,7 +12,7 @@ using namespace aare;
int main() { int main() {
std::srand(std::time(nullptr)); std::srand(std::time(nullptr));
std::string endpoint = "tcp://*:5555"; std::string const endpoint = "tcp://*:5555";
aare::ZmqSocketSender socket(endpoint); aare::ZmqSocketSender socket(endpoint);
socket.bind(); socket.bind();
Frame frame(1024, 1024, sizeof(uint32_t) * 8); Frame frame(1024, 1024, sizeof(uint32_t) * 8);
@ -34,7 +34,7 @@ int main() {
while (true) { while (true) {
zmq_frames.clear(); zmq_frames.clear();
header.acqIndex = acqid++; 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("acquisition:", header.acqIndex);
aare::logger::info("Header size:", header.to_string().size()); aare::logger::info("Header size:", header.to_string().size());
@ -44,7 +44,7 @@ int main() {
for (size_t i = 0; i < n_frames; i++) { for (size_t i = 0; i < n_frames; i++) {
zmq_frames.push_back({header, frame}); 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); aare::logger::info("Sent bytes", rc);
sleep(1); sleep(1);
} }

View File

@ -22,7 +22,7 @@ class File {
* @throws std::invalid_argument if the file mode is not supported * @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); void write(Frame &frame);
Frame read(); Frame read();
Frame iread(size_t frame_number); Frame iread(size_t frame_number);
@ -31,19 +31,19 @@ class File {
void read_into(std::byte *image_buf, size_t n_frames); void read_into(std::byte *image_buf, size_t n_frames);
size_t frame_number(size_t frame_index); size_t frame_number(size_t frame_index);
size_t bytes_per_frame(); size_t bytes_per_frame();
size_t pixels(); size_t pixels_per_frame();
void seek(size_t frame_number); void seek(size_t frame_number);
size_t tell() const; size_t tell() const;
size_t total_frames() const; size_t total_frames() const;
ssize_t rows() const; size_t rows() const;
ssize_t cols() const; size_t cols() const;
ssize_t bitdepth() const; size_t bitdepth() const;
/** /**
* @brief Move constructor * @brief Move constructor
* @param other File object to move from * @param other File object to move from
*/ */
File(File &&other); File(File &&other) noexcept;
/** /**
* @brief destructor: will only delete the FileInterface object * @brief destructor: will only delete the FileInterface object

View File

@ -16,8 +16,8 @@ namespace aare {
*/ */
struct FileConfig { struct FileConfig {
aare::DType dtype = aare::DType(typeid(uint16_t)); aare::DType dtype = aare::DType(typeid(uint16_t));
uint64_t rows; uint64_t rows{};
uint64_t cols; uint64_t cols{};
xy geometry{1, 1}; xy geometry{1, 1};
bool operator==(const FileConfig &other) const { bool operator==(const FileConfig &other) const {
return dtype == other.dtype && rows == other.rows && cols == other.cols && geometry == other.geometry; 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 * @brief get the number of pixels in one frame
* @return 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 * @brief seek to the given frame number
@ -116,17 +116,17 @@ class FileInterface {
* @brief get the number of rows in the file * @brief get the number of rows in the file
* @return 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 * @brief get the number of columns in the file
* @return 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 * @brief get the bitdepth of the file
* @return 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 * @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 // function to query the data type of the file
/*virtual DataType dtype = 0; */ /*virtual DataType dtype = 0; */
virtual ~FileInterface(){ virtual ~FileInterface() = default;
};
protected: protected:
std::string m_mode; std::string m_mode{};
std::filesystem::path m_fname; std::filesystem::path m_fname{};
std::filesystem::path m_base_path; std::filesystem::path m_base_path{};
std::string m_base_name, m_ext; std::string m_base_name{}, m_ext{};
int m_findex; int m_findex{};
size_t m_total_frames{}; size_t m_total_frames{};
size_t max_frames_per_file{}; size_t max_frames_per_file{};
std::string version; std::string version{};
DetectorType m_type; DetectorType m_type{};
ssize_t m_rows{}; size_t m_rows{};
ssize_t m_cols{}; size_t m_cols{};
ssize_t m_bitdepth{}; size_t m_bitdepth{};
size_t current_frame{}; size_t current_frame{};
}; };

View File

@ -3,6 +3,7 @@
#include "aare/core/defs.hpp" #include "aare/core/defs.hpp"
#include "aare/file_io/FileInterface.hpp" #include "aare/file_io/FileInterface.hpp"
#include "aare/file_io/NumpyHelpers.hpp" #include "aare/file_io/NumpyHelpers.hpp"
#include "aare/utils/logger.hpp"
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
#include <numeric> #include <numeric>
@ -24,7 +25,7 @@ class NumpyFile : public FileInterface {
* @param mode file mode (r, w) * @param mode file mode (r, w)
* @param cfg file configuration * @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; void write(Frame &frame) override;
Frame read() override { return get_frame(this->current_frame++); } 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; 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 frame_number(size_t frame_index) override { return frame_index; };
size_t bytes_per_frame() override; 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; } void seek(size_t frame_number) override { this->current_frame = frame_number; }
size_t tell() override { return this->current_frame; } size_t tell() override { return this->current_frame; }
size_t total_frames() const override { return m_header.shape[0]; } size_t total_frames() const override { return m_header.shape[0]; }
ssize_t rows() const override { return m_header.shape[1]; } size_t rows() const override { return m_header.shape[1]; }
ssize_t cols() const override { return m_header.shape[2]; } size_t cols() const override { return m_header.shape[2]; }
ssize_t bitdepth() const override { return m_header.dtype.bitdepth(); } size_t bitdepth() const override { return m_header.dtype.bitdepth(); }
/** /**
* @brief get the data type of the numpy file * @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() { template <typename T, size_t NDim> NDArray<T, NDim> load() {
NDArray<T, NDim> arr(make_shape<NDim>(m_header.shape)); NDArray<T, NDim> arr(make_shape<NDim>(m_header.shape));
fseek(fp, header_size, SEEK_SET); if (fseek(fp, static_cast<int64_t>(header_size), SEEK_SET)) {
fread(arr.data(), sizeof(T), arr.size(), fp); 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; return arr;
} }
~NumpyFile(); ~NumpyFile() noexcept override;
private: private:
FILE *fp = nullptr; FILE *fp = nullptr;
@ -79,9 +85,11 @@ class NumpyFile : public FileInterface {
NumpyHeader m_header; NumpyHeader m_header;
uint8_t major_ver_{}; uint8_t major_ver_{};
uint8_t minor_ver_{}; uint8_t minor_ver_{};
size_t m_bytes_per_frame{};
size_t m_pixels_per_frame{};
void load_metadata(); 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); Frame get_frame(size_t frame_number);
}; };

View File

@ -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); bool is_digits(const std::string &str);
aare::DType parse_descr(std::string typestring); 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); size_t write_header(std::ostream &out, const NumpyHeader &header);
} // namespace NumpyHelpers } // namespace NumpyHelpers

View File

@ -18,13 +18,13 @@ class RawFile : public FileInterface {
* @param mode file mode (r, w) * @param mode file mode (r, w)
* @param cfg file configuration * @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 * @brief write function is not implemented for RawFile
* @param frame frame to write * @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++); }; Frame read() override { return get_frame(this->current_frame++); };
std::vector<Frame> read(size_t n_frames) override; 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); }; 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 * @brief get the number of pixels in the frame
* @return number of pixels * @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 // goto frame number
void seek(size_t frame_number) override { this->current_frame = 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 * @brief check if the file is a master file
* @param fpath path to the 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 * @brief set the module gap row and column
@ -83,17 +83,17 @@ class RawFile : public FileInterface {
* @param file_id file id * @param file_id file id
* @return path to the data file * @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 * @brief destructor: will delete the subfiles
*/ */
~RawFile(); ~RawFile() override;
size_t total_frames() const override { return m_total_frames; } size_t total_frames() const override { return m_total_frames; }
ssize_t rows() const override { return m_rows; } size_t rows() const override { return m_rows; }
ssize_t cols() const override { return m_cols; } size_t cols() const override { return m_cols; }
ssize_t bitdepth() const override { return m_bitdepth; } size_t bitdepth() const override { return m_bitdepth; }
private: private:
/** /**
@ -101,7 +101,7 @@ class RawFile : public FileInterface {
* @param frame_number frame number to read * @param frame_number frame number to read
* @param image_buf buffer to store the frame * @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 * @brief get the frame at the given frame number
@ -140,22 +140,21 @@ class RawFile : public FileInterface {
* @param fname path to the data subfile * @param fname path to the data subfile
* @return sls_detector_header * @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 * @brief open the subfiles
*/ */
void open_subfiles(); void open_subfiles();
private: size_t n_subfiles{};
size_t n_subfiles; size_t n_subfile_parts{};
size_t n_subfile_parts;
std::vector<std::vector<SubFile *>> subfiles; std::vector<std::vector<SubFile *>> subfiles;
int subfile_rows, subfile_cols; size_t subfile_rows{}, subfile_cols{};
xy geometry; xy geometry{};
std::vector<xy> positions; std::vector<xy> positions;
RawFileConfig cfg{0, 0}; RawFileConfig cfg{0, 0};
TimingMode timing_mode; TimingMode timing_mode{};
bool quad{false}; bool quad{false};
}; };

View File

@ -45,7 +45,7 @@ class SubFile {
* @param bitdepth bitdepth of the subfile * @param bitdepth bitdepth of the subfile
* @throws std::invalid_argument if the detector,type pair is not supported * @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 * @brief read the subfile into a buffer
@ -74,20 +74,20 @@ class SubFile {
* @param frame_number frame number to read * @param frame_number frame number to read
* @return number of bytes read * @return number of bytes read
*/ */
size_t get_part(std::byte *buffer, int frame_number); size_t get_part(std::byte *buffer, size_t frame_number);
size_t frame_number(int frame_index); size_t frame_number(size_t frame_index);
// TODO: define the inlines as variables and assign them in constructor // 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 bytes_per_part() const { return (m_bitdepth / 8) * m_rows * m_cols; }
inline size_t pixels_per_part() { return m_rows * m_cols; } inline size_t pixels_per_part() const { return m_rows * m_cols; }
protected: protected:
FILE *fp = nullptr; FILE *fp = nullptr;
ssize_t m_bitdepth; size_t m_bitdepth;
std::filesystem::path m_fname; std::filesystem::path m_fname;
ssize_t m_rows{}; size_t m_rows{};
ssize_t m_cols{}; size_t m_cols{};
ssize_t n_frames{}; size_t n_frames{};
int m_sub_file_index_{}; int m_sub_file_index_{};
}; };

View File

@ -6,7 +6,7 @@
namespace aare { 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") { if (mode != "r" && mode != "w" && mode != "a") {
throw std::invalid_argument("Unsupported file mode"); 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); } 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::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::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); } void File::seek(size_t frame_number) { file_impl->seek(frame_number); }
size_t File::tell() const { return file_impl->tell(); } size_t File::tell() const { return file_impl->tell(); }
ssize_t File::rows() const { return file_impl->rows(); } size_t File::rows() const { return file_impl->rows(); }
ssize_t File::cols() const { return file_impl->cols(); } size_t File::cols() const { return file_impl->cols(); }
ssize_t File::bitdepth() const { return file_impl->bitdepth(); } size_t File::bitdepth() const { return file_impl->bitdepth(); }
File::~File() { delete file_impl; } File::~File() { delete file_impl; }
Frame File::iread(size_t frame_number) { return file_impl->iread(frame_number); } Frame File::iread(size_t frame_number) { return file_impl->iread(frame_number); }
File::File(File &&other) { File::File(File &&other) noexcept : file_impl(other.file_impl) { other.file_impl = nullptr; }
file_impl = other.file_impl;
other.file_impl = nullptr;
}
// write move assignment operator // write move assignment operator

View File

@ -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); 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) { void NumpyFile::write(Frame &frame) {
@ -33,10 +36,14 @@ void NumpyFile::write(Frame &frame) {
throw std::runtime_error("File not open"); throw std::runtime_error("File not open");
} }
if (not(m_mode == "w" or m_mode == "a")) { 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) { 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"); throw std::runtime_error("File not open");
} }
if (frame_number > m_header.shape[0]) { 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() { size_t NumpyFile::pixels_per_frame() { return m_pixels_per_frame; };
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_bytes_per_frame; };
};
size_t NumpyFile::bytes_per_frame() { return m_header.dtype.bitdepth() / 8 * pixels(); };
std::vector<Frame> NumpyFile::read(size_t n_frames) { std::vector<Frame> NumpyFile::read(size_t n_frames) {
// TODO: implement this in a more efficient way // 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 // TODO: implement this in a more efficient way
for (size_t i = 0; i < n_frames; i++) { for (size_t i = 0; i < n_frames; i++) {
get_frame_into(current_frame++, image_buf); 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") { if (m_mode == "w" or m_mode == "a") {
// determine number of frames // determine number of frames
fseek(fp, 0, SEEK_END); if (fseek(fp, 0, SEEK_END)) {
size_t file_size = ftell(fp); aare::logger::error("Could not seek to end of file");
size_t data_size = file_size - initial_header_len; }
size_t n_frames = data_size / bytes_per_frame(); 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) // update number of frames in header (first element of shape)
m_header.shape[0] = n_frames; 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 // create string stream to contain header
std::stringstream ss; std::stringstream ss;
aare::NumpyHelpers::write_header(ss, m_header); aare::NumpyHelpers::write_header(ss, m_header);
std::string header_str = ss.str(); std::string const header_str = ss.str();
// write header // 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) { 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 // read magic number
std::array<char, 6> tmp{}; 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) { if (tmp != aare::NumpyHelpers::magic_str) {
for (auto item : tmp) for (auto item : tmp)
fmt::print("{}, ", int(item)); fmt::print("{}, ", static_cast<int>(item));
fmt::print("\n"); fmt::print("\n");
throw std::runtime_error("Not a numpy file"); throw std::runtime_error("Not a numpy file");
} }
// read version // read version
fread(reinterpret_cast<char *>(&major_ver_), sizeof(major_ver_), 1, fp); rc = 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 *>(&minor_ver_), sizeof(minor_ver_), 1, fp);
if (rc != 2) {
throw std::runtime_error("Error reading numpy version");
}
if (major_ver_ == 1) { if (major_ver_ == 1) {
header_len_size = 2; header_len_size = 2;
@ -125,7 +150,10 @@ void NumpyFile::load_metadata() {
} }
// read header length // 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; header_size = aare::NumpyHelpers::magic_string_length + 2 + header_len_size + header_len;
if (header_size % 16 != 0) { if (header_size % 16 != 0) {
fmt::print("Warning: header length is not a multiple of 16\n"); fmt::print("Warning: header length is not a multiple of 16\n");
@ -133,31 +161,34 @@ void NumpyFile::load_metadata() {
// read header // read header
std::string header(header_len, '\0'); 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 // 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\""); aare::logger::debug("original header: \"header\"");
auto dict_map = aare::NumpyHelpers::parse_dict(header, keys); 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"); throw std::runtime_error("invalid dictionary in header");
std::string descr_s = dict_map["descr"]; std::string const descr_s = dict_map["descr"];
std::string fortran_s = dict_map["fortran_order"]; std::string const fortran_s = dict_map["fortran_order"];
std::string shape_s = dict_map["shape"]; std::string const shape_s = dict_map["shape"];
std::string descr = aare::NumpyHelpers::parse_str(descr_s); std::string const descr = aare::NumpyHelpers::parse_str(descr_s);
aare::DType dtype = aare::NumpyHelpers::parse_descr(descr); aare::DType const dtype = aare::NumpyHelpers::parse_descr(descr);
// convert literal Python bool to C++ bool // 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 // parse the shape tuple
auto shape_v = aare::NumpyHelpers::parse_tuple(shape_s); auto shape_v = aare::NumpyHelpers::parse_tuple(shape_s);
shape_t shape; shape_t shape;
for (auto item : shape_v) { for (const auto &item : shape_v) {
auto dim = static_cast<unsigned long>(std::stoul(item)); auto dim = static_cast<size_t>(std::stoul(item));
shape.push_back(dim); shape.push_back(dim);
} }
m_header = {dtype, fortran_order, shape}; m_header = {dtype, fortran_order, shape};

View File

@ -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> parse_dict(std::string in, const std::vector<std::string> &keys) {
std::unordered_map<std::string, std::string> map; std::unordered_map<std::string, std::string> map;
if (keys.size() == 0) if (keys.empty())
return map; return map;
in = trim(in); 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; std::vector<std::pair<size_t, std::string>> positions;
for (auto const &key : keys) { for (auto const &key : keys) {
size_t pos = in.find("'" + key + "'"); size_t const pos = in.find("'" + key + "'");
if (pos == std::string::npos) if (pos == std::string::npos)
throw std::runtime_error("Missing '" + key + "' key."); 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); 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) { for (size_t i = 0; i < positions.size(); ++i) {
std::string raw_value; std::string raw_value;
size_t begin{positions[i].first}; size_t const begin{positions[i].first};
size_t end{std::string::npos}; size_t end{std::string::npos};
std::string key = positions[i].second; std::string const key = positions[i].second;
if (i + 1 < positions.size()) if (i + 1 < positions.size())
end = positions[i + 1].first; end = positions[i + 1].first;
@ -104,7 +104,7 @@ aare::DType parse_descr(std::string typestring) {
const char byteorder_c = typestring[0]; const char byteorder_c = typestring[0];
const char kind_c = typestring[1]; 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)) { if (!in_array(byteorder_c, endian_chars)) {
throw std::runtime_error("invalid typestring (byteorder)"); 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) { 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) if (sep_pos == std::string::npos)
return ""; return "";
std::string tmp = mapstr.substr(sep_pos + 1); std::string const tmp = mapstr.substr(sep_pos + 1);
return trim(tmp); 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) { void write_magic(std::ostream &ostream, int version_major, int version_minor) {
ostream.write(magic_str.data(), magic_string_length); ostream.write(magic_str.data(), magic_string_length);
ostream.put(version_major); ostream.put(static_cast<char>(version_major));
ostream.put(version_minor); ostream.put(static_cast<char>(version_minor));
} }
template <typename T> inline std::string write_tuple(const std::vector<T> &v) { template <typename T> inline std::string write_tuple(const std::vector<T> &v) {
if (v.size() == 0) if (v.empty())
return "()"; return "()";
std::ostringstream ss; std::ostringstream ss;
ss.imbue(std::locale("C")); 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) { inline std::string write_boolean(bool b) {
if (b) if (b)
return "True"; return "True";
else
return "False"; return "False";
} }
inline std::string write_header_dict(const std::string &descr, bool fortran_order, const shape_t &shape) { 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 const s_fortran_order = write_boolean(fortran_order);
std::string shape_s = write_tuple(shape); std::string const shape_s = write_tuple(shape);
return "{'descr': '" + descr + "', 'fortran_order': " + s_fortran_order + ", 'shape': " + shape_s + ", }"; 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); std::ofstream out(fname, std::ios::binary | std::ios::out);
return write_header(out, header); return write_header(out, header);
} }
size_t write_header(std::ostream &out, const NumpyHeader &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; size_t length = magic_string_length + 2 + 2 + header_dict.length() + 1;
int version_major = 1; int version_major = 1;
int version_minor = 0; 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; length = magic_string_length + 2 + 4 + header_dict.length() + 1;
version_major = 2; version_major = 2;
version_minor = 0; version_minor = 0;
} }
size_t padding_len = 16 - length % 16; size_t const padding_len = 16 - length % 16;
std::string padding(padding_len, ' '); std::string const padding(padding_len, ' ');
// write magic // write magic
write_magic(out, version_major, version_minor); write_magic(out, version_major, version_minor);

View File

@ -30,7 +30,7 @@ void RawFile::open_subfiles() {
for (size_t i = 0; i != n_subfiles; ++i) { for (size_t i = 0; i != n_subfiles; ++i) {
auto v = std::vector<SubFile *>(n_subfile_parts); auto v = std::vector<SubFile *>(n_subfile_parts);
for (size_t j = 0; j != n_subfile_parts; ++j) { 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); subfiles.push_back(v);
} }
@ -42,18 +42,18 @@ sls_detector_header RawFile::read_header(const std::filesystem::path &fname) {
if (!fp) if (!fp)
throw std::runtime_error(fmt::format("Could not open: {} for reading", fname.c_str())); 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); size_t const rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
fclose(fp);
if (rc != 1) 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; return h;
} }
bool RawFile::is_master_file(std::filesystem::path fpath) { bool RawFile::is_master_file(const std::filesystem::path &fpath) {
std::string stem = fpath.stem(); std::string const stem = fpath.stem();
if (stem.find("_master_") != std::string::npos) return stem.find("_master_") != std::string::npos;
return true;
else
return false;
} }
void RawFile::find_number_of_subfiles() { void RawFile::find_number_of_subfiles() {
@ -62,7 +62,7 @@ void RawFile::find_number_of_subfiles() {
; ;
n_subfiles = n_mod; 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); 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++; r++;
c++; c++;
m_rows = r * subfile_rows; m_rows = (r * subfile_rows);
m_cols = c * subfile_cols; 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() { void RawFile::parse_metadata() {
@ -109,7 +109,7 @@ void RawFile::parse_metadata() {
} else { } else {
throw std::runtime_error(LOCATION + "Unsupported file type"); 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() { void RawFile::parse_json_metadata() {
@ -141,7 +141,7 @@ void RawFile::parse_raw_metadata() {
for (std::string line; std::getline(ifs, line);) { for (std::string line; std::getline(ifs, line);) {
if (line == "#Frame Header") if (line == "#Frame Header")
break; break;
auto pos = line.find(":"); auto pos = line.find(':');
auto key_pos = pos; auto key_pos = pos;
while (key_pos != std::string::npos && std::isspace(line[--key_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_path = m_fname.parent_path();
m_base_name = m_fname.stem(); m_base_name = m_fname.stem();
m_ext = m_fname.extension(); 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)); m_findex = std::stoi(m_base_name.substr(pos + 1));
pos = m_base_name.find("_master_"); pos = m_base_name.find("_master_");
m_base_name.erase(pos); 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) { if (frame_number > this->m_total_frames) {
throw std::runtime_error(LOCATION + "Frame number out of range"); 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 // create frame and get its buffer
if (this->geometry.col == 1) { if (this->geometry.col == 1) {
@ -214,11 +214,11 @@ void RawFile::get_frame_into(size_t frame_number, std::byte *frame_buffer) {
} else { } else {
// create a buffer that will hold a the frame part // create a buffer that will hold a the frame part
auto bytes_per_part = this->subfile_rows * this->subfile_cols * this->m_bitdepth / 8; 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) { 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); 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 irow = cur_row + (part_idx / this->geometry.col) * this->subfile_rows;
auto icol = (part_idx % this->geometry.col) * this->subfile_cols; auto icol = (part_idx % this->geometry.col) * this->subfile_cols;
auto dest = (irow * this->m_cols + icol); 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) { if (frame_index > this->m_total_frames) {
throw std::runtime_error(LOCATION + "Frame number out of range"); 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); return this->subfiles[subfile_id][0]->frame_number(frame_index % this->max_frames_per_file);
} }
RawFile::~RawFile() { RawFile::~RawFile() {
for (auto &vec : subfiles) { for (auto &vec : subfiles) {
for (auto subfile : vec) { for (auto *subfile : vec) {
delete subfile; delete subfile;
} }
} }

View File

@ -7,12 +7,10 @@
namespace aare { namespace aare {
SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth) { SubFile::SubFile(const std::filesystem::path &fname, DetectorType detector, size_t rows, size_t cols, size_t bitdepth)
this->m_rows = rows; : m_bitdepth(bitdepth), m_fname(fname), m_rows(rows), m_cols(cols),
this->m_cols = cols; n_frames(std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8)) {
this->m_fname = fname;
this->m_bitdepth = bitdepth;
this->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()) { if (read_impl_map.find({detector, bitdepth}) == read_impl_map.end()) {
auto error_msg = LOCATION + "No read_impl function found for detector: " + toString(detector) + auto error_msg = LOCATION + "No read_impl function found for detector: " + toString(detector) +
" and bitdepth: " + std::to_string(bitdepth); " 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}); this->read_impl = read_impl_map.at({detector, bitdepth});
} }
size_t SubFile::get_part(std::byte *buffer, int frame_number) { size_t SubFile::get_part(std::byte *buffer, size_t frame_number) {
if (frame_number >= n_frames or frame_number < 0) { if (frame_number >= n_frames) {
throw std::runtime_error("Frame number out of range"); throw std::runtime_error("Frame number out of range");
} }
// TODO: find a way to avoid opening and closing the file for each frame // 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) { if (!fp) {
throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str())); 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); auto ret = (this->*read_impl)(buffer);
fclose(fp); if (fclose(fp))
throw std::runtime_error(LOCATION + "Could not close file");
return ret; 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) { template <typename DataType> size_t SubFile::read_impl_reorder(std::byte *buffer) {
std::vector<DataType> tmp(this->pixels_per_part()); 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}; 100, 125, 150, 175, 100, 125, 150, 175, 0, 25, 50, 75, 0, 25, 50, 75};
int sc_width = 25; int const sc_width = 25;
int nadc = 32; int const nadc = 32;
int pixels_per_sc = 5000; int const pixels_per_sc = 5000;
auto dst = reinterpret_cast<DataType *>(buffer); auto dst = reinterpret_cast<DataType *>(buffer);
int pixel = 0; int pixel = 0;
for (int i = 0; i != pixels_per_sc; ++i) { for (int i = 0; i != pixels_per_sc; ++i) {
for (int i_adc = 0; i_adc != nadc; ++i_adc) { for (int i_adc = 0; i_adc != nadc; ++i_adc) {
int col = adc_nr[i_adc] + (i % sc_width); int const col = adc_nr[i_adc] + (i % sc_width);
int row; int row = 0;
if ((i_adc / 4) % 2 == 0) if ((i_adc / 4) % 2 == 0)
row = 199 - int(i / sc_width); row = 199 - (i / sc_width);
else else
row = 200 + int(i / sc_width); row = 200 + (i / sc_width);
dst[col + row * 400] = tmp[pixel]; dst[col + row * 400] = tmp[pixel];
pixel++; pixel++;
@ -72,15 +72,15 @@ template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
// read to temporary buffer // read to temporary buffer
// TODO! benchmark direct reads // TODO! benchmark direct reads
std::vector<std::byte> tmp(this->bytes_per_part()); 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 // copy to place
const size_t start = this->m_cols * (this->m_rows - 1) * sizeof(DataType); const size_t start = this->m_cols * (this->m_rows - 1) * sizeof(DataType);
const size_t row_size = this->m_cols * sizeof(DataType); const size_t row_size = this->m_cols * sizeof(DataType);
auto dst = buffer + start; auto *dst = buffer + start;
auto src = &tmp[0]; 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); std::memcpy(dst, src, row_size);
dst -= row_size; dst -= row_size;
src += row_size; src += row_size;
@ -89,16 +89,18 @@ template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
return rc; return rc;
}; };
size_t SubFile::frame_number(int frame_index) { size_t SubFile::frame_number(size_t frame_index) {
sls_detector_header h{}; sls_detector_header h{};
fp = fopen(this->m_fname.c_str(), "r"); fp = fopen(this->m_fname.c_str(), "r");
if (!fp) if (!fp)
throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str())); 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); fseek(fp, (sizeof(sls_detector_header) + bytes_per_part()) * frame_index, SEEK_SET); // NOLINT
size_t rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp); size_t const rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
fclose(fp);
if (rc != 1) 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; return h.frameNumber;
} }

View File

@ -18,16 +18,16 @@ template <> simdjson_inline simdjson::simdjson_result<std::array<int, 4>> simdjs
if (error) { if (error) {
return error; return error;
} }
std::array<int, 4> arr; std::array<int, 4> arr{};
int i = 0; int i = 0;
for (auto v : array) { for (auto v : array) {
int64_t val; int64_t val = 0;
error = v.get_int64().get(val); error = v.get_int64().get(val);
if (error) { if (error) {
return error; return error;
} }
arr[i++] = val; arr[i++] = static_cast<int>(val);
} }
return arr; return arr;
} }
@ -37,7 +37,7 @@ template <> simdjson_inline simdjson::simdjson_result<std::array<int, 4>> simdjs
* adds a check for 32bit overflow * adds a check for 32bit overflow
*/ */
template <> simdjson_inline simdjson::simdjson_result<uint32_t> simdjson::ondemand::value::get() noexcept { 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); auto error = get_uint64().get(val);
if (error) { if (error) {
return error; return error;
@ -70,9 +70,9 @@ simdjson::ondemand::value::get() noexcept {
if (error) { if (error) {
return error; return error;
} }
std::string_view key_view = field.unescaped_key(); std::string_view const key_view = field.unescaped_key();
std::string key_str(key_view.data(), key_view.size()); std::string const key_str(key_view.data(), key_view.size());
std::string_view value_view = field.value().get_string(); std::string_view const value_view = field.value().get_string();
map[key_str] = {value_view.data(), value_view.size()}; map[key_str] = {value_view.data(), value_view.size()};
} }
return map; return map;
@ -122,7 +122,7 @@ struct ZmqHeader {
uint8_t detType{0}; uint8_t detType{0};
uint8_t version{0}; uint8_t version{0};
/** if rows of image should be flipped */ /** if rows of image should be flipped */
int flipRows{0}; int64_t flipRows{0};
/** quad type (eiger hardware specific) */ /** quad type (eiger hardware specific) */
uint32_t quad{0}; uint32_t quad{0};
/** true if complete image, else missing packets */ /** true if complete image, else missing packets */

View File

@ -32,7 +32,7 @@ class ZmqSocket {
std::string m_endpoint; std::string m_endpoint;
int m_zmq_hwm{1000}; int m_zmq_hwm{1000};
int m_timeout_ms{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; constexpr static size_t m_max_header_size = 1024;
char *m_header_buffer = new char[m_max_header_size]; char *m_header_buffer = new char[m_max_header_size];
}; };

View File

@ -19,7 +19,7 @@ namespace aare {
*/ */
class ZmqSocketReceiver : public ZmqSocket { class ZmqSocketReceiver : public ZmqSocket {
public: public:
ZmqSocketReceiver(const std::string &endpoint); explicit ZmqSocketReceiver(const std::string &endpoint);
void connect(); void connect();
std::vector<ZmqFrame> receive_n(); std::vector<ZmqFrame> receive_n();

View File

@ -12,7 +12,7 @@ namespace aare {
*/ */
class ZmqSocketSender : public ZmqSocket { class ZmqSocketSender : public ZmqSocket {
public: public:
ZmqSocketSender(const std::string &endpoint); explicit ZmqSocketSender(const std::string &endpoint);
void bind(); void bind();
size_t send(const ZmqHeader &header, const std::byte *data, size_t size); size_t send(const ZmqHeader &header, const std::byte *data, size_t size);
size_t send(const ZmqFrame &zmq_frame); size_t send(const ZmqFrame &zmq_frame);

View File

@ -6,6 +6,7 @@
#include <string> #include <string>
namespace aare { namespace aare {
/** /**
* @brief ZmqFrame structure * @brief ZmqFrame structure
* wrapper class to contain a ZmqHeader and a Frame * wrapper class to contain a ZmqHeader and a Frame
@ -24,9 +25,9 @@ class NetworkError : public std::runtime_error {
const char *m_msg; const char *m_msg;
public: public:
NetworkError(const char *msg) : std::runtime_error(msg), m_msg(msg) {} explicit 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()); } explicit 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; } const char *what() const noexcept override { return m_msg; }
}; };
} // namespace network_io } // namespace network_io

View File

@ -3,8 +3,6 @@
#include "simdjson.h" #include "simdjson.h"
using namespace simdjson;
// helper functions to write json // helper functions to write json
// append to string for better performance (not tested) // 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 += "\"";
s += key; s += key;
s += "\": {"; s += "\": {";
for (auto &kv : value) { for (const auto &kv : value) {
write_str(s, kv.first, kv.second); write_str(s, kv.first, kv.second);
} }
// remove last comma or trailing spaces // 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] == ' ') { if (s[i] == ',' or s[i] == ' ') {
s.pop_back(); s.pop_back();
} else } else
@ -66,7 +64,7 @@ void write_array(std::string &s, const std::string &key, const std::array<int, 4
namespace aare { namespace aare {
std::string ZmqHeader::to_string() const { std::string ZmqHeader::to_string() const {
std::string s = ""; std::string s;
s.reserve(1024); s.reserve(1024);
s += "{"; s += "{";
write_digit(s, "data", data ? 1 : 0); write_digit(s, "data", data ? 1 : 0);
@ -108,78 +106,79 @@ std::string ZmqHeader::to_string() const {
return s; 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()); simdjson::padded_string const ps(s.c_str(), s.size());
ondemand::parser parser; simdjson::ondemand::parser parser;
ondemand::document doc = parser.iterate(ps); simdjson::ondemand::document doc = parser.iterate(ps);
ondemand::object object = doc.get_object(); simdjson::ondemand::object object = doc.get_object();
for (auto field : object) { for (auto field : object) {
std::string_view key = field.unescaped_key(); std::string_view const key = field.unescaped_key();
if (key == "data") { if (key == "data") {
data = uint64_t(field.value()) ? true : false; data = static_cast<uint64_t>(field.value()) != 0;
} else if (key == "jsonversion") { } else if (key == "jsonversion") {
jsonversion = uint32_t(field.value()); jsonversion = static_cast<uint32_t>(field.value());
} else if (key == "dynamicRange") { } else if (key == "dynamicRange") {
dynamicRange = uint32_t(field.value()); dynamicRange = static_cast<uint32_t>(field.value());
} else if (key == "fileIndex") { } else if (key == "fileIndex") {
fileIndex = uint64_t(field.value()); fileIndex = static_cast<uint64_t>(field.value());
} else if (key == "ndetx") { } else if (key == "ndetx") {
ndetx = uint32_t(field.value()); ndetx = static_cast<uint32_t>(field.value());
} else if (key == "ndety") { } else if (key == "ndety") {
ndety = uint32_t(field.value()); ndety = static_cast<uint32_t>(field.value());
} else if (key == "npixelsx") { } else if (key == "npixelsx") {
npixelsx = uint32_t(field.value()); npixelsx = static_cast<uint32_t>(field.value());
} else if (key == "npixelsy") { } else if (key == "npixelsy") {
npixelsy = uint32_t(field.value()); npixelsy = static_cast<uint32_t>(field.value());
} else if (key == "size") { } else if (key == "size") {
size = uint32_t(field.value()); size = static_cast<uint32_t>(field.value());
} else if (key == "acqIndex") { } else if (key == "acqIndex") {
acqIndex = uint64_t(field.value()); acqIndex = static_cast<uint64_t>(field.value());
} else if (key == "frameIndex") { } else if (key == "frameIndex") {
frameIndex = uint64_t(field.value()); frameIndex = static_cast<uint64_t>(field.value());
} else if (key == "progress") { } else if (key == "progress") {
progress = field.value().get_double(); progress = field.value().get_double();
} else if (key == "fname") { } 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()}; fname = {tmp.begin(), tmp.end()};
} else if (key == "frameNumber") { } else if (key == "frameNumber") {
frameNumber = uint64_t(field.value()); frameNumber = static_cast<uint64_t>(field.value());
} else if (key == "expLength") { } else if (key == "expLength") {
expLength = uint32_t(field.value()); expLength = static_cast<uint32_t>(field.value());
} else if (key == "packetNumber") { } else if (key == "packetNumber") {
packetNumber = uint32_t(field.value()); packetNumber = static_cast<uint32_t>(field.value());
} else if (key == "detSpec1") { } else if (key == "detSpec1") {
detSpec1 = uint64_t(field.value()); detSpec1 = static_cast<uint64_t>(field.value());
} else if (key == "timestamp") { } else if (key == "timestamp") {
timestamp = uint64_t(field.value()); timestamp = static_cast<uint64_t>(field.value());
} else if (key == "modId") { } else if (key == "modId") {
modId = uint32_t(field.value()); modId = static_cast<uint32_t>(field.value());
} else if (key == "row") { } else if (key == "row") {
row = uint32_t(field.value()); row = static_cast<uint32_t>(field.value());
} else if (key == "column") { } else if (key == "column") {
column = uint32_t(field.value()); column = static_cast<uint32_t>(field.value());
} else if (key == "detSpec2") { } else if (key == "detSpec2") {
detSpec2 = uint32_t(field.value()); detSpec2 = static_cast<uint32_t>(field.value());
} else if (key == "detSpec3") { } else if (key == "detSpec3") {
detSpec3 = uint32_t(field.value()); detSpec3 = static_cast<uint32_t>(field.value());
} else if (key == "detSpec4") { } else if (key == "detSpec4") {
detSpec4 = uint32_t(field.value()); detSpec4 = static_cast<uint32_t>(field.value());
} else if (key == "detType") { } else if (key == "detType") {
detType = uint32_t(field.value()); detType = static_cast<uint32_t>(field.value());
} else if (key == "version") { } else if (key == "version") {
version = uint32_t(field.value()); version = static_cast<uint32_t>(field.value());
} else if (key == "flipRows") { } else if (key == "flipRows") {
flipRows = uint32_t(field.value()); flipRows = static_cast<int64_t>(field.value());
} else if (key == "quad") { } else if (key == "quad") {
quad = uint32_t(field.value()); quad = static_cast<uint32_t>(field.value());
} else if (key == "completeImage") { } else if (key == "completeImage") {
completeImage = uint64_t(field.value()) ? true : false; completeImage = static_cast<uint64_t>(field.value()) != 0;
} else if (key == "addJsonHeader") { } 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") { } else if (key == "rx_roi") {
rx_roi = std::array<int, 4>(field.value()); rx_roi = static_cast<std::array<int, 4>>(field.value());
} }
} }
} }

View File

@ -24,13 +24,13 @@ void ZmqSocketReceiver::connect() {
fmt::print("Setting ZMQ_RCVHWM to {}\n", m_zmq_hwm); 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 int rc = zmq_setsockopt(m_socket, ZMQ_RCVHWM, &m_zmq_hwm, sizeof(m_zmq_hwm)); // should be set before connect
if (rc) 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; size_t bufsize = m_potential_frame_size * m_zmq_hwm;
fmt::print("Setting ZMQ_RCVBUF to: {} MB\n", bufsize / (1024 * 1024)); 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)); rc = zmq_setsockopt(m_socket, ZMQ_RCVBUF, &bufsize, sizeof(bufsize));
if (rc) 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_connect(m_socket, m_endpoint.c_str());
zmq_setsockopt(m_socket, ZMQ_SUBSCRIBE, "", 0); zmq_setsockopt(m_socket, ZMQ_SUBSCRIBE, "", 0);
@ -44,7 +44,7 @@ ZmqHeader ZmqSocketReceiver::receive_header() {
// receive string ZmqHeader // receive string ZmqHeader
aare::logger::debug("Receiving header"); 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); aare::logger::debug("Bytes: ", header_bytes_received);
m_header_buffer[header_bytes_received] = '\0'; // make sure we zero terminate m_header_buffer[header_bytes_received] = '\0'; // make sure we zero terminate
@ -71,9 +71,9 @@ ZmqHeader ZmqSocketReceiver::receive_header() {
* @return ZmqHeader * @return ZmqHeader
*/ */
int ZmqSocketReceiver::receive_data(std::byte *data, size_t size) { 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) 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); aare::logger::debug("Bytes: ", data_bytes_received);
return data_bytes_received; return data_bytes_received;
@ -98,7 +98,7 @@ ZmqFrame ZmqSocketReceiver::receive_zmqframe() {
if (bytes_received == -1) { if (bytes_received == -1) {
throw network_io::NetworkError(LOCATION + "Error receiving frame"); 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( throw network_io::NetworkError(
fmt::format("{} Expected {} bytes but received {}", LOCATION, header.size, bytes_received)); 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; std::vector<ZmqFrame> frames;
while (true) { while (true) {
// receive header and frame // receive header and frame
ZmqFrame zmq_frame = receive_zmqframe(); ZmqFrame const zmq_frame = receive_zmqframe();
if (!zmq_frame.header.data) { if (!zmq_frame.header.data) {
break; break;
} }

View File

@ -16,9 +16,9 @@ ZmqSocketSender::ZmqSocketSender(const std::string &endpoint) { m_endpoint = end
void ZmqSocketSender::bind() { void ZmqSocketSender::bind() {
m_context = zmq_ctx_new(); m_context = zmq_ctx_new();
m_socket = zmq_socket(m_context, ZMQ_PUB); 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) { 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); throw network_io::NetworkError("zmq_bind failed: " + error);
} }
} }
@ -31,11 +31,11 @@ void ZmqSocketSender::bind() {
* @return number of bytes sent * @return number of bytes sent
*/ */
size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, size_t size) { size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, size_t size) {
size_t rc; size_t rc = 0;
// if (serialize_header) { // if (serialize_header) {
// rc = zmq_send(m_socket, &header, sizeof(ZmqHeader), ZMQ_SNDMORE); // rc = zmq_send(m_socket, &header, sizeof(ZmqHeader), ZMQ_SNDMORE);
// assert(rc == sizeof(ZmqHeader)); // 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); aare::logger::debug("Header :", header_str);
rc = zmq_send(m_socket, header_str.c_str(), header_str.size(), ZMQ_SNDMORE); rc = zmq_send(m_socket, header_str.c_str(), header_str.size(), ZMQ_SNDMORE);
assert(rc == header_str.size()); assert(rc == header_str.size());
@ -43,7 +43,7 @@ size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, siz
return rc; 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); assert(rc2 == size);
return rc + rc2; 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) { size_t ZmqSocketSender::send(const ZmqFrame &zmq_frame) {
const Frame &frame = zmq_frame.frame; const Frame &frame = zmq_frame.frame;
// send 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 // send end of message header
ZmqHeader end_header = zmq_frame.header; ZmqHeader end_header = zmq_frame.header;
end_header.data = false; end_header.data = false;
size_t rc2 = send(end_header, nullptr, 0); size_t const rc2 = send(end_header, nullptr, 0);
return rc + rc2; return rc + rc2;
} }

View File

@ -20,7 +20,7 @@
*/ */
template <typename T> std::ostream &operator<<(std::ostream &out, const std::vector<T> &v) { template <typename T> std::ostream &operator<<(std::ostream &out, const std::vector<T> &v) {
out << "["; out << "[";
size_t last = v.size() - 1; size_t const last = v.size() - 1;
for (size_t i = 0; i < v.size(); ++i) { for (size_t i = 0; i < v.size(); ++i) {
out << v[i]; out << v[i];
if (i != last) if (i != last)
@ -71,9 +71,7 @@ template <typename K, typename V> std::ostream &operator<<(std::ostream &out, co
return out; return out;
} }
namespace aare { namespace aare::logger {
namespace logger {
/** /**
* @brief enum to define the logging level * @brief enum to define the logging level
*/ */
@ -96,17 +94,14 @@ class Logger {
/** /**
* @brief get the instance of the logger * @brief get the instance of the logger
*/ */
Logger() { Logger() : standard_output(new std::ostream(standard_buf)), error_output(new std::ostream(error_buf)) {} // NOLINT
standard_output = new std::ostream(standard_buf);
error_output = new std::ostream(error_buf);
}
/** /**
* @brief set the output file for the logger by filename * @brief set the output file for the logger by filename
* @param filename name of the file to log to * @param filename name of the file to log to
* @return void * @return void
*/ */
void set_output_file(std::string filename) { void set_output_file(const std::string &filename) {
if (out_file.is_open()) if (out_file.is_open())
out_file.close(); out_file.close();
out_file.open(filename); out_file.open(filename);
@ -152,6 +147,10 @@ class Logger {
delete standard_output; delete standard_output;
delete error_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 * @brief log a message
@ -199,9 +198,9 @@ class Logger {
*/ */
template <LOGGING_LEVEL level> void log_() { template <LOGGING_LEVEL level> void log_() {
if (level == LOGGING_LEVEL::ERROR) { if (level == LOGGING_LEVEL::ERROR) {
*error_output << std::endl; *error_output << std::endl; // NOLINT
} else { } 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) { template <LOGGING_LEVEL level, typename First, typename... Strings> void log_(First arg, const Strings... s) {
if (level == LOGGING_LEVEL::ERROR) { if (level == LOGGING_LEVEL::ERROR) {
*error_output << (arg) << ' '; *error_output << (arg) << ' ';
error_output->flush();
} else { } else {
*standard_output << (arg) << ' '; *standard_output << (arg) << ' ';
standard_output->flush();
} }
log_<level>(s...); log_<level>(s...);
} }
@ -230,7 +227,7 @@ namespace internal {
/** /**
* @brief global instance of the logger * @brief global instance of the logger
*/ */
extern aare::logger::Logger logger_instance; extern aare::logger::Logger logger_instance; // NOLINT
} // namespace internal } // 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, std::streambuf *err);
extern void set_streams(std::streambuf *out); extern void set_streams(std::streambuf *out);
extern void set_verbosity(LOGGING_LEVEL level); 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(); extern Logger &get_logger_instance();
} // namespace logger } // namespace aare::logger
} // namespace aare

View File

@ -1,14 +1,12 @@
#include "aare/utils/logger.hpp" #include "aare/utils/logger.hpp"
namespace aare { namespace aare::logger {
namespace logger {
namespace internal { namespace internal {
aare::logger::Logger logger_instance = aare::logger::Logger(); aare::logger::Logger logger_instance = aare::logger::Logger(); // NOLINT
} // namespace internal } // namespace internal
void set_streams(std::streambuf *out, std::streambuf *err) { internal::logger_instance.set_streams(out, err); } 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_streams(std::streambuf *out) { internal::logger_instance.set_streams(out); }
void set_verbosity(LOGGING_LEVEL level) { internal::logger_instance.set_verbosity(level); } void set_verbosity(LOGGING_LEVEL level) { internal::logger_instance.set_verbosity(level); }
Logger &get_logger_instance() { return internal::logger_instance; } Logger &get_logger_instance() { return internal::logger_instance; }
void set_output_file(std::string filename) { internal::logger_instance.set_output_file(filename); } void set_output_file(const std::string &filename) { internal::logger_instance.set_output_file(filename); }
} // namespace logger } // namespace aare::logger
} // namespace aare