From a04a6262056d5d5b8ad7f39f6c783b31c5f5a2a2 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Mon, 11 Mar 2024 17:36:39 +0100 Subject: [PATCH 01/17] make pyopenms compile again --- src/pyOpenMS/addons/MatrixDouble.pyx | 54 ++++++++++++++++------------ 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index 7dde4217fc8..6a43cc3ac4d 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -3,7 +3,7 @@ from Matrix cimport * # continue with extra code if needed - def get_matrix(self): + def get_matrix_as_view(self): """Cython signature: numpy_matrix get_matrix() """ @@ -11,15 +11,23 @@ from Matrix cimport * cdef unsigned int rows = mat_.rows() cdef unsigned int cols = mat_.cols() + cdef unsigned int n = rows * cols + cdef np.ndarray[double, ndim=2] data + data = np.zeros( (rows,cols), dtype=np.float64) - cdef libcpp_vector[double] tmp_vec; - tmp_vec = mat_.asVector(); + cdef libcpp_vector[double] * vec_ptr = mat_ + cdef double * raw_ptr = address(deref(vec_ptr)[0]) - xarr = np.asarray(tmp_vec) + ## # We use a memory view to get the data from the raw data + ## # See https://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html + ## # See https://stackoverflow.com/questions/43021574/cast-c-array-into-numpy-array-cython-typed-memoryview-in-cython-code + cdef double[:] vec_view = raw_ptr # cast to memoryview, refer to the underlying buffer without copy + xarr = np.asarray(vec_view) # numpy array refer to the underlying buffer without copy xarr = xarr.reshape(rows, cols) - return xarr + return xarr.transpose() - def get_matrix_as_view(self): + + def get_matrix(self): """Cython signature: numpy_matrix get_matrix() """ @@ -40,23 +48,23 @@ from Matrix cimport * cdef double[:] vec_view = raw_ptr # cast to memoryview, refer to the underlying buffer without copy xarr = np.asarray(vec_view) # numpy array refer to the underlying buffer without copy xarr = xarr.reshape(rows, cols) - return xarr - - def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): - """Cython signature: numpy_matrix set_matrix() - """ - - cdef _Matrix[double] * mat_ = self.inst.get() - - cdef unsigned int rows = data.shape[0] - cdef unsigned int cols = data.shape[1] - mat_.resize(rows, cols, 0) - - cdef int i = 0 - cdef int j = 0 - for i in range(int(rows)): - for j in range(int(cols)): - mat_.setValue(i,j,data[i][j]) + return xarr.transpose().copy() + +# def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): +# """Cython signature: numpy_matrix set_matrix() +# """ +# +# cdef _Matrix[double] * mat_ = self.inst.get() +# +# cdef unsigned int rows = data.shape[0] +# cdef unsigned int cols = data.shape[1] +# mat_.resize(rows, cols, 0) +# +# cdef int i = 0 +# cdef int j = 0 +# for i in range(int(rows)): +# for j in range(int(cols)): +# mat_.setValue(i,j,data[i][j]) From 4276c98bd2b12c113526237d75ae6a7a10307653 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Mon, 11 Mar 2024 19:15:40 +0100 Subject: [PATCH 02/17] fix more tests --- src/pyOpenMS/tests/unittests/test000.py | 5 +- .../unittests/test_BilinearInterpolation.py | 54 +++++++------------ 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/src/pyOpenMS/tests/unittests/test000.py b/src/pyOpenMS/tests/unittests/test000.py index a18e506a2cc..7f6f1d4e44c 100644 --- a/src/pyOpenMS/tests/unittests/test000.py +++ b/src/pyOpenMS/tests/unittests/test000.py @@ -3631,9 +3631,8 @@ def testMatrixDouble(): MapAlignmentAlgorithmIdentification.__init__ """ - m = pyopenms.MatrixDouble() N = 90 - m.resize(N-1, N+2, 5.0) + m = pyopenms.MatrixDouble(N-1, N+2, 5.0) assert m.rows() == 89 assert m.cols() == 92 @@ -3680,7 +3679,7 @@ def testMatrixDouble(): assert m.getValue(1, 6) == 11.0 assert matrix_view[1, 6] == 11.0 - m.clear() + m = pyopenms.MatrixDouble() assert m.rows() == 0 assert m.cols() == 0 diff --git a/src/pyOpenMS/tests/unittests/test_BilinearInterpolation.py b/src/pyOpenMS/tests/unittests/test_BilinearInterpolation.py index fa8877b20f5..43fd759a0cb 100644 --- a/src/pyOpenMS/tests/unittests/test_BilinearInterpolation.py +++ b/src/pyOpenMS/tests/unittests/test_BilinearInterpolation.py @@ -8,8 +8,7 @@ class TestBilinearInterpolation(unittest.TestCase): def test_BilinearInterpolation(self): - mat = pyopenms.MatrixDouble() - mat.resize(2, 3, float()) + mat = pyopenms.MatrixDouble(2, 3, 0.0) mat.setValue(0, 0, 17) mat.setValue(0, 1, 18.9) mat.setValue(0, 2, 20.333) @@ -43,8 +42,8 @@ def test_BilinearInterpolation(self): def test_getData_setData(self): bilip = pyopenms.BilinearInterpolation() - tmp = bilip.getData() - tmp.resize(2, 3, float()) + tmp = pyopenms.MatrixDouble(2, 3, 0.0) + tmp.setValue(1, 2, 10012) tmp.setValue(0, 0, 10000) tmp.setValue(1, 0, 10010) @@ -108,8 +107,8 @@ def test_supportMax_0(self): bilip.setMapping_0(3.0, 1.0, 2.0) bilip.setMapping_1(5.0, 3.0, 4.0) - tmp = bilip.getData() - tmp.resize(2, 3, float()) + tmp = pyopenms.MatrixDouble(2, 3, 0.0) + bilip.setData(tmp) self.assertAlmostEqual(bilip.index2key_0(0), -1) self.assertAlmostEqual(bilip.index2key_0(1), 2) @@ -174,8 +173,7 @@ def test_supportMax_1(self): bilip.setMapping_1(3.0, 1.0, 2.0) bilip.setMapping_0(5.0, 3.0, 4.0) - tmp = bilip.getData() - tmp.resize(3, 2, float()) + tmp = pyopenms.MatrixDouble(3, 2, 0.0) bilip.setData(tmp) self.assertAlmostEqual(bilip.index2key_1(0), -1) self.assertAlmostEqual(bilip.index2key_1(1), 2) @@ -191,43 +189,36 @@ def test_empty(self): bilip = pyopenms.BilinearInterpolation() self.assertTrue(bilip.empty()) - tmp = bilip.getData() - tmp.resize(1, 2, float()) + tmp = pyopenms.MatrixDouble(1, 2, 0.0) bilip.setData(tmp) self.assertFalse(bilip.empty()) - tmp = bilip.getData() - tmp.resize(0, 0, float()) + tmp = pyopenms.MatrixDouble(0, 0, 0.0) bilip.setData(tmp) self.assertTrue(bilip.empty()) - tmp = bilip.getData() - tmp.resize(1, 2, float()) + tmp = pyopenms.MatrixDouble(1, 2, 0.0) bilip.setData(tmp) self.assertFalse(bilip.empty()) - tmp = bilip.getData() - tmp.resize(1, 0, float()) + tmp = pyopenms.MatrixDouble(1, 0, 0.0) bilip.setData(tmp) self.assertTrue(bilip.empty()) - tmp = bilip.getData() - tmp.resize(1, 2, float()) + tmp = pyopenms.MatrixDouble(1, 2, 0.0) bilip.setData(tmp) self.assertFalse(bilip.empty()) - tmp = bilip.getData() - tmp.resize(0, 0, float()) + tmp = pyopenms.MatrixDouble(0, 0, 0.0) bilip.setData(tmp) self.assertTrue(bilip.empty()) - tmp = bilip.getData() - tmp.resize(2, 2, float()) + tmp = pyopenms.MatrixDouble(2, 2, 0.0) bilip.setData(tmp) self.assertFalse(bilip.empty()) tmp = bilip.getData() - tmp.clear() + tmp = pyopenms.MatrixDouble(0, 0, 0.0) bilip.setData(tmp) self.assertTrue(bilip.empty()) @@ -239,23 +230,21 @@ def test_addValue(self): q = j / 10.0 bilip_small = pyopenms.BilinearInterpolation() - tmp = bilip_small.getData() - tmp.resize(5, 5, float()) + tmp = pyopenms.MatrixDouble(5, 5, 0.0) bilip_small.setData(tmp) bilip_small.setMapping_0(0.0, 0.0, 5.0, 5.0) bilip_small.setMapping_1(0.0, 0.0, 5.0, 5.0) bilip_small.addValue(p, q, 100) bilip_big = pyopenms.BilinearInterpolation() - tmp = bilip_big.getData() - tmp.resize(15, 15, float()) + tmp = pyopenms.MatrixDouble(15, 15, 0.0) bilip_big.setData(tmp) bilip_big.setMapping_0(5.0, 0.0, 10.0, 5.0) bilip_big.setMapping_1(5.0, 0.0, 10.0, 5.0) bilip_big.addValue(p, q, 100) - big_submatrix = pyopenms.MatrixDouble() - big_submatrix.resize(5, 5, float()) + big_submatrix = pyopenms.MatrixDouble(5, 5, 0.0) + for m in range(5): for n in range(5): big_submatrix.setValue(m, n, @@ -271,11 +260,8 @@ def test_value(self): bilip_small = pyopenms.BilinearInterpolation() bilip_big = pyopenms.BilinearInterpolation() - tmp_small = bilip_small.getData() - tmp_big = bilip_big.getData() - - tmp_small.resize(5, 5, float()) - tmp_big.resize(15, 15, float()) + tmp_small = pyopenms.MatrixDouble(5, 5, 0.0) + tmp_big = pyopenms.MatrixDouble(15, 15, 0.0) for i in range(5): for j in range(5): From 0fe3c90904d932dd5f63e3b96cb9cf87f1ca8c5c Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Tue, 12 Mar 2024 10:01:49 +0100 Subject: [PATCH 03/17] new attempt with inheritance --- .../include/OpenMS/DATASTRUCTURES/Matrix.h | 86 ++++--------------- .../source/ANALYSIS/OPENSWATH/MRMScoring.cpp | 48 +++++------ .../QUANTITATION/IsotopeLabelingMDVs.cpp | 4 +- .../ANALYSIS/QUANTITATION/ItraqConstants.cpp | 2 +- .../COMPARISON/SPECTRA/PeakAlignment.cpp | 16 ++-- .../MISC/NonNegativeLeastSquaresSolver.cpp | 6 +- src/pyOpenMS/pxds/Matrix.pxd | 1 + 7 files changed, 56 insertions(+), 107 deletions(-) diff --git a/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h b/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h index 3f6eb7820f2..3c95fdd5fb0 100644 --- a/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h +++ b/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h @@ -28,13 +28,15 @@ namespace OpenMS * @ingroup Datastructures */ template - class Matrix + class Matrix : public Eigen::Matrix { public: /** * @brief Eigen matrix type. */ using EigenMatrixType = Eigen::Matrix; + using EigenMatrixType::resize; + using EigenMatrixType::fill; // Default constructor. Creates the "null" matrix. Matrix() = default; @@ -61,33 +63,9 @@ namespace OpenMS * @param cols Number of columns in the matrix. * @param value Initial value to fill the matrix. */ - Matrix(Size rows, Size cols, Value value = Value()) : data_(rows, cols) + Matrix(Size rows, Size cols, Value value = Value()) : EigenMatrixType(rows, cols) { - data_.fill(value); - } - - /** - * @brief Accessor to get the value at the specified position in the matrix. - * - * @param i Row index. - * @param j Column index. - * @return reference to the value at the specified position. - */ - const Value& operator()(int i, int j) const - { - return data_(i, j); - } - - /** - * @brief Accessor to get the value at the specified position in the matrix. - * - * @param i Row index. - * @param j Column index. - * @return const reference to the value at the specified position. - */ - Value& operator()(int i, int j) - { - return data_(i, j); + fill(value); } /* @@ -96,7 +74,7 @@ namespace OpenMS */ const Value& getValue(size_t const i, size_t const j) const { - return data_(i, j); + return *this(i, j); } /* @@ -105,7 +83,7 @@ namespace OpenMS */ Value& getValue(size_t const i, size_t const j) { - return data_(i, j); + return this->operator()(i, j); } /* @@ -114,23 +92,7 @@ namespace OpenMS */ void setValue(size_t const i, size_t const j, const Value& value) { - data_(i, j) = value; - } - - /** - * @brief Number of rows - */ - size_t rows() const - { - return data_.rows(); - } - - /** - * @brief Number of columns - */ - size_t cols() const - { - return data_.cols(); + this->operator()(i, j) = value; } /** @@ -145,15 +107,15 @@ namespace OpenMS * @tparam COLS The number of columns in the matrix. * @param array The 2D array containing the values to be assigned to the matrix. */ - template + template void setMatrix(T const (&array)[ROWS][COLS]) { - data_.resize(ROWS, COLS); + resize(ROWS, COLS); for (int i = 0; i < ROWS; ++i) { for (int j = 0; j < COLS; ++j) { - data_(i, j) = array[i][j]; + this->operator()(i, j) = array[i][j]; } } } @@ -164,20 +126,8 @@ namespace OpenMS * @param rhs The matrix to be compared. * @return True if matrices are equal, false otherwise. */ - bool operator==(const Matrix& rhs) const - { - return data_ == rhs.data_; - } - - /** - * @brief Get the total number of elements in the matrix. Useful for checking if the matrix is empty - * or iterating over raw data. - * - * @return The total number of elements. - */ - size_t size() const - { - return data_.size(); + bool operator==(const Matrix& rhs) const { + return EigenMatrixType::operator==(rhs); } /** @@ -189,9 +139,9 @@ namespace OpenMS */ friend std::ostream& operator<<(std::ostream& os, const Matrix& matrix) { - for (size_t i = 0; i < matrix.rows(); ++i) + for (long int i = 0; i < matrix.rows(); ++i) { - for (size_t j = 0; j < matrix.cols(); ++j) + for (long int j = 0; j < matrix.cols(); ++j) { os << std::setprecision(6) << std::setw(6) << matrix(i, j) << ' '; } @@ -207,7 +157,7 @@ namespace OpenMS */ const EigenMatrixType& getEigenMatrix() const { - return data_; + return *this; } /** @@ -217,9 +167,7 @@ namespace OpenMS */ EigenMatrixType& getEigenMatrix() { - return data_; + return *this; } - private: - EigenMatrixType data_; ///< Eigen matrix storing the actual data. }; } // namespace OpenMS diff --git a/src/openms/source/ANALYSIS/OPENSWATH/MRMScoring.cpp b/src/openms/source/ANALYSIS/OPENSWATH/MRMScoring.cpp index a64e19b7525..2bea1a59c77 100644 --- a/src/openms/source/ANALYSIS/OPENSWATH/MRMScoring.cpp +++ b/src/openms/source/ANALYSIS/OPENSWATH/MRMScoring.cpp @@ -252,9 +252,9 @@ namespace OpenSwath OPENSWATH_PRECONDITION(xcorr_matrix_max_peak_.rows() > 1, "Expect cross-correlation matrix of at least 2x2"); OpenSwath::mean_and_stddev msc; - for (std::size_t i = 0; i < xcorr_matrix_max_peak_.rows(); i++) + for (long int i = 0; i < xcorr_matrix_max_peak_.rows(); i++) { - for (std::size_t j = i; j < xcorr_matrix_max_peak_.rows(); j++) + for (long int j = i; j < xcorr_matrix_max_peak_.rows(); j++) { // first is the X value (RT), should be an int //deltas.push_back(std::abs(Scoring::xcorrArrayGetMaxPeak(xcorr_matrix_.getValue(i, j))->first)); @@ -281,7 +281,7 @@ namespace OpenSwath double weights = 0; #endif double deltas{0}; - for (std::size_t i = 0; i < xcorr_matrix_max_peak_.rows(); i++) + for (long int i = 0; i < xcorr_matrix_max_peak_.rows(); i++) { deltas += (xcorr_matrix_max_peak_(i, i)//std::abs(Scoring::xcorrArrayGetMaxPeak(xcorr_matrix_.getValue(i, i))->first) * normalized_library_intensity[i] @@ -291,7 +291,7 @@ namespace OpenSwath normalized_library_intensity[i] * normalized_library_intensity[i] << std::endl; weights += normalized_library_intensity[i] * normalized_library_intensity[i]; #endif - for (std::size_t j = i + 1; j < xcorr_matrix_max_peak_.rows(); j++) + for (long int j = i + 1; j < xcorr_matrix_max_peak_.rows(); j++) { // first is the X value (RT), should be an int deltas += (xcorr_matrix_max_peak_(i, j)//std::abs(Scoring::xcorrArrayGetMaxPeak(xcorr_matrix_.getValue(i, j))->first) @@ -318,10 +318,10 @@ namespace OpenSwath OPENSWATH_PRECONDITION(xcorr_contrast_matrix_.rows() > 0 && xcorr_contrast_matrix_.cols() > 1, "Expect cross-correlation matrix of at least 1x2"); std::vector deltas; - for (std::size_t i = 0; i < xcorr_contrast_matrix_.rows(); i++) + for (long int i = 0; i < xcorr_contrast_matrix_.rows(); i++) { double deltas_id = 0; - for (std::size_t j = 0; j < xcorr_contrast_matrix_.cols(); j++) + for (long int j = 0; j < xcorr_contrast_matrix_.cols(); j++) { // first is the X value (RT), should be an int auto x = Scoring::xcorrArrayGetMaxPeak(xcorr_contrast_matrix_(i, j)); @@ -341,9 +341,9 @@ namespace OpenSwath OPENSWATH_PRECONDITION(xcorr_precursor_matrix_.rows() > 1, "Expect cross-correlation matrix of at least 2x2"); OpenSwath::mean_and_stddev msc; - for (std::size_t i = 0; i < xcorr_precursor_matrix_.rows(); i++) + for (long int i = 0; i < xcorr_precursor_matrix_.rows(); i++) { - for (std::size_t j = i; j < xcorr_precursor_matrix_.rows(); j++) + for (long int j = i; j < xcorr_precursor_matrix_.rows(); j++) { // first is the X value (RT), should be an int auto x = Scoring::xcorrArrayGetMaxPeak(xcorr_precursor_matrix_(i, j)); @@ -416,9 +416,9 @@ namespace OpenSwath OPENSWATH_PRECONDITION(xcorr_precursor_combined_matrix_.rows() > 1, "Expect cross-correlation matrix of at least 2x2"); OpenSwath::mean_and_stddev msc; - for (std::size_t i = 0; i < xcorr_precursor_combined_matrix_.rows(); i++) + for (long int i = 0; i < xcorr_precursor_combined_matrix_.rows(); i++) { - for (std::size_t j = i; j < xcorr_precursor_combined_matrix_.rows(); j++) + for (long int j = i; j < xcorr_precursor_combined_matrix_.rows(); j++) { // first is the X value (RT), should be an int auto x = Scoring::xcorrArrayGetMaxPeak(xcorr_precursor_combined_matrix_(i, j)); @@ -448,9 +448,9 @@ namespace OpenSwath size_t element_number{0}; double intensities{0}; - for (std::size_t i = 0; i < xcorr_matrix_max_peak_sec_.rows(); i++) + for (long int i = 0; i < xcorr_matrix_max_peak_sec_.rows(); i++) { - for (std::size_t j = i; j < xcorr_matrix_max_peak_sec_.rows(); j++) + for (long int j = i; j < xcorr_matrix_max_peak_sec_.rows(); j++) { // second is the Y value (intensity) intensities += xcorr_matrix_max_peak_sec_(i, j); @@ -469,7 +469,7 @@ namespace OpenSwath // see _calc_weighted_xcorr_shape_score in MRM_pgroup.pm // -- they only multiply up the intensity once double intensities{0}; - for (std::size_t i = 0; i < xcorr_matrix_max_peak_sec_.rows(); i++) + for (long int i = 0; i < xcorr_matrix_max_peak_sec_.rows(); i++) { intensities += (xcorr_matrix_max_peak_sec_(i, i) * normalized_library_intensity[i] @@ -478,7 +478,7 @@ namespace OpenSwath std::cout << "_xcorr_weighted " << i << " " << i << " " << Scoring::xcorrArrayGetMaxPeak(xcorr_matrix_[i][i])->second << " weight " << normalized_library_intensity[i] * normalized_library_intensity[i] << std::endl; #endif - for (std::size_t j = i + 1; j < xcorr_matrix_max_peak_sec_.rows(); j++) + for (long int j = i + 1; j < xcorr_matrix_max_peak_sec_.rows(); j++) { intensities += (xcorr_matrix_max_peak_sec_(i, j) * normalized_library_intensity[i] @@ -504,10 +504,10 @@ namespace OpenSwath OPENSWATH_PRECONDITION(xcorr_contrast_matrix_max_peak_sec_.rows() > 0 && xcorr_contrast_matrix_max_peak_sec_.cols() > 1, "Expect cross-correlation matrix of at least 1x2"); std::vector intensities; - for (std::size_t i = 0; i < xcorr_contrast_matrix_max_peak_sec_.rows(); i++) + for (long int i = 0; i < xcorr_contrast_matrix_max_peak_sec_.rows(); i++) { double intensities_id = 0; - for (std::size_t j = 0; j < xcorr_contrast_matrix_max_peak_sec_.cols(); j++) + for (long int j = 0; j < xcorr_contrast_matrix_max_peak_sec_.cols(); j++) { // second is the Y value (intensity) intensities_id += xcorr_contrast_matrix_max_peak_sec_(i,j); @@ -523,9 +523,9 @@ namespace OpenSwath OPENSWATH_PRECONDITION(xcorr_precursor_matrix_.rows() > 1, "Expect cross-correlation matrix of at least 2x2"); double intensities{0}; - for(size_t i = 0; i < xcorr_precursor_matrix_.rows(); i++) + for(long int i = 0; i < xcorr_precursor_matrix_.rows(); i++) { - for(size_t j = i; j < xcorr_precursor_matrix_.cols(); j++) + for(long int j = i; j < xcorr_precursor_matrix_.cols(); j++) { auto x = Scoring::xcorrArrayGetMaxPeak(xcorr_precursor_matrix_(i, j)); intensities += x->second; @@ -573,9 +573,9 @@ namespace OpenSwath OPENSWATH_PRECONDITION(xcorr_precursor_combined_matrix_.rows() > 1, "Expect cross-correlation matrix of at least 2x2"); double intensities{0}; - for(size_t i = 0; i < xcorr_precursor_combined_matrix_.rows(); i++) + for(long int i = 0; i < xcorr_precursor_combined_matrix_.rows(); i++) { - for(size_t j = i; j < xcorr_precursor_combined_matrix_.cols(); j++) + for(long int j = i; j < xcorr_precursor_combined_matrix_.cols(); j++) { auto x = Scoring::xcorrArrayGetMaxPeak(xcorr_precursor_combined_matrix_(i, j)); intensities += x->second; @@ -837,7 +837,7 @@ namespace OpenSwath OPENSWATH_PRECONDITION(mi_matrix_.rows() > 1, "Expect mutual information matrix of at least 2x2"); double mi_scores{0}; - for (std::size_t i = 0; i < mi_matrix_.rows(); i++) + for (long int i = 0; i < mi_matrix_.rows(); i++) { mi_scores += mi_matrix_(i, i) * normalized_library_intensity[i] @@ -846,7 +846,7 @@ namespace OpenSwath std::cout << "_mi_weighted " << i << " " << i << " " << mi_matrix_[i][i] << " weight " << normalized_library_intensity[i] * normalized_library_intensity[i] << std::endl; #endif - for (std::size_t j = i + 1; j < mi_matrix_.rows(); j++) + for (long int j = i + 1; j < mi_matrix_.rows(); j++) { mi_scores += mi_matrix_(i, j) * normalized_library_intensity[i] @@ -900,10 +900,10 @@ namespace OpenSwath std::vector mi_scores; mi_scores.resize(mi_contrast_matrix_.rows()); - for (std::size_t i = 0; i < mi_contrast_matrix_.rows(); i++) + for (long int i = 0; i < mi_contrast_matrix_.rows(); i++) { double mi_scores_id = 0; - for (std::size_t j = 0; j < mi_contrast_matrix_.cols(); j++) + for (long int j = 0; j < mi_contrast_matrix_.cols(); j++) { mi_scores_id += mi_contrast_matrix_(i, j); } diff --git a/src/openms/source/ANALYSIS/QUANTITATION/IsotopeLabelingMDVs.cpp b/src/openms/source/ANALYSIS/QUANTITATION/IsotopeLabelingMDVs.cpp index 08dce160b27..2dfc52ad344 100644 --- a/src/openms/source/ANALYSIS/QUANTITATION/IsotopeLabelingMDVs.cpp +++ b/src/openms/source/ANALYSIS/QUANTITATION/IsotopeLabelingMDVs.cpp @@ -84,9 +84,9 @@ namespace OpenMS else { correction_matrix_eigen.resize(correction_matrix.rows(), correction_matrix.cols()); - for (size_t i = 0; i < correction_matrix.rows(); ++i) + for (long int i = 0; i < correction_matrix.rows(); ++i) { - for (size_t j = 0; j < correction_matrix.cols(); ++j) + for (long int j = 0; j < correction_matrix.cols(); ++j) { correction_matrix_eigen(i,j) = correction_matrix(i,j); } diff --git a/src/openms/source/ANALYSIS/QUANTITATION/ItraqConstants.cpp b/src/openms/source/ANALYSIS/QUANTITATION/ItraqConstants.cpp index e5d3cdb99b4..af586478933 100644 --- a/src/openms/source/ANALYSIS/QUANTITATION/ItraqConstants.cpp +++ b/src/openms/source/ANALYSIS/QUANTITATION/ItraqConstants.cpp @@ -177,7 +177,7 @@ namespace OpenMS channel_names[2].setMatrix(CHANNELS_TMT_SIXPLEX); map.clear(); - for (Size i = 0; i < channel_names[itraq_type].rows(); ++i) + for (long int i = 0; i < channel_names[itraq_type].rows(); ++i) { ChannelInfo info; info.description = ""; diff --git a/src/openms/source/COMPARISON/SPECTRA/PeakAlignment.cpp b/src/openms/source/COMPARISON/SPECTRA/PeakAlignment.cpp index 3601171a0f9..7c15e2978d4 100644 --- a/src/openms/source/COMPARISON/SPECTRA/PeakAlignment.cpp +++ b/src/openms/source/COMPARISON/SPECTRA/PeakAlignment.cpp @@ -100,11 +100,11 @@ namespace OpenMS //initialize alignment matrix with 0 in (0,0) and a multiple of gapcost in the first row/col matrix(row,col,values) Matrix matrix(spec1.size() + 1, spec2.size() + 1, 0); - for (Size i = 1; i < matrix.rows(); i++) + for (long int i = 1; i < matrix.rows(); i++) { matrix(i, 0) = -gap * i; } - for (Size i = 1; i < matrix.cols(); i++) + for (long int i = 1; i < matrix.cols(); i++) { matrix(0, i) = -gap * i; } @@ -184,11 +184,11 @@ namespace OpenMS //get best overall score and return double best_score(numeric_limits::min()); - for (Size i = 0; i < matrix.cols(); i++) + for (long int i = 0; i < matrix.cols(); i++) { best_score = max(best_score, matrix(matrix.rows() - 1, i)); } - for (Size i = 0; i < matrix.rows(); i++) + for (long int i = 0; i < matrix.rows(); i++) { best_score = max(best_score, matrix(i, matrix.cols() - 1)); } @@ -235,11 +235,11 @@ namespace OpenMS //initialize alignment matrix with 0 in (0,0) and a multiple of gapcost in the first row/col matrix(row,col,values) Matrix matrix(spec1.size() + 1, spec2.size() + 1, 0); - for (Size i = 1; i < matrix.rows(); i++) + for (long int i = 1; i < matrix.rows(); i++) { matrix(i, 0) = -gap * i; } - for (Size i = 1; i < matrix.cols(); i++) + for (long int i = 1; i < matrix.cols(); i++) { matrix(0, i) = -gap * i; } @@ -346,7 +346,7 @@ namespace OpenMS //get matrix coordinates from best alloverscore Size row_index(0), col_index(0); double best_score(numeric_limits::min()); - for (Size i = 0; i < matrix.cols(); i++) + for (long int i = 0; i < matrix.cols(); i++) { if (best_score < matrix(matrix.rows() - 1, i)) { @@ -355,7 +355,7 @@ namespace OpenMS col_index = i; } } - for (Size i = 0; i < matrix.rows(); i++) + for (long int i = 0; i < matrix.rows(); i++) { if (best_score < matrix(i, matrix.cols() - 1)) { diff --git a/src/openms/source/MATH/MISC/NonNegativeLeastSquaresSolver.cpp b/src/openms/source/MATH/MISC/NonNegativeLeastSquaresSolver.cpp index af72bf38877..b5fe54df4ac 100644 --- a/src/openms/source/MATH/MISC/NonNegativeLeastSquaresSolver.cpp +++ b/src/openms/source/MATH/MISC/NonNegativeLeastSquaresSolver.cpp @@ -22,9 +22,9 @@ namespace OpenMS // translate A to array a (column major order) double * a_vec = new double[A.rows() * A.cols()]; size_t idx = 0; - for (size_t col = 0; col < A.cols(); ++col) + for (long int col = 0; col < A.cols(); ++col) { - for (size_t row = 0; row < A.rows(); ++row) + for (long int row = 0; row < A.rows(); ++row) { a_vec[idx] = A(row, col); idx++; @@ -41,7 +41,7 @@ namespace OpenMS // translate b double * b_vec = new double[a_rows]; - for (size_t row = 0; row < b.rows(); ++row) + for (long int row = 0; row < b.rows(); ++row) { b_vec[row] = b(row, 0); } diff --git a/src/pyOpenMS/pxds/Matrix.pxd b/src/pyOpenMS/pxds/Matrix.pxd index 102c0cdce9b..5180d558ddf 100644 --- a/src/pyOpenMS/pxds/Matrix.pxd +++ b/src/pyOpenMS/pxds/Matrix.pxd @@ -17,6 +17,7 @@ cdef extern from "" namespace "OpenMS": size_t rows() nogil size_t cols() nogil size_t size() nogil + ValueT* data() nogil ## bool operator==(Matrix & rhs) except + nogil ## bool operator<(Matrix & rhs) except + nogil # TEMPLATE # void setMatrix(ValueType matrix) except + nogil From adb5e6b608ce7f49f420aa4f0a0741fb0609e31e Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Wed, 13 Mar 2024 22:37:05 +0100 Subject: [PATCH 04/17] fix normal test --- src/pyOpenMS/addons/MatrixDouble.pyx | 38 ++++++------------------- src/pyOpenMS/tests/unittests/test000.py | 2 ++ 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index 6a43cc3ac4d..b07de66fbd2 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -1,30 +1,19 @@ from Matrix cimport * - +cimport numpy as np # continue with extra code if needed def get_matrix_as_view(self): - """Cython signature: numpy_matrix get_matrix() + """Cython signature: numpy_matrix get_matrix_as_view() """ cdef _Matrix[double] * mat_ = self.inst.get() cdef unsigned int rows = mat_.rows() cdef unsigned int cols = mat_.cols() - cdef unsigned int n = rows * cols - cdef np.ndarray[double, ndim=2] data - data = np.zeros( (rows,cols), dtype=np.float64) - - cdef libcpp_vector[double] * vec_ptr = mat_ - cdef double * raw_ptr = address(deref(vec_ptr)[0]) - - ## # We use a memory view to get the data from the raw data - ## # See https://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html - ## # See https://stackoverflow.com/questions/43021574/cast-c-array-into-numpy-array-cython-typed-memoryview-in-cython-code - cdef double[:] vec_view = raw_ptr # cast to memoryview, refer to the underlying buffer without copy - xarr = np.asarray(vec_view) # numpy array refer to the underlying buffer without copy - xarr = xarr.reshape(rows, cols) - return xarr.transpose() + cdef double* data = mat_.data() + # Create a NumPy array from the buffer, specifying not to copy the data. + return np.array( data, copy=False).reshape(rows, cols) def get_matrix(self): @@ -32,23 +21,12 @@ from Matrix cimport * """ cdef _Matrix[double] * mat_ = self.inst.get() - cdef unsigned int rows = mat_.rows() cdef unsigned int cols = mat_.cols() - cdef unsigned int n = rows * cols - cdef np.ndarray[double, ndim=2] data - data = np.zeros( (rows,cols), dtype=np.float64) - - cdef libcpp_vector[double] * vec_ptr = mat_ - cdef double * raw_ptr = address(deref(vec_ptr)[0]) + cdef double* data = mat_.data() + # Create a NumPy array from the buffer, specifying not to copy the data. + return np.array( data, copy=True).reshape(rows, cols) - ## # We use a memory view to get the data from the raw data - ## # See https://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html - ## # See https://stackoverflow.com/questions/43021574/cast-c-array-into-numpy-array-cython-typed-memoryview-in-cython-code - cdef double[:] vec_view = raw_ptr # cast to memoryview, refer to the underlying buffer without copy - xarr = np.asarray(vec_view) # numpy array refer to the underlying buffer without copy - xarr = xarr.reshape(rows, cols) - return xarr.transpose().copy() # def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): # """Cython signature: numpy_matrix set_matrix() diff --git a/src/pyOpenMS/tests/unittests/test000.py b/src/pyOpenMS/tests/unittests/test000.py index 7f6f1d4e44c..199f998f554 100644 --- a/src/pyOpenMS/tests/unittests/test000.py +++ b/src/pyOpenMS/tests/unittests/test000.py @@ -3666,7 +3666,9 @@ def testMatrixDouble(): m.setValue(3, 5, 8.0) assert m.getValue(3, 5) == 8.0 + print(m) mat = m.get_matrix_as_view() + print(mat) assert mat[3, 5] == 8.0 mat = m.get_matrix() From 8e06fab1ca8cf289c306e5783a5955d433a65874 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Thu, 14 Mar 2024 09:24:23 +0100 Subject: [PATCH 05/17] why? --- src/pyOpenMS/pxds/Matrix.pxd | 2 +- src/pyOpenMS/tests/unittests/test000.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pyOpenMS/pxds/Matrix.pxd b/src/pyOpenMS/pxds/Matrix.pxd index 5180d558ddf..ee4afc73629 100644 --- a/src/pyOpenMS/pxds/Matrix.pxd +++ b/src/pyOpenMS/pxds/Matrix.pxd @@ -17,7 +17,7 @@ cdef extern from "" namespace "OpenMS": size_t rows() nogil size_t cols() nogil size_t size() nogil - ValueT* data() nogil + ValueT* data() nogil # wrap-ignore ## bool operator==(Matrix & rhs) except + nogil ## bool operator<(Matrix & rhs) except + nogil # TEMPLATE # void setMatrix(ValueType matrix) except + nogil diff --git a/src/pyOpenMS/tests/unittests/test000.py b/src/pyOpenMS/tests/unittests/test000.py index 199f998f554..037e711c238 100644 --- a/src/pyOpenMS/tests/unittests/test000.py +++ b/src/pyOpenMS/tests/unittests/test000.py @@ -3659,21 +3659,21 @@ def testMatrixDouble(): assert sum(sum(matrix_view)) == (N-1)*(N+2)*5 - # Column = 3 / Row = 5 + # Column = 2 / Row = 3 ## Now change a value: - assert m.getValue(3, 5) == 5.0 - m.setValue(3, 5, 8.0) - assert m.getValue(3, 5) == 8.0 + assert m.getValue(2, 3) == 5.0 + m.setValue(2, 3, 8.0) + assert m.getValue(2, 3) == 8.0 print(m) mat = m.get_matrix_as_view() print(mat) - assert mat[3, 5] == 8.0 + assert mat[2, 3] == 8.0 mat = m.get_matrix() - assert m.getValue(3, 5) == 8.0 - assert mat[3, 5] == 8.0 + assert m.getValue(2, 3) == 8.0 + assert mat[2, 3] == 8.0 # Whatever we change here gets changed in the raw data as well matrix_view = m.get_matrix_as_view() @@ -3687,7 +3687,7 @@ def testMatrixDouble(): mat[3, 6] = 9.0 m.set_matrix(mat) - assert m.getValue(3, 5) == 8.0 + assert m.getValue(2, 3) == 8.0 assert m.getValue(3, 6) == 9.0 From f6aafe958d42ab23cd0775e95fb6f61d75d9c29a Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Thu, 14 Mar 2024 09:56:15 +0100 Subject: [PATCH 06/17] 1,2 --- src/pyOpenMS/tests/unittests/test000.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pyOpenMS/tests/unittests/test000.py b/src/pyOpenMS/tests/unittests/test000.py index 037e711c238..8fb92c67f6c 100644 --- a/src/pyOpenMS/tests/unittests/test000.py +++ b/src/pyOpenMS/tests/unittests/test000.py @@ -3659,21 +3659,21 @@ def testMatrixDouble(): assert sum(sum(matrix_view)) == (N-1)*(N+2)*5 - # Column = 2 / Row = 3 + # Column = 1 / Row = 2 ## Now change a value: - assert m.getValue(2, 3) == 5.0 - m.setValue(2, 3, 8.0) - assert m.getValue(2, 3) == 8.0 + assert m.getValue(1, 2) == 5.0 + m.setValue(1, 2, 8.0) + assert m.getValue(1, 2) == 8.0 print(m) mat = m.get_matrix_as_view() print(mat) - assert mat[2, 3] == 8.0 + assert mat[1, 2] == 8.0 mat = m.get_matrix() - assert m.getValue(2, 3) == 8.0 - assert mat[2, 3] == 8.0 + assert m.getValue(1, 2) == 8.0 + assert mat[1, 2] == 8.0 # Whatever we change here gets changed in the raw data as well matrix_view = m.get_matrix_as_view() @@ -3687,7 +3687,7 @@ def testMatrixDouble(): mat[3, 6] = 9.0 m.set_matrix(mat) - assert m.getValue(2, 3) == 8.0 + assert m.getValue(1, 2) == 8.0 assert m.getValue(3, 6) == 9.0 From 146953c367184d50c1dc1f40b355ea95ca87119c Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Fri, 15 Mar 2024 00:57:37 +0100 Subject: [PATCH 07/17] test --- src/pyOpenMS/addons/MatrixDouble.pyx | 41 ++++++++++++++++++++++--- src/pyOpenMS/tests/unittests/test000.py | 14 +++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index b07de66fbd2..47bc287fb67 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -1,11 +1,44 @@ from Matrix cimport * cimport numpy as np +from numpy.lib.stride_tricks import as_strided # continue with extra code if needed - def get_matrix_as_view(self): """Cython signature: numpy_matrix get_matrix_as_view() """ + cdef _Matrix[double] * mat_ = self.inst.get() + + cdef unsigned int rows = mat_.rows() + cdef unsigned int cols = mat_.cols() + cdef double* data = mat_.data() + cdef double[:,:] mem_view = data + dtype = 'double' + cdef int itemsize = np.dtype(dtype).itemsize + cdef int row_stride = 1 + cdef int col_stride = 1 + + return as_strided(np.asarray(mem_view, dtype=dtype, order="C"), strides=[row_stride*itemsize, col_stride*itemsize]) + + def get_matrix(self): + """Cython signature: numpy_matrix get_matrix() + """ + cdef _Matrix[double] * mat_ = self.inst.get() + + cdef unsigned int rows = mat_.rows() + cdef unsigned int cols = mat_.cols() + cdef double* data = mat_.data() + cdef double[:,:] mem_view = data + dtype = 'double' + cdef int itemsize = np.dtype(dtype).itemsize + cdef int row_stride = 1 + cdef int col_stride = 1 + + return np.copy(as_strided(np.asarray(mem_view, dtype=dtype, order="C"), strides=[row_stride*itemsize, col_stride*itemsize])) + + + def get_matrix_as_view2(self): + """Cython signature: numpy_matrix get_matrix_as_view() + """ cdef _Matrix[double] * mat_ = self.inst.get() @@ -13,10 +46,10 @@ cimport numpy as np cdef unsigned int cols = mat_.cols() cdef double* data = mat_.data() # Create a NumPy array from the buffer, specifying not to copy the data. - return np.array( data, copy=False).reshape(rows, cols) + return np.array( data, order='C', copy=False).reshape(rows, cols) - def get_matrix(self): + def get_matrix2(self): """Cython signature: numpy_matrix get_matrix() """ @@ -25,7 +58,7 @@ cimport numpy as np cdef unsigned int cols = mat_.cols() cdef double* data = mat_.data() # Create a NumPy array from the buffer, specifying not to copy the data. - return np.array( data, copy=True).reshape(rows, cols) + return np.array( data, order='C', copy=True).reshape(rows, cols) # def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): diff --git a/src/pyOpenMS/tests/unittests/test000.py b/src/pyOpenMS/tests/unittests/test000.py index 8fb92c67f6c..9f03d134fba 100644 --- a/src/pyOpenMS/tests/unittests/test000.py +++ b/src/pyOpenMS/tests/unittests/test000.py @@ -3631,6 +3631,20 @@ def testMatrixDouble(): MapAlignmentAlgorithmIdentification.__init__ """ + m = pyopenms.MatrixDouble(3, 2, 0.0) + for i in range(3): + for j in range(2): + m.setValue(i, j, i * 10.0 + j) + print(m) + + mv = m.get_matrix_as_view() + print(mv) + + mc = m.get_matrix() + print(mc) + + mat = m.get_matrix_as_view() + N = 90 m = pyopenms.MatrixDouble(N-1, N+2, 5.0) From 47d9374a9afe66433f45ad965480fdab54ea60a6 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Fri, 15 Mar 2024 08:28:03 +0100 Subject: [PATCH 08/17] set order in reshape --- src/pyOpenMS/addons/MatrixDouble.pyx | 69 +++++++--------------------- 1 file changed, 17 insertions(+), 52 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index 47bc287fb67..11095845f29 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -1,42 +1,11 @@ from Matrix cimport * cimport numpy as np -from numpy.lib.stride_tricks import as_strided + # continue with extra code if needed - def get_matrix_as_view(self): - """Cython signature: numpy_matrix get_matrix_as_view() - """ - cdef _Matrix[double] * mat_ = self.inst.get() - - cdef unsigned int rows = mat_.rows() - cdef unsigned int cols = mat_.cols() - cdef double* data = mat_.data() - cdef double[:,:] mem_view = data - dtype = 'double' - cdef int itemsize = np.dtype(dtype).itemsize - cdef int row_stride = 1 - cdef int col_stride = 1 - - return as_strided(np.asarray(mem_view, dtype=dtype, order="C"), strides=[row_stride*itemsize, col_stride*itemsize]) - - def get_matrix(self): - """Cython signature: numpy_matrix get_matrix() - """ - cdef _Matrix[double] * mat_ = self.inst.get() - - cdef unsigned int rows = mat_.rows() - cdef unsigned int cols = mat_.cols() - cdef double* data = mat_.data() - cdef double[:,:] mem_view = data - dtype = 'double' - cdef int itemsize = np.dtype(dtype).itemsize - cdef int row_stride = 1 - cdef int col_stride = 1 - - return np.copy(as_strided(np.asarray(mem_view, dtype=dtype, order="C"), strides=[row_stride*itemsize, col_stride*itemsize])) - def get_matrix_as_view2(self): + def get_matrix_as_view(self): """Cython signature: numpy_matrix get_matrix_as_view() """ @@ -46,10 +15,10 @@ from numpy.lib.stride_tricks import as_strided cdef unsigned int cols = mat_.cols() cdef double* data = mat_.data() # Create a NumPy array from the buffer, specifying not to copy the data. - return np.array( data, order='C', copy=False).reshape(rows, cols) + return np.array( data, order='F', copy=False).reshape(rows, cols, order='F') - def get_matrix2(self): + def get_matrix(self): """Cython signature: numpy_matrix get_matrix() """ @@ -57,25 +26,21 @@ from numpy.lib.stride_tricks import as_strided cdef unsigned int rows = mat_.rows() cdef unsigned int cols = mat_.cols() cdef double* data = mat_.data() - # Create a NumPy array from the buffer, specifying not to copy the data. - return np.array( data, order='C', copy=True).reshape(rows, cols) + return np.array( data, order='F', copy=True).reshape(rows, cols, order='F') + def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): + """Cython signature: numpy_matrix set_matrix() + """ -# def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): -# """Cython signature: numpy_matrix set_matrix() -# """ -# -# cdef _Matrix[double] * mat_ = self.inst.get() -# -# cdef unsigned int rows = data.shape[0] -# cdef unsigned int cols = data.shape[1] -# mat_.resize(rows, cols, 0) -# -# cdef int i = 0 -# cdef int j = 0 -# for i in range(int(rows)): -# for j in range(int(cols)): -# mat_.setValue(i,j,data[i][j]) + cdef _Matrix[double] * mat_ = self.inst.get() + cdef unsigned int rows = data.shape[0] + cdef unsigned int cols = data.shape[1] + mat_.resize(rows, cols, 0) + cdef int i = 0 + cdef int j = 0 + for i in range(int(rows)): + for j in range(int(cols)): + mat_.setValue(i,j,data[i][j]) From 02d7a93e4ef07a50a23148cd8820b899eb6c08f4 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Fri, 15 Mar 2024 08:32:25 +0100 Subject: [PATCH 09/17] fix compile errors --- src/pyOpenMS/addons/MatrixDouble.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index 11095845f29..a6314a7343d 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -36,7 +36,7 @@ cimport numpy as np cdef unsigned int rows = data.shape[0] cdef unsigned int cols = data.shape[1] - mat_.resize(rows, cols, 0) + mat_.resize(rows, cols) cdef int i = 0 cdef int j = 0 From 48f55af186142ac3a38cfc251b29b96662b4c515 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Fri, 15 Mar 2024 09:37:53 +0100 Subject: [PATCH 10/17] fix --- src/pyOpenMS/addons/MatrixDouble.pyx | 24 ++++++++++++------------ src/pyOpenMS/pxds/Matrix.pxd | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index a6314a7343d..9970f3eeb40 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -28,19 +28,19 @@ cimport numpy as np cdef double* data = mat_.data() return np.array( data, order='F', copy=True).reshape(rows, cols, order='F') - def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): - """Cython signature: numpy_matrix set_matrix() - """ +# def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): +# """Cython signature: numpy_matrix set_matrix() +# """ - cdef _Matrix[double] * mat_ = self.inst.get() +# cdef _Matrix[double] * mat_ = self.inst.get() - cdef unsigned int rows = data.shape[0] - cdef unsigned int cols = data.shape[1] - mat_.resize(rows, cols) +# cdef unsigned int rows = data.shape[0] +# cdef unsigned int cols = data.shape[1] +# mat_.resize(rows, cols) - cdef int i = 0 - cdef int j = 0 - for i in range(int(rows)): - for j in range(int(cols)): - mat_.setValue(i,j,data[i][j]) +# cdef int i = 0 +# cdef int j = 0 +# for i in range(int(rows)): +# for j in range(int(cols)): +# mat_.setValue(i,j,data[i][j]) diff --git a/src/pyOpenMS/pxds/Matrix.pxd b/src/pyOpenMS/pxds/Matrix.pxd index ee4afc73629..d0057a73c56 100644 --- a/src/pyOpenMS/pxds/Matrix.pxd +++ b/src/pyOpenMS/pxds/Matrix.pxd @@ -17,6 +17,7 @@ cdef extern from "" namespace "OpenMS": size_t rows() nogil size_t cols() nogil size_t size() nogil + #resize(size_t rows, size_t cols) nogil ValueT* data() nogil # wrap-ignore ## bool operator==(Matrix & rhs) except + nogil ## bool operator<(Matrix & rhs) except + nogil From 0c19ad3bb4145e480511c013dbe4bd3b1202ec02 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Fri, 15 Mar 2024 16:31:05 +0100 Subject: [PATCH 11/17] why --- .../include/OpenMS/DATASTRUCTURES/Matrix.h | 24 ++++++++++++++- src/pyOpenMS/addons/MatrixDouble.pyx | 29 ++++++++++++++++--- src/pyOpenMS/pxds/Matrix.pxd | 3 ++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h b/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h index 3c95fdd5fb0..81d034c0ec7 100644 --- a/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h +++ b/src/openms/include/OpenMS/DATASTRUCTURES/Matrix.h @@ -35,8 +35,9 @@ namespace OpenMS * @brief Eigen matrix type. */ using EigenMatrixType = Eigen::Matrix; - using EigenMatrixType::resize; using EigenMatrixType::fill; + using EigenMatrixType::innerStride; + using EigenMatrixType::outerStride; // Default constructor. Creates the "null" matrix. Matrix() = default; @@ -95,6 +96,27 @@ namespace OpenMS this->operator()(i, j) = value; } + // apparently needed for cython + void resize(size_t rows, size_t cols) + { + EigenMatrixType::resize(rows, cols); + } + + int innerStride() const + { + return EigenMatrixType::innerStride(); + } + + int outerStride() const + { + return EigenMatrixType::outerStride(); + } + + bool rowMajor() const + { + return EigenMatrixType::IsRowMajor; + } + /** * @brief Sets the matrix values using a 2D array. * diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index 9970f3eeb40..478aa7c3e0e 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -1,5 +1,6 @@ from Matrix cimport * cimport numpy as np +from numpy.lib.stride_tricks import as_strided # continue with extra code if needed @@ -10,12 +11,21 @@ cimport numpy as np """ cdef _Matrix[double] * mat_ = self.inst.get() - cdef unsigned int rows = mat_.rows() cdef unsigned int cols = mat_.cols() cdef double* data = mat_.data() - # Create a NumPy array from the buffer, specifying not to copy the data. - return np.array( data, order='F', copy=False).reshape(rows, cols, order='F') + cdef double[:,:] mem_view = data + dtype = 'double' + cdef int itemsize = np.dtype(dtype).itemsize + cdef unsigned int row_stride, col_stride + if mat_.rowMajor(): + row_stride = mat_.outerStride() if mat_.outerStride() > 0 else cols + col_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 + else: + row_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 + col_stride = mat_.outerStride() if mat_.outerStride() > 0 else rows + + return np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order="F"), strides=[row_stride*itemsize, col_stride*itemsize]) def get_matrix(self): @@ -26,7 +36,18 @@ cimport numpy as np cdef unsigned int rows = mat_.rows() cdef unsigned int cols = mat_.cols() cdef double* data = mat_.data() - return np.array( data, order='F', copy=True).reshape(rows, cols, order='F') + cdef double[:,:] mem_view = data + dtype = 'double' + cdef int itemsize = np.dtype(dtype).itemsize + cdef unsigned int row_stride, col_stride + if mat_.rowMajor(): + row_stride = mat_.outerStride() if mat_.outerStride() > 0 else cols + col_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 + else: + row_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 + col_stride = mat_.outerStride() if mat_.outerStride() > 0 else rows + + return np.copy(np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order="F"), strides=[row_stride*itemsize, col_stride*itemsize])) # def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): # """Cython signature: numpy_matrix set_matrix() diff --git a/src/pyOpenMS/pxds/Matrix.pxd b/src/pyOpenMS/pxds/Matrix.pxd index d0057a73c56..eaa188a2eb1 100644 --- a/src/pyOpenMS/pxds/Matrix.pxd +++ b/src/pyOpenMS/pxds/Matrix.pxd @@ -17,6 +17,9 @@ cdef extern from "" namespace "OpenMS": size_t rows() nogil size_t cols() nogil size_t size() nogil + int innerStride() nogil # wrap-ignore + int outerStride() nogil # wrap-ignore + bool rowMajor() nogil # wrap-ignore #resize(size_t rows, size_t cols) nogil ValueT* data() nogil # wrap-ignore ## bool operator==(Matrix & rhs) except + nogil From f8da39233b63fa89cc76803ac14627533c97bfc0 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Fri, 15 Mar 2024 16:41:34 +0100 Subject: [PATCH 12/17] yeeeeeeeeeees --- src/pyOpenMS/addons/MatrixDouble.pyx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index 478aa7c3e0e..f9c5fe922e0 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -18,14 +18,17 @@ from numpy.lib.stride_tricks import as_strided dtype = 'double' cdef int itemsize = np.dtype(dtype).itemsize cdef unsigned int row_stride, col_stride + o = 'F' if mat_.rowMajor(): row_stride = mat_.outerStride() if mat_.outerStride() > 0 else cols col_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 + o = 'F' else: row_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 col_stride = mat_.outerStride() if mat_.outerStride() > 0 else rows + o = 'C' - return np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order="F"), strides=[row_stride*itemsize, col_stride*itemsize]) + return np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order=o), strides=[row_stride*itemsize, col_stride*itemsize]) def get_matrix(self): @@ -40,14 +43,18 @@ from numpy.lib.stride_tricks import as_strided dtype = 'double' cdef int itemsize = np.dtype(dtype).itemsize cdef unsigned int row_stride, col_stride + o = 'F' + if mat_.rowMajor(): row_stride = mat_.outerStride() if mat_.outerStride() > 0 else cols col_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 + o = 'F' else: row_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 col_stride = mat_.outerStride() if mat_.outerStride() > 0 else rows + o = 'C' - return np.copy(np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order="F"), strides=[row_stride*itemsize, col_stride*itemsize])) + return np.copy(np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order=o), strides=[row_stride*itemsize, col_stride*itemsize])) # def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): # """Cython signature: numpy_matrix set_matrix() From aa31df00305394ae19c4c98f32086201464a5889 Mon Sep 17 00:00:00 2001 From: Timo Sachsenberg Date: Fri, 15 Mar 2024 17:05:00 +0100 Subject: [PATCH 13/17] added back set_matrix --- src/pyOpenMS/addons/MatrixDouble.pyx | 24 ++++++++++++------------ src/pyOpenMS/pxds/Matrix.pxd | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index f9c5fe922e0..abddf6d7eec 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -56,19 +56,19 @@ from numpy.lib.stride_tricks import as_strided return np.copy(np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order=o), strides=[row_stride*itemsize, col_stride*itemsize])) -# def set_matrix(self, np.ndarray[double, ndim=2, mode="c"] data not None): -# """Cython signature: numpy_matrix set_matrix() -# """ + def set_matrix(self, np.ndarray[double, ndim=2] data not None): + """Cython signature: numpy_matrix set_matrix() + """ -# cdef _Matrix[double] * mat_ = self.inst.get() + cdef _Matrix[double] * mat_ = self.inst.get() -# cdef unsigned int rows = data.shape[0] -# cdef unsigned int cols = data.shape[1] -# mat_.resize(rows, cols) + cdef unsigned int rows = data.shape[0] + cdef unsigned int cols = data.shape[1] + mat_.resize(rows, cols) -# cdef int i = 0 -# cdef int j = 0 -# for i in range(int(rows)): -# for j in range(int(cols)): -# mat_.setValue(i,j,data[i][j]) + cdef int i = 0 + cdef int j = 0 + for i in range(int(rows)): + for j in range(int(cols)): + mat_.setValue(i, j, data[i][j]) diff --git a/src/pyOpenMS/pxds/Matrix.pxd b/src/pyOpenMS/pxds/Matrix.pxd index eaa188a2eb1..b289b87eff5 100644 --- a/src/pyOpenMS/pxds/Matrix.pxd +++ b/src/pyOpenMS/pxds/Matrix.pxd @@ -20,7 +20,7 @@ cdef extern from "" namespace "OpenMS": int innerStride() nogil # wrap-ignore int outerStride() nogil # wrap-ignore bool rowMajor() nogil # wrap-ignore - #resize(size_t rows, size_t cols) nogil + void resize(size_t rows, size_t cols) nogil ValueT* data() nogil # wrap-ignore ## bool operator==(Matrix & rhs) except + nogil ## bool operator<(Matrix & rhs) except + nogil From a905b2e4cce600176649abf4018a4c6c4b11fcd3 Mon Sep 17 00:00:00 2001 From: julianuspfeuffer Date: Sat, 16 Mar 2024 10:41:32 +0100 Subject: [PATCH 14/17] docs and refactor --- src/pyOpenMS/addons/MatrixDouble.pyx | 36 +++++++++++----------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/pyOpenMS/addons/MatrixDouble.pyx b/src/pyOpenMS/addons/MatrixDouble.pyx index abddf6d7eec..534160b8b9b 100644 --- a/src/pyOpenMS/addons/MatrixDouble.pyx +++ b/src/pyOpenMS/addons/MatrixDouble.pyx @@ -7,7 +7,13 @@ from numpy.lib.stride_tricks import as_strided def get_matrix_as_view(self): - """Cython signature: numpy_matrix get_matrix_as_view() + """get_matrix(self) -> np.ndarray[double, ndim=2] + + Returns a view on the underlying Matrix as a 2D numpy ndarray. + .. caution:: + Future changes to the Matrix will affect the ndarray and vice versa. + Make sure that the Matrix does not go out of scope before the last use + of your ndarray. """ cdef _Matrix[double] * mat_ = self.inst.get() @@ -32,32 +38,18 @@ from numpy.lib.stride_tricks import as_strided def get_matrix(self): - """Cython signature: numpy_matrix get_matrix() + """get_matrix(self) -> np.ndarray[double, ndim=2] + + Returns a copy of the underlying Matrix as a 2D numpy ndarray. """ - cdef _Matrix[double] * mat_ = self.inst.get() - cdef unsigned int rows = mat_.rows() - cdef unsigned int cols = mat_.cols() - cdef double* data = mat_.data() - cdef double[:,:] mem_view = data - dtype = 'double' - cdef int itemsize = np.dtype(dtype).itemsize - cdef unsigned int row_stride, col_stride - o = 'F' - - if mat_.rowMajor(): - row_stride = mat_.outerStride() if mat_.outerStride() > 0 else cols - col_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 - o = 'F' - else: - row_stride = mat_.innerStride() if mat_.innerStride() > 0 else 1 - col_stride = mat_.outerStride() if mat_.outerStride() > 0 else rows - o = 'C' + return np.copy(self.get_matrix_as_view()) - return np.copy(np.lib.stride_tricks.as_strided(np.asarray(mem_view, dtype=dtype, order=o), strides=[row_stride*itemsize, col_stride*itemsize])) def set_matrix(self, np.ndarray[double, ndim=2] data not None): - """Cython signature: numpy_matrix set_matrix() + """set_matrix(self, data: np.ndarray[double, ndim=2]) -> None + + Copies the values from the numpy ndarray into the Matrix. """ cdef _Matrix[double] * mat_ = self.inst.get() From 65f728755083b7d7a1039fb0e374dded64cdb16d Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Sat, 16 Mar 2024 14:41:34 +0100 Subject: [PATCH 15/17] [Fix] GHA MacOS python brew problem --- .github/workflows/openms_ci_matrix_full.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/openms_ci_matrix_full.yml b/.github/workflows/openms_ci_matrix_full.yml index 7142c6f28ab..286c90ed1e1 100644 --- a/.github/workflows/openms_ci_matrix_full.yml +++ b/.github/workflows/openms_ci_matrix_full.yml @@ -266,12 +266,12 @@ jobs: fi if [[ "${{ matrix.os }}" == macos-* ]]; then - brew install --quiet ccache autoconf automake libtool ninja && brew link --overwrite ccache +## Needed for Qt. Install before to overwrite the default softlinks on the GH runners +brew install python3 --force --overwrite brew install --quiet ccache autoconf automake libtool ninja && brew link --overwrite ccache brew install libsvm xerces-c boost eigen sqlite coinutils cbc cgl clp qt@5 echo "cmake_prefix=$(brew --prefix qt@5)/lib/cmake;$(brew --prefix qt@5)" >> $GITHUB_OUTPUT echo "Qt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5" >> $GITHUB_ENV if [[ "${{ steps.set-vars.outputs.pkg_type }}" != "none" ]]; then - brew install python3 --force --overwrite brew install --quiet doxygen ghostscript graphviz fi fi From cc1e042190feebd1c94e22781d76c1487455930a Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Sat, 16 Mar 2024 15:01:52 +0100 Subject: [PATCH 16/17] indent --- .github/workflows/openms_ci_matrix_full.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/openms_ci_matrix_full.yml b/.github/workflows/openms_ci_matrix_full.yml index 286c90ed1e1..9da9679bf0c 100644 --- a/.github/workflows/openms_ci_matrix_full.yml +++ b/.github/workflows/openms_ci_matrix_full.yml @@ -265,9 +265,10 @@ jobs: fi fi - if [[ "${{ matrix.os }}" == macos-* ]]; then -## Needed for Qt. Install before to overwrite the default softlinks on the GH runners -brew install python3 --force --overwrite brew install --quiet ccache autoconf automake libtool ninja && brew link --overwrite ccache + if [[ "${{ matrix.os }}" == macos-* ]]; then + ## Needed for Qt. Install before to overwrite the default softlinks on the GH runners + brew install python3 --force --overwrite + brew install --quiet ccache autoconf automake libtool ninja && brew link --overwrite ccache brew install libsvm xerces-c boost eigen sqlite coinutils cbc cgl clp qt@5 echo "cmake_prefix=$(brew --prefix qt@5)/lib/cmake;$(brew --prefix qt@5)" >> $GITHUB_OUTPUT echo "Qt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5" >> $GITHUB_ENV From 9643475fbf3023376f34e2b9b46b0733ec3c6bc5 Mon Sep 17 00:00:00 2001 From: Samuel Wein Date: Mon, 18 Mar 2024 01:26:24 +0100 Subject: [PATCH 17/17] Update CMakeLists.txt Fix typos --- doc/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index f652e12dd9f..ca645b28a67 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -323,7 +323,7 @@ if(ENABLE_DOCS) #------------------------------------------------------------------------------ # add virtual dependency of doc_minimal on TOPP # this is not necessary but defers the generation of doc_minimal to a later - # stage to avoid confusion if doc_minimal is build first + # stage to avoid confusion if doc_minimal is built first add_dependencies(doc_minimal TOPP) if (DOXYGEN_DOT_FOUND OR DOXYGEN_DOT_EXECUTABLE) @@ -381,9 +381,9 @@ if(ENABLE_DOCS) message(STATUS "Build C++ tutorials: ${BUILD_EXAMPLES} (-DBUILD_EXAMPLES=ON/OFF);") if(BUILD_EXAMPLES AND "${PACKAGE_TYPE}" STREQUAL "none") add_subdirectory(code_examples) - message(STATUS " --> Tutorials in '${PROJECT_SOURCE_DIR}/code_examples' will be build!") + message(STATUS " --> Tutorials in '${PROJECT_SOURCE_DIR}/code_examples' will be built!") else() - message(STATUS " --> Tutorials in '${PROJECT_SOURCE_DIR}/code_examples' will NOT be build! (since PACKAGE_TYPE=${PACKAGE_TYPE}, but must be 'none')") + message(STATUS " --> Tutorials in '${PROJECT_SOURCE_DIR}/code_examples' will NOT be built! (since PACKAGE_TYPE=${PACKAGE_TYPE}, but must be 'none')") endif()