OSCR

Ultrasound neural interface enabling acute spinal cord monitoring and blood flow modulation

Code ↔ Paper

2 matches 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 2 matches
  1. [1] § MATERIALS AND METHODS › Ultrasound imaging acquisition ↔ HEPIUS_MUSIC_imaging-main/matlab/SetUpL11_5vSpectralDoppler.m, lines 1 to 74 · score 0.83 · Vantage NXT, duplex mode, Doppler PRF, ultrasound system, spectral Doppler, Doppler image · Report a mismatch
  2. [2] § MATERIALS AND METHODS › Ultrasound imaging acquisition ↔ HEPIUS_MUSIC_imaging-main/matlab/SetupMusicSD_saveiq.m, lines 1 to 95 · score 0.75 · duplex mode, Doppler PRF, ultrasound system, Doppler image, spectral Doppler, pixel · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

MATLAB · 868 lines · 33 KB · no license · 1 match

  1. %
  2. % File name: SetUpL11_5vSpectralDoppler.m - Spectral doppler with plane wave transmit.
  3. %
  4. % Description:
  5. % Sequence programming file for L11-5v Linear array, using plane wave
  6. % transmits for 2D and doppler imaging.
  7. % - for the 2D image, a single plane wave transmit is used. All transmit
  8. % and receive channels are active for each acquisition.
  9. % - for the doppler ensemble, multiple pulses are transmitted at a
  10. % steering angle of dopAngle radians. 128 transmit and 64 receive
  11. % channels are active for each acquisition. The Doppler measurement
  12. % region is the region under the central 64 transducer elements.
  13. % - processing is asynchronous with respect to acquisition
  14. % - An acquisition 'frame' consists of the number of transmit/receive events
  15. % that equals 10msec of time. Doppler and 2D acquisitions are interleaved.
  16. % - Doppler PRF will be quantized such that the acquisition PRF (twice
  17. % the Doppler PRF) has a PRI of integer microseconds.
  18. % - For the Doppler measurement, the sample volume in the measurement
  19. % region is selected by clicking the left mouse button in the DisplayWindow.
  20. % The sample volume is selected as a single I,Q pixel whose location is
  21. % indicated by a red circle. This action also switches the processing mode
  22. % to Doppler only. Clicking the right mouse button cancels the Doppler
  23. % processing and returns to 2D only processing. While the processing
  24. % operates in duplex mode - either 2D or Doppler, acquisition is always
  25. % the same, allowing Doppler operation in RcvData Loop playback mode.
  26. %
  27. % Notice:
  28. % This file is provided by Verasonics to end users as a programming
  29. % example for the Verasonics Vantage NXT Research Ultrasound System.
  30. % Verasonics makes no claims as to the functionality or intended
  31. % application of this program and the user assumes all responsibility
  32. % for its use.
  33. %
  34. % Copyright © 2013-2023 Verasonics, Inc.
  35. clear all
  36. % - 2D P(1) structure
  37. P(1).startDepth = 2; % Acquisition depth in wavelengths
  38. P(1).endDepth = 128; % This should preferrably be a multiple of 128 samples.
  39. % - Doppler P(2) structure (This is the pixel region for possible Doppler reconstructions.)
  40. P(2).startDepth = 0; % Acquisition depth in wavelengths
  41. P(2).endDepth = 128; % This should preferrably equate to a multiple of 128 samples.
  42. nfrms = 10; % no. of frames to acquire in RcvBuffer (sets size of RF cineloop).
  43. dopPRFnominal = 2000;
  44. framePeriodnominal_uSec = 40000; % nominal frame period for collections of PRIs.
  45. [psched ] = spectralDoppler('restrictAcqPRF',framePeriodnominal_uSec,dopPRFnominal);
  46. [pschedAll ]= spectralDoppler('restrictAcqPRF',framePeriodnominal_uSec,[]);
  47. disp(' '),
  48. disp([mfilename,': Allowed PRF values: '])
  49. disp(sprintf('%4.4f Hz\n',pschedAll.PRFDop))
  50. framePeriod = psched.FrameTime_uSec*1e-6;
  51. dopPRF = psched.PRFDop;
  52. ttna_microsec = psched.PRIAcq_uSec;
  53. acqPRF = psched.PRFAcq;
  54. maxAcqPRF = psched.maxPRFAcq;
  55. maxDopPRF = psched.maxPRFDop;
  56. minAcqPRF = psched.minPRFAcq;
  57. minDopPRF = psched.minPRFDop;
  58. NWindow = round(dopPRF*0.014); %samples in FFT window (not including zero padding)
  59. SDDespeckle = 0.4;
  60. dopWFCutoffNorm = 0.025; %allfilter normalized cutoff frequency
  61. dopSweepTimeIndex = 2;%1-4 avail for 20msec frame time
  62. SDDynRangeDB = 13;% not including FFT processing gain
  63. sgp= spectralDoppler('spectrogramParameters',framePeriod,dopSweepTimeIndex);
  64. sweepTime = sgp.THist;
  65. baseLineShiftNorm = -0.375;
  66. nPRIs = psched.pulsesPerFrameAcq; % needs to start as even .default no. of acquisition PRIs in a 'frame'
  67. nDopPRIs = psched.pulsesPerFrameDop;
  68. dopAngle = 14 * pi/180; % angle for Doppler flash transmits.
  69. maxPRIs = psched.pulsesPerFrameAcqMax ; % max no. of acquisition PRIs in a frame .
  70. % - Specify system parameters
  71. Resource.Parameters.numTransmit = 244; % number of transmit channels.
  72. Resource.Parameters.numRcvChannels = 244; % number of receive channels.
  73. Resource.Parameters.speedOfSound = 1540;
  74. Resource.Parameters.speedCorrectionFactor = 1.0;
  75. Resource.Parameters.initializeOnly = 0;
  76. Resource.Parameters.simulateMode = 0;
  77. Resource.Parameters.Connector = [1,2];
  78. % Specify Trans structure array.
  79. %Trans.name = 'L11-5v';
  80. Trans.name = 'MUSIC3_Biobox';
  81. Trans.units = 'wavelengths'; % Explicit declaration avoids warning message when selected by default
  82. Trans = computeTrans2(Trans); % computeTrans is used for known transducers.
  83. Trans.maxHighVoltage = 30; % set a reasonable high voltage limit.
  84. % Specify PData structure arrays.
  85. % - 2D PData structure
  86. PData(1).PDelta = [1.0,0,0.5];
  87. PData(1).Size(1,1) = ceil(P(1).endDepth/PData(1).PDelta(3)); % rows
  88. PData(1).Size(1,2) = ceil((Trans.numelements*Trans.spacing)/PData(1).PDelta(1)); % cols
  89. PData(1).Size(1,3) = 1; % single image page
  90. PData(1).Origin = [-Trans.spacing*(Trans.numelements-1)/2,0,P(1).startDepth]; % x,y,z of upr lft crnr w respect to xducer origin.
  91. % - Doppler PData structure
  92. PData(2).PDelta = [1.0,0,1.0];
  93. PData(2).Size(1,1) = 4; % 4 IQ samples for Doppler
  94. PData(2).Size(1,2) = 1; % single column for Doppler
  95. PData(2).Size(1,3) = 1; % single image page
  96. PData(2).Origin = [0,0,ceil(P(2).endDepth/2)];
  97. % - Region Outline for Region Constrain of Doppler Processing
  98. DopRegionLim.x = [-32,32]; % in wavelength
  99. DopRegionLim.y = [4,128];
  100. PData(3) = PData(1);
  101. PData(3).Region = struct('Shape',struct('Name','Rectangle',...
  102. 'Position',[0,0,DopRegionLim.y(1)],...
  103. 'width',diff(DopRegionLim.x),...
  104. 'height',diff(DopRegionLim.y)));
  105. % Specify Media object.
  106. pt1;
  107. Media.function = 'movePoints';
  108. % - RcvBuffer(1) is for 2D, and Doppler steering angle.
  109. Resource.RcvBuffer(1).datatype = 'int16';
  110. Resource.RcvBuffer(1).rowsPerFrame = 2048*maxPRIs;
  111. Resource.RcvBuffer(1).colsPerFrame = Resource.Parameters.numRcvChannels;
  112. Resource.RcvBuffer(1).numFrames = nfrms;
  113. % - InterBuffer(1) is for 2D data.
  114. Resource.InterBuffer(1).datatype = 'complex';
  115. Resource.InterBuffer(1).numFrames = 1; % one intermediate frame needed for 2D.
  116. % - InterBuffer(2) is for Doppler data.
  117. Resource.InterBuffer(2).datatype = 'complex';
  118. Resource.InterBuffer(2).numFrames = 1; % two intermediate frames needed for color
  119. Resource.InterBuffer(2).pagesPerFrame = maxPRIs/2; % no. of pages set by maxPRIs
  120. % - ImageBuffer(1) is for 2D image.
  121. Resource.ImageBuffer(1).datatype = 'double';
  122. Resource.ImageBuffer(1).numFrames = 10;
  123. % - DisplayWindow for 2D image
  124. Resource.DisplayWindow(1).Title = 'L11-5vSpectralDoppler';
  125. Resource.DisplayWindow(1).pdelta = 0.4;
  126. ScrnSize = get(0,'ScreenSize');
  127. DwWidth = ceil(PData(1).Size(2)*PData(1).PDelta(1)/Resource.DisplayWindow(1).pdelta);
  128. DwHeight = ceil(PData(1).Size(1)*PData(1).PDelta(3)/Resource.DisplayWindow(1).pdelta);
  129. Resource.DisplayWindow(1).Position = [250,(ScrnSize(4)-(DwHeight+150))/2, ... % lower left corner position
  130. DwWidth, DwHeight];
  131. Resource.DisplayWindow(1).ReferencePt = [PData(1).Origin(1),0,PData(1).Origin(3)]; % 2D imaging is in the X,Z plane
  132. Resource.DisplayWindow(1).numFrames = 20;
  133. Resource.DisplayWindow(1).Type = 'Verasonics';
  134. Resource.DisplayWindow(1).AxesUnits = 'mm';
  135. Resource.DisplayWindow(1).Colormap = gray(256);
  136. % Specify Transmit waveform structure.
  137. % - 2D transmit waveform
  138. TW(1).type = 'parametric';
  139. TW(1).Parameters = [Trans.frequency,0.67,2,1];
  140. % - Doppler transmit waveform
  141. TW(2).type = 'parametric';
  142. TW(2).Parameters = [Trans.frequency,0.67,6,1];
  143. % Specify TX structure arrays.
  144. % We need 1 TX specification for 2D and 1 TX specification for Doppler (1 steering angle).
  145. TX = repmat(struct('waveform', 1, ...
  146. 'Origin', [0.0,0.0,0.0], ...
  147. 'focus', 0.0, ...
  148. 'Steer', [0.0,0.0], ...
  149. 'Apod', ones(1,Trans.numelements), ...
  150. 'Delay', zeros(1,Trans.numelements)), 1, 2); %
  151. % - Set event specific TX attributes.
  152. TX(1).Delay = computeTXDelays(TX(1));
  153. % -- Second TX struct needed for Doppler
  154. TX(2).waveform = 2;
  155. TX(2).Steer = [dopAngle,0.0];
  156. TX(2).Delay = computeTXDelays(TX(2));
  157. % Specify TGC Waveform structures.
  158. % 2D TGC waveform
  159. TGC(1).CntrlPts = [51,331,430,515,603,690,777,887];
  160. TGC(1).rangeMax = P(1).endDepth;
  161. TGC(1).Waveform = computeTGCWaveform(TGC(1));
  162. % Doppler TGC waveform
  163. TGC(2).CntrlPts = [400,500,640,710,770,830,890,950];
  164. TGC(2).rangeMax = P(1).endDepth;
  165. TGC(2).Waveform = computeTGCWaveform(TGC(2));
  166. % Specify Receive structure arrays -
  167. % Define enough Receives to handle the maxPRI case. For lower PRIs, some of the Receives will go
  168. % unused in the Event list.
  169. % endDepth - add additional acquisition depth to account for some channels
  170. % having longer path lengths.
  171. maxAcqLength = ceil(sqrt(P(1).endDepth^2 + ((Trans.numelements-1)*Trans.spacing)^2));
  172. Receive = repmat(struct('Apod', zeros(1,Trans.numelements), ...
  173. 'startDepth', P(1).startDepth, ...
  174. 'endDepth', maxAcqLength, ...
  175. 'TGC', 1, ...
  176. 'bufnum', 1, ...
  177. 'framenum', 1, ...
  178. 'acqNum', 1, ...
  179. 'sampleMode', 'BS100BW',...
  180. 'mode', 0, ...
  181. 'callMediaFunc', 0),1,maxPRIs*nfrms);
  182. % - Set event specific Receive attributes.
  183. for i = 1:nfrms
  184. k = maxPRIs*(i-1);
  185. for j = 1:2:maxPRIs
  186. % -- 2D acquisition.
  187. Receive(k+j).Apod(1:128) = 1.0;
  188. Receive(k+j).framenum = i;
  189. Receive(k+j).acqNum = j;
  190. if j==1, Receive(k+j).callMediaFunc = 1; end
  191. % -- Doppler.
  192. Receive(k+j+1).Apod(33:96) = 1.0; % start Dop aperture at element 33
  193. Receive(k+j+1).TGC = 2;
  194. Receive(k+j+1).framenum = i;
  195. Receive(k+j+1).acqNum = j+1;
  196. end
  197. end
  198. % Specify Recon structure arrays.
  199. % - We need a Recon structure for 2D and one for Doppler. The 2D frame will only use
  200. % the first two 2D acquisitions of the acquisition 'frame'.
  201. % - We only need one Recon structure for the Doppler line. The Doppler reconstruction will use
  202. % nPRIs/2 acquisitions from each 'frame' for reconstruction, with each Doppler PRI reconstructed
  203. % to a different page of the IQData buffer.
  204. Recon = repmat(struct('senscutoff', 0.6, ...
  205. 'pdatanum', 1, ...
  206. 'rcvBufFrame', -1, ... % use the most recent frame
  207. 'IntBufDest', [1,1], ...
  208. 'ImgBufDest', [1,-1], ...
  209. 'RINums', zeros(1,1)), 1, 2);
  210. % - Set Recon values for 2D frame.
  211. Recon(1).RINums(1,1:2) = (1:2); % 2 ReconInfos needed for 2-1 synthetic aperture
  212. k = 3;
  213. % - Set Recon values for first Doppler ensemble.
  214. Recon(2).pdatanum = 2;
  215. Recon(2).IntBufDest = [2,1];
  216. Recon(2).ImgBufDest = [];
  217. Recon(2).RINums(1,1:(nPRIs/2)) = (k:(k+(nPRIs/2)-1)); % nPRIs/2 ReconInfos needed for Doppler.
  218. Recon(2).senscutoff = 0.8; %reduce aperture to reduce angle spread
  219. % Define ReconInfo structures.
  220. % - For 2D, we need 2 ReconInfo structures.
  221. % - For Doppler, we only need nPRIs/2 ReconInfo structures for the default case, but we will
  222. % define maxPRIs/2 structures to allow handling the maxPRI case.
  223. ReconInfo = repmat(struct('mode', 'replaceIQ', ... % set replace IQ data as default.
  224. 'txnum', 1, ...
  225. 'rcvnum', 1, ...
  226. 'pagenum',1, ...
  227. 'regionnum', 1), 1, 2 + nPRIs/2);
  228. % - Set specific ReconInfo attributes.
  229. % - ReconInfos for 2D frame.
  230. ReconInfo(1).mode = 'replaceIQ'; % replace IQ data
  231. ReconInfo(1).txnum = 1;
  232. ReconInfo(1).rcvnum = 1;
  233. ReconInfo(2).mode = 'accumIQ_replaceIntensity'; % accum and detect
  234. ReconInfo(2).txnum = 1;
  235. ReconInfo(2).rcvnum = 3;
  236. k = 2;
  237. % - ReconInfos for Doppler ensemble.
  238. for j = 1:nPRIs/2
  239. ReconInfo(k+j).mode = 'replaceIQ';
  240. ReconInfo(k+j).txnum = 2;
  241. ReconInfo(k+j).rcvnum = 2*(j-1) + 2;
  242. ReconInfo(k+j).pagenum = j;
  243. ReconInfo(k+j).regionnum = 1; % only 1 col..
  244. end
  245. % Specify Process structure arrays.
  246. pers = 20;
  247. Process(1).classname = 'Image';
  248. Process(1).method = 'imageDisplay';
  249. Process(1).Parameters = {'imgbufnum',1,... % number of buffer to process.
  250. 'framenum',-1,... % (-1 => lastFrame)
  251. 'pdatanum',1,... % number of PData structure to use
  252. 'pgain',1.0,... % pgain is image processing gain
  253. 'reject',2,... % reject level
  254. 'persistMethod','simple',...
  255. 'persistLevel',pers,...
  256. 'interpMethod','4pt',...
  257. 'grainRemoval','none',...
  258. 'processMethod','none',...
  259. 'averageMethod','none',...
  260. 'compressMethod','power',...
  261. 'compressFactor',40,...
  262. 'mappingMethod','full',...
  263. 'display',1,... % display image after processing
  264. 'displayWindow',1};
  265. Process(2).classname = 'External';
  266. Process(2).method = 'spectralDoppler';
  267. Process(2).Parameters = {'srcbuffer','inter',... % name of buffer to process.
  268. 'srcbufnum',2,...
  269. 'srcframenum',1,...
  270. 'dstbuffer','none'};
  271. % EF2 is external function for ROI plot
  272. Process(3).classname = 'External';
  273. Process(3).method = 'ROIplot';
  274. Process(3).Parameters = {'srcbuffer','none'};
  275. % Specify SeqControl structure arrays. Missing fields are set to NULL.
  276. % - Jump back to start of acquisition.
  277. SeqControl(1).command = 'jump';
  278. SeqControl(1).argument = []; % will be modified later
  279. SeqControl(2).command = 'timeToNextAcq';
  280. SeqControl(2).argument = ttna_microsec ; % time in usec
  281. % loopCnt/loopTst are used to implement a conditional jump
  282. SeqControl(3).command = 'loopCnt'; % for 2D only
  283. SeqControl(3).argument = 0;
  284. SeqControl(4).command = 'loopCnt'; % for doppler
  285. SeqControl(4).argument = 1;
  286. nsc = 5; % nsc is count for next SeqControl object
  287. n = 1; % n is count for next Event
  288. Event(n).info = 'ROI plot';
  289. Event(n).tx = 0;
  290. Event(n).rcv = 0;
  291. Event(n).recon = 0;
  292. Event(n).process = 3;
  293. Event(n).seqControl = 0;
  294. n = n+1;
  295. Event(n).info = 'Start here for 2D only processing.';
  296. Event(n).tx = 0;
  297. Event(n).rcv = 0;
  298. Event(n).recon = 0;
  299. Event(n).process = 0;
  300. Event(n).seqControl = 3;
  301. n = n+1;
  302. Event(n).info = 'Jump to start of acquisitions';
  303. Event(n).tx = 0;
  304. Event(n).rcv = 0;
  305. Event(n).recon = 0;
  306. Event(n).process = 0;
  307. Event(n).seqControl = 1;
  308. n = n+1;
  309. Event(n).info = 'Start here for Doppler only processing.';
  310. Event(n).tx = 0;
  311. Event(n).rcv = 0;
  312. Event(n).recon = 0;
  313. Event(n).process = 0;
  314. Event(n).seqControl = 4;
  315. n = n+1;
  316. nStartAcq = n;
  317. SeqControl(1).argument = nStartAcq;
  318. for i = 1:nfrms % Acquire frames
  319. k = maxPRIs*(i-1);
  320. for j = 1:2:nPRIs % acquisition repeats every 2 acquisitions
  321. Event(n).info = '2D acquisition.';
  322. Event(n).tx = 1;
  323. Event(n).rcv = k+j;
  324. Event(n).recon = 0;
  325. Event(n).process = 0;
  326. Event(n).seqControl = 2;
  327. n = n+1;
  328. Event(n).info = 'Doppler acquisition.';
  329. Event(n).tx = 2;
  330. Event(n).rcv = k+j+1;
  331. Event(n).recon = 0;
  332. Event(n).process = 0;
  333. Event(n).seqControl = 2;
  334. n = n+1;
  335. end
  336. Event(n).info = 'transfer acquired frame data to host';
  337. Event(n).tx = 0;
  338. Event(n).rcv = 0;
  339. Event(n).recon = 0;
  340. Event(n).process = 0;
  341. Event(n).seqControl = nsc;
  342. SeqControl(nsc).command = 'transferToHost';
  343. nsc = nsc+1;
  344. n = n+1;
  345. Event(n).info = 'test loopCnt';
  346. Event(n).tx = 0;
  347. Event(n).rcv = 0;
  348. Event(n).recon = 0;
  349. Event(n).process = 0;
  350. Event(n).seqControl = nsc;
  351. SeqControl(nsc).command = 'loopTst';
  352. SeqControl(nsc).argument = n+3; % jump to Doppler if nz
  353. nsc = nsc+1;
  354. n = n+1;
  355. Event(n).info = 'recon and process 2D';
  356. Event(n).tx = 0;
  357. Event(n).rcv = 0;
  358. Event(n).recon = 1;
  359. Event(n).process = 1;
  360. Event(n).seqControl = 0;
  361. n = n+1;
  362. Event(n).info = 'jump over Doppler';
  363. Event(n).tx = 0;
  364. Event(n).rcv = 0;
  365. Event(n).recon = 0;
  366. Event(n).process = 0;
  367. Event(n).seqControl = nsc;
  368. SeqControl(nsc).command = 'jump';
  369. SeqControl(nsc).argument = n+3;
  370. nsc = nsc+1;
  371. n = n+1;
  372. Event(n).info = 'recon and process Doppler';
  373. Event(n).tx = 0;
  374. Event(n).rcv = 0;
  375. Event(n).recon = 2;
  376. Event(n).process = 2;
  377. Event(n).seqControl = 0;
  378. n = n+1;
  379. Event(n).info = 'set loopCnt back to 1';
  380. Event(n).tx = 0;
  381. Event(n).rcv = 0;
  382. Event(n).recon = 0;
  383. Event(n).process = 0;
  384. Event(n).seqControl = 4;
  385. n = n+1;
  386. Event(n).info = 'exit to Matlab';
  387. Event(n).tx = 0;
  388. Event(n).rcv = 0;
  389. Event(n).recon = 0;
  390. Event(n).process = 0;
  391. Event(n).seqControl = 0;
  392. % Exit to Matlab every 3rd frame
  393. if floor(i/3) == i/3
  394. Event(n).seqControl = nsc;
  395. SeqControl(nsc).command = 'returnToMatlab';
  396. nsc = nsc+1;
  397. end
  398. n = n+1;
  399. end
  400. Event(n).info = 'Jump back to the start of aquisition';
  401. Event(n).tx = 0;
  402. Event(n).rcv = 0;
  403. Event(n).recon = 0;
  404. Event(n).process = 0;
  405. Event(n).seqControl = 1;
  406. % User specified UI Control Elements
  407. import vsv.seq.uicontrol.VsSliderControl;
  408. % - Sensitivity Cutoff
  409. UI(1).Control = VsSliderControl( 'LocationCode', 'UserB7', ...
  410. 'Label', 'Sens. Cutoff', ...
  411. 'SliderMinMaxVal', [ 0,1.0,Recon(1).senscutoff], ...
  412. 'SliderStep', [0.025,0.1], ...
  413. 'ValueFormat', '%1.3f', ...
  414. 'Callback', @sensitivityCutoffCallback );
  415. % - Range Change
  416. MinMaxVal = [64,300,P(1).endDepth ]; % default unit is wavelength
  417. AxesUnit = 'wls';
  418. if isfield(Resource.DisplayWindow(1),'AxesUnits')&&~isempty(Resource.DisplayWindow(1).AxesUnits)
  419. if strcmp(Resource.DisplayWindow(1).AxesUnits,'mm')
  420. AxesUnit = 'mm';
  421. MinMaxVal = MinMaxVal * (Resource.Parameters.speedOfSound/1000/Trans.frequency);
  422. end
  423. end
  424. UI(2).Control = VsSliderControl( 'LocationCode', 'UserA1','Label',['Range (',AxesUnit,')'],...
  425. 'SliderMinMaxVal',MinMaxVal,'SliderStep',[0.1,0.2],'ValueFormat','%3.0f', ...
  426. 'Callback', @rangeChangeCallback);
  427. % - PRF control
  428. UI(3).Control = VsSliderControl( 'LocationCode', 'UserB4','Label','Doppler PRF',...
  429. 'SliderMinMaxVal',[minDopPRF,maxDopPRF,dopPRF],...
  430. 'SliderStep',[100/ (maxDopPRF-minDopPRF),200/ (maxDopPRF-minDopPRF)],'ValueFormat','%4.0f Hz', ...
  431. 'Callback', @dopplerPRFCallback);
  432. % - Wall Filter control
  433. UI(4).Control = VsSliderControl( 'LocationCode','UserB3','Label','Doppler WF',...
  434. 'SliderMinMaxVal',[8,0.1*maxDopPRF,dopWFCutoffNorm*dopPRF],...
  435. 'SliderStep',[0.02,0.2],'ValueFormat','%4.0f Hz', ...
  436. 'Callback', @dopplerWallFilterCallback);
  437. % - Sweep Time control
  438. UI(5).Control = VsSliderControl('LocationCode', 'UserB2','Label','Sweep Time',...
  439. 'SliderMinMaxVal',[min(sgp.THistAllow),max(sgp.THistAllow),sweepTime],...
  440. 'SliderStep',[0.25,0.25],'ValueFormat','%1.0f s', ...
  441. 'Callback', @sweepTimeCallback);
  442. % - Baseline control
  443. UI(6).Control = VsSliderControl('LocationCode', 'UserB1','Label','Baseline',...
  444. 'SliderMinMaxVal',[-0.5,0.5,baseLineShiftNorm],...
  445. 'SliderStep',[0.05,0.1],'ValueFormat','%1.2f', ...
  446. 'Callback', @baselineCallback );
  447. % - Window ButtonDown callback for setting sample volume position.
  448. UI(7).Callback = @wbdCallback;
  449. UI(7).Statement = @()setCallback(Resource.DisplayWindow(1).Type);
  450. % external functions
  451. import vsv.seq.function.ExFunctionDef;
  452. EF(1).Function = ExFunctionDef('setCallback', @setCallback);
  453. EF(2).Function = ExFunctionDef('ROIplot', @ROIplot );
  454. % Specify factor for converting sequenceRate to frameRate.
  455. frameRateFactor = 3;
  456. % Save all the structures to a .mat file.
  457. filename = 'MatFiles/L11-5vSpectralDoppler';
  458. % Save all the structures to a .mat file.
  459. save(filename);
  460. %% **** Callback routines used by External function definition (EF) ****
  461. function sensitivityCutoffCallback(~, ~, UIValue)
  462. ReconL = evalin('base', 'Recon');
  463. for i = 1:size(ReconL,2)
  464. ReconL(i).senscutoff = UIValue;
  465. end
  466. assignin('base','Recon',ReconL);
  467. Control = evalin('base','Control');
  468. Control.Command = 'update&Run';
  469. Control.Parameters = {'Recon'};
  470. assignin('base','Control', Control);
  471. return
  472. end
  473. function rangeChangeCallback(hObject, ~, UIValue )
  474. simMode = evalin('base','Resource.Parameters.simulateMode');
  475. % No range change if in simulate mode 2.
  476. if simMode == 2
  477. set(hObject,'Value',evalin('base','P.endDepth'));
  478. return
  479. end
  480. Trans = evalin('base','Trans');
  481. Resource = evalin('base','Resource');
  482. scaleToWvl = Trans.frequency/(Resource.Parameters.speedOfSound/1000);
  483. P = evalin('base','P');
  484. P(1).endDepth = UIValue;
  485. if isfield(Resource.DisplayWindow(1),'AxesUnits')&&~isempty(Resource.DisplayWindow(1).AxesUnits)
  486. if strcmp(Resource.DisplayWindow(1).AxesUnits,'mm')
  487. P(1).endDepth = UIValue*scaleToWvl;
  488. end
  489. end
  490. assignin('base','P',P);
  491. evalin('base','PData(1).Size(1) = ceil((P(1).endDepth-P(1).startDepth)/PData(1).PDelta(3));');
  492. evalin('base','PData(1).Region = computeRegions(PData(1));');
  493. evalin('base','Resource.DisplayWindow(1).Position(4) = ceil(PData(1).Size(1)*PData(1).PDelta(3)/Resource.DisplayWindow(1).pdelta);');
  494. Receive = evalin('base', 'Receive');
  495. maxAcqLength = ceil(sqrt(P(1).endDepth^2 + ((Trans.numelements-1)*Trans.spacing)^2));
  496. for i = 1:size(Receive,2)
  497. Receive(i).endDepth = maxAcqLength;
  498. end
  499. assignin('base','Receive',Receive);
  500. evalin('base','TGC(1).rangeMax = P(1).endDepth;');
  501. evalin('base','TGC(1).Waveform = computeTGCWaveform(TGC(1));');
  502. Control = evalin('base','Control');
  503. Control.Command = 'update&Run';
  504. Control.Parameters = {'PData','InterBuffer','ImageBuffer','Receive','TGC','Recon','DisplayWindow'};
  505. assignin('base','Control', Control);
  506. assignin('base', 'action', 'displayChange');
  507. return
  508. end
  509. function dopplerPRFCallback( hObject, ~, UIValue)
  510. dopPRFnom = UIValue;
  511. framePeriod = evalin('base','framePeriod');
  512. psched = spectralDoppler('restrictAcqPRF',round(framePeriod*1e6),dopPRFnom);
  513. acqPRF = psched.PRFAcq ;
  514. dopPRF = psched.PRFDop ;
  515. ttna_microsec = psched.PRIAcq_uSec ;
  516. % ttnaNom_microsec = psched.PRIAcq_uSec ;
  517. framePeriod = psched.FrameTime_uSec*1e-6 ;
  518. nPRIs= psched.pulsesPerFrameAcq ;
  519. nDopPRIs = psched.pulsesPerFrameDop ;
  520. % maxPRIs = psched.pulsesPerFrameAcqMax ;
  521. set(hObject,'Value',dopPRF);
  522. assignin('base', 'dopPRF', dopPRF);
  523. assignin('base', 'acqPRF', acqPRF);
  524. assignin('base', 'framePeriod', framePeriod);
  525. nfrms = evalin('base','nfrms');
  526. maxPRIs = evalin('base','maxPRIs');
  527. assignin('base','nDopPRIs',nDopPRIs);
  528. assignin('base','nPRIs',nPRIs);
  529. % Update the Doppler Recon to specify nDopPRIs ReconInfo structures.
  530. Recon = evalin('base','Recon');
  531. Recon(2).RINums(1,1:nDopPRIs) = (3:(3+(nDopPRIs)-1));
  532. assignin('base', 'Recon', Recon);
  533. ReconInfo = evalin('base','ReconInfo');
  534. % - ReconInfos for Doppler ensemble.
  535. k = 2;
  536. for j = 1:nPRIs/2
  537. ReconInfo(k+j).mode = 'replaceIQ';
  538. ReconInfo(k+j).txnum = 2;
  539. ReconInfo(k+j).rcvnum = 2*(j-1) + 2;
  540. ReconInfo(k+j).pagenum = j;
  541. ReconInfo(k+j).regionnum = 1; % only 1 col..
  542. end
  543. assignin('base','ReconInfo',ReconInfo);
  544. % Re-compute Event structures.
  545. Event = evalin('base','Event');
  546. nStartAcq = evalin('base','nStartAcq');
  547. n = nStartAcq;
  548. Event = Event(1:n-1); % throw out all but preamble
  549. SeqControl = evalin('base','SeqControl');
  550. nsc =5;
  551. SeqControl = SeqControl(1:nsc-1); % throw out all but those prior to nsc
  552. SeqControl(2).argument = ttna_microsec;
  553. % Re-build the Event list.
  554. for i = 1:nfrms % Acquire frames
  555. k = maxPRIs*(i-1);
  556. for j = 1:2:nPRIs % acquisition repeats every 2 acquisitions
  557. Event(n)=struct('info','2D acquisition.',...
  558. 'tx',1,'rcv',k+j,'recon',0,'process',0,'seqControl',2);
  559. n = n+1;
  560. Event(n)=struct('info','Doppler acquisition.',...
  561. 'tx',2,'rcv',k+j+1,'recon',0,'process',0,'seqControl',2);
  562. n = n+1;
  563. end
  564. Event(n)=struct('info','transfer acquired frame data to host',...
  565. 'tx',0,'rcv',0,'recon',0,'process',0,'seqControl',nsc);
  566. SeqControl(nsc).command = 'transferToHost';
  567. nsc = nsc+1;
  568. n = n+1;
  569. Event(n)=struct('info','test loopCnt',...
  570. 'tx',0,'rcv',0,'recon',0,'process',0,'seqControl',nsc);
  571. SeqControl(nsc).command = 'loopTst';
  572. SeqControl(nsc).argument = n+3; % jump to Doppler if nz
  573. nsc = nsc+1;
  574. n = n+1;
  575. Event(n)=struct('info','recon and process 2D',...
  576. 'tx',0,'rcv',0,'recon',1,'process',1,'seqControl',0);
  577. n = n+1;
  578. Event(n)=struct('info','jump over Doppler',...
  579. 'tx',0,'rcv',0,'recon',0,'process',0,'seqControl',nsc);
  580. SeqControl(nsc).command = 'jump';
  581. SeqControl(nsc).argument = n+3;
  582. nsc = nsc+1;
  583. n = n+1;
  584. Event(n)=struct('info','recon and process Doppler',...
  585. 'tx',0,'rcv',0,'recon',2,'process',2,'seqControl',0);
  586. n = n+1;
  587. Event(n)=struct('info','set loopCnt back to 1',...
  588. 'tx',0,'rcv',0,'recon',0,'process',0,'seqControl',4);
  589. n = n+1;
  590. Event(n)=struct('info','exit to Matlab',...
  591. 'tx',0,'rcv',0,'recon',0,'process',0,'seqControl',0);
  592. % Exit to Matlab every 3rd frame
  593. if floor(i/3) == i/3
  594. Event(n).seqControl = nsc;
  595. SeqControl(nsc).command = 'returnToMatlab';
  596. nsc = nsc+1;
  597. end
  598. n = n+1;
  599. end
  600. Event(n)=struct('info','Jump back to first event',...
  601. 'tx',0,'rcv',0,'recon',0,'process',0,'seqControl',1);
  602. assignin('base', 'Event', Event);
  603. assignin('base', 'SeqControl', SeqControl);
  604. % Update VDAS parameters for Receive objects
  605. evalin('base','VsUpdate(''Receive'')');
  606. % Set Control.Command to update changed structures in runAcq.
  607. Control = evalin('base','Control');
  608. Control.Command = 'update&Run';
  609. Control.Parameters = {'Recon','Event','SeqControl'};
  610. assignin('base','Control', Control);
  611. % Update the WF control:
  612. hwf = findobj('tag','UserB3Slider');
  613. dopWFCutoffNorm = evalin('base' ,'dopWFCutoffNorm');
  614. set(hwf,'Value',dopPRF*dopWFCutoffNorm);
  615. hwf = findobj('tag','UserB3Edit');
  616. set(hwf,'String',num2str(dopPRF*dopWFCutoffNorm,'%4.0f Hz'));
  617. return
  618. end
  619. function dopplerWallFilterCallback(~, ~, UIValue)
  620. dopPRF = evalin('base','dopPRF');
  621. dopWFCutoffNorm = UIValue/dopPRF;
  622. assignin('base', 'dopWFCutoffNorm', dopWFCutoffNorm);
  623. return
  624. end
  625. function sweepTimeCallback( hObject, ~, UIValue)
  626. %-UI#5Callback - Sweep Time
  627. sweepTime = round(UIValue);
  628. TFrame=evalin('base','framePeriod');
  629. sgp=spectralDoppler('spectrogramParameters',TFrame,1);
  630. [~,swInd] = min(abs(sgp.THistAllow-sweepTime));
  631. %sweepTimeAllowed = sgp.THistAllow(swInd);
  632. dopSweepTimeIndex = swInd;
  633. assignin('base', 'dopSweepTimeIndex', dopSweepTimeIndex);
  634. set(hObject,'Value',sweepTime);
  635. assignin('base', 'sweepTime', sweepTime);
  636. return
  637. end
  638. function baselineCallback( hObject, ~, UIValue)
  639. %-UI#6Callback - Baseline
  640. baseLineShiftNorm = UIValue;
  641. baseLineShiftNorm = round(baseLineShiftNorm*20)/20;
  642. set(hObject,'Value',baseLineShiftNorm);
  643. assignin('base', 'baseLineShiftNorm', baseLineShiftNorm);
  644. return
  645. end
  646. function wbdCallback(varargin)
  647. % Window ButtonDown callback for sample volume positioning.
  648. persistent init wbFig wbAxes elypHndl
  649. Trans = evalin('base','Trans');
  650. Resource = evalin('base','Resource');
  651. DopRegionLim = evalin('base','DopRegionLim');
  652. if isempty(init)
  653. init = 1;
  654. elypHndl = 0;
  655. end
  656. % Get pos ofmouse click and ensure the unit is wavelength for spectral doppler
  657. VsType = Resource.DisplayWindow(1).Type;
  658. if strcmp(VsType,'Matlab')
  659. hObject = varargin{1};
  660. wbFig = evalin('base','Resource.DisplayWindow(1).figureHandle');
  661. wbAxes = get(wbFig,'CurrentAxes');
  662. cp = get(wbAxes,'CurrentPoint');
  663. if isfield(Resource.DisplayWindow(1),'AxesUnits')&&~isempty(Resource.DisplayWindow(1).AxesUnits)
  664. if strcmp(Resource.DisplayWindow(1).AxesUnits,'mm')
  665. scaleToWvl = Trans.frequency/(Resource.Parameters.speedOfSound/1000);
  666. % wl2mm = (Resource.Parameters.speedOfSound/1000)/Trans.frequency;
  667. cp = cp*scaleToWvl;
  668. unitMm = 1;
  669. end
  670. else
  671. unitMm = 0;
  672. end
  673. % Check for sample volume outside of measurement region.
  674. x = min(max(cp(1,1),DopRegionLim.x(1)),DopRegionLim.x(2));
  675. z = min(max(cp(1,2),DopRegionLim.y(1)),DopRegionLim.y(2));
  676. else
  677. mct = evalin('base','mct');
  678. mouseButton = mct.buttonName;
  679. switch string(mouseButton)
  680. case 'Start'
  681. return
  682. case 'Left'
  683. hObject.SelectionType = 'normal';
  684. imageViewer = evalin('base','imageViewer');
  685. imageCanvas = imageViewer(1).getImageCanvas();
  686. srcImage = imageCanvas.getSrcImage;
  687. x = mct.xImgPos/srcImage.pixelUnitScaling;
  688. z = mct.yImgPos/srcImage.pixelUnitScaling;
  689. case 'Right'
  690. hObject.SelectionType = 'alt';
  691. end
  692. end
  693. % Change Event Sequence if left mouse button is pressed
  694. if strcmp(hObject.SelectionType,'normal')
  695. if elypHndl == 0
  696. % set startEvent for Doppler only.
  697. Control = evalin('base','Control');
  698. Control(2).Command = 'set&Run';
  699. Control(2).Parameters = {'Parameters',1,'startEvent',4};
  700. evalin('base','Resource.Parameters.startEvent = 4;');
  701. else
  702. delete(elypHndl); % delete previous annotation circle
  703. end
  704. if strcmp(VsType,'Matlab')
  705. % set annotation in the Matlab Viewer (Verasonics Viewer is done in MouseClickTool)
  706. abox = [x-1,z-1,2,2];
  707. axun = get(wbAxes,'Units'); % save axis units
  708. set(wbAxes,'Units','normalized'); % make axes units normalized
  709. axpos = get(wbAxes,'Position'); % get axes position
  710. axlim = axis(wbAxes); % get the axis limits [xlim ylim (zlim)]
  711. if unitMm, axlim = axlim*scaleToWvl; end
  712. axwidth = diff(axlim(1:2));
  713. axheight = diff(axlim(3:4));
  714. % Transform from data space coordinates to normalized figure coordinates
  715. bbox(1) = (abox(1)-axlim(1))/axwidth * axpos(3) + axpos(1);
  716. bbox(2) = (axlim(4)-abox(2))/axheight * axpos(4) + axpos(2);
  717. bbox(3) = abox(3) * axpos(3)/axwidth;
  718. bbox(4) = abox(4) * axpos(4)/axheight;
  719. set(wbAxes,'Units',axun); % restore axis units
  720. elypHndl = annotation('ellipse',bbox,'EdgeColor',[1 .2 .2],'LineWidth',1.0);
  721. end
  722. assignin('base','SVPos',[x,z-2])
  723. %Modify structures for new SV position.
  724. evalin('base','PData(2).Origin = [SVPos(1),0,SVPos(2)];');
  725. evalin('base','PData(2).Region=computeRegions(PData(2));');
  726. Control(1).Command = 'update&Run';
  727. Control(1).Parameters = {'PData'};
  728. assignin('base','Control', Control);
  729. % if right mouse button ...
  730. elseif strcmp(hObject.SelectionType,'alt')
  731. % delete annotation circle
  732. if elypHndl ~= 0
  733. delete(elypHndl);
  734. elypHndl = 0;
  735. end
  736. % set startEvent for 2D only
  737. Control.Command = 'set&Run';
  738. Control.Parameters = {'Parameters',1,'startEvent',1};
  739. evalin('base','Resource.Parameters.startEvent = 1;');
  740. assignin('base','Control',Control);
  741. end
  742. return
  743. end
  744. %% **** Callback routines used by External function definition (EF) ****
  745. function setCallback(VsType)
  746. switch VsType
  747. case 'Verasonics'
  748. vantageWindow = evalin('base','vantageWindow');
  749. imageViewer = evalin('base','imageViewer');
  750. DopRegionLim = evalin('base','DopRegionLim');
  751. mct = javaObjectEDT( 'com.verasonics.viewer.tools.mouseclicktool.MouseClickTool', vantageWindow, imageViewer(1));
  752. mcth = javaObjectEDT( handle(mct, 'callbackproperties' ) );
  753. mct.setToolEnabled(true);
  754. mct.lowerLimitX = DopRegionLim.x(1);
  755. mct.upperLimitX = DopRegionLim.x(2);
  756. mct.lowerLimitY = DopRegionLim.y(1);
  757. mct.upperLimitY = DopRegionLim.y(2);
  758. mcth.ClickedEventCallback = @wbdCallback;
  759. assignin('base','mct',mct);
  760. case 'Matlab'
  761. evalin('base','set(Resource.DisplayWindow(1).figureHandle,''WindowButtonDownFcn'',@wbdCallback);');
  762. end
  763. return
  764. end
  765. function ROIplot(varargin)
  766. %ROIplot
  767. persistent drawROI
  768. % drawRegionOutline(WinNum,PDataNum,RegionNum) creates an outline from
  769. % PData(PDataNum).Region(RegionNum) on displayWindow(WinNum) with default color - white.
  770. if isempty(drawROI)
  771. drawROI = 1;
  772. evalin('base','hROI = drawRegionOutline(1,3,1);')
  773. else
  774. evalin('base','drawRegionOutline(hROI,1,3,1);')
  775. end
  776. return
  777. end

