Here is a sample program which demonstrate how to use python arrays with VTK. It can be used with almost no changes with numpy arrays. Similar code snippets for Java can be taken from jCAE, here. Using such array API is required to work with decent size mesh because it’s much faster than working at the VTK cell level.
#! /usr/bin/env python
from array import *
from vtk import *
def create_points(array):
"""Create vtkPoints from double array"""
vtk_points = vtkPoints()
double_array = vtkDoubleArray()
double_array.SetVoidArray(array, len(array), 1)
double_array.SetNumberOfComponents(3)
vtk_points.SetData(double_array)
return vtk_points
def create_cells(array):
"""Create a vtkCellArray from long array"""
vtk_cells = vtkCellArray()
vtk_id_array = vtkIdTypeArray()
vtk_id_array.SetVoidArray(array, len(array), 1)
vtk_cells.SetCells(len(array)/4, vtk_id_array)
return vtk_cells
def vtk_to_array(vtk_array):
at = vtk_array.GetDataType()
if at == 11:
#vtkDoubleArray
pt='d'
elif at == 12:
#vtkIdTypeArray
pt='l'
#this is slow. numpy.zeros would be faster.
r = array(pt, [0]*vtk_array.GetSize())
vtk_array.ExportToVoidPointer(r)
return r
#Create polydata
points = array('d', [0,0,0,1,0,0,1,1,0,1,1,1])
triangles = array('l', [3 ,0,1,2, 3, 0,1,3])
polydata = vtkPolyData()
polydata.SetPoints(create_points(points))
polydata.SetPolys(create_cells(triangles))
#Save it
writer = vtkXMLPolyDataWriter()
writer.SetFileName("zob.vtp")
writer.SetInput(polydata)
writer.Write()
#Read it
reader = vtkXMLPolyDataReader()
reader.SetFileName("zob.vtp")
reader.Update()
polydata = reader.GetOutput()
#Display arrays
print vtk_to_array(polydata.GetPoints().GetData())
print vtk_to_array(polydata.GetPolys().GetData())
In Netbeans platform icons are displayed in the toolbar editor only if the underlying action have the iconBase property defined. I had more than hundred action to change when I found this bug/limitation. So I needed to add:
putValue("iconBase","org/foobar");
in all action constructors. I first tried with a find+awk/sed combo without any success. Here is the python script I used to this refactoring operation:
#! /usr/bin/python
import sys
import re
import tempfile
import os
import shutil
def do_a_file(filename):
input=open(filename)
output, output_name = tempfile.mkstemp()
output = os.fdopen(output, "w")
print output_name
rawstr = r"""(.*)putValue\(.*NAME"""
compile_obj = re.compile(rawstr)
for l in input:
match_obj = compile_obj.search(l)
if match_obj != None and len(match_obj.groups()) > 0:
output.write(match_obj.group(1)+'putValue("iconBase","org/foobar");\n')
output.write(l)
input.close()
output.close()
shutil.move(output_name, filename)
for root, subFolders, files in os.walk(sys.argv[1]):
for file in files:
if file.endswith(".java"):
do_a_file(os.path.join(root,file))
Now I often use it with minor changes for any refactoring operations which are to specific to be supported by my favorit IDE.
Anyway I guess such multiline context search/replacement is possible with awk or sed, and I would be glad to know how.
In my previous post I compared I/O and string formating and python was better than Java. Anyway as Java have primitive types and do not need to box/unbox variables it could be realy faster than python. Here is an exemple where I compute the distances between 3D points.
The python code
import time
from numpy import *
from math import *
n = 1000000
v1 = zeros(n*3)
v2 = zeros(n*3)
dn = double(n)
for i in xrange(n):
v1[i] = 1.0 + i / dn;
v2[i] = 2.0 + i / dn;
r = zeros(n)
t1 = time.time()
for i in xrange(n/3):
for j in xrange(3):
r[i]=r[i] + (v1[i*3+j]-v2[i*3+j])**2
r[i]=sqrt(r[i])
t2 = time.time()
print t2-t1
The Java code
public static void main(String[] argv)
{
int n = 1000000;
double[] v1 = new double[n*3];
double[] v2 = new double[n*3];
for(int i = 0; i < n; i++)
{
v1[i] = 1.0+i/(double)n;
v2[i] = 2.0+i/(double)n;
}
double[] r = new double[n];
double tmp;
long t1 = System.nanoTime();
for(int i = 0; i < n/3; i++)
{
for(int j = 0; j < 3; j++)
{
tmp = v1[i*3+j]-v2[i*3+j];
tmp = tmp*tmp;
r[i] += tmp;
}
r[i] = Math.sqrt(r[i]);
}
long t2 = System.nanoTime();
System.out.println("time: "+(t2-t1)/1E9);
for(int i = 0; i<n; i++)
{
System.out.println(r[i]);
}
}
Results
- Java: 0.02s (with a precision of 0.05s)
- Python: 9.49s
Conclusion
There are probably ways to improve my python code using numpy a better way, but most of the time to get rid of boxing/unboxing time you will have to write C code to speedup most critical part of algorithms. While Python is only a gluing (yet very good) technology, Java can be used to write fast low level algorithms.
Here is what I tried to print a large image (6000×4000 px) tiled on 16 A4 pages.
Jos van Eijndhoven poster
convert oisan2.png eps:- | poster -c2% -p111.76x68.58cm | ps2pdf - output2.pdf
It works but need one hour to do the conversion. I guess it’s because it work on a Postscript file.
It’s fast but it does not manage overlap. This is something I really need.
#! /usr/bin/python
import Image, ImageDraw, ImageFont
im = Image.open("input.png")
ni = 4
nj = 4
imarging = 40
jmarging = 40
width=(im.size[0] + (ni-1) * 2 * imarging) / ni
height=(im.size[1] + (nj-1) * 2 * jmarging) / nj
iincr=width - 2 * imarging
jincr=height - 2 * jmarging
f = ImageFont.truetype("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf", 25)
for i in xrange(ni):
for j in xrange(nj):
ipos = iincr * i
jpos = jincr * j
box = (ipos, jpos, ipos + width, jpos + height)
print box
thumb = im.crop(box)
d = ImageDraw.Draw(thumb)
d.text( (5,0), str(j+1) + ',' + str(i+1), font=f, fill='blue')
thumb.save( '/tmp/im' + str(i) + '_' + str(j) + '.png' )
Then with
ImageMagick:
convert -units PixelsPerInch -density 160x160 /tmp/im*.png output.pdf
A guy wrote a script to get the size of his files. Once finished he typed :wq! and ran its script:
chmod +x fileweight.py
./fileweight.py
Then nothing happened… Unless his cursor became a cross. He tried to get his cursor back by clicking everywhere. He couldn’t get what was going on. The only new things he could see were two files named os and sys in his directory.
Adding this at the beginning of a python script will not work:
#!/usr/bin/env LD_LIBRARY_PATH=mypath python2.5
because shebang only interpret the first space. So it will be interpreted as:
#!/usr/bin/env LD_LIBRARY_PATH="mypath python2.5"
The script will call it self in an infinit loop.
Reference:
My former blog was http://xrunhprof.free.fr/serendipity/. I wanted to change to no longer maintain it myself and to improve its visibility. I bench-marked Blogger and WordPress hosting. Blogger has a very powerful way to customize look and feel of the blog but it’s a bit hard to use for a non web-developer. Moreover it doesn’t have any import and export features, so I chose WordPress. In WordPress you need to pay to have the CSS customization feature, but I don’t really need it.
WordPress import/export format (WXR) is a bit broken. It claims to be an RSS extension but if you look at the import source code you can see it’s even not XML file. Look at this file
wordpress-2.3.1/wp-admin/import/wordpress.php
You will see that the WXR are parsed line by line using the php fgets command.
Serendipity RSS export is also broken as it only export summary but not full content of posts. Here is how I get round those problems.
Read more…
Here is a nice web site to compare languages properties: http://shootout.alioth.debian.org. But I did not found the test I was looking for: writing/reading float text stream. So I wrote mine.
Read more…