Skip to content

SHRIMP: Sub ParseRawData

sbodorkos edited this page May 26, 2017 · 6 revisions

SQUID 2.50 Sub: ParseRawData

[The following is a generalised function, used and reused by SQUID 2.50 multiple times 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), 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 SpotNumber, ParseRawData has a pair of mandatory Booleans: FirstPass and IgnoredChangedRunTable. FirstPass is an input 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 nominal input, as it is always explicitly set FALSE early in the subroutine. It is a flag monitoring the compatibility of each individual analysis with (a) the number of mass-stations specified in the governing Task, and (b) minimum standards for sensible data-reduction in general. Data reduction proceeds smoothly for as long as IgnoredChangedRunTable is FALSE.

Usage

ParseRawData(SpotNumber, FirstPass, IgnoredChangedRuntable, sDate, GetTrim, DelMT, GetTrimSigma)

Mandatory variables

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, for each specific invocation of ParseRawData, whether the 'once-only' operations are to be conducted.

IgnoredChangedRunTable: Boolean operating effectively as an error-trapping measure. It is explicitly set to FALSE early in ParseRawData, so its value as an input is inconsequential. During smooth data-processing, it remains FALSE throughout. It only becomes TRUE if a 'test' is failed; these tests are detailed below.

Optional variables

sDate: A string comprising the comma-separated date and time the analysis was commenced, 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.


Definition of variables

Values of type Boolean
FirstPass, GetTrim, IgnoredChangedRunTable [, DelMT, GetTrimSigma]

Values of type String
psSpotName, sDate

Values of type Integer
j, k, SpotNpeaks, SpotNscans, SpotNumber, 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, time_stamp_sec, TrimMass, TrimTime

Arrays comprising values of type String
psaSpotNames, psaSpotDateTime


The function of the subroutine is paraphrased as follows:

If SpotNumber < 1 
  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 one of the tests fails, 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 added lines are marked in the code-blocks below with triple-asterisks at each end.


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  

Clone this wiki locally