SetUpL11_5vSpectralDoppler.m, no license · at the source

Overview

Authors: Max J Kerensky1,2, Siddharth Krishnan2,3, Ruixing Liang2,4, Kelley M Kempski Leadingham2,3, Victor M Quiroz1,5, Joshua Punnoose2,3, Constantin Smit2,3, Denis Routkevitch1,2,3, Avisha Kumar2,4, A Daniel Davidar2,3, Leonard Steger2,3, Carly Weber-Levine2,3, Kelly Jiang2,3, Meghana Bhimreddy2,3, Stuart J Bauer1,5, Angelica F Lopez1,2, Patrick Kramer2,3, Kayla Robinson2,6, Arjun K Menta2,3, Abdul Karim Ghaith2,3
and 22 other authorsAndrew M Hersh2,3, Haley G Abramson1,2,7, Ali Mohammadabadi2,3, John N Theodore1,5, Osamah M Zmily1,5, Ritvik Jillala2,3, Vikas Vattipally2,3, David Kopala1,2, Siavash S Barough8, Mohammad Hossein Amini9, Jonathan Maltz10, Francisco Chavez11, Kyle Morrison11, Laura Roy12, Ian Suk3, Ryan P Lee3, Betty Tyler3, Mark Luciano3, Nitish V Thakor1,2,4, Joshua C Doloff1,5,13, Nicholas Theodore1,2,3,14,15, Amir Manbachi1,2,3,4,6,16
16 affiliations
  1. Department of Biomedical Engineering, Johns Hopkins University, Baltimore, MD, USA
  2. HEPIUS Innovation Laboratory, School of Medicine, Johns Hopkins University, Baltimore, MD, USA
  3. Department of Neurosurgery, Johns Hopkins University, Baltimore, MD, USA
  4. Department of Electrical & Computer Engineering, Johns Hopkins University, Baltimore, MD, USA
  5. Translational Therapeutics & Regenerative Engineering Center, Johns Hopkins University, Baltimore, MD, USA
  6. Department of Mechanical Engineering, Johns Hopkins University, Baltimore, MD, USA
  7. Advanced Patient Monitoring, Becton, Dickinson, and Company, Irvine, CA, USA
  8. Department of Neurology, Johns Hopkins University, Baltimore, MD, USA
  9. Fujifilm Visualsonics Inc., Toronto, ON, Canada
  10. Molecular Biophysics and Integrated Bioimaging, Berkeley Lab, University of California, Berkeley, CA, USA
  11. Sonic Concepts Inc., Bothell, WA, USA
  12. Roy Illustration, New York, NY, USA
  13. Department of Materials Science and Engineering, Institute for NanoBioTechnology, Johns Hopkins University, Baltimore, MD, USA
  14. Department of Orthopaedic Surgery, School of Medicine, Johns Hopkins University, Baltimore, MD, USA
  15. Department of Pediatrics, School of Medicine, Johns Hopkins University, Baltimore, MD, USA
  16. Department of Anesthesiology and Critical Care, School of Medicine, Johns Hopkins University, Baltimore, MD, USA
