/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Reconstruction/TrkReco/TrkReco-00-08-59-patch4-slc6tag/src/TSegment.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 // $Id: TSegment.cxx,v 1.16 2010/03/31 09:58:59 liucy Exp $
00003 //-----------------------------------------------------------------------------
00004 // Filename : TSegment.cc
00005 // Section  : Tracking
00006 // Owner    : Yoshi Iwasaki
00007 // Email    : yoshihito.iwasaki@kek.jp
00008 //-----------------------------------------------------------------------------
00009 // Description : A class to manage a group of TMLink's.
00010 //               See http://bsunsrv1.kek.jp/~yiwasaki/tracking/
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 //#include "cdc/Range.h"
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 //    _times = 4.0;
00042 //    if (_links[0]->wire()->stereo()) _times = 7.0;
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 //    _times = 4.0;
00070 //    if (_links[0]->wire()->stereo()) _times = 7.0;
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 }  //the above two innitial function are temporary for tsf!!!
00084 
00085 /*TSegment::TSegment()
00086 : TTrackBase(),
00087   _innerWidth(0),
00088   _outerWidth(0),
00089   _nLayer(0),
00090   _clusterType(0),
00091   _duality(0.),
00092   _nDual(0),
00093   _angle(0.),
00094   _state(0) {
00095     _fitted = false;
00096 }
00097 
00098 TSegment::TSegment(const AList<TMLink> & a)
00099 : TTrackBase(a),
00100   _innerWidth(0),
00101   _outerWidth(0),
00102   _nLayer(0),
00103   _clusterType(0),
00104   _duality(0.),
00105   _nDual(0),
00106   _angle(0.),
00107   _state(0) {
00108     _links.sort(SortByWireId);
00109     _fitted = false;
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; //tmp for tsf
00157 //    if (_links.length() < 3) return;
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 /*//--------------------------------tsf---------------------------------//
00176         const HepPoint3D & p = _links[i]->positionD();
00177         double d = _links[i]->cDrift();
00178         HepPoint3D posOnLine = closestPoint(p, _lineTsf);
00179         HepPoint3D v = (posOnLine - p).unit();
00180         const HepPoint3D tmp = p + d*v;
00181 *///--------------------------------tsf---------------------------------//
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 //      TTrackBase::dump("hits");
00196 //      std::cout << "0:nin,nout=" << nInner << "," << nOuter << std::endl;
00197 //      std::cout << "0:in,out=" << inner << ", " << _outerPosition << std::endl;
00198 //      std::cout << "0:npos=" << n << std::endl;
00199 //      std::cout << "0:pos=" << _position << std::endl;
00200 
00201     _innerWidth = Width(_inners);
00202     _outerWidth = Width(_outers);
00203     _position *= (1. / float(n));   //tmp for tsf
00204 
00205     inner *= (1. / (float) nInner);
00206     _outerPosition *= (1. / (float) nOuter);
00207     _direction = (inner - _outerPosition).unit();   //tmp for tsf
00208 
00209 /*//----------------------liuqg add for tsf-----------------------//
00210     if (_links.length() > 3) {
00211         _position = ORIGIN;
00212         _direction = ORIGIN;
00213         HepPoint3D nearLine;
00214         nearLine = _lineTsf;
00215 //      nearLine = leastSquaresFitting1(_links, _lineTsf);
00216 //      _lineTsf = nearLine;
00217         if (nearLine.z() != 0) {
00218             HepPoint3D lineVector;  //exchange line to vector.
00219             lineVector.set(-nearLine.y()/nearLine.z(), nearLine.x()/nearLine.z(), 0.);
00220             _direction = (lineVector).unit();
00221         }
00222         else cout<<"nearLine.z == 0"<<endl;
00223         _position = positionTsf(_links, nearLine);
00224         //cout<<"pos of seg .. = "<<_position<<endl;
00225         //cout<<"dir of seg .. = "<<_direction<<endl;
00226     }
00227 *///----------------------liuqg add for tsf-----------------------//
00228 
00229 //      std::cout << "1:in,out=" << inner << ", " << _outerPosition << std::endl;
00230 //      std::cout << "1:dir=" << _direction << std::endl;
00231 //      std::cout << "1:pos=" << _position << std::endl;
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     //...Search for a center...
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 //     std::cout << "    center=" << center << std::endl;
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 //      std::cout << "    ";
00314 //      std::cout << _links[i]->wire()->layerId() << "-";
00315 //      std::cout << _links[i]->wire()->localId() << ",";
00316 //      std::cout << _links[i]->position().x();
00317 //      std::cout << ",0,1=" << distance0 << "," << distance1;
00318 //      std::cout << ",l,r=" << distanceL << "," << distanceR;
00319 //      std::cout << std::endl;
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     //...Parameter...
00335     unsigned fat = 3;
00336     unsigned tall = 3;
00337 //    unsigned tall = 2;
00338 
00339     //...Calculate
00340     updateDuality();
00341 
00342     //...Long or short...
00343     if ((_innerWidth < fat) && (_outerWidth < fat)) {
00344         _clusterType = 1;
00345 
00346         //...Check length across a super layer...
00347         if (_nLayer > tall) _clusterType = 2;
00348         return;
00349     }
00350 
00351     //...A...
00352     else if (_outerWidth < fat) {
00353         _clusterType = 3;
00354         return;
00355     }
00356 
00357     //...V...
00358     else if (_innerWidth < fat) {
00359         _clusterType = 4;
00360         return;
00361     }
00362 
00363     //...X or parallel...
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     //...Do not split if cluster type is 1, 2, or 7...
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         // beta 5
00399         //if (_nDual > 2 && _duality > 0.7 && _angle > 0.7) return splitDual();
00400 
00401         // 1.67g
00402         // if (_nDual > 2 && _duality > 0.7) return splitDual();
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     //...Parallel...
00411     else if (t == 6) return splitParallel();
00412     // else if (t == 6) return list;
00413 
00414     //...Avoid splitting of X or parallel...(future implementation)...
00415     else if (t > 4) return splitComplicated();
00416 
00417     //...A or V...
00418     return splitAV();
00419 }
00420 
00421 AList<TSegment>
00422 TSegment::splitAV(void) const {
00423     unsigned t = clusterType();
00424     AList<TMLink> seeds[2];
00425 
00426     //...Calculate corner of V or A...
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     //...Calculdate edges...
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     //...Examine each hits...
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     //...Select best hits...
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     //...Main loop...
00528     goodHits.sort(SortByWireId);
00529     AList<TMLink> original(_links);
00530     while (goodHits.length()) {
00531 
00532         //...Select an edge hit...
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             //...Straight?...
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         //...Create new cluster...
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     //...Remainings...
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     //...Solve them...
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 //#include "tuple/BelleTupleManager.h"
00806 #include "BesKernel/BesModule.h"
00807 #include "BesKernel/BesHistogramService.h"
00808 #include "BesKernel/BesHObject.h"
00809 
00810 void
00811 CheckSegments(const CAList<TSegment> & list) {
00812     static bool first = true;
00813 //    static BelleHistogram * hError;
00814 //    static BelleHistogram * hNHeps[11];
00815 //    static BelleHistogram * hNHits[3];
00816     BesHistogramService * svc = Framework()->HistogramSvc();
00817     static BesHObject * hError;
00818     static BesHObject * hNHeps[11];  
00819     static BesHObject * hNHits[3];  
00820     
00821     if (first) {
00822         first = false;
00823 //      extern BelleTupleManager * BASF_Histogram;
00824 //      BelleTupleManager * m = BASF_Histogram;
00825 
00826 //      hError = m->histogram("segment errors", 10, 0, 10, 20000);
00827 //
00828 //      hNHeps[0] = m->histogram("segment nheps sl 0", 10, 0., 10.);
00829 //      hNHeps[1] = m->histogram("segment nheps sl 1", 10, 0., 10.);
00830 //      hNHeps[2] = m->histogram("segment nheps sl 2", 10, 0., 10.);
00831 //      hNHeps[3] = m->histogram("segment nheps sl 3", 10, 0., 10.);
00832 //      hNHeps[4] = m->histogram("segment nheps sl 4", 10, 0., 10.);
00833 //      hNHeps[5] = m->histogram("segment nheps sl 5", 10, 0., 10.);
00834 //      hNHeps[6] = m->histogram("segment nheps sl 6", 10, 0., 10.);
00835 //      hNHeps[7] = m->histogram("segment nheps sl 7", 10, 0., 10.);
00836 //      hNHeps[8] = m->histogram("segment nheps sl 8", 10, 0., 10.);
00837 //      hNHeps[9] = m->histogram("segment nheps sl 9", 10, 0., 10.);
00838 //      hNHeps[10] = m->histogram("segment nheps sl 10", 10, 0., 10.);
00839 //
00840 //      hNHits[0] = m->histogram("segment nhits, nheps = 1", 20, 0., 20.);
00841 //      hNHits[1] = m->histogram("segment nhits, nheps = 2", 20, 0., 20.);
00842 //      hNHits[2] = m->histogram("segment nhits, nheps >= 3", 20, 0., 20.);
00843 //
00844         hError = svc -> Book(1,"segment errors", 10, 0, 10, 20000);
00845         
00846         hNHeps[0] = svc -> Book(1,"segment nheps sl 0", 10, 0., 10.); 
00847         hNHeps[1] = svc -> Book(1,"segment nheps sl 1", 10, 0., 10.);    
00848         hNHeps[2] = svc -> Book(1,"segment nheps sl 2", 10, 0., 10.);    
00849         hNHeps[3] = svc -> Book(1,"segment nheps sl 3", 10, 0., 10.);    
00850         hNHeps[4] = svc -> Book(1,"segment nheps sl 4", 10, 0., 10.);    
00851         hNHeps[5] = svc -> Book(1,"segment nheps sl 5", 10, 0., 10.);    
00852         hNHeps[6] = svc -> Book(1,"segment nheps sl 6", 10, 0., 10.);    
00853         hNHeps[7] = svc -> Book(1,"segment nheps sl 7", 10, 0., 10.);    
00854         hNHeps[8] = svc -> Book(1,"segment nheps sl 8", 10, 0., 10.);    
00855         hNHeps[9] = svc -> Book(1,"segment nheps sl 9", 10, 0., 10.);    
00856         hNHeps[10] = svc -> Book(1,"segment nheps sl 10", 10, 0., 10.);    
00857         
00858         hNHits[0] = svc -> Book(1,"segment nhits, nheps = 1", 20, 0., 20.);  
00859         hNHits[1] = svc -> Book(1,"segment nhits, nheps = 2", 20, 0., 20.);     
00860         hNHits[2] = svc -> Book(1,"segment nhits, nheps >= 3", 20, 0., 20.);     
00861         
00862         std::cout << "CheckSegments ... initialized" << std::endl;
00863         return;
00864     }
00865 
00866     unsigned n = list.length();
00867     for (unsigned i = 0; i < n; i++) {
00868         const TSegment & s = * list[i];
00869         const AList<TMLink> & links = s.links();
00870         unsigned nLinks = links.length();
00871         if (nLinks == 0) {
00872 //          hError->accumulate(0.5);
00873         hError->Fill(0.5);
00874         continue;
00875         }
00876 
00877         unsigned sl = links[0]->wire()->superLayerId();
00878         unsigned nHeps = s.nHeps();
00879 //      hNHeps[sl]->accumulate((float) nHeps + .5);
00880         hNHeps[sl]->Fill((float) nHeps + .5);  
00881 //      if (nHeps == 1)      hNHits[0]->accumulate((float) nLinks + .5);
00882 //      else if (nHeps == 2) hNHits[1]->accumulate((float) nLinks + .5);
00883 //      else                 hNHits[2]->accumulate((float) nLinks + .5);
00884         if (nHeps == 1)      hNHits[0]->Fill((float) nLinks + .5);
00885         else if (nHeps == 2) hNHits[1]->Fill((float) nLinks + .5);
00886         else                 hNHits[2]->Fill((float) nLinks + .5);
00887                         
00888     }
00889 }
00890 
00891 void
00892 CheckSegmentLink(const TSegment & base,
00893                  const TSegment & next,
00894                  float distance,
00895                  float dirAngle) {
00896         
00897     static bool first = true;
00898     static BelleHistogram * hAngle[2];
00899     static BelleHistogram * hAngle1[2];
00900     static BelleHistogram * hDistance[2];
00901     static BelleHistogram * hDirAngle[2];
00902     static BelleHistogram * hDirAngle1[2];
00903 
00904     if (first) {
00905         first = false;
00906         extern BelleTupleManager * BASF_Histogram;
00907         BelleTupleManager * m = BASF_Histogram;
00908 
00909         hAngle[0] = m->histogram("segment correct link, angle",
00910                                  50, -1., 1., 21000);
00911         hAngle[1] = m->histogram("segment wrong link, angle", 50, -1., 1.);
00912         hAngle1[0] = m->histogram("segment correct link, angle, wide",
00913                                   50, .8, 1.);
00914         hAngle1[1] = m->histogram("segment wrong link, angle, wide",
00915                                   50, .8, 1.);
00916         hDistance[0] = m->histogram("segment correct link, dist", 50, 0., 1.);
00917         hDistance[1] = m->histogram("segment wrong link, dist", 50, 0., 1.);
00918         hDirAngle[0] = m->histogram("segment correct link, dir angle",
00919                                     50, -1, 1.);
00920         hDirAngle[1] = m->histogram("segment wrong link, dir angle",
00921                                     50, -1, 1.);
00922         hDirAngle1[0] = m->histogram("segment correct link, dir angle, wide",
00923                                     50, .8, 1.);
00924         hDirAngle1[1] = m->histogram("segment wrong link, dir angle, wide",
00925                                     50, .8, 1.);
00926 
00927         std::cout << "CheckSegmentLink ... initialized" << std::endl;
00928         return;
00929     }
00930 
00931     const TTrackHEP * const hep0 = base.hep();
00932     const TTrackHEP * const hep1 = next.hep();
00933 
00934     float angle = base.direction().dot(next.direction());
00935 
00936     unsigned id = 0;
00937     if (hep0 != hep1) id = 1;
00938     hAngle[id]->accumulate(angle);
00939     hAngle1[id]->accumulate(angle);
00940     hDistance[id]->accumulate(distance);
00941     hDirAngle[id]->accumulate(dirAngle);
00942     hDirAngle1[id]->accumulate(dirAngle);
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 //      s = s->innerLinks()[0];    //tmp for tsf
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 //      const TSegment * t = s->innerLinks()[0];   //tmp for tsf
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 //liuqg add for tsf...................//
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     //get links in each layer.
01136     AList<TSegment> list;
01137     AList<TMLink> links[4];   //links in each local layer.
01138     AList<TMLink> seeds2;     //links in the outer layer.
01139     AList<TMLink> exTsf;      //links in other local layers.
01140     TMLink *seed;             //link in the mostinner layer.
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     //prepare for segment finding.
01148     if (links[0].length() == 0) {  //find in 234.
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) { //find in 1234, 124, 134, 123.
01159         seed = links[0][0];
01160         if (links[3].length() > 0) {     //1..4
01161             seeds2.append(links[3]);
01162             exTsf.append(links[1]);
01163             exTsf.append(links[2]);
01164         }
01165         else if (links[2].length() > 0) { //1..3
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);  //add the outer layer...
01173 
01174     //find segments
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) {   //for 123
01185         exTsf.removeAll();
01186         seeds2.removeAll();
01187         exTsf.append(links[1]);
01188         exTsf.append(links[2]);   //add the outer layer...
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     //calculate ...
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 //cout<<"dis of circles = "<<dis<<"   radius of circles N1 = "<<ar<<"  N2 = "<<br<<endl;
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 /*    for (int i = 0; i < 4; ++i) {
01234         double d1 = distance2(seed, line[i]);
01235         double d2 = distance2(outer, line[i]);
01236         cout<<"dis of line to seed = "<<d1<<"  dis to outer = "<<d2<<endl;
01237         cout<<"radius of seed      = "<<ar<<"  rad to outer = "<<br<<endl;
01238     }
01239 *///check the calculation of line. right!!
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 //cout<<"seed: lId:"<<seed->wire()->layerId()<<" loId:"<<seed->wire()->localId()<<endl;
01251 //cout<<"outer: lId:"<<outer->wire()->layerId()<<" loId:"<<outer->wire()->localId()<<endl;
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 //cout<<"restHits: lId:"<<l->wire()->layerId()<<" loId:"<<l->wire()->localId()<<endl;
01258             double maxdis = maxdDistance(l) * _times[slId];
01259             double dis = distance2(l, line[i]);
01260 //cout<<"maxdis: "<<maxdis<<"  dis: "<<dis<<endl;
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         //check...at least 3 layers.
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         //check the neighbor hits in the first locallayer.
01277         for (int k = 0; k < seedNeighbors.length(); ++k) {
01278             TMLink * l =seedNeighbors[k];
01279 //cout<<"seedNeighbors: lId:"<<l->wire()->layerId()<<" loId:"<<l->wire()->localId()<<endl;
01280             double maxdis = maxdDistance(l) * _times[slId];
01281             double dis = distance2(l, line[i]);
01282 //cout<<"maxdis: "<<maxdis<<"  dis: "<<dis<<endl;
01283             if(seeds.hasMember(l)) continue;
01284             if (fabs(dis - l->cDrift()) < maxdis) seeds.append(l);
01285             else continue;
01286         }
01287 
01288         //update tag of each link.
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         //creat segment and update.
01296         TSegment * seg = new TSegment(seeds);
01297         seg->lineTsf(line[i]);
01298         seg->update();
01299 
01300         list.append(seg);
01301     }
01302 
01303     //salvage in new line...after update
01304 //    AList<TMLink> all;
01305 //    all.removeAll();
01306 //    all.append(restHits);
01307 //    all.append(seedNeighbors);
01308 //    for (int j = 0; j < list.length(); ++j) 
01309 //      list[j]->segSalvage(all);
01310 
01311     //expand 3layers segment
01312 /*    unsigned sl = seed->wire()->superLayerId();
01313     if(sl != 10) {
01314         for( int i = 0; i < list.length(); ++i) {
01315             AList<TMLink> segLinks = list[i]->links();
01316             unsigned nHits[4] = {0,0,0,0};
01317             int emptyLayer = -1;
01318             for(int j = 0; j < segLinks.length(); ++j)
01319                 ++nHits[segLinks[j]->wire()->localLayerId()];
01320             for (int j = 0; j < 4; ++j) {
01321                 if(nHits[j] == 0) emptyLayer = j;
01322                 if (emptyLayer != -1) break;
01323             }
01324             if(emptyLayer == -1) continue;
01325 
01326             for(int j = 0; j < all.length(); ++j){
01327                 TMLink *l = all[j];
01328                 if (l->wire()->localLayerId() == emptyLayer){
01329                     double maxdis = maxdDistance(l) * _times;
01330                     double dis = distance2(l, list[i]->lineTsf());
01331                 cout<<"layer:  "<<l->wire()->layerId()<<"  local: "<<l->wire()->localId()<<endl;
01332                 cout<<"maxdis: "<<maxdis<<"  dis in empty layer: "<<dis<<endl;
01333                 }
01334             }
01335 
01336 //          list[i]->expandSeg(emptyLayer, all);
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 //cout<<"n: "<<nTrial<<"  line = "<<line<<endl;
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     }//while...
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 //    cout<<"tsfLine = "<<tsfLine<<endl;
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 //cout<<"nTrial: "<<nTrial<<"    line0"<<a0<<" "<<b0<<" "<<c0<<endl;
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 //      cout<<"line = "<<line<<endl;
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 //cout<<"dis: "<<dis<<"  DRIFT: "<<DRIFT<<"  Sig: "<<Sig<<endl;
01500             Sig = 1./(Sig*Sig);
01501             chi2 += (dis - DRIFT)*(dis - DRIFT)*Sig;
01502         }
01503 //cout<<"chi2 = "<<chi2<<endl;
01504 
01505         //check...
01506         if(fabs(a-a0)<0.00001) break;
01507         //get line para...
01508         line0 = line;
01509         ++nTrial;
01510 /*      if(nTrial>9){
01511             cout<<"length of links = "<<n<<endl;
01512             for(int i = 0; i<n; ++i){
01513                 const HepPoint3D & p = links[i]->positionD();
01514                 cout<<"layer: "<<links[i]->wire()->layerId()<<" localId:"<<links[i]->wire()->localId()<<endl;
01515                 cout<<"drift: "<<links[i]->cDrift()<<" dis0: "<<a0*p.x() + b0*p.y() + c0*p.z()
01516                     <<" dis1:"<<a*p.x() + b*p.y() + c*p.z()<<endl;
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     //initial...
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 //      cout<<"layerId: "<<_links[i]->wire()->layerId()<<"  localId: "<<_links[i]->wire()->localId()<<endl;
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         //...Cache pointers to a neighbor...
01667         const TMDCWire * neighbor[6];
01668         for (unsigned j = 0; j < 6; j++) neighbor[j] = w->neighbor(j);
01669 
01670         //...Decide hit pattern...
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         //...Solve LR locally...
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         //...Store it...
01690         h->state(state);
01691     }
01692 }
01693 
01694 //............................tsf//

Generated on Tue Nov 29 23:14:16 2016 for BOSS_7.0.2 by  doxygen 1.4.7