00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TrkReco/TTrack.h"
00014 #include "TrkReco/TSegment.h"
00015 #include "TrkReco/TMDCUtil.h"
00016 #include "TrkReco/TMLink.h"
00017 #include "TrkReco/TMDC.h"
00018 #include "TrkReco/TMDCWire.h"
00019 #include "TrkReco/TMDCWireHit.h"
00020
00021 #include "TrkReco/Range.h"
00022
00023 #include "CLHEP/Vector/ThreeVector.h"
00024 #include <math.h>
00025 #include "CLHEP/Matrix/Vector.h"
00026
00027 TMDC *
00028 TSegment::_cdc = 0;
00029
00030 TSegment::TSegment()
00031 : TTrackBase(),
00032 _innerWidth(0),
00033 _outerWidth(0),
00034 _nLayer(0),
00035 _clusterType(0),
00036 _duality(0.),
00037 _nDual(0),
00038 _angle(0.),
00039 _state(0),
00040 _lineTsf(0.,0.,0.) {
00041
00042
00043 _times[0] = 7;
00044 _times[1] = 7;
00045 _times[2] = 4;
00046 _times[3] = 4;
00047 _times[4] = 4;
00048 _times[5] = 5;
00049 _times[6] = 5;
00050 _times[7] = 5;
00051 _times[8] = 5;
00052 _times[9] = 4;
00053 _times[10] = 4;
00054 _fitted = false;
00055 }
00056
00057 TSegment::TSegment(const AList<TMLink> & a)
00058 : TTrackBase(a),
00059 _innerWidth(0),
00060 _outerWidth(0),
00061 _nLayer(0),
00062 _clusterType(0),
00063 _duality(0.),
00064 _nDual(0),
00065 _angle(0.),
00066 _state(0),
00067 _lineTsf(0.,0.,0.) {
00068 _links.sort(SortByWireId);
00069
00070
00071 _times[0] = 7;
00072 _times[1] = 7;
00073 _times[2] = 4;
00074 _times[3] = 4;
00075 _times[4] = 4;
00076 _times[5] = 5;
00077 _times[6] = 5;
00078 _times[7] = 5;
00079 _times[8] = 5;
00080 _times[9] = 4;
00081 _times[10] = 4;
00082 _fitted = false;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 TSegment::~TSegment() {
00113 }
00114
00115 void
00116 TSegment::dump(const std::string & msg, const std::string & pre) const {
00117 if (! _fitted) update();
00118 bool def = false;
00119 if (msg == "") def = true;
00120
00121 if (def || msg.find("cluster") != std::string::npos || msg.find("detail") != std::string::npos) {
00122 std::cout << pre;
00123 std::cout << "#links=" << _links.length();
00124 std::cout << "(" << _innerWidth << "," << _outerWidth << ":";
00125 std::cout << clusterType() << ")," << _nDual << "," << _duality << ",";
00126 std::cout << _angle << std::endl;
00127 }
00128 if (def || msg.find("vector") != std::string::npos || msg.find("detail") != std::string::npos) {
00129 std::cout << pre;
00130 std::cout << "pos" << _position << "," << "dir" << _direction;
00131 std::cout << std::endl;
00132 }
00133 if (def || msg.find("state") != std::string::npos || msg.find("detail") != std::string::npos) {
00134 std::cout << pre;
00135 std::cout << "state=" << _state << std::cout << std::endl;
00136 }
00137 if (def || msg.find("link") != std::string::npos || msg.find("detail") != std::string::npos) {
00138 std::cout << pre;
00139 std::cout << "unique links=" << NUniqueLinks(* this);
00140 std::cout << ",major links=" << NMajorLinks(* this);
00141 std::cout << ",branches=" << NLinkBranches(* this);
00142 std::cout << std::endl;
00143 }
00144 if (! def) TTrackBase::dump(msg, pre);
00145 }
00146
00147 void
00148 TSegment::update(void) const {
00149 _clusterType = 0;
00150 _position = ORIGIN;
00151 _direction = ORIGIN;
00152 _outerPosition = ORIGIN;
00153 _inners.removeAll();
00154 _outers.removeAll();
00155
00156 if (_links.length() == 0) return;
00157
00158
00159 _innerMostLayer = _links[0]->wire()->layerId();
00160 _outerMostLayer = _innerMostLayer;
00161 for (unsigned i = 1; i < _links.length(); i++) {
00162 unsigned id = _links[i]->wire()->layerId();
00163 if (id < _innerMostLayer) _innerMostLayer = id;
00164 else if (id > _outerMostLayer) _outerMostLayer = id;
00165 }
00166 _nLayer = _outerMostLayer - _innerMostLayer + 1;
00167
00168 double centerX = _links[0]->position().x();
00169 HepPoint3D inner = ORIGIN;
00170 unsigned nInner = 0;
00171 unsigned nOuter = 0;
00172 unsigned n = _links.length();
00173 for (unsigned i = 0; i < n; i++) {
00174 const HepPoint3D & tmp = _links[i]->position();
00175
00176
00177
00178
00179
00180
00181
00182 _position += tmp;
00183 unsigned id = _links[i]->wire()->layerId();
00184 if (id == _innerMostLayer) {
00185 inner += tmp;
00186 ++nInner;
00187 _inners.append(_links[i]);
00188 }
00189 if (id == _outerMostLayer) {
00190 _outerPosition += tmp;
00191 ++nOuter;
00192 _outers.append(_links[i]);
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201 _innerWidth = Width(_inners);
00202 _outerWidth = Width(_outers);
00203 _position *= (1. / float(n));
00204
00205 inner *= (1. / (float) nInner);
00206 _outerPosition *= (1. / (float) nOuter);
00207 _direction = (inner - _outerPosition).unit();
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 _fitted = true;
00234 }
00235
00236 double
00237 TSegment::distance(const TSegment & c) const {
00238 HepVector3D dir = c.position() - _position;
00239 if (dir.x() > M_PI) dir.setX(dir.x() - 2. * M_PI);
00240 else if (dir.x() < - M_PI) dir.setX(2. * M_PI + dir.x());
00241
00242 float radial = fabs(_direction.dot(dir));
00243 float radial2 = radial * radial;
00244
00245 return (dir.mag2() - radial2) > 0.0 ? sqrt(dir.mag2() - radial2) : 0.;
00246 }
00247
00248 double
00249 TSegment::distance(const HepPoint3D & p, const HepVector3D & v) const {
00250 HepVector3D dir = _position - p;
00251 if (dir.x() > M_PI) dir.setX(dir.x() - 2. * M_PI);
00252 else if (dir.x() < - M_PI) dir.setX(2. * M_PI + dir.x());
00253
00254 float radial = fabs(v.unit().dot(dir));
00255 float radial2 = radial * radial;
00256
00257 return (dir.mag2() - radial2) > 0.0 ? sqrt(dir.mag2() - radial2) : 0.;
00258 }
00259
00260 Range
00261 TSegment::rangeX(double min, double max) const {
00262 #ifdef TRKRECO_DEBUG_DETAIL
00263 if (min > max) {
00264 std::cout << "TSegment::range !!! bad arguments:min,max=";
00265 std::cout << min << "," << max << std::endl;
00266 }
00267 #endif
00268
00269 unsigned n = _links.length();
00270 if (n == 0) return Range(0., 0.);
00271
00272
00273 bool found = false;
00274 double center;
00275 for (unsigned i = 0; i < n; i++) {
00276 double x = _links[i]->position().x();
00277 if (x < min || x > max) continue;
00278 center = x;
00279 found = true;
00280 break;
00281 }
00282 if (! found) return Range(0., 0.);
00283
00284 #ifdef TRKRECO_DEBUG_DETAIL
00285
00286 #endif
00287
00288 double distanceR = 0.;
00289 double distanceL = 0.;
00290 double distanceMax = max - min;
00291 for (unsigned i = 0; i < n; i++) {
00292 double x = _links[i]->position().x();
00293 if (x < min || x > max) continue;
00294
00295 double distance0, distance1;
00296 if (x > center) {
00297 distance0 = x - center;
00298 distance1 = distanceMax - distance0;
00299 }
00300 else {
00301 distance1 = center - x;
00302 distance0 = distanceMax - distance1;
00303 }
00304
00305 if (distance0 < distance1) {
00306 if (distance0 > distanceR) distanceR = distance0;
00307 }
00308 else {
00309 if (distance1 > distanceL) distanceL = distance1;
00310 }
00311
00312 #ifdef TRKRECO_DEBUG_DETAIL
00313
00314
00315
00316
00317
00318
00319
00320 #endif
00321 }
00322
00323 double right = center + distanceR;
00324 double left = center - distanceL;
00325
00326 return Range(left, right);
00327 }
00328
00329 void
00330 TSegment::updateType(void) const {
00331 if (! nLinks()) return;
00332 if (! _fitted) update();
00333
00334
00335 unsigned fat = 3;
00336 unsigned tall = 3;
00337
00338
00339
00340 updateDuality();
00341
00342
00343 if ((_innerWidth < fat) && (_outerWidth < fat)) {
00344 _clusterType = 1;
00345
00346
00347 if (_nLayer > tall) _clusterType = 2;
00348 return;
00349 }
00350
00351
00352 else if (_outerWidth < fat) {
00353 _clusterType = 3;
00354 return;
00355 }
00356
00357
00358 else if (_innerWidth < fat) {
00359 _clusterType = 4;
00360 return;
00361 }
00362
00363
00364 else {
00365 bool space = true;
00366 for (unsigned i = _innerMostLayer; i <= _outerMostLayer; i++) {
00367 unsigned n = 0;
00368 AList<TMLink> tmp;
00369 for (unsigned j = 0; j < _links.length(); j++)
00370 if (_links[j]->wire()->layerId() == i) {
00371 ++n;
00372 tmp.append(_links[j]);
00373 }
00374
00375 if (n == Width(tmp)) {
00376 space = false;
00377 break;
00378 }
00379 }
00380
00381 _clusterType = 5;
00382 if (space) _clusterType = 6;
00383 return;
00384 }
00385 }
00386
00387 AList<TSegment>
00388 TSegment::split(void) const {
00389 AList<TSegment> list;
00390
00391
00392 unsigned t = clusterType();
00393 #ifdef TRKRECO_DEBUG_DETAIL
00394 std::cout << " ... splitting : type=" << t << std::endl;
00395 #endif
00396 if (t == 0) return list;
00397 else if (t == 2) {
00398
00399
00400
00401
00402
00403
00404 if (_nDual > 2 && _duality > 0.7 && _angle > 0.7) return splitDual();
00405 return list;
00406 }
00407 else if (t == 1) return list;
00408 else if (t == 7) return list;
00409
00410
00411 else if (t == 6) return splitParallel();
00412
00413
00414
00415 else if (t > 4) return splitComplicated();
00416
00417
00418 return splitAV();
00419 }
00420
00421 AList<TSegment>
00422 TSegment::splitAV(void) const {
00423 unsigned t = clusterType();
00424 AList<TMLink> seeds[2];
00425
00426
00427 const AList<TMLink> * corners;
00428 if (t == 3) corners = & _outers;
00429 else corners = & _inners;
00430 HepPoint3D corner;
00431 for (unsigned i = 0; i < corners->length(); i++)
00432 corner += (* corners)[i]->wire()->xyPosition();
00433 corner *= 1. / (float) corners->length();
00434 seeds[0].append(* corners);
00435 seeds[1].append(* corners);
00436
00437
00438 const AList<TMLink> * links;
00439 if (t == 3) links = & _inners;
00440 else links = & _outers;
00441 AList<TMLink> edge = Edges(* links);
00442 HepPoint3D edgePos[2];
00443 HepVector3D v[2];
00444 for (unsigned i = 0; i < 2; i++) {
00445 edgePos[i] = edge[i]->wire()->xyPosition();
00446 v[i] = (edgePos[i] - corner).unit();
00447 }
00448 seeds[0].append(edge[0]);
00449 seeds[1].append(edge[1]);
00450
00451 #ifdef TRKRECO_DEBUG_DETAIL
00452 std::cout << " corner:" << corner << std::endl;
00453 std::cout << " edge:" << edgePos[0] << "(";
00454 std::cout << edge[0]->wire()->layerId() << "-";
00455 std::cout << edge[0]->wire()->localId() << ")";
00456 std::cout << v[0] << std::endl;
00457 std::cout << " ";
00458 std::cout << edgePos[1] << "(";
00459 std::cout << edge[1]->wire()->layerId() << "-";
00460 std::cout << edge[1]->wire()->localId() << ")";
00461 std::cout << v[1] << std::endl;
00462 #endif
00463
00464
00465 unsigned n = _links.length();
00466 for (unsigned i = 0; i < n; i++) {
00467 TMLink * l = _links[i];
00468 if (edge.member(l)) continue;
00469 if (corners->member(l)) continue;
00470
00471 HepVector3D p = l->wire()->xyPosition() - corner;
00472 double p2 = p.mag2();
00473
00474 double dist[2];
00475 for (unsigned j = 0; j < 2; j++) {
00476 dist[j] = v[j].dot(p);
00477 double d2 = dist[j] * dist[j];
00478 dist[j] = (p2 - d2) > 0. ? sqrt(p2 - d2) : 0.;
00479 }
00480 if (dist[0] < dist[1]) seeds[0].append(l);
00481 else seeds[1].append(l);
00482
00483 #ifdef TRKRECO_DEBUG_DETAIL
00484 std::cout << " p:" << p << std::endl;
00485 std::cout << " " << l->wire()->layerId() << "-";
00486 std::cout << l->wire()->localId() << ":" << dist[0];
00487 std::cout << "," << dist[1] << std::endl;
00488 #endif
00489 }
00490
00491 AList<TSegment> list;
00492 for (unsigned i = 0; i < 2; i++) {
00493 if (seeds[i].length()) {
00494 TSegment * nc = new TSegment(seeds[i]);
00495 AList<TSegment> ncx = nc->split();
00496 if (ncx.length() == 0) {
00497 nc->solveDualHits();
00498 list.append(nc);
00499 }
00500 else {
00501 list.append(ncx);
00502 delete nc;
00503 }
00504 }
00505 }
00506 return list;
00507 }
00508
00509 AList<TSegment>
00510 TSegment::splitComplicated(void) const {
00511
00512
00513 AList<TSegment> newClusters;
00514 AList<TMLink> goodHits;
00515 unsigned n = _links.length();
00516 for (unsigned i = 0; i < n; i++) {
00517 const TMDCWireHit * h = _links[i]->hit();
00518 unsigned state = h->state();
00519 if (! (state & WireHitContinuous)) continue;
00520 if (! (state & WireHitIsolated)) continue;
00521 if ((! (state & WireHitPatternLeft)) &&
00522 (! (state & WireHitPatternRight))) continue;
00523 goodHits.append(_links[i]);
00524 }
00525 if (goodHits.length() == 0) return newClusters;
00526
00527
00528 goodHits.sort(SortByWireId);
00529 AList<TMLink> original(_links);
00530 while (goodHits.length()) {
00531
00532
00533 TMLink * seed = goodHits.last();
00534 const TMDCWire * wire = seed->wire();
00535 unsigned localId = wire->localId();
00536 AList<TMLink> used;
00537 unsigned nn = _links.length();
00538 for (unsigned i = 0; i < nn; i++) {
00539 TMLink * t = _links[i];
00540 const TMDCWire * w = t->wire();
00541
00542
00543 if (abs((int) w->localId() - (int) localId) < 2) used.append(t);
00544 }
00545
00546 #ifdef TRKRECO_DEBUG_DETAIL
00547 std::cout << " seed is " << seed->wire()->name() << std::endl;
00548 std::cout << " ";
00549 for (unsigned i = 0; i < used.length(); i++) {
00550 std::cout << used[i]->wire()->name() << ",";
00551 }
00552 std::cout << std::endl;
00553 #endif
00554
00555
00556 if (used.length() == 0) continue;
00557 if (used.length() == nLinks()) return newClusters;
00558 TSegment * c = new TSegment(used);
00559 AList<TSegment> cx = c->split();
00560 if (cx.length() == 0) {
00561 c->solveDualHits();
00562 newClusters.append(c);
00563 }
00564 else {
00565 newClusters.append(cx);
00566 delete c;
00567 }
00568 goodHits.remove(used);
00569 original.remove(used);
00570 }
00571
00572
00573 if ((original.length()) && (original.length() < nLinks())) {
00574 TSegment * c = new TSegment(original);
00575 AList<TSegment> cx = c->split();
00576 if (cx.length() == 0) {
00577 c->solveDualHits();
00578 newClusters.append(c);
00579 }
00580 else {
00581 newClusters.append(cx);
00582 delete c;
00583 }
00584 }
00585
00586 return newClusters;
00587 }
00588
00589 AList<TSegment>
00590 TSegment::splitParallel(void) const {
00591 AList<TMLink> seeds[2];
00592 AList<TSegment> newClusters;
00593 for (unsigned i = _innerMostLayer; i <= _outerMostLayer; i++) {
00594 AList<TMLink> list = SameLayer(_links, i);
00595 AList<TMLink> outerList = Edges(list);
00596
00597 #ifdef TRKRECO_DEBUG_DETAIL
00598 if (outerList.length() != 2) {
00599 std::cout << "TSegment::splitParallel !!! ";
00600 std::cout << "This is not a parallel cluster" << std::endl;
00601 }
00602 #endif
00603
00604 seeds[0].append(outerList[0]);
00605 seeds[1].append(outerList[1]);
00606 if (list.length() == 2) continue;
00607
00608 const TMDCWire & wire0 = * outerList[0]->wire();
00609 const TMDCWire & wire1 = * outerList[1]->wire();
00610 for (unsigned k = 0; k < list.length(); k++) {
00611 TMLink * t = list[k];
00612 if (t == outerList[0]) continue;
00613 if (t == outerList[1]) continue;
00614
00615 if (abs(wire0.localIdDifference(* t->wire())) <
00616 abs(wire1.localIdDifference(* t->wire())))
00617 seeds[0].append(t);
00618 else
00619 seeds[1].append(t);
00620 }
00621 }
00622
00623 if ((seeds[0].length()) && (seeds[0].length() < nLinks())) {
00624 TSegment * c0 = new TSegment(seeds[0]);
00625 AList<TSegment> c0x = c0->split();
00626 if (c0x.length()) {
00627 newClusters.append(c0x);
00628 delete c0;
00629 }
00630 else {
00631 c0->solveDualHits();
00632 newClusters.append(c0);
00633 }
00634 }
00635
00636 if ((seeds[1].length()) && (seeds[1].length() < nLinks())) {
00637 TSegment * c1 = new TSegment(seeds[1]);
00638 AList<TSegment> c1x = c1->split();
00639 if (c1x.length()) {
00640 newClusters.append(c1x);
00641 delete c1;
00642 }
00643 else {
00644 c1->solveDualHits();
00645 newClusters.append(c1);
00646 }
00647 }
00648
00649 return newClusters;
00650 }
00651
00652 void
00653 TSegment::updateDuality(void) const {
00654 _duality = 0.;
00655 _nDual = 0;
00656 HepPoint3D x[2];
00657 for (unsigned i = _innerMostLayer; i <= _outerMostLayer; i++) {
00658 AList<TMLink> list = SameLayer(_links, i);
00659 if (i == _innerMostLayer) {
00660 for (unsigned j = 0; j < list.length(); j++)
00661 x[0] += list[j]->hit()->xyPosition();
00662 x[0] *= 1. / float(list.length());
00663 }
00664 else if (i == _outerMostLayer) {
00665 for (unsigned j = 0; j < list.length(); j++)
00666 x[1] += list[j]->hit()->xyPosition();
00667 x[1] *= 1. / float(list.length());
00668 }
00669
00670 if (list.length() == 2) {
00671 if (Width(list) != 2) continue;
00672 const TMDCWireHit * h0 = list[0]->hit();
00673 const TMDCWireHit * h1 = list[1]->hit();
00674
00675 double distance = (h0->xyPosition() - h1->xyPosition()).mag();
00676 distance = fabs(distance - list[0]->drift() - list[1]->drift());
00677 _duality += distance;
00678 ++_nDual;
00679 }
00680 }
00681 if (_nDual > 0) _duality /= float(_nDual);
00682 _angle = (x[1] - x[0]).unit().dot(x[0].unit());
00683 }
00684
00685 AList<TSegment>
00686 TSegment::splitDual(void) const {
00687 #ifdef TRKRECO_DEBUG_DETAIL
00688 std::cout << " TSegment::splitDual called" << std::endl;
00689 #endif
00690 AList<TMLink> seeds[2];
00691 AList<TMLink> unknown;
00692 for (unsigned i = _innerMostLayer; i <= _outerMostLayer; i++) {
00693 AList<TMLink> list = SameLayer(_links, i);
00694
00695 if (list.length() == 2) {
00696 if (Width(list) == 2) {
00697 seeds[0].append(list[0]);
00698 seeds[1].append(list[1]);
00699 continue;
00700 }
00701 }
00702 unknown.append(list);
00703 }
00704
00705 if (unknown.length() > 0) {
00706 #ifdef TRKRECO_DEBUG_DETAIL
00707 if (seeds[0].length() == 0)
00708 std::cout << "TSegment::splitDual !!! no TMLink for seed 0" << std::endl;
00709 if (seeds[1].length() == 0)
00710 std::cout << "TSegment::splitDual !!! no TMLink for seed 1" << std::endl;
00711 #endif
00712 const HepPoint3D & p0 = seeds[0][0]->xyPosition();
00713 const HepPoint3D & p1 = seeds[1][0]->xyPosition();
00714 HepVector3D v0 = (seeds[0].last()->xyPosition() - p0).unit();
00715 HepVector3D v1 = (seeds[1].last()->xyPosition() - p1).unit();
00716
00717 for (unsigned i = 0; i < unknown.length(); i++) {
00718 TMLink * t = unknown[i];
00719 HepVector3D x0 = t->xyPosition() - p0;
00720 double d0 = (x0 - (x0.dot(v0) * v0)).mag();
00721 HepVector3D x1 = t->xyPosition() - p1;
00722 double d1 = (x1 - (x1.dot(v0) * v0)).mag();
00723
00724 if (d0 < d1) seeds[0].append(t);
00725 else seeds[1].append(t);
00726 }
00727 }
00728
00729 AList<TSegment> newClusters;
00730 newClusters.append(new TSegment(seeds[0]));
00731 newClusters.append(new TSegment(seeds[1]));
00732 return newClusters;
00733 }
00734
00735 int
00736 TSegment::solveDualHits(void) {
00737 updateType();
00738 if (_clusterType == 0) return 0;
00739 if (_nDual == 0) return 0;
00740 update();
00741 return 0;
00742
00743 updateType();
00744 if (_clusterType == 0) return 0;
00745 if (_nDual == 0) return 0;
00746
00747 AList<TMLink> seeds;
00748 AList<TMLink> duals;
00749 for (unsigned i = _innerMostLayer; i <= _outerMostLayer; i++) {
00750 AList<TMLink> list = SameLayer(_links, i);
00751
00752 if (list.length() == 1) {
00753 seeds.append(list[0]);
00754 }
00755 else if (list.length() == 2) {
00756 if (Width(list) > 1) {
00757 const TMDCWireHit * h0 = list[0]->hit();
00758 const TMDCWireHit * h1 = list[1]->hit();
00759 double distance = (h0->xyPosition() - h1->xyPosition()).mag();
00760 distance = fabs(distance -
00761 list[0]->drift() -
00762 list[1]->drift());
00763 if (distance > 0.5) duals.append(list);
00764 #ifdef TRKRECO_DEBUG_DETAIL
00765 h0->dump("", " ");
00766 h1->dump("", " ");
00767 std::cout << " lyr=" << i;
00768 std::cout << ", duality distance = " << distance << std::endl;
00769 #endif
00770 }
00771 }
00772 else if (list.length() == 0) {
00773 continue;
00774 }
00775 #ifdef TRKRECO_DEBUG_DETAIL
00776 else {
00777 std::cout << "TSegment::solveDualHits !!! this is not expected 2";
00778 std::cout << std::endl;
00779 this->dump("cluster hits mc", " ");
00780 }
00781 #endif
00782 }
00783
00784
00785 if (seeds.length() < 2) return -1;
00786 AList<TMLink> outers = InOut(seeds);
00787 const HepPoint3D & p = outers[0]->xyPosition();
00788 HepVector3D v = (outers[1]->xyPosition() - p).unit();
00789 unsigned n = duals.length() / 2;
00790 for (unsigned i = 0; i < n; i++) {
00791 TMLink * t0 = duals[i * 2 + 0];
00792 TMLink * t1 = duals[i * 2 + 1];
00793 HepVector3D x0 = t0->xyPosition() - p;
00794 HepVector3D x1 = t1->xyPosition() - p;
00795 double d0 = (x0 - (x0.dot(v) * v)).mag();
00796 double d1 = (x1 - (x1.dot(v) * v)).mag();
00797 if (d0 < d1) _links.remove(t1);
00798 else _links.remove(t0);
00799 }
00800 update();
00801 return n;
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 unsigned
00947 NCoreLinks(const CAList<TSegment> & list) {
00948 unsigned n = 0;
00949 unsigned nList = list.length();
00950 for (unsigned i = 0; i < nList; i++) {
00951 const AList<TMLink> & links = list[i]->links();
00952 for (unsigned j = 0; j < links.length(); j++) {
00953 unsigned state = links[j]->hit()->state();
00954 if ((! (state & WireHitPatternLeft)) &&
00955 (! (state & WireHitPatternRight)))
00956 ++n;
00957 }
00958 }
00959 return n;
00960 }
00961
00962 AList<TMLink>
00963 Links(const TSegment & s, const TTrack & t) {
00964 AList<TMLink> a;
00965
00966 const AList<TMLink> & links = s.links();
00967 const AList<TMLink> & trackLinks = t.links();
00968 unsigned n = links.length();
00969 for (unsigned i = 0; i < n; i++) {
00970 if (trackLinks.hasMember(links[i]))
00971 a.append(links[i]);
00972 }
00973
00974 return a;
00975 }
00976
00977 unsigned
00978 NUniqueLinks(const TSegment & a) {
00979 unsigned n = 0;
00980 const TSegment * s = & a;
00981 while (s) {
00982 unsigned nLinks = s->innerLinks().length();
00983 if (nLinks != 1) return n;
00984 ++n;
00985 s = s->innerLinks()[0];
00986 }
00987 return n;
00988 }
00989
00990 AList<TSegment>
00991 UniqueLinks(const TSegment & a) {
00992 AList<TSegment> links;
00993 const TSegment * s = & a;
00994 while (s) {
00995 unsigned nLinks = s->innerLinks().length();
00996 if (nLinks != 1) return links;
00997 const TSegment * t = s->innerLinks()[0];
00998 links.append((TSegment *) t);
00999 s = t;
01000 }
01001 return links;
01002 }
01003
01004 unsigned
01005 NMajorLinks(const TSegment & a) {
01006 unsigned n = 0;
01007 const TSegment * s = & a;
01008 while (s) {
01009 unsigned nLinks = s->innerLinks().length();
01010 if (nLinks == 0) return n;
01011 ++n;
01012 int tmp = 0, ii = 0;
01013 for (int i = 0; i < nLinks; ++i) {
01014 if(s->innerLinks()[i]->links().length() > tmp) {
01015 tmp = s->innerLinks()[i]->links().length();
01016 ii = i;
01017 }
01018 }
01019 s = s->innerLinks()[ii];
01020
01021 }
01022 return n;
01023 }
01024
01025 AList<TSegment>
01026 MajorLinks(const TSegment & a) {
01027 AList<TSegment> links;
01028 const TSegment * s = & a;
01029 while (s) {
01030 unsigned nLinks = s->innerLinks().length();
01031 if (nLinks == 0) return links;
01032 int tmp = 0, ii = 0;
01033 for (int i = 0; i < nLinks; ++i) {
01034 if(s->innerLinks()[i]->links().length() > tmp) {
01035 tmp = s->innerLinks()[i]->links().length();
01036 ii = i;
01037 }
01038 }
01039 const TSegment * t = s->innerLinks()[ii];
01040
01041 links.append((TSegment *) t);
01042 s = t;
01043 }
01044 return links;
01045 }
01046
01047 unsigned
01048 NLinkBranches(const TSegment & a) {
01049 unsigned n = 0;
01050 const TSegment * s = & a;
01051 while (s) {
01052 unsigned nLinks = s->innerLinks().length();
01053 if (nLinks == 0) return n;
01054 if (nLinks > 1) ++n;
01055 s = s->innerLinks()[0];
01056 }
01057 return n;
01058 }
01059
01060 void
01061 SeparateCrowded(const AList<TSegment> & in,
01062 AList<TSegment> & isolated,
01063 AList<TSegment> & crowded) {
01064 unsigned n = in.length();
01065 if (n == 0) return;
01066
01067 for (unsigned i = 0; i < n; i++) {
01068 TSegment & s = * in[i];
01069 if (s.state() & TSegmentCrowd) crowded.append(s);
01070 else isolated.append(s);
01071 }
01072 }
01073
01074 unsigned
01075 SuperLayer(const AList<TSegment> & list) {
01076 unsigned sl = 0;
01077 unsigned n = list.length();
01078 for (unsigned i = 0; i < n; i++)
01079 sl |= (1 << (list[i]->superLayerId()));
01080 return sl;
01081 }
01082
01083 TSegment *
01084 OuterMostUniqueLink(const TSegment & a) {
01085 const TSegment * o = & a;
01086 while (o->outerLinks().length() == 1)
01087 o = o->outerLinks()[0];
01088 return (TSegment *) o;
01089 }
01090
01091 AList<TMLink>
01092 Links(const AList<TSegment> & list) {
01093 AList<TMLink> links;
01094 unsigned n = list.length();
01095 for (unsigned i = 0; i < n; i++)
01096 links.append(list[i]->links());
01097 return links;
01098 }
01099
01100 unsigned
01101 TSegment::width(void) const {
01102 unsigned maxWidth = 0;
01103 for (unsigned i = innerMostLayer(); i <= outerMostLayer(); i++) {
01104 AList<TMLink> tmp = SameLayer(links(), i);
01105 unsigned w = Width(tmp);
01106 if (w > maxWidth) maxWidth = w;
01107 }
01108 return maxWidth;
01109 }
01110
01111
01112 double
01113 TSegment::maxdDistance(TMLink *l) const{
01114 unsigned sl = l->wire()->superLayerId();
01115 unsigned lId = l->wire()->layerId();
01116 double _averR[11] = {9.7, 14.5, 22.14, 28.62, 35.1, 42.39, 48.87, 55.35, 61.83, 69.12, 74.79};
01117 double _averR2[43] = { 7.885, 9.07, 10.29, 11.525,
01118 12.72, 13.875, 15.01, 16.16,
01119 19.7, 21.3, 22.955, 24.555,
01120 26.215, 27.82, 29.465, 31.06,
01121 32.69, 34.265, 35.875, 37.455,
01122 39.975, 41.52, 43.12, 44.76,
01123 46.415, 48.02, 49.685, 51.37,
01124 53.035, 54.595, 56.215, 57.855,
01125 59.475, 60.995, 62.565, 64.165,
01126 66.68, 68.285, 69.915, 71.57,
01127 73.21, 74.76, 76.345};
01128 double radius = _averR2[lId];
01129 const double singleSigma = l->dDrift();
01130 return 2 * singleSigma / (radius * radius);
01131 }
01132
01133 AList<TSegment>
01134 TSegment::splitTsf(AList<TMLink> & seedNeighbors) {
01135
01136 AList<TSegment> list;
01137 AList<TMLink> links[4];
01138 AList<TMLink> seeds2;
01139 AList<TMLink> exTsf;
01140 TMLink *seed;
01141
01142 for (unsigned i = 0; i < _links.length(); ++i) {
01143 TMLink * l = _links[i];
01144 links[l->wire()->localLayerId()].append(l);
01145 }
01146
01147
01148 if (links[0].length() == 0) {
01149 if (links[3].length() == 0) return list;
01150 if (links[1].length() != 1) {
01151 cout<<"wrong in tsf, TSegment::splitTsf ...1"<<endl;
01152 return list;
01153 }
01154 seed = links[1][0];
01155 seeds2.append(links[3]);
01156 exTsf.append(links[2]);
01157 }
01158 else if (links[0].length() == 1) {
01159 seed = links[0][0];
01160 if (links[3].length() > 0) {
01161 seeds2.append(links[3]);
01162 exTsf.append(links[1]);
01163 exTsf.append(links[2]);
01164 }
01165 else if (links[2].length() > 0) {
01166 seeds2.append(links[2]);
01167 exTsf.append(links[1]);
01168 }
01169 else return list;
01170 }
01171 else cout<<"wrong in tsf, TSegment::splitTsf ...2"<<endl;
01172 exTsf.append(seeds2);
01173
01174
01175 for (unsigned i = 0; i < seeds2.length(); ++i) {
01176 if (seed->tsfTag() > 0 && seeds2[i]->tsfTag() > 0) continue;
01177 AList<TSegment> segments;
01178 HepPoint3D line[4];
01179 fitLine(seed, seeds2[i], line);
01180 segments = appendByLine(seed, seeds2[i], seedNeighbors, exTsf, line);
01181 list.append(segments);
01182 segments.removeAll();
01183 }
01184 if (seed->wire()->localLayerId() == 0) {
01185 exTsf.removeAll();
01186 seeds2.removeAll();
01187 exTsf.append(links[1]);
01188 exTsf.append(links[2]);
01189 for (int k = 0; k < links[2].length(); ++k){
01190 if (links[2][k]->tsfTag() == 0) seeds2.append(links[2][k]);
01191 }
01192 for (unsigned i = 0; i < seeds2.length(); ++i) {
01193 if (seed->tsfTag() > 0 && seeds2[i]->tsfTag() > 0) continue;
01194 AList<TSegment> segments2;
01195 HepPoint3D line2[4];
01196 fitLine(seed, seeds2[i], line2);
01197 segments2 = appendByLine(seed, seeds2[i], seedNeighbors, exTsf, line2);
01198 list.append(segments2);
01199 segments2.removeAll();
01200 }
01201 }
01202
01203 return list;
01204 }
01205
01206 void
01207 TSegment::fitLine(TMLink *seed, TMLink *outer, HepPoint3D line[4]) const {
01208 double ax = seed->positionD().x();
01209 double ay = seed->positionD().y();
01210 double ar = seed->cDrift();
01211 double bx = outer->positionD().x();
01212 double by = outer->positionD().y();
01213 double br = outer->cDrift();
01214
01215 double dis = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
01216 double costheta = (bx - ax) / dis;
01217 double sintheta = (by - ay) / dis;
01218 double c1 = (ax * ax - bx * bx + ay * ay - by * by) / (2 * dis);
01219 double c2 = (ax * by - bx * ay) / dis;
01220
01221 line[0].setX((br - ar) * costheta + sqrt(dis * dis - (ar - br) * (ar - br)) * sintheta);
01222 line[0].setY((br - ar) * sintheta - sqrt(dis * dis - (ar - br) * (ar - br)) * costheta);
01223 line[0].setZ((br - ar) * c1 - sqrt(dis * dis - (ar - br) * (ar - br)) * c2 + 0.5 * dis * (ar + br));
01224 line[1].setX((br - ar) * costheta - sqrt(dis * dis - (ar - br) * (ar - br)) * sintheta);
01225 line[1].setY((br - ar) * sintheta + sqrt(dis * dis - (ar - br) * (ar - br)) * costheta);
01226 line[1].setZ((br - ar) * c1 + sqrt(dis * dis - (ar - br) * (ar - br)) * c2 + 0.5 * dis * (ar + br));
01227 line[2].setX((br + ar) * costheta + sqrt(dis * dis - (ar + br) * (ar + br)) * sintheta);
01228 line[2].setY((br + ar) * sintheta - sqrt(dis * dis - (ar + br) * (ar + br)) * costheta);
01229 line[2].setZ((br + ar) * c1 - sqrt(dis * dis - (ar + br) * (ar + br)) * c2 + 0.5 * dis * (br - ar));
01230 line[3].setX((br + ar) * costheta - sqrt(dis * dis - (ar + br) * (ar + br)) * sintheta);
01231 line[3].setY((br + ar) * sintheta + sqrt(dis * dis - (ar + br) * (ar + br)) * costheta);
01232 line[3].setZ((br + ar) * c1 + sqrt(dis * dis - (ar + br) * (ar + br)) * c2 + 0.5 * dis * (br - ar));
01233
01234
01235
01236
01237
01238
01239
01240 return;
01241 }
01242
01243 AList<TSegment>
01244 TSegment::appendByLine(TMLink * seed, TMLink * outer, AList<TMLink> & seedNeighbors, AList<TMLink> & restHits, const HepPoint3D line[4]) {
01245 AList<TSegment> list;
01246 list.removeAll();
01247
01248 const unsigned slId = seed->wire()->superLayerId();
01249
01250
01251
01252 for (int i = 0; i < 4; ++i) {
01253 AList<TMLink> seeds;
01254 for (int j = 0, size = restHits.length(); j < size; ++j) {
01255 TMLink * l = restHits[j];
01256 if (l->wire()->id() == outer->wire()->id()) continue;
01257
01258 double maxdis = maxdDistance(l) * _times[slId];
01259 double dis = distance2(l, line[i]);
01260
01261 if(seeds.hasMember(l)) continue;
01262 if (fabs(dis - l->cDrift()) < maxdis) seeds.append(l);
01263 else continue;
01264 }
01265 seeds.append(seed);
01266 seeds.append(outer);
01267 unsigned nHitsLayer[4] = {0, 0, 0, 0};
01268 unsigned nLayers = 0;
01269
01270 for (int j = 0; j < seeds.length(); ++j)
01271 ++nHitsLayer[seeds[j]->wire()->localLayerId()];
01272 for (int j = 0; j < 4; ++j)
01273 if (nHitsLayer[j] > 0) ++nLayers;
01274 if (nLayers < 3) continue;
01275
01276
01277 for (int k = 0; k < seedNeighbors.length(); ++k) {
01278 TMLink * l =seedNeighbors[k];
01279
01280 double maxdis = maxdDistance(l) * _times[slId];
01281 double dis = distance2(l, line[i]);
01282
01283 if(seeds.hasMember(l)) continue;
01284 if (fabs(dis - l->cDrift()) < maxdis) seeds.append(l);
01285 else continue;
01286 }
01287
01288
01289 for (int k = 0; k < seeds.length(); ++k) {
01290 unsigned a = seeds[k]->tsfTag();
01291 ++a;
01292 seeds[k]->tsfTag(a);
01293 }
01294
01295
01296 TSegment * seg = new TSegment(seeds);
01297 seg->lineTsf(line[i]);
01298 seg->update();
01299
01300 list.append(seg);
01301 }
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 return list;
01341 }
01342
01343 double
01344 TSegment::distance2(TMLink * hit, HepPoint3D line) const {
01345 double x = hit->positionD().x();
01346 double y = hit->positionD().y();
01347 double a = line.x();
01348 double b = line.y();
01349 double c = line.z();
01350 return fabs(a * x + b * y + c) / sqrt(a * a + b * b);
01351 }
01352
01353 HepPoint3D
01354 TSegment::positionTsf(const AList<TMLink> & links, const HepPoint3D line) const {
01355 HepPoint3D sumPos(0., 0., 0.);
01356 int n = 0;
01357 for(int i = 0; i < links.length(); ++i){
01358 const HepPoint3D & p = links[i]->positionD();
01359 double d = links[i]->cDrift();
01360 HepPoint3D posOnLine = closestPoint(p, _lineTsf);
01361 HepPoint3D v = (posOnLine - p).unit();
01362 const HepPoint3D p1 = p + d*v;
01363 sumPos += p1;
01364 ++n;
01365 }
01366 sumPos *= (1. / double(n));
01367 HepPoint3D posTsf = closestPoint(sumPos, line);
01368 return posTsf;
01369 }
01370
01371 HepPoint3D
01372 TSegment::leastSquaresFitting1(const AList<TMLink> & links, const HepPoint3D tsfLine) const {
01373 HepPoint3D line0;
01374 line0.setX(tsfLine.x()/sqrt(tsfLine.x()*tsfLine.x()+tsfLine.y()*tsfLine.y()));
01375 line0.setY(tsfLine.y()/sqrt(tsfLine.x()*tsfLine.x()+tsfLine.y()*tsfLine.y()));
01376 line0.setZ(tsfLine.z()/sqrt(tsfLine.x()*tsfLine.x()+tsfLine.y()*tsfLine.y()));
01377
01378 HepPoint3D line;
01379 unsigned n = links.length();
01380 unsigned nTrial = 0;
01381 while(1){
01382 if (nTrial > 10) break;
01383 double a = 0., b = 0.;
01384 double sumXSig = 0., sumYSig = 0., sumX2Sig = 0., sumXYSig = 0., sumSig = 0.;
01385 for (unsigned i = 0; i < n; i++) {
01386 const HepPoint3D & p = links[i]->positionD();
01387 double d = links[i]->cDrift();
01388 HepPoint3D posOnLine = closestPoint(p, _lineTsf);
01389 HepPoint3D v = (posOnLine - p).unit();
01390 const HepPoint3D p1 = p + d*v;
01391 double Sig = maxdDistance(links[i]);
01392 Sig = 1./(Sig*Sig);
01393 double X = p1.x();
01394 double Y = p1.y();
01395 sumXSig += X*Sig;
01396 sumYSig += Y*Sig;
01397 sumX2Sig += X * X * Sig;
01398 sumXYSig += X * Y * Sig;
01399 sumSig += Sig;
01400 }
01401
01402 b = (sumXYSig * sumSig - sumXSig * sumYSig) / (sumX2Sig * sumSig - sumXSig * sumXSig);
01403 a = (sumYSig - sumXSig * b) / sumSig;
01404
01405 line.set(b/sqrt(1+b*b), -1/sqrt(1+b*b), a/sqrt(1+b*b));
01406
01407
01408 double chi2 = 0.;
01409 for (unsigned i = 0; i < n; i++) {
01410 const HepPoint3D & p = links[i]->positionD();
01411 double d = links[i]->cDrift();
01412 double Sig = maxdDistance(links[i]);
01413 Sig = 1./(Sig*Sig);
01414 double dis = fabs(p.x()*line.x()+p.y()*line.y()+line.z()) - d;
01415 chi2 += dis * dis * Sig;
01416 }
01417 if (nTrial > 6) {
01418 cout<<"n = "<<n<<" nTrial = "<<nTrial<<" line0 = "<<line0<<endl;
01419 cout<<"chi2 in TSF = "<<chi2<<endl;
01420 }
01421
01422 if (fabs(line.x()-line0.x()) < 0.0001) break;
01423
01424 line0 = line;
01425 ++nTrial;
01426 }
01427 return line;
01428 }
01429
01430 HepPoint3D
01431 TSegment::leastSquaresFitting(const AList<TMLink> & links, const HepPoint3D tsfLine) const {
01432 HepPoint3D line0;
01433 line0.setX(tsfLine.x()/sqrt(tsfLine.x()*tsfLine.x()+tsfLine.y()*tsfLine.y()));
01434 line0.setY(tsfLine.y()/sqrt(tsfLine.x()*tsfLine.x()+tsfLine.y()*tsfLine.y()));
01435 line0.setZ(tsfLine.z()/sqrt(tsfLine.x()*tsfLine.x()+tsfLine.y()*tsfLine.y()));
01436
01437
01438 HepPoint3D line;
01439 int n = links.length();
01440 int nTrial = 0;
01441
01442 while(1){
01443 if (nTrial>15) break;
01444 double a0 = line0.x();
01445 double b0 = line0.y();
01446 double c0 = line0.z();
01447
01448
01449 if (b0 == 0) {
01450 cout<<"b0 == 0 TSegment::leastSquaresFitting!"<<endl;
01451 break;
01452 }
01453
01454 double a = 0., b = 0., c = 0.;
01455 double sumSigX2 = 0., sumSigX = 0., sumSig = 0.;
01456 for (int i = 0; i < n; ++i) {
01457 const HepPoint3D & p = links[i]->positionD();
01458 double X = p.x();
01459 double Y = p.y();
01460 double Sig = maxdDistance(links[i]);
01461 Sig = 1./(Sig*Sig);
01462 sumSigX2 += Sig*(X-Y*a0/b0)*(X-Y*a0/b0);
01463 sumSigX += Sig*(X-Y*a0/b0);
01464 sumSig += Sig;
01465 }
01466 double detM = sumSigX2*sumSig - sumSigX*sumSigX;
01467 double M11 = sumSig/detM;
01468 double M12 = -sumSigX/detM;
01469 double M21 = M12;
01470 double M22 = sumSigX2/detM;
01471 for (int i = 0; i < n; ++i) {
01472 const HepPoint3D & p = links[i]->positionD();
01473 double X = p.x();
01474 double Y = p.y();
01475 double DRIFT = links[i]->cDrift();
01476 if (a0*p.x() + b0*p.y() + c0*p.z() < 0) DRIFT = (-1) * DRIFT;
01477 double Sig = maxdDistance(links[i]);
01478 Sig = 1./(Sig*Sig);
01479 double D = DRIFT-Y/b0;
01480 a += ((X-Y*a0/b0)*M11+M12)*Sig*D;
01481 c += ((X-Y*a0/b0)*M21+M22)*Sig*D;
01482 }
01483
01484 b = (1 - a0*a)/b0;
01485
01486 line.setX(a/sqrt(a*a+b*b));
01487 line.setY(b/sqrt(a*a+b*b));
01488 line.setZ(c/sqrt(a*a+b*b));
01489 a = line.x();
01490 b = line.y();
01491 c = line.z();
01492
01493 double chi2 = 0.;
01494 for (int i = 0; i< n; ++i){
01495 const HepPoint3D & p = links[i]->positionD();
01496 double dis = fabs(a*p.x()+b*p.y()+c);
01497 double DRIFT = links[i]->cDrift();
01498 double Sig = maxdDistance(links[i]);
01499
01500 Sig = 1./(Sig*Sig);
01501 chi2 += (dis - DRIFT)*(dis - DRIFT)*Sig;
01502 }
01503
01504
01505
01506 if(fabs(a-a0)<0.00001) break;
01507
01508 line0 = line;
01509 ++nTrial;
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519 }
01520 return line;
01521 }
01522
01523 void
01524 TSegment::segSalvage(AList<TMLink> & links) {
01525 HepPoint3D line = _lineTsf;
01526 AList<TMLink> segLinks = _links;
01527 for (int i = 0; i < links.length(); ++i) {
01528 TMLink * l = links[i];
01529 if(segLinks.hasMember(l)) continue;
01530 const unsigned slId = l->wire()->superLayerId();
01531 double maxdis = maxdDistance(l) * (_times[slId]);
01532 double dis = distance2(l, line);
01533 if (fabs(dis - l->cDrift()) < maxdis) {
01534 _links.append(l);
01535 unsigned a = l->tsfTag();
01536 ++a;
01537 l->tsfTag(a);
01538 }
01539 else continue;
01540 }
01541 update();
01542 }
01543
01544 void
01545 TSegment::expandSeg(const int empty, AList<TMLink> & allLinks) {
01546 if(empty>=4 || empty<0) return;
01547 AList<TMLink> linksOnEmptyLayer;
01548 for (int i = 0; i < allLinks.length(); ++i)
01549 if (allLinks[i]->wire()->localLayerId() == empty) linksOnEmptyLayer.append(allLinks[i]);
01550
01551 if (linksOnEmptyLayer.length()==0) return;
01552
01553 if (_cdc == 0) _cdc = TMDC::getTMDC();
01554 float maxPhi[4] = {0.,0.,0.,0.};
01555 float minPhi[4] = {999.,999.,999.,999.};
01556 float max = 0., min = 999.;
01557 for (int i = 0; i < _links.length(); ++i) {
01558 TMLink *l = _links[i];
01559 unsigned lId = l->wire()->layerId();
01560 int local = l->wire()->localId();
01561 unsigned loId = l->wire()->localLayerId();
01562 float phi0 = _cdc->layer(lId)->offset();
01563 int nWir = (int) _cdc->layer(lId)->nWires();
01564 float phi = phi0 + local*2*pi/nWir;
01565
01566 if (phi > maxPhi[loId]) maxPhi[loId] = phi;
01567 if (phi < minPhi[loId]) minPhi[loId] = phi;
01568 if (phi > max) max = phi;
01569 if (phi < min) min = phi;
01570 }
01571
01572 AList<TMLink> tmpList;
01573 for (int i = 0; i < linksOnEmptyLayer.length(); ++i) {
01574 TMLink *l = linksOnEmptyLayer[i];
01575 unsigned lId = l->wire()->layerId();
01576 int local = l->wire()->localId();
01577 float phi0 = _cdc->layer(lId)->offset();
01578 int nWir = (int) _cdc->layer(lId)->nWires();
01579 float phi = phi0 + local*2*pi/nWir;
01580
01581 if (empty != 0 || empty != 3) {
01582 if (phi <= maxPhi[empty + 1] && phi >= minPhi[empty - 1]) tmpList.append(l);
01583 else if (phi <= maxPhi[empty - 1] && phi >= minPhi[empty + 1]) tmpList.append(l);
01584 else if (tmpList.length() == 0 && phi <= max && phi >= min) tmpList.append(l);
01585 }
01586 if (empty == 0 || empty == 3) {
01587 if (phi <= maxPhi[1] && phi >= minPhi[2]) tmpList.append(l);
01588 else if (phi <= maxPhi[2] && phi >= minPhi[1]) tmpList.append(l);
01589 else if (tmpList.length() == 0 && phi <= max && phi >= min) tmpList.append(l);
01590 }
01591 }
01592
01593 for(int i = 0; i < tmpList.length(); ++i) {
01594 TMLink * l = tmpList[i];
01595 _links.append(l);
01596 unsigned a = l->tsfTag();
01597 ++a;
01598 l->tsfTag(a);
01599 }
01600 update();
01601 }
01602
01603 void
01604 TSegment::solveLR(void) {
01605 unsigned n = _links.length();
01606
01607 if (n <= 3) {
01608 solveThreeHits();
01609 return;
01610 }
01611 for (int i = 0; i < n; ++i) {
01612 TMLink *l = _links[i];
01613 if (l->hit()->state() & WireHitPatternRight){
01614 unsigned newState = l->hit()->state()&(~WireHitPatternRight);
01615 l->hit()->state(newState);
01616 }
01617 if (l->hit()->state() & WireHitPatternLeft){
01618 unsigned newState = l->hit()->state()&(~WireHitPatternLeft);
01619 l->hit()->state(newState);
01620 }
01621 }
01622
01623 HepPoint3D originCon(0., 0., 0.);
01624 HepPoint3D dirZ(0., 0., 1.);
01625 HepPoint3D center = closestPoint(originCon, _lineTsf);
01626 HepPoint3D v1 = (center - originCon).unit();
01627 HepPoint3D v2 = dirZ.cross(v1);
01628 for (int i = 0; i < n; ++i) {
01629
01630 const HepPoint3D & p = _links[i]->positionD();
01631 unsigned state = _links[i]->hit()->state();
01632
01633 double cosA = (p - center).unit().dot(v1.unit());
01634 double cosB = (p - center).unit().dot(v2.unit());
01635 if (cosA*cosB < 0) state |= WireHitPatternLeft;
01636 else state |= WireHitPatternRight;
01637
01638 _links[i]->hit()->state(state);
01639 }
01640 }
01641
01642 HepPoint3D
01643 TSegment::closestPoint(const HepPoint3D & p, const HepPoint3D line) const {
01644 HepPoint3D Dir(-line.y(), line.x(), 0);
01645 Dir = Dir.unit();
01646 HepPoint3D PointOnLine(1, -(line.x()+line.z())/line.y(), 0);
01647 double dis = (p - PointOnLine).dot(Dir);
01648 HepPoint3D tmp(dis*Dir.x(), dis*Dir.y(), 0.);
01649 HepPoint3D closestPoint = PointOnLine + tmp;
01650
01651 double disPLine = fabs(p.x()*line.x()+p.y()*line.y()+line.z())/sqrt(line.x()*line.x()+line.y()*line.y());
01652 double disP1P2 = sqrt((p.x()-closestPoint.x())*(p.x()-closestPoint.x())+(p.y()-closestPoint.y())*(p.y()-closestPoint.y()));
01653 if (fabs(disPLine-disP1P2)>0.00001) cout<<"TSegment::closestPoint: dis p -> line = "<<disPLine<<" dis p -> pos = "<<disP1P2<<endl;
01654 return closestPoint;
01655 }
01656
01657 void
01658 TSegment::solveThreeHits(void) {
01659 unsigned n = _links.length();
01660
01661 for (unsigned i = 0; i < n; i++) {
01662 const TMDCWireHit * h = _links[i]->hit();
01663 const TMDCWire * w = h->wire();
01664 unsigned state = h->state();
01665
01666
01667 const TMDCWire * neighbor[6];
01668 for (unsigned j = 0; j < 6; j++) neighbor[j] = w->neighbor(j);
01669
01670
01671 unsigned pattern = 0;
01672 for (unsigned j = 0; j < 6; j++) {
01673 if (neighbor[j])
01674 if (neighbor[j]->hit())
01675 pattern += (1 << j);
01676 }
01677 state |= (pattern << WireHitNeighborHit);
01678
01679
01680 if ((pattern == 34) || (pattern == 42) ||
01681 (pattern == 40) || (pattern == 10) ||
01682 (pattern == 35) || (pattern == 50))
01683 state |= WireHitPatternRight;
01684 else if ((pattern == 17) || (pattern == 21) ||
01685 (pattern == 20) || (pattern == 5) ||
01686 (pattern == 19) || (pattern == 49))
01687 state |= WireHitPatternLeft;
01688
01689
01690 h->state(state);
01691 }
01692 }
01693
01694