1
2
3
4 package de.desy.acop.video;
5
6 import java.awt.Graphics;
7 import java.awt.Graphics2D;
8 import java.awt.geom.GeneralPath;
9 import java.awt.geom.Line2D;
10 import java.awt.geom.Rectangle2D;
11
12 import javax.swing.JPanel;
13
14
15
16
17
18
19
20
21
22 public class SideProfileDisplayer extends JPanel {
23
24 private static final long serialVersionUID = 1L;
25
26 private boolean horizontalOrientation = true;
27
28 private double[] profile = null;
29 private double[] gaussProfile = null;
30 private double[] gaussProfileFit = null;
31 private double max;
32 private double min;
33
34 private double canvasStart = 0;
35 private double canvasSize = 0;
36 private int roiStart = -1;
37 private int roiLength = -1;
38 private double roi1 = Double.NaN;
39 private double roi2 = Double.NaN;
40
41 private boolean displayStatistics = true;
42
43 private Object mutex = new Object();
44
45
46
47
48
49
50
51 public SideProfileDisplayer(boolean horizontalOrientation) {
52 this.horizontalOrientation = horizontalOrientation;
53 setBackground(Definitions.getBackgroundColor());
54 }
55
56
57
58
59
60
61
62
63
64
65
66 @SuppressWarnings({"null"})
67 public void setData(double[] profile, double amplitude, double mean, double std, double constant,
68 double amplitudeFit, double meanFit, double stdFit, double constantFit, double slopeFit, int roiStart, int roiLength,
69 boolean drawFit) {
70 this.profile = profile;
71 this.roiStart = roiStart;
72 this.roiLength = roiLength;
73
74 int length = profile.length;
75 if (roiStart < 0 || roiLength < 0 || roiStart+roiLength > length) throw new IllegalStateException("Illegal region of interest!");
76
77 int i = 0;
78 double[] statProfile = new double[roiLength];
79 double[] fitProfile = null;
80 if (drawFit) {
81 fitProfile = new double[roiLength];
82 for(; i < roiLength; i++) {
83 statProfile[i] = amplitude*Math.exp(-(roiStart+i-mean)*(roiStart+i-mean)/(2*std*std))+constant;
84 fitProfile[i] = amplitudeFit*Math.exp(-(roiStart+i-meanFit)*(roiStart+i-meanFit)/(2*stdFit*stdFit))+constantFit + (roiStart+i)*slopeFit;
85 }
86 } else {
87 for(; i < roiLength; i++) {
88 statProfile[i] = amplitude*Math.exp(-(roiStart+i-mean)*(roiStart+i-mean)/(2*std*std))+constant;
89 }
90 }
91
92 min = Double.MAX_VALUE;
93 max = -Double.MAX_VALUE;
94 for (i = 0; i < length; i++) {
95 if (profile[i] < min) min = profile[i];
96 if (profile[i] > max) max = profile[i];
97 }
98 if (drawFit) {
99 for (i = 0; i < roiLength; i++) {
100 if (statProfile[i] < min) min = statProfile[i];
101 if (statProfile[i] > max) max = statProfile[i];
102 if (fitProfile[i] < min) min = fitProfile[i];
103 if (fitProfile[i] > max) max = fitProfile[i];
104 }
105 } else {
106 for (i = 0; i < roiLength; i++) {
107 if (statProfile[i] < min) min = statProfile[i];
108 if (statProfile[i] > max) max = statProfile[i];
109 }
110 }
111 synchronized(mutex) {
112 if (drawFit) {
113 gaussProfileFit = fitProfile;
114 gaussProfile = statProfile;
115 } else {
116 gaussProfile = statProfile;
117 gaussProfileFit = null;
118 }
119 }
120
121 repaint();
122 }
123
124
125
126
127 public void clearData() {
128 profile = null;
129 gaussProfile = null;
130 gaussProfileFit = null;
131 min = Double.MAX_VALUE;
132 max = -Double.MAX_VALUE;
133
134 canvasStart = 0;
135 canvasSize = 0;
136 roiStart = -1;
137 roiLength = -1;
138 roi1 = Double.NaN;
139 roi2 = Double.NaN;
140
141 repaint();
142 }
143
144
145
146
147
148
149 public void setRoi(double c1, double c2) {
150 roi1 = c1;
151 roi2 = c2;
152 repaint();
153 }
154
155 public void setCanvasSize(double start, double size, boolean repaintAtOnce) {
156 canvasSize = size;
157 canvasStart = start;
158 if (repaintAtOnce) repaint();
159 }
160
161 public void setCanvasStart(double start) {
162 if (canvasStart == start) return;
163 canvasStart = start;
164 repaint();
165 }
166
167
168
169
170 public void clearRoi() {
171 roi1 = Double.NaN;
172 roi2 = Double.NaN;
173 repaint();
174 }
175
176 @Override
177 protected void paintComponent(Graphics g) {
178 super.paintComponent(g);
179 drawProfile((Graphics2D) g);
180 drawRoi((Graphics2D) g);
181 }
182
183 void setDisplayStatistics(boolean display) {
184 this.displayStatistics = display;
185 repaint();
186 }
187
188 private void drawProfile(Graphics2D g) {
189 if (gaussProfile == null || gaussProfile.length == 0) return;
190 int i = 0;
191 int length = profile.length;
192
193 double coeff = (horizontalOrientation ? getHeight() : getWidth())/(max-min);
194 double delta = canvasSize/(length-1);
195
196 GeneralPath dataPath = new GeneralPath();
197 GeneralPath statisticsPath = new GeneralPath();
198 GeneralPath fitPath = new GeneralPath();
199 double x, y;
200 synchronized (mutex) {
201 if (horizontalOrientation) {
202 for (i = 0; i < length; i++) {
203 x = canvasStart+i*delta;
204 y = getHeight()-(profile[i]-min)*coeff;
205 if (i == 0) dataPath.moveTo(x, y);
206 else dataPath.lineTo(x, y);
207 }
208 for (i = 0; i < roiLength; i++) {
209 x = canvasStart+(roiStart+i)*delta;
210 y = getHeight()-(gaussProfile[i]-min)*coeff;
211 if (i == 0) statisticsPath.moveTo(x, y);
212 else statisticsPath.lineTo(x, y);
213 }
214 if (gaussProfileFit != null) {
215 for (i = 0; i < roiLength; i++) {
216 x = canvasStart+(roiStart+i)*delta;
217 y = getHeight()-(gaussProfileFit[i]-min)*coeff;
218 if (i == 0) fitPath.moveTo(x, y);
219 else fitPath.lineTo(x, y);
220 }
221 }
222 } else {
223 for (i = 0; i < length; i++) {
224 x = canvasStart+i*delta;
225 y = getWidth()-(profile[i]-min)*coeff;
226 if (i == 0) dataPath.moveTo(y, x);
227 else dataPath.lineTo(y, x);
228 }
229 for (i = 0; i < roiLength; i++) {
230 x = canvasStart+(roiStart+i)*delta;
231 y = getWidth()-(gaussProfile[i]-min)*coeff;
232 if (i == 0) statisticsPath.moveTo(y, x);
233 else statisticsPath.lineTo(y, x);
234 }
235 if (gaussProfileFit != null) {
236 for (i = 0; i < roiLength; i++) {
237 x = canvasStart+(roiStart+i)*delta;
238 y = getWidth()-(gaussProfileFit[i]-min)*coeff;
239 if (i == 0) fitPath.moveTo(y,x);
240 else fitPath.lineTo(y,x);
241 }
242 }
243 }
244 }
245
246 double x1 = horizontalOrientation ? canvasStart : 0;
247 double y1 = horizontalOrientation ? 0 : canvasStart;
248 double x2 = horizontalOrientation ? canvasSize : getWidth();
249 double y2 = horizontalOrientation ? getHeight() : canvasSize;
250 Rectangle2D r = new Rectangle2D.Double(x1, y1, x2, y2);
251 g.setPaint(Definitions.getCanvasColor());
252 g.fill(r);
253
254 g.setPaint(Definitions.getDataColor());
255 g.draw(dataPath);
256 if (gaussProfileFit != null) {
257 g.setPaint(Definitions.getFitColor());
258 g.draw(fitPath);
259 }
260 if (displayStatistics) {
261 g.setPaint(Definitions.getStatisticsColor());
262 g.draw(statisticsPath);
263 }
264
265 double p1 = canvasStart+roiStart*delta;
266 double p2 = canvasStart+(roiStart+roiLength-1)*delta;
267
268 x1 = horizontalOrientation ? p1 : 0;
269 y1 = horizontalOrientation ? 0 : p1;
270 x2 = horizontalOrientation ? p1 : getWidth();
271 y2 = horizontalOrientation ? getHeight() : p1;
272 Line2D l1 = new Line2D.Double(x1, y1, x2, y2);
273 x1 = horizontalOrientation ? p2 : 0;
274 y1 = horizontalOrientation ? 0 : p2;
275 x2 = horizontalOrientation ? p2 : getWidth();
276 y2 = horizontalOrientation ? getHeight() : p2;
277 Line2D l2 = new Line2D.Double(x1, y1, x2, y2);
278
279 g.setPaint(Definitions.getRoiColor());
280 g.draw(l1);
281 g.draw(l2);
282
283 }
284
285 private void drawRoi(Graphics2D g) {
286 if (!Double.isNaN(roi1) && !Double.isNaN(roi2)) {
287 double x1 = horizontalOrientation ? roi1 : 0;
288 double y1 = horizontalOrientation ? 0 : roi1;
289 double x2 = horizontalOrientation ? roi1 : getWidth();
290 double y2 = horizontalOrientation ? getHeight() : roi1;
291 Line2D l1 = new Line2D.Double(x1, y1, x2, y2);
292 x1 = horizontalOrientation ? roi2 : 0;
293 y1 = horizontalOrientation ? 0 : roi2;
294 x2 = horizontalOrientation ? roi2 : getWidth();
295 y2 = horizontalOrientation ? getHeight() : roi2;
296 Line2D l2 = new Line2D.Double(x1, y1, x2, y2);
297
298 g.setPaint(Definitions.getRoiSelectingColor());
299 g.draw(l1);
300 g.draw(l2);
301 }
302 }
303
304 }