GumCalc
|
The first version of GumCalc was developed using Borland C++, but all the recent work has been done using Microsoft Visual C++. The Visual C++ version provides a better user interface and more features than the original version. The newer development system also provides a more standard version of the C++ language and standard library.
The links below allow you to download an installer package, Gum Calculator.msi, which will install GumCalc and required files on your computer. The 2009 version has a couple of known bugs. The bugs in the 2011 (and now 2012) versions, which were produced using Visual Studio 2008 and Windows 7, are being eliminated as quickly as I find them (and likely being replaced by new bugs as I continue working).
Download 2009-09-06 version
Download 1.0 beta (2012-01-26)
If you don’t want to install GumCalc, or can’t, you can just copy the contents of this compressed folder to a folder of your choice and run the program from there. You may not be able to configure the program completely, but it should run and produce results.
Please provide feedback if you find bugs. GumCalc has grown into a large, complicated project, and thorough testing has become more than one person can easily handle. There are many features large and small, and I am occasionally surprised by a bug in a feature I seldom use or a bug that occurs only in an unusual situation. The cause may be nothing more than a typo or an overlooked line of code, but the effect may be a program crash.
GumCalc is an automated measurement-modeling tool. The most important feature, which makes it different from most other calculation tools, is its ability to propagate measurement uncertainty automatically. A second unusual feature is its ability to propagate the dimensions of measurable quantities. These two features together provide the developer’s rationale for calling it a “measurement-modeling tool” rather than a calculator program.
Note: Although GumCalc lets you create measurement models, you can use it every day for calculations and unit conversions without ever creating a model at all. You just type an expression in the Evaluation window and click a button to evaluate it. There is an option to specify the unit of measurement for the result.
The program allows you to specify a measurement model as a collection of definitions of variables and functions. Each model may be saved in an electronic file and reopened and edited later. GumCalc also provides a capability to “run” a model on imported sets of data, with the values of specified variables being obtained from import files in CSV format. When the model runs, it can also export results to CSV files, which presumably can then be uploaded to other software systems or even a LIMS.
Model variables come in four types:
Measurement uncertainty is introduced into a model via the input quantities. The user specifies the value and uncertainty of an input quantity by specifying a type of probability distribution and the values of the parameters of the distribution. When other results (output quantities) are calculated from input quantities, they acquire uncertainty too. The uncertainty of an output quantity (combined standard uncertainty) is automatically determined by uncertainty propagation.
The creator of a model can define variables and functions in any order, without worrying about the order of evaluation. The application itself determines the evaluation order that is needed to obtain meaningful results. It is possible for the model creator to create circular definitions, but GumCalc will detect any circularity without entering an infinite recursion, which would crash the program.
Dimensions in GumCalc are built up from the seven base quantities of the International System of Units (SI). The seven base units of the SI are “hard-coded” in the program, while all other units are defined in XML setup files. The unit prefixes of the SI are also hard-coded in the program, and the unit setup files specify which units can be used with prefixes.
GumCalc is directly descended from a primitive DOS-based ancestor called “LabCalc,” which I developed at the USEPA National Air and Radiation Environmental Laboratory about 1994. I never enjoyed using electronic spreadsheet programs to automate typical laboratory calculations; so, I designed LabCalc to let the user define a measurement model by typing a set of equations that defined variables and functions, each identified by name. A model could be developed conceptually as a set of written equations (e.g., in Word, WordPerfect, or TEX) and then translated easily into LabCalc’s language, one equation at a time. Although LabCalc propagated uncertainty automatically, it did not propagate the dimensions of quantities. It provided some features for unit conversions, which were useful but hardly breathtaking.
Since LabCalc was DOS-based and command-line oriented, almost nobody but the developer ever took advantage of its capabilities.
During the late 1990s I borrowed the concepts I had used to provide automatic uncertainty propagation in LabCalc (a standalone application), and created C++ library classes and functions to allow other software systems to propagate uncertainty automatically. The classes were designed so that a programmer could write code to calculate the result of a measurement and let the library propagate uncertainty in the background. Eventually I presented this library at the 2003 Radiobioassay and Radiochemical Measurements Conference (RRMC) in Jackson, WY, and made the source code available for free download at this web site. (In 2007 the old code was removed from public view, because I had a newer, better implementation.)
For several years, while I was a member of the MARLAP workgroup, Dr. Carl Gogolak, another workgroup member, occasionally suggested that LabCalc be rewritten as a Windows GUI application, or that I develop a GUI application to wrap around the class library described at the RRMC. I agreed with Carl in principle, but I knew that either task would be less simple than it sounded. From time to time, my boss, Dr. John Griggs, who chaired the MARLAP workgroup, also said that new software would be needed to help radiochemistry labs implement MARLAP’s guidance. The MARLAP manual was finally approved and released in 2004; and in late 2004, I started the GumCalc project. GumCalc is intended to be what LabCalc always wanted to be when it grew up.
GumCalc began as a Windows XP project, although I’ve seen it run under Vista too. In early 2010, I acquired a Windows 7 computer (64-bit) and installed GumCalc on it without any obvious problems. I’ve been running it on that computer ever since. Windows 7 has created some problems with the original location of the GumCalc library files, which may make them effectively read-only, but you can move the files to a new folder if you need to update them. The 2011/2012 versions install the library files in a folder of your choice.
In February and March 2011, I made the leap from 8-bit characters (char) to 16-bit characters (wchar_t). I prefer a serif font like Times New Roman when printing mathematical symbols, but the current version of that font in Windows does not provide all the Unicode characters I want to use. So, for now at least, I am switching to Arial Unicode MS for printing (2011-03-19). Sometime in the future I hope to provide a better math font for the ordinary characters and use Arial Unicode MS only for special characters that may not print correctly without it.
In October 2011, I made major changes in the date-parsing algorithms. The old parser was working reliably but I was afraid to tinker with it because of its complexity — a consequence of rapid prototyping and the passage of time. So, I scrapped much of that code and replaced it with something that should be easier to maintain. The new approach allows me to add more features, which I have done. The downside is that more testing is needed to verify that I haven’t broken some part of it.
Note: I’ve found one break so far, in an apparently unrelated feature that I don’t promote and seldom use: the subscript operator for strings, vectors, and matrices. The bug was caused by an undetected class naming conflict and has been corrected (2012-01-26 build).
In November and December 2011, I tried to make a final push to complete everything I had planned for version 1.0. (Yes, finally, after seven years of intermittent work on the project, and partly motivated by Ken Inn’s advertising the program at the RRMC, I decided it was time to finish it.) The last required but still missing feature had been a user interface for editing the constant library. That interface now exists (under Tools | Edit constants…). I also tried to fix a lot of the little annoying things that had not been high priorities before. For example I hope that all the accelerator keys now work in all the contexts where users expect them. I also couldn’t resist implementing some of the features that I had planned for later versions of the program. The most significant of these is a pop-up list that appears as soon as you start typing an identifier in an expression. The list contains all the currently available constants, variables, functions, and parameters; and it highlights the first one that matches the characters you have typed. When this pop-up list appears you can either keep typing or just select the identifier you want from the list. A similar pop-up list of escape sequences for Unicode characters appears in most edit controls when you start typing a sequence starting with an ampersand (&).
I tested the pop-up lists extensively in a couple of places in the program, barely tested them in a couple of others, and published the program here. I later found the feature to be a nuisance as implemented in some of the environments I hadn’t tested well, but the current build should correct those problems.
For some time I had thought about providing “inline” uncertainty functions, which create input estimates in the middle of an expression without the need for a model. I thought it would be easy to do, but I focused on other things instead. In December 2011, I thought about this idea a little more and realized that for many would-be casual users, those inline uncertainty functions would provide a lot of “bang for the buck” — i.e., a lot of benefit for them at the cost of very little effort on my part. So, the newest version of the program provides such functions (N, Rect, Tri, Trap, U, and Poi). To make it easier to build up large expressions using these functions, I increased the size of the Expression field in the Evaluation window. It is now a multi-line edit control with a scrollbar. A casual user might use this window and nothing else in the program.
As always, new features probably mean new bugs, but since the new year (2012) began my focus has been on eliminating bugs and polishing existing features rather than adding new features. I am also working to make the help system more complete.
GumCalc now has all of the features envisioned for version 1.0, including:
Ideas for future work after version 1.0 include:
I really want a better user interface (item 1), and I have some ideas for the design. Items 2–4 would also be nice to have.
Although it is listed last, providing built-in functions to calculate ingrowth factors with uncertainties is appealing. The functions would probably be called decayP and decayA, and they would calculate decay/ingrowth factors based on probability (or atoms) and activity, respectively. There would also be overloaded versions for average decay and ingrowth factors during a counting interval. Note that a function for calculating simple decay factors (decay) is already included, since it does not require a new database.
A few other user-friendly interface features will also be added. For example there will be a tool to search a model for occurrences of specified identifiers or text strings. The current version already implements mouse-over tooltips for components of mathematical expressions. It also matches parentheses and other grouping symbols automatically as you type (by color-highlighting both of the paired symbols) and by request (by selecting the matching symbol when you select one of a matched pair and type Ctrl-]).
I also intend to update many of the nuclide half-lives. You can wait for me to do it or you can do it yourself. I downloaded a large file of nuclide data from the National Nuclear Data Center years ago and did not update it again. Only recently have I started manually updating half-lives using data from Laboratoire National Henri Becquerel (www.nucleide.org).
GumCalc has some aspects that may seem odd on first encounter. Many of us are accustomed to performing a series of calculations with numbers, using mathematical functions such as exp, log, or sin, without worrying about the units of measurement till the final result is obtained. Since GumCalc propagates the dimensions of quantities step by step as it calculates the results of these functions, it must enforce some restrictions on the values of the arguments.
Since the dimension of a quantity is a product of powers of the seven “base dimensions,” it makes sense to raise a quantity x to a power or take its square root, but it makes no metrological sense to say exp(x), log(x), or sin(x) unless x is dimensionless. This does not mean that x cannot be expressed in some unit of measurement, but the unit must be a dimensionless unit, such as the radian, degree, or percent.
Similar observations can be made about raising a quantity y to the power x. The expression yx makes no sense unless x is dimensionless.
One may encounter expressions of this sort in the literature, but they make sense only if the unit of measurement is specified. When an equation is written in terms of the numerical values of quantities relative to specified units, all the variables in the equation become dimensionless and anything goes. GumCalc on the other hand allows one to write equations in terms of the values of the quantities, not just the numerical values, and this fact requires one to be more careful. It also helps the software detect logical errors in the user’s work.
Looking at it another way, writing “yx where x is the mass of the residue in milligrams” is equivalent to writing “yx/(1 mg) where x is the mass of the residue.” The latter version makes it clear that the exponent is a dimensionless ratio. It would be nonsensical to say “yx where x is the mass of the residue” without specifying the unit of measurement for x.
A second issue is the fact that GumCalc cannot distinguish between different types of quantities unless they have different dimensions. For example, activity, count rate, and frequency are three different types of quantities and are usually expressed in different units. However, since all three have the dimension of reciprocal time, T−1, GumCalc cannot distinguish one type from the other, and it allows you to express any of these quantities in any unit of measurement that has the dimension of reciprocal time. For example, you can convert a frequency from hertz (Hz) to becquerels (Bq), and GumCalc won’t detect the error. Of course GumCalc will not let you use a unit with the wrong dimension for the quantity being expressed.
One other quirk exists because of the software’s need to compare dimensional exponents without rounding error when adding or subtracting quantities. To eliminate rounding error, GumCalc requires that dimensional exponents be rational numbers, not floating-point numbers. So, a quantity that is not dimensionless cannot be raised to a power that isn’t rational. Therefore, if the dimension of x is not unity, you can evaluate x3/5 but not x0.6, because GumCalc obtains a rational value for the expression 3/5 and a floating-point value for the expression 0.6. With an enhanced numeric parsing function, this limitation might be partially eliminated, so that the program would recognize 0.6 as equivalent to 3/5, but the requirement that dimensional exponents be rational is likely to remain.
The versions of GumCalc produced since 2010 provide the ability to include arbitrary positive numerical factors in a unit expression, allowing expressions like pCi/100 cm2. I’m not sure how kosher this is, but it is a common practice when reporting swipe measurement results in the U.S. This feature raises new questions about the syntax of unit expressions, since an expression of the form a2/3 b could reasonably be interpreted now as either a2/3 b or a2 / (3 b). The parser currently uses the first of these interpretations, but I recommend that you use parentheses to eliminate any possible ambiguity (either a(2/3) b or a2/(3 b)).
In 2011, I implemented absolute temperatures in the program with a choice of temperature scales. (Note that I have not implemented either “Celsius temperature” or “Fahrenheit temperature” as a new type of quantity.) To specify an absolute temperature, you can use any of the functions celsius, fahrenheit, kelvin, or rankine. Since these functions return absolute temperatures, some arithmetic operations are undefined on the results. The only operations currently guaranteed to be provided are certain types of addition and subtraction. Although it makes sense to multiply or divide a temperature by a numerical factor, it may be confusing to many users. For example what result do you expect if you type the expression celsius(4) * 2? Since celsius(4) is equivalent to kelvin(277.15), the correct result is 554.3 K, or 281.15 °C, not 8 °C. I may decide that to avoid confusion, multiplication and division of these temperatures should not be allowed.
I’m also reconsidering the decision to have the celsius and fahrenheit functions return absolute temperatures instead of Celsius and Fahrenheit temperatures (relative to 0 °C and 0 °F, respectively). The rationale for the original design is that it makes the results from all the new temperature functions comparable, so that subtraction is easy and unit conversions make sense. The downside is that there is a small but noticeable loss of precision when expressing the results relative to 0 °C or 0 °F. Because of this loss of precision, the implementation may change.
Combining automatic uncertainty propagation with “unit propagation” reveals relationships between the two that may not be obvious. In particular, the uncertainty of the result of a measurement depends on the unit of measurement. It should be clear that the numerical value of the uncertainty depends on the unit of measurement, but in fact the actual value of the uncertainty depends on it too.
Why does the uncertainty depend on the unit of measurement? Because measuring a quantity really means determining the ratio of that quantity to another specified quantity — the unit of measurement — and the uncertainty of that ratio depends on the unit. The value of the ratio may be known better for some units than others. For example, if you want the uncertainty of the mass of the prototype kilogram standard, it matters whether the value is expressed in kilograms or unified atomic mass units. If the unit is the kilogram, the uncertainty is exactly zero. If the unit is the unified atomic mass unit, the uncertainty is positive. Conversely, the mass of an atom of carbon-12 in its ground state is known with no uncertainty if it is expressed in atomic mass units, but it has positive uncertainty if it is expressed in kilograms.
Although the uncertainty of a measurement result depends on the unit, the interface that GumCalc presents does not make this fact obvious, because it provides a function u(x) that returns the standard uncertainty of the argument x, and the unit of measurement is not specified. GumCalc can do this only because it implicitly bases all quantities on the International System of Units (SI), which provides a frame of reference in which the concept of the uncertainty is unambiguous.
In GumCalc the expression u(x) returns u({x}) × [x], where [x] is the appropriate SI unit for x (base unit or coherent derived unit) and {x} is the numerical value of x with respect to that unit. When you evaluate the expression x in the Evaluation window, you can specify any appropriate unit for the result, and GumCalc will evaluate the uncertainty properly for the chosen unit. Note: The uncertainty you get may differ from what you would get by evaluating the expression u(x) with the same unit.
The GumCalc icon (a red-green-blue delta) has no significance. It was designed only to be easily recognizable on the desktop.
| Feedback |
top | 26 Jan 2012 Keith |