Help on Pygwy Console, Gwyddion Scripting with Python

Leonard
2013-10-02
2013-10-30
  • Leonard
    Leonard
    2013-10-02

    Hi,

    I would like to do simple batch processing of images but I am not quite sure how to do that and what method I should use.
    What I need is: I have usually 8 images (containers) in one data file. I want to tell Gwyddion to take lets say image Nr. 1, 4 and 5 and apply a set of processing steps on those (flatten, denoise, set limits of z- scale bar to e.g. -0.5 to 0.5 V) and save them all as a jpg into a predefined folder (maybe with different names for image 1, 4 and 5).
    Because I already know Python a little, I thought about using this. I understood from the gwyddion homepage that I can either use Python or the Pygwy console inside gwyddion. Is there a major difference between the two possibilities?
    The first problem I have is, I don't know how to get Python communicating with Gwyddion and which command prompts or Shells I would need to use (I don't know much about programming). I installed Python 2.7.5 and PyGTK (using the all in one installer).
    Instead of using Python directly I tried to use the Pygwy console and I copied your code from the example "Calling process module and export" into Pygwy console and it worked.
    The only things I still need are the commands of how to e.g. set the z-scale to certain values for several containers of a dataset. I thought all process modules were listed in this pygwy documentation http://gwyddion.net/documentation/head/pygwy/ but I can't figure out which process modules belong to which processes in the gwyddion visual interface.
    Could you please help me with that?
    If you think, I should better use Python itself rather than Pygwy console to do that or another method, please feel free to say so.

    I hope I explained my problem understandably enough. If not, please ask me what is unclear to you.

    Thank you very much.

    Leonard

     
  • Hey,

    I'm pretty new to Gwyddion development, but let me try to help you.

    If you are comfortable with Pygwy and see no problems in using Python scripts inside Gwyddion, you should do it. But if you're not, one can always write a standalone Python script to run from command line including Gwydion libraries.

    I'd recommend you reading the last Pygwy example on the documentation/tutorial page - it's about editting different containers from a file and inverting all their values.

    Instead of inverting their values, you want to flatten, denoise and change the z-scale. The steps you take to flatten and denoise will depende on which correction functions and tools you use.

    I didn't understand if you just want to show a scale bar from -.5V .5V or rescale your data. If so you'll have a minimum of -.5V and a maximum of .5V (the scale would be adjusted as well).

    Maybe someone more experienced might be able to give better advice, but feel free to e-mail me anyway and I'll see what I can do.

    Best,

    Vinicius.

     
  • Leonard
    Leonard
    2013-10-03

    Hi Vinicius,

    thank you very much for your very quick reply. I had a look at the last pygwy example. My problem is that I don't know what I have to actually type into the console to get what I want. E.g. for rescaling Z-axis, I don't know which command I have to use.
    I tried this one: gwy_color_axis_new_with_range(1, -0.5, 0.5)
    but it did not work.
    I don't really understand the code. For example, I don't know if all processed containers are saved as a png file and into which location. It would be great if someone could explain me the syntax of the code a little more in detail (in relatively easy words :-)?

    Thank you,

    Leonard

     
    • Leonard
      Leonard
      2013-10-09

      Hi Everyone,

      I tried to run the pygwy example that Vinicius suggested (Iteration over opened files on http://gwyddion.net/documentation/pygwy.php). It does change all containers in one data file but it does not export the changed images as png files. It just opens the export window for one of the containers and when I press ok, it does not even save the image somewhere. Do you think I have those troubles because I am running a 64 bit windows version?

      Thank you for your help.

      Leonard

       
  • David Nečas
    David Nečas
    2013-10-10

    Hello, the example script works for me in Linux. I'm not sure what the scripts gets as the working directory on MS Windows though. Did you try to put an absolute output file path there instead of just "exported_png_%d.png"?

     
  • Leonard
    Leonard
    2013-10-10

    Hello David,

    thank you for your reply. I just tried what you suggested and set instead of "exported_png%d.png" a path "C:\Gwyddion.png" I don't know if I did that correctly but I still have the same problems as before.
    However, I have tried both the last example "Iteration over opened files" and "Calling process module and export" from the website and both did not seem to work correctly for me.
    I copied the code exactly like it is from the website into my pygwy console. When I ran the "Calling process module and export" code on one of my files, the last image (image=datafield is that correct?) of my container (I think the container consists of all images that belong are usually stored in one of my AFM files is that correct?) was processed and exported as png in the same location as the original AFM file is stored. It also stored the fixed file and the text files for the one dimensional autocorrelation function etc. in the same folder so these things work. However, I thought the code would process and export the currently selected image as png but it always only processes and saves the last image of the container and displays all images of the container in the GUI (all images get ticked in the data browser).
    It is similar with the "Iteration over opened files" code. It processes all images of the container. However, it opens the export dialog for one of the images in the container (always the same image but not the last one) and when I click ok, it does not even save the image as png in the folder. What I would like to have is, that the code only processes the image that I have currently selected and exports it as a jpg for example.
    I guess what I describe is not what those codes should do? Do you have any good ideas what I could try?
    I thought about trying to do the same on a 32 bit windows os because I thought it might be a compatibility issue? I also used the PyGTK all in one installer so I thought there might be a problem.

    It would be really great if you could help me out!

    Thank you,

    Leonard

     
    • David Nečas
      David Nečas
      2013-10-11

      "C:\Gwyddion.png"

      That's a fixed file name so, of course, you would get only one output file and you need to remove the %-formatting

      ... basename % i ...
      

      because the string no longer contains any format specifier. But assuming that, and the you can write to C:\, it should work.

      (image=datafield is that correct?) of my container (I think the container consists of all images that belong are usually stored in one of my AFM files is that correct?)

      DataField is what represents an image in Gwyddion -- more or less, because for instance mask is another DataField

      Container is a general hash-table-like structure which is used to represent an entire file (and some other things).

      Please see

      http://gwyddion.net/gwydump.php
      http://gwyddion.net/documentation/user-guide-en/gwyfile-format.html

      for organisation of data in Gwyddion.

      The example Calling process module and export processes a fixed datafield at "/0/data" (see the code), which is usually the first in the file. To get the id of the current image use

      i = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
      

      The key in the container is then

      "/%d/data" % i
      
       
  • Leonard
    Leonard
    2013-10-11

    Thank you very much David. I am now one step further. I hope I will manage to get the code code right from here on.

    Leonard

     
  • Leonard
    Leonard
    2013-10-21

    Hi David,

    I tried to process the color scale of my images like I described in my previous posts lets say to 0 V min to 1 V max. I tried to do it with those commands:

    "gwy.Ruler.set_range(0.0,2.0,1.0,2.0)" for example
    and I also used this:
    "gwy.ColorAxis.set_range(0.0,1.0)"
    But the console just returned the following error:
    File "<string>", line 13, in <module>
    TypeError: descriptor 'set_range' requires a 'gwy.Ruler' object but received a 'float'

    On http://gwyddion.net/documentation/head/pygwy/gwy.ColorAxis-class.html it says the ColorAxis.set_range min and max need to be floats but it does not work (for Ruler as well).
    Do you know what's the problem there or do you think I should use some other command to do that? I would also like to be able to tell gwyddion to run the set_range command on e.g. datafields 3 and 5 of a container like here:

    gwyutils.save_dfield_to_jpg(c, "/5/data", filebase+"_lateral.jpg", gwy.RUN_INTERACTIVE)

    but instead of saving the datafield as jpg set the color range of it. Is that possible?

    I also have another question regarding gwydump. You suggested me to use gwydump to better understand how gwyddion works. I'm not sure if I really understood what it is good for. I assume I can open a file with gwyddion, process a datafield using the GUI and save the file and then print it in a textual form to see what command lines were created due to my manual processing, is that correct? If that's the case, can I then use those command lines in pygwy console?

    Thank you,

    Leonard

     
  • David Nečas
    David Nečas
    2013-10-21

    gwy.Ruler or gwy.ColorAxis are the classes of the ruler and colour axis widgets. You definitely don't want and can't call any methods such as set_range() on them.

    You can (in principle) but still don't want to do this with specific instances, i.e. specific ruler or axis widgets in a specific data window. This would mean locating the specific data window and then the specific widget inside (which is possible though not completely trivial) and setting the values. The result of such exercise would be a temporary change of the range because that's not how it is controlled.

    If you don't understand what classes and instances are please read some object oriented programming introduction. I can explain how things are organised in Gwyddion but can't provide a general programming guide...

    Unless you write a module with its own graphical user interface, you do not interact with the widgets directly. Only work with data and other values in the container; occasionally use of data browser functions may be necessary/useful.

    To change the range minimum of channel 0, set

    "/0/base/min"
    

    to the required value (as described in organisation of data linked before). Furthermore, to set the colour range type of channel 0 set

    "/0/base/range_type"
    

    e.g. to gwy.LAYER_BASIC_RANGE_FIXED. The types correspond to the modes in the colour range tool,

    Concerning gwydump, it shows the structure of a gwy file (and to a certain extent its contents). Let's say you want to see what happens in the container when you set the colour range to fixed. So you do this in the colour range tool, save the modified file and use gwydump to inspect it.

     
  • Leonard
    Leonard
    2013-10-29

    Hi David,

    I tried to understand the structure of files in gwyddion and from the table of the Channels in http://gwyddion.net/documentation/user-guide-en/gwyfile-format.html I thought I had to do it like this:

    import gwyutils, gwy

    c = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    filename = c.get_string_by_name("/filename")
    filebase = filename[0:-4]

    c.set_double_by_name("/0/base/min", "0.0")
    c.set_double_by_name("/0/base/max", "1.0")

    f.close()

    But I just received the following error:
    File "<string>", line 10, in <module>
    TypeError: a float is required
    I think 0.0 and 1.0 are floats. Can you please tell me how I can set the min and max (and how to set the range type, I tried to do that as well) for an image?
    I also tried c.set_string_by_name("/0/base/min", "0.0") but it had no effect.

    I also tried to use gwydump. I copied the exe file into the same directory where gwyddion was installed and I also added the directory to my system's path but when I tried to start gwydump, the PC attempts to start it, but then nothing happens. Do you think it can be run on a 64 bit OS?

    Thank you,

    Leonard

     
    Last edit: Leonard 2013-10-29
  • David Nečas
    David Nečas
    2013-10-29

    The number has to be a number, i.e.

    c.set_double_by_name("/0/base/min", 0.0)
    

    not a string rendering of the number as in

    c.set_double_by_name("/0/base/min", "0.0")
    

    Then it should work.

    Concerning gwydump, it is a command-line program. So I'm not sure if `nothing happens' doesn't just mean that you run it from the GUI, so the program runs, prints some help (since it didn't get any arguments) and happily terminates. Or it really does not work. But certainly the executable on gwyddion.net is 32bit so it only works with 32bit installation of Gwyddion (in whateverbit version of the OS).

     
  • Leonard
    Leonard
    2013-10-29

    Hello David,

    I tried the command that you told me:
    c.set_double_by_name("/0/base/min", 0.0)
    But it did not work. No error comes up but nothing happens as well to my images.
    Do you have any other idea?

    Thanks,

    Leonard

     
  • David Nečas
    David Nečas
    2013-10-29

    c = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    c.set_int32_by_name("/0/base/range-type", gwy.LAYER_BASIC_RANGE_FIXED)
    c.set_double_by_name("/0/base/min", 0.0)
    c.set_double_by_name("/0/base/max", 1.0)
    

    works for me. That is it sets the false colour range for channel 0 to fixed and the fixed range to [0, 1].

     
  • Leonard
    Leonard
    2013-10-30

    Thank you David you're a star! Now it works. I think it was because the range type was not set and I did not know that I had to type c.set_int32_by_name for this.

    Thank you!

    Leonard