A raytracer in python – part 5: non-planar samplers

In this post we are going to describe and implement non-planar samplers. In the previous post about samplers, we implemented and characterized different planar samplers to make antialiasing possible. The characteristic of these samplers was to produce regular or random points on a plane with x,y between zero and one. To implement effects such as simulation of lenses behavior, reflections and so on, we also need to be able to shoot rays according to  geometrical patterns other than the plane. More specifically, we need to be able to map points on a disk (to simulate lenses) or on a hemisphere (to simulate other optical effects such as reflections), while at the same time preserving the good characteristics of the random distributions outlined in the planar case.

To achieve this, the samplers now implement two new methods, BaseSampler.map_samples_to_disk() and BaseSampler.map_sampler_to_hemisphere(). They are in charge of remapping the planar distribution to a disk or to a hemisphere, but with a couple of twists: in the disk remap, the points in the range [0:1] must be remapped to a full circle from [-1:1] in both axes, so to cover the circle completely while preserving the distribution. This is done through a formulation called Shirley’s concentric maps.

In the hemisphere remapping, we also want to introduce a variation in the density so that it changes with the cosine of the polar angle from the top of the hemisphere. In other words, we want an adjustable parameter e to focus the point density closer to the top of the hemisphere.

We will need the characteristics of this distributions later on, when we will have to implement reflections and other optical effects. As you can see from the above plot, higher values of the parameter e produce a higher concentration of the points close to the top of the hemisphere. On the other hand, a low e parameter tend to produce a more uniform distribution over the full hemisphere.

To obtain the points, the sampler object has now three methods to request an iterator. We are no longer iterating on the object itself, because we need to provide three different iteration strategies. Methods BaseSampler.diskiter(), BaseSampler.hemisphereiter() and BaseSampler.squareiter(), each returning a generator over the proper set of points. Note that the hemisphere point generator returns 3D points, differently from the other two returning 2D points.

You can find the code for this post at github.

Sorry 2012 doomsdayers, the world is still here

Yesterday, according to the 2012 doomsdayers, was supposed to be the end of the world. Sorry, the world is still here, but don’t worry, there will be a new proposed date soon in the queue to delight once again humanity. Interestingly, unless someone proposes an earlier one, Isaac Newton’s prediction is the next one, with an estimated end of the world for 2060. I have the feeling that 2038, the year where all UNIX dates will flip back 1901, is another likely candidate. Remember Y2K ?

Considering the frequency of such announcements, we may be tempted to say that sooner or later someone is going to hit jackpot. James Randi, famous magician and debunker, uses the same approach: every morning, he puts a new business card in his pocket, with the words “I, James Randi, will die today” followed by the current date. Imagine the amazement of those who will find him dead. Reality, however, is different. In 5 billion years, our Sun will grow into a red giant and swallow our planet, an event that won’t take place in one day. It will be a progressive change, so it will be hard to assign “the day when the Sun cooked us all”.

If we limit ourselves to extinction (or really strong reduction) of the human species, this may indeed actually happen rather soon and quickly. Meteorites actually do hit the planet from time to time, and a large impact may trigger mass extinctions like it did in the past, but we don’t have to wait from problems from above. We live in an overpopulated planet, in exponential population growth, and way beyond the carrying capacity in absence of fossil fuels. I think we should focus on the real problems of humanity, instead of Mayan calendars.

Liquid crystal layer of water and charge separation at surface boundaries

Here is an extremely interesting talk by Prof. Gerald Pollack about the characteristics of water layers at the surface boundaries. He presents experimental results supporting the point that water forms a relatively thick liquid crystal layer at the boundary, establishing a separation of charge that may be exploited for energy production. Interestingly, this phenomenon is largely promoted by infrared light. The same phenomenon may be used for efficient and cost effective water purification.

A pregnancy test positive for a man may indicate testicular cancer

I recently learned some important information for men. It appears, from various sources I scouted and first learned from reddit, that a pregnancy test turning positive for a man may indicate the presence of testicular cancer. The reason is that pregnancy tests work by detecting the hormone human chorionic gonadotropin (hCG), present in urine and blood after conception. The same hormone is also present in the urine when some types of cancers are developing, therefore the presence of a positive result in men may indicate presence of these types of cancer, most often found in testicular cancer.

Now, I am not a medical doctor, but a quick search on google scholar led me to this paper, where indeed hCG is considered a viable marker for testicular cancer. Wikipedia seems to be a reliable source on this regard, and according to what I found on the web, it’s reasonable for me to say that indeed a pregnancy test can be used by a man to assess a potential testicular cancer. Like any other medical evaluation, it must however always be confirmed with additional checks.

I welcome comments or corrections on this regard.

NASA computer model of the formation of a spiral galaxy

I really love this movie (720p mode strongly suggested). It shows a computational model for the formation of a spiral galaxy, from the big bang to the present day.

Note how the galaxy shape at the beginning is rather similar to pictures of young galaxies from the Hubble Ultra Deep Field

Hubble Ultra Deep Field

and how the galaxy inverts its rotation as it collides with other galaxies.

Genetic testing for the masses (including myself): 23andme

Two years ago, I learned about 23andme.com, a company that does genetic testing for health, traits and ancestry. The idea is as follows: you send them a sample of your saliva (containing your DNA, I guess from cells in the mouth mucosa), they process it and check for specific genes. Then, they compare your genetic information with the currently known research about health (higher or lower chance of getting some diseases), ancestry (maternal and paternal) and genetic traits (color of the eyes, blood group).

It took me a while to decide and take the test: the idea of giving my DNA information to a private company, with information stored and available on the net, didn’t appeal me at all. Call me paranoid, but I can’t help it. I made some reputation checks with some trusted people I know, learned that the company has close ties with Google (a co-founder is Brin’s wife) and decided for it. The main push, however, was curiosity. In my genetic code it is written how my biological computer works, how it can break, and where it comes from. Too much to resist. After you place your order, they send you a sampling container, which is a test tube with a buffer solution in the cap.

What I found out is appealing: I learned that genetically I am a very healthy person, confirmed some hypotheses about my ancestors, and realized I have superpowers: I am immune to the most common strain of viral gastroenteritis. I left my genetic information in their database and, as long as I keep paying a small fee, they perform additional analyses on my sample for new genes. I keep receiving updates about new findings around once a month.

Do I recommend it? Yes and no. The most important point to keep into account is that, once you open the box of your genetic information, there’s no way back. What you learn may change forever how you see yourself, your past, your future and the future of your children. 23andme keeps you health information hidden to you unless unlocked manually. I didn’t even ponder a second about it, and clicked on all the “show my health information” buttons I could find. I cannot deal with not knowing, regardless how bad it can be. Knowledge may also allow to take action whenever possible, but for some conditions there’s not much to be done.

Calling a C routine from python, the easy way

I think it may be interesting for others to see how to call easily a C routine from python, without implementing a python module. What you need is the ctypes module. Remeber however that apparently the use of this module is generally frowned upon, at least according to a note I found in PEP 399:

Usage of ctypes to provide an API for a C library will continue to be frowned upon as ctypes lacks compiler guarantees that C code typically relies upon to prevent certain errors from occurring (e.g., API changes).

although to be honest, it may be in the context of the PEP itself, and not as a general recommendation.

Nevertheless, suppose you want to call the function

double pow(double, double)

in the standard math library.

The first thing to do is to define the prototype of the function. You achieve this via the following:

prototype=ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double, ctypes.c_double)

The call to ctypes.CFUNCTYPE creates a prototype object for a C function that returns a double (the first argument) and accepts two double (the second and third arguments).

Now you have a prototype. This entity is a class

>>> prototype
<class 'ctypes.CFunctionType'>

and you can bind this prototype to the actual function in the math library with the following. First you create an object representing the library

>>> dll=ctypes.cdll.LoadLibrary("libm.dylib") # on Mac. Linux use libm.so

and then you bind to the actual function

>>> pow = prototype(("pow", dll))
>>> pow(3,4)
81.0

This just brushes the surface, but I wanted to make a simple introductory post.

Copying and pasting from the python interpreter

One very powerful feature of python is the interactive interpreter: it allows you to test and quickly evaluate snippets of code. Occasionally, I need to rerun the same code, either during the same or another python interpreter session. One quick way to achieve would be to copy and paste the code again, but you quickly realize the prompt makes it hard:

>>> for i in xrange(10):
...     print i+10
...     print i-10
...     print i/2
... 
10
-10
and so on

if you directy copy and paste the above snippet, it clearly won’t work due to the presence of the prompts:

>>> >>> for i in xrange(10):
 File "<stdin>", line 1
 >>> for i in xrange(10):
 ^
SyntaxError: invalid syntax
>>> ...     print i+10

Frustrated, I decided to solve the problem once and for all: I created a .pythonrc file where I override the normal “>>> ” prompt to a header prompt, and the continuation prompt to the empty string:

import sys
sys.ps1='--- [Python] ---\n'
sys.ps2=''

Then, I added the PYTHONSTARTUP variable in my .bash_profile to refer to this file:

export PYTHONSTARTUP=$HOME/.pythonrc

Now my interactive session looks like this

Python 2.7.1 (r271:86832, Feb 27 2011, 20:04:04) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
--- [Python] ---
for i in xrange(2):
        print i

0
1
--- [Python] ---

I am now free to copy and paste the above code and replay it in the interpreter, or later on, directly into a vim session (but I will have to change tab spacing).

3d plot of earthquakes in Ferrara-Modena-Bologna

The earthquakes that recently hit my hometown and region triggered a natural sequence of minor quakes. Thanks to the available data, I was able to plot the 3d representation of the ipocenters. Red points represent all the quakes from the start of the seismic sequence to the 3rd of June. Points in purple represent particularly strong quakes (5.0 or higher). Blue squares represent cities. I suggest to enable the 720p version.

The science of decay: beautiful BBC documentary