OSCR

Pharmacological activation of cGMP signaling promotes astrocyte remodeling and enrichment of perivascular GLUT1 in the murine retina.

Code ↔ Paper

1 match between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 1 match
  1. [1] § Methods › Single cell astrocyte and vessel analysis ↔ skfmm/__init__.py, lines 1–52 · score 0.52 · fast marching, scikit, boundary, Python, zero, distance

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 902 lines · 33 KB · BSD-3-Clause · 1 match

  1. # -*- mode: doctest -*-
  2. """scikit-fmm is a Python extension module which implements the fast
  3. marching method.
  4. https://github.com/scikit-fmm/scikit-fmm
  5. The fast marching method is used to model the evolution of boundaries
  6. and interfaces in a variety of application areas. More specifically,
  7. the fast marching method is a numerical technique for finding
  8. approximate solutions to boundary value problems of the Eikonal
  9. equation:
  10. F(x) | grad T(x) | = 1.
  11. Typically, such a problem describes the evolution of a closed curve as
  12. a function of time T with speed F(x)>0 in the normal direction at a
  13. point x on the curve. The speed function is specified, and the time at
  14. which the contour crosses a point x is obtained by solving the
  15. equation.
  16. skfmm.distance(phi, dx=1.0, self_test=False, order=2, narrow=0.0,
  17. periodic=False)
  18. Return the signed distance from the zero contour of the array phi.
  19. skfmm.travel_time(phi, speed, dx=1.0, self_test=False, order=2,
  20. narrow=0.0, periodic=False)
  21. Return the travel from the zero contour of the array phi given the
  22. scalar velocity field speed.
  23. skfmm.extension_velocities(phi, speed, dx=1.0, self_test=False,
  24. order=2, ext_mask=None, narrow=0.0, periodic=False)
  25. Extend the velocities defined at the zero contour of phi, in the
  26. normal direction, to the rest of the domain. Extend the velocities
  27. such that grad f_ext dot grad d = 0 where where f_ext is the
  28. extension velocity and d is the signed distance function.
  29. :Copyright: Copyright 2025 The scikit-fmm team.
  30. :License: BSD-style license. See LICENSE.txt in the source directory.
  31. """
  32. __version__ = "2025.06.23"
  33. __docformat__ = 'restructuredtext'
  34. __all__ = ['distance', 'travel_time', 'extension_velocities', 'heap']
  35. from .pfmm import distance, travel_time, extension_velocities
  36. from .heap import heap
  37. def testing():
  38. r"""
  39. These tests are gathered from FiPy_, PyLSMLIB_ and original
  40. Scikit-fmm_ tests.
  41. .. _FiPy: http://www.ctcms.nist.gov/fipy/
  42. .. _PyLSMLIB: https://github.com/ktchu/LSMLIB/tree/master/pylsmlib
  43. .. _Scikit-fmm: http://packages.python.org/scikit-fmm/
  44. .. _LSMLIB: http://ktchu.serendipityresearch.org/software/lsmlib/index.html
  45. **1D Test**
  46. >>> import numpy as np
  47. >>> print(np.allclose(distance((-1., -1., -1., -1., 1., 1., 1., 1.), dx=.5),
  48. ... (-1.75, -1.25, -.75, -0.25, 0.25, 0.75, 1.25, 1.75)))
  49. True
  50. Small dimensions.
  51. >>> dx = 1e-10
  52. >>> print(np.allclose(distance((-1., -1., -1., -1., 1., 1., 1., 1.), dx=dx),
  53. ... np.arange(8) * dx - 3.5 * dx))
  54. True
  55. **Bug Fix**
  56. Test case for a bug in the upwind finite difference scheme for
  57. negative phi. When computing finite differences we want to
  58. preferentially use information from the frozen neighbors that
  59. are closest to the zero contour in each dimension. This means
  60. that we must compare absolute distances when checking neighbors
  61. in the negative phi direction.
  62. The error can result in incorrect values of the updated signed
  63. distance function for regions close to the minimum contour of
  64. the level set function, i.e. in the middle of holes.
  65. To test we use a square matrix for the initial phi field that is
  66. equal to -1 on the main diagonal and on the three diagonals above
  67. and below this. The matrix is set to 1 everywhere else. The bug
  68. results in errors in positions (1,1), (2,2), (3,3), (6,6), (7,7)
  69. and (8,8) along the main diagonal.
  70. This error occurs for first- and second-order updates. For
  71. simplicity, we choose to only test the first-order update.
  72. >>> phi = np.ones((10, 10))
  73. >>> i,j = np.indices(phi.shape)
  74. >>> phi[i==j-3] = -1
  75. >>> phi[i==j-2] = -1
  76. >>> phi[i==j-1] = -1
  77. >>> phi[i==j] = -1
  78. >>> phi[i==j+1] = -1
  79. >>> phi[i==j+2] = -1
  80. >>> phi[i==j+3] = -1
  81. >>> phi = distance(phi, order=1)
  82. >>> print(np.allclose(phi[1, 1], -2.70464, atol=1e-4))
  83. True
  84. >>> print(np.allclose(phi[2, 2], -2.50873, atol=1e-4))
  85. True
  86. >>> print(np.allclose(phi[3, 3], -2.47487, atol=1e-4))
  87. True
  88. >>> print(np.allclose(phi[6, 6], -2.47487, atol=1e-4))
  89. True
  90. >>> print(np.allclose(phi[7, 7], -2.50873, atol=1e-4))
  91. True
  92. >>> print(np.allclose(phi[8, 8], -2.70464, atol=1e-4))
  93. True
  94. **Bug Fix**
  95. A 2D test case to test trial values for a pathological case.
  96. >>> dx = 1.
  97. >>> dy = 2.
  98. >>> vbl = -dx * dy / np.sqrt(dx**2 + dy**2) / 2.
  99. >>> vbr = dx / 2
  100. >>> vml = dy / 2.
  101. >>> crossProd = dx * dy
  102. >>> dsq = dx**2 + dy**2
  103. >>> top = vbr * dx**2 + vml * dy**2
  104. >>> sqrt = crossProd**2 *(dsq - (vbr - vml)**2)
  105. >>> sqrt = np.sqrt(max(sqrt, 0))
  106. >>> vmr = (top + sqrt) / dsq
  107. >>> print(np.allclose(distance(((-1., 1., -1.), (1., 1., 1.)), dx=(dx, dy), order=1),
  108. ... ((vbl, vml, vbl), (vbr, vmr, vbr))))
  109. True
  110. **Test Extension Field Calculation**
  111. >>> tmp = 1 / np.sqrt(2)
  112. >>> phi = np.array([[-1., 1.], [1., 1.]])
  113. >>> phi, ext = extension_velocities(phi,
  114. ... [[-1, .5], [2., -1.]],
  115. ... ext_mask=phi < 0,
  116. ... dx=1., order=1)
  117. >>> print(np.allclose(phi, ((-tmp / 2, 0.5), (0.5, 0.5 + tmp))))
  118. True
  119. >>> print(np.allclose(ext, [[1.25, .5], [2., 1.25]]))
  120. True
  121. >>> phi = np.array(((-1., 1., 1.), (1., 1., 1.), (1., 1., 1.)))
  122. >>> phi, ext = extension_velocities(phi,
  123. ... ((-1., 2., -1.),
  124. ... (.5, -1., -1.),
  125. ... (-1., -1., -1.)),
  126. ... ext_mask=phi < 0,
  127. ... order=1)
  128. >>> v1 = 0.5 + tmp
  129. >>> v2 = 1.5
  130. >>> tmp1 = (v1 + v2) / 2 + np.sqrt(2. - (v1 - v2)**2) / 2
  131. >>> tmp2 = tmp1 + 1 / np.sqrt(2)
  132. >>> print(np.allclose(phi, ((-tmp / 2, 0.5, 1.5),
  133. ... (0.5, 0.5 + tmp, tmp1),
  134. ... (1.5, tmp1, tmp2))))
  135. True
  136. >>> print(np.allclose(ext, ((1.25, 2., 2.),
  137. ... (.5, 1.25, 1.5456),
  138. ... (.5, 0.9544, 1.25)),
  139. ... rtol = 1e-4))
  140. True
  141. **Bug Fix**
  142. Test case for a bug that occurs when initializing the distance
  143. variable at the interface. Currently it is assumed that adjacent
  144. cells that are opposite sign neighbors have perpendicular normal
  145. vectors. In fact the two closest cells could have opposite
  146. normals.
  147. >>> print(np.allclose(distance((-1., 1., -1.)), (-0.5, 0.5, -0.5)))
  148. True
  149. Testing second order. This example failed with Scikit-fmm_.
  150. >>> phi = ((-1., -1., 1., 1.),
  151. ... (-1., -1., 1., 1.),
  152. ... (1., 1., 1., 1.),
  153. ... (1., 1., 1., 1.))
  154. >>> answer = ((-1.30473785, -0.5, 0.5, 1.49923009),
  155. ... (-0.5, -0.35355339, 0.5, 1.45118446),
  156. ... (0.5, 0.5, 0.97140452, 1.76215286),
  157. ... (1.49923009, 1.45118446, 1.76215286, 2.33721352))
  158. >>> print(np.allclose(distance(phi),
  159. ... answer,
  160. ... rtol=1e-9))
  161. True
  162. **A test for a bug in both LSMLIB and Scikit-fmm**
  163. The following test gives different results depending on whether
  164. LSMLIB_ or Scikit-fmm_ is used. This issue occurs when calculating
  165. second order accurate distance functions. When a value becomes
  166. "known" after previously being a "trial" value it updates its
  167. neighbors' values. In a second order scheme the neighbors one step
  168. away also need to be updated (if the cell between the new "known"
  169. cell and the cell required for second order accuracy also happens
  170. to be "known"), but are not updated in either package. By luck
  171. (due to trial values having the same value), the values calculated
  172. in Scikit-fmm_ for the following example are correct although an
  173. example that didn't work for Scikit-fmm_ could also be
  174. constructed.
  175. >>> phi = distance([[-1, -1, -1, -1],
  176. ... [ 1, 1, -1, -1],
  177. ... [ 1, 1, -1, -1],
  178. ... [ 1, 1, -1, -1]], order=2)
  179. >>> phi = distance(phi, order=2)
  180. The following values come form Scikit-fmm_.
  181. >>> answer = [[-0.5, -0.58578644, -1.08578644, -1.85136395],
  182. ... [ 0.5, 0.29289322, -0.58578644, -1.54389939],
  183. ... [ 1.30473785, 0.5, -0.5, -1.5 ],
  184. ... [ 1.49547948, 0.5, -0.5, -1.5 ]]
  185. The 3rd and 7th element are different for LSMLIB_. This is because
  186. the 15th element is not "known" when the "trial" value for the 7th
  187. element is calculated. Scikit-fmm_ calculates the values in a
  188. slightly different order so gets a seemingly better answer, but
  189. this is just chance.
  190. >>> print(np.allclose(phi, answer, rtol=1e-9))
  191. True
  192. The following tests for the same issue but is a better test case
  193. guaranteed to fail.
  194. >>> phi = np.array([[-1, 1, 1, 1, 1, -1],
  195. ... [-1, -1, -1, -1, -1, -1],
  196. ... [-1, -1, -1, -1, -1, -1]])
  197. >>> phi = distance(phi)
  198. >>> print(phi[2, 2] == phi[2, 3])
  199. True
  200. >>> phi = distance(phi)
  201. >>> print(phi[2, 2] == phi[2, 3])
  202. True
  203. **Circle Example**
  204. Solve the level set equation in two dimensions for a circle.
  205. The 2D level set equation can be written,
  206. .. math::
  207. |\nabla \phi| = 1
  208. and the boundary condition for a circle is given by, :math:`\phi = 0` at
  209. :math:`(x - L / 2)^2 + (y - L / 2)^2 = (L / 4)^2`.
  210. The solution to this problem will be demonstrated in the following
  211. script. Firstly, setup the parameters.
  212. >>> def mesh(nx=1, ny=1, dx=1., dy=1.):
  213. ... y, x = np.mgrid[0:nx,0:ny]
  214. ... x = x * dx + dx / 2
  215. ... y = y * dy + dy / 2
  216. ... return x, y
  217. >>> dx = 1.
  218. >>> N = 11
  219. >>> L = N * dx
  220. >>> x, y = mesh(nx=N, ny=N, dx=dx, dy=dx)
  221. >>> phi = -np.ones(N * N, 'd')
  222. >>> phi[(x.flatten() - L / 2.)**2 + (y.flatten() - L / 2.)**2 < (L / 4.)**2] = 1.
  223. >>> phi = np.reshape(phi, (N, N))
  224. >>> phi = distance(phi, dx=dx, order=1).flatten()
  225. >>> dX = dx / 2.
  226. >>> m1 = dX * dX / np.sqrt(dX**2 + dX**2)
  227. >>> def evalCell(phix, phiy, dx):
  228. ... aa = dx**2 + dx**2
  229. ... bb = -2 * ( phix * dx**2 + phiy * dx**2)
  230. ... cc = dx**2 * phix**2 + dx**2 * phiy**2 - dx**2 * dx**2
  231. ... sqr = np.sqrt(bb**2 - 4. * aa * cc)
  232. ... return ((-bb - sqr) / 2. / aa, (-bb + sqr) / 2. / aa)
  233. >>> v1 = evalCell(-dX, -m1, dx)[0]
  234. >>> v2 = evalCell(-m1, -dX, dx)[0]
  235. >>> v3 = evalCell(m1, m1, dx)[1]
  236. >>> v4 = evalCell(v3, dX, dx)[1]
  237. >>> v5 = evalCell(dX, v3, dx)[1]
  238. >>> MASK = -1000.
  239. >>> trialValues = np.array((
  240. ... MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK,
  241. ... MASK, MASK, MASK, MASK,-3*dX,-3*dX,-3*dX, MASK, MASK, MASK, MASK,
  242. ... MASK, MASK, MASK, v1, -dX, -dX, -dX, v1, MASK, MASK, MASK,
  243. ... MASK, MASK, v2, -m1, m1, dX, m1, -m1, v2, MASK, MASK,
  244. ... MASK, -dX*3, -dX, m1, v3, v4, v3, m1, -dX,-dX*3, MASK,
  245. ... MASK, -dX*3, -dX, dX, v5, MASK, v5, dX, -dX,-dX*3, MASK,
  246. ... MASK, -dX*3, -dX, m1, v3, v4, v3, m1, -dX,-dX*3, MASK,
  247. ... MASK, MASK, v2, -m1, m1, dX, m1, -m1, v2, MASK, MASK,
  248. ... MASK, MASK, MASK, v1, -dX, -dX, -dX, v1, MASK, MASK, MASK,
  249. ... MASK, MASK, MASK, MASK,-3*dX,-3*dX,-3*dX, MASK, MASK, MASK, MASK,
  250. ... MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK, MASK), 'd')
  251. >>> phi[trialValues == MASK] = MASK
  252. >>> print(np.allclose(phi, trialValues))
  253. True
  254. **Square Example**
  255. Here we solve the level set equation in two dimensions for a square. The equation is
  256. given by:
  257. .. math::
  258. |\nabla \phi| &= 1 \\
  259. \phi &= 0 \qquad \text{at} \qquad \begin{cases}
  260. x = \left( L / 3, 2 L / 3 \right)
  261. & \text{for $L / 3 \le y \le 2 L / 3$} \\
  262. y = \left( L / 3, 2 L / 3 \right)
  263. & \text{for $L / 3 \le x \le 2 L / 3$}
  264. \end{cases}
  265. >>> dx = 0.5
  266. >>> dy = 2.
  267. >>> nx = 5
  268. >>> ny = 5
  269. >>> Lx = nx * dx
  270. >>> Ly = ny * dy
  271. >>> x, y = mesh(nx=nx, ny=ny, dx=dx, dy=dy)
  272. >>> x = x.flatten()
  273. >>> y = y.flatten()
  274. >>> phi = -np.ones(nx * ny, 'd')
  275. >>> phi[((Lx / 3. < x) & (x < 2. * Lx / 3.)) & ((Ly / 3. < y) & (y < 2. * Ly / 3))] = 1.
  276. >>> phi = np.reshape(phi, (nx, ny))
  277. >>> phi = distance(phi, dx=(dy, dx), order=1).flatten()
  278. >>> def evalCell(phix, phiy, dx, dy):
  279. ... aa = dy**2 + dx**2
  280. ... bb = -2 * ( phix * dy**2 + phiy * dx**2)
  281. ... cc = dy**2 * phix**2 + dx**2 * phiy**2 - dx**2 * dy**2
  282. ... sqr = np.sqrt(bb**2 - 4. * aa * cc)
  283. ... return ((-bb - sqr) / 2. / aa, (-bb + sqr) / 2. / aa)
  284. >>> val = evalCell(-dy / 2., -dx / 2., dx, dy)[0]
  285. >>> v1 = evalCell(val, -3. * dx / 2., dx, dy)[0]
  286. >>> v2 = evalCell(-3. * dy / 2., val, dx, dy)[0]
  287. >>> v3 = evalCell(v2, v1, dx, dy)[0]
  288. >>> v4 = dx * dy / np.sqrt(dx**2 + dy**2) / 2
  289. >>> arr = np.array((
  290. ... v3 , v2 , -3. * dy / 2. , v2 , v3,
  291. ... v1 , val , -dy / 2. , val , v1 ,
  292. ... -3. * dx / 2., -dx / 2., v4 , -dx / 2., -3. * dx / 2.,
  293. ... v1 , val , -dy / 2. , val , v1 ,
  294. ... v3 , v2 , -3. * dy / 2. , v2 , v3 ))
  295. >>> print(np.allclose(arr, phi))
  296. True
  297. **Assertion Errors**
  298. >>> distance([[-1, 1],[1, 1]], dx=(1, 2, 3))
  299. Traceback (most recent call last):
  300. ...
  301. ValueError: dx must be of length len(phi.shape)
  302. >>> extension_velocities([[-1, 1],[1, 1]], speed=[1, 1])
  303. Traceback (most recent call last):
  304. ...
  305. ValueError: phi and speed must have the same shape
  306. **Test for 1D equality between `distance` and `travel_time`**
  307. >>> phi = np.arange(-5, 5) + 0.499
  308. >>> d = distance(phi)
  309. >>> t = travel_time(phi, speed=np.ones_like(phi))
  310. >>> np.testing.assert_allclose(t, np.abs(d))
  311. **Tests taken from FiPy**
  312. >>> phi = np.array(((-1, -1, 1, 1),
  313. ... (-1, -1, 1, 1),
  314. ... (1, 1, 1, 1),
  315. ... (1, 1, 1, 1)))
  316. >>> o1 = distance(phi, order=1, self_test=True)
  317. >>> dw_o1 = [[-1.20710678, -0.5, 0.5, 1.5],
  318. ... [-0.5, -0.35355339, 0.5, 1.5],
  319. ... [ 0.5, 0.5, 1.20710678, 2.04532893],
  320. ... [ 1.5, 1.5, 2.04532893, 2.75243571]]
  321. >>> np.testing.assert_allclose(o1, dw_o1)
  322. >>> phi = np.array(((-1, -1, 1, 1),
  323. ... (-1, -1, 1, 1),
  324. ... (1, 1, 1, 1),
  325. ... (1, 1, 1, 1)))
  326. >>> o1 = travel_time(phi, np.ones_like(phi), order=1, self_test=True)
  327. >>> dw_o1 = [[-1.20710678, -0.5, 0.5, 1.5],
  328. ... [-0.5, -0.35355339, 0.5, 1.5],
  329. ... [ 0.5, 0.5, 1.20710678, 2.04532893],
  330. ... [ 1.5, 1.5, 2.04532893, 2.75243571]]
  331. >>> np.testing.assert_allclose(o1, np.abs(dw_o1))
  332. >>> phi = np.array(((-1, -1, 1, 1),
  333. ... (-1, -1, 1, 1),
  334. ... (1, 1, 1, 1),
  335. ... (1, 1, 1, 1)))
  336. >>> o2 = distance(phi, self_test=True)
  337. >>> dw_o2 = [[-1.30473785, -0.5, 0.5, 1.49923009],
  338. ... [-0.5, -0.35355339, 0.5, 1.45118446],
  339. ... [ 0.5, 0.5, 0.97140452, 1.76215286],
  340. ... [ 1.49923009, 1.45118446, 1.76215286, 2.33721352]]
  341. >>> np.testing.assert_allclose(o2, dw_o2)
  342. >>> phi = np.array(((-1, -1, 1, 1),
  343. ... (-1, -1, 1, 1),
  344. ... (1, 1, 1, 1),
  345. ... (1, 1, 1, 1)))
  346. >>> o2 = travel_time(phi, np.ones_like(phi), self_test=True)
  347. >>> dw_o2 = [[-1.30473785, -0.5, 0.5, 1.49923009],
  348. ... [-0.5, -0.35355339, 0.5, 1.45118446],
  349. ... [ 0.5, 0.5, 0.97140452, 1.76215286],
  350. ... [ 1.49923009, 1.45118446, 1.76215286, 2.33721352]]
  351. >>> np.testing.assert_allclose(o2, np.abs(dw_o2))
  352. >>> distance([-1,1], order=0)
  353. Traceback (most recent call last):
  354. ...
  355. ValueError: order must be 1 or 2
  356. >>> distance([-1,1], order=3)
  357. Traceback (most recent call last):
  358. ...
  359. ValueError: order must be 1 or 2
  360. **Extension velocity tests**
  361. Test 1d extension constant.
  362. >>> phi = [-1,-1,-1,1,1,1]
  363. >>> speed = [1,1,1,1,1,1]
  364. >>> d, f_ext = extension_velocities(phi, speed, self_test=True)
  365. >>> np.testing.assert_allclose(speed, f_ext)
  366. Test the 1D extension block.
  367. >>> phi = np.ones(10)
  368. >>> phi[0] =- 1
  369. >>> speed = np.ones(10)
  370. >>> speed[0:3] = 5
  371. >>> d, f_ext = extension_velocities(phi, speed, self_test=True)
  372. >>> np.testing.assert_allclose(f_ext, 5)
  373. Test that a uniform speed value is preserved.
  374. >>> N = 50
  375. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  376. >>> r = 0.25
  377. >>> dx = 2.0 / (N - 1)
  378. >>> phi = (X) ** 2 + (Y) ** 2 - r ** 2
  379. >>> speed = np.ones_like(phi)
  380. >>> d, f_ext = extension_velocities(phi, speed, dx, self_test=True)
  381. >>> np.testing.assert_allclose(f_ext, 1.0)
  382. Constant value march-out test
  383. >>> speed[abs(Y)<0.3] = 10.0
  384. >>> d, f_ext = extension_velocities(phi, speed, dx, self_test=True)
  385. >>> np.testing.assert_allclose(f_ext, 10.0)
  386. Test distance from extension
  387. >>> speed = np.ones_like(phi)
  388. >>> d, f_ext = extension_velocities(phi, speed, dx, self_test=True)
  389. >>> d2 = distance(phi, dx, self_test=True)
  390. >>> np.testing.assert_allclose(d, d2)
  391. Test for extension velocity bug
  392. >>> N = 150
  393. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  394. >>> r = 0.5
  395. >>> dx = 2.0 / (N - 1)
  396. >>> phi = (X) ** 2 + (Y) ** 2 - r ** 2
  397. >>> speed = np.ones_like(phi)
  398. >>> speed[X>0.25] = 3.0
  399. >>> d2, f_ext = extension_velocities(phi, speed, dx)
  400. >>> assert (f_ext <= 3.0000001).all()
  401. >>> assert (f_ext >= 1).all()
  402. >>> np.testing.assert_almost_equal(f_ext[137, 95], 1, 3)
  403. >>> np.testing.assert_almost_equal(f_ext[103, 78], 1, 2)
  404. >>> np.testing.assert_almost_equal(f_ext[72, 100], 3, 3)
  405. >>> np.testing.assert_almost_equal(f_ext[72, 86], 3, 3)
  406. >>> np.testing.assert_almost_equal(f_ext[110, 121], 3, 3)
  407. Simple two point tests
  408. >>> np.testing.assert_array_equal(distance([-1, 1]),
  409. ... [-0.5, 0.5])
  410. >>> np.testing.assert_allclose(distance([-1, -1, -1, 1, 1, 1]),
  411. ... [-2.5, -1.5, -0.5, 0.5, 1.5, 2.5])
  412. >>> np.testing.assert_allclose(distance([1, 1, 1, -1, -1, -1]),
  413. ... [2.5, 1.5, 0.5, -0.5, -1.5, -2.5])
  414. Three point test case
  415. >>> np.testing.assert_array_equal(distance([-1, 0, 1]), [-1, 0, 1])
  416. >>> np.testing.assert_array_equal(distance([-1, 0, 1], dx=[2]), [-2, 0, 2])
  417. >>> np.testing.assert_array_equal(distance([-1, 0, 1], dx=2), [-2, 0, 2])
  418. >>> np.testing.assert_array_equal(distance([-1, 0, 1], dx=2.0), [-2, 0, 2])
  419. >>> np.testing.assert_array_equal(travel_time([1, 0, -1], [1, 1, 1]),
  420. ... [1, 0, 1])
  421. >>> np.testing.assert_array_equal(travel_time([-1, 0, 1], [1, 1, 1]),
  422. ... [1, 0, 1])
  423. >>> np.testing.assert_array_equal(travel_time([1, 0, -1], [1, 1, 1], dx=2),
  424. ... [2, 0, 2])
  425. >>> np.testing.assert_array_equal(travel_time([1, 0, -1], [1, 1, 1], dx=[2]),
  426. ... [2, 0, 2])
  427. >>> np.testing.assert_array_equal(travel_time([1, 0, -1], [1, 1, 1], dx=2.0),
  428. ... [2, 0, 2])
  429. Travel time tests 1
  430. >>> np.testing.assert_allclose(travel_time([0, 1, 1, 1, 1], [2, 2, 2, 2, 2]),
  431. ... [0, 0.5, 1.0, 1.5, 2.0])
  432. >>> np.testing.assert_array_equal(travel_time([1, 0, -1], [2, 2, 2]),
  433. ... [0.5, 0, 0.5])
  434. Travel time tests 2
  435. >>> phi = [1, 1, 1, -1, -1, -1]
  436. >>> t = travel_time(phi, np.ones_like(phi))
  437. >>> exact = [2.5, 1.5, 0.5, 0.5, 1.5, 2.5]
  438. >>> np.testing.assert_allclose(t, exact)
  439. Travel time tests 3
  440. >>> phi = [-1, -1, -1, 1, 1, 1]
  441. >>> t = travel_time(phi, np.ones_like(phi))
  442. >>> exact = [2.5, 1.5, 0.5, 0.5, 1.5, 2.5]
  443. >>> np.testing.assert_allclose(t, exact)
  444. Corner case
  445. >>> np.testing.assert_array_equal(distance([0, 0]), [0, 0])
  446. >>> np.testing.assert_array_equal(travel_time([0, 0], [1, 1]), [0, 0])
  447. Test zero
  448. >>> distance([1, 0, 1, 1], 0)
  449. Traceback (most recent call last):
  450. ...
  451. ValueError: dx must be greater than zero
  452. Test dx shape
  453. >>> distance([0, 0, 1, 0, 0], [0, 0, 1, 0, 0])
  454. Traceback (most recent call last):
  455. ...
  456. ValueError: dx must be of length len(phi.shape)
  457. Test for small speeds
  458. Test catching speeds which are too small. Speeds less than the
  459. machine epsilon are masked off to avoid an overflow.
  460. >>> t = travel_time([-1, -1, 0, 1, 1], [1, 1, 1, 1, 0])
  461. >>> assert isinstance(t, np.ma.MaskedArray)
  462. >>> np.testing.assert_array_equal(t.data[:-1], [2, 1, 0, 1])
  463. >>> np.testing.assert_array_equal(t.mask, [False, False, False, False, True])
  464. >>> t2 = travel_time([-1, -1, 0, 1, 1], [1, 1, 1, 1, 1e-300])
  465. >>> np.testing.assert_array_equal(t, t2)
  466. Mask test
  467. Test that when the mask cuts off the solution, the cut off points
  468. are also masked.
  469. >>> ma = np.ma.MaskedArray([1, 1, 1, 0], [False, True, False, False])
  470. >>> d = distance(ma)
  471. >>> exact = np.ma.MaskedArray([0, 0, 1, 0], [True, True, False, False])
  472. >>> np.testing.assert_array_equal(d.mask, exact.mask)
  473. >>> np.testing.assert_array_equal(d, exact)
  474. Circular level set
  475. >>> N = 50
  476. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  477. >>> r = 0.5
  478. >>> dx = 2.0 / (N - 1)
  479. >>> phi = (X) ** 2 + (Y) ** 2 - r ** 2
  480. >>> d = distance(phi, dx, self_test=True)
  481. >>> exact = np.sqrt(X ** 2 + Y ** 2) - r
  482. >>> np.testing.assert_allclose(d, exact, atol=dx)
  483. Planar level set
  484. >>> N = 50
  485. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  486. >>> dx = 2.0 / (N - 1)
  487. >>> phi = np.ones_like(X)
  488. >>> phi[0, :] = -1
  489. >>> d = distance(phi, dx, self_test=True)
  490. >>> exact = Y + 1 - dx / 2.0
  491. >>> np.testing.assert_allclose(d, exact)
  492. Masked input
  493. >>> N = 50
  494. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  495. >>> dx = 2.0 / (N - 1)
  496. >>> phi = np.ones_like(X)
  497. >>> phi[0, 0] = -1
  498. >>> mask = np.logical_and(abs(X) < 0.25, abs(Y) < 0.25)
  499. >>> mphi = np.ma.MaskedArray(phi.copy(), mask)
  500. >>> d0 = distance(phi, dx, self_test=True)
  501. >>> d = distance(mphi, dx, self_test=True)
  502. >>> d0[mask] = 0
  503. >>> d[mask] = 0
  504. >>> shadow = d0 - d
  505. >>> bsh = abs(shadow) > 0.001
  506. >>> diff = (bsh).sum()
  507. >>> assert diff > 635 and diff < 645
  508. Test Eikonal solution
  509. >>> N = 50
  510. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  511. >>> r = 0.5
  512. >>> dx = 2.0 / (N - 1)
  513. >>> phi = (X) ** 2 + (Y) ** 2 - r ** 2
  514. >>> speed = np.ones_like(phi) * 2
  515. >>> t = travel_time(phi, speed, dx)
  516. >>> exact = 0.5 * np.abs(np.sqrt(X ** 2 + Y ** 2) - 0.5)
  517. >>> np.testing.assert_allclose(t, exact, atol=dx)
  518. Test 1d
  519. >>> N = 100
  520. >>> X = np.linspace(-1.0, 1.0, N)
  521. >>> dx = 2.0 / (N - 1)
  522. >>> phi = np.zeros_like(X)
  523. >>> phi[X < 0] = -1
  524. >>> phi[X > 0] = 1
  525. >>> d = distance(phi, dx, self_test=True)
  526. >>> np.testing.assert_allclose(d, X)
  527. Test 3d
  528. >>> N = 15
  529. >>> X = np.linspace(-1, 1, N)
  530. >>> Y = np.linspace(-1, 1, N)
  531. >>> Z = np.linspace(-1, 1, N)
  532. >>> phi = np.ones((N, N, N))
  533. >>> phi[0, 0, 0] = -1.0
  534. >>> dx = 2.0 / (N - 1)
  535. >>> d = distance(phi, dx, self_test=True)
  536. >>> exact = np.sqrt((X + 1) ** 2 +
  537. ... (Y + 1)[:, np.newaxis] ** 2 +
  538. ... (Z + 1)[:, np.newaxis, np.newaxis] ** 2)
  539. >>> np.testing.assert_allclose(d, exact, atol=dx)
  540. Test default dx
  541. >>> N = 50
  542. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  543. >>> r = 0.5
  544. >>> phi = (X) ** 2 + (Y) ** 2 - r ** 2
  545. >>> speed = np.ones_like(phi) * 2
  546. >>> out = travel_time(phi, speed, self_test=True)
  547. Test non-square grid and dx different in different directions
  548. >>> N = 50
  549. >>> NX, NY = N, 5 * N
  550. >>> X, Y = np.meshgrid(np.linspace(-1, 1, NY), np.linspace(-1, 1, NX))
  551. >>> r = 0.5
  552. >>> phi = X ** 2 + Y ** 2 - r ** 2
  553. >>> dx = [2.0 / (NX - 1), 2.0 / (NY - 1)]
  554. >>> d = distance(phi, dx, self_test=True)
  555. >>> exact = np.sqrt(X ** 2 + Y ** 2) - r
  556. >>> np.testing.assert_allclose(d, exact, atol=1.3*max(dx))
  557. No zero level set test
  558. >>> distance([1, 1], self_test=False)
  559. Traceback (most recent call last):
  560. ...
  561. ValueError: the array phi contains no zero contour (no zero level set)
  562. Shape mismatch test
  563. >>> travel_time([-1, 1], [2])
  564. Traceback (most recent call last):
  565. ...
  566. ValueError: phi and speed must have the same shape
  567. Speed wrong type test
  568. >>> travel_time([0, 0, 1, 1], 2)
  569. Traceback (most recent call last):
  570. ...
  571. ValueError: speed must be a 1D to 12-D array of doubles
  572. dx mismatch test
  573. >>> travel_time([-1, 1], [2, 2], [2, 2, 2, 2])
  574. Traceback (most recent call last):
  575. ...
  576. ValueError: dx must be of length len(phi.shape)
  577. Test c error handling
  578. >>> distance([-1, 1], self_test=44)
  579. Traceback (most recent call last):
  580. ...
  581. ValueError: self_test must be 0 or 1
  582. Check array type test
  583. >>> distance(np.array(["a", "b"]))
  584. Traceback (most recent call last):
  585. ...
  586. ValueError: phi must be a 1 to 12-D array of doubles
  587. >>> from skfmm import heap
  588. >>> h = heap(10,True)
  589. >>> h.push(0,0.2)
  590. 0
  591. >>> h.push(1,0.3)
  592. 1
  593. >>> h.push(2,0.1)
  594. 2
  595. >>> h.update(1, 0.01)
  596. >>> h.pop()
  597. (1, 0.01)
  598. >>> h.pop()
  599. (2, 0.1)
  600. >>> h.pop()
  601. (0, 0.2)
  602. >>> h.empty()
  603. True
  604. >>> h.pop()
  605. Traceback (most recent call last):
  606. ...
  607. RuntimeError: heap pop error: empty heap
  608. <BLANKLINE>
  609. Test narrow optional argument.
  610. >>> phi = np.array([-1,-1,-1,1,1,1])
  611. >>> d = distance(phi, narrow=1.0)
  612. >>> d.data[2:-2]
  613. array([-0.5, 0.5])
  614. >>> assert (d.mask == [ True, True, False, False, True, True]).all()
  615. >>> N = 50
  616. >>> X, Y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N))
  617. >>> r = 0.5
  618. >>> dx = 2.0 / (N - 1)
  619. >>> phi = (X) ** 2 + (Y) ** 2 - r ** 2
  620. >>> exact = np.sqrt(X ** 2 + Y ** 2) - r
  621. >>> d = distance(phi, dx)
  622. >>> bandwidth=5*dx
  623. >>> d2 = distance(phi, dx, narrow=bandwidth)
  624. >>> np.testing.assert_allclose(d, exact, atol=dx)
  625. >>> # make sure we get a normal array if there are no points outside the narrow band
  626. >>> np.testing.assert_allclose(distance(phi, dx, narrow=1000*dx), exact, atol=dx)
  627. >>> assert (d2<bandwidth).all()
  628. >>> assert type(d2) is np.ma.masked_array
  629. >>> speed = np.ones_like(phi)
  630. >>> speed[X>0] = 1.8
  631. >>> t = travel_time(phi, speed, dx)
  632. >>> t2 = travel_time(phi, speed, dx, narrow=bandwidth)
  633. >>> assert type(t2) is np.ma.masked_array
  634. >>> assert (t2<bandwidth).all()
  635. >>> speed = np.ones_like(phi)
  636. >>> speed = X + Y
  637. >>> ed, ev = extension_velocities(phi, speed, dx)
  638. >>> ed2, ev2 = extension_velocities(phi, speed, dx, narrow=bandwidth)
  639. >>> assert type(ed2) is np.ma.masked_array
  640. >>> assert type(ev2) is np.ma.masked_array
  641. >>> assert (ed2<bandwidth).all()
  642. >>> assert ed2.shape == ed.shape == ev.shape == ev2.shape
  643. >>> distance(phi, dx, narrow=-1)
  644. Traceback (most recent call last):
  645. ...
  646. ValueError: parameter "narrow" must be greater than or equal to zero.
  647. >>> # make sure the narrow options works with an existing mask.
  648. >>> mask = abs(X)<0.25
  649. >>> d3 = distance(np.ma.masked_array(phi, mask), dx, narrow=bandwidth)
  650. >>> assert (d3.mask[mask]==True).all()
  651. >>> assert d3.mask.sum() > mask.sum()
  652. Testing periodic argument
  653. >>> X, Y = np.meshgrid(np.linspace(-2,2,200), np.linspace(-2,2,200))
  654. >>> phi = -1*np.ones_like(X); phi[X**2+(Y-0.9)**2<0.5] = 1.0
  655. >>> speed = np.ones_like(X); speed[(X-0.9)**2+Y**2<1.0] = 2.0
  656. >>> np.allclose(distance(phi),distance(phi,periodic=False)) and np.allclose(distance(phi),distance(phi,periodic=(0,0)))
  657. True
  658. >>> np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=False)) and np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=(0,0)))
  659. True
  660. >>> phi = -1*np.ones_like(X); phi[X**2+Y**2<0.5] = 1.0
  661. >>> speed = np.ones_like(X); speed[X**2+Y**2<1.0] = 2.0
  662. >>> np.allclose(distance(phi),distance(phi,periodic=True)) and np.allclose(distance(phi),distance(phi,periodic=(1,1)))
  663. True
  664. >>> np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=True)) and np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=(1,1)))
  665. True
  666. >>> np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=True)) and np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=[1,1]))
  667. True
  668. >>> np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=True)) and np.allclose(travel_time(phi,speed),travel_time(phi,speed,periodic=[True,True]))
  669. True
  670. >>> phi = -1*np.ones_like(X); phi[X**2+(Y-0.9)**2<0.5] = 1.0
  671. >>> speed = np.ones_like(X); speed[(X-0.9)**2+Y**2<1.0] = 2.0
  672. >>> np.allclose(distance(np.roll(phi,137,axis=0),periodic=True),np.roll(distance(phi,periodic=True),137,axis=0))
  673. True
  674. >>> np.allclose(travel_time(np.roll(phi,-77,axis=1),np.roll(speed,-77,axis=1),periodic=True),np.roll(travel_time(phi,speed,periodic=True),-77,axis=1))
  675. True
  676. >>> phi=[1,-1,1,1,1,1]
  677. >>> speed=[4,1,2,2,2,2]
  678. >>> np.allclose(extension_velocities(phi,speed)[1],(2.5,2.5,1.5,1.5,1.5,1.5))
  679. True
  680. >>> np.allclose(extension_velocities(phi,speed,periodic=True)[1],(2.5,2.5,1.5,1.5,1.5,2.5))
  681. True
  682. This is issue #18,
  683. >>> phi = np.array([[ 1, 1, -1, -1, -1, -1, 1],
  684. ... [ 3, 1, -1, -1, -1, -1, 1],
  685. ... [ 3, 3, 1, 1, 1, 1, 3],
  686. ... [ 3, 3, 3, 3, 3, 3, 3],
  687. ... [ 3, 3, 3, 3, 3, 3, 3]])
  688. >>> speed = np.array([[ 1. , 1. , 0.057, 0.128, 0.037, 0.039, 1. ],
  689. ... [ 1. , 1. , 0.199, 0.408, 0.997, 0.688, 1. ],
  690. ... [ 1. , 1. , 1. , 1. , 1. , 1. , 1. ],
  691. ... [ 1. , 1. , 1. , 1. , 1. , 1. , 1. ],
  692. ... [ 1. , 1. , 1. , 1. , 1. , 1. , 1. ]])
  693. >>> assert not travel_time(phi,speed)[0][3] == 0
  694. >>> phi = np.array([[1, -1, -1],
  695. ... [0, 0, -1],
  696. ... [0, 0, 1]])
  697. >>> value = 0.01
  698. >>> speed = np.array([[ 1, value, 0.1],
  699. ... [ 0, 0, 1. ],
  700. ... [ 0, 0, 1. ]])
  701. >>> phi = np.ma.MaskedArray(phi, phi==0)
  702. >>> tt = travel_time(phi,speed)
  703. >>> tt.fill_value=0
  704. >>> np.testing.assert_allclose(tt.data, ((0.5, 50, 7.5),
  705. ... (0, 0, 0.5),
  706. ... (0, 0, 0.5)))
  707. This is from Pull Request #57:
  708. >>> a = np.array([[[600, 399, 641], [607, 605, 796], [602, 641, 797], [602, 658, 814]], [[272, -1, 398], [208, 282, 539], [209, 285, 513], [208, 298, 519]], [[-19, 51, 307], [-191, 2, 403], [-171, 5, 325], [-172, 3, 318]]])
  709. >>> d = distance(a)
  710. >>> assert not (d==0).any()
  711. A 2D version of this bug was also discovered
  712. >>> a = np.array([[399, -1, 51, 10.0], [605, 282, 2, -3], [641, 285, 5, -100], [658, 298, 3, -3]])
  713. >>> d = distance(a)
  714. >>> assert not (d==0).any()
  715. """
  716. def test(verbose=None):
  717. r"""
  718. Run all the doctests available.
  719. """
  720. import doctest
  721. import skfmm
  722. fail0, test0 = doctest.testmod(skfmm, verbose=verbose)
  723. fail1, test1 = doctest.testfile("heap.py", verbose=verbose)
  724. print ("Summary: {} tests run {} failures".format(test0+test1,
  725. fail0+fail1))
  726. return fail0+fail1

