Introduction by Dave Mitchell
How to compile scripts
The instructions below were a response from Douglas Hague (Gatan) in connection to a query from Dave Mitchell about how to go about compiling scripts for Digital Micrograph. Why would you want to compile scripts? Well scripts, as run directly within Digital Micrograph, are interpreted, not compiled. This means that each line of instruction in a script is read in the high level language in which it is written (C++ – like language) and then interpreted into a low level instruction before execution. This makes it slow. For processor-intensive operations, this can result in scripts taking minutes to do their thing. However, if the scripts are compiled, they are converted into low level machine code and stored in a plugin. This plugin will be in the form of a file living in the DM folder, with a name like ‘pluginname.dll’, where dll stands for dynamic linked library. When DM launches, it reads and loads all the dlls. If you then invoke a script function in a script where the script function has been compiled as a dll, it will be executed in machine code (no interpretation) and will be blisteringly fast. This is my primitive level of understanding of the process. So if you write a script which is painfully slow, you can compile it and it will be much faster. However, it is not that simple a process, and some prior C++ programming experience will help you greatly.
If you struggle through this process to compile your own scripts and enjoy some success, please share your experiences with fellow scripters at the DM Script Archive web site (where you got this from). I have followed Doug’s instructions and have successfully compiled the example code he created from my original script. I used Microsoft’s Visual C++ version 6 compiler successfully. However, I couldn’t get the version 7 to work. I did not proceed further with this as there seemed to be just too many subtleties and variables in both converting regular DM scripts into C++ scripts for compilation, and actually doing the compilation. I just don’t understand enough about what is going on. I may revisit it later, when I have learnt a bit more. However, don’t let that put you off, as I am a bit hard of thinking. Good luck!
Foreword Dave Mitchell
The original example script I sent to Doug (to compile) was called Horizontal Derivatives DM.s. This very simple script takes the foremost image and calculates the horizontal derivatives (left and right) of the image. The derivative is just the difference between the image and a copy of the same image displaced slightly (either left or right). It is good for showing up vertical features such as lines on x-ray film.
I used Microsoft’s Visual C++ version 6 to do the compiling, which is reasonably straightforward to use. Version 7 has all sorts of extra twiddle in it, and is very confusing – I couldn’t get it to work.
As Doug mentions below, you have to use the version of the Software Developer’s Kit (363beta) which is supplied here, otherwise it won’t work.
Instructions by Douglas Hague (Gatan)
I have attached a package containing a sample plugin that implements the image processing part of
your ‚Horizontal_Derivative_DM.s‘ script. If you unpackage this at the same level as the example plugins in the DM SDK, it should build. In the directory containing the SDK is <DMSDK>, it will place the plugin in
<DMSDK>/Debug/bin/Plugins for the debug build
<DMSDK>/Release/bin/Plugins for the release build
The ‚DMSDK362‘ sdk turned out not to have a useful function, so I have created a slightly modified called DMSDK363Beta.exe. That will be required to build the package.
What I have done is take the image processing part of your script, and move it into a script function ( using DM script notation )
void ImgProc_Horizontal_Derivative( Image src_img, Image &l_deriv_img, Image &r_deriv_img )
The script function ‚Horizontal_Derivatives_DM.s‘ in the package is your script modified to use the C++ function. I have implemented the function in a simple way ( and it may be slightly incorrect, I didn’t check too closely whether it matched your script exactly, so it may be off by ‚1‘ or the right and left images may be swapped ). Some of the issues I glossed over are
1) Proper floating point to integer conversion in C++ are tricky. I didn’t go into these in detail, but if you’d like I can go into the problems. You may want to consider producing only floating point images in C++, and then use as you did in your script ‘ConvertToShort‘, or the more general ‚ImageChangeDataType‘ to do the conversion properly. Some other issues
2) You will have to handle the various data types DM provides explicitly in C++. Templates can make your life easier, but if not used carefully they will lead to code bloat. I am currently looking into public template libraries that can be used, such as ‚http://www.oonumerics.org/blitz/‘, which you might want to check out. Otherwise, you can do what I did and simply convert the image to floating point ( which wastes time and space, but you could do the conversion yourself line-by line with templates ). I hope to provide some of the utilities we use to do this, but it won’t happen in the immediate future.
One of the tricky issues of providing a C++ script function is dealing with the various types. Gatain really needs to make proper documentation available, but until then I have provided the example, and I will try to produce better documentation over the next few months.
Footnote by Dave Mitchell
The DMSDK contains a folder called SampleInterfaces. If you open the ‘SamplePlugin.cpp’ file in Visual C++ you should be able to compile it into a dll. When you put this dll into the Digital Micrograph folder and then launch DM, the dll should run – it’s function is to print ‘hello world’ into the Results Window. (I think this is correct – I did all this some time back, and have removed the compiler from my computer, so I can’t check – experiment). This shows everything is working correctly, and you can then move on to checking out Doug’s C++ code.
Files for Download
The following files are included in the zip-file (3.6MB):
- Horizontal Derivatives DM.s
- How to compile DM Scripts.rtf
Example 2: Hough-Transform
Christoph Koch (Max Planck Institut für Metallforschung, Stuttgart, Germany) took up the task of creating a C++ compiled DLL file out of the script Do-Hough-Transforms by Vincent Hou.
He also provided the code as a full Visual C++ 6.0 Workspace to give an example on how to do C++ DLLs with the DMSDK. All (15) files are included in the C++ Workspace, zip-file (3.3MB) and should be extracted to the Gatan\DMSDK\ directory, since it expects the Gatan DLLs to be in the proper directories relative to it.
The following text is quoted from his email to the DMSUG-mailing list:
As for the tutorial, I don’t know whether I can do this, especially since I have not enough experience in this. However, the DLL C++ code for the Hough Transform will be a good example of how to read an image, process it, and create another image based on the information of the previous one.
I suppose it does take some experience in C++ programming, although not very much.
The Gatan DMSDK (http://www.gatan.com/scripting/SDK.php)already includes quite a few examples, demonstrating you how to read in numbers, images, print text messages, etc.
This was the only source of information available to me when I wrote my first DLL, and it still is.
My incentive to write DLLs in the first place was to be able to do FFTs of any arraysize, as is implemented in the free (and extremely fast) FFTW3 library (www.fftw.org).
I run Visual C++ 6.0 on my laptop, and I zipped and uploaded the full Visual C++ workspace. I suggest that you unzip the file HoughTransform_DLL.zip in the ….\Gatan\DMSDK\ directory, because it will look for the gatan DMSDK dlls. All you have to do is to load this workspace in your C++ compiler and edit and recompile it.
Even without compiling it yourself you may find the DLL by looking in the ….Gatan\DMSDK\HoughTransform\Debug\ folder.
DM should not be running, when you compile, since the compiler will automatically copy the compiled DLL into the DM plugin directory ….\Gatan\DigitalMicrograph\PlugIns\.
You can change this if DM is installed somewhere else. If DM is running during compilation, and this
DLL is already loaded, it will simply not copy – that’s all.
Maybe somebody could tell us how to dynamically load and unload DLLs, so that one does not have to restart DM (and wait forever!) everytime you make a change to a plugin.
I hope this helps getting started to write DLLs yourself. By the way, I believe HREM Research (http://www.hremresearch.com/) is doing custom plugin development, if you want somebody to do it for you.