[ Introduction | Designing Raphael | User Documentation | Writing Modules | Other Packages | About Us ]

Raphael Project


NEEDS to be FORMATTED

jana's instructions modified by dan -> metamind@intap.net
typemaps dir:
/vision/packages/swig/SWIG1.1/lib/swig_lib/python/
dir of arrayobject.h (PyArray_Object):
/vision/packages/Python/Python-1.4/NumPy/Include/
dir of abstract.h (Pyobject and related functions):
/vision/packages/Python/Python-1.4/Include/

INSTRUCTIONS ON SWIG:

make a new directory to work in, previous work is in the /vision/projects/kimia/python-c-code directory.
1)write the .i (interface) file (look at bottom of this file or other examples for this )
2)copy the Makefile.pre.in from (current dir or) /vision/projects/kimia/raphael/dcs or any other /vision/projects/kimia/python-c-code directory -- this file should not be changed.
3)copy the Setup.in file also (you will have to change this file to include the libraries that you need. look at Setup.in in this directory for this)
4)now that you have everything you need modify make.bat and run it. make.bat is used to make the debugging process easier, nothing more.
5)_IF_ you were creating the simple_utils module for example, in your directory you will have:
- the original Makefile.pre.in,
- your Setup.in,
- and your simple_utils.i.

If everything SWIGed smoothly, SWIG will have made: - simple_utils_wrap.c , - simple_utils_wrap.doc, - simple_utils_wrap.o, - simple_utilsmodule.so. THE .so FILE IS MODULE THAT YOU IMPORT into python! just use the command: import simple_utils (for this example). You must leave off the module part of the .so's name. Now that you have made the module, you have to put it into a directory that's in your PYTHONPATH environment variable. Depending on your machine, you can copy the .so file into $LEMS_ARCH_DIR/lib/python1.4/sharedmodules/. There is a symbolic link to the sharedmodules directory that (at least) lems61 uses in: /vision/projects/kimia/python-c-code/sharedmodules.

NOTE: if you copy the .so file to a PYTHONPATH directory, and rebuild it in your working directory, you have to overwrite or delete the old one. I think the order of directories that python searches for modules uses the PYTHONPATH dirs FIRST, but I am not positive. I always copy over all old versions just in case! ALSO: when you change your .i file when debugging, or perhaps change your typemaps.i (if you use one) or even your Setup.in file you must run the unmake.bat before you make.bat again. In other words you must re-SWIG, but delete your previous SWIGed files and Makefiles. unmake.bat will do this all for you. OK YOU'RE DONE WITH SWIG!!!

6) now it's time to write the raphael wrapper. When bringing your Module into Raphael don't forget to: - register module with the module manager (see example at bottom of file), - put module path into ModuleList (in the raphael dir, look at syntax in file).
ok that's it!

sample .i file: /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ %module simple_utils %{ #include #include /* directory defined in Setup.in */ %} %include lems_typemaps.i /* ^ is in /vision/packages/swig/SWIG1.1/lib/swig_lib/python */ %apply float* ARRAY{float *a} /* this says find the rule for float* ARRAY (in type_maps.i) and use it for all float *a defined in this file %apply float* ARRAY{float *b} %apply float* ARRAY{float *output} /*Function to ADD two arrays. The output is set to the sum of the two numbers */ void Add_Arrays(float *a, /*Input Array*/ float *b, /*Input Array*/ float *output, /*Output Array*/ int height, /*Height of array*/ int width); /*Width of array*/ /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

sample Setup.in: See /vision/projects/kimia/raphael/dcs/Setup.in # ----------------------------------------------------- #

sample of Raphael .py file: #make sure your module name is of the form: SimpleArrayModule.py. With the capital Module at the end of the file!! import simple_utils ,RaphaelAPI , string , Numeric def add_arrays(RID1, RID2): # define the function that will run your module if RaphaelAPI.objectManager_doit(RID1,"getMode")!="L": print 'not gray' # make sure the arrays are grayscale return if RaphaelAPI.objectManager_doit(RID2,"getMode")!="L": print 'not gray' # make sure the arrays are grayscale return else: inputArrayList1 = RaphaelAPI.objectManager_doit(RID1,"getArrayList") # ^^ This is the line to get an array from an RID (IMAGE). inarray1 = inputArrayList1[0].astype(Numeric.Float32) # if you need to pass a float *Array into your module -> # USE Numeric.Float32 type in case the conversion isn't automatic!!! shape1 = inarray1.shape height= shape1[0] width = shape1[1] print shape1 #prints the dimensions of the array # now I run the same procedure for the second RID (IMAGE) inputed inputArrayList2 = RaphaelAPI.objectManager_doit(RID2,"getArrayList") inarray2 = inputArrayList2[0].astype(Numeric.Float32) shape2= inarray2.shape print shape2 #check if sizes are the same if shape2 != shape1: print "shapes not equal"; return hw = height*width returnArray = Numeric.zeros(shape1, Numeric.Float32) # create an array for holding the output data simple_utils.Add_Arrays(inarray1, inarray2,returnArray,height,width) # now this is the procedure to pass back the returned data # as an "IMAGE" rid = RaphaelAPI.objectManager_createNewObject("IMAGE") # this creates a new "IMAGE" Object in the objectManager RaphaelAPI.objectManager_doit(rid,"fromArray",returnArray) # this turns our output array into an image return rid # and lastly we give raphael our "IMAGE" object which will be displayed # by default # outside of our module definition we define arguments: arguments = """ """ # if your module requires user input to set variables in your module, you # would define input boxes inside the arguments. # you may use radio buttons, check buttons, and entry boxes .. maybe more.. # see /vision/projects/kimia/raphael/work-in-progress/MorphologyModule.py # for an insane example of this. # things to remember with arguments: # - when defining your function, write the variable name to be input # i.e. def math_morphology(RID1, OP, NOTFLAG): where RID1 gets passed by raphael, and OP and NOTFLAG are defined in arguments # - if you use an ENTRY, the value from it is a string and you might need to convert it into a int or float with: # import string # ENTRYVar = string.atoi(ENTRYVar) # for int conv. RaphaelAPI.moduleManager_registerMethod("SimpleUtils","add_arrays",add_arrays, ["IMAGE","IMAGE"], arguments, "IMAGE") # syntax to registerMethod: # registerMethod ("name of pyfile, - the Module", "name of method", name of method, ["Input types"], arguments, "returned Output type") #___________________..............----------...............___________________ BUBBLES: /vision/projects/kimia/segmentation/2d-bubbles/ /vision/projects/kimia/segmentation/2d-bubbles/bubbles-modules/general-modules

(RaphaelAPI documentation goes here.)


Email the Raphael Project