00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TrkReco/TMLine.h"
00014 #include "TrkReco/TMDCUtil.h"
00015 #include "TrkReco/TMDCWire.h"
00016 #include "TrkReco/TMDCWireHit.h"
00017 #include "TrkReco/TMDCWireHitMC.h"
00018 #include "TrkReco/TTrackHEP.h"
00019
00020 const TLineFitter
00021 TMLine::_fitter = TLineFitter("TMLine Default Line Fitter");
00022
00023 TMLine::TMLine()
00024 : TTrackBase(),
00025 _a(0.),
00026 _b(0.),
00027 _det(0.),
00028 _fittedUpdated(false),
00029 _chi2(0.),
00030 _reducedChi2(0.) {
00031
00032
00033 fitter(& TMLine::_fitter);
00034 }
00035
00036 TMLine::TMLine(const AList<TMLink> & a)
00037 : TTrackBase(a),
00038 _a(0.),
00039 _b(0.),
00040 _det(0.),
00041 _fittedUpdated(false),
00042 _chi2(0.),
00043 _reducedChi2(0.) {
00044
00045
00046 fitter(& TMLine::_fitter);
00047 }
00048
00049 TMLine::~TMLine() {
00050 }
00051
00052 void
00053 TMLine::dump(const std::string & msg, const std::string & pre) const {
00054 bool def = false;
00055 if (msg == "") def = true;
00056
00057 if (def || msg.find("line") != std::string::npos || msg.find("detail") != std::string::npos) {
00058 std::cout << pre;
00059 std::cout << "#links=" << _links.length();
00060 std::cout << ",a=" << _a;
00061 std::cout << ",b=" << _b;
00062 std::cout << ",det=" << _det;
00063 std::cout << std::endl;
00064 }
00065 if (! def) TTrackBase::dump(msg, pre);
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
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 double
00113 TMLine::chi2(void) const {
00114 #ifdef TRKRECO_DEBUG
00115 if (! _fitted)
00116 std::cout << "TMLine::chi2 !!! fit not performed" << std::endl;
00117 #endif
00118
00119 if (_fittedUpdated) return _chi2;
00120 _chi2 = 0.;
00121 unsigned n = _links.length();
00122 for (unsigned i = 0; i < n; i++) {
00123 TMLink & l = * _links[i];
00124
00125 double x = l.position().x();
00126 double y = l.position().y();
00127 double c = y - _a * x - _b;
00128 _chi2 += c * c;
00129 }
00130 _fittedUpdated = true;
00131 return _chi2;
00132 }
00133
00134 void
00135 TMLine::refine(AList<TMLink> & list, float maxSigma) {
00136 AList<TMLink> bad;
00137 unsigned n = _links.length();
00138 for (unsigned i = 0; i < n; i++) {
00139 TMLink & l = * _links[i];
00140 double dist = distance(l);
00141 if (dist > maxSigma) bad.append(l);
00142 }
00143
00144 #ifdef TRKRECO_DEBUG_DETAIL
00145 std::cout << " TMLine::refine ... rejected hits:max distance=" << maxSigma;
00146 std::cout << std::endl;
00147 bad.sort(SortByWireId);
00148 for (unsigned i = 0; i < bad.length(); i++) {
00149 TMLink & l = * _links[i];
00150 std::cout << " ";
00151 std::cout << l.wire()->layerId() << "-";
00152 std::cout << l.wire()->localId();
00153 std::cout << "(";
00154 if (l.hit()->mc()) {
00155 if (l.hit()->mc()->hep()) std::cout << l.hit()->mc()->hep()->id();
00156 else std::cout << "0";
00157 }
00158 std::cout << "),";
00159 std::cout << l.position() << "," << distance(l);
00160 if (distance(l) > maxSigma) std::cout << " X";
00161 std::cout << std::endl;
00162 }
00163 #endif
00164
00165 if (bad.length()) {
00166 _links.remove(bad);
00167 list.append(bad);
00168 _fitted = false;
00169 _fittedUpdated = false;
00170 }
00171 }
00172
00173 int
00174 TMLine::fit2() {
00175 std::cout<<" "<<__FILE__<<" "<<__LINE__<<" ERROR : nsl"<<std::endl;
00176
00177
00178 unsigned n = _links.length();
00179 int mask[100] = {0};
00180 int nsl[11] = {64,80,96,128,144,160,192,208,240,256,288};
00181 int npos = 0, nneg = 0;
00182 for (unsigned i = 0; i < n -1 ; i++) {
00183 TMLink & l = * _links[i];
00184 for (unsigned j = i+1; j < n ; j++) {
00185 TMLink & s = * _links[j];
00186 if(l.hit()->wire()->layerId() == s.hit()->wire()->layerId()){
00187
00188 if(i > 0 && (mask[i-1] == 1 && mask[j] == 1) ){
00189 TMLink & t = * _links[i-1];
00190 if(l.hit()->wire()->layerId() == t.hit()->wire()->layerId()){
00191 mask[i] = 1;
00192 }
00193 }
00194 int ilast = nsl[l.hit()->wire()->superLayerId()]-1;
00195 int ilocal = l.hit()->wire()->localId();
00196 int jlocal = s.hit()->wire()->localId();
00197 if(ilocal > 0 && ilocal < ilast){
00198 if(abs(jlocal-ilocal) > 1 ) {
00199 mask[i] = 1;
00200 mask[j] = 1;
00201 }
00202 }else if(ilocal == 0){
00203 if(jlocal > 1 && jlocal < ilast){
00204 mask[i] = 1;
00205 mask[j] = 1;
00206 }
00207 }else if(ilocal == ilast){
00208 if(jlocal > 0 && jlocal < ilast-1){
00209 mask[i] = 1;
00210 mask[j] = 1;
00211 }
00212 }
00213 }
00214 }
00215
00216 if(mask[i] == 0){
00217 if(l.position().y() >= 0) npos += 1;
00218 if(l.position().y() < 0) nneg += 1;
00219 }
00220 }
00221
00222
00223 double sumX = 0., sumY = 0., sumX2 = 0., sumXY = 0., sumY2 = 0.;
00224 int nused = 0;
00225 int lyid[2];
00226 for (unsigned i = 0; i < n; i++) {
00227
00228 if(mask[i] == 1) continue;
00229
00230 TMLink & l = * _links[i];
00231
00232 double x = l.position().x();
00233 double y = l.position().y();
00234 if(abs(npos-nneg) > 3){
00235 if(npos > nneg && y < 0 ) continue;
00236 if(npos < nneg && y > 0 ) continue;
00237 }
00238 sumX += x;
00239 sumY += y;
00240 sumX2 += x * x;
00241 sumXY += x * y;
00242 sumY2 += y * y;
00243 if(nused < 2){
00244 lyid[nused] = l.hit()->wire()->layerId();
00245 }
00246 nused += 1;
00247 }
00248
00249 if(nused < 2 || (nused == 2 && lyid[0]==lyid[1])) {
00250 return -2;
00251 }
00252 double sum = double(nused);
00253 _det = sum * sumX2 - sumX * sumX;
00254 if(_det == 0.) {
00255 return -1;
00256 }
00257 _a = (sumXY * sum - sumX * sumY) / _det;
00258 _b = (sumX2 * sumY - sumX * sumXY) / _det;
00259
00260 _fitted = true;
00261 return 0;
00262 }
00263
00264 int
00265 TMLine::fit2s() {
00266
00267
00268 unsigned n = _links.length();
00269 int mask[100] = {0};
00270 int npos = 0, nneg = 0;
00271 for (unsigned i = 0; i < n -1 ; i++) {
00272 TMLink & l = * _links[i];
00273 for (unsigned j = i+1; j < n ; j++) {
00274 TMLink & s = * _links[j];
00275 if(l.hit()->wire()->layerId() == s.hit()->wire()->layerId()){
00276 mask[i] = 1;
00277 mask[j] = 1;
00278 }
00279 }
00280
00281 if(mask[i] == 0){
00282 if(l.position().y() >= 0) npos += 1;
00283 if(l.position().y() < 0) nneg += 1;
00284 }
00285 }
00286
00287
00288 double sumX = 0., sumY = 0., sumX2 = 0., sumXY = 0., sumY2 = 0.;
00289 int nused = 0;
00290 int lyid[2];
00291 for (unsigned i = 0; i < n; i++) {
00292
00293 if(mask[i] == 1) continue;
00294
00295 TMLink & l = * _links[i];
00296
00297 double x = l.position().x();
00298 double y = l.position().y();
00299 if(npos > nneg && y < 0 ) continue;
00300 if(npos < nneg && y > 0 ) continue;
00301
00302 sumX += x;
00303 sumY += y;
00304 sumX2 += x * x;
00305 sumXY += x * y;
00306 sumY2 += y * y;
00307 nused += 1;
00308 }
00309
00310 if(nused < 4) {
00311 return -2;
00312 }
00313 double sum = double(nused);
00314 _det = sum * sumX2 - sumX * sumX;
00315 if(_det == 0.) {
00316 return -1;
00317 }
00318 _a = (sumXY * sum - sumX * sumY) / _det;
00319 _b = (sumX2 * sumY - sumX * sumXY) / _det;
00320
00321 _fitted = true;
00322 return 0;
00323 }
00324 int
00325 TMLine::fit2sp() {
00326
00327
00328 unsigned n = _links.length();
00329 int mask[100] = {0};
00330 double phi_ave = 0.;
00331 int nphi = 0;
00332 double Crad = 180./3.141592;
00333 for (unsigned i = 0; i < n -1 ; i++) {
00334 TMLink & l = * _links[i];
00335 for (unsigned j = i+1; j < n ; j++) {
00336 TMLink & s = * _links[j];
00337 if(l.hit()->wire()->layerId() == s.hit()->wire()->layerId()){
00338 mask[i] = 1;
00339 mask[j] = 1;
00340 }
00341 }
00342
00343 if(mask[i] != 1){
00344 double phi = Crad*atan2(l.position().y(), l.position().x());
00345 phi_ave += phi;
00346 nphi += 1;
00347 }
00348 }
00349
00350
00351 if(mask[n-1] != 1){
00352 TMLink & l = * _links[n-1];
00353 double phi = Crad*atan2(l.position().y(), l.position().x());
00354 phi_ave += phi;
00355 nphi += 1;
00356 }
00357 double phi_max = 0.;
00358 double phi_min = 0.;
00359 if(nphi> 0){
00360 phi_max = phi_ave/n + 40;
00361 phi_min = phi_ave/n - 40;
00362 }
00363
00364
00365 double sumX = 0., sumY = 0., sumX2 = 0., sumXY = 0., sumY2 = 0.;
00366 int nused = 0;
00367 int lyid[2];
00368 for (unsigned i = 0; i < n; i++) {
00369
00370 if(mask[i] == 1) continue;
00371
00372 TMLink & l = * _links[i];
00373
00374 double x = l.position().x();
00375 double y = l.position().y();
00376 double phi = Crad*atan2(l.position().y(), l.position().x());
00377 if(phi > phi_max && phi<phi_min ) continue;
00378
00379 sumX += x;
00380 sumY += y;
00381 sumX2 += x * x;
00382 sumXY += x * y;
00383 sumY2 += y * y;
00384 nused += 1;
00385 }
00386
00387 if(nused < 4) {
00388 return -2;
00389 }
00390 double sum = double(nused);
00391 _det = sum * sumX2 - sumX * sumX;
00392 if(_det == 0.) {
00393 return -1;
00394 }
00395 _a = (sumXY * sum - sumX * sumY) / _det;
00396 _b = (sumX2 * sumY - sumX * sumXY) / _det;
00397
00398 _fitted = true;
00399 return 0;
00400 }
00401
00402 int
00403 TMLine::fit2p() {
00404
00405
00406 std::cout<<" "<<__FILE__<<" "<<__LINE__<<" ERROR : nsl"<<std::endl;
00407 unsigned n = _links.length();
00408 int mask[100] = {0};
00409 int nsl[11] = {64,80,96,128,144,160,192,208,240,256,288};
00410 double phi_ave = 0.;
00411 int nphi = 0;
00412 double Crad = 180./3.141592;
00413 for (unsigned i = 0; i < n -1 ; i++) {
00414 TMLink & l = * _links[i];
00415 for (unsigned j = i+1; j < n ; j++) {
00416 TMLink & s = * _links[j];
00417 if(l.hit()->wire()->layerId() == s.hit()->wire()->layerId()){
00418
00419 if(i > 0 && (mask[i-1] == 1 && mask[j] == 1) ){
00420 TMLink & t = * _links[i-1];
00421 if(l.hit()->wire()->layerId() == t.hit()->wire()->layerId()){
00422 mask[i] = 1;
00423 }
00424 }
00425 int ilast = nsl[l.hit()->wire()->superLayerId()]-1;
00426 int ilocal = l.hit()->wire()->localId();
00427 int jlocal = s.hit()->wire()->localId();
00428 if(ilocal > 0 && ilocal < ilast){
00429 if(abs(jlocal-ilocal) > 1 ) {
00430 mask[i] = 1;
00431 mask[j] = 1;
00432 }
00433 }else if(ilocal == 0){
00434 if(jlocal > 1 && jlocal < ilast){
00435 mask[i] = 1;
00436 mask[j] = 1;
00437 }
00438 }else if(ilocal == ilast){
00439 if(jlocal > 0 && jlocal < ilast-1){
00440 mask[i] = 1;
00441 mask[j] = 1;
00442 }
00443 }
00444 }
00445 }
00446
00447
00448 if(mask[i] != 1){
00449 double phi = Crad*atan2(l.position().y(), l.position().x());
00450 phi_ave += phi;
00451 nphi += 1;
00452 }
00453 }
00454
00455
00456 if(mask[n-1] != 1){
00457 TMLink & l = * _links[n-1];
00458 double phi = Crad*atan2(l.position().y(), l.position().x());
00459 phi_ave += phi;
00460 nphi += 1;
00461 }
00462 double phi_max = 0.;
00463 double phi_min = 0.;
00464 if(nphi> 0){
00465 phi_max = phi_ave/n + 40;
00466 phi_min = phi_ave/n - 40;
00467 }
00468
00469
00470 double sumX = 0., sumY = 0., sumX2 = 0., sumXY = 0., sumY2 = 0.;
00471 int nused = 0;
00472 int lyid[2];
00473 for (unsigned i = 0; i < n; i++) {
00474
00475 if(mask[i] == 1) continue;
00476
00477 TMLink & l = * _links[i];
00478
00479 double x = l.position().x();
00480 double y = l.position().y();
00481 double phi = Crad*atan2(l.position().y(), l.position().x());
00482 if(phi > phi_max && phi<phi_min ) continue;
00483
00484 sumX += x;
00485 sumY += y;
00486 sumX2 += x * x;
00487 sumXY += x * y;
00488 sumY2 += y * y;
00489 if(nused < 2){
00490 lyid[nused] = l.hit()->wire()->layerId();
00491 }
00492 nused += 1;
00493 }
00494
00495 if(nused < 2 || (nused == 2 && lyid[0]==lyid[1])) {
00496 return -2;
00497 }
00498 double sum = double(nused);
00499 _det = sum * sumX2 - sumX * sumX;
00500 if(_det == 0.) {
00501 return -1;
00502 }
00503 _a = (sumXY * sum - sumX * sumY) / _det;
00504 _b = (sumX2 * sumY - sumX * sumXY) / _det;
00505
00506 _fitted = true;
00507 return 0;
00508 }
00509
00510 void
00511 TMLine::removeChits() {
00512
00513 unsigned n = _links.length();
00514 int nlyr[50] = {0};
00515 int nneg = 0, npos = 0;
00516 for (unsigned i = 0; i < n -1 ; i++) {
00517 TMLink & l = * _links[i];
00518 nlyr[l.hit()->wire()->layerId()] += 1;
00519 if(l.position().y() < 0.){
00520 nneg += 1;
00521 }else {
00522 npos += 1;
00523 }
00524 }
00525
00526
00527 AList<TMLink> bad;
00528 for (unsigned i = 0; i < n; i++) {
00529
00530 TMLink & l = * _links[i];
00531
00532
00533 if (nlyr[l.hit()->wire()->layerId()] > 3) {
00534 bad.append(l);
00535 continue;
00536 }
00537
00538 if(abs(nneg - npos) > 3) {
00539 if(npos > nneg && l.position().y() < 0 ) bad.append(l);
00540 if(npos < nneg && l.position().y() > 0 ) bad.append(l);
00541 }
00542 }
00543
00544 if (bad.length() > 0 && bad.length() < n) {
00545 _links.remove(bad);
00546 }
00547
00548
00549 _fitted = false;
00550 _fittedUpdated = false;
00551 }
00552
00553 void
00554 TMLine::removeSLY(AList<TMLink> & list) {
00555 _links.remove(list);
00556 _fitted = false;
00557 _fittedUpdated = false;
00558 }
00559
00560 void
00561 TMLine::appendSLY(AList<TMLink> & list) {
00562 _links.append(list);
00563 _fitted = false;
00564 _fittedUpdated = false;
00565 }
00566
00567 void
00568 TMLine::appendByszdistance(AList<TMLink> & list, unsigned isl, float maxSigma) {
00569
00570
00571 unsigned nb = _links.length();
00572
00573
00574 unsigned n = list.length();
00575 for (unsigned i = 0; i < n; i++) {
00576 TMLink & l = * list[i];
00577 if(l.hit()->wire()->superLayerId() == isl){
00578 double dist = distance(l);
00579 if (dist < maxSigma) {
00580 _links.append(l);
00581 }
00582 }
00583 }
00584
00585 unsigned na = _links.length();
00586 if(nb != na){
00587 AList<TMLink> bad;
00588
00589 for(unsigned i = 0; i<na ;i++){
00590 TMLink & l = * _links[i];
00591 if(i < na - 1) {
00592 TMLink & lnext = * _links[i+1];
00593 if(l.hit()->wire()->layerId() == lnext.hit()->wire()->layerId() ){
00594 if(l.hit()->wire()->localId() == lnext.hit()->wire()->localId()){
00595 bad.append(l);
00596 }
00597 }
00598 }
00599 }
00600 if(bad.length() > 0) _links.remove(bad);
00601 _fitted = false;
00602 _fittedUpdated = false;
00603 }
00604 }
00605
00606 double
00607 TMLine::reducedChi2(void) const {
00608 #ifdef TRKRECO_DEBUG
00609 if (! _fitted)
00610 std::cout << "TMLine::reducedChi2 !!! fit not performed" << std::endl;
00611 #endif
00612
00613 if (_fittedUpdated) return _reducedChi2;
00614 double chi2 = 0.;
00615 double scale = 20.;
00616 unsigned n = _links.length();
00617 for (unsigned i = 0; i < n; i++) {
00618 TMLink & l = * _links[i];
00619
00620 double x = l.position().x();
00621 double y = l.position().y();
00622 double c = y - _a * x - _b;
00623 double err = 1.;
00624 if (l.hit()) err = scale * l.hit()->dDrift();
00625 chi2 += c * c / err / err;
00626 }
00627
00628 _reducedChi2 = chi2/(n-2);
00629 _fittedUpdated = true;
00630 return _reducedChi2;
00631 }
00632
00633 #if defined(__GNUG__)
00634
00635 int
00636 SortByB(const TMLine ** a, const TMLine ** b) {
00637 if (fabs((* a)->b()) > fabs((* b)->b()))
00638 return 1;
00639 else if (fabs((* a)->b()) == fabs((* b)->b()))
00640 return 0;
00641 else
00642 return -1;
00643 }
00644
00645 #else
00646
00647 extern "C" int
00648 SortByB(const void * av, const void * bv) {
00649 const TMLine ** a((const TMLine **) av);
00650 const TMLine ** b((const TMLine **) bv);
00651 if (fabs((* a)->b()) > fabs((* b)->b()))
00652 return 1;
00653 else if (fabs((* a)->b()) == fabs((* b)->b()))
00654 return 0;
00655 else
00656 return -1;
00657 }
00658
00659 #endif