-
Notifications
You must be signed in to change notification settings - Fork 16
SQ2.50 Procedural Framework: Part 5
The final phase of Loop A "cleans up" the 232Th/238U calculations in the Perm2 and Perm4 cases (i.e. where piNumDauPar = 2): the subroutine ThUfromA1A2 can now be executed properly, because WtdMeanA1 and WtdMeanA2 now both exist. Unfortunately, this entails some really nasty code, much of which looks (to my eye) obsolete and pointless. But I can't be certain, so I have documented it below.
Recalling that pbHasTh is TRUE if the run-table contains at least one peak with mass 232, 248 or 264 (which it usually does, for geochronology), and pbHasU is TRUE if the run-table contains at least one peak with mass 238, 254 or 270 (which it almost always will, for geochronology), then the code for the Perm2 and Perm4 scenarios proceeds (from the end of Part 4) as follows:
If (pbHasTh = TRUE) AND (pbHasU = TRUE) AND (piNumDauPar = 2)
--Then replace the dummy values of "1" for 232Th/238U with true formulae
If (pbStd = TRUE) AND (piNumDauPar = 2)
Set CalibConst1 = frSr(1 + plaFirstDatRw[1], [WtdMeanA1].Column, Lrw)
The previous line looks like it contains a bug: this frSr statement defines a one-column cell-range containing the calibration-constant values for the primary calibration constant (i.e. 206Pb/238U for Perm2, 208Pb/232Th for Perm4), but the use of "1 + plaFirstDatRw[1]" means that the cell-range excludes the first row! Having stepped through the code, I am convinced this is a slip, and that the "1 +" should be deleted. Let's leave it in place for now, because with respect to our SQUID-books of record, it's "what SQUID 2.50 does".
The next line of code invokes a SQUID 2.50 subroutine which Ludwig named "Clean", which is a bit confusing, because Microsoft VBA has a function of the same name, which does a different thing. For the sake of this documentation (and to allay my own considerable confusion!), I have renamed Ludwig's subroutine "SQUIDClean". In addition to the first two arguments (which are the input and output cell-ranges) and the third argument (which enumerates the "clean" data-rows), SQUIDClean has 7 optional Boolean arguments, the first 6 of which are assigned their default values. The last ("AddStrikeThru") is set to TRUE, where its default is FALSE:
SQUIDClean CalibConst1, CleanedConst, 0, , , , , , , TRUE
--subroutine documented separately
In this context, SQUIDClean takes the input range of 20 (not 21!) primary calibration-constant values (remember that the first row is ignored owing to the bug described above), and "cleans" them to remove those that have already been excluded via the application of Strikethrough font as part of the WtdMeanAcalc subroutine earlier. CleanedConst comprises the 15 primary calibration-constant values that survive the cleaning process.
AvCalibrConst = Average( CalibConst1 )
If CleanedConst.Count < CalibConst1.Count --these "counts" refer to number of rows
p = 12
Else
p = 0
End If
End If --(pbStd = TRUE) AND (piNumDauPar = 2)
I do not understand the relevance of the parameter p. As far as I can see, its sole purpose is to force multiple iterations of the subroutine ThUfromA1A2 in the code below, but the benefit of these iterations remains unclear, as I can't see any place that the value of p or its dependents actually influences the input to ThUfromA1A2... The code continues:
Do
p = p + 1
AvCalibrConst0 = AvCalibrConst
For DatRow = Frw To Lrw
ThUfromA1A2 pbStd, (DatRow), FALSE
--because WtdMeanA1 and WtdMeanA2 now exist
--subroutine previously documented (Procedure Part 3)
Next DatRow
Recalculate
If (p > 12) OR ( (pbStd = TRUE) AND (piNumDauPar = 2) ) = FALSE
Exit Do
End If
AvCalibrConst = Average( CalibConst1 )
vTmp = 100 * Abs( (AvCalibrConst - AvCalibrConst0) / AvCalibrConst )
Loop Until (p > 1) AND (vTmp < 0.001)
I can't see any point to the iterated calculation of AvCalibrConst and vTmp. As far as I can see, the sole benefit of the above Do... loop is the invocation of subroutine ThUfromA1A2 for Perm2 and Perm4 Tasks, and even there, the subroutine need only be invoked once. The code proceeds by calculating ["ppmTh"] for the Perm2 and Perm4 cases:
If (piaPpmUcol[-pbStd] > 0) AND (piaPpmThcol[-pbStd] > 0)
--i.e. if the StandardData (or SampleData) sheets has columns
--for BOTH "ppmU" and "ppmTh":
Term1 = " = ["232Th/238U"] * ["ppmU"] * 0.9678 "
--"magic number" 0.9678 documented below
--now use Term1 to populate column ["ppmTh"] for Perm2/Perm4
PlaceFormulae Term1, Frw, {ppmTh-column}, Lrw
End If --(piaPpmUcol[-pbStd] > 0) AND (piaPpmThcol[-pbStd] > 0)
The "magic number" 0.9678 (4 decimal places) is hard-coded into the SQUID 2.50 code, which is a bit naughty because it actually is actually the product of several physical "constants" related to the masses and isotopic abundances of Th and U. Essentially it represents the product:
("Atomic mass of 232Th"/"Atomic mass of 238U") * ( ("238U"/"AllNaturalU") / ("232Th"/"AllNaturalTh") )
The atomic masses of 232Th and 238U are immutable physical properties: 238U comprises 92 protons and 146 neutrons by definition, so its atomic mass is 238 by definition. Similarly, 232Th is defined as the isotope containing 90 protons and 142 neutrons, so its atomic mass of 232 is an intrinsic property.
However, the ratios ("238U"/"AllNaturalU") and ("232Th"/"AllNaturalTh") have more scope for variation, and should certainly be modelled separately. Having scoured the internet and the literature, I believe Ludwig explicitly assumed exact values (4 decimal places) of 0.9928 for the former and 1.0000 for the latter. Both are perfectly reasonable values, but ought to be identified as explicit physical "constants" constraining the arithmetic. So the magic number 0.9678 represents the product:
(232/238) * (0.9928/1.0000)
rounded to 4 decimal places. For the present, we ought to retain the hard-coded "magic number" (0.9678). The If clause concludes with some tidying up for Standards, basically assembling a string of index-numbers of the Rejected calibration-constan:
If pbStd = TRUE
--{Compile and report a list of index-numbers of Rejected calibration-constant values,
--for each set of calibration constants}
End If
End If --(pbHasTh = TRUE) AND (pbHasU = TRUE) AND (piNumDauPar = 2)
--i.e. End of If that commenced Part 5
Loop Until (pbStd = FALSE) OR (pbStdsOnly = TRUE) --End of Loop A that commenced at start of **PART 1**
This concludes the major "Standard-Sample" loop that has spanned Procedural Framework Parts 1-5.
The remainder of the master "SquidfGeochron" routine will be documented in Part 6.