WCML (formerly Jumbo90)¶
Jumbo90 (by Jon Wakelin) is a library written in Fortran for creating CML documents. Actually, Jumbo allows you to create XML, CML and STMML (another markup language closely related to CML). After a moments thought you may ask why do we need a library to write things? I mean, you can always type
write(*,*)
"<cml>stuff</cml>"
Well, while in theory it is a fairly simply task to write CML, or indeed any XML, in any language, in practice it’s not quite that easy. Balancing tags that are opened at one end of a 2000 line source file and closed at the other or even opened and closed in different source files, is an unnecessary memory exercise, and balancing them in the right order a pain. More importantly, you’ll probably only spot your mistake when you try to process the file, and given that XML is case sensitive it’s a pretty easy to make a mistake. Furthermore, CML elements will often be built up in a standard manner using a large number of tags - and it can be fairly tedious typing in all of these. Add to this the fact that it is extremely difficult to correctly indent an XML document whose structure is as dynamic as that of the underlying program [1] (just using write statements). So, we decided that it was probably worth our while to create a library for handling the more tedious or tricky elements of creating a CML document. We also added functionality to check the well-formedness of all XML. In fact, most programming languages provide utilties for performing these seemingly simple tasks.
The original idea for Jumbo90 came from Peter Murray-Rust, who has a similar but much more rounded suite of tools written in Java, called Jumbo. Jon then converted Peter’s original F77 code into F90, but it suffered a little from its F77 inheritance, so now the base XML formatting layer of Jumbo is provided by Alberto Garcia’s WXML library.
A breakdown of all Jumbo90 subroutines follows.
Jon Wakelin, March 2004
[1] It’s only a cosmetic feature but it’s very useful when you need someone to read the file, of course, there’s nothing wrong with writing a 12M XML file in a single line.
What is Jumbo90?¶
Jumbo90 is a CML formatting Library for Fortran, it provides:
Convenience routines to write complete CML elements
Convenience routines to write complete STMML elements
Optional Indentation of output
Checks that tags are properly balanced
Checks that attribute names are well formed (i.e. contain only [A-Z a-z 0-9 _ -] and start with [A-Z a-z _]).
The colon is allowed but should be reserved for namespacing so an error is flagged if more than one colon is present in attribute name
Checks if attribute values contain predefined entities (<, >, &, ’, “)
Checks for duplicate attribute names
How to use Jumbo90¶
Jumbo covers CML, STMML and basic XML. Below is the full list of subroutine names, followed by the arguments they take. Whenever writing a real*8 or real*4 you can always pass an optional format argument, e.g.
call xml_AddAttribute(file, 'martin','height', 32.1285)
call xml_AddAttribute(file, 'martin','height', 32.1285, '(f6.2)')
would add an “height” attribute with a value of “32.1285” to a “martin” element . In the first case the default format ‘(f8.3)’ would be used, in the second case the user supplied format ‘(f6.2)’ would be used. Many subroutines can take a number of optional arguments (reflecting the CML schema) therefore the longer ‘argument=value’ format should be use when calling these subroutines, e.g.,
call xml_OpenFile('myFile.xml', file)
Notes:¶
Jumbo90 is based on an earlier fortran 77 program called Jumbo77, which was itself based on an existing Java CML parser called JUMBO written by Peter Murray-Rust. Jumbo90 is now built in a modular fashion allowing output of basic XML, STMML and CML. The STMML layer builds on the XML. The CML layer, in turn, builds on the STMML layer. The base XML writing utilities are now provided by (xmlf90-wxml), a set of F90 modules written by Alberto Garcia.
STMML routines¶
stmAddScalar <#stmsca>
stmAddArray <#stmarr>
stmAddMatrix <#stmmat>
stmAddTriangle <#stmtri>
stmError <#stmerr>
stmMessage <#stmmsg>
stmWarning <#stmwar>
CMLCore routines¶
cmlAddMolecule - adds a complete CML <molecule> element
cmlAddAtom <#cmlato> - adds a CML <atom> start tag
cmlAddCoordinates <#cmlcoo> - adds coordinate attributes to an <atom> tag
cmlAddCrystal <#cmlcry> - adds a complete CML <crystal> element
cmlAddMetadata <#cmlmet> - adds a complete CML <metadata> element
cmlAddLength <#cmllen>(length, id, atomRef1, atomRef2, fmt)
cmlAddAngle <#cmlang>(angle, id, atomRef1, atomRef2, atomRef3, fmt)
cmlAddTorsion <#cmltor>(torsion, id, atomRef1, atomRef2, atomRef3, atomRef4, fmt)
cmlAddEigenvalue <#cmleig>(n, dim, eigvec, eigval, id, title, dictRef, fmt)
CMLComa routines (Condensed Matter)¶
cmlAddLattice <#comalat> - write a complete lattice element
cmlAddProperty <#comapro> - write a complete property element, containing scalar, array (vector) or matrix value (i.e. it has several interfaces)
cmlAddParameter <#comapar> - adds a complete CML <parameter> element
Subroutine Guide
stmAddStartTag(xf, name, id, title, dictref)
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
name
tag name
character(len=*)
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
stmAddScalar(xf, value, id, title, dictref, type, fmt) <>
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
value
the scalar value
character(len=*) | integer | real*8 | real*4
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
fmt
format for reals
character(len=*)
yes
f8.3
stmAddArray(xf, nvalue, array, id, title, dictref, type|units, delim|fmt) <>
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
nvalue
length of array
integer
no
array
the array
character(len=*) | integer | real*8 | real*4
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
fmt
format for reals
character(len=*)
yes
f8.3
stmAddMatrix(xf, nrows, ncols, dim, matrix, id, title, dictref, units, fmt) <>
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
nrows
number of rows
integer
no
ncols
number of columns
integer
no
dim
fastest dimension
integer
no
matrix
the matrix
character(len=*) | integer | real*8 | real*4
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
fmt
format for reals
character(len=*)
yes
f8.3
stmAddTriangle(xf, nvalue, array, id, title, dictref, units, fmt) <>
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
nvalue
length of array
integer
no
array
the array
character(len=*) | integer | real*8 | real*4
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
fmt
format for reals
character(len=*)
yes
f8.3
stmAddError(xf, msg, id, title, dictRef) <>
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
msg
length of array
character(len=*)
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
stmAddMessage(xf, msg, id, title, dictRef) <>
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
msg
length of array
character(len=*)
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
stmAddWarning(xf, msg, id, title, dictRef) <>
argument
role
type
optional
default
xf
xml filehandle
type(xmlf_t)
no
msg
length of array
character(len=*)
no
id
unique id
character(len=*)
yes
title
tag description
character(len=*)
yes
dictref
dictionary reference
character(len=*)
yes
cmlAddMolecule(xf, natoms, elements, coords, style, id, title, dictref, fmt) <>
argument |
role |
type |
optional |
default |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
natoms |
number of atoms |
integer |
no |
|
ele ments(natoms) |
list of atomic symbols |
cha racter(len=2) |
no |
|
coords(3, natoms) |
atomic coordinates |
real*8 | real*4 |
no |
|
style |
(x3 | xFrac | xyz3 | xyzFrac) |
cha racter(len=*) |
yes |
x3 |
id |
unique id |
cha racter(len=*) |
yes |
|
title |
tag description |
cha racter(len=*) |
yes |
|
dictref |
dictionary reference |
cha racter(len=*) |
yes |
|
fmt |
format for reals |
cha racter(len=*) |
yes |
f8.3 |
cmlAddAtom(xf, elem, id, charge, hCount, occupancy, fmt) <>¶
argument |
role |
type |
optional |
default |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
elem |
atomic symbol |
character(len=2) |
yes |
|
id |
unique id |
character(len=*) |
yes |
|
charge |
formal charge |
integer |
no |
|
hCount |
hydrogen count |
integer |
no |
|
occupancy |
site occupancy |
real*8 | real*4 |
no |
|
fmt |
format for occupancy |
character(len=*) |
yes |
f8.3 |
cmlAddCoordinates(xf, x, y, z, style, fmt) <>¶
arg ument |
role |
type |
opt ional |
de fault |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
x |
x coordinate in cartesian format |
real*8 | real*4 |
no |
|
y |
y coordinate in cartesian format |
real*8 | real*4 |
no |
|
z |
z coordinate in cartesian format |
real*8 | real*4 |
yes |
|
style |
(x3 | xFrac | xyz3 | xyzFrac | xy2) |
char acter(len=*) |
yes |
x3 |
fmt |
format for coordinates |
char acter(len=*) |
yes |
f8.3 |
cmlAddcrystal(xf, a, b, c, alpha, beta, gamma, id, title, dictref, lenunits, angunits, fmt) <>¶
argument |
role |
type |
optional |
default |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
a |
lattice parameter a |
real*8 | real*4 |
no |
|
b |
lattice parameter b |
real*8 | real*4 |
no |
|
c |
lattice parameter c |
real*8 | real*4 |
no |
|
alpha |
lattice angle alpha |
real*8 | real*4 |
no |
|
beta |
lattice angle beta |
real*8 | real*4 |
no |
|
gamma |
lattice angle gamma |
real*8 | real*4 |
no |
|
lenunits |
units for lattice parameters |
character(len=*) |
yes |
angstrom |
angunits |
units for lattice angles |
character(len=*) |
yes |
degree |
id |
unique id |
character(len=*) |
yes |
|
title |
tag description |
character(len=*) |
yes |
|
dictref |
dictionary reference |
character(len=*) |
yes |
|
fmt |
format for reals |
character(len=*) |
yes |
f8.3 |
cmlAddMetadata(xf, name, content, conv) <>¶
argument |
role |
type |
optional |
default |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
name |
name (eg author) |
character(len=*) |
no |
|
content |
value (eg Jon Wakelin) |
character(len=*) |
no |
|
conv |
a convention |
character(len=*) |
yes |
cmlAddLattice(xf, cell, units, title, id, dictref, conv, lattType, spaceType) <>¶
argument |
role |
type |
optional |
default |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
cell(3,3) |
the lattice vectors |
real*8 | real*4 |
no |
|
units |
units for lattice vectors |
character(len=*) |
yes |
|
title |
tag description |
character(len=*) |
yes |
|
id |
unique id |
character(len=*) |
yes |
|
dictref |
dictionary reference |
character(len=*) |
yes |
|
conv |
a convention |
character(len=*) |
yes |
f8.3 |
lattType |
lattice type (primitive |full) |
character(len=*) |
yes |
|
spaceType |
space type (real | reciprocal) |
character(len=*) |
yes |
cmlAddProperty(xf, property, nvalues, ncols, nrows, dim, id, title, conv, dictref, ref, units, fmt) <>¶
argument |
role |
type |
optional |
default |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
property |
a scalar, array or matrix property. Yes it takes all three, but see next three arguments. |
ch arcter(len=*) | integer | real*8 | real*4 |
no |
|
nvalue |
number of value for vector |
integer |
no if writing a vector |
|
ncols |
number of rows for matrix |
integer |
no if writing a matrix |
|
nrows |
number of rows for matrix |
integer |
no if writing a matrix |
|
dim |
number of the fastest growing dimension in the matrix |
integer |
yes |
|
id |
unique id |
cha racter(len=*) |
yes |
|
title |
tag description |
cha racter(len=*) |
yes |
|
conv |
a convention |
cha racter(len=*) |
yes |
|
dictref |
dictionary reference |
cha racter(len=*) |
yes |
|
ref |
refernce to an atom (via the atom ‘id’ attribute) |
cha racter(len=*) |
yes |
|
units |
units for the property |
cha racter(len=*) |
yes |
|
fmt |
format for reals |
cha racter(len=*) |
yes |
f8.3 |
cmlAddParameter(xf, value, name, id, title, conv, cons, dictref, ref, role, units, fmt) <>¶
argument |
role |
type |
optional |
default |
---|---|---|---|---|
xf |
xml filehandle |
type(xmlf_t) |
no |
|
value |
the parameter |
charcter(len=*) | integer | real*8 | real*4 | logical |
no |
|
id |
unique id |
character(len=*) |
yes |
|
title |
tag description |
character(len=*) |
yes |
|
conv |
a convention |
character(len=*) |
yes |
|
cons |
a constraint |
character(len=*) |
yes |
|
role |
the role of the parameter |
character(len=*) |
yes |
|
dictref |
dictionary reference |
character(len=*) |
yes |
|
ref |
refernce to an atom (via the atom ‘id’ attribute) |
character(len=*) |
yes |
|
units |
units for the parameter |
character(len=*) |
yes |
|
fmt |
format for reals |
character(len=*) |
yes |
f8.3 |