holoviz-topics / imagen

ImaGen: Generic Python library for 0D, 1D and 2D pattern distributions
https://imagen.holoviz.org/
BSD 3-Clause "New" or "Revised" License
31 stars 16 forks source link

Let SquareGrating be asymmetric #22

Closed JoelChavas closed 10 years ago

JoelChavas commented 10 years ago

Dear,

I am Joël Chavas from the neuroinformatics lab of Andrew Davison. I am using imagen to generate visual stimuli for illusory contours. A key point for these illusory contour stimuli is the generation of asymmetric square wave gratings.

Motivation behind the changes

A priori, you can generate an asymmetric square grating by making a Composite (operator multiply) of two shifted symmetric SquareGrating. However, if the desired duty_cycle and the pixel density are small, then we visually observe some misses (lines are cut at some points). These are misses in the sense that they are not present by making a direct discretization of the desired analytic operator. It doesn't look like a programmation bug. It is expected and is due to the multiply operator and to the discrete nature of the operands: indeed, multiplying the two pixellized version of two analytic functions doesn't give the same result as the pixellization of the product of these same two analytic functions. That's why I propose to modify directly the SquareGrating pattern generator to make it asymmetric at will.

Names of the parameter and description of the change

I propose to add the parameter duty_cycle: it describes the ratio between the pulse duration (width of the bright bar) and the period. This term is the accepted term to describe the asymmetry in a square wave or in a periodic pulse. It is bounded by [0.0,1.0]. As it has no meaning outside of this range, I have put these bounds as bounds, not softbounds. To achieve the goal, I have reduced the change to a minimum by keeping the around over a sinusoid. I shift the sinuoid on the y-direction by 0.5sin(pi(p.duty_cycle-0.5)).

Test

I test it with the following python code. I have tested it particularly for the limit values of the duty_cycle (0.0,1.0), and for different orientations. It looks fine

import matplotlib.pyplot as plt import matplotlib.cm as cm from numpy import pi

import imagen from dataviews.sheetviews.boundingregion import BoundingBox

bounds=BoundingBox(radius = 6) xdensity = 20 ydensity = 20

def plot(image): print image im = plt.imshow(image,cmap=cm.Greys, interpolation='none', aspect='auto', extent=[-6,6,-6,6]) plt.colorbar()

def asymmetric_square_grating(phase=0, orientation=0, duty_cycle=0.5): square = imagen.SquareGrating(frequency=0.2, duty_cycle=duty_cycle, orientation=orientation,phase=phase,bounds=bounds,xdensity=xdensity,ydensity=ydensity) return square()

plot(asymmetric_square_grating(orientation=pi/4,duty_cycle=0.1))

plt.show()

Last comment

I think it is useful.

thanks for releasing imagen,

best,

Joël.

jbednar commented 10 years ago

Looks great to me, thanks for contributing it! The new code all looks fine to me, but I'll have to get the main authors of DataViews to look at the importing changes; you might have caught it in an inconsistent state between a series of commits.

JoelChavas commented 10 years ago

OK, I have taken the latest imagen and made the merge (sorry for the 3 commits for just the merging part!). Do you want me to add the tests for this feature in a tests folder?

jbednar commented 10 years ago

Thanks. Please do add tests, which can be part of your second pull request. Thanks again!