1 package org.lcsim.mc.fast.cluster.ronan;
2
3 import org.lcsim.mc.fast.MCFast;
4 import hep.physics.particle.Particle;
5 import java.util.Collections;
6 import java.util.List;
7 import java.util.Random;
8 import org.lcsim.event.Cluster;
9
10 public abstract class ReconCluster implements Cluster {
11 protected ClusterResolutionTables parm;
12 protected Particle mcp;
13 protected double a = 0;
14 protected double b = 0;
15 protected double c = 0;
16 protected double d = 0;
17 protected double energy;
18 protected double energyError;
19 protected double neg_energy;
20 protected double sigma;
21 protected double phi;
22 protected double radius;
23 protected double theta;
24 protected double transDist;
25
26 ReconCluster(ClusterResolutionTables parm, Random rand, Particle mcp, boolean hist) {
27 this.parm = parm;
28 this.mcp = mcp;
29 }
30
31
32 public double getEnergy() {
33 return energy;
34 }
35
36 public double getEnergyError() {
37 return energyError;
38 }
39
40 public void setEnergyError(double energyError) {
41 this.energyError = energyError;
42 }
43
44 public double getNegEnergy() {
45 return neg_energy;
46 }
47
48 public double getSigma() {
49 return sigma;
50 }
51
52 public void adjustEnergy(double neg_energy_total, double pos_energy_weight_total) {
53 MCFast.log.info(" min(sigma,energy)=" + Math.min(sigma, energy) + " ratio= " + (Math.min(sigma, energy) / pos_energy_weight_total) + " before adjust energy= " + energy);
54 energy += neg_energy_total * Math.min(sigma, energy) / pos_energy_weight_total;
55
56 if (energy <= mcp.getMass())
57 energy = mcp.getMass() + Double.MIN_VALUE;
58
59 MCFast.log.info(" neg_energy_total= " + neg_energy_total + " after adjust energy= " + energy);
60 }
61
62 protected void smear(Random rand, boolean hist) {
63
64 double E = mcp.getEnergy();
65
66
67
68 smearEnergy(rand, E, hist);
69
70
71 smearPosition(rand, E, hist);
72 }
73
74 protected void smearEnergy(Random rand, double E, boolean hist) {
75 sigma = Math.sqrt(Math.pow(a, 2.) * E + Math.pow(b * E, 2.));
76
77 energy = E + (sigma * rand.nextGaussian());
78 if (energy <= mcp.getMass()) {
79 neg_energy = energy - mcp.getMass();
80 energy = mcp.getMass() + Double.MIN_VALUE;
81 } else {
82 neg_energy = 0.;
83 }
84 }
85
86 protected void smearPosition(Random rand) {
87
88 double Px = mcp.getPX();
89 double Py = mcp.getPY();
90 double Pz = mcp.getPZ();
91
92 double P = Math.sqrt((Px * Px) + (Py * Py) + (Pz * Pz));
93 double Phi = Math.atan2(Py, Px);
94 if (Phi < 0) {
95 Phi += (2 * Math.PI);
96 }
97
98 double Theta = Math.acos(Pz / P);
99
100
101 radius = 2000.0;
102
103 double x = (radius * Px) / P;
104 double y = (radius * Py) / P;
105 double z = (radius * Pz) / P;
106
107
108
109 double[] vt = { -Math.cos(Theta) * Math.cos(Phi), -Math.cos(Theta) * Math.sin(Phi), Math.sin(Theta) };
110 double[] vs = { Math.sin(Phi), -Math.cos(Phi), 0 };
111
112
113 double alpha = rand.nextDouble() * Math.PI;
114 x = x + transDist * (Math.cos(alpha) * vt[0] + Math.sin(alpha) * vs[0]);
115 y = y + transDist * (Math.cos(alpha) * vt[1] + Math.sin(alpha) * vs[1]);
116 z = z + transDist * (Math.cos(alpha) * vt[2] + Math.sin(alpha) * vs[2]);
117
118 phi = Math.atan2(y, x);
119 if (phi < 0) {
120 phi += (2 * Math.PI);
121 }
122 theta = Math.acos(z / radius);
123 }
124
125 public Particle getMCParticle() {
126 return mcp;
127 }
128
129 abstract void smearPosition(Random rand, double E, boolean hist);
130
131 public double[] getHitContributions() {
132 return null;
133 }
134
135 public List getClusters() {
136 return Collections.EMPTY_LIST;
137 }
138
139 public double[] getSubdetectorEnergies() {
140 return null;
141 }
142
143 public double[] getPositionError() {
144 return null;
145 }
146
147 public int getType() {
148 return 0;
149 }
150
151 public double getITheta() {
152 return 0;
153 }
154
155 public double getIPhi() {
156 return 0;
157 }
158
159 public double[] getDirectionError() {
160 return null;
161 }
162
163 public List getCalorimeterHits() {
164 return Collections.EMPTY_LIST;
165 }
166
167 public double[] getShape() {
168 return null;
169 }
170
171 public double[] getPosition() {
172 double x = radius * Math.sin(theta) * Math.cos(phi);
173 double y = radius * Math.sin(theta) * Math.sin(phi);
174 double z = radius * Math.cos(theta);
175 return new double[] { x, y, z };
176 }
177
178 public double[] getParticleType() {
179 return null;
180 }
181
182 public int getParticleId() {
183 return 0;
184 }
185
186 public int getSize() {
187 return 0;
188 }
189 }