OSCR

Differential Effects of Balanced and Imbalanced Binocular Stimulation on Visual Cortex Responses in Amblyopic Children.

Code ↔ Paper

9 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 9 matches
  1. [1] § Materials and Methods › MRI Sequence ↔ mripy/dicom.py, lines 80–155 · score 0.96 · phase encoding direction, gradient recalled, echo planar, GE EPI, distortion correction, FOV
  2. [2] § Materials and Methods › MRI Sequence ↔ mripy/dicom_report.py, lines 23–80 · score 0.79 · distortion correction, MPRAGE, TE, FA, FOV, Siemens
  3. [3] § Materials and Methods › fMRI Data Analysis › Preprocessing ↔ mripy/preprocess.py, lines 1888–2011 · score 0.70 · rigid body, AFNI, lpc, preprocessed, EPI, transformations
  4. [4] § Materials and Methods › Visual Stimuli for Cortical Activation ↔ stimuli/gratingStimulus.m, lines 1–121 · score 0.63 · square wave, temporal frequency, sinusoidally, modulated, deg, SF
  5. [5] § Materials and Methods › Visual Stimuli for Cortical Activation ↔ stimuli/colourGratingStimulus.m, lines 1–133 · score 0.61 · square wave, temporal frequency, sinusoidally, deg, SF, angle
  6. [6] § Materials and Methods › Apparatus ↔ calibration/calibrateLuminance.m, lines 1–81 · score 0.56 · SpectroCal, instructed, monitored, Linux, luminance, asked
  7. [7] § Materials and Methods › Apparatus ↔ calibration/calibrateLuminanceNew.m, lines 1–81 · score 0.56 · SpectroCal, instructed, monitored, Linux, luminance, asked
  8. [8] § Materials and Methods › Retinotopic Mapping ↔ stimuli/colourGratingStimulus.m, lines 1–133 · score 0.56 · square wave, phase reversed, ratio, background, setup
  9. [9] § Materials and Methods › Retinotopic Mapping ↔ stimuli/polarGratingStimulus.m, lines 1–144 · score 0.56 · square wave, phase reversed, ratio, background, setup

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

MATLAB · 605 lines · 21 KB · LGPL-3.0 · 2 matches

  1. % ========================================================================
  2. %> @brief colour grating stimulus, inherits from baseStimulus
  3. %> COLOURGRATINGSTIMULUS colour grating stimulus, inherits from baseStimulus
  4. %> The basic properties are:
  5. %> type = 'sinusoid' or 'square', if square you should set sigma which
  6. %> smoothes the interface and stops pixel motion artifacts that normally
  7. %> inflict square wave gratings, set sigma to 0 to remove smoothing.
  8. %> colour = first grating colour
  9. %> colour2 = second grating colour
  10. %> baseColour = the midpoint between the two from where contrast works,
  11. %> defult just inherits the background colour from screenManager
  12. %> correctBaseColour = automatically generate baseColour as the average
  13. %> of colour and colour2
  14. %> contrast = contrast from 0 - 1
  15. %> sf = spatial frequency in degrees
  16. %> tf = temporal frequency in degs/s
  17. %> angle = angle in degrees
  18. %> rotateTexture = do we rotate the grating texture (true) or the patch itself (false)
  19. %> phase = phase of grating
  20. %> mask = use circular mask (true) or not (false)
  21. %>
  22. %> See docs for more property details.
  23. %>
  24. %> @todo phase appears different to gratingStimulus, work out why
  25. %>
  26. %> Copyright ©2014-2022 Ian Max Andolina — released: LGPL3, see LICENCE.md
  27. % ========================================================================
  28. classdef colourGratingStimulus < baseStimulus
  29. properties %--------------------PUBLIC PROPERTIES----------%
  30. %> family type, can be 'sinusoid' or 'square'
  31. type char = 'sinusoid'
  32. %> spatial frequency of the grating
  33. sf(1,1) double = 1
  34. %> temporal frequency of the grating
  35. tf(1,1) double = 1
  36. %> second colour of a colour grating stimulus
  37. colour2(1,:) double = [0 1 0 1]
  38. %> base colour from which colour and colour2 are blended via contrast value
  39. %> if empty [default], uses the background colour from screenManager
  40. baseColour(1,:) double = []
  41. %> rotate the grating patch (false) or the grating texture within the patch (default = true)?
  42. rotateTexture logical = true
  43. %> phase of grating
  44. phase(1,1) double = 0
  45. %> contrast of grating (technically the contrast from the baseColour)
  46. contrast(1,1) double = 0.5
  47. %> use a circular mask for the grating (default = true).
  48. mask logical = true
  49. %> direction of the drift; default = false means drift left>right when angle is 0deg.
  50. %This switch can be accomplished simply setting angle, but this control enables
  51. %simple reverse direction protocols.
  52. reverseDirection logical = false
  53. %> the direction of the grating object if moving.
  54. direction double = 0
  55. %> Do we need to correct the phase to be relative to center not edge? This enables
  56. %> centre surround stimuli are phase matched, and if we enlarge a grating object its
  57. %> phase stays identical at the centre of the object (where we would imagine our RF)
  58. correctPhase logical = false
  59. %> In certain cases the base colour should be calculated
  60. %> dynamically from colour and colour2, and this enables this to
  61. %> occur blend
  62. correctBaseColour logical = false
  63. %> Reverse phase of grating X times per second? Useful with a static grating for linearity testing
  64. phaseReverseTime(1,1) double = 0
  65. %> What phase to use for reverse?
  66. phaseOfReverse(1,1) double = 180
  67. %> sigma of square wave smoothing, use -1 for sinusoidal gratings
  68. sigma(1,1) double = -1
  69. %> aspect ratio of the grating
  70. aspectRatio(1,1) double = 1;
  71. %> turn stimulus on/off at X hz, [] diables this
  72. visibleRate = []
  73. end
  74. properties (SetAccess = protected, GetAccess = public)
  75. %stimulus family
  76. family char = 'grating'
  77. %> scale is used when changing size as an independent variable to keep sf accurate
  78. scale double = 1
  79. %> the phase amount we need to add for each frame of animation
  80. phaseIncrement double = 0
  81. end
  82. properties (Constant)
  83. typeList cell = {'sinusoid';'square'}
  84. end
  85. properties (SetAccess = protected, GetAccess = {?baseStimulus})
  86. %> properties to not show in the UI panel
  87. ignorePropertiesUI = 'alpha';
  88. end
  89. properties (SetAccess = protected, GetAccess = protected)
  90. %> as get methods are slow, we cache sf, then recalculate sf whenever
  91. %> changeScale event is called
  92. sfCache = []
  93. %>to stop a loop between set method and an event
  94. sfRecurse = false
  95. %> allowed properties passed to object upon construction
  96. allowedProperties = {'type','colour2', 'sf', 'tf', 'angle', 'direction', 'phase', 'rotateTexture', ...
  97. 'contrast', 'mask', 'reverseDirection', 'speed', 'startPosition', 'aspectRatio', ...
  98. 'sigma', 'correctPhase', 'phaseReverseTime', 'phaseOfReverse','visibleRate',...
  99. 'correctBaseColour'}
  100. %> properties to not create transient copies of during setup phase
  101. ignoreProperties = {'type', 'scale', 'phaseIncrement', 'correctPhase', 'contrastMult', 'mask', 'typeList'}
  102. %> how many frames between phase reverses
  103. phaseCounter = 0
  104. %> mask value (radius for the procedural shader)
  105. maskValue
  106. %> the raw shader, we can try to change colours.
  107. shader
  108. %> these store the current colour so we can check if update needs
  109. %to regenerate the shader
  110. colourCache
  111. colour2Cache
  112. visibleTick = 0
  113. visibleFlip = Inf
  114. end
  115. %=======================================================================
  116. methods %------------------PUBLIC METHODS
  117. %=======================================================================
  118. % ===================================================================
  119. %> @brief Class constructor
  120. %>
  121. %> More detailed description of what the constructor does.
  122. %>
  123. %> @param args are passed as a structure of properties which is
  124. %> parsed.
  125. %> @return instance of class.
  126. % ===================================================================
  127. function me = colourGratingStimulus(varargin)
  128. args = optickaCore.addDefaults(varargin,...
  129. struct('name','colour-grating','colour',[1 0 0 1],'colour2',[0 1 0 1]));
  130. me=me@baseStimulus(args); %we call the superclass constructor first
  131. me.parseArgs(args, me.allowedProperties);
  132. me.isRect = true; %uses a rect for drawing
  133. me.ignoreProperties = [me.ignorePropertiesBase me.ignoreProperties];
  134. me.salutation('constructor method','Stimulus initialisation complete');
  135. end
  136. % ===================================================================
  137. %> @brief Setup this object in preparation for use
  138. %> When displaying a stimulus object, the main properties that are to be
  139. %> modified are copied into cache copies of the property, both to convert from
  140. %> visual description (c/d, Hz, degrees) to
  141. %> computer metrics, and to be animated and modified as independant
  142. %> variables. So xPosition is copied to xPositionOut and converted from
  143. %> degrees to pixels. The animation and drawing functions use these modified
  144. %> properties, and when they are updated, for example to change to a new
  145. %> xPosition, internal methods ensure reconversion and update any dependent
  146. %> properties. This method initialises the object with all the cache properties
  147. %> for display.
  148. %>
  149. %> @param sM screenManager object to use
  150. % ===================================================================
  151. function setup(me,sM)
  152. reset(me); %reset object back to its initial state
  153. me.inSetup = true; me.isSetup = false;
  154. if isempty(me.isVisible); show(me); end
  155. me.sM = sM;
  156. if ~sM.isOpen; error('Screen needs to be Open!'); end
  157. me.ppd=sM.ppd;
  158. me.screenVals = sM.screenVals;
  159. me.texture = []; %we need to reset this
  160. fn = sort(properties(me));
  161. for j=1:length(fn)
  162. if ~matches(fn{j}, me.ignoreProperties)
  163. p=me.addprop([fn{j} 'Out']);
  164. if strcmp(fn{j}, 'sf'); p.SetMethod = @set_sfOut; end
  165. if strcmp(fn{j}, 'tf')
  166. p.SetMethod = @set_tfOut; p.SetObservable = true;
  167. addlistener(me, [fn{j} 'Out'], 'PostSet', @me.calculatePhaseIncrement);
  168. end
  169. if strcmp(fn{j}, 'reverseDirection')
  170. p.SetMethod = @set_reverseDirectionOut; p.SetObservable = true;
  171. addlistener(me, [fn{j} 'Out'], 'PostSet', @me.calculatePhaseIncrement);
  172. end
  173. if strcmp(fn{j}, 'size')
  174. p.SetMethod = @set_sizeOut; p.SetObservable = true;
  175. addlistener(me, [fn{j} 'Out'], 'PostSet', @me.calculateScale);
  176. end
  177. if strcmp(fn{j}, 'xPosition'); p.SetMethod = @set_xPositionOut; end
  178. if strcmp(fn{j}, 'yPosition'); p.SetMethod = @set_yPositionOut; end
  179. if strcmp(fn{j}, 'colour')
  180. p.SetMethod = @set_cOut; p.SetObservable = true;
  181. addlistener(me, [fn{j} 'Out'], 'PostSet', @me.fixBaseColour);
  182. end
  183. if strcmp(fn{j}, 'colour2')
  184. p.SetMethod = @set_c2Out; p.SetObservable = true;
  185. addlistener(me, [fn{j} 'Out'], 'PostSet', @me.fixBaseColour);
  186. end
  187. me.([fn{j} 'Out']) = me.(fn{j}); %copy our property value to our temporary copy
  188. end
  189. end
  190. addRuntimeProperties(me);
  191. if ~isprop(me,'rotateMode'); addprop(me,'rotateMode'); end
  192. if me.rotateTexture
  193. me.rotateMode = kPsychUseTextureMatrixForRotation;
  194. else
  195. me.rotateMode = [];
  196. end
  197. if ~isprop(me,'gratingSize'); addprop(me,'gratingSize'); end
  198. me.gratingSize = round(me.ppd*me.size); %virtual support larger than initial size
  199. if ~isprop(me,'driftPhase'); addprop(me,'driftPhase'); end
  200. if me.correctPhase
  201. ps = me.calculatePhase;
  202. me.driftPhase = me.phaseOut-ps;
  203. else
  204. me.driftPhase = me.phaseOut;
  205. end
  206. if ~isprop(me,'res'); addprop(me,'res'); end
  207. switch length(me.aspectRatio)
  208. case 1
  209. me.res = round([me.gratingSize*me.aspectRatio me.gratingSize]);
  210. case 2
  211. me.res = round([me.gratingSize*me.aspectRatio(1) me.gratingSize*me.aspectRatio(2)]);
  212. end
  213. if max(me.res) > me.sM.screenVals.width %scale to be no larger than screen width
  214. me.res = floor( me.res / (max(me.res) / me.sM.screenVals.width));
  215. end
  216. if me.mask == true
  217. me.maskValue = floor((me.ppd*me.size))/2;
  218. else
  219. me.maskValue = [];
  220. end
  221. if me.phaseReverseTime > 0
  222. me.phaseCounter = round(me.phaseReverseTime / me.sM.screenVals.ifi);
  223. end
  224. if isempty(me.baseColour)
  225. if me.correctBaseColour
  226. me.baseColourOut = (me.colourOut(1:3) + me.colour2Out(1:3)) / 2;
  227. me.baseColourOut(4) = me.alpha;
  228. else
  229. me.baseColourOut = me.sM.backgroundColour;
  230. me.baseColourOut(4) = me.alpha;
  231. end
  232. end
  233. if strcmpi(me.type,'square')
  234. if me.sigma < 0; me.sigma = 0.05; me.sigmaOut = me.sigma; end
  235. else
  236. me.salutation('SETUP', 'Reset sigma to -1 as type=squarewave', true)
  237. me.sigmaOut = -1; %just make sure type overrides sigma if conflict
  238. end
  239. % this is a two color grating, passing in colorA and colorB.
  240. [me.texture, ~, me.shader] = CreateProceduralColorGrating(me.sM.win, me.res(1),...
  241. me.res(2), me.colourOut, me.colour2Out, me.maskValue);
  242. me.colourCache = me.colourOut; me.colour2Cache = me.colour2Out;
  243. if ~isempty(me.visibleRateOut) && isnumeric(me.visibleRateOut)
  244. me.visibleTick = 0;
  245. me.visibleFlip = round((me.screenVals.fps/2) / me.visibleRateOut);
  246. else
  247. me.visibleFlip = Inf; me.visibleTick = 0;
  248. end
  249. me.inSetup = false; me.isSetup = true;
  250. computePosition(me);
  251. setRect(me);
  252. function set_cOut(me, value)
  253. len=length(value);
  254. switch len
  255. case {4,3}
  256. c = [value(1:3) me.alpha]; %force our alpha to override
  257. case 1
  258. c = [value value value me.alpha]; %construct RGBA
  259. otherwise
  260. c = [1 1 1 me.alpha]; %return white for everything else
  261. end
  262. c(c<0)=0; c(c>1)=1;
  263. me.colourOut = c;
  264. end
  265. function set_c2Out(me, value) %#ok<*MCSGP>
  266. len=length(value);
  267. switch len
  268. case {4,3}
  269. c = [value(1:3) me.alpha]; %force our alpha to override
  270. case 1
  271. c = [value value value me.alpha]; %construct RGBA
  272. otherwise
  273. c = [1 1 1 me.alpha]; %return white for everything else
  274. end
  275. c(c<0)=0; c(c>1)=1;
  276. me.colour2Out = c;
  277. end
  278. function set_sfOut(me,value)
  279. if me.sfRecurse == false
  280. me.sfCache = (value / me.ppd);
  281. me.sfOut = me.sfCache * me.scale;
  282. else
  283. me.sfOut = value;
  284. me.sfRecurse = false;
  285. end
  286. %fprintf('\nSET SFOut: %d | cache: %d | in: %d\n', me.sfOut, me.sfCache, value);
  287. end
  288. function set_tfOut(me,value)
  289. me.tfOut = value;
  290. end
  291. function set_reverseDirectionOut(me,value)
  292. me.reverseDirectionOut = value;
  293. end
  294. function set_sizeOut(me,value)
  295. me.sizeOut = value*me.ppd;
  296. me.szPx = me.sizeOut;
  297. end
  298. function set_xPositionOut(me, value)
  299. me.xPositionOut = value * me.ppd;
  300. end
  301. function set_yPositionOut(me,value)
  302. me.yPositionOut = value*me.ppd;
  303. end
  304. end
  305. % ===================================================================
  306. %> @brief Update this stimulus object for display
  307. %>
  308. % ===================================================================
  309. function update(me)
  310. resetTicks(me);
  311. if me.correctPhase
  312. ps=me.calculatePhase;
  313. me.driftPhase=me.phaseOut-ps;
  314. else
  315. me.driftPhase=me.phaseOut;
  316. end
  317. if ~all(me.colourCache(1:3) == me.colourOut(1:3)) || ...
  318. ~all(me.colour2Cache(1:3) == me.colour2Out(1:3))
  319. glUseProgram(me.shader);
  320. glUniform4f(glGetUniformLocation(me.shader, 'color1'),...
  321. me.colourOut(1),me.colourOut(2),me.colourOut(3),me.alphaOut);
  322. glUniform4f(glGetUniformLocation(me.shader, 'color2'),...
  323. me.colour2Out(1),me.colour2Out(2),me.colour2Out(3),me.alphaOut);
  324. if me.mask == true
  325. me.maskValue = me.sizeOut/2;
  326. else
  327. me.maskValue = 0;
  328. end
  329. glUniform1f(glGetUniformLocation(me.shader, 'radius'), me.maskValue);
  330. glUseProgram(0);
  331. me.colourCache = me.colourOut; me.colour2Cache = me.colour2Out;
  332. end
  333. if ~isempty(me.visibleRateOut) && isnumeric(me.visibleRateOut)
  334. me.isVisible = true;
  335. me.visibleTick = 0;
  336. me.visibleFlip = round((me.screenVals.fps/2) / me.visibleRateOut);
  337. else
  338. me.visibleFlip = Inf; me.visibleTick = 0;
  339. end
  340. computePosition(me);
  341. setRect(me);
  342. end
  343. % ===================================================================
  344. %> @brief Draw this stimulus object for display
  345. %>
  346. %>
  347. % ===================================================================
  348. function draw(me)
  349. if me.isVisible && me.tick >= me.delayTicks && me.tick < me.offTicks
  350. Screen('DrawTexture', me.sM.win, me.texture, [], me.mvRect,...
  351. me.angleOut, [], [], me.baseColourOut, [], me.rotateMode,...
  352. [me.driftPhase, me.sfOut, me.contrastOut, me.sigmaOut]);
  353. me.drawTick = me.drawTick + 1;
  354. end
  355. if me.isVisible; me.tick = me.tick + 1; end
  356. end
  357. % ===================================================================
  358. %> @brief Animate this object for runExperiment
  359. %>
  360. % ===================================================================
  361. function animate(me)
  362. if (me.isVisible || ~isempty(me.visibleRate)) && me.tick >= me.delayTicks
  363. if me.mouseOverride
  364. getMousePosition(me);
  365. if me.mouseValid
  366. me.mvRect = CenterRectOnPointd(me.mvRect, me.mouseX, me.mouseY);
  367. end
  368. end
  369. if me.doMotion
  370. me.mvRect=OffsetRect(me.mvRect,me.dX_,me.dY_);
  371. end
  372. if me.doDrift
  373. me.driftPhase = me.driftPhase + me.phaseIncrement;
  374. end
  375. if mod(me.tick,me.phaseCounter) == 0
  376. me.driftPhase = me.driftPhase + me.phaseOfReverse;
  377. end
  378. me.visibleTick = me.visibleTick + 1;
  379. if me.visibleTick == me.visibleFlip
  380. me.isVisible = ~me.isVisible;
  381. me.visibleTick = 0;
  382. end
  383. end
  384. end
  385. % ===================================================================
  386. %> @brief Reset an structure for runExperiment
  387. %>
  388. %> @param rE runExperiment object for reference
  389. %> @return stimulus structure.
  390. % ===================================================================
  391. function reset(me)
  392. resetTicks(me);
  393. me.inSetup = false; me.isSetup = false;
  394. if ~isempty(me.texture) && Screen(me.texture,'WindowKind') == -1
  395. try Screen('Close',me.texture); end %#ok<*TRYNC>
  396. end
  397. me.visibleFlip = Inf; me.visibleTick = 0;
  398. me.texture=[];
  399. me.shader=[];
  400. if me.mask > 0
  401. me.mask = true;
  402. end
  403. me.maskValue = [];
  404. me.removeTmpProperties;
  405. list = {'res','gratingSize','driftPhase','rotateMode'};
  406. for l = list; if isprop(me,l{1});delete(me.findprop(l{1}));end;end
  407. end
  408. % ===================================================================
  409. %> @brief calculate phase offset
  410. %>
  411. % ===================================================================
  412. function phase = calculatePhase(me)
  413. phase = 0;
  414. if me.correctPhase > 0
  415. ppd = me.ppd;
  416. size = (me.sizeOut / 2); %divide by 2 to get the 0 point
  417. sfTmp = (me.sfOut / me.scale) * ppd;
  418. md = size / (ppd / sfTmp);
  419. md = md - floor(md);
  420. % note for some reason colourgratings are 180° different to
  421. % gratings, so we compensate here so they should align if
  422. % correctPhase is true
  423. phase = (360 * md) + 180;
  424. end
  425. end
  426. % ===================================================================
  427. %> @brief sf Set method
  428. %>
  429. % ===================================================================
  430. function set.sf(me,value)
  431. if value <= 0
  432. value = 0.05;
  433. end
  434. me.sf = value;
  435. me.salutation(['set sf: ' num2str(value)],'Custom set method')
  436. end
  437. % ===================================================================
  438. %> @brief SET Colour2 method
  439. %> Allow 1 (R=G=B) 3 (RGB) or 4 (RGBA) value colour
  440. % ===================================================================
  441. function set.colour2(me,value)
  442. len=length(value);
  443. switch len
  444. case 4
  445. c = value;
  446. case 3
  447. c = [value(1:3) me.alpha]; %force our alpha to override
  448. case 1
  449. c = [value value value me.alpha]; %construct RGBA
  450. otherwise
  451. c = [1 1 1 me.alpha]; %return white for everything else
  452. end
  453. c(c<0)=0; c(c>1)=1;
  454. me.colour2 = c;
  455. if isprop(me, 'baseColour') && me.correctBaseColour %#ok<*MCSUP>
  456. me.baseColour = (me.colour(1:3) + me.colour2(1:3))/2;
  457. end
  458. end
  459. % ===================================================================
  460. %> @brief SET baseColour method
  461. %> Allow 1 (R=G=B) 3 (RGB) or 4 (RGBA) value colour
  462. % ===================================================================
  463. function set.baseColour(me,value)
  464. len=length(value);
  465. switch len
  466. case 4
  467. c = value;
  468. case 3
  469. c = [value(1:3) me.alpha]; %force our alpha to override
  470. case 1
  471. c = [value value value me.alpha]; %construct RGBA
  472. otherwise
  473. c = [1 1 1 me.alpha]; %return white for everything else
  474. end
  475. c(c<0)=0; c(c>1)=1;
  476. me.baseColour = c;
  477. end
  478. % ===================================================================
  479. %> @brief sfOut Pseudo Get method
  480. %>
  481. % ===================================================================
  482. function sf = getsfOut(me)
  483. sf = 0;
  484. if ~isempty(me.sfCache)
  485. sf = me.sfCache * me.ppd;
  486. end
  487. end
  488. end %---END PUBLIC METHODS---%
  489. %=======================================================================
  490. methods ( Access = protected ) %-------PROTECTED METHODS-----%
  491. %=======================================================================
  492. % ===================================================================
  493. %> @brief setRect
  494. %> setRect makes the PsychRect based on the texture and screen values
  495. %> this is modified over parent method as gratings have slightly different
  496. %> requirements.
  497. % ===================================================================
  498. function setRect(me)
  499. %me.dstRect=Screen('Rect',me.texture);
  500. me.dstRect=ScaleRect([0 0 me.res(1) me.res(2)],me.scale,me.scale);
  501. if me.mouseOverride && me.mouseValid
  502. me.dstRect = CenterRectOnPointd(me.dstRect, me.mouseX, me.mouseY);
  503. else
  504. if isprop(me, 'directionOut')
  505. [sx, sy]=pol2cart(me.d2r(me.directionOut),me.startPosition);
  506. else
  507. [sx, sy]=pol2cart(me.d2r(me.direction),me.startPosition);
  508. end
  509. me.dstRect=CenterRectOnPointd(me.dstRect,me.sM.xCenter,me.sM.yCenter);
  510. if isprop(me, 'xPositionOut')
  511. me.dstRect=OffsetRect(me.dstRect,me.xPositionOut+(sx*me.ppd),me.yPositionOut+(sy*me.ppd));
  512. else
  513. me.dstRect=OffsetRect(me.dstRect,(me.xPosition)*me.ppd,(me.yPosition)*me.ppd);
  514. end
  515. end
  516. me.mvRect=me.dstRect;
  517. me.szPx = RectWidth(me.dstRect);
  518. setAnimationDelta(me);
  519. end
  520. % ===================================================================
  521. %> @brief calculateScale
  522. %> Use an event to recalculate scale as get method is slower (called
  523. %> many more times), than an event which is only called on update
  524. % ===================================================================
  525. function calculateScale(me,~,~)
  526. me.scale = me.sizeOut/(me.size*me.ppd);
  527. me.maskValue = me.sizeOut / 2;
  528. me.sfRecurse = true;
  529. me.sfOut = me.sfCache * me.scale;
  530. %fprintf('\nCalculate SFOut: %d | in: %d | scale: %d\n', me.sfOut, me.sfCache, me.scale);
  531. end
  532. % ===================================================================
  533. %> @brief calculatePhaseIncrement
  534. %> Use an event to recalculate as get method is slower (called
  535. %> many more times), than an event which is only called on update
  536. % ===================================================================
  537. function calculatePhaseIncrement(me,~,~)
  538. if isprop(me,'tfOut')
  539. me.phaseIncrement = (me.tfOut * 360) * me.sM.screenVals.ifi;
  540. if isprop(me,'reverseDirectionOut')
  541. if me.reverseDirectionOut == false
  542. me.phaseIncrement = -me.phaseIncrement;
  543. end
  544. end
  545. end
  546. end
  547. % ===================================================================
  548. %> @brief fixBaseColour POST SET
  549. %>
  550. % ===================================================================
  551. function fixBaseColour(me,varargin)
  552. if me.correctBaseColour %#ok<*MCSUP>
  553. if isprop(me, 'baseColourOut')
  554. me.baseColourOut = (me.getP('colour',[1:3]) + me.getP('colour2',[1:3])) / 2;
  555. else
  556. me.baseColour = (me.getP('colour',[1:3]) + me.getP('colour2',[1:3])) / 2;
  557. end
  558. end
  559. end
  560. end
  561. end

