23
23
static PyObject * ErrorObject ;
24
24
25
25
/*
26
- Check that PyArrayObject is a double (Float) type and a 1d, or 2d array.
26
+ Check that PyArrayObject is a double (Float) type and a 1d, or 2d, or 3d array.
27
27
Return 1 if an error and raise exception.
28
28
*/
29
29
static int check_type (PyArrayObject * a , int min_dim , int max_dim ) {
@@ -41,11 +41,15 @@ static int check_type(PyArrayObject* a, int min_dim, int max_dim) {
41
41
*/
42
42
static int check_same_shapes (PyArrayObject * a , PyArrayObject * b ) {
43
43
if (PyArray_NDIM (a ) != PyArray_NDIM (b )) {
44
+ PyErr_SetString (PyExc_ValueError ,
45
+ "In check_same_shapes: arrays must have same number of dimensions." );
44
46
return 1 ;
45
47
}
46
48
Py_ssize_t ndims = PyArray_NDIM (a );
47
49
for (int i = 0 ; i < ndims ; ++ i ) {
48
50
if (PyArray_SHAPE (a )[i ] != PyArray_SHAPE (b )[i ]) {
51
+ PyErr_SetString (PyExc_ValueError ,
52
+ "In check_same_shapes: arrays must have same number of dimensions." );
49
53
return 1 ;
50
54
}
51
55
}
@@ -55,7 +59,7 @@ static int check_same_shapes(PyArrayObject* a, PyArrayObject* b) {
55
59
56
60
static PyObject *
57
61
continuum_generic_impl (PyObject * self , PyObject * args ,
58
- void (* continuum_processing_f )(double * , double * , double * , size_t ))
62
+ void (* continuum_processing_f )(double * , double * , double * , size_t * , size_t ))
59
63
{
60
64
PyArrayObject * ain ;
61
65
PyArrayObject * aout ;
@@ -69,8 +73,8 @@ continuum_generic_impl(PyObject *self, PyObject *args,
69
73
if (NULL == aout ) return Py_None ;
70
74
if (NULL == awl ) return Py_None ;
71
75
72
- if (check_type (ain , 1 , 2 )) return Py_None ;
73
- if (check_type (aout , 1 , 2 )) return Py_None ;
76
+ if (check_type (ain , 1 , 3 )) return Py_None ;
77
+ if (check_type (aout , 1 , 3 )) return Py_None ;
74
78
if (check_type (awl , 1 , 1 )) return Py_None ;
75
79
76
80
if (check_same_shapes (ain , aout )) return Py_None ;
@@ -86,8 +90,10 @@ continuum_generic_impl(PyObject *self, PyObject *args,
86
90
"In continuum_generic_impl: wavelengths array has incorrect length." );
87
91
return Py_None ;
88
92
}
89
- continuum_processing_f (datain , dataout , dataawl , spectrum_length );
90
- } else {
93
+ size_t * indices = malloc (sizeof (size_t ) * spectrum_length );
94
+ continuum_processing_f (datain , dataout , dataawl , indices , spectrum_length );
95
+ free (indices );
96
+ } else if (PyArray_NDIM (ain ) == 2 ) {
91
97
Py_ssize_t num_spectra = PyArray_SHAPE (ain )[0 ];
92
98
Py_ssize_t spectrum_length = PyArray_SHAPE (ain )[1 ];
93
99
if (spectrum_length != PyArray_SHAPE (awl )[0 ]) {
@@ -96,14 +102,49 @@ continuum_generic_impl(PyObject *self, PyObject *args,
96
102
return Py_None ;
97
103
}
98
104
99
- //#pragma omp parallel for
105
+ #pragma omp parallel
106
+ {
107
+ size_t * indices = malloc (sizeof (size_t ) * spectrum_length );
108
+
109
+ #pragma omp for
100
110
for (Py_ssize_t i = 0 ; i < num_spectra ; ++ i ) {
101
111
double * datain = (double * )(PyArray_DATA (ain )
102
112
+ i * PyArray_STRIDES (ain )[0 ]);
103
113
double * dataout = (double * )(PyArray_DATA (aout )
104
114
+ i * PyArray_STRIDES (aout )[0 ]);
105
- continuum_processing_f (datain , dataout , dataawl , spectrum_length );
115
+ continuum_processing_f (datain , dataout , dataawl , indices , spectrum_length );
116
+ }
117
+
118
+ free (indices );
119
+ } // pragma omp parallel
120
+ } else {
121
+ Py_ssize_t num_rows = PyArray_SHAPE (ain )[0 ];
122
+ Py_ssize_t num_cols = PyArray_SHAPE (ain )[1 ];
123
+ Py_ssize_t spectrum_length = PyArray_SHAPE (ain )[2 ];
124
+ if (spectrum_length != PyArray_SHAPE (awl )[0 ]) {
125
+ PyErr_SetString (PyExc_ValueError ,
126
+ "In continuum_generic_impl: wavelengths array has incorrect length." );
127
+ return Py_None ;
106
128
}
129
+
130
+ //TODO: This could be optimized for better work sharing.
131
+ #pragma omp parallel
132
+ {
133
+ size_t * indices = malloc (sizeof (size_t ) * spectrum_length );
134
+
135
+ #pragma omp for
136
+ for (Py_ssize_t i = 0 ; i < num_rows ; ++ i ) {
137
+ for (Py_ssize_t j = 0 ; j < num_cols ; ++ j ) {
138
+ double * datain = (double * )(PyArray_DATA (ain )
139
+ + i * PyArray_STRIDES (ain )[0 ] + j * PyArray_STRIDES (ain )[1 ]);
140
+ double * dataout = (double * )(PyArray_DATA (aout )
141
+ + i * PyArray_STRIDES (aout )[0 ] + j * PyArray_STRIDES (aout )[1 ]);
142
+ continuum_processing_f (datain , dataout , dataawl , indices , spectrum_length );
143
+ }
144
+ }
145
+
146
+ free (indices );
147
+ } // pragma omp parallel
107
148
}
108
149
109
150
return Py_None ;
@@ -114,7 +155,7 @@ continuum_generic_impl(PyObject *self, PyObject *args,
114
155
PyDoc_STRVAR (ccontinuum_continuum_doc ,
115
156
"continuum(spectrum)\n\
116
157
\n\
117
- Return continuum of the spectrum." );
158
+ Return continuum of the spectrum or each spectrum in image ." );
118
159
119
160
static PyObject *
120
161
ccontinuum_continuum (PyObject * self , PyObject * args )
@@ -127,7 +168,7 @@ ccontinuum_continuum(PyObject *self, PyObject *args)
127
168
PyDoc_STRVAR (ccontinuum_continuum_removed_doc ,
128
169
"continuum_removed(spectrum)\n\
129
170
\n\
130
- Return continuum removed spectrum." );
171
+ Return continuum removed spectrum or image ." );
131
172
132
173
static PyObject *
133
174
ccontinuum_continuum_removed (PyObject * self , PyObject * args )
0 commit comments