1
2 package hep.wired.heprep.projection;
3
4 import javax.swing.event.*;
5
6 import hep.wired.feature.Resetable;
7 import hep.wired.variable.DoubleVariable;
8 import hep.wired.variable.BooleanVariable;
9
10 import hep.wired.heprep.services.Projection;
11
12 /***
13 * Projects R : sqrt(x^2 + y^2) and Z.
14 *
15 * @author Mark Donszelmann
16 * @version $Id: RhoZProjection.java 2164 2005-08-02 23:27:44Z duns $
17 */
18
19 public class RhoZProjection extends VariableProjection implements Resetable {
20
21 private static final double PI2 = Math.PI*2;
22
23 private double[] uvw = new double[3];
24
25 private DoubleVariable varPhi0;
26 private double phi0, resetPhi0;
27 private BooleanVariable varSplitPhi;
28 private boolean splitPhi, resetSplitPhi;
29
30
31 public RhoZProjection() {
32 this(0, 0, true, true);
33 }
34
35 private RhoZProjection(double phi0, double resetPhi0, boolean splitPhi, boolean resetSplitPhi) {
36 super("RhoZProjection");
37 varPhi0 = addVariable("phi0", 0.0, 180, phi0, "degrees", "Angle at which to slice detector into two halves.");
38 varSplitPhi = addVariable("splitPhi", splitPhi, "Slice detector into two halves.");
39
40 varSplitPhi.addChangeListener(new ChangeListener() {
41 public void stateChanged(ChangeEvent e) {
42 varPhi0.setEnabled(varSplitPhi.getBooleanVariable());
43 }
44 });
45 varPhi0.setEnabled(splitPhi);
46
47 this.phi0 = phi0;
48 this.resetPhi0 = resetPhi0;
49 this.splitPhi = splitPhi;
50 this.resetSplitPhi = resetSplitPhi;
51 }
52
53 public String getFormula() {
54 return "(u,v,w) = "+
55 "z, "+
56 "sqrt(x^2 + y^2), "+
57 "0";
58 }
59
60 public double[] transform(double[] xyz) {
61 double phi = Math.atan2(xyz[Y], xyz[X]);
62 int sign = getSign(phi);
63
64 xyz = transform(xyz, sign);
65 return xyz;
66 }
67
68 public double[][] transform(double[][] xyz, int n) {
69 if (n == 0) return xyz;
70
71 int sign = 0;
72 for (int i=0; i<n; i++) {
73 if (xyz[X][i] != 0) {
74 double phi = Math.atan2(xyz[Y][i], xyz[X][i]);
75 sign += getSign(phi);
76 }
77 }
78 sign = (sign >= 0) ? +1 : -1;
79
80 for (int i=0; i<n; i++) {
81 uvw[U] = xyz[X][i];
82 uvw[V] = xyz[Y][i];
83 uvw[W] = xyz[Z][i];
84 uvw = transform(uvw, sign);
85 xyz[U][i] = uvw[U];
86 xyz[V][i] = uvw[V];
87 xyz[W][i] = uvw[W];
88 }
89 return xyz;
90 }
91
92 private int getSign(double phi) {
93 phi = (phi + PI2) % PI2;
94 phi = phi - Math.toRadians(phi0);
95 phi = (phi + PI2) % PI2;
96 return phi <= Math.PI ? +1 : -1;
97 }
98
99 private double[] transform(double[] xyz, int sign) {
100 double x = xyz[X];
101 double y = xyz[Y];
102 double z = xyz[Z];
103
104 double rho = Math.sqrt((x*x) + (y*y));
105
106 xyz[U] = z;
107 xyz[V] = (splitPhi) ? sign*rho : rho;
108 xyz[W] = 1;
109
110 return xyz;
111 }
112
113 public double[] deltaTransform(double[] xyz) {
114 return transform(xyz);
115 }
116
117 public double[] inverseTransform(double[] uvw) throws UnsupportedOperationException {
118 throw new UnsupportedOperationException("No inverse transform on "+getClass());
119 }
120
121 public double[] inverseDeltaTransform(double[] uvw) throws UnsupportedOperationException {
122 return inverseTransform(uvw);
123 }
124
125 public Projection copy() {
126 return new RhoZProjection(phi0, resetPhi0, splitPhi, resetSplitPhi);
127 }
128
129
130 public Object reset(Object newState) {
131 Object oldState = new Object[] { new Double(phi0), new Boolean(splitPhi) };
132 if (newState == null) {
133 phi0 = resetPhi0;
134 splitPhi = resetSplitPhi;
135 } else {
136 Object[] array = (Object[])newState;
137 phi0 = ((Double)array[0]).doubleValue();
138 splitPhi = ((Boolean)array[1]).booleanValue();
139
140 }
141 varPhi0.setEnabled(splitPhi);
142 return oldState;
143 }
144
145 }