colourGratingStimulus.m at commit dd582c8, under LGPL-3.0 · at the source

Overview

Authors: Yuanyang Huang1, Shu Wang1, Yazhu Qian2, Linghan Kong3, Peijun Zhao3, Yan Liu4, Shahab Aldin Zarei5, Peng Zhang2, Ian Max Andolina5, Hong Liu1,6
  1. Department of Ophthalmology, Shanghai Children’s Medical Center, School of Medicine, Shanghai Jiao Tong University, Shanghai, People’s Republic of China
  2. State Key Laboratory of Brain and Cognitive Science, Institute of Biophysics, Chinese Academy of Sciences, Beijing, People’s Republic of China
  3. School of Biomedical Engineering, Shanghai Jiao Tong University, Shanghai, 200030, People’s Republic of China
  4. Department of Ophthalmology and Visual Science, Eye and ENT Hospital, Shanghai Medical College, Fudan University, Shanghai, People’s Republic of China
  5. Center for Excellence in Brain Science and Intelligence Technology, State Key Laboratory of Brain Cognition and Brain-inspired Intelligence Technology, Institute of Neuroscience, Chinese Academy of Sciences, Shanghai, People’s Republic of China
  6. College of Clinical Medicine for Obstetrics and Gynecology and Pediatrics, Fujian Medical University, Fuzhou, Fujian, People’s Republic of China