Journal: Science advances, volume 12, issue 45, article eaeg2342
Dates: received 8 February 2026; accepted 1 October 2026; published online 4 November 2026; in print November 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI · PMCID PMC13733905
Status: code verified (how the code is found and verified)
Categories: other (modality), clinical / translational (subfield)
Methods: Spectral & time-frequency, fMRI & imaging, Physiology & signal measures
Citations: not cited yet (Europe PMC); 91 references in the paper

Abstract

The days following decompression surgery for acute spinal cord injury (SCI) are a critical period for postoperative monitoring. After wound closure, clinicians lack on-demand access to local spinal cord morphology and hemodynamics, and care therefore remains guided largely by systemic surrogates rather than direct postoperative insight into the injured cord. We present the Multimodal Ultrasound System for Injury Care (MUSIC), a temporary epidural ultrasound neural interface placed during standard decompression surgery to enable postoperative brightness-mode imaging, Doppler-derived hemodynamic monitoring, and future device-integrated ultrasound actuation. Across simulations, benchtop, human cadaveric, and porcine studies, MUSIC enabled on-demand visualization of cord structure, hematoma tracking, detection and longitudinal tracking of localized Doppler flow signatures attributable to the sulcal artery region, and, in healthy pigs, proof-of-concept focused ultrasound modulation of blood-flow velocity. MUSIC establishes a temporary postoperative acoustic interface that provides spinal cord information to inform monitoring, future management, and localized intervention strategies after SCI.

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

