BR's crystallographic computing tutorials

Creating GIF files for web application within FORTRAN CGIs

Below is a form starting a little CGI script that creates a GIF plot of atomic scattering factors for a selected element and a given temperature factor B.  Try the application and you will get back a nice plot instead of the crude line graphs or lists I had in my first generation CGI's. So how is this done?

Enter a valid element symbol and a B-factor (0-50 �2)

Introduction

Why in FORTRAN ?

As scientists, we may have a useful program in FORTRAN that does a nice job and it would be desirable to make the program available on the web. The obvious benefit is that you do not have to deal with platform and implementation issues - no invalidated version proliferation, no source code mess etc - the application runs on your host computer, and the browsers take care of the platform specific implementation. All of a sudden your old F66 code has a graphical windows interface and returns great looking graphs! Just imagine how you can now create really interactive web based tutorials or applications!

The problem at hand can be split up into two essentially independent parts : First, how to get the information from the web server (which is the program that receives the web form with the requested action) into the CGI (Common Gateway Interface) program that actually executes the computation, creates the GIF and then sends the information back in the format of a valid web page to the server for display at the client's browser. The first part I describe in my CGI tutorial. If what I say here does not make sense to you, please go back go back and review basic CGI programming in FORTRAN.

The second task is to create a GIF file [gname] within the FORTRAN code, and then to display the file within the html document with a simple HTML command :

c --- pop the image to stdout                                           WEBS0221
      write(*,*)'<p><img src="'//gname//'" width="600" height="450">'   WEBS0222

The new art now is to write a GIF in FORTRAN. GIF (Graphics Interchange Format) is the most commonly used compressed file format in web exchange. The GIF specification incorporates the Lempel-Zev-Welch (LZW) compression technology which is the subject of a patent awarded to Unisys. Use of this technology, and in particular creation of GIF  format files, may require a license from Unisys [1].No license or license fees are required for non-commercial, not-for-profit GIF-based applications or for non-commercial, not-for-profit GIF-freeware, so long as the LZW capability provided is only for GIF. However, a license is required if freeware is incorporated into, or sold or distributed with a commercial or for-profit product, introduced in 1995 [or later], or enhancements of products that were introduced prior to 1995.

The PGPLOT library

Writing a compressed binary file and coding all the graphing routines would be indeed painful. Fortunately, there is quite an excellent graphics library for FORTRAN (and C). PGPLOT is not public-domain software. However, it is freely available for non-commercial use. The source code and documentation are copyrighted by the California Institute of Technology, and may not be redistributed or placed on public Web servers without permission. The installation (which I tested on NT for the DEC FORTRAN 90 compiler V5.0b) is very straightforward if you *exactly* (red, bold, asterixed) follow the provided instructions. PGPLOT can be downloaded from http://astro.caltech.edu/~tjp/pgplot/ .For the DEC NT compiler, and to obtain the necessarily 'quiet' CGI application, comparable as a Win32 console (NOT Quickwin!) application, you MUST add a few marginally modified subroutines to your project, which are available from my site. Including these subroutines explicitly in your project files overrides the PGPLOT library call resolution.

Here are the details on how to proceed for NT :

  1. Download and install PGPLOT  - pay attention to the windows-specific instructions
  2. Create a static library as described in the instructions
  3. Create a new application, including the necessary files as outlined in my example. I suggest to run the example I provide (a stripped-down example 1 from PGPLOT). Don't forget to link the PGPLOT.LIB library you made in the previous step. If necessary, exclude libc.lib (may happen on upgrade installations from MS to DEC FORTRAN)
  4. Look at the other examples to familiarize yourself with PGPLOT graphics programming
  5. Combine the GIF creation with your CGI program. The code below is the example application I provide which writes a random named gif file xy.GIF.

If things don't work :

  1. Use the standard PGPLOT files and  *exactly* (red, bold, asterixed) follow the standard installation, run the standard examples. It worked really well for me - no problems at all.
  2. If that does not work, your problem are not my files. I may be able to help, but Tim Pearson, DEC, Microsoft or whoever may be better sources of information.
  3. If the standard PGPLOT windows NT installation and the examples work, but the quiet console application with my modified file does not work, e-mail me. DO NOT bug Tim Pearson at Caltech.   
  4. Nota bene : I am talking DEC Visual Fortran 5.0 under Windows NT. I have no more MS Fortran PowerStation available, so no luck there as far as I am concerned.
  5. Break up the problem - make sure the CGI part alone works. Again, I may be able to help here. Run the plot part on mock data. Make sure it runs stand-alone. For help, see above. 

Console code example

      program console                                                   CONS0001
c-----------------------------------------------------------------------CONS0002
c demonstration program for quiet PGPLOT Win32 console application :    CONS0003
c quietly writes a gif file in background as needed for web CGIs        CONS0004
c web-tutorial example by B.RUPP Macromolecular Crystallography         CONS0005
c                             LLNL-BBRP                                 CONS0006
c-----------------------------------------------------------------------CONS0007
c --- needs following modified routines (add them to each console       CONS0008
c     project - no need to change or recompile the PGPLOT library):     CONS0009
c                                                                       CONS0010
c     gidriv_c.f  (_c means 'CONSOLE' in my lingo)                      CONS0011
c     grdos_c.f                                                         CONS0012
c     grexec_c.f                                                        CONS0013
c                                                                       CONS0014
c     and in case they create trouble (i.e., unwanted but in-           CONS0015
c     consequential warning messages), comment out the write            CONS0016
c     statements in :                                                   CONS0017
c                                                                       CONS0018
c     grmsg.f                                                           CONS0019
c     grwarn.f                                                          CONS0020
c                                                                       CONS0021
c     I normally would leave them in - in case you have a problem       CONS0022
c     and need diagnostics                                              CONS0023
c                                                                       CONS0024
c --- that's all folks --                                               CONS0025
                                                                        CONS0026
      character fname*6,fext*4                                          CONS0027
c --- PGOPEN is an integer function of PGPLOT library                   CONS0028
      integer PGOPEN                                                    CONS0029
                                                                        CONS0030
c --- create a random file name in case 2 users concurrently use the    CONS0031
c     same cgi -  not elegant but p=1/625 does it for me here           CONS0032
      fext='.gif'                                                       CONS0033
      call random_name (fname,fext,2,25)                                CONS0034
                                                                        CONS0035
c --- call PGOPEN to initiate PGPLOT and open the output device         CONS0036
c     with the filename as parameter and check the return code          CONS0037
c     from PGOPEN.                                                      CONS0038
                                                                        CONS0039
      if (PGOPEN(fname//'/GIF') .le. 0) stop                            CONS0040
                                                                        CONS0041
c --- we want black linegraphs on white background                      CONS0042
      call PGSCR(0, 1., 1., 1.)    !black becomes white                 CONS0043
      call PGSCR(1, 0., 0., 0.)    !white becomes black                 CONS0044
                                                                        CONS0045
c --- call the first PGPLOT demonstration subroutine                    CONS0046
      call PGEX1                                                        CONS0047
c --- no argument needed, all graphics definitions etc in               CONS0048
c     include files of PGPLOT library                                   CONS0049
                                                                        CONS0050
c --- clean up things and close files/device properly                   CONS0051
      call pgclos                                                       CONS0052
c --- now you should have a gif file xy.GIF in your active directory    CONS0053
      end                                                               CONS0054
                                                                        CONS0055
      subroutine random_name (fname,fext,in,num)                        RAND0001
                                                                        RAND0002
      character fname*(*),fext*4                                        RAND0003
      integer iran(in)                                                  RAND0004
      real rand(in)                                                     RAND0005
                                                                        RAND0006
      call random_seed ()                                               RAND0007
      call random_number (rand)                                         RAND0008
                                                                        RAND0009
      do i=1,in                                                         RAND0010
         iran(i)=int(rand(i)*num)                                       RAND0011
         fname(i:i)=char(iran(i)+65)                                    RAND0012
      end do                                                            RAND0013
                                                                        RAND0014
      fname=fname(1:in)//fext                                           RAND0015
      return                                                            RAND0016
      end                                                               RAND0017

References

[1] I once received a patent for an algorithm describing the form function, including its FFT, of the common English water toilet. Sitting on the crapper may henceforth require a license. I hope we have properly covered all legal aspects.


Back to Introduction
This World Wide Web site conceived and maintained by Bernhard Rupp
Last revised Dezember 27, 2009 01:40