Journal: Clinical ophthalmology (Auckland, N.Z.), volume 20, article 590186
Dates: received 19 December 2025; accepted 5 April 2026; published online 23 April 2026
Type: Research article · Language: English
License: CC BY-NC
Identifiers: DOI 10.2147/opth.s590186 · PMID 42052216 · PMCID PMC13117856 · OpenAlex W7155367740
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: fMRI (modality), human (organism), other condition (population)
Methods: Statistics, Connectivity, fMRI & imaging
Keywords: anisometropic amblyopia, fMRI, dichoptic, pediatric
Topic: Visual perception and processing mechanisms (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: Natural Science Foundation of Shanghai (23ZR1459200); National Natural Science Foundation of China (32070 992, 81770957)
Citations: not cited yet (Europe PMC); 86 references in the paper

Abstract

Purpose: To investigate the changes in neural activity in V1, V2, and V3 visual cortical areas of control participants and amblyopic patients during visual stimulation under four differing visual inputs.

Patients and Methods: A total of 14 children with monocular amblyopia and 11 age-matched healthy controls were recruited for the study. A fast meridional retinotopic mapping paradigm was employed to efficiently localize regions of interest (ROIs) within the visual cortex. Four types of visual stimulation were achieved using a spatiotemporally modulating checkerboard paired with anaglyph red-blue glasses: amblyopic or non-dominant eye only (AE), fellow or dominant eye only (FE), balanced dichoptic (BE), and imbalanced-dichoptic stimulation (DE).

Results: Amblyopic patients exhibit significantly reduced neural activity across V1, V2, and V3 compared to control participants. DE resulted in the most significant reductions in cortical responses for amblyopes. In the control group, significant differences were observed between AE and BE, FE and BE, and BE and DE, while no significant differences were found between AE and DE. In the amblyopic group, significant differences were identified between AE and DE, FE and DE, AE and BE, FE and BE, as well as between BE and DE.

Conclusion: Imbalanced dichoptic stimulation produced the largest and most significant reductions in cortical responses, observed exclusively in the patient group, indicating a suppressive influence from the fellow eye. These exploratory data support the view that imbalanced dichoptic stimulation may offer greater potential for neural response recovery compared to monocular approaches. The experimental protocols and findings reported here provide a comparative framework to inform the development of more effective rehabilitation strategies for children with amblyopia.

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

Repositories

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

CogPlatform/binocularMRI

License: MIT
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Commit: 3e1faabdf18ee50cf6eaeac658aa77dba468e387, 8 May 2026
Languages: MATLAB (1)
Size: 5 files, 1 script
Software Heritage: not archived
Found in: the text, “Visual Stimuli for Cortical Activation”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Psychtoolbox (1 file)
Availability: 1 check, the latest on 29 September 2026: the link answers
  • 29 September 2026: the link answers
3 files

herrlich10/mripy

License: MIT
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Commit: db1324a1a712c1948cc10ea3c629e74e7d2ea430, 17 April 2025
Languages: Python (48), MATLAB (19), Shell (1)
Size: 112 files, 68 scripts
Software Heritage: archived
Found in: the text, “Preprocessing”
Holds: README, license file, environment (requirements.txt, setup.py, docs/requirements.txt), tests, documentation
Not found: CITATION.cff, continuous integration
Tools: NumPy (29 files), SciPy (12 files), Matplotlib (9 files), pandas (8 files), AFNI (4 files), Statistics and Machine Learning Toolbox (3 files), scikit-learn (3 files), seaborn (3 files), SPM (2 files), CoSMoMVPA (1 file), CuPy (1 file), FreeSurfer (1 file), NiBabel (1 file)
Availability: 1 check, the latest on 29 September 2026: the link answers
  • 29 September 2026: the link answers
70 files

Zenodo 592253

License: CC-BY-4.0
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: the references
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 29 September 2026: the link answers (HTTP 200)
  • 29 September 2026: the link answers (HTTP 200)
231 files
At the source:

iandol/opticka

License: LGPL-3.0
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Commit: dd582c8c3fd22468856fd54a836051a42478c62a, 24 August 2026
Languages: MATLAB (287), Shell (1), Perl (1)
Size: 562 files, 289 scripts
Software Heritage: archived
Found in: the Zenodo archive record
Holds: README, license file, CITATION.cff, tests, continuous integration
Not found: environment file, documentation
Availability: 1 check, the latest on 29 September 2026: the link answers
  • 29 September 2026: the link answers
291 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:

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

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

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

Recorded: type, language, journal, volume, pages, dates, 10 authors, 4 keywords, 2 funders, 81 references.

Cite

This paper

Huang, Y., Wang, S., Qian, Y., Kong, L., Zhao, P., Liu, Y., Zarei, S. A., Zhang, P., Andolina, I. M., & Liu, H. (2026). Differential Effects of Balanced and Imbalanced Binocular Stimulation on Visual Cortex Responses in Amblyopic Children. Clinical ophthalmology (Auckland, N.Z.), 20, 590186. https://doi.org/10.2147/opth.s590186

BibTeX

@article{huang2026differential,
author = {Huang, Yuanyang and Wang, Shu and Qian, Yazhu and Kong, Linghan and Zhao, Peijun and Liu, Yan and Zarei, Shahab Aldin and Zhang, Peng and Andolina, Ian Max and Liu, Hong},
title = {{Differential Effects of Balanced and Imbalanced Binocular Stimulation on Visual Cortex Responses in Amblyopic Children}},
journal = {Clinical ophthalmology (Auckland, N.Z.)},
year = {2026},
month = apr,
volume = {20},
pages = {590186},
publisher = {Dove Press},
issn = {1177-5467},
doi = {10.2147/opth.s590186},
url = {https://doi.org/10.2147/opth.s590186},
pmid = {42052216},
pmcid = {PMC13117856}
}

RIS

TY - JOUR
AU - Huang, Yuanyang
AU - Wang, Shu
AU - Qian, Yazhu
AU - Kong, Linghan
AU - Zhao, Peijun
AU - Liu, Yan
AU - Zarei, Shahab Aldin
AU - Zhang, Peng
AU - Andolina, Ian Max
AU - Liu, Hong
TI - Differential Effects of Balanced and Imbalanced Binocular Stimulation on Visual Cortex Responses in Amblyopic Children
T2 - Clinical ophthalmology (Auckland, N.Z.)
J2 - Clin Ophthalmol
PY - 2026
DA - 2026/04/23
VL - 20
SP - 590186
SN - 1177-5467
PB - Dove Press
DO - 10.2147/opth.s590186
UR - https://doi.org/10.2147/opth.s590186
LA - en
ER -

CSL-JSON

{
"id": "10.2147/opth.s590186",
"type": "article-journal",
"title": "Differential Effects of Balanced and Imbalanced Binocular Stimulation on Visual Cortex Responses in Amblyopic Children",
"container-title": "Clinical ophthalmology (Auckland, N.Z.)",
"author": [
{
"family": "Huang",
"given": "Yuanyang"
},
{
"family": "Wang",
"given": "Shu"
},
{
"family": "Qian",
"given": "Yazhu"
},
{
"family": "Kong",
"given": "Linghan"
},
{
"family": "Zhao",
"given": "Peijun"
},
{
"family": "Liu",
"given": "Yan"
},
{
"family": "Zarei",
"given": "Shahab Aldin"
},
{
"family": "Zhang",
"given": "Peng"
},
{
"family": "Andolina",
"given": "Ian Max"
},
{
"family": "Liu",
"given": "Hong"
}
],
"container-title-short": "Clin Ophthalmol",
"volume": "20",
"page": "590186",
"DOI": "10.2147/opth.s590186",
"PMID": "42052216",
"PMCID": "PMC13117856",
"ISSN": "1177-5467",
"publisher": "Dove Press",
"URL": "https://doi.org/10.2147/opth.s590186",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
23
]
]
}
}

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/s41586-026-10631-3 [code]
A prognostic human brain network for diffuse midline glioma.
Journal: Nature
In common: Psychtoolbox, Curve Fitting Toolbox, FieldTrip, 13 other tools, other condition
[2] doi:10.1038/s41467-026-71151-2 [code]
Common and distinct neural correlates of social interaction processing and theory of mind in narratives.
Journal: Nature communications
In common: Psychtoolbox, AFNI, FieldTrip, 13 other tools
[3] doi:10.1002/hbm.70602 [code]
Neuroimaging Correlates of Post-Stroke Pain After Ischemic Stroke: Secondary Analysis of the INSPiRE-TMS Trial.
Journal: Human brain mapping
In common: Psychtoolbox, Curve Fitting Toolbox, FieldTrip, 12 other tools, other condition
[4] doi:10.1111/ene.70678 [code]
Who Falls After a Stroke? Evidence From a Prospective Stroke Cohort.
Journal: European journal of neurology
In common: Psychtoolbox, Curve Fitting Toolbox, FieldTrip, 12 other tools
[5] doi:10.1016/j.celrep.2026.117404 [code]
Action and rest tremor map to distinct networks within the primary motor cortex.
Journal: Cell reports
In common: Psychtoolbox, Curve Fitting Toolbox, FieldTrip, 12 other tools
[6] doi:10.1002/ana.78206 [code]
Multimodal Image Guidance in Subthalamic Deep Brain Stimulation for Parkinson's Disease.
Journal: Annals of neurology
In common: Psychtoolbox, Curve Fitting Toolbox, FieldTrip, 12 other tools
[7] doi:10.1016/j.neuron.2026.04.011 [code]
Precision fMRI reveals densely interdigitated network patches with conserved motifs in the lateral prefrontal cortex.
Journal: Neuron
In common: AFNI, FieldTrip, Parallel Computing Toolbox, 9 other tools, fMRI, 2 references
[8] doi:10.1038/s41467-026-73668-y [code]
Convergent and divergent brain-cognition development in early adolescence.
Journal: Nature communications
In common: AFNI, FieldTrip, FreeSurfer, 11 other tools, fMRI
[9] doi:10.1002/hbm.70483 [code]
Untamed: Unconstrained Tensor Decomposition and Graph Node Embedding for Cortical Parcellation.
Journal: Human brain mapping
In common: AFNI, FieldTrip, Parallel Computing Toolbox, 10 other tools, fMRI
[10] doi:10.1038/s42003-026-10276-y [code]
The cellular correlates and adolescent reorganisation of cortical myelination networks in the common marmoset.
Journal: Communications biology
In common: AFNI, Parallel Computing Toolbox, FreeSurfer, 11 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.

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.