-
Notifications
You must be signed in to change notification settings - Fork 16
SHRIMP: Sub ParseRawData
[The following is a generalised function, used and reused by SQUID 2.50 on several different occasions during a 'typical' data-reduction. As such, the inputs and outputs of the functions have generalised names. The identities of the specific inputs and outputs are defined when the function is called.]
The subroutine examines, on an analysis-by-analysis basis, the (already-)parsed XML file and extracts 'useful' information such as the spot-label (as string), analysis date and time (as string), analysis date 'only' (as string), analysis 'time only' (as string), the number of mass-stations (integer), and the number of scans (integer). Pending the results of some test, the subroutine then proceeds to the calculations documented in SHRIMP: Step 2. The comment in the SQUID VBA code fort this subroutine reads "Extracts data for a single SHRIMP spot, correcting for background counts; assumes cursor is on the sample-name column & row of the raw data."
In addition to the spot index-number Sp, ParseRawData has a pair of Boolean inputs: FirstPass and IgnoredChangedRunTable. FirstPass is a flag that caters for the fact that although SQUID 'parses' individual sets (and subsets) of analyses multiple times, there are some aspects of this process that need only be done once. IgnoredChangedRunTable is a flag monitoring the number of peaks in the run-table of the analysis in comparison to the number of mass-stations specified in the governing Task, and as long as it remains set to FALSE, everything is all right.
ParseRawData(SpotNumber, FirstPass, IgnoredChangedRuntable, sDate, GetTrim, DelMT, GetTrimSigma)
SpotNumber: Index number of the analysis within the XML file, starting at 1 and assigned chronologically (i.e. SpotNumber = 1 is the first analysis acquired, and all analyses are time-sequenced, irrespective of whether they classify as 'standards' or 'unknowns').
FirstPass: Boolean input which dictates whether the 'once-only' operations of ParseRawData are to be conducted, during this particular invocation.
IgnoredChangedRunTable: Boolean operating effectively as an error-trapping measure. It is usually (perhaps universally) set to FALSE prior to invocation of ParseRawData (and during smooth data-processing, it remains FALSE throughout). It only becomes TRUE if one of a number of 'tests' are failed; these are detailed below.
sDate: A string comprising the comma-separated date and time the analysis was completed, in the form "YYYY-MM-DD, HH24:MI:SS". Default is the blank value "".
GetTrim: Boolean dictating whether or not trim-mass information is collated. Default value is TRUE.
DelMT: Boolean of uncertain purpose; not used in subroutine. Default value is FALSE.
GetTrimSigma: Boolean of uncertain purpose; not used in subroutine. Default value is FALSE.
Values of type String
psSpotName
Values of type Integer
j, k, SpotNpeaks, SpotNscans, Task.Npeaks, SBM_zero_cps
Values of type Double
BackgroundCPS, CalcBkrdCPS, CalcVariance, MeanNetCps, Seconds, StartTime, SumBkrdCPS
Vectors comprising values of type Double
BkrdCPS, count_time_sec, NetCps, TotCps
Arrays comprising values of type Double
AbsNetPkCps, NetPkCps, PkCounts, PkCps, PkFerr, SBMCounts, SBMCps, TrimMass, TrimTime, time_stamp_sec
Arrays comprising values of type String
psaSpotNames, psaSpotDateTime
The function of the subroutine is paraphrased as follows:
If SpotNumber = 0
Exit Sub
End If
psSpotName = psaSpotNames[SpotNumber]
IgnoredChangedRunTable = FALSE
If FirstPass = TRUE
sDate = psaSpotDateTime[SpotNumber]
<<Convert sDate string to an integer number of Seconds since
the commencement of calendar 1990.>>
StartTime = Seconds
End If
<<For SpotNumber, extract SpotDateTime, SpotNpeaks, SpotNscans.>>
The subroutine then runs a series of tests to see whether the analysis meets some fundamental criteria (both in itself, and by reference to the Task in use). If the tests fail, the subroutine exits, or data-processing stops with the offending analysis selected.
If SpotNpeaks <> Task.Npeaks
If FirstPass = TRUE and IgnoredChangedRunTable = FALSE
MsgBox("Run Table changes from " & StR(Task.Npeaks) &
" mass stations to " & StR(SpotNpeaks) & " at spot number "
& StR(SpotNumber) & ". Ignoring all peaks not having the
original Run Table.")
End If
IgnoredChangedRunTable = TRUE
Exit Sub
ElseIf FirstPass = FALSE And (SpotNpeaks < 2 Or Task.Npeaks < 2)
MsgBox("Invalid number of pks obtained when parsing the PD file.")
<<Select offending row, and End.>>
ElseIf SpotNscans < 1
If FirstPass = TRUE
MsgBox("Ignoring spot" & StR(SpotNumber) & " -- fewer than 2 scans.")
--Note the apparent discrepancy between MsgBox and ElseIf criterion:
--both are reproduced verbatim from the VBA code.
End If
IgnoredChangedRunTable = TRUE
Exit Sub
End If
Assuming that the subroutine has not been exited by this point, the remainder of its workings are essentially equivalent to the code previously presented as SHRIMP: Step 2. There are some minor differences (mostly additions), and these are marked in the code-blocks below with triple-asterisks.
For each analysis/fraction, we have thus far generated a matrix of data comprising SpotNscans (= 6 in demo XML) measurements at each of SpotNpeaks (= 10 in demo XML) nuclides, for a total of 60 "peak" measurements. For each of these peaks, the previously calculated values of interest (from SHRIMP: Step 1) can be defined as:
For j = 1 to SpotNscans
For k = 1 to SpotNpeaks
PkCounts[j, k] = 'total counts at mass'[j, k]
SBMCounts[j, k] = 'total SBM counts'[j, k]
***If GetTrim = TRUE and FirstPass = TRUE
TrimMass[j, k] = 'trim mass at peak'[j, k]
TrimTime[j, k] = (StartTime + time_stamp_sec[j, k]) / 3600
End If***
Next k
Next j
For each peak, start by calculating the PkCps and SBMCps values, correcting the latter for the measured SBM_zero_cps.
[SBM_zero_cps is a measure of the reading on the secondary beam monitor when the beam is off, and its numeric value depends on the range to which the SBM monitor has been set, using the SHRIMP control software. There is only one sbm_zero_cps value per analysis.]
In implementing the below, note that a means of identifying the background peak is needed, including determination of whether a background peak even exists in the XML file being processed. (This is because there is no formal analytical requirement to measure background, and obviously background-correction should not happen if background has not been measured.) In the demo XML, background corresponds to k = 3.
For j = 1 to SpotNscans
For k = 1 to SpotNpeaks
PkCps[j, k] = PkCounts[j, k] / count_time_sec[k]
SBMCps[j, k] = ( SBMCounts[j, k] / count_time_sec[k] ) - SBM_zero_cps
If k = background --isolate its PkCps vector of length SpotNscans,
--and maintain its sum:
BkrdCps[k] = PkCps[j, k]
SumBkrdCps = SumBkrdCps + BkrdCps[k]
End If
Next k
Next j
If [background exists within collection of species]
CalcBkrdCps = SumBkrdCps / SpotNscans
If CalcBkrdCps < 10
BackgroundCps = CalcBkrdCps
Else
BackgroundCps = [biweight value of BkrdCps, with tuning = 9]
End If
Else
BackgroundCps = 0
End If
Now use this value to perform the background correction for each peak, and calculate the associated fractional error:
For k = 1 to SpotNpeaks
If k is NOT background
For j = 1 to SpotNscans
NetPkCps[j, k] = PkCps[j, k] – BackgroundCps
AbsNetPkCps[j, k] = abs( NetPkCps[j, k] )
If AbsNetPkCps[j, k] > 1e-6
CalcVariance = PkCounts[j, k] + ( abs( BackgroundCps ) *
( count_time_sec[k] / count_time_sec[background] ) ^2 )
PkFerr[j, k] = sqrt( CalcVariance ) /
( AbsNetPkCps[j, k] * count_time_sec[k] )
Else
PkFerr[j, k] = 1 --this is to control the magnitudes of
--errors associated with ~0 cps
End If
Next j
End If
Next k
If FirstPass = TRUE, calculate 'total cps' values for placement as columns on StandardData and SampleData sheets:
***If FirstPass = TRUE***
For k = 1 to Task.Npeaks
For j = 1 to SpotNscans
NetCps[j] = NetPkCps[j, k]
Next j
MeanNetCps = average( NetCps )
TotCps[k] = MeanNetCps + BackgroundCps
--Bodorkos 2017-04-04: next line inserted to force VBA-Java match
TotCps[k] = SigDigStrDbl( TotCps[k], 12 ) --12 sig. digits
Next k
***End If***
--Bodorkos 2017-04-04: next line inserted to force VBA-Java match
BackgroundCps = SigDigStrDbl( BackgroundCps, 12 ) --12 sig. digits