scattnlay.pyx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # Copyright (C) 2009-2015 Ovidio Pena <ovidio@bytesfall.com>
  2. #
  3. # This file is part of python-scattnlay
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # The only additional remark is that we expect that all publications
  16. # describing work using this software, or all commercial products
  17. # using it, cite the following reference:
  18. # [1] O. Pena and U. Pal, "Scattering of electromagnetic radiation by
  19. # a multilayered sphere," Computer Physics Communications,
  20. # vol. 180, Nov. 2009, pp. 2348-2354.
  21. #
  22. # You should have received a copy of the GNU General Public License
  23. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. # distutils: language = c++
  25. # distutils: sources = nmie-wrapper.cc
  26. from __future__ import division
  27. import numpy as np
  28. cimport numpy as np
  29. from libcpp.vector cimport vector
  30. from libcpp.vector cimport complex
  31. # cdef extern from "<vector>" namespace "std":
  32. # cdef cppclass vector[T]:
  33. # cppclass iterator:
  34. # T operator*()
  35. # iterator operator++()
  36. # bint operator==(iterator)
  37. # bint operator!=(iterator)
  38. # vector()
  39. # void push_back(T&)
  40. # T& operator[](int)
  41. # T& at(int)
  42. # iterator begin()
  43. # iterator end()
  44. cdef inline double *npy2c(np.ndarray a):
  45. assert a.dtype == np.float64
  46. if not (<object>a).flags["C_CONTIGUOUS"]: # Array is not contiguous, need to make contiguous copy
  47. a = a.copy('C')
  48. # Return data pointer
  49. return <double *>(a.data)
  50. ##############################################################################
  51. ##############################################################################
  52. ##############################################################################
  53. ##############################################################################
  54. # cdef extern from "py_nmie.h":
  55. # cdef int nMie(int L, int pl, vector[double] x, vector[double complex] m, int nTheta, vector[double] Theta, int nmax, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, double S1r[], double S1i[], double S2r[], double S2i[])
  56. # cdef int nField(int L, int pl, vector[double] x, vector[double complex] m, int nmax, int nCoords, vector[double] Xp, vector[double] Yp, vector[double] Zp, double Erx[], double Ery[], double Erz[], double Eix[], double Eiy[], double Eiz[], double Hrx[], double Hry[], double Hrz[], double Hix[], double Hiy[], double Hiz[])
  57. ##############################################################################
  58. ##############################################################################
  59. ##############################################################################
  60. ##############################################################################
  61. cdef extern from "nmie-wrapper.h" namespace "nmie":
  62. cdef int nMie_wrapper(int L, const vector[double] x, const vector[double complex] m , int nTheta, const vector[double] Theta, double *qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, vector[double complex] S1, vector[double complex] S2);
  63. ##############################################################################
  64. ##############################################################################
  65. ##############################################################################
  66. ##############################################################################
  67. # def scattnlay(np.ndarray[np.float64_t, ndim = 2] x, np.ndarray[np.complex128_t, ndim = 2] m, np.ndarray[np.float64_t, ndim = 1] theta = np.zeros(0, dtype = np.float64), np.int_t pl = -1, np.int_t nmax = -1):
  68. # cdef Py_ssize_t i
  69. # cdef np.ndarray[np.int_t, ndim = 1] terms = np.zeros(x.shape[0], dtype = np.int)
  70. # cdef np.ndarray[np.float64_t, ndim = 1] Qext = np.zeros(x.shape[0], dtype = np.float64)
  71. # cdef np.ndarray[np.float64_t, ndim = 1] Qabs = np.zeros(x.shape[0], dtype = np.float64)
  72. # cdef np.ndarray[np.float64_t, ndim = 1] Qsca = np.zeros(x.shape[0], dtype = np.float64)
  73. # cdef np.ndarray[np.float64_t, ndim = 1] Qbk = np.zeros(x.shape[0], dtype = np.float64)
  74. # cdef np.ndarray[np.float64_t, ndim = 1] Qpr = np.zeros(x.shape[0], dtype = np.float64)
  75. # cdef np.ndarray[np.float64_t, ndim = 1] g = np.zeros(x.shape[0], dtype = np.float64)
  76. # cdef np.ndarray[np.float64_t, ndim = 1] Albedo = np.zeros(x.shape[0], dtype = np.float64)
  77. # cdef np.ndarray[np.complex128_t, ndim = 2] S1 = np.zeros((x.shape[0], theta.shape[0]), dtype = np.complex128)
  78. # cdef np.ndarray[np.complex128_t, ndim = 2] S2 = np.zeros((x.shape[0], theta.shape[0]), dtype = np.complex128)
  79. # cdef np.ndarray[np.float64_t, ndim = 1] S1r
  80. # cdef np.ndarray[np.float64_t, ndim = 1] S1i
  81. # cdef np.ndarray[np.float64_t, ndim = 1] S2r
  82. # cdef np.ndarray[np.float64_t, ndim = 1] S2i
  83. # for i in range(x.shape[0]):
  84. # S1r = np.zeros(theta.shape[0], dtype = np.float64)
  85. # S1i = np.zeros(theta.shape[0], dtype = np.float64)
  86. # S2r = np.zeros(theta.shape[0], dtype = np.float64)
  87. # S2i = np.zeros(theta.shape[0], dtype = np.float64)
  88. # terms[i] = nMie(x.shape[1], pl, x[i].copy('C'), m[i].copy('C'), theta.shape[0], theta.copy('C'), nmax, &Qext[i], &Qsca[i], &Qabs[i], &Qbk[i], &Qpr[i], &g[i], &Albedo[i], npy2c(S1r), npy2c(S1i), npy2c(S2r), npy2c(S2i))
  89. # S1[i] = S1r.copy('C') + 1.0j*S1i.copy('C')
  90. # S2[i] = S2r.copy('C') + 1.0j*S2i.copy('C')
  91. # return terms, Qext, Qsca, Qabs, Qbk, Qpr, g, Albedo, S1, S2
  92. # ##############################################################################
  93. # ##############################################################################
  94. # ##############################################################################
  95. # ##############################################################################
  96. # #def fieldnlay(np.ndarray[np.float64_t, ndim = 2] x, np.ndarray[np.complex128_t, ndim = 2] m, np.ndarray[np.float64_t, ndim = 2] coords = np.zeros((0, 3), dtype = np.float64), np.int_t pl = 0, np.int_t nmax = 0):
  97. # def fieldnlay(np.ndarray[np.float64_t, ndim = 2] x, np.ndarray[np.complex128_t, ndim = 2] m, np.ndarray[np.float64_t, ndim = 2] coords, np.int_t pl = 0, np.int_t nmax = 0):
  98. # cdef Py_ssize_t i
  99. # cdef np.ndarray[np.int_t, ndim = 1] terms = np.zeros(x.shape[0], dtype = np.int)
  100. # cdef np.ndarray[np.complex128_t, ndim = 3] E = np.zeros((x.shape[0], coords.shape[0], 3), dtype = np.complex128)
  101. # cdef np.ndarray[np.complex128_t, ndim = 3] H = np.zeros((x.shape[0], coords.shape[0], 3), dtype = np.complex128)
  102. # cdef np.ndarray[np.float64_t, ndim = 1] Erx
  103. # cdef np.ndarray[np.float64_t, ndim = 1] Ery
  104. # cdef np.ndarray[np.float64_t, ndim = 1] Erz
  105. # cdef np.ndarray[np.float64_t, ndim = 1] Eix
  106. # cdef np.ndarray[np.float64_t, ndim = 1] Eiy
  107. # cdef np.ndarray[np.float64_t, ndim = 1] Eiz
  108. # cdef np.ndarray[np.float64_t, ndim = 1] Hrx
  109. # cdef np.ndarray[np.float64_t, ndim = 1] Hry
  110. # cdef np.ndarray[np.float64_t, ndim = 1] Hrz
  111. # cdef np.ndarray[np.float64_t, ndim = 1] Hix
  112. # cdef np.ndarray[np.float64_t, ndim = 1] Hiy
  113. # cdef np.ndarray[np.float64_t, ndim = 1] Hiz
  114. # for i in range(x.shape[0]):
  115. # Erx = np.zeros(coords.shape[0], dtype = np.float64)
  116. # Ery = np.zeros(coords.shape[0], dtype = np.float64)
  117. # Erz = np.zeros(coords.shape[0], dtype = np.float64)
  118. # Eix = np.zeros(coords.shape[0], dtype = np.float64)
  119. # Eiy = np.zeros(coords.shape[0], dtype = np.float64)
  120. # Eiz = np.zeros(coords.shape[0], dtype = np.float64)
  121. # Hrx = np.zeros(coords.shape[0], dtype = np.float64)
  122. # Hry = np.zeros(coords.shape[0], dtype = np.float64)
  123. # Hrz = np.zeros(coords.shape[0], dtype = np.float64)
  124. # Hix = np.zeros(coords.shape[0], dtype = np.float64)
  125. # Hiy = np.zeros(coords.shape[0], dtype = np.float64)
  126. # Hiz = np.zeros(coords.shape[0], dtype = np.float64)
  127. # terms[i] = nField(x.shape[1], pl, x[i].copy('C'), m[i].copy('C'), nmax, coords.shape[0], coords[:, 0].copy('C'), coords[:, 1].copy('C'), coords[:, 2].copy('C'), npy2c(Erx), npy2c(Ery), npy2c(Erz), npy2c(Eix), npy2c(Eiy), npy2c(Eiz), npy2c(Hrx), npy2c(Hry), npy2c(Hrz), npy2c(Hix), npy2c(Hiy), npy2c(Hiz))
  128. # E[i] = np.vstack((Erx.copy('C') + 1.0j*Eix.copy('C'), Ery.copy('C') + 1.0j*Eiy.copy('C'), Erz.copy('C') + 1.0j*Eiz.copy('C'))).transpose()
  129. # H[i] = np.vstack((Hrx.copy('C') + 1.0j*Hix.copy('C'), Hry.copy('C') + 1.0j*Hiy.copy('C'), Hrz.copy('C') + 1.0j*Hiz.copy('C'))).transpose()
  130. # return terms, E, H
  131. ##############################################################################
  132. ##############################################################################
  133. ##############################################################################
  134. ##############################################################################
  135. def scattnlay_wrapper(np.ndarray[np.float64_t, ndim = 2] x, np.ndarray[np.complex128_t, ndim = 2] m, np.ndarray[np.float64_t, ndim = 1] theta = np.zeros(0, dtype = np.float64), np.int_t pl = -1, np.int_t nmax = -1):
  136. cdef Py_ssize_t i
  137. cdef np.ndarray[np.int_t, ndim = 1] terms = np.zeros(x.shape[0], dtype = np.int)
  138. cdef np.ndarray[np.float64_t, ndim = 1] Qext = np.zeros(x.shape[0], dtype = np.float64)
  139. cdef np.ndarray[np.float64_t, ndim = 1] Qabs = np.zeros(x.shape[0], dtype = np.float64)
  140. cdef np.ndarray[np.float64_t, ndim = 1] Qsca = np.zeros(x.shape[0], dtype = np.float64)
  141. cdef np.ndarray[np.float64_t, ndim = 1] Qbk = np.zeros(x.shape[0], dtype = np.float64)
  142. cdef np.ndarray[np.float64_t, ndim = 1] Qpr = np.zeros(x.shape[0], dtype = np.float64)
  143. cdef np.ndarray[np.float64_t, ndim = 1] g = np.zeros(x.shape[0], dtype = np.float64)
  144. cdef np.ndarray[np.float64_t, ndim = 1] Albedo = np.zeros(x.shape[0], dtype = np.float64)
  145. cdef np.ndarray[np.complex128_t, ndim = 2] S1 = np.zeros((x.shape[0], theta.shape[0]), dtype = np.complex128)
  146. cdef np.ndarray[np.complex128_t, ndim = 2] S2 = np.zeros((x.shape[0], theta.shape[0]), dtype = np.complex128)
  147. cdef np.ndarray[np.float64_t, ndim = 1] S1r
  148. cdef np.ndarray[np.float64_t, ndim = 1] S1i
  149. cdef np.ndarray[np.float64_t, ndim = 1] S2r
  150. cdef np.ndarray[np.float64_t, ndim = 1] S2i
  151. for i in range(x.shape[0]):
  152. S1r = np.zeros(theta.shape[0], dtype = np.float64)
  153. S1i = np.zeros(theta.shape[0], dtype = np.float64)
  154. S2r = np.zeros(theta.shape[0], dtype = np.float64)
  155. S2i = np.zeros(theta.shape[0], dtype = np.float64)
  156. terms[i] = nMie_wrapper(x.shape[1], x[i].copy('C'),
  157. m[i].copy('C'), theta.shape[0],
  158. theta.copy('C'), &Qext[i], &Qsca[i],
  159. &Qabs[i], &Qbk[i], &Qpr[i], &g[i],
  160. &Albedo[i],
  161. S1r, S2r)
  162. S1[i] = S1r.copy('C')
  163. S2[i] = S2r.copy('C')
  164. return terms, Qext, Qsca, Qabs, Qbk, Qpr, g, Albedo, S1, S2