9 template<
class T> T
sqr(T
x){
return x*
x;}
13 : fChannel(chan), fCharge(q), fPred(0)
19 : fSC(sc), fCoupling(coupling)
27 : fX(x), fY(y), fZ(z),
28 fCWire(cwire), fWire1(wire1), fWire2(wire2),
40 nei.fSC->fNeiPotential += dq * nei.fCoupling;
48 const std::vector<SpaceCharge*>&
cross)
49 : fChannel(chan), fCharge(q), fCrossings(cross)
52 std::cout <<
"Trying to construct collection wire with negative charge " << q <<
" this should never happen." << std::endl;
56 const double p = q/cross.size();
83 double Metric(
const std::vector<SpaceCharge*>& scs,
double alpha)
87 std::set<InductionWireHit*> iwires;
89 if(sc->fWire1) iwires.insert(sc->fWire1);
90 if(sc->fWire2) iwires.insert(sc->fWire2);
93 ret -= alpha*
sqr(sc->fPred);
96 ret -= alpha * sc->fPred * sc->fNeiPotential;
101 ret +=
Metric(iwire->fCharge, iwire->fPred);
108 double Metric(
const std::vector<CollectionWireHit*>& cwires,
double alpha)
110 std::vector<SpaceCharge*> scs;
112 scs.insert(scs.end(), cwire->fCrossings.begin(), cwire->fCrossings.end());
113 return Metric(scs, alpha);
125 const double scip = sci->
fPred;
126 const double scjp = scj->
fPred;
129 ret -= alpha*
sqr(scip + x);
130 ret -= alpha*
sqr(scjp - x);
141 ret += 2 * alpha * (scip +
x) * scjp * n.
fCoupling;
142 ret += 2 * alpha * (scjp - x) * scip * n.
fCoupling;
145 ret -= 2 * alpha * (scip +
x) * (scjp - x) * n.
fCoupling;
155 const double qi1 = iwire1 ? iwire1->
fCharge : 0;
156 const double pi1 = iwire1 ? iwire1->
fPred : 0;
158 const double qj1 = jwire1 ? jwire1->
fCharge : 0;
159 const double pj1 = jwire1 ? jwire1->
fPred : 0;
161 if(iwire1 == jwire1){
163 if(iwire1) ret +=
Metric(qi1, pi1);
166 if(iwire1) ret +=
Metric(qi1, pi1 + x);
167 if(jwire1) ret +=
Metric(qj1, pj1 - x);
173 const double qi2 = iwire2 ? iwire2->
fCharge : 0;
174 const double pi2 = iwire2 ? iwire2->
fPred : 0;
176 const double qj2 = jwire2 ? jwire2->
fCharge : 0;
177 const double pj2 = jwire2 ? jwire2->
fPred : 0;
179 if(iwire2 == jwire2){
180 if(iwire2) ret +=
Metric(qi2, pi2);
183 if(iwire2) ret +=
Metric(qi2, pi2 + x);
184 if(jwire2) ret +=
Metric(qj2, pj2 - x);
199 const double scp = sc->
fPred;
202 ret -= alpha*
sqr(scp + x);
222 const double chisq0 = chisq.
Eval(0);
228 const double xmin = -sci->
fPred;
229 const double xmax = scj->
fPred;
235 const double chisq_new = chisq.
Eval(x);
240 const double chisq_p = chisq.
Eval(xmax);
241 const double chisq_n = chisq.
Eval(xmin);
244 std::cout <<
"Solution at " << x <<
" is worse than current state! Scan from " << xmin <<
" to " << xmax << std::endl;
245 for(
double x = xmin; x < xmax; x += .01*(xmax-xmin)){
246 std::cout << x <<
" " << chisq.
Eval(x) << std::endl;
249 std::cout <<
"Soln, original, up edge, low edge:" << std::endl;
250 std::cout << chisq_new <<
" " << chisq0 <<
" " << chisq_p <<
" " << chisq_n << std::endl;
254 if(
std::min(chisq_n, chisq_p) < chisq_new){
255 if(chisq_n < chisq_p)
return xmin;
266 const unsigned int N = cwire->
fCrossings.size();
268 for(
unsigned int i = 0; i+1 < N; ++i){
271 for(
unsigned int j = i+1; j < N; ++j){
274 const double x =
SolvePair(cwire, sci, scj, alpha);
294 const double xmin = -sc->
fPred;
299 const double chisq_new = chisq.
Eval(x);
304 const double chisq_n = chisq.
Eval(xmin);
306 if(chisq_n < chisq_new)
313 void Iterate(
const std::vector<CollectionWireHit*>& cwires,
314 const std::vector<SpaceCharge*>& orphanSCs,
319 unsigned int cwireIdx = 0;
321 Iterate(cwires[cwireIdx], alpha);
323 const unsigned int prime = 1299827;
324 cwireIdx = (cwireIdx+prime)%cwires.size();
325 }
while(cwireIdx != 0);
void AddCharge(double dq)
std::vector< Neighbour > fNeighbours
SpaceCharge(double x, double y, double z, CollectionWireHit *cwire, InductionWireHit *wire1, InductionWireHit *wire2)
double fNeiPotential
Neighbour-induced potential.
void Iterate(CollectionWireHit *cwire, double alpha)
std::vector< SpaceCharge * > fCrossings
double SolvePair(CollectionWireHit *cwire, SpaceCharge *sci, SpaceCharge *scj, double alpha)
InductionWireHit * fWire2
InductionWireHit * fWire1
double Metric(double q, double p)
Neighbour(SpaceCharge *sc, double coupling)
InductionWireHit(int chan, double q)
double Eval(double x) const
Vector cross(Vector const &a, Vector const &b)
Return cross product of two vectors.
CollectionWireHit(int chan, double q, const std::vector< SpaceCharge * > &cross)