Repositories

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

Zenodo 22908234

License: none: the authors keep all their rights
State: the link answers, verified on 7 November 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Data, code, and materials availability:”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 7 November 2026: the link answers (HTTP 200)
  • 7 November 2026: the link answers (HTTP 200)
267 files

Zenodo 22907737

License: Apache-2.0
State: the link answers, verified on 7 November 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Data, code, and materials availability:”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (5 files), NumPy (5 files), pandas (4 files), SciPy (4 files), seaborn (3 files), scikit-learn (2 files), Plotly (1 file), statannotations (1 file), statsmodels (1 file)
Availability: 1 check, the latest on 7 November 2026: the link answers (HTTP 200)
  • 7 November 2026: the link answers (HTTP 200)
8 files

Zenodo 22908477

License: none: the authors keep all their rights
State: the link answers, verified on 7 November 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Data, code, and materials availability:”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 7 November 2026: the link answers (HTTP 200)
  • 7 November 2026: the link answers (HTTP 200)
7 files

The paper's code and data availability statement is in the Data section.

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:

  • 3 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 282 scripts, each with its path and the digest of its content;
  • 2 matches 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

Datasets cited

Data, code, and materials availability

All data and code needed to evaluate and reproduce the results in the paper are present in the paper and/or the Supplementary Materials and the permanent repositories cited here. Experimental data and analyses are archived in Dryad at https://doi.org/10.5061/dryad.nk98sf891. Publication-version software associated with MUSIC imaging, focused-ultrasound analysis, and the MUSIC mobile application is archived in Zenodo at https://doi.org/10.5281/zenodo.22908234, https://doi.org/10.5281/zenodo.22907737, and https://doi.org/10.5281/zenodo.22908477, respectively. The corresponding development repositories are available through the HEPIUS Lab GitHub organization at https://github.com/HEPIUSLAB. This study did not generate new materials.

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, 7 November 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 42 authors, 74 references.

Cite

This paper

Kerensky, M. J., Krishnan, S., Liang, R., Kempski Leadingham, K. M., Quiroz, V. M., Punnoose, J., Smit, C., Routkevitch, D., Kumar, A., Davidar, A. D., Steger, L., Weber-Levine, C., Jiang, K., Bhimreddy, M., Bauer, S. J., Lopez, A. F., Kramer, P., Robinson, K., Menta, A. K., . . . Manbachi, A. (2026). Ultrasound neural interface enabling acute spinal cord monitoring and blood flow modulation. Science advances, 12(45), eaeg2342.

BibTeX

@article{kerensky2026ultrasound,
author = {Kerensky, Max J and Krishnan, Siddharth and Liang, Ruixing and Kempski Leadingham, Kelley M and Quiroz, Victor M and Punnoose, Joshua and Smit, Constantin and Routkevitch, Denis and Kumar, Avisha and Davidar, A Daniel and Steger, Leonard and Weber-Levine, Carly and Jiang, Kelly and Bhimreddy, Meghana and Bauer, Stuart J and Lopez, Angelica F and Kramer, Patrick and Robinson, Kayla and Menta, Arjun K and Ghaith, Abdul Karim and Hersh, Andrew M and Abramson, Haley G and Mohammadabadi, Ali and Theodore, John N and Zmily, Osamah M and Jillala, Ritvik and Vattipally, Vikas and Kopala, David and Barough, Siavash S and Amini, Mohammad Hossein and Maltz, Jonathan and Chavez, Francisco and Morrison, Kyle and Roy, Laura and Suk, Ian and Lee, Ryan P and Tyler, Betty and Luciano, Mark and Thakor, Nitish V and Doloff, Joshua C and Theodore, Nicholas and Manbachi, Amir},
title = {{Ultrasound neural interface enabling acute spinal cord monitoring and blood flow modulation}},
journal = {Science advances},
year = {2026},
month = nov,
volume = {12},
number = {45},
pages = {eaeg2342},
publisher = {American Association for the Advancement of Science},
issn = {2375-2548},
pmcid = {PMC13733905}
}

RIS

TY - JOUR
AU - Kerensky, Max J
AU - Krishnan, Siddharth
AU - Liang, Ruixing
AU - Kempski Leadingham, Kelley M
AU - Quiroz, Victor M
AU - Punnoose, Joshua
AU - Smit, Constantin
AU - Routkevitch, Denis
AU - Kumar, Avisha
AU - Davidar, A Daniel
AU - Steger, Leonard
AU - Weber-Levine, Carly
AU - Jiang, Kelly
AU - Bhimreddy, Meghana
AU - Bauer, Stuart J
AU - Lopez, Angelica F
AU - Kramer, Patrick
AU - Robinson, Kayla
AU - Menta, Arjun K
AU - Ghaith, Abdul Karim
AU - Hersh, Andrew M
AU - Abramson, Haley G
AU - Mohammadabadi, Ali
AU - Theodore, John N
AU - Zmily, Osamah M
AU - Jillala, Ritvik
AU - Vattipally, Vikas
AU - Kopala, David
AU - Barough, Siavash S
AU - Amini, Mohammad Hossein
AU - Maltz, Jonathan
AU - Chavez, Francisco
AU - Morrison, Kyle
AU - Roy, Laura
AU - Suk, Ian
AU - Lee, Ryan P
AU - Tyler, Betty
AU - Luciano, Mark
AU - Thakor, Nitish V
AU - Doloff, Joshua C
AU - Theodore, Nicholas
AU - Manbachi, Amir
TI - Ultrasound neural interface enabling acute spinal cord monitoring and blood flow modulation
T2 - Science advances
J2 - Sci Adv
PY - 2026
DA - 2026/11/06
VL - 12
IS - 45
SP - eaeg2342
SN - 2375-2548
PB - American Association for the Advancement of Science
LA - en
ER -

