There are two detection limit calculations in Probe for EPMA. One of the equations requires pure element standard intensities, so those are calculated automatically.
To learn more about how these detection limits are calculated, check the DebugMode menu in the Output menu to see all the intermediate calculations steps, though you might want to select only a single analysis because there is a lot of output to the log window! See the Analyze Selected Lines button in the Analyze! window.
One calculation is for single analysis points based on the method of Scott and Love (1983) which is essentially based on 3 times the background variance. The code for this calculation is shown here:
Function ConvertDetectionLimits2(datarow As Integer, chan As Integer, tRowUnkCors() As Single, tRowStdCts() As Single, analysis As TypeAnalysis, sample() As TypeSample) As Single
' Calculate detection limit for a single element (off-peak measurement)
ierror = False
On Error GoTo ConvertDetectionLimits2Error
Dim temp As Single, bgdcount2 As Single
Dim tmsg As String
' Default is zero
ConvertDetectionLimits2! = 0#
' Normalize standard counts to pure element counts by apply std k-factor (0 = phi/rho/z, 1,2,3,4 = alpha fits, 5 = calilbration curve, 6 = fundamental parameters)
If CorrectionFlag% = 0 Or CorrectionFlag% = 5 Then
If analysis.StdAssignsKfactors!(chan%) = 0# Then Exit Function
stdcps100! = tRowStdCts!(datarow%, chan%) / analysis.StdAssignsKfactors!(chan%)
' Alpha-Factors (calculate alpha k-fac = conc/beta)
ElseIf CorrectionFlag% > 0 And CorrectionFlag% < 5 Then
If analysis.StdAssignsBetas!(chan%) = 0# Then Exit Function
temp! = (analysis.StdAssignsPercents!(chan%) / 100#) / analysis.StdAssignsBetas!(chan%)
If temp! = 0# Then Exit Function
stdcps100! = tRowStdCts!(datarow%, chan%) / temp! ' leave std counts in cps/nominal beam
' Fundamental parameter corrections
ElseIf CorrectionFlag% = MAXCORRECTION% Then
End If
' Check for valid stdcps100 (pure element intensity)
If stdcps100! = 0# Then Exit Function
' Determine background count time for unknown (0=off-peak, 1=MAN, 2=multipoint)
If sample(1).BackgroundTypes%(chan%) <> 1 Then
' 0=linear, 1=average, 2=high only, 3=low only, 4=exponential, 5=slope hi, 6=slope lo, 7=polynomial, 8=multi-point
If sample(1).OffPeakCorrectionTypes%(chan%) = 2 Then
bgdtime! = sample(1).HiTimeData!(datarow%, chan%) ' high only
ElseIf sample(1).OffPeakCorrectionTypes%(chan%) = 3 Then
bgdtime! = sample(1).LoTimeData!(datarow%, chan%) ' low only
Else
bgdtime! = sample(1).HiTimeData!(datarow%, chan%) + sample(1).LoTimeData!(datarow%, chan%) ' all other off peak types
End If
Else
bgdtime! = sample(1).OnTimeData!(datarow%, chan%) ' use on-peak time for MAN
End If
' Check for valid count times on background
If bgdtime! <= 0# Then Exit Function
' Determine unknown beam current for each element
If Not sample(1).CombinedConditionsFlag Then
bgdbeam! = sample(1).OnBeamData!(datarow%, chan%) ' use OnBeamData in case of aggregate intensity calculation (use average aggregate beam)
Else
bgdbeam! = sample(1).OnBeamDataArray!(datarow%, chan%) ' use OnBeamDataArray in case of aggregate intensity calculation (use average aggregate beam)
End If
' De-normalize unknown background counts for time and beam
bgdcount! = sample(1).BgdData(datarow%, chan%) * bgdtime!
Call DataCorrectDataBeamDrift2(bgdcount!, bgdbeam!)
If ierror Then Exit Function
' Take square root to get gaussian standard deviation of background
If bgdcount! < 0# Then
If DebugMode Then
tmsg$ = "ConvertDetectionLimits2: negative background counts (" & Format$(sample(1).BgdData(datarow%, chan%)) & ", unable to calculate detection limits on channel " & Format$(chan%) & "..."
Call IOWriteLogRichText(tmsg$, vbNullString, Int(LogWindowFontSize%), vbMagenta, Int(FONT_REGULAR%), Int(0))
End If
Exit Function
End If
' Calculate off-peak variance for this element and row (0=off-peak, 1=MAN, 2=multipoint)
If sample(1).BackgroundTypes%(chan%) <> 1 Then
bgddevraw! = Sqr(bgdcount!) ' off peak or multi-point bgd only variance, assume gaussian statistics
' Calculate MAN (net) variance for this element and row (0=off-peak, 1=MAN, 2=multipoint)
Else
bgddevraw! = ConvertDetectionLimits3!(datarow%, chan%, analysis, sample()) ' MAN net variance, calculate using Jared Singer MAN sensitivity expressions
End If
' Re-normalize modeled background variance to cps and nominal beam again
bgddevcps! = bgddevraw! / bgdtime!
Call DataCorrectDataBeamDrift(bgddevcps!, bgdbeam!)
If ierror Then Exit Function
' Load off-peak bgd only dev cps for log debug output below
If sample(1).BackgroundTypes%(chan%) <> 1 Then
bgd_onlydevcps! = bgddevcps!
End If
' Re-normalize raw background count to cps and nominal beam again (for ConvertDetectionLimits5 call below)
bgdcount2! = bgdcount! / bgdtime!
Call DataCorrectDataBeamDrift(bgdcount2!, bgdbeam!)
If ierror Then Exit Function
'UseSingerMANExpressionsFlag = False
UseSingerMANExpressionsFlag = True
If (sample(1).BackgroundTypes%(chan%) = 1 And UseSingerMANExpressionsFlag) Or ConvertDataIsNthPoint(datarow%, chan%, sample()) Or (sample(1).BackgroundTypes%(chan%) <> 1 And NthPointCalculationFlag) Then ' calculate traditional sensitivity
ConvertDetectionLimits2! = 2# * bgddevcps! / stdcps100! * 100# * tRowUnkCors!(datarow%, chan%) ' net intensity statistics- assume 2x net variation for CDL for MAN and Nth point
Else
ConvertDetectionLimits2! = 3# * bgddevcps! / stdcps100! * 100# * tRowUnkCors!(datarow%, chan%) ' bgd intensity only statistics- assume 3x bgd variation for CDL for off-peak
End If
' Save bgd intensity and variance to array for statistics output to log window
If DebugMode Then
Call ConvertDetectionLimits5(chan%, bgdcount2!, bgd_onlydevcps!, sample())
If ierror Then Exit Function
End If
Exit Function
' Errors
ConvertDetectionLimits2Error:
MsgBox Error$, vbOKOnly + vbCritical, "ConvertDetectionLimits2"
ierror = True
Exit Function
End Function
The above code only applies to off-peak measurements, because the statistics for MAN backgrounds are completely different. See Donovan et al., 2016 for a detailed discussion of the MAN background statistics.
For the calculation of average detection limits using a t-test, these calculations are based on equations in Goldstein et al, 1992 and those values are dominated by the concentration variance. The code that performs these calculations is shown here:
' Detection limits (mode% = 4)
If mode% = 4 Then
' Calculate average standard counts (already corrected for aggregate intensities if flagged)
Call MathArrayAverage(averstd, tRowStdCts!(), sample(1).Datarows%, sample(1).LastElm%, sample())
If ierror Then Exit Sub
For j% = 1 To MAXCI% ' calculate MAXCI% different confidence intervals (60 to 99%)
Call StudentGetT(df!, Alpha!(j%), t!)
If ierror Then Exit Sub
For chan% = 1 To sample(1).LastElm%
ip% = IPOS2(NumberofStandards%, sample(1).StdAssigns%(chan%), StandardNumbers%())
If ip% > 0 And averstd.averags!(chan%) <> 0# Then
analysis.CalData!(j%, chan%) = analysis.StdPercents!(ip%, chan%) / Abs(averstd.averags!(chan%)) * Sqr(2#)
analysis.CalData!(j%, chan%) = analysis.CalData!(j%, chan%) * t! * average.Stddevs!(chan%) / Sqr(sample(1).GoodDataRows%)
End If
Next chan%
Next j%
Exit Sub
End If
Let us know if you have further questions.