Skip to content

A web service implementation of the online exposure age calculator

September 26, 2014

What is this?

This posting is to point out the existence of a new interface to the online exposure age calculator. This is a “web service” implementation, which means that when one submits an HTTP request, the server returns only a compact representation of the calculator results in a structured data format, rather than as a complete web page. It’s not really compliant with formal web service protocols (except possibly by accident); basically it just responds to a HTTP GET request with an XML object rather than a web page. The idea here is that other software can simply query the online exposure age calculator to obtain an exposure age, rather than doing the calculations itself. The purpose of building this is to enable a database project for Antarctic exposure age data that I am working on and that will, presumably, be described here in a subsequent post.

Update: The directions below have changed due to an upgrade to the online exposure age calculator. The web service implementation is no longer available for the version 2.x family of calculators. It is only available for the version 3 calculator.

Specifically, it works like this:

1. Submit a HTTP “GET” request to the calculator Octave server at the following address:

The GET request should have the following fields:



resultType=long (for non-time-dependent and time-dependent scaling)

resultType=short (for non-time-dependent only)


The ‘text_block’ field is simply the text string that you would paste into the input window of the online calculator, with appropriate HTML escape strings (these are the %20 character strings to denote spaces) inserted. Multiple-line input should be supported. Version 3 input is preferred but version 2 input should still work; this example uses version 2 input format.

So a complete URL would look like:

The response to this will be an XML object that looks like:

	<diagnostics>No diagnostics</diagnostics>
		<validate>validate_v2_input.m - 3.0-dev</validate>
		<muons>1A, alpha = 1</muons>

Basically this is an XML representation of the exposure ages (the tNNxxxx_XX elements, where NN is the nuclide, e.g., 10 for Be-10, etc., xxxx is the mineral, and XX is the scaling method), the internal uncertainties (the delt…int… elements), and the external uncertainties (the delt…ext… elements). The code attempts to intelligently pass errors in the “diagnostics” element, so if you make an input format error you should get exposure ages of zero with some information in the diagnostics element about what happened.

Note that this format is slightly changed from what was in the version 2 implementation.

Some important features:

You can also submit optional fields to force use of non-default production rates. Example:


As in the web-page implementation, you can only submit non-default production rates for one nuclide at a time. Theoretically it should manage the situation where you only supply calibrated production rates for some of the scaling methods by using default production rates for the others. Note that this deviates from the general policy of not allowing users to randomly enter arbitrary production rates, but the thinking is that if you have gotten far enough into this that you are coding your own interface to the server, you understand the concept that a reference production rate is a scaling-scheme-specific representation of a calibration data set and not an independent parameter that you get to futz with as you like.

Other comments:

The code is basically the same as in the rest of the version 3 online exposure age calcuator. It should give the same results.

This has been reasonably well tested and although I’ve attempted to catch formatting errors that are reasonably likely to happen, it is likely that there are some formatting errors that will crash it, in which case there will be no response.

If you want to develop something to use this, especially if it is high volume, you should talk to me about it.

In general, if you make use of this to do anything useful, I would appreciate your letting me know.

Please avoid embedding URLs for this service in web pages, which would create unnecessary search engine traffic on the web server.

What can you do with this?

You can write dynamic web pages that calculate exposure ages online using data generated from a database. That’s what I’m trying to do.

You can access the exposure age calculator  directly from within MATLAB or other software without cutting and pasting into the web page or running the code locally. This seems potentially useful. Of course, you need a live internet connection.

You can write iPhone apps that calculate exposure ages. This is not high on my priority list.

Note that you could have done this already using the existing interface with POST requests, but you would have to do much more work to parse the resulting web pages. All this new interface does is simplify things a bit and make it work with XML parsers.

Here are some examples.

Here is an example of how one might use this in MATLAB, using the ‘urlread’ function.

Note that this uses the obsolete version 2 API, so is now obsolete. You’ll have to change it to follow the revised instructions above. But it should give the general idea. 

% Utilizes online exposure age calculator interface

% Enter data
sample_name = 'PH-1'
lat = 41.3567;
long = -70.7348;
elv = 91;
atm = 'std';
thick = 4.5;
rho = 2.7;
shielding = 1;
erate = 8e-5;
N10 = 123500;
delN10 = 3700;
std10 = 'KNSTD';
N26 = 712400;
delN26 = 31200;
std26 = 'KNSTD';

% Assemble fields for GET request 

mlmfile = 'al_be_age_many_v22_ws';

text_block = [sample_name ' ' sprintf('%0.4f',lat) ' ' sprintf('%0.4f',long) ' ' sprintf('%0.0f',elv) ];
text_block = [text_block ' ' atm ' ' sprintf('%0.1f',thick) ' ' sprintf('%0.2f',rho) ' ' sprintf('%0.4f',shielding)];
text_block = [text_block ' ' sprintf('%0.2e',erate) ' ' sprintf('%0.0f',N10) ' ' sprintf('%0.0f',delN10) ' ' std10];
text_block = [text_block ' ' sprintf('%0.0f',N26) ' ' sprintf('%0.0f',delN26) ' ' std26];

% Specify URL
ws_url = '';

% Use urlread to query exposure age server and get XML data
xmldata = urlread(ws_url,'get',{'mlmfile',mlmfile,'text_block',text_block});

