Dear Hernan,

This is review of my modifications to plotting package. 

Go to http://www.atmos.ucla.edu/~alex/Plot and get file plot.tar.

This plotting package is based on the version which is not the
most recent, so you may found some features which are not present
in yours. At the same time, based on what I saw in your newest
version available, most of the changes you have made are associated
with additions of possibilities to plot brand new types of fields,
while the basic plotting, input and netCDF data processing routines
were not changed. In contrast to that I worked predominantly on
those, so that my changes are most likely orthogonal to what your
did.

The motivation for my changes changes was four-fold:

(1) improving quality of generated hard copy plots, such as
    optimization of viewports (utilization of space), frames,
    proper scaling of font sizes (e.g., avoiding undesirable
    overlaps, avoiding to small or too large letters; possibility
    of font control from input script, etc.)


(2) code reorganization and making future modifications to do more
    easy. Specifically I made effort to merge codes which are
    parallel (e.g. if two or more codes exist, presumably made by
    copying one into another and then modifying the copied one. If
    then future modification is needed for some reason, it must be
    done in more than one place, which requires some effort to make
    it consistently. This involves merging of codes cnt.F/ccnt.F --> 
    ccnt.F;    get_nc2dat.F/get_nc3dat.F --> get_nc3dat.F etc.
    in such a way that both programs can be generated from the same
    source code. 

    Rearranging input according to the principle "one input file --
    one program to read it", so that if format of input file is to
    be changed for whatever reason, only one file needs to be edited
    and this file is easy to identify, e,g. read_inputs.F reads input
    script, one for all ccnt,cnt,sec,sec; set_defaults.F reads
    default file and sets some defaul initial values; read_varid.F
    reads variable IDs from appropriate file; set_palette.F reads
    color palette, etc (Thus there is no longer need to change all
    four, ccnt.F cnt.F csec.F and sec.F if, for example, format of
    file default.cnt has been changed.)

    Presently all input files formats are made consistent with 

    Elimination of redundant (dead variables) from the common
    blocks (mostly because these make it hard to trace data
    dependency rather than slow down the execution time) as well
    as privatizing some variables for the same reason.

    Straightening up complex logic in some places into
    straightforward nesting (easiness to read). 

    Making on-and-off debugging diagnostics.



(3) certain adaptations associated with MPI code:
      --> I use four basic dimensions xi_rho,eta_rho,xi_u,eta_v
          instead of eight. The remaining four, xi_psi,eta_psi,
          eta_u,xi_v have been abolished. Thus get_nc2dat.F ...
          get_nc3dat.F were modified to accept (this is done in 
          backward compatible fashion: it accepts both old and
          new file formats. 
      --> I tend to store simple variables as global attributes.
          Therefore get_nc1dat.F was modified to search for named
          object as a global attribute, and if not found, then as
          a variable, if not found again give up.

(4) performance issues, although this is quite smaller priority.
    basically it boils down to making mathematically dense code
    vectorizable, whenever possible. 

    Also speeding up compilation process. 





New features added:

--> Instead of generating gmeta file, one can generate a sequence
    of named postscript (one file per page) files ready to print or
    incert into latex paper. This feature is activated by making 
    PLTLOGO=.true. in the input file. (I found that PLTLOGO is a
    redundant variable, since it is parallel to WRTHDR. So in my
    input files I renamed it to POSTSCRIPT, while keeping format
    exactly the same.

--> It is now possible to make as many plots on page as possible.
    Parameter NPAGE in the input file may be either 1,2,4 (as
    previously) as well as numbers like 22, 32, -23, etc, which are
    simply interpreted as say 32 ==> 3x2 (i.e. 3 plots in horizontal
    direction and 2 in vertical on the same page; if negative --
    conserve aspect ratio (ccnt only)). 

    Note: file viewport.F is rewritten from scratch; sec_frame.F and
    cnt_frame.F are almost so.

--> Pmin,Pmax,Rmin,Rmax,Cint are now arrays, so that if desired,
    contour levels can be specified separately for each
    field/level/viweport. 

--> All font sizes are proportional to global variable magscale.
    (see file "set_defaults.F", try to change magscale from its
    default value of 1 to something else, like 0.0001, 0.5, 2.0
    and see what is going on.) Note: all margins for printing text
    labels, etc are being adjusted automatically as needed;
    Plot occupies as much space as possible, but is guaranteed to
    run out of boundaries (compile everything using -D"VERBOSE=3"
    cpp switch for the CPP in file Makedefs.WhatEverMachineIs to
    see Bounding Box (external boundary) of the maximum possible
    viewport.

--> Subroutine checkstrm.F (the one which replaces colon ':' symbol
    with ':133:' so that the string can be plotted by plchhq without
    causing problem now is capable to identify NCAR switches, e.g.
    Input string from file ccnt.in

                 ':F21:Roman style text: :F14:Italic style'

    will be converted into 
 
                ':F21:Roman style text:133: :F14:Italic style'

    so that colons associated with :F21: and :F14: remain unchanged.

    This allows one to write titles in any style he wishes, including
    formulaes, if you know how to do thai in NCARG.

--> In addition to Plotting coast line, it is now also possible to
    plot geographical names, like cities or characheristic points.
    These are stored in a special file, name of which is located
    just after coast line data file. Each record of this file has
    form 
           lat lon size angle ctr 'Character String'
     where
           lat,lon  -- are geographical coordinates of the object,
                             (longitude and latitude in degrees);
           size,angle,ctr -- size,angle and centering parameter
                          of the desired label (the same as
                          the last three arguments of plchhq)
           'Character String' -- name of the object.

     NOTE: 1. It is not necessary to encase 'Character String' into
              single or double quites, just leaving blank characters
              is enough. The numbers may be separated with commas, or
              just blank spaces;

           2. The size is the size of letters as it is desired on
              plot which occupies the whole page. If is automatically
              rescaled (multiplied by basesize, if the current
              viewport is smaller that the whole page).

   for example

      38.2 -122.5 0.0175, 20., -1, ':F6:San Francisco'
      34.5 -119   0.0125  20   -1   :F1:Los Angeles

      lat   lon     size  angle ctr  string

    any character style can be specified via :Fx: NCARG switch.
      


--> a lot of line formatting routines were changed for better behavior
    (typically to make labels more compact)


Code organization:
---- -------------

--> Various merges of codes; typically to facilitate further
    modification;

--> All subroutines are combined into three quasi-independent
    libraries: 

       lib_phys.a -- Physical computational routines; Mostly these
                     are related to computation of derived fields
                     for plotting. This library is expected to grow
                     as new routines added. 

       lib_plot.a -- Plotting routines (these are the ones which
                     call NCAR graphics routines).

       lib_util.a -- utilities, including those which make netCDF
                     calls, as well as many string processing 
                     functions. 

    Note: routines which belong to lib_phys.a may call routines
              belonging to lib_util.a, but never call lib_plot.a;
          routines which belong to lib_plot.a may call routines
              from lib_util.a, but never call lib_phys.a
          Obviously the compiling sequence may be
          either
                  lib_phys.a lib_plot.a lib_util.a
          or
                  lib_plot.a lib_phys.a lib_util.a
          
          Because typically, when I work on the code only one library
          is being rebuild, it takes less time to recompile.


--> debugging: In many places I have added lines like

          #ifdef VERBOSE
                 write something
          #endif  

       or

          #if VERBOSE > 1
                  write something
          #endif

     where CPP macro VERBOSE is defined in CPP preprocessing line. 
     These lines do not affect the plots (except the BoundingBox
     will be drawn by maptitles, if VERBOSE > 2. 

     It simply facilitates tracking what code is doing at any given
     time, as well as find places where it hangs (occasionally it
     occurs, including dead loop situations inside NCAR graphics
     calls under some circumstances, for example aredam (and NCAR
     library routine) hangs on Soliton problem output because of some
     roundoff error problem confusing internal logic.


     VERBOSE =1 (the lowest level typically prints successful about
                 variable retrieved, viewport infiormation, etc;
     Other levels are for more intrusive debugging ==> more level
     more messages.



--> Makefile: I made effort to make Makefiles as portable as
    possible. All you have to do is to place the appropriate
    "Makedefs.Plot" file into you $HOME/bin directory, provided
    that you modify it to set correct path to NCAR and netCDF
    libraries. After that you justs same "make" and few minutes
    later everything will be compiled.

    (In my case, I keep source code in a directory, which is
    accessable by both SGI and Sun. Since Physical location of
    $HOME/bin depends on the machine (and they are physically
    different) I placed the machine dependent files there. After
    that if I say "make" on one machine on on the other, it works
    both ways without ano adaptations whatsoever.

--> Use of mpc is optional for this code; mpc now works as 
    pipe: 
               /..../cpp -P file.F | mpc > file.f

    (the prefered usage) is the same as

               /..../cpp -P file.F > file.i
               mpc file.i > file.f

    except that faster because the intermediate file does not
    have to land on the disk. for this code

            /..../cpp -P file.F > file.f

    will have the same result.






Overal I modified to some degree about 40% of the files for various
reasons, mostly straightening out logic while trying to understand
what is going on.
Stylistically I prefer straightforward AFFIRMATIVE if-nesting rather
than multiple returns, goto or even worse, crash calls, for example

       ierr=nc_call_1(...)
       if (ierr.ne.nf_noerr) then
         write(*,*) 'error message 1'
         call crash (...) 
       endif
       ierr=nc_call_2(...)
       if (ierr.ne.nf_noerr) then
         write(*,*) 'error message 2'
         call crash(...)
       endif
       ierr=nc_call_3(...)
       if (ierr.ne.nf_noerr) then
         write(*,*) 'error message 3'
         call crash (...) 
       endif

       do appropriate action when
       read operation is successful.
       return
       

translates into code

       ierr=nc_call_1(...)
       if (ierr.eq.nf_noerr) then
         ierr=nc_call_2(...)
         if (ierr.eq.nf_noerr) then
           ierr=nc_call_3(...)
           if (ierr.eq.nf_noerr) then

                do appropriate action when
                read operation is successful
           
           else
             write(*,*) 'error message 3'
           endif
         else
           write(*,*) 'error message 2'
         endif
       else
         write(*,*) 'error message 1'
       endif
       return

(Note that there is only one return statement and no calls
to crash. Error status -- variable ierr -- will be returned
to the calling program and will be handled accordingly.
(On long term I would rather prefer to eliminate calls to
crash completely, but rather return error status all the way
to the top.)  Because error messages are typically verbose,
a couple lines or more each, the AFFIRMATIVE part of the
code (that is the one which goes if everything is normal)
becomes very short in comparison with the code above, where
it is distributed throughout the whole code, for example,
see how vvumxy.F and get_nc3dat.F look like now.)


--> Some of the subroutines are not called explicitly from
    the plotting package, but rather internally from NCAR
    library. Basically they overwrite (take over) the inernal
    subroutines. Thus their names and arguments (number, type
    and order) should not be modified under any circumstances.
    I placed WARNING massages in such places.

 

What I want from You
==== = ==== ==== ===

1. I want to have input files as universal as possible, thut is
   ccnt.in and cnt.in should be the same (almost there, except
   that parameter icnt (in ccnt.in) which maps to cint (in cnt.in)
   read comment inside read_inputs.F.

   Similarly ccnt.in and csec.in should be as close as possible,
   and can be made so.

   See read_inputs.F. I believe, the format of input files should
   be made such that it would require only one 

              if (plttyp.eq.cntplt) then

              elseif (plttyp.eq.secplt) then

              endif

   logical branch. Just a frew swappings of lines will do the job.
   Let's agree on common standard. 



2. Land masking algorithm (landmask.F) is not robust and never being
   robust: for some reason data files for coastline (extracted from
   NCAR graphics dataset) contain unclosed segments and
   self-intersecting polygons. The program is not able to detect
   it and make preventive measures. 

   Although I have checked and found that the algorithm is correct:
   if I give a simple coast line it works OK.

   Any clue how to say whether a polygon is self-intersecting or not?



3. If you have updated graphics package, can you integrate my
   changes and send me back? I believe, since changes I made are
   quite nonlocal, the easiest thing to do is to add new physical
   routines, but use this code as the platform, rather than trying
   to migrate changes made here to another code.


4. vvumxy.F: I modified vvumxy.F trying to make its nested logic
   more straightforward. Do we need to dintinguis so many different
   exit error status codes, or Zero -- non Zero would work just fine. 




Sasha