__init__.py at commit 3618765, under BSD-3-Clause · at the source

Overview

Authors: Kristin L Clark1, Shane Mecca1, Elio Almaoui1, Olivia L Bossardet2, Joseph M Holden1, David J Calkins1, Lauren K Wareham1
  1. Vanderbilt Eye Institute, Vanderbilt University Medical Center, Nashville, TN, United States
  2. School of Medicine, University of Miami, Miami, FL, United States
Institutions: Vanderbilt University Medical Center (United States); University of Miami (United States)
Journal: Frontiers in cellular neuroscience, volume 20, article 1870679
Dates: received 1 May 2026; accepted 12 June 2026; published online 2 July 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.3389/fncel.2026.1870679 · PMID 42459923 · PMCID PMC13372325 · OpenAlex W7166842734
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: mouse (organism), cellular / molecular (subfield)
Methods: Statistics, Connectivity, fMRI & imaging
Keywords: astrocyte, GLUT1, neurovascular coupling, neurovascular unit, perivascular endfeet, retina, retinal ganglion cell
Topic: Retinal Development and Disorders (Molecular Biology, Biochemistry, Genetics and Molecular Biology), according to OpenAlex
Funding: NEI NIH HHS (R01 EY036002)
Citations: not cited yet (Europe PMC); 44 references in the paper