% Use lame regexp calls to parse XML because the MATLAB XML parser appears
% to operate only on files. 
s.t10St = regexp(xmldata,'<t10St>([\d]*)</t10St>','tokens');
s.int10St = regexp(xmldata,'<delt10_int_St>([\d]*)</delt10_int_St>','tokens');
s.ext10St = regexp(xmldata,'<delt10_ext_St>([\d]*)</delt10_ext_St>','tokens');
s.t10Lm = regexp(xmldata,'<t10Lm>([\d]*)</t10Lm>','tokens');
s.int10Lm = regexp(xmldata,'<delt10_int_Lm>([\d]*)</delt10_int_Lm>','tokens');
s.ext10Lm = regexp(xmldata,'<delt10_ext_Lm>([\d]*)</delt10_ext_Lm>','tokens');
s.t26St = regexp(xmldata,'<t26St>([\d]*)</t26St>','tokens');
s.int26St = regexp(xmldata,'<delt26_int_St>([\d]*)</delt26_int_St>','tokens');
s.ext26St = regexp(xmldata,'<delt26_ext_St>([\d]*)</delt26_ext_St>','tokens');
s.t26Lm = regexp(xmldata,'<t26Lm>([\d]*)</t26Lm>','tokens');
s.int26Lm = regexp(xmldata,'<delt26_int_Lm>([\d]*)</delt26_int_Lm>','tokens');
s.ext26Lm = regexp(xmldata,'<delt26_ext_Lm>([\d]*)</delt26_ext_Lm>','tokens');
% Convert to numbers; for loop accommodates multiple samples
for a = 1:length(s.t10St);
    n.t10St(a) = str2num(char(s.t10St{a}(1)));
    n.t10Lm(a) = str2num(char(s.t10Lm{a}(1)));
    n.t26St(a) = str2num(char(s.t26St{a}(1)));
    n.t26Lm(a) = str2num(char(s.t26Lm{a}(1)));
    n.int10St(a) = str2num(char(s.int10St{a}(1)));
    n.int10Lm(a) = str2num(char(s.int10Lm{a}(1)));
    n.int26St(a) = str2num(char(s.int26St{a}(1)));
    n.int26Lm(a) = str2num(char(s.int26Lm{a}(1)));
    n.ext10St(a) = str2num(char(s.ext10St{a}(1)));
    n.ext10Lm(a) = str2num(char(s.ext10Lm{a}(1)));
    n.ext26St(a) = str2num(char(s.ext26St{a}(1)));
    n.ext26Lm(a) = str2num(char(s.ext26Lm{a}(1)));
    str = ['Sample ' int2str(a) '-- t10St: ' int2str(n.t10St(a)) ' +/- ' int2str(n.int10St(a)) '(' int2str(n.ext10St) ')'];
    str = [str ' t10Lm: ' int2str(n.t10Lm(a)) ' +/- ' int2str(n.int10Lm(a)) '(' int2str(n.ext10Lm(a)) ')'];
    str = [' t26St: ' int2str(n.t26St(a)) ' +/- ' int2str(n.int26St(a)) '(' int2str(n.ext26St) ')'];
    str = [str ' t26Lm: ' int2str(n.t26Lm(a)) ' +/- ' int2str(n.int26Lm(a)) '(' int2str(n.ext26Lm) ')'];

Here is an example of how one might use this in a Python script, using Python modules for getting URLs and parsing XML. This is pretty lame because I am not great at Python. This uses the option to pass nonstandard production rates.

Note that this also is obsolete and uses the version 2 API. You’ll have to change it to follow the version 3 instructions above. But it should give the general idea. 


import urllib2
import urllib
import xml.etree.ElementTree as xmlET

# Make up a text block
text_block = "PH-1 41.3567 -70.7348 91 std 4.5 2.70 1.0000 8.00e-05 123500 3700 KNSTD 712400 31200 KNSTD"

# Form URL
this_url_string =     ("" \
    + "text_block=" + urllib.quote(text_block) \
    +  "&P10_St=3.93089&delP10_St=0.18857" \
    + "&P10_Lm=3.87397&delP10_Lm=0.18737")

# Read response
response = urllib2.urlopen(this_url_string)

# Parse XML
tree = xmlET.fromstring(

# Print results
print "t10St (yr) = " + tree.findall("./exposureAgeResult/t10St")[0].text  + \
    " +/- " + tree.findall("./exposureAgeResult/delt10_int_St")[0].text + \
    " (" + tree.findall("./exposureAgeResult/delt10_ext_St")[0].text + ")\n"
print "t26St (yr) = " + tree.findall("./exposureAgeResult/t26St")[0].text  + \
    " +/- " + tree.findall("./exposureAgeResult/delt26_int_St")[0].text + \
    " (" + tree.findall("./exposureAgeResult/delt26_ext_St")[0].text + ")\n"
print "t10Lm (yr) = " + tree.findall("./exposureAgeResult/t10Lm")[0].text  + \
    " +/- " + tree.findall("./exposureAgeResult/delt10_int_Lm")[0].text + \
    " (" + tree.findall("./exposureAgeResult/delt10_ext_Lm")[0].text + ")\n"
print "t26Lm (yr) = " + tree.findall("./exposureAgeResult/t26Lm")[0].text  + \
    " +/- " + tree.findall("./exposureAgeResult/delt26_int_Lm")[0].text + \
    " (" + tree.findall("./exposureAgeResult/delt26_ext_Lm")[0].text + ")\n"
print format(tree[1].tag) + ": " + format(tree[1].text) + "\n"





Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: