-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBasicExtraction.java
More file actions
205 lines (171 loc) · 6.74 KB
/
BasicExtraction.java
File metadata and controls
205 lines (171 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
package fact.extraction;
import fact.Constants;
import fact.Utils;
import fact.calibrationservice.SinglePulseGainCalibService;
import org.jfree.chart.plot.IntervalMarker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stream.Data;
import stream.Processor;
import stream.annotations.Parameter;
import stream.annotations.Service;
/**
* This processor performs a basic extraction on the data array. It contains three steps:
* 1. Calculates the position of the max amplitude in [startSearchWindow,startSearchWindow+rangeSearchWindow[
* 2. Calculates the position of the half height in front of the maxAmplitudePosition
* 3. Calculates the integral by summing up the following integrationWindow slices beginning with the half heigth position
* The resulting photoncharge is calculated by dividing the integral by the integralGain of the pixel
*
* This processor also serves as a basic class for extraction processors
*
* @author Fabian Temme
*
*/
public class BasicExtraction implements Processor {
static Logger log = LoggerFactory.getLogger(BasicExtraction.class);
@Parameter(required = true, description="key to the data array")
protected String dataKey = null;
@Parameter(required = true, description="outputKey for the position of the max amplitudes")
protected String outputKeyMaxAmplPos = null;
@Parameter(required = true, description="outputKey for the calculated photoncharge")
protected String outputKeyPhotonCharge = null;
@Service(required = true, description = "The calibration service for the integral single pulse gain")
SinglePulseGainCalibService gainService;
@Parameter(required = false, description="start slice of the search window for the max amplitude", defaultValue="35")
protected int startSearchWindow = 35;
@Parameter(required = false, description="range of the search window for the max amplitude", defaultValue="90")
protected int rangeSearchWindow = 90;
@Parameter(required = false, description="range of the search window for the half heigt position", defaultValue="25")
protected int rangeHalfHeightWindow = 25;
@Parameter(required = false, description="range of the integration window", defaultValue="30")
protected int integrationWindow = 30;
@Parameter(required = false, description="minimal slice with valid values (we want to ignore slices below this value", defaultValue="10")
protected int validMinimalSlice = 10;
protected double[] integralGains = null;
private int npix = Constants.NUMBEROFPIXEL;
@Override
public Data process(Data input) {
Utils.mapContainsKeys(input, dataKey,"NROI");
int roi = (Integer) input.get("NROI");
npix = (Integer) input.get("NPIX");
integralGains = gainService.getIntegralSinglePulseGain();
double[] data = (double[]) input.get(dataKey);
int[] positions = new int[npix];
IntervalMarker[] mPositions = new IntervalMarker[npix];
double[] photonCharge = new double[npix];
IntervalMarker[] mPhotonCharge = new IntervalMarker[npix];
Utils.checkWindow(startSearchWindow, rangeSearchWindow, rangeHalfHeightWindow+validMinimalSlice, roi);
for (int pix = 0; pix < npix; pix++) {
positions[pix] = calculateMaxPosition(pix, startSearchWindow, startSearchWindow+rangeSearchWindow, roi, data);
mPositions[pix] = new IntervalMarker(positions[pix],positions[pix] + 1);
int halfHeightPos = calculatePositionHalfHeight(pix, positions[pix],positions[pix]-rangeHalfHeightWindow, roi, data);
Utils.checkWindow(halfHeightPos, integrationWindow, validMinimalSlice, roi);
photonCharge[pix] = calculateIntegral(pix, halfHeightPos, integrationWindow, roi, data) / integralGains[pix];
mPhotonCharge[pix] = new IntervalMarker(halfHeightPos,halfHeightPos + integrationWindow);
}
input.put(outputKeyMaxAmplPos, positions);
input.put(outputKeyMaxAmplPos + "Marker", mPositions);
input.put(outputKeyPhotonCharge, photonCharge);
input.put("@photoncharge", photonCharge);
input.put(outputKeyPhotonCharge + "Marker", mPhotonCharge);
return input;
}
public int calculateMaxPosition(int px, int start, int rightBorder, int roi, double[] data) {
int maxPos = start;
double tempMax = -Double.MAX_VALUE;
for (int sl = start ; sl < rightBorder ; sl++)
{
int pos = px * roi + sl;
if (data[pos] > tempMax)
{
maxPos = sl;
tempMax = data[pos];
}
}
return maxPos;
}
/**
* In an area ]amplitudePositon-leftBorder,amplitudePosition] searches for the last position, where data[pos] is < 0.5 *
* maxAmplitude. Returns the following slice.
*
* @param px
* @param maxPos
* @param leftBorder
* @param roi
* @param data
* @return
*/
public int calculatePositionHalfHeight(int px, int maxPos, int leftBorder, int roi, double[] data) {
int slice = maxPos;
double maxHalf = data[px*roi+maxPos] / 2.0;
for (; slice > leftBorder ; slice--)
{
int pos = px * roi + slice;
if (data[pos-1] < maxHalf)
{
break;
}
}
return slice;
}
public double calculateIntegral(int px, int startingPosition, int integralSize, int roi, double[] data) {
double integral = 0;
for (int sl = startingPosition ; sl < startingPosition + integralSize ; sl++)
{
int pos = px*roi + sl;
integral += data[pos];
}
return integral;
}
public String getDataKey() {
return dataKey;
}
public void setDataKey(String dataKey) {
this.dataKey = dataKey;
}
public void setGainService(SinglePulseGainCalibService gainService) {
this.gainService = gainService;
}
public String getOutputKeyMaxAmplPos() {
return outputKeyMaxAmplPos;
}
public void setOutputKeyMaxAmplPos(String outputKeyMaxAmplPos) {
this.outputKeyMaxAmplPos = outputKeyMaxAmplPos;
}
public String getOutputKeyPhotonCharge() {
return outputKeyPhotonCharge;
}
public void setOutputKeyPhotonCharge(String outputKeyPhotonCharge) {
this.outputKeyPhotonCharge = outputKeyPhotonCharge;
}
public int getStartSearchWindow() {
return startSearchWindow;
}
public void setStartSearchWindow(int startSearchWindow) {
this.startSearchWindow = startSearchWindow;
}
public int getRangeSearchWindow() {
return rangeSearchWindow;
}
public void setRangeSearchWindow(int rangeSearchWindow) {
this.rangeSearchWindow = rangeSearchWindow;
}
public int getRangeHalfHeightWindow() {
return rangeHalfHeightWindow;
}
public void setRangeHalfHeightWindow(int rangeHalfHeightWindow) {
this.rangeHalfHeightWindow = rangeHalfHeightWindow;
}
public int getIntegrationWindow() {
return integrationWindow;
}
public void setIntegrationWindow(int integrationWindow) {
this.integrationWindow = integrationWindow;
}
public int getValidMinimalSlice() {
return validMinimalSlice;
}
public void setValidMinimalSlice(int validMinimalSlice) {
this.validMinimalSlice = validMinimalSlice;
}
}