CSL-JSON

{
"id": "pmcid:PMC13733905",
"type": "article-journal",
"title": "Ultrasound neural interface enabling acute spinal cord monitoring and blood flow modulation",
"container-title": "Science advances",
"author": [
{
"family": "Kerensky",
"given": "Max J"
},
{
"family": "Krishnan",
"given": "Siddharth"
},
{
"family": "Liang",
"given": "Ruixing"
},
{
"family": "Kempski Leadingham",
"given": "Kelley M"
},
{
"family": "Quiroz",
"given": "Victor M"
},
{
"family": "Punnoose",
"given": "Joshua"
},
{
"family": "Smit",
"given": "Constantin"
},
{
"family": "Routkevitch",
"given": "Denis"
},
{
"family": "Kumar",
"given": "Avisha"
},
{
"family": "Davidar",
"given": "A Daniel"
},
{
"family": "Steger",
"given": "Leonard"
},
{
"family": "Weber-Levine",
"given": "Carly"
},
{
"family": "Jiang",
"given": "Kelly"
},
{
"family": "Bhimreddy",
"given": "Meghana"
},
{
"family": "Bauer",
"given": "Stuart J"
},
{
"family": "Lopez",
"given": "Angelica F"
},
{
"family": "Kramer",
"given": "Patrick"
},
{
"family": "Robinson",
"given": "Kayla"
},
{
"family": "Menta",
"given": "Arjun K"
},
{
"family": "Ghaith",
"given": "Abdul Karim"
},
{
"family": "Hersh",
"given": "Andrew M"
},
{
"family": "Abramson",
"given": "Haley G"
},
{
"family": "Mohammadabadi",
"given": "Ali"
},
{
"family": "Theodore",
"given": "John N"
},
{
"family": "Zmily",
"given": "Osamah M"
},
{
"family": "Jillala",
"given": "Ritvik"
},
{
"family": "Vattipally",
"given": "Vikas"
},
{
"family": "Kopala",
"given": "David"
},
{
"family": "Barough",
"given": "Siavash S"
},
{
"family": "Amini",
"given": "Mohammad Hossein"
},
{
"family": "Maltz",
"given": "Jonathan"
},
{
"family": "Chavez",
"given": "Francisco"
},
{
"family": "Morrison",
"given": "Kyle"
},
{
"family": "Roy",
"given": "Laura"
},
{
"family": "Suk",
"given": "Ian"
},
{
"family": "Lee",
"given": "Ryan P"
},
{
"family": "Tyler",
"given": "Betty"
},
{
"family": "Luciano",
"given": "Mark"
},
{
"family": "Thakor",
"given": "Nitish V"
},
{
"family": "Doloff",
"given": "Joshua C"
},
{
"family": "Theodore",
"given": "Nicholas"
},
{
"family": "Manbachi",
"given": "Amir"
}
],
"container-title-short": "Sci Adv",
"volume": "12",
"issue": "45",
"page": "eaeg2342",
"PMCID": "PMC13733905",
"ISSN": "2375-2548",
"publisher": "American Association for the Advancement of Science",
"language": "en",
"issued": {
"date-parts": [
[
2026,
11,
6
]
]
}
}

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.1038/s41598-025-25330-8 [code]
Spinal cord neuromodulation for blood pressure control using low-intensity focused ultrasound.
Journal: Scientific reports
In common: other, 8 references
[2] doi:10.1038/s41467-023-36643-5 [code]
Sleep cycle-dependent vascular dynamics in male mice and the predicted effects on perivascular cerebrospinal fluid flow and solute transport.
Journal: Nature communications
In common: Wavelet Toolbox, statannotations, Signal Processing Toolbox, 8 other tools
[3] doi:10.1016/j.crmeth.2026.101371 [code]
Electrophysiological development and functional plasticity in dissociated human cerebral organoids across multiple cell lines.
Journal: Cell reports methods
In common: Wavelet Toolbox, statsmodels, Signal Processing Toolbox, 8 other tools
[4] doi:10.64898/2025.12.17.694950 [code]
Mecp2 deficiency impairs microscale cortical network topology and dynamics in a Rett syndrome mouse model
Journal: bioRxiv (preprint)
In common: Wavelet Toolbox, statsmodels, Signal Processing Toolbox, 8 other tools
[5] doi:10.1038/s41586-025-08969-1 [code]
Striatum supports fast learning but not memory recall.
Journal: Nature
In common: Wavelet Toolbox, statsmodels, Signal Processing Toolbox, 8 other tools
[6] doi:10.1016/j.crmeth.2024.100901 [code]
MEA-NAP: A flexible network analysis pipeline for neuronal 2D and 3D organoid multielectrode recordings.
Journal: Cell reports methods
In common: Wavelet Toolbox, statsmodels, Signal Processing Toolbox, 8 other tools
[7] doi:10.1038/s41597-023-02214-y [code]
Responses of pyramidal cell somata and apical dendrites in mouse visual cortex over multiple days.
Journal: Scientific data
In common: Wavelet Toolbox, statsmodels, Signal Processing Toolbox, 8 other tools
[8] doi:10.1038/s41598-022-23902-6 [code]
Unsupervised EEG preictal interval identification in patients with drug-resistant epilepsy.
Journal: Scientific reports
In common: Wavelet Toolbox, Plotly, Signal Processing Toolbox, 7 other tools, clinical / translational
[9] doi:10.1038/s41467-025-66562-6 [code]
Spatiotemporal patterns differentiate hippocampal sharp-wave ripples from interictal epileptiform discharges in mice and humans.
Journal: Nature communications
In common: Wavelet Toolbox, Plotly, Signal Processing Toolbox, 7 other tools
[10] doi:10.1016/j.neuron.2023.01.017 [code]
Brief synaptic inhibition persistently interrupts firing of fast-spiking interneurons.
Journal: Neuron
In common: Wavelet Toolbox, Plotly, Signal Processing Toolbox, 7 other tools

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.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/repo/zenodo:22908234.svg)](https://openscicode.org/badge/repo/zenodo:22908234)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/repo/zenodo:22908234.svg
   :target: https://openscicode.org/badge/repo/zenodo:22908234
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/repo/zenodo:22908234"><img src="https://openscicode.org/badge/repo/zenodo:22908234.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge 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: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

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