Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
REAL-TIME DSP IMPLEMENTATION OF SELF-CALIBRATING PULSE-SHAPE
DISCRIMINATOR FOR HIGH PURITY GERMANIUM
By
REYNOLD SUAREZ
A thesis submitted in partial fulfillment of the requirements for the degree of
MASTER OF SCIENCE OF ELECTRICAL ENGINEERING
WASHINGTON STATE UNIVERSITY School of Electrical Engineering & Computer Science
DECEMBER 2006
© Copyright by REYNOLD SUAREZ, 2006
All Rights Reserved
To the Faculty of Washington State University: The members of the Committee appointed to examine the thesis of REYNOLD SUAREZ find it satisfactory and recommend that it be accepted.
_________________________________ Chair
_________________________________
_________________________________
ii
ACKNOWLEDGMENT
I would like to acknowledge Dr. Craig Aalseth and Dr. John Orell for their
continued support on the nuclear physics portion of this research as well as aiding in
setting up nuclear experiments. Dr. Aalseth developed the original algorithm used in this
research effort. I would also like to acknowledge Charles Hubbard and Brian Schrom for
their suggestions and help on the assembly level programming aspects of this research.
iii
REAL-TIME DSP IMPLEMENTATION OF SELF-CALIBRATING PULSE-SHAPE
DISCRIMINATOR FOR HIGH PURITY GERMANIUM
Abstract
By Reynold Suarez M.S. Washington State University
December 2006
Chair: Scott Hudson
Pulse-shape discrimination (PSD) for germanium ionization spectrometers
attempts to extract additional information from each event. Electronic signals, “pulses,”
occur when radiation interacts with the spectrometer. Normally, the total charge is the
only parameter measured and indicates the amount of energy deposited. The number of
interaction loci for a radiation event “interaction multiplicity” is a useful additional
parameter to consider. Pacific Northwest National Laboratories has previously
developed a discriminator using a 3-D parametric space that self-calibrates and is
sensitive to interaction multiplicity. The algorithm was implemented in C++ and events
were post-processed and classified as being high or low multiplicity. Optimizations were
then made to the algorithm reducing memory requirements and increasing speed. This
work dramatically increases the speed and applicability to real-time applications by
implementing all the PSD and processing in real-time on a digital signal processor (DSP)
embedded in the hardware.
iv
TABLE OF CONTENTS
ACKNOWLEDGMENT.................................................................................................... iii ABSTRACT....................................................................................................................... iv TABLE OF CONTENTS.................................................................................................... v LIST OF FIGURES ........................................................................................................... vi CHAPTER
1. INTRODUCTION................................................................................................. 1
2. PULSE-SHAPE DISCRIMINATION .................................................................. 2
Radiation Detection ............................................................................................. 2
PNNL Multi-Parametric Discriminator ............................................................... 3
3. DIGITAL SIGNAL PROCESSING PULSE-SHAPE DISCRIMINATION ........ 6
DSP Platform ....................................................................................................... 6
DSP Implementation............................................................................................ 7
Savitzky-Golay Filtering...................................................................................... 8
Calculating Parameters on DSP........................................................................... 9
4. EXPERIMENTAL RESULTS ............................................................................ 12
Experimental Data ............................................................................................. 12
Results................................................................................................................ 14
Conclusion ......................................................................................................... 15
BIBLIOGRAPHY............................................................................................................. 17 APPENDIX....................................................................................................................... 18
A. DSP Programming Code .................................................................................... 18
v
LIST OF FIGURES
Figure 2.1 Graph Illustrating Gamma Ray Interaction Probabilities................................ 3
Figure 2.2 3-D Parameter-Space....................................................................................... 5
Figure 3.1 Pixie-4 Spectrometer Hardware Block Diagram............................................. 6
Figure 5.1 Savitzky-Golay Filter Implementation ............................................................ 9
Figure 4.1 3-D Parameter-Space Generated using Offline Analysis Tool...................... 12
Figure 4.2 3-D Parameter-Space Generated using DSP ................................................. 13
Figure 4.3 Histograms Illustrating Differences in Paramters using both Methods......... 13
Figure 4.4 Filtered Spectrum using DSP Generated Parameters .................................... 15
vi
CHAPTER ONE
INTRODUCTION
Radiation exists everywhere in many forms from cosmic radiation to the kind
originating in nuclear processes. Detection of radiation is important from understanding
radioactive effects to sensing nuclear detonations. Digital spectroscopy for nuclear
detection has been greatly improved through recent advances in high-speed ADC chips
and digital signal processor (DSP) based instrumentation. The development of high
precision ADCs that digitize the output signals from preamplifiers allow for precise and
efficient pulse shape analysis. Through DSP technology, pulses may be processed in
real-time. Digital signal processors are designed to perform data filtering and processing
efficiently at high speeds. Pulse shape filtering can greatly increase energy resolution
and reject bad pulses. Fast electronics combined with digital signal processing have
made for powerful digital Multi-Channel Analyzers.
1
CHAPTER TWO
PULSE-SHAPE DISCRIMINATION
Radiation Detection
Pulses evolve when radiation interacts with a germanium spectrometer. Under the
influence of an applied bias voltage, charge carriers drift from the radiation interaction
location toward the electrodes. During the drift time, a current signal is observed, with
the total charge being proportional to the amount of energy (ionization) deposited. Under
normal measuring techniques the total charge is the only parameter measured and is an
indicator of the amount of energy deposited.
The number of “interaction multiplicity” is a useful parameter to consider.
Multiplicity refers to the interactions of gamma rays within the germanium. Radioactive
events may be characterized as having low-multiplicity (single-site) or high-multiplicity
(multiple-site). Low multiplicity events generally occur in Gamma signals below
150keV. Examples of low multiplicity events are: 72Ge(n,n’,e-) fast neutrons, double-
escape peaks, and internal beta decay. High multiplicity events generally occur at
energies above 400keV where Compton scattering and pair-production become more
probable. The graph below illustrates the probabilities of gamma ray interactions at
different energies.
2
Figure 2.1. Graph illustrating gamma ray interaction probabilities
PNNL Multi-Parametric Discriminator
The ability to discriminate multiplicity is useful for several applications. If it is
necessary to measure 76Ge bb-decay, for instance, rejecting high-multiplicity gamma
events is desirable. Other applications for multiplicity discriminations include enhanced
fast-neutron sensitivity, enhanced double-escape-peak (DEP) signals for high-energy
gamma detection, discrimination of internal pure-beta decay from gamma signals, and
identification of cascade-sum lines in complex gamma spectra.
A discriminator developed by scientists at Pacific Northwest National
Laboratories (PNNL) performs multiplicity discrimination. The technique involves
defining a 3-D parameter space using pulse width, pulse asymmetry, and normalized
moment about the pulse midpoint. The pulse width is the charge collection time. The
pulse asymmetry is formulated from front-half-area minus back-half area divided by the
total pulse area. The pulse asymmetry will vary about 0 with 1 and -1 being the limits.
An asymmetry value of 0 would correspond to a symmetric pulse. The normalized
moment is defined as follows:
3
12
))((
0
0
2
∑
∑
=
=
Δ
Δ−= N
Nii
N
Nimidi
n
tj
tNijI
Equation 2.1 Calculation for Normalized Moment Parameter
Where Nmid is the midpoint of the sample pulse, N is the number of sample points
between beginning and end of the pulse, ji is the value of the current at index I, and N0 is
the index of the starting sample of the pulse. The time granularity of the indices is
indicated by Δt.
Implementation of the discriminator involves first acquiring calibration data
pulses involving events of interest such as single site events like DEP. Once this
calibration process is complete, the events from the peak of interest are put into a 3-D
parameter space histogram. The bins in the resulting 3-D histogram are sorted in
descending order of counts. Bins are summed, in descending order of individual bin
counts, until the desired percentage, or confidence level, of the total events are contained.
This will be the approximate acceptance fraction for events like those in the calibration
data set. The bins contributing to the sum form the acceptance region of the
discriminator. Experimental data pulses are analyzed and marked as falling inside or
outside the acceptance region of the discriminator. Figure 3.1 below illustrates a
calibration data set for double escape peak of Tl-208.
4
Figure 2.2 3-D parameter-space for events taken from double-escape peak 1592.5keV from 208Tl
5
CHAPTER THREE
DIGITAL SIGNAL PROCESSING (DSP) PULSE-SHAPE DISCRIMINATION
DSP Platform
The hardware used for data collection and processing is a product of X-Ray
Instrument Associates (XIA). Pulses generated in the germanium move through a
preamplifier, then are sampled in the DGF Pixie-4 spectrometer at 75MHz with 14-bit
ADCs. A Field Programmable Gate Array (FPGA) is used for triggering, energy
trapezoidal filtering, and pileup inspection. These parameters are defined using user set
values. A DSP then reads out the energy filter value from the FPGA, reconstructs the
pulse height, and bins the energy. The DSP may perform additional tasks depending on
the application.
Figure 3.1 Pixie-4 spectrometer hardware block diagram
Digital signal processors are known for their ability to process data and perform
filtering at very fast rates. The high processing speeds are in large part due to the
multiply-accumulator (MAC) that can multiply numbers and accumulate with very few
instructions. They are optimized for matrix operations such as convolution and dot
products.
6
The Pixie-4 spectrometer uses a 16-bit fixed-point DSP capable of executing
33MIPS. The DSP is a 2185 from Analog Devices. The computational units located on
this DSP are, one Arithmetic Logic Unit (ALU), one Multiplier/Accumulator (MAC), and
one Barrel Shifter. The ALU takes two 16-bit inputs and provides a 16-bit output. The
MAC takes two 16-bit inputs for multiplication and has a 40-bit output that consists of
two 16-bit and one 8-bit register. This output can be fed back to the input of the MAC
allowing for accumulation. The Barrel Shifter has a 32-bit output, consisting of two 16-
bit registers, of the shifted data. Barrel shifters differ from normal shifters in digital
electronics in that they allow multiple bits to be altered in one clock cycle.
A feature available to users of the DGF Pixie-4 is the ability to write DSP code
and compile it into the firmware for custom pulse processing. This was the characteristic
used to implement the PNNL Multi-Parametric Discriminator.
DSP Implementation
XIA recommends that all code be written in assembly as they found compilers,
such as C, inflate the code causing system execution to be slow. This also allows users to
keep code efficient and concise. For this reason, familiarity with the ADSP2100 family
instruction set is useful to develop custom DSP code for the Pixie-4. XIA provides a
pointer to the start of the pulse data, the length, and energy values among other variables.
This is necessary for traversing the pulse data during filtering operations.
One way to move data back and forth is through data and program memory. Data
memory has 16-bit registers and program memory contains 24-bit registers. One
7
constraint in writing custom DSP code for XIA is that only data memory may be used for
data storage and transfers.
The DSP uses fixed-point integer math for processing known as 16.0 format. In
this format, the radix point falls at the end of the number. This means values must be
scaled to fall within -215 and 215-1 for signed values and 0 and 216 for unsigned values.
Twos compliment is used for the representation. So a number in 1.15 format would need
to be multiplied by 216 to scale it to 16.0 format.
Savitzky-Golay Filtering
Number normalization was important when implementing the initial part of the
discriminator where Savitzky-Golay (SG) filtering is performed. SG is a type of low-
pass filter where a least-square fit to an nth order polynomial is performed on a moving
window of a user-defined length. It is generally used to smooth data as it retains most of
the spectral features. Another advantage is that it may inherently perform a smoothed nth
order derivative, a feature useful for analyzing pulses generated from an integrating
preamplifier. There exists a set of pre-computed coefficients that perform the Savitzky-
Golay filtering depending on filter requirements. The sum of the coefficients is one and
each is in 1.15 format. To use this filter in the DSP, the pre computed coefficients where
shifted by 216 to convert them to 16.0 format.
To keep the memory used on the DSP concise, it was preferred to write the new
SG-filtered data over the old pulse data. A challenge in doing this was the possibility of
using previously filtered data points to calculate subsequent points. To avoid this, a
temporary circular buffer was allocated that contained the unaltered pulse data pertaining
8
to the front part of the moving window. When a filtered data point was calculated, the
unaltered point was copied to the temporary buffer, the pointer incremented, and the
original data point then written over. When the filter was applied to the next data point,
the pointer in the circular buffer would be pointing to the correct data point. Figure 5.1
below illustrates this process.
U16U15U14U13U12U11U10U9U8S7S6S5S4S3S2S1 Pulse Data
Pulse Data Pointer
U6U5U4U7 Circular Buffer
Circular Buffer Pointer
C9C8C7C6C5C4C3C2C1 SG Coefficients
Figure 5.1 Savitzky-Golay filter implementation
Where Sn is a smoothed data points, Un is unsmoothed data points, and Cn are the
SG coefficients. In this case, the unsmoothed data point U7 was just copied to the
circular buffer and the smoothed point S7 was written to the pulse data memory location.
To calculate S8, the MAC would use the circular buffer and the five data points starting
from the pulse data pointer and take the dot product of those with the SG coefficients.
This methodology was used to calculate the SG filter when necessary.
Calculating Parameters on DSP
The pulse width was calculated by first finding the max value of the pulse. A
constant fraction discriminator (CFD) value of 8 percent was used to find the front and
back locations of the pulse width. This process involved taking 8 percent of the peak,
9
then traversing the pulse in both directions from the peak until the CFD limit was
reached. The address of the start and end locations of the pulse were stored for further
parameter calculations. The difference of start and end locations was the pulse width
used and stored in a 16-bit register.
The pulse asymmetry calculation involved first finding the midpoint between the
start and end address of the pulse. The difference of start and end address was just
shifted right by one bit to find the midpoint, effectively dividing by 2. Subsequent to the
location of the midpoint, the front and back halves of the pulse were integrated. These
values were stored for further processing. Since the possibility that the area for either
front or back might exceed 16 bits, 32 bit addition and subtraction was performed. This
involved performing addition with carry, and a subtraction with borrow. Each result was
stored in two 16-bit registers.
The ADSP2100 family instruction set provides two instructions for performing a
division DIVS and DIVQ. DIVS is executed first, for signed division, followed by 15
executions of the DIVQ instruction. These instructions implement a conditional
add/subtract non-restoring division algorithm. This division algorithm takes a 32-bit
dividend and 16-bit divisor outputting a 16-bit quotient. Since the divisor could
potentially exceed 16-bits, it is scaled. If it was 16-bits or less, the number was left
intact. If it was larger than 16-bits, the most significant bit was shifted to bit 15 of the
16-bit divisor and the shift number was stored. Bit 16 of the divisor served as a sign bit.
The value of the pulse asymmetry parameter should vary about 0 between -1 and
1. Since the DSP uses integer math, when the value is read out, the shift value may also
be read out. For readability outside the DSP this parameter should be divided by 2 raised
10
to the shift value to obtain the floating-point representation between -1 and 1. This
converts 16.0 format to 1.15.
The normalized moment was calculated by using equation 2.1 above. The pulse
was traversed from start to end locations. The mid-point value of the pulse was loaded
and used to subtract the current location (i-Nmid). The MAC has a 16-bit register that is
fed back to the input of the multiplier through a multiplexer (MUX) for performing
smaller multiplications such as squaring numbers. This feedback register was used to
calculate the squared portion of (i-Nmid)2 . This value was fed to the input of the MAC
along with the current location value, ji. These values were accumulated and the result
was multiplied by 12. This provided the dividend portion of the total moment of the
pulse and was stored in two 16 bit registers.
The divisor portion of the normalized moment was calculated by taking the total
area under the pulse, which was previously found in the pulse asymmetry calculation, and
multiplying this by the square of the width. This number potentially exceeded 16-bits, so
scaling was necessary. Since the normalized moment is always a positive number,
unsigned 16-bit representation was used. This allows another bit for representing the
value. To perform the scaling, the most significant bit of the divisor was shifted to bit 16
of the register and the shift amount in was stored separate location.
The normalized moment falls between 0 and 2. When this value is read out from
the DSP, the shift value is also available. In order to scale the number correctly outside
the DSP, the output should be divided by 2 raised to the shift value. This converts the
number to the floating point representation that falls between 0 and 2.
11
CHAPTER FOUR
EXPERIMENTAL RESULTS
Experimental Data
To test the parameters generated with the DSP, a discriminator was constructed to
enhance double-escape-peak events. Data was taken on a 130% Ortec high purity
germanium detector. A Tl-208 source was used to produce 1592.5-keV double-escape-
peak events. The DSP firmware was loaded onto the XIA unit and several sets of data
were taken. The three discriminator parameters were calculated with both the DSP and
an offline analysis tool. The double-escape-peak events were located on the energy
histogram and used to build the discriminator. The 3-D parameter-space plots using both
methods are illustrated below in figures 4.1 and 4.2.
Figure 4.1 3-D parameter-space distribution of double-escape peak events. These events
were taken from 1592.5-keV DEP from 208TL and generated using off-line analysis.
12
Figure 4.2 3-D parameter-space distribution of double-escape peak events. These events
were taken from 1592.5-keV DEP from 208TL and generated on the DSP.
Both methods of analysis generate similar parameter space distributions. A closer
look at the actual parameters generated reveals slight differences. The differences in the
three parameters were calculated and histograms were generated to displays the
differences. Figure 6.3 below illustrates the three difference plots.
Figure 4.3 Histogram of difference between discriminator parameters generated from DSP and offline analysis with width delta (left), pulse asymmetry delta (Center) and
normalized moment delta (right).
Each sample unit for a given pulse is 13.3ns in length. The width delta plot
represents only a few sample units of difference at most. Careful examination of the
offline analysis utility showed a slight difference in the way the width parameter was
calculated. The DSP method sets the left most window point as the value prior to
reaching the CFD limit. The offline utility uses the value immediately following the
CFD as the left most window point. A similar approach is used in both methods for
finding the right window edge. The small difference in the width parameter effects the
13
pulse asymmetry calculation as the integration limits differ depending on the pulse. The
differences in width and area get propagated through the normalized moment equation.
The offline analysis utility also interpolates between ADC sampling points also
contributing differences.
A feature of this pulse-shape discriminator is that it is self-calibrating. Therefore
differences that exist between the parameters generated using both methods are not
significant. This is demonstrated in the next section by comparing the output of the
discriminator using a figure-of-merit.
Results
The efficacy of the discriminator can be described by a figure-of-merit (FOM).
The FOM takes both the suppression factor and efficiency for retaining low multiplicity
events into consideration. The formula used is illustrated in equation 4.1 below.
background
depFOMε
ε=
Equation 4.1 Calculation for Figure-of-Merit
Where εdep are the acceptance fractions for low multiplicity events, εbackground are the
background events. In this case we were interested in keeping double-escape-peak
events.
A discriminator constructed from both the DSP and offline analysis utility and
applied to a set of spectral data. A confidence level of 80% was chosen for the
discriminators. Figure 4.4 below illustrates output spectrum from the DSP
discrimination. In this case, “background” events were taken from the Ac-228 1587-keV
14
peak. These events were high multiplicity and it was desired to reject them. The “dep”
events were taken from the Tl-208 1592keV peak. These events are single-site and the
desired physics signature.
228Ac
DEP of 208Tl
PSD Result
Original Spectrum
Figure 4.4 Filtered data using DSP generated parameters. White is original data, black is residual, gray area is filtered data.
To calculate the figure of merit, a Gaussian was used to fit the peaks and the areas
were calculated. The figure of merit for the DSP filtered data was 1.44. This was similar
to the figure of merit for the offline analysis which was 1.57. These FOM numbers
describe the improved sensitivity to detect the DEP events in the presence of
“background”.
Conclusion
The ability to generate the 3-D parameter space for multiplicity discrimination in
real-time removes the need for offline calculations. The discriminator parameters are
available with every pulse allowing any dataset to form a discriminator. The self-
calibrating feature allows optimal discrimination for each detector. This technique
15
started out as a complex C++ program, then was later reduced in complexity and
optimized for speed by eliminating Fast-Fourier Transforms and reducing code size. This
research effort took it to another level now allowing for real-time construction of a
discriminator. Real-time generation of the parameters makes it effective and simple to
use.
16
BIBLIOGRAPHY [1] G. F. Knoll. Radiation detection and measurement. John Wiley & Sons, Inc., second
edition, 1989. [2] W. Hennig, Y.X. Chu, H. Tan, A. Fallu-Labruyere, W.K. Warburton, and R
Grzywacz, “The DGF Pixie-4 spectrometer – compact digital readout electronics for HPGe clover detectors”, submitted to NIM B. 2005.
[3] C. E. Aalseth, “Germanium Spectrometer Pulse-Shape Discrimination for 76Ge
Double-Beta Decay”, submitted to University of South Carolina for PhD., 2000. [4] W. H. Press, B. P. Flannery, S. A. Teukolsky, W. T. Vetterling. Numerical Recipes in
C. Cambridge University Press, second edition, 1992.
17
APPENDIX
A. DSP Programming Code .MODULE/RAM/SEG=UserProgram user; .ENTRY UserBegin; .ENTRY UserRunInit; .ENTRY UserChannel; .ENTRY UserEvent; .ENTRY UserRunFinish; .EXTERNAL UserBeginReturn; .EXTERNAL UserRunInitReturn; .EXTERNAL UserChannelReturn; .EXTERNAL UserEventReturn; .EXTERNAL UserRunFinishReturn; #include <INTRFACE.INC> /* interface provided by XIA */ .VAR/DM/SEG=UserData saveI0, saveI1, saveI3, saveI4, saveM3, saveL4, saveL3; .VAR/DM/SEG=UserData maxPeak, areaF0, areaB0, FplusB0, FplusB1, FminusB0 ,FminusB1; .VAR/DM/SEG=UserData areaF1, areaB1, totMoment0, totMoment1, momBot, momShift, cfd; .VAR/DM/SEG=UserData midAddr, asymBot, asymShift; .VAR/DM/SEG=UserData outWidth; .VAR/DM/SEG=UserData MyBuffer[16]; .VAR/DM/CIRC/SEG=UserData sg_coeff[9]; .VAR/DM/CIRC/SEG=UserData d_buff[4]; .VAR/DM/CIRC/SEG=UserData modPulse[300]; /*--------------------------------------------------------------------- + + UserBegin is called once after power up or reboot, after all + memory and variables have been initialized, but before + the trigger/filter FPGAs and the DACs have been programmed. + ----------------------------------------------------------------------*/ UserBegin: { ar=^MyBuffer; /* UserOut[0]=address of MyBuffer */ ar=ar+0x4000; dm(UserOut)=ar; /* address as seen from the host */ ar=%MyBuffer; dm(UserOut+1)=ar; } /* UserOut[1]=length of MyBuffer */ /* To communicate address */ /* and size of buffer to host. */ JUMP UserBeginReturn; /*--------------------------------------------------------------------- +
18
+ UserRunInit is called once during the run initialization phase + ----------------------------------------------------------------------*/ UserRunInit: nop; /* user program instructions */ JUMP UserRunInitReturn; /*----------------------------------------------------------------------- + + UserChannel is called for every event, and for every channel + with an entry in the read/hit pattern, and for which bit 0 + in its ChanCSRB has been set. + ------------------------------------------------------------------------*/ UserChannel: /* Save Registers for Reset on Exit */ dm(saveI0) = I0; dm(saveI1) = I1; dm(saveI3) = I3; dm(saveI4) = I4; dm(saveM3) = M3; dm(saveL4) = L4; dm(saveL3) = L3; /* Initialize Coefficients */ /* 9th Order SG Derivative */ M3 = 4; I3 = ^sg_coeff; AR = 0x1288; dm(I3,M1)=AR; AR = 0xE167; dm(I3,M1)=AR; AR = 0xD669; dm(I3,M1)=AR; AR = 0xE4D9; dm(I3,M1)=AR; AR = 0x0000; dm(I3,M1)=AR; AR = 0x1B27; dm(I3,M1)=AR; AR = 0x2997; dm(I3,M1)=AR; AR = 0x1E99; dm(I3,M1)=AR; AR = 0xED78; dm(I3,M1)=AR; /* 9th Order SG No Derivative */ /* M3 = 4; + I3 = ^sg_coeff; + AR = 0x08F3; + dm(I3,M1)=AR; + AR = 0xDF2E;
19
+ dm(I3,M1)=AR; + AR = 0x11E7; + dm(I3,M1)=AR; + AR = 0x508F; + dm(I3,M1)=AR; + AR = 0x6AD1; + dm(I3,M1)=AR; + AR = 0x508F; + dm(I3,M1)=AR; + AR = 0x11E7; + dm(I3,M1)=AR; + AR = 0xDF2E; + dm(I3,M1)=AR; + AR = 0x08F3; + dm(I3,M1)=AR;*/ /* Set Starting Pointers for SG */ I0=dm(ATstart); I4=^sg_coeff; L4=%sg_coeff; modify(I0,M3); I1=I0; M3=-4; modify(I1,M3); /* Initialize d_buff */ I3=^d_buff; L3=%d_buff; CNTR=L3; DO buff_init UNTIL CE; AR=dm(I1,M1); buff_init: dm(I3,M1)=AR; /* Apply SG Filter */ /* Setup Counter */ AX0=dm(TLen); AY0=8; /* coeff. length minus 1 */ AR=AX0-AY0; CNTR=AR; DO sg UNTIL CE; I1=I0; CNTR=L3; MR=0; DO Sum_L UNTIL CE; /* Sum Left Side */ MX0=dm(I3,M1); MY0=dm(I4,M5); Sum_L: MR = MR + MX0 * MY0(us); AR=dm(I0,M0); /* Copy Middle Term */ dm(I3,M1)=AR; AX0=L3; AR=AX0+1; CNTR=AR; DO Sum_R UNTIL CE; /* Sum Right Side */ MX0 = dm(I1,M1); MY0 = dm(I4,M5); Sum_R: MR = MR + MX0 * MY0(us);
20
MR = MR (rnd); sg: dm(I0,M1)=MR1; /*Set begin and end locations to 0 for derivative*/ I0=dm(ATstart); AX0=dm(TLen); AY0=I0; AR=AX0+AY0; AR=AR-1; /* Point to last data point */ I1=AR; CNTR=4; /* 4 Data Points on Ends */ DO zero_ends UNTIL CE; dm(I0,M1)=0; dm(I1,M2)=0; zero_ends: nop; /* Make Negative Values Zero */ I0=dm(ATstart); AR=dm(TLen); CNTR=AR; AX1=0; DO p_shift UNTIL CE; AR=0; AY1=dm(I0,M0); AR=AX1+AY1; IF GE JUMP not_zero; dm(I0,M0)=0; not_zero: p_shift: modify(I0,M1); /* -------------------------- */ /* All Data Derivative Now */ /* I0 - data location */ /* I1 - peak location */ /* I2 - left window location */ /* I3 - right window location */ /* I4 - midpoint location */ /* -------------------------- */ /* Find Max Peak */ AX0=dm(TLen); AY0=8; AR=AX0-AY0; AX0=AR; AR=AX0-1; CNTR=AR; AY0=0; M3=4; I0=dm(ATstart); modify(I0,M3); AX0=dm(I0,M1); /* Set 1st data point to Max */ DO maxFind UNTIL CE; AY0=dm(I0,M0);
21
AR=AX0-AY0; IF GE JUMP cont; AX0=AY0; I1=I0; /* Store Peak Address */ cont: modify(I0,M1); maxFind: nop; dm(maxPeak)=AX0; /* Find CFD */ AR=dm(maxPeak); /* Peak Value */ MX0=0x147B; /* 8 percent */ MY0=AR; MR=0; MR=MX0*MY0 (uu); AX0=MR1; /* Upper 16bits */ dm(cfd)=AX0; /* Store CFD */ /* Find Front Window Point */ I0=dm(ATstart); AY0=I0; /* Start Address */ AX0=I1; /* Peak Address */ AR=AX0-AY0; /* End Address */ CNTR=AR; /* Ensures we don't traverse beyond start point */ I0=I1; /* Set I0 to Max Address */ AX0=dm(cfd); /* Get CFD */ AR=0; DO leftFind UNTIL CE; AY0=dm(I0,M0); /* Get Next Value */ AR=AX0-AY0; /* Check Difference */ IF GE JUMP l_cont; /* If value greater than CFD, store location */ I2=I0; /* Set I2 to Current Position */ modify(I0,M2); /* Decrement pointer to next address */ leftFind: nop; JUMP l_noFind; /*Counter Expired didn't find CFD point*/ l_cont: /*Found CFD Point*/ POP CNTR; POP LOOP; POP PC; l_noFind: /* Find Back Window Point */ I0=dm(ATstart); AX0=I0; /* Start Address */ AY0=dm(TLen);/* Pulse Length */ AR=AX0+AY0; /* End Address */ AX1=AR; AR=0; AY1=I1; /* Peak Address */ AR=AX1-AY1; CNTR=AR; /* Ensures we do not traverse beyond pulse data */ I0=I1; /* Set I0 to Peak Address */ AX0=dm(cfd); /* Get CFD */
22
AR=0; DO rightFind UNTIL CE; AY0=dm(I0,M0); /* Get Current Value */ AR=AX0-AY0; /* Check Difference */ IF GE JUMP r_cont; /* If value greater than CFD, store location */ I3=I0; /* Set I3 to Current Position */ modify(I0,M1); /* Increment to next address */ rightFind: nop; JUMP r_noFind; /*Counter Expired didn't find CFD point*/ r_cont: /*Found CFD Point*/ POP CNTR; POP LOOP; POP PC; r_noFind: /* ------------------------------------ */ /* Now have startTime and stopTime */ /* Now calculate midTime which is: */ /* startTime + (stopTime - startTime)/2 */ /* ------------------------------------ */ /* Find Mid Address for Area Calculations */ AY0 = I2; /* startTime */ AX0 = I3; /* stopTime */ AR = AX0-AY0; SR = ashift AR by -1 (LO); /* Divide by 2 */ AX0 = SR0; AR = AX0+AY0; /* MidTime */ dm(midAddr)=AR; /* ------------------------------------ */ /* Calculate Front Area and Moment */ /* FArea=Sum from start to mid time */ /* FMom=sum(f(x)*(midTime-x)^2) from */ /* startTime to midTime */ /* ------------------------------------ */ /* Find Front Area */ I0=I2; /* Set I0 to Start Address (left window address) */ AX0=dm(midAddr); AY0=I2; /* Set AY0 to Front window address */ AR=AX0-AY0; /* Get Length, Doesn't Include Mid Point */ CNTR=AR; MR=0; MY0=1; DO leftArea UNTIL CE; MX0=dm(I0,M1); /* Get Current Area Value */ MR=MR+MX0*MY0 (uu); /* Add Area */ leftArea: nop; dm(areaF1)=MR1; /* Store Front Area Upper 16 bits */ dm(areaF0)=MR0; /* Store Lower 16 bits */ /* Find Total Moment (Front Moment + Back Moment) */ I0=I2; /* Set I0 to Start Address */
23
AY0=I2; /* Set AY0 to Front window address */ AX0=I3; /* Set AX0 to Right Window End Address (stopTime) */ AR=AX0-AY0; /* Get Length */ AR=AR+1; /* Add 1 so we point to last position */ CNTR=AR; /* AR already set */ MR=0; AR=0; AX0=dm(midAddr); DO leftMom UNTIL CE; MF=0; AX1=dm(I0,M0); /* f(x) Get Current Value */ AY0=I0; /* x */ AR=0; AR=AX0-AY0; /* (midTime-x) */ IF LT AR = -AR; SR = ashift AR by 8 (LO); /* Shift by 8 */ MY0 = SR0; /*(midTime-x)*/ AR = SR0; /*(midTime-x)*/ MF=AR*MY0 (uu); /* (midTime-x)^2 */ MX0=AX1; /* f(x) to MAC X Input */ MR=MR+MX0*MF (uu); /* f(x)*(midTime-x)^2 and accums */ leftMom: modify(I0,M1); AR=MR0; /* Store LO 16 Bits */ dm(totMoment0)=AR; AR=MR1; /* Store HI 16 Bits */ dm(totMoment1)=AR; /* ------------------------------------ */ /* Calculate Back Area and Moment */ /* BArea=Sum from mid to stop time */ /* BArea includes midpoint value */ /* FMom=sum(f(x)*(x-midTime)^2) from */ /* midTime to stopTime */ /* ------------------------------------ */ /* Find Back Area */ I0=dm(midAddr); AY0=I0; /* Set AY0 to Mid Address */ AX0=I3; /* Set AX0 to Right Window End Address (stopTime) */ AR=AX0-AY0; /* Get Length */ AR=AR+1; CNTR=AR; AR=0; MR=0; MY0=1; DO rightArea UNTIL CE; MX0=dm(I0,M1); /* Get Current Area Value */ MR=MR+MX0*MY0 (us); /* Add Area */ rightArea: nop; dm(areaB1)=MR1; /* Store Back Area Upper 16 Bits */ dm(areaB0)=MR0; /* Lower 16 Bits */ /* ---------------------------------------------- */ /* Calculate Outputs: */
24
/* *Width (stopTime - startTime) */ /* *(F-B)/(F+B) (Areas, result -1 to 1) */ /* *Norm Moment (NM/((FA+BA)*(stpT-strT)^2/12)) */ /* where NM = momentFront+momentBack */ /* ---------------------------------------------- */ /* --- Calculate Width --- */ /* --- 1st Parameter --- */ /* Calculate Width */ AX0=I3; /* Back Address */ AY0=I2; /* Front Address */ AR=AX0-AY0; dm(outWidth)=AR; dm(UretVal)=AR; /* FIRST PARAMTER */ /* --- Calculate F-B/F+B --- */ /* --- 2nd Paramter --- */ /* Calculate F-B and F+B */ AX1=dm(areaF1); /* Get Front Area */ AX0=dm(areaF0); AY1=dm(areaB1); /* Get Back Area */ AY0=dm(areaB0); /* F+B (32bit addition) */ AR=AX0+AY0; /* Add Low Words */ dm(FplusB0)=AR; /* Store Low Side */ AR=AX1+AY1+C; /* Add High Words + Carry */ dm(FplusB1)=AR; /* Store High Side */ /* F-B (32bit subtraction) */ AR=0; AR=AX0-AY0; /* Subtract Low Words */ dm(FminusB0)=AR; /* Store Low Side */ AR=AX1-AY1+C-1; /* Add High Words + Carry */ dm(FminusB1)=AR; /* Scale Result of Bottom portion of NM to 16 bits */ AX0=dm(FplusB1); /* Load High Side of Divisor */ AY0=0; AR=AX0 OR AY0; if EQ JUMP uselowerAsym; AR=dm(FplusB1); MR0=dm(FplusB0); MR1=dm(FplusB1); SE=exp AR (HI); /* Find exp */ AX1=SE; /* Store Shift */ AR=AX1; AR=-AR; /* Change Direction */ dm(asymShift)=AR; /* Store Shift (Shift HI Word by this much)*/ SE=AR; SI=MR1; /* Set Shift Input */ SR=LSHIFT SI (LO); /* Shift High Word */ AR=SR0;
25
SI=MR0; SE=dm(asymShift); SR=LSHIFT SI (LO); /* Shift Low Word */ AY0=SR1; AR=AR OR AY0; dm(asymBot)=AR; AX0=dm(asymBot); /* Load Denominator */ AY0=dm(FminusB0); /* Load Numerator Low Word */ AY1=dm(FminusB1); /* Load Numerator Hi Word */ JUMP normalizedAsym; uselowerAsym: AR=dm(FplusB0); /* Just use lower word */ dm(asymBot)=AR; AR=15; dm(asymShift)=AR; AX0=dm(asymBot); AY0=0x0000; AY1=dm(FminusB0); normalizedAsym: /* (F-B/F+B) */ DIVS AY1,AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; AR=AY0; dm(UretVal+1)=AR; /* SECOND PARAMETER */ AR=dm(asymShift); dm(UretVal+4)=AR; /* --- Calculate Normalized Moment --- */ /* --- 3rd Paramter --- */ /* - (NM/((FA+BA)*(stpT-strT)^2/12)) - */ MR=0; AR=dm(outWidth); MX0=AR; /* Width */ MY0=AR; /* Width */ MR=MR+MX0*MY0 (uu); /* Width^2 */ MX0=MR0; /* Store Lower 16 bits */ MR=0; AR=dm(FplusB0); /* Load lower 16bits of F+B */ MY0=AR; MR=MX0*MY0 (uu); /* Calculate (FA+FB)*(stpT-StrT)^2 */ /* Scale Result of Bottom portion of NM to 16 bits */ AX0=MR1; AY0=0; AR=AX0 OR AY0; if EQ JUMP uselower;
26
AR=MR1; SE=exp AR (HI); /* Find exp */ AX1=SE; /* Store Shift */ AR=AX1; AR=-AR; /* Change Direction */ dm(momShift)=AR; /* Store Shift (Shift HI Word by this much)*/ SE=AR; SI=MR1; /* Set Shift Input */ SR=LSHIFT SI (LO); /* Shift High Word */ AR=SR0; SI=MR0; SE=dm(momShift); SR=LSHIFT SI (LO); /* Shift Low Word */ AY0=SR1; AR=AR OR AY0; dm(momBot)=AR; JUMP normalized; uselower: dm(momBot)=MR0; AR=0; dm(momShift)=AR; normalized: /* Multiply Total Moment by 12 */ /* 32-Bit addition 12 times */ AX1=dm(totMoment1); /* Get Total Moment */ AX0=dm(totMoment0); AY1=dm(totMoment1); /* Get Total Moment */ AY0=dm(totMoment0); CNTR=11; DO momMult UNTIL CE; AR=AX0+AY0; /* Add Low Words */ AX0=AR; /* Save New Low Word */ AR=AX1+AY1+C; /* Add High Words + Carry */ AX1=AR; /* Save New High Word */ momMult: nop; dm(totMoment0)=AX0; /* Low Word */ dm(totMoment1)=AX1; /* High Word */ /* Total Moment/(FA+FB)*(StpT-strT)^2 */ AX0=dm(momBot); /* Load Lo 16 bits Divisor */ AY0=dm(totMoment0); /* Load Lo 16 bits of Dividend */ AY1=dm(totMoment1); /* Load Hi 16 bits of Dividend */ AF=PASS AY1; /* Pass to AF register for unsigned */ ASTAT=0; /* Clear for Unsigned Divide */ DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; DIVQ AX0; AR=AY0; dm(UretVal+2)=AR; /* THIRD PARAMETER */
27
AR=dm(momShift); AX0=16; AY0=AR; AR=AX0-AY0; AR=AR-1; dm(UretVal+3)=AR; /* Store Shift */ /* Set Registers Back to Default Value */ I0 = dm(saveI0); I1 = dm(saveI1); I3 = dm(saveI3); I4 = dm(saveI4); M3 = dm(saveM3); L4 = dm(saveL4); L3 = dm(saveL3); JUMP UserChannelReturn; /*--------------------------------------------------------------------- + + UserEvent is called after the regular event processing has finished, + and only if for at least one channel bit 0 of ChanCSRB was set. + ----------------------------------------------------------------------*/ UserEvent: nop; /* user program instructions */ JUMP UserEventReturn; /*--------------------------------------------------------------------- + + UserRunFinish is called after the run has ended, but before the host + is notified,but only if for at least one channel bit 0 of ChanCSRB + was set. + ----------------------------------------------------------------------*/ UserRunFinish: nop; /* user program instructions */ JUMP UserRunFinishReturn; .EndMod;
28