Abstract

Astrocytes regulate metabolic exchange between the vasculature and neurons in the central nervous system (CNS). In the retina of the eye, also a component of the CNS, astrocyte endfeet couple to vascular elements to mediate glucose uptake via the glucose transporter GLUT1 and shuttle metabolic resources to the axons of retinal ganglion cells (RGCs), which provide visual input to the brain. In addition to its own transcriptional regulation, GLUT1 is also modulated by signaling pathways that influence its subcellular localization at the astrocyte-vascular interface. For example, cyclic guanosine monophosphate (cGMP) signaling, a key regulator of vascular tone, is associated with changes in retinal astrocyte morphology and is implicated in age-related loss of RGCs, suggesting a potential role in astrocyte function within the neurovascular unit. Here, we tested this possibility directly by investigating the effects of 8-Br-cGMP on astrocyte morphology, vascular interactions, and GLUT1 localization in the retina. Using a transgenic mouse that allows resolution of individual astrocytes in great detail across the retina (the G-MORF mouse), we show that acute elevation of 8-Br-cGMP increases astrocyte coverage area without altering overall vascular structure. 8-Br-cGMP treatment was also associated with enhanced astrocyte-vascular association, reflected by increased endfoot coverage of blood vessels and altered scaling of astrocyte contact with vessel size. Treatment to increase cGMP signaling promoted redistribution of GLUT1 to astrocyte perivascular endfeet without changing overall levels of GLUT1. Together, these findings indicate that increased cGMP signaling induces coordinated structural and molecular remodeling of astrocytes at the vascular interface. These results provide important insight into how cyclic nucleotide signaling pathways may regulate astrocyte organization in the retina and suggests a potential role for cGMP in modulating astrocyte-vascular interactions within the neurovascular unit.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 1 match between paragraphs and lines of code.

scikit-fmm/scikit-fmm

License: BSD-3-Clause
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 3618765f26fe469163840dd0d9775848ec379c3e, 1 July 2026
Languages: Python (8), C++ (8), C/C++ (5), Shell (2)
Size: 55 files, 23 scripts
Software Heritage: archived
Found in: the text
Holds: README, license file, environment (pyproject.toml, doc/requirements.txt), continuous integration, documentation
Not found: CITATION.cff, tests
Tools: NumPy (5 files), Matplotlib (4 files)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
25 files

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 23 scripts, each with its path and the digest of its content;
  • 1 match between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data availability statement

The raw data supporting the conclusions of this article will be made available by the authors, without undue reservation.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 7 authors, 7 keywords, 1 funder, 44 references.

Cite

This paper

Clark, K. L., Mecca, S., Almaoui, E., Bossardet, O. L., Holden, J. M., Calkins, D. J., & Wareham, L. K. (2026). Pharmacological activation of cGMP signaling promotes astrocyte remodeling and enrichment of perivascular GLUT1 in the murine retina. Frontiers in cellular neuroscience, 20, 1870679. https://doi.org/10.3389/fncel.2026.1870679

BibTeX

@article{clark2026pharmacological,
author = {Clark, Kristin L and Mecca, Shane and Almaoui, Elio and Bossardet, Olivia L and Holden, Joseph M and Calkins, David J and Wareham, Lauren K},
title = {{Pharmacological activation of cGMP signaling promotes astrocyte remodeling and enrichment of perivascular GLUT1 in the murine retina}},
journal = {Frontiers in cellular neuroscience},
year = {2026},
month = jul,
volume = {20},
pages = {1870679},
publisher = {Frontiers Media SA},
issn = {1662-5102},
doi = {10.3389/fncel.2026.1870679},
url = {https://doi.org/10.3389/fncel.2026.1870679},
pmid = {42459923},
pmcid = {PMC13372325}
}

RIS

TY - JOUR
AU - Clark, Kristin L
AU - Mecca, Shane
AU - Almaoui, Elio
AU - Bossardet, Olivia L
AU - Holden, Joseph M
AU - Calkins, David J
AU - Wareham, Lauren K
TI - Pharmacological activation of cGMP signaling promotes astrocyte remodeling and enrichment of perivascular GLUT1 in the murine retina
T2 - Frontiers in cellular neuroscience
J2 - Front Cell Neurosci
PY - 2026
DA - 2026/07/02
VL - 20
SP - 1870679
SN - 1662-5102
PB - Frontiers Media SA
DO - 10.3389/fncel.2026.1870679
UR - https://doi.org/10.3389/fncel.2026.1870679
LA - en
ER -

CSL-JSON

{
"id": "10.3389/fncel.2026.1870679",
"type": "article-journal",
"title": "Pharmacological activation of cGMP signaling promotes astrocyte remodeling and enrichment of perivascular GLUT1 in the murine retina",
"container-title": "Frontiers in cellular neuroscience",
"author": [
{
"family": "Clark",
"given": "Kristin L"
},
{
"family": "Mecca",
"given": "Shane"
},
{
"family": "Almaoui",
"given": "Elio"
},
{
"family": "Bossardet",
"given": "Olivia L"
},
{
"family": "Holden",
"given": "Joseph M"
},
{
"family": "Calkins",
"given": "David J"
},
{
"family": "Wareham",
"given": "Lauren K"
}
],
"container-title-short": "Front Cell Neurosci",
"volume": "20",
"page": "1870679",
"DOI": "10.3389/fncel.2026.1870679",
"PMID": "42459923",
"PMCID": "PMC13372325",
"ISSN": "1662-5102",
"publisher": "Frontiers Media SA",
"URL": "https://doi.org/10.3389/fncel.2026.1870679",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
2
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1126/sciadv.adx5109 [code]
Substance P regulates Tacr1 neurons, which control nitric oxide-mediated neurovascular coupling in the mouse cortex.
Journal: Science advances
In common: mouse, cellular / molecular, 3 references
[2] doi:10.1038/s42003-026-10646-6 [code]
Energy paradox in REM sleep: balancing supply and consumption in brain metabolism.
Journal: Communications biology
In common: Matplotlib, NumPy, mouse, cellular / molecular, 2 references
[3] doi:10.1113/jp290864
Heart failure-induced reprogramming of salt-evoked neurovascular coupling in the rat hypothalamus.
Journal: The Journal of physiology
In common: cellular / molecular, 3 references
[4] doi:10.1162/imag.a.1174 [code]
Retinal nerve fibre layer thickness reflects characteristics of brain grey and white matter.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Matplotlib, NumPy, 2 references
[5] doi:10.1371/journal.pcbi.1013113 [code]
Systems biology analysis of vasodynamics in mouse cerebral arterioles during resting state and functional hyperemia.
Journal: PLoS computational biology
In common: mouse, 2 references
[6] doi:10.1038/s41467-026-76132-z [code]
ATP13A4 gates extracellular polyamine levels to control excitatory synaptogenesis.
Journal: Nature communications
In common: mouse, 2 references
[7] doi:10.1167/iovs.67.5.73 [code]
Identification of a Small-Molecule Modulator of Astrocyte Reactivity for Optic Nerve Protection.
Journal: Investigative ophthalmology & visual science
In common: Matplotlib, NumPy, mouse, cellular / molecular, 1 reference
[8] doi:10.3389/fncel.2026.1830831
Brief mechanical pulses induce sustained intracellular L-lactate production in astrocytes.
Journal: Frontiers in cellular neuroscience
In common: cellular / molecular, 2 references
[9] doi:10.1002/jdn.70161 [code]
Spatio-Temporal Dynamics of Macroglial Cell Organization and Proximity to Blood Vessels During Postnatal Development.
Journal: International journal of developmental neuroscience : the official journal of the International Society for Developmental Neuroscience
In common: Matplotlib, NumPy, mouse, 1 reference
[10] doi:10.1038/s41592-026-03154-2 [code]
Simultaneous single-cell calcium imaging of neuronal population activity and brain-wide BOLD fMRI.
Journal: Nature methods
In common: Matplotlib, NumPy, mouse, 1 reference

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.