00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TrkReco/TBuilderCurl.h"
00017 #include "TrkReco/TMLink.h"
00018 #include "TrkReco/TTrack.h"
00019 #include "TrackUtil/Lpav.h"
00020
00021
00022
00023
00024 #include "TrkReco/TMLine.h"
00025 #include "TrkReco/TRobustLineFitter.h"
00026
00027
00028
00029 #define DEBUG_CURL_DUMP 0
00030 #define DEBUG_CURL_GNUPLOT 0
00031 #define DEBUG_CURL_MC 0
00032
00033 #if (DEBUG_CURL_GNUPLOT+DEBUG_CURL_MC)
00034 #include "TrkReco/TMDCWireHitMC.h"
00035 #include "TrkReco/TTrackHEP.h"
00036
00037 #include "MdcTables/MdcTables.h"
00038 #include <algo.h>
00039 #endif
00040
00041 #include "GaudiKernel/StatusCode.h"
00042 #include "GaudiKernel/IInterface.h"
00043 #include "GaudiKernel/Kernel.h"
00044 #include "GaudiKernel/Service.h"
00045 #include "GaudiKernel/ISvcLocator.h"
00046 #include "GaudiKernel/SvcFactory.h"
00047 #include "GaudiKernel/IDataProviderSvc.h"
00048 #include "GaudiKernel/Bootstrap.h"
00049 #include "GaudiKernel/MsgStream.h"
00050 #include "GaudiKernel/SmartDataPtr.h"
00051 #include "GaudiKernel/IMessageSvc.h"
00052
00053 #if (DEBUG_CURL_DUMP+DEBUG_CURL_GNUPLOT+DEBUG_CURL_MC)
00054
00055
00056 static int debugMcFlag = 1;
00057 #endif
00058
00059 TBuilderCurl::TBuilderCurl(const std::string & name)
00060 : TBuilder0(name),
00061 _fitter("TBuilderCurl Fitter"){
00062
00063
00064 StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF);
00065 if(scmgn!=StatusCode::SUCCESS) {
00066 std::cout<< __FILE__<<"Unable to open Magnetic field service"<<std::endl;
00067 }
00068
00069 #if 0
00070
00071
00072
00073
00074
00075 if (m_param.ON_CORRECTION & 1) _fitter.sag(true);
00076 if (m_param.ON_CORRECTION & 2) _fitter.propagation(true);
00077 if (m_param.ON_CORRECTION & 4) _fitter.tof(true);
00078 #endif
00079 }
00080
00081 TBuilderCurl::~TBuilderCurl() {
00082
00083
00084
00085
00086 }
00087
00088 void
00089 TBuilderCurl::setParam(const TCurlFinderParameter &p) {
00090 m_param.Z_CUT = p.Z_CUT;
00091 m_param.Z_DIFF_FOR_LAST_ATTEND = p.Z_DIFF_FOR_LAST_ATTEND;
00092 m_param.SELECTOR_MAX_SIGMA = p.SELECTOR_MAX_SIGMA;
00093 m_param.SELECTOR_MAX_IMPACT = p.SELECTOR_MAX_IMPACT;
00094 m_param.SELECTOR_STRANGE_PZ = p.SELECTOR_STRANGE_PZ;
00095 m_param.SELECTOR_REPLACE_DZ = p.SELECTOR_REPLACE_DZ;
00096 m_param.SVD_RECONSTRUCTION = p.SVD_RECONSTRUCTION;
00097 m_param.MIN_SVD_ELECTRONS = p.MIN_SVD_ELECTRONS;
00098 m_param.ON_CORRECTION = p.ON_CORRECTION;
00099 m_param.CURL_VERSION = p.CURL_VERSION;
00100 #if 1
00101
00102
00103
00104
00105
00106 if (m_param.ON_CORRECTION & 1) _fitter.sag(true);
00107 if (m_param.ON_CORRECTION & 2) _fitter.propagation(true);
00108 if (m_param.ON_CORRECTION & 4) _fitter.tof(true);
00109 #endif
00110
00113
00114
00115
00116 }
00117
00118
00119
00120 void
00121 TBuilderCurl::resetHelixFit(THelixFitter *fit) const {
00122 fit->fit2D(false);
00123 fit->sag(false);
00124 fit->propagation(false);
00125 fit->tof(false);
00126 fit->freeT0(false);
00127 }
00128
00129
00130
00131
00132
00133 bool
00134 TBuilderCurl::buildStereo(TTrack & track,
00135 double &dZ,
00136 double &tanL) const {
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 }
00180
00181 TTrack *
00182 TBuilderCurl::buildStereo(TTrack & track,
00183 const AList<TMLink> & stereoList) const {
00184 return NULL;
00185 }
00186
00187 TTrack *
00188 TBuilderCurl::buildStereo(TTrack & track,
00189 const AList<TMLink> & stereoList,
00190 const AList<TMLink> & allStereoList) const {
00191 #if (DEBUG_CURL_DUMP+DEBUG_CURL_GNUPLOT+DEBUG_CURL_MC)
00192 Belle_event_Manager &evtMgr = Belle_event_Manager::get_manager();
00193 debugMcFlag = 1;
00194 if(evtMgr.count() != 0 &&
00195 evtMgr[0].ExpMC() != 2)debugMcFlag = 0;
00196 #endif
00197
00198 AList<TMLink> list = stereoList;
00199 unsigned nList = list.length();
00200
00201
00202 for(unsigned i = 0, size = track.links().length(); i < size; ++i){
00203 unsigned superID = (track.links())[i]->wire()->superLayerId();
00204 if(superID == 0 || superID == 1 || superID == 5 ||
00205 superID == 6 || superID == 7 || superID == 8 ){
00206 int ok = 1;
00207 for (unsigned j = 0; j < nList; ++j) {
00208 TMLink * l = list[j];
00209 if(l->hit()->wire()->id() == (track.links())[i]->hit()->wire()->id()){
00210 ok = 0; break;
00211 }
00212 }
00213 if(ok == 1)list.append(((track.links())[i]));
00214 }
00215
00216 (track.links())[i]->leftRight(2);
00217 }
00218 for(unsigned i = 0, size = list.length(); i < size; ++i){
00219 track._links.remove(list[i]);
00220
00221 list[i]->leftRight(2);
00222 }
00223
00224 if(list.length() < 2 ||
00225 list.length()+track.nLinks() < 5)return NULL;
00226 #if DEBUG_CURL_DUMP
00227 unsigned debug_stereo_counter1 = 0;
00228 for(unsigned i=0;i<track.links().length();++i){
00229 unsigned superID = (track.links())[i]->hit()->wire()->superLayerId();
00230 if(superID == 0 || superID == 1 ||
00231 superID == 5 || superID == 6 ||
00232 superID == 7 || superID == 8 )++debug_stereo_counter1;
00233 }
00234 std::cout << "(TBuilderCurl)Fitted Track:";
00235 std::cout << ", A# = " << track.links().length()-debug_stereo_counter1;
00236 std::cout << ", S# = " << debug_stereo_counter1 << "(==0)";
00237 std::cout << ", A+S# = " << track.links().length();
00238 std::cout << ", Cand Stereo Wires # = " << list.length() << std::endl;
00239 double debugChg = -1.;
00240 if(track.charge() > 0.)debugChg = 1.;
00241 if(debugChg > 0.)std::cout << "(TBuilderCurl) Positive Track" << std::endl;
00242 else std::cout << "(TBuilderCurl) Negative Track" << std::endl;
00243 #endif
00244
00245
00246 double xc2D;
00247 double yc2D;
00248 double r2D;
00249 AList<TMLink> tmpAxialList = track.links();
00250 bool err2D = fitWDD(xc2D,yc2D,r2D,tmpAxialList);
00251
00252
00253
00254
00255
00256
00257 setArcZ(track,list);
00258 AList<TMLink> removeList;
00259 for(unsigned i = 0, size = list.length(); i < size; ++i){
00260 if(list[i]->arcZ(0).x() == -999. && list[i]->arcZ(1).x() == -999.)removeList.append(list[i]);
00261 }
00262 list.remove(removeList);
00263 if(list.length() < 2 ||
00264 list.length()+track.nLinks() < 5){
00265 #if DEBUG_CURL_DUMP
00266 std::cout << "(TBuilderCurl) Fail...few wires which can be set Arc-Z # = "
00267 << list.length() << std::endl;
00268 #endif
00269 return NULL;
00270 }
00271 #if DEBUG_CURL_DUMP
00272 std::cout << "(TBuilderCurl) Cand Stereo Wires which can be set Arc-Z # = "
00273 << list.length() << std::endl;
00274 plotArcZ(list,0.,0.,0);
00275 #endif
00276
00277 #if 0
00278
00279 AList<TMLink> layer[18];
00280 for(unsigned i = 0, size = list.length(); i < size; ++i){
00281 layer[list[i]->wire()->layer()->axialStereoLayerId()].append(*list[i]);
00282 }
00283
00284 #if DEBUG_CURL_DUMP
00285 for(int i=0;i<18;++i){
00286 if(layer[i].length())
00287 std::cout << "(TBuilderCurl) Cand Stereo Wires which can be set Arc-Z # = "
00288 << layer[i].length()
00289 << " on " << i << " Layer." << std::endl;
00290 }
00291 #endif
00292 #endif
00293
00294
00295 AList<TMLink> goodL;
00296 AList<HepPoint3D> goodP;
00297 double minChi2 = 9999.;
00298 double goodA = 9999.;
00299 double goodB = 9999.;
00300 makeLine(track, list, allStereoList, goodL,
00301 minChi2, goodA, goodB, goodP);
00302 HepAListDeleteAll(goodP);
00303
00304 #if DEBUG_CURL_DUMP
00305 std::cout << "(TBuilderCurl) a = " << goodA << ", b = " << goodB
00306 << " (after makeLine-function)" << std::endl;
00307 #endif
00308
00309
00310 static TRobustLineFitter rfitter("Can you work well?");
00311 TMLine newLine0(goodL);
00312 if(rfitter.fit(newLine0) != 0){
00313 #if DEBUG_CURL_DUMP
00314 std::cout << "(TBuilderCurl) Fail...linefitting...fail." << std::endl;
00315 #endif
00316 return NULL;
00317 }
00318
00319 #if DEBUG_CURL_DUMP
00320 std::cout << "(TBuilderCurl) a = " << newLine0.a() << ", b = " << newLine0.b()
00321 << " (after robustline-fit)" << std::endl;
00322 #endif
00323
00324
00325 unsigned nGoodL = goodL.length();
00326 list.remove(goodL);
00327 AList<TMLink> goodL2;
00328 if(m_param.CURL_VERSION == 0){
00329 if(fabs(newLine0.b()) < 10.){
00330 appendPoints(list, goodL2,
00331 newLine0.a(), newLine0.b(), track, m_param.Z_DIFF_FOR_LAST_ATTEND);
00332 }else{
00333 appendPoints(list, goodL2,
00334 goodA, goodB, track, m_param.Z_DIFF_FOR_LAST_ATTEND);
00335 }
00336 }else{
00337
00338 appendPoints(list, goodL2,
00339 newLine0.a(), newLine0.b(), track, m_param.Z_DIFF_FOR_LAST_ATTEND);
00340 }
00341 goodL.append(goodL2);
00342 TMLine newLine(goodL);
00343
00344
00345 if(rfitter.fit(newLine) != 0){
00346 #if DEBUG_CURL_DUMP
00347 std::cout << "(TBuilderCurl) Fail...appending and re-fitting...fail." << std::endl;
00348 #endif
00349 return NULL;
00350 }
00351
00352 #if DEBUG_CURL_DUMP
00353 std::cout << "(TBuilderCurl) a = " << newLine.a() << ", b = " << newLine.b()
00354 << " (after last-append + re-robustline-fit)" << std::endl;
00355 #endif
00356
00357 const AList<TMLink> &good = newLine.links();
00358 track.TTrackBase::append(good);
00359 if(!check(track)){
00360 #if DEBUG_CURL_DUMP
00361 std::cout << "(TBuilderCurl) Fail...checking wire numbers...fail." << std::endl;
00362 #endif
00363 return NULL;
00364 }
00365
00366
00367 Vector a = track.helix().a();
00368 if(err2D){
00369 double tmpA[3];
00370 double tmpQ = track.charge() > 0. ? 1. : -1.;
00371 tmpA[1] = fmod(atan2(tmpQ * yc2D,
00372 tmpQ * xc2D)
00373 + 4. * M_PI,
00374 2. * M_PI);
00375
00376
00377 tmpA[2] = tmpQ*(333.564095/(-1000*(m_pmgnIMF->getReferField())))/r2D;
00378
00379 tmpA[0] = xc2D/cos(tmpA[1]) - tmpQ*r2D;
00380
00381
00382
00383
00384 a[0] = tmpA[0];
00385 a[1] = tmpA[1];
00386 a[2] = tmpA[2];
00387 }
00388 a[3] = newLine.b();
00389 a[4] = newLine.a();
00390
00391
00392
00393
00394
00395
00396 if(m_param.CURL_VERSION == 0){
00397 if(fabs(a[3]) > 10. && fabs(goodB) < 10.){
00398
00399 a[3] = goodB;
00400 a[4] = goodA;
00401 }
00402 }else{
00403 if(fabs(a[3]) > 50. && fabs(goodB) < 50.){
00404 a[3] = goodB;
00405 a[4] = goodA;
00406 track.TTrackBase::remove(goodL2);
00407 }
00408 }
00409
00410 track._helix->a(a);
00411
00412 #if DEBUG_CURL_DUMP
00413 std::cout << "(TBuilderCurl) Created Line: y = " << newLine.a()
00414 << " * x + " << newLine.b()
00415 << ", size = " << good.length() << std::endl;
00416 plotArcZ(const_cast< AList<TMLink>& >(good), newLine.a(), newLine.b(), 0);
00417 #endif
00418
00419
00420
00421
00422
00423
00424 #if 1
00425
00426
00427
00428
00429
00430 if (m_param.ON_CORRECTION & 1) _fitter.sag(true);
00431 if (m_param.ON_CORRECTION & 2) _fitter.propagation(true);
00432 if (m_param.ON_CORRECTION & 4) _fitter.tof(true);
00433 #endif
00434
00435
00436 AList<TMLink> bad;
00437 int err = _fitter.fit(track);
00438 if (err < 0){
00439 #if DEBUG_CURL_DUMP
00440 std::cout << "(TBuilderCurl) Fail fitting(0)...error code = " << err << std::endl;
00441 #endif
00442 return NULL;
00443 } else if ( fabs(track.helix().a()[3]) > fabs(a[3]) &&
00444 (fabs(track.helix().a()[3]) > 50. ||
00445 fabs(track.helix().a()[2]) > 100. ||
00446 fabs(track.helix().a()[2]) < 0.1) ){
00447
00448
00449 if(m_param.ON_CORRECTION){
00450 if (m_param.ON_CORRECTION & 1) _fitter.sag(true);
00451 if (m_param.ON_CORRECTION & 2) _fitter.propagation(true);
00452 if (m_param.ON_CORRECTION & 4) _fitter.tof(true);
00453
00454
00455
00456 track._helix->a(a);
00457
00458 }else{
00459 return NULL;
00460 }
00461 }
00462
00463
00464
00465
00466
00467
00468 track.refine(bad, m_param.SELECTOR_MAX_SIGMA * 100.);
00469 if (!check(track)){
00470 #if DEBUG_CURL_DUMP
00471 std::cout << "(TBuilderCurl) Fail checking(1)..." << std::endl;
00472 #endif
00473 return NULL;
00474 }
00475 err = _fitter.fit(track);
00476 if (err < 0){
00477 #if DEBUG_CURL_DUMP
00478 std::cout << "(TBuilderCurl) Fail fitting(1)...error code = " << err << std::endl;
00479 #endif
00480 return NULL;
00481 }
00482 track.refine(bad, m_param.SELECTOR_MAX_SIGMA * 10.);
00483 if (!check(track)){
00484 #if DEBUG_CURL_DUMP
00485 std::cout << "(TBuilderCurl) Fail checking(2)..." << std::endl;
00486 #endif
00487 return NULL;
00488 }
00489 err = _fitter.fit(track);
00490 if (err < 0){
00491 #if DEBUG_CURL_DUMP
00492 std::cout << "(TBuilderCurl) Fail fitting(2)...error code = " << err << std::endl;
00493 #endif
00494 return NULL;
00495 }
00496 track.refine(bad, m_param.SELECTOR_MAX_SIGMA);
00497 if (!check(track)){
00498 #if DEBUG_CURL_DUMP
00499 std::cout << "(TBuilderCurl) Fail checking(3)..." << std::endl;
00500 #endif
00501 return NULL;
00502 }
00503 err = _fitter.fit(track);
00504 if (err < 0){
00505 #if DEBUG_CURL_DUMP
00506 std::cout << "(TBuilderCurl) Fail fitting(3)...error code = " << err << std::endl;
00507 #endif
00508 return NULL;
00509 }
00510
00511 #if 0
00512 for(int i=0;i<track.links().length();++i){
00513 if(track.links()[i]->pull() > 36.){
00514 std::cout << track.links()[i]->wire()->id()
00515 << " :+: " << track.links()[i]->pull() << std::endl;
00516 }
00517 if(track.links()[i]->hit()->state() & WireHitInvalidForFit)
00518 std::cout << "Not Valid For Fit!" << std::endl;
00519
00520
00521 }
00522 #endif
00523 track.refine(bad, m_param.SELECTOR_MAX_SIGMA);
00524 if (!check(track)){
00525 #if DEBUG_CURL_DUMP
00526 std::cout << "(TBuilderCurl) Fail checking(4)..." << std::endl;
00527 #endif
00528 return NULL;
00529 }
00530 err = _fitter.fit(track);
00531 if (err < 0){
00532 #if DEBUG_CURL_DUMP
00533 std::cout << "(TBuilderCurl) Fail fitting(4)...error code = " << err << std::endl;
00534 #endif
00535 return NULL;
00536 }
00537
00538 #if 0
00539 for(int i=0;i<track.links().length();++i){
00540 if(track.links()[i]->pull() > 36.){
00541 std::cout << track.links()[i]->wire()->id()
00542 << " :*: " << track.links()[i]->pull() << std::endl;
00543 }
00544 if(track.links()[i]->hit()->state() & WireHitInvalidForFit)
00545 std::cout << "Not Valid For Fit!" << std::endl;
00546
00547
00548 }
00549 #endif
00550
00551
00552
00553
00554
00555
00556
00557 if (track.nLinks() < 5){
00558 #if DEBUG_CURL_DUMP
00559 std::cout << "(TBuilderCurl) Success fitting, but pre-selection...fail." << std::endl;
00560 #endif
00561 return NULL;
00562 }
00563 if(fabs(track.impact()) > m_param.SELECTOR_MAX_IMPACT ||
00564 track.pt() < 0.005 ||
00565 fabs(track.pz()) > m_param.SELECTOR_STRANGE_PZ){
00566 #if DEBUG_CURL_DUMP
00567 std::cout << "(TBuilderCurl) Success fitting, but selection...fail." << std::endl;
00568 std::cout << "(TBuilderCurl) impact = " << track.impact() << std::endl;
00569 std::cout << "(TBuilderCurl) pt = " << track.pt() << std::endl;
00570 std::cout << "(TBuilderCurl) pz = " << track.pz() << std::endl;
00571 std::cout << "(TBuilderCurl) dz = " << track.helix().a()[3] << std::endl;
00572 #endif
00573 return NULL;
00574 }
00575
00576
00577 if(fabs(track.helix().a()[3]) > m_param.SELECTOR_REPLACE_DZ &&
00578 fabs(a[3]) < fabs(track.helix().a()[3])){
00579 track._helix->a(a);
00580 }
00581 #if DEBUG_CURL_DUMP
00582 std::cout << "(TBuilderCurl) Success Build Stereo!!!" << std::endl;
00583 #endif
00584 return & track;
00585 }
00586
00587
00588
00589
00590
00591 void
00592 TBuilderCurl::setArcZ(TTrack &track, AList<TMLink> &list) const {
00593 if(track.nLinks() < 4){
00594 track.stereoHitForCurl(list);
00595 return;
00596 }
00597
00598 AList<TMLink> alayer[5];
00599 AList<TMLink> slayer[6];
00600 for(unsigned i=0,size=track.nLinks();i<size;++i){
00601 unsigned id = (track.links())[i]->wire()->superLayerId();
00602 if(id == 2)alayer[0].append((track.links())[i]);
00603 else if(id == 3)alayer[1].append((track.links())[i]);
00604 else if(id == 4)alayer[2].append((track.links())[i]);
00605 else if(id == 9)alayer[3].append((track.links())[i]);
00606 else if(id == 10)alayer[4].append((track.links())[i]);
00607 }
00608
00609 for(unsigned i=0,size=list.length();i<size;++i){
00610 unsigned id = list[i]->wire()->superLayerId();
00611 if(id == 0)slayer[0].append(list[i]);
00612 else if(id == 1)slayer[1].append(list[i]);
00613 else if(id == 5)slayer[2].append(list[i]);
00614 else if(id == 6)slayer[3].append(list[i]);
00615 else if(id == 7)slayer[4].append(list[i]);
00616 else if(id == 8)slayer[5].append(list[i]);
00617 }
00618 #if 0
00619 std::cout << "Stereo = "
00620 << slayer[0].length() << " "
00621 << slayer[1].length() << " "
00622 << slayer[2].length() << " "
00623 << slayer[3].length() << " "
00624 << slayer[4].length() << std::endl;
00625 std::cout << "Axial = "
00626 << alayer[0].length() << " "
00627 << alayer[1].length() << " "
00628 << alayer[2].length() << " "
00629 << alayer[3].length() << " "
00630 << alayer[4].length() << " "
00631 << alayer[5].length() << std::endl;
00632 #endif
00633 unsigned ip = 0;
00634 if(slayer[0].length() >= 1){
00635 if(alayer[0].length()+alayer[1].length() >= 4){
00636 setArcZ(track,slayer[0],alayer[0],alayer[1],ip);
00637 }else if(alayer[0].length()+alayer[1].length()+
00638 alayer[2].length() >= 4){
00639 setArcZ(track,slayer[0],alayer[0],alayer[1],
00640 alayer[2],ip);
00641 }else if(alayer[0].length()+alayer[1].length()+
00642 alayer[2].length()+alayer[3].length() >= 4){
00643 setArcZ(track,slayer[0],alayer[0],alayer[1],
00644 alayer[2],alayer[3],ip);
00645 }else if(alayer[0].length()+alayer[1].length()+
00646 alayer[2].length()+alayer[3].length()+
00647 alayer[4].length() >= 4){
00648 setArcZ(track,slayer[0],alayer[0],alayer[1],
00649 alayer[2],alayer[3],alayer[4],ip);
00650 }
00651 }
00652 if(slayer[1].length() >= 1){
00653 if(alayer[0].length()+alayer[1].length() >= 4){
00654 setArcZ(track,slayer[1],alayer[0],alayer[1],ip);
00655 }else if(alayer[0].length()+alayer[1].length()+
00656 alayer[2].length() >= 4){
00657 setArcZ(track,slayer[1],alayer[0],alayer[1],
00658 alayer[2],ip);
00659 }else if(alayer[0].length()+alayer[1].length()+
00660 alayer[2].length()+alayer[3].length() >= 4){
00661 setArcZ(track,slayer[1],alayer[0],alayer[1],
00662 alayer[2],alayer[3],ip);
00663 }else if(alayer[0].length()+alayer[1].length()+
00664 alayer[2].length()+alayer[3].length()+
00665 alayer[4].length() >= 4){
00666 setArcZ(track,slayer[1],alayer[0],alayer[1],
00667 alayer[2],alayer[3],alayer[4],ip);
00668 }
00669 }
00670 if(slayer[2].length() >= 1){
00671 if(alayer[1].length()+alayer[2].length() >= 4){
00672 setArcZ(track,slayer[2],alayer[1],alayer[2],ip);
00673 }
00674 else if(alayer[0].length()+alayer[1].length()+
00675 alayer[2].length() >= 4){
00676 setArcZ(track,slayer[2],alayer[0],alayer[1],alayer[2],ip);
00677 }else if(alayer[0].length()+alayer[1].length()+
00678 alayer[2].length()+alayer[3].length() >= 4){
00679 setArcZ(track,slayer[2],alayer[0],alayer[1],
00680 alayer[2],alayer[3],ip);
00681 }else if(alayer[0].length()+alayer[1].length()+
00682 alayer[2].length()+alayer[3].length()+
00683 alayer[4].length() >= 4){
00684 setArcZ(track,slayer[2],alayer[0],alayer[1],
00685 alayer[2],alayer[3],alayer[4],ip);
00686
00687 }
00688 }
00689 if(slayer[3].length() >= 1){
00690 if(alayer[1].length()+alayer[2].length() >= 4){
00691 setArcZ(track,slayer[3],alayer[1],alayer[2],ip);
00692 }else if(alayer[0].length()+alayer[1].length()+
00693 alayer[2].length() >= 4){
00694 setArcZ(track,slayer[3],alayer[0],alayer[1],
00695 alayer[2],ip);
00696 }else if(alayer[0].length()+alayer[1].length()+
00697 alayer[2].length()+alayer[3].length()
00698 >= 4){
00699 setArcZ(track,slayer[3],alayer[0],alayer[1],
00700 alayer[2],alayer[3],ip);
00701 }else if(alayer[0].length()+alayer[1].length()+
00702 alayer[2].length()+alayer[3].length()+
00703 alayer[4].length() >= 4){
00704 setArcZ(track,slayer[3],alayer[0],alayer[1],
00705 alayer[2],alayer[3],alayer[4],ip);
00706
00707 }
00708 }
00709 if(slayer[4].length() >= 1){
00710 if(alayer[1].length()+alayer[2].length()
00711 >= 4){
00712 setArcZ(track,slayer[4],alayer[1],alayer[2],
00713 ip);
00714 }else if(alayer[0].length()+alayer[1].length()+
00715 alayer[2].length() >= 4){
00716 setArcZ(track,slayer[4],alayer[0],alayer[1],
00717 alayer[2],ip);
00718 }else if(alayer[0].length()+alayer[1].length()+
00719 alayer[2].length()+alayer[3].length()
00720 >= 4){
00721 setArcZ(track,slayer[4],alayer[0],alayer[1],
00722 alayer[2],alayer[3],ip);
00723 }else if(alayer[0].length()+alayer[1].length()+
00724 alayer[2].length()+alayer[3].length()+
00725 alayer[4].length() >= 4){
00726 setArcZ(track,slayer[4],alayer[0],alayer[1],
00727 alayer[2],alayer[3],alayer[4],ip);
00728 }
00729 }
00730 if(slayer[5].length() >= 1){
00731 if(alayer[1].length()+alayer[2].length()
00732 >= 4){
00733 setArcZ(track,slayer[5],alayer[1],alayer[2],
00734 ip);
00735 }else if(alayer[1].length()+alayer[2].length()+
00736 alayer[3].length() >= 4){
00737 setArcZ(track,slayer[5],alayer[1],alayer[2],
00738 alayer[3],ip);
00739 }else if(alayer[0].length()+alayer[1].length()+
00740 alayer[2].length()+alayer[3].length()
00741 >= 4){
00742 setArcZ(track,slayer[5],alayer[0],alayer[1],
00743 alayer[2],alayer[3],ip);
00744 }else if(alayer[0].length()+alayer[1].length()+
00745 alayer[2].length()+alayer[3].length()+
00746 alayer[4].length() >= 4){
00747 setArcZ(track,slayer[5],alayer[0],alayer[1],
00748 alayer[2],alayer[3],alayer[4],ip);
00749 }
00750 }
00751 }
00752
00753
00754
00755
00756 unsigned
00757 TBuilderCurl::appendPoints(AList<TMLink> &list, AList<TMLink> &line,
00758 double a, double b, TTrack &track, double z_cut) const {
00759 unsigned size = list.length();
00760 if(size == 0)return 0;
00761 unsigned counter(0);
00762 for(unsigned i=0;i<size;++i){
00763 for(unsigned j=0;j<4;++j){
00764 if(j <= 1 && list[i]->arcZ(j).x() == -999.)continue;
00765 else if(j > 1 && list[i]->arcZ(j).x() == -999.)break;
00766 double y = a*list[i]->arcZ(j).x()+b;
00767 if(fabs(y-list[i]->arcZ(j).y()) < z_cut){
00768 list[i]->position(list[i]->arcZ(j));
00769 line.append(list[i]);
00770 ++counter;
00771 break;
00772 }
00773 }
00774 }
00775 return counter;
00776 }
00777
00778
00779
00780
00781
00782 int
00783 doLineFit(AList<TMLink> &points,
00784 double &m_a, double &m_b, double &chi2, double &nhits,
00785 int ipC = 1)
00786 {
00787 m_a = m_b = nhits = 0.;
00788 chi2 = 1.e+10;
00789 unsigned n = points.length();
00790 double sum = double(n);
00791 double sumX = 0., sumY = 0., sumX2 = 0., sumXY = 0., sumY2 = 0.;
00792 for (unsigned i = 0; i < n; i++) {
00793 TMLink & l = * points[i];
00794
00795 double x = l.position().x();
00796 double y = l.position().y();
00797 sumX += x;
00798 sumY += y;
00799 sumX2 += x * x;
00800 sumXY += x * y;
00801 sumY2 += y * y;
00802 }
00803 if(ipC != 0)sum += 1.0;
00804 nhits = sum;
00805
00806 double m_det = sum * sumX2 - sumX * sumX;
00807 if(m_det == 0. && sum != 2.){
00808 return -1;
00809 }else if(m_det == 0. && sum == 2.){
00810 double x0 = points[0]->position().x();
00811 double y0 = points[0]->position().y();
00812 double x1 = points[1]->position().x();
00813 double y1 = points[1]->position().y();
00814 if(x0 == x1)return -1;
00815 m_a = (y0-y1)/(x0-x1);
00816 m_b = -m_a*x1 + y1;
00817 chi2 = 0.;
00818 return 0;
00819 }
00820 chi2 = 0.;
00821 m_a = (sumXY * sum - sumX * sumY) / m_det;
00822 m_b = (sumX2 * sumY - sumX * sumXY) / m_det;
00823
00824 for(unsigned i = 0; i < n; i++) {
00825 TMLink & l = * points[i];
00826
00827 double x = l.position().x();
00828 double y = l.position().y();
00829 double d = y-(x*m_a+m_b);
00830 chi2 += d*d;
00831 }
00832
00833 return 0;
00834 }
00835
00836 void
00837 TBuilderCurl::fitLine(AList<TMLink> &tmpLine, double &min_chi2,
00838 double &good_a, double &good_b,
00839 AList<TMLink> &goodLine, AList<HepPoint3D> &goodPosition,
00840 int &overCounter) const {
00841 #if 0
00842
00843 unsigned size = tmpLine.length();
00844 TMLine line(tmpLine);
00845 if(!(line.fit())){
00846 double chi2 = line.chi2()/(static_cast<double>(size-2));
00847 if(chi2 < min_chi2 && fabs(line.b()) < m_param.Z_CUT){
00848 min_chi2 = chi2;
00849 good_a = line.a();
00850 good_b = line.b();
00851 goodLine = tmpLine;
00852 HepAListDeleteAll(goodPosition);
00853 for(unsigned i=0;i<size;++i)
00854 goodPosition.append(new HepPoint3D(const_cast<HepPoint3D&>(tmpLine[i]->position())));
00855 }
00856 }
00857 ++overCounter;
00858 #else
00859 unsigned size = tmpLine.length();
00860 double ta,tb,tc,tn;
00861 if(!(doLineFit(tmpLine,ta,tb,tc,tn,1)) && tn > 2.){
00862 double chi2 = tc/(tn-2.);
00863 if(chi2 < min_chi2 && fabs(tb) < m_param.Z_CUT){
00864 min_chi2 = chi2;
00865 good_a = ta;
00866 good_b = tb;
00867 goodLine = tmpLine;
00868 HepAListDeleteAll(goodPosition);
00869 for(unsigned i=0;i<size;++i)
00870 goodPosition.append(new HepPoint3D(const_cast<HepPoint3D&>(tmpLine[i]->position())));
00871 }
00872 }
00873 ++overCounter;
00874 #endif
00875 }
00876
00877
00878
00879
00880
00881 unsigned
00882 TBuilderCurl::check(const TTrack &track) const {
00883 unsigned nAhits(0), nShits(0);
00884 for(unsigned i=0,size=track.nLinks();i<size;++i){
00885 if(!(track.links()[i]->hit()->state() & WireHitFittingValid))continue;
00886 if(track.links()[i]->wire()->stereo())++nShits;
00887 else ++nAhits;
00888 }
00889 if(nAhits >= 3 && nShits >= 2)return 1;
00890 return 0;
00891 }
00892
00893
00894
00895
00896
00897 int
00898 checkBorder(AList<TMLink> &layer0,
00899 AList<TMLink> &layer1,
00900 AList<TMLink> &layer2){
00901 AList<TMLink> list = layer0;
00902 list.append(layer1);
00903 list.append(layer2);
00904 int size = list.length();
00905 if(size <= 1)return 0;
00906 int layerId = list[0]->hit()->wire()->layerId();
00907 int maxLocalId = 79;
00908 if(layerId >= 15)maxLocalId = 127;
00909 if(layerId >= 23)maxLocalId = 159;
00910 if(layerId >= 32)maxLocalId = 207;
00911 if(layerId >= 41)maxLocalId = 255;
00912 int HId = (int)(0.8*(maxLocalId+1));
00913 int LId = (int)(0.2*(maxLocalId+1));
00914 int low = 0;
00915 int high = 0;
00916 for(int i=0;i>size;++i){
00917 if(list[i]->hit()->wire()->localId() < LId)low = 1;
00918 else if(list[i]->hit()->wire()->localId() > HId)high = 1;
00919 if(low == 1 && high == 1)return 1;
00920 }
00921 return 0;
00922 }
00923
00924 int
00925 checkBorder(AList<TMLink> &layer0,
00926 AList<TMLink> &layer1,
00927 AList<TMLink> &layer2,
00928 AList<TMLink> &layer3){
00929 AList<TMLink> list = layer0;
00930 list.append(layer1);
00931 list.append(layer2);
00932 list.append(layer3);
00933 int size = list.length();
00934 if(size <= 1)return 0;
00935 int layerId = list[0]->hit()->wire()->layerId();
00936 int maxLocalId = 79;
00937 if(layerId >= 15)maxLocalId = 127;
00938 if(layerId >= 23)maxLocalId = 159;
00939 if(layerId >= 32)maxLocalId = 207;
00940 if(layerId >= 41)maxLocalId = 255;
00941 int HId = (int)(0.8*(maxLocalId+1));
00942 int LId = (int)(0.2*(maxLocalId+1));
00943 int low = 0;
00944 int high = 0;
00945 for(int i=0;i>size;++i){
00946 if(list[i]->hit()->wire()->localId() < LId)low = 1;
00947 else if(list[i]->hit()->wire()->localId() > HId)high = 1;
00948 if(low == 1 && high == 1)return 1;
00949 }
00950 return 0;
00951 }
00952
00953 int
00954 offsetBorder(TMLink *l){
00955 int layerId = l->hit()->wire()->layerId();
00956 int maxLocalId = 79;
00957 if(layerId >= 15)maxLocalId = 127;
00958 if(layerId >= 23)maxLocalId = 159;
00959 if(layerId >= 32)maxLocalId = 207;
00960 if(layerId >= 41)maxLocalId = 255;
00961 return maxLocalId+1;
00962 }
00963
00964 void
00965 makeList(AList<TMLink> &layer, AList<TMLink> &list, double q, int border, int checkB, TMLink *layer0){
00966 int n = layer.length();
00967 if(checkB == 0){
00968 for(int i=0;i<n;++i){
00969 if(q < 0.){
00970 if(layer[i]->hit()->wire()->localId() >= border)list.append(layer[i]);
00971 }else{
00972 if(layer[i]->hit()->wire()->localId() <= border)list.append(layer[i]);
00973 }
00974 }
00975 }else{
00976
00977 int offset = offsetBorder(layer0);
00978 if(border*2 < offset)border += offset;
00979 for(int i=0;i<n;++i){
00980 int lId = layer[i]->hit()->wire()->localId();
00981 if(lId*2 < offset)lId += offset;
00982 if(q < 0.){
00983 if(lId >= border)list.append(layer[i]);
00984 }else{
00985 if(lId <= border)list.append(layer[i]);
00986 }
00987 }
00988 }
00989 }
00990
00991 int
00992 TBuilderCurl::sortByLocalId(AList<TMLink> &list) const{
00993 int size = list.length();
00994 if(size <= 1)return 0;
00995 int layerId = list[0]->hit()->wire()->layerId();
00996 int maxLocalId;
00997
00998
00999
01000
01001
01002
01003
01004 if(layerId == 0)maxLocalId = 39;
01005 else if(layerId == 1)maxLocalId = 43;
01006 else if(layerId == 2)maxLocalId = 47;
01007 else if(layerId == 3)maxLocalId = 55;
01008 else if(layerId == 4)maxLocalId = 63;
01009 else if(layerId == 5)maxLocalId = 71;
01010 else if(layerId < 8)maxLocalId = 79;
01011 else if(layerId < 24)maxLocalId = 159;
01012 else if(layerId < 28)maxLocalId = 175;
01013 else if(layerId < 32)maxLocalId = 207;
01014 else if(layerId < 43)maxLocalId = 239;
01015 int flag = 0;
01016 for(int i=0;i<size;++i){
01017 if(list[i]->hit()->wire()->localId() == 0 ||
01018 list[i]->hit()->wire()->localId() == 1 ||
01019 list[i]->hit()->wire()->localId() == maxLocalId-1 ||
01020 list[i]->hit()->wire()->localId() == maxLocalId){
01021 flag = 1;
01022 break;
01023 }
01024 }
01025 if(flag == 0)return 0;
01026 int maxDif = (int)(0.5*(maxLocalId+1));
01027 AList<TMLink> fList;
01028 AList<TMLink> lList;
01029 for(int i=0;i<size;++i){
01030 if(list[i]->hit()->wire()->localId() < maxDif)
01031 lList.append(list[i]);
01032 else
01033 fList.append(list[i]);
01034 }
01035 list.removeAll();
01036 list.append(fList);
01037 list.append(lList);
01038 if(fList.length() >= 1 &&
01039 lList.length() >= 1)return 1;
01040 else return 0;
01041 }
01042
01043
01044
01045
01046
01047
01048
01049 TTrack *
01050 TBuilderCurl::buildStereoMC(TTrack & track, const AList<TMLink> & stereoList) const {
01051 #if DEBUG_CURL_MC
01052 AList<TMLink> list = stereoList;
01053
01054 HepPoint3D center = track.helix().center();
01055 double r = fabs(track.helix().curv());
01056 for(unsigned i = 0, size = list.length();
01057 i < size; ++i){
01058 HepPoint3D point((list[i]->hit()->mc()->datcdc()->m_xin+
01059 list[i]->hit()->mc()->datcdc()->m_xout)*0.5,
01060 (list[i]->hit()->mc()->datcdc()->m_yin+
01061 list[i]->hit()->mc()->datcdc()->m_yout)*0.5,
01062 0.);
01063 double cosdPhi = - center.dot((point - center).unit()) / center.mag();
01064 double dPhi;
01065 if(fabs(cosdPhi) < 1.0){
01066 dPhi = acos(cosdPhi);
01067 }else if(cosdPhi >= 1.0){
01068 dPhi = 0.;
01069 }else{
01070 dPhi = M_PI;
01071 }
01072 list[i]->position(HepPoint3D(r*dPhi,
01073 (list[i]->hit()->mc()->datcdc()->m_zin+
01074 list[i]->hit()->mc()->datcdc()->m_zout)*0.5,
01075 0.));
01076
01077
01078
01079
01080
01081 }
01082
01083 double xc2D;
01084 double yc2D;
01085 double r2D;
01086 bool err2D = fitWDD(xc2D,yc2D,r2D,track.links());
01087
01088 TLine0 newLine(list);
01089 if(newLine.fit() != 0) return NULL;
01090 const AList<TMLink> &good = newLine.links();
01091 track.append(good);
01092 Vector a = track.helix().a();
01093 a[3] = newLine.b();
01094 a[4] = newLine.a();
01095 if(err2D){
01096 double tmpA[3];
01097 double tmpQ = track.charge() > 0. ? 1. : -1.;
01098 tmpA[1] = fmod(atan2(tmpQ * yc2D,
01099 tmpQ * xc2D)
01100 + 4. * M_PI,
01101 2. * M_PI);
01102
01103
01104 tmpA[2] =tmpQ*(333.564095/(-1000*(m_pmgnIMF->getReferField())))/r2D;
01105 tmpA[0] = xc2D/cos(tmpA[1]) - tmpQ*r2D;
01106 a[0] = tmpA[0];
01107 a[1] = tmpA[1];
01108 a[2] = tmpA[2];
01109 }
01110 track._helix->a(a);
01111 #if 0
01112 std::cout << track.helix().a()[0] << " " << track.helix().a()[1] << " "
01113 << track.helix().a()[2] << " " << track.helix().a()[3] << " "
01114 << track.helix().a()[4] << std::endl;
01115 #endif
01116
01117 AList<TMLink> bad;
01118 int err = _fitter.fit(track);
01119 if (err < m_param.ERROR_FOR_HELIX_FIT)return NULL;
01120 track.refine(bad, m_param.SELECTOR_MAX_SIGMA * 100.);
01121 err = _fitter.fit(track);
01122 if (err < m_param.ERROR_FOR_HELIX_FIT)return NULL;
01123 track.refine(bad, m_param.SELECTOR_MAX_SIGMA * 10.);
01124 err = _fitter.fit(track);
01125 if (err < m_param.ERROR_FOR_HELIX_FIT)return NULL;
01126 track.refine(bad, m_param.SELECTOR_MAX_SIGMA);
01127 err = _fitter.fit(track);
01128 if (err < m_param.ERROR_FOR_HELIX_FIT)return NULL;
01129 #if 0
01130 std::cout << track.helix().a()[0] << " " << track.helix().a()[1] << " "
01131 << track.helix().a()[2] << " " << track.helix().a()[3] << " "
01132 << track.helix().a()[4] << std::endl;
01133 #endif
01134
01135
01136
01137 if (track.nLinks() < m_param.SELECTOR_NLINKS)return NULL;
01138 if (fabs(track.impact()) > m_param.SELECTOR_MAX_IMPACT ||
01139 track.pt() < m_param.SELECTOR_MIN_PT)return NULL;
01140 return & track;
01141 #else
01142 return NULL;
01143 #endif
01144 }
01145
01146
01147
01148
01149
01150 void
01151 TBuilderCurl::plotArcZ(AList<TMLink> &tmpLine,
01152 double a, double b, const int flag) const {
01153 #if DEBUG_CURL_GNUPLOT
01154
01155 if(a == 9999. || b == 9999.){
01156 a = 0.;
01157 b = 0.;
01158 }
01159 int nCounter = 0;
01160 double gmaxX = 0. ,gminX = 0.;
01161 double gmaxY = 0. ,gminY = 0.;
01162 FILE *gnuplot, *data;
01163 if((data = fopen("you_can_remove_this.dat","w")) != NULL){
01164 for(int ii=0;ii<tmpLine.length();ii++){
01165 ++nCounter;
01166 fprintf(data,"%lf, %lf\n",
01167 tmpLine[ii]->position().x(),
01168 tmpLine[ii]->position().y());
01169 if(flag)std::cout << " Wire ID = " << tmpLine[ii]->hit()->wire()->id()
01170 << " Arc = " << tmpLine[ii]->position().x()
01171 << " Z = " << tmpLine[ii]->position().y();
01172
01173
01174
01175
01176
01177
01178 if(gmaxX < tmpLine[ii]->position().x())
01179 gmaxX = tmpLine[ii]->position().x();
01180 if(gminX > tmpLine[ii]->position().x())
01181 gminX = tmpLine[ii]->position().x();
01182 if(gmaxY < tmpLine[ii]->position().y())
01183 gmaxY = tmpLine[ii]->position().y();
01184 if(gminY > tmpLine[ii]->position().y())
01185 gminY = tmpLine[ii]->position().y();
01186 }
01187 fclose(data);
01188 }
01189 if((data = fopen("you_can_remove_this.dat2","w")) != NULL){
01190 #if 0
01191 if(debugMcFlag){
01192 for(int ii=0;ii<tmpLine.length();ii++){
01193 double z = (tmpLine[ii]->hit()->mc()->datcdc()->m_zin+
01194 tmpLine[ii]->hit()->mc()->datcdc()->m_zout)*0.5;
01195 if(tmpLine[ii]->arcZ(0).x() != -999.){
01196 ++nCounter;
01197 fprintf(data,"%lf, %lf\n",tmpLine[ii]->arcZ(0).x(),z);
01198 if(gmaxX < tmpLine[ii]->arcZ(0).x())
01199 gmaxX = tmpLine[ii]->arcZ(0).x();
01200 if(gminX > tmpLine[ii]->arcZ(0).x())
01201 gminX = tmpLine[ii]->arcZ(0).x();
01202 if(gmaxY < z)
01203 gmaxY = z;
01204 if(gminY > z)
01205 gminY = z;
01206 }
01207 }
01208 }
01209 #endif
01210 fclose(data);
01211 }
01212 if((data = fopen("you_can_remove_this.dat3","w")) != NULL){
01213 for(int ii=0;ii<tmpLine.length();ii++){
01214 for(int jj=0;jj<4;++jj){
01215 if(tmpLine[ii]->arcZ(jj).x() != -999.){
01216 ++nCounter;
01217 fprintf(data,"%lf, %lf\n",
01218 tmpLine[ii]->arcZ(jj).x(),
01219 tmpLine[ii]->arcZ(jj).y());
01220 if(gmaxX < tmpLine[ii]->arcZ(jj).x())
01221 gmaxX = tmpLine[ii]->arcZ(jj).x();
01222 if(gminX > tmpLine[ii]->arcZ(jj).x())
01223 gminX = tmpLine[ii]->arcZ(jj).x();
01224 if(gmaxY < tmpLine[ii]->arcZ(jj).y())
01225 gmaxY = tmpLine[ii]->arcZ(jj).y();
01226 if(gminY > tmpLine[ii]->arcZ(jj).y())
01227 gminY = tmpLine[ii]->arcZ(jj).y();
01228 }else{
01229 break;
01230 }
01231 }
01232 }
01233 fclose(data);
01234 }
01235 if(gmaxX < 0.)gmaxX = 0.;if(gminX > 0.)gminX = 0.;
01236 if(gmaxY < 0.)gmaxY = 0.;if(gminY > 0.)gminY = 0.;
01237 if(nCounter && (gnuplot = popen("gnuplot","w")) != NULL){
01238 fprintf(gnuplot,"set nokey \n");
01239 fprintf(gnuplot,"set size 0.721,1.0 \n");
01240 fprintf(gnuplot,"set xrange [%f:%f] \n",gminX,gmaxX);
01241 fprintf(gnuplot,"set yrange [%f:%f] \n",gminY,gmaxY);
01242 if(a == 0. && b == 0.){
01243 fprintf(gnuplot,"plot \"you_can_remove_this.dat3\", \"you_can_remove_this.dat\", \"you_can_remove_this.dat2\" \n");
01244 }else{
01245 fprintf(gnuplot,"plot \"you_can_remove_this.dat3\", \"you_can_remove_this.dat\", \"you_can_remove_this.dat2\", %lf*x+%lf \n", a, b);
01246 }
01247 fflush(gnuplot);
01248 char tmp[8];
01249 gets(tmp);
01250 pclose(gnuplot);
01251 }
01252 #endif
01253 return;
01254 }
01255
01256
01257
01258
01259
01260 unsigned
01261 findMaxLocalId(unsigned layerId){
01262
01263
01264
01265
01266
01267
01268
01269
01270 unsigned maxLocalId = 39;
01271 if(layerId == 1)maxLocalId = 43;
01272 else if(layerId == 2)maxLocalId = 47;
01273 else if(layerId == 3)maxLocalId = 55;
01274 else if(layerId == 4)maxLocalId = 63;
01275 else if(layerId == 5)maxLocalId = 71;
01276 else if(layerId == 6 || layerId == 7 )maxLocalId = 79;
01277 else if(layerId == 20 || layerId == 21 || layerId == 22 || layerId == 23)maxLocalId = 159;
01278 else if(layerId == 24 || layerId == 25 || layerId == 26 || layerId == 27)maxLocalId = 175;
01279 else if(layerId == 28 || layerId == 29 || layerId == 30 || layerId == 31)maxLocalId = 207;
01280 else if(layerId == 32 || layerId == 33 || layerId == 34 || layerId == 35)maxLocalId = 239;
01281
01282 return maxLocalId;
01283 }
01284
01285 unsigned
01286 isIsolation(unsigned localId,
01287 unsigned maxLocalId,
01288 unsigned layerId,
01289 int lr,
01290 const AList<TMLink> &allStereoList){
01291 unsigned findId;
01292 if(lr == 1){
01293 findId = maxLocalId;
01294 if(localId != 0)findId = localId-1;
01295 }else if(lr == -1){
01296 findId = 0;
01297 if(localId != maxLocalId)findId = localId+1;
01298 }else{
01299 return 1;
01300 }
01301 unsigned isolate = 1;
01302 for(int i=0;i<allStereoList.length();++i){
01303 if(allStereoList[i]->wire()->layerId() == layerId &&
01304 allStereoList[i]->wire()->localId() == findId){
01305 isolate = 0;
01306 break;
01307 }
01308 }
01309 return isolate;
01310 }
01311
01312 void
01313 findTwoHits(AList<TMLink> &twoOnLayer,
01314 const AList<TMLink> &hitsOnLayer,
01315 const AList<TMLink> &allStereoList){
01316
01317
01318 if(hitsOnLayer.length() == 0 ||
01319 hitsOnLayer.length() > 3)return;
01320 twoOnLayer.removeAll();
01321 if(hitsOnLayer.length() == 1){
01322 if(hitsOnLayer[0]->wire()->superLayerId() == 0)return;
01323 unsigned maxLocalId = findMaxLocalId(hitsOnLayer[0]->wire()->layerId());
01324 unsigned R = isIsolation(hitsOnLayer[0]->wire()->localId(),
01325 maxLocalId,
01326 hitsOnLayer[0]->wire()->layerId(),1,allStereoList);
01327 unsigned L = isIsolation(hitsOnLayer[0]->wire()->localId(),
01328 maxLocalId,
01329 hitsOnLayer[0]->wire()->layerId(),-1,allStereoList);
01330 if(R == 1 && L == 0){
01331 unsigned nextLocalId = hitsOnLayer[0]->wire()->localIdForPlus()+1;
01332 L = isIsolation(nextLocalId,
01333 maxLocalId,
01334 hitsOnLayer[0]->wire()->layerId(),-1,allStereoList);
01335 if(L == 1){
01336 hitsOnLayer[0]->leftRight(1);
01337 hitsOnLayer[0]->position(hitsOnLayer[0]->arcZ(1));
01338 twoOnLayer.append(hitsOnLayer[0]);
01339 }
01340 }else if(R == 0 && L == 1){
01341 unsigned nextLocalId = hitsOnLayer[0]->wire()->localIdForMinus()+1;
01342 R = isIsolation(nextLocalId,
01343 maxLocalId,
01344 hitsOnLayer[0]->wire()->layerId(),1,allStereoList);
01345 if(R == 1){
01346 hitsOnLayer[0]->leftRight(0);
01347 hitsOnLayer[0]->position(hitsOnLayer[0]->arcZ(0));
01348 twoOnLayer.append(hitsOnLayer[0]);
01349 }
01350 }
01351 }
01352 if(hitsOnLayer.length() == 2){
01353 if(hitsOnLayer[0]->wire()->localIdForPlus()+1 ==
01354 hitsOnLayer[1]->wire()->localId()){
01355 unsigned maxLocalId = findMaxLocalId(hitsOnLayer[0]->wire()->layerId());
01356 unsigned R = isIsolation(hitsOnLayer[0]->wire()->localId(),
01357 maxLocalId,
01358 hitsOnLayer[0]->wire()->layerId(),1,allStereoList);
01359 unsigned L = isIsolation(hitsOnLayer[1]->wire()->localId(),
01360 maxLocalId,
01361 hitsOnLayer[1]->wire()->layerId(),-1,allStereoList);
01362 if(R == 1 && L == 1){
01363 hitsOnLayer[0]->leftRight(1);
01364 hitsOnLayer[0]->position(hitsOnLayer[0]->arcZ(1));
01365 hitsOnLayer[1]->leftRight(0);
01366 hitsOnLayer[1]->position(hitsOnLayer[1]->arcZ(0));
01367 twoOnLayer.append(hitsOnLayer[0]);
01368 twoOnLayer.append(hitsOnLayer[1]);
01369 }
01370 }
01371 }
01372 if(hitsOnLayer.length() == 3){
01373 if(hitsOnLayer[0]->wire()->localIdForPlus()+1 ==
01374 hitsOnLayer[1]->wire()->localId() &&
01375 hitsOnLayer[1]->wire()->localIdForPlus()+1 !=
01376 hitsOnLayer[2]->wire()->localId()){
01377 unsigned maxLocalId = findMaxLocalId(hitsOnLayer[0]->wire()->layerId());
01378 unsigned R = isIsolation(hitsOnLayer[0]->wire()->localId(),
01379 maxLocalId,
01380 hitsOnLayer[0]->wire()->layerId(),1,allStereoList);
01381 unsigned L = isIsolation(hitsOnLayer[1]->wire()->localId(),
01382 maxLocalId,
01383 hitsOnLayer[1]->wire()->layerId(),-1,allStereoList);
01384 if(R == 1 && L == 1){
01385 hitsOnLayer[0]->leftRight(1);
01386 hitsOnLayer[0]->position(hitsOnLayer[0]->arcZ(1));
01387 hitsOnLayer[1]->leftRight(0);
01388 hitsOnLayer[1]->position(hitsOnLayer[1]->arcZ(0));
01389 twoOnLayer.append(hitsOnLayer[0]);
01390 twoOnLayer.append(hitsOnLayer[1]);
01391 }
01392 }else if(hitsOnLayer[0]->wire()->localIdForPlus()+1 !=
01393 hitsOnLayer[1]->wire()->localId() &&
01394 hitsOnLayer[1]->wire()->localIdForPlus()+1 ==
01395 hitsOnLayer[2]->wire()->localId()){
01396 unsigned maxLocalId = findMaxLocalId(hitsOnLayer[1]->wire()->layerId());
01397 unsigned R = isIsolation(hitsOnLayer[1]->wire()->localId(),
01398 maxLocalId,
01399 hitsOnLayer[1]->wire()->layerId(),1,allStereoList);
01400 unsigned L = isIsolation(hitsOnLayer[2]->wire()->localId(),
01401 maxLocalId,
01402 hitsOnLayer[2]->wire()->layerId(),-1,allStereoList);
01403 if(R == 1 && L == 1){
01404 hitsOnLayer[1]->leftRight(1);
01405 hitsOnLayer[1]->position(hitsOnLayer[1]->arcZ(1));
01406 hitsOnLayer[2]->leftRight(0);
01407 hitsOnLayer[2]->position(hitsOnLayer[2]->arcZ(0));
01408 twoOnLayer.append(hitsOnLayer[1]);
01409 twoOnLayer.append(hitsOnLayer[2]);
01410 }
01411 }
01412 }
01413
01414
01415
01416 }
01417
01418 void
01419 setLR(AList<TMLink> &hitsOnLayer, unsigned LR = 0){
01420
01421
01422 for(unsigned i=0;i<hitsOnLayer.length();++i){
01423 if(LR == 0){
01424 hitsOnLayer[i]->leftRight(0);
01425 hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(0));
01426 }else{
01427 hitsOnLayer[i]->leftRight(1);
01428 hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(1));
01429 }
01430 }
01431 }
01432
01433 bool
01434 moveLR(AList<TMLink> &hitsOnLayer){
01435 unsigned nHits = hitsOnLayer.length();
01436 if(nHits == 0)return false;
01437
01438 if(hitsOnLayer[nHits-1]->leftRight() == 1)return false;
01439 for(unsigned i=0;i<nHits;++i){
01440 if(hitsOnLayer[i]->leftRight() == 0){
01441 hitsOnLayer[i]->leftRight(1);
01442 hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(1));
01443 return true;
01444 }
01445 }
01446 return false;
01447 }
01448
01449 void
01450 selectGoodWires(const AList<TMLink> &allWires,
01451 AList<TMLink> &goodWires){
01452 goodWires.removeAll();
01453 for(int i=0;i<allWires.length();++i){
01454 if(allWires[i]->position().x() != -999.){
01455 goodWires.append(allWires[i]);
01456 }
01457 }
01458 }
01459
01460 void
01461 TBuilderCurl::fitLine2(const AList<TMLink> &tmpLine, double &min_chi2,
01462 double &good_a, double &good_b,
01463 AList<TMLink> &goodLine, AList<HepPoint3D> &goodPosition,
01464 int &overCounter) const {
01465 AList<TMLink> goodWires;
01466 selectGoodWires(tmpLine,goodWires);
01467 if(goodWires.length() >= 3)
01468 fitLine(goodWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01469 }
01470
01471 void
01472 calVirtualCircle(const TMLink &hit, const TTrack &track, const int LR,
01473 HepPoint3D ¢er, double &radius){
01474 if(abs(LR) != 1)return;
01475 double Q = track.charge();
01476 int isOuter = 1;
01477 if(Q > 0. && LR == 1)isOuter = -1;
01478 else if(Q < 0. && LR == -1)isOuter = -1;
01479 radius = fabs(track.radius());
01480 center = track.helix().center();
01481 HepPoint3D wire = hit.wire()->xyPosition();
01482 center.setZ(0.);
01483 wire.setZ(0.);
01484
01485 center = wire +
01486 (radius+((double)isOuter)*(hit.hit()->drift()))*(center-wire).unit();
01487 }
01488
01489 void
01490 moveLR(AList<TMLink> &hits,
01491 const AList<TMLink> &hitsOnLayerOrg,
01492 const TTrack &track){
01493 AList<TMLink> hitsOnLayer = hitsOnLayerOrg;
01494 hitsOnLayer.remove(hits);
01495 if(hitsOnLayer.length() == 0)return;
01496
01497 unsigned nHits = hits.length();
01498 if(nHits == 0)return;
01499
01500
01501
01502 int LR = -1;
01503 TMLink ref;
01504 if(hits[nHits-1]->leftRight() == 1){
01505 LR = 1;
01506 ref = *hits[nHits-1];
01507 }
01508 for(unsigned i=0;i<nHits;++i){
01509 if(hits[i]->leftRight() == 0){
01510 ref = *hits[i];
01511 break;
01512 }
01513 }
01514
01515 HepPoint3D center;
01516 double radius;
01517 calVirtualCircle(ref,track,LR,center,radius);
01518
01519 double Q = track.charge();
01520 for(int i=0;i<hitsOnLayer.length();++i){
01521 int isOuter = 1;
01522 if((hitsOnLayer[i]->wire()->xyPosition()-center).mag()-radius < 0.)isOuter = -1;
01523 if(Q > 0. && isOuter == 1){
01524 hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(0));
01525 hitsOnLayer[i]->leftRight(0);
01526 }else if(Q > 0. && isOuter == -1){
01527 hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(1));
01528 hitsOnLayer[i]->leftRight(1);
01529 }else if(Q < 0. && isOuter == 1){
01530 hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(1));
01531 hitsOnLayer[i]->leftRight(1);
01532 }else if(Q < 0. && isOuter == -1){
01533 hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(0));
01534 hitsOnLayer[i]->leftRight(0);
01535 }
01536 }
01537 }
01538
01539 void
01540 TBuilderCurl::makeLine(TTrack &track,
01541 AList<TMLink> &list, const AList<TMLink> &allStereoList, AList<TMLink> &goodLine,
01542 double &min_chi2, double &good_a, double &good_b,
01543 AList<HepPoint3D> &goodPosition) const {
01544 if(list.length() == 0)return;
01545
01546 AList<TMLink> layer[24];
01547 AList<TMLink> layerOrg[24];
01548 for(unsigned i = 0, size = list.length(); i < size; ++i){
01549 layer[list[i]->wire()->layer()->axialStereoLayerId()].append(*list[i]);
01550 layerOrg[list[i]->wire()->layer()->axialStereoLayerId()].append(*list[i]);
01551 }
01552
01553 AList<TMLink> fixedWires[6];
01554 AList<TMLink> nonFixedWires[6];
01555 AList<TMLink> allFixedWires;
01556 for(unsigned i=0;i<24;++i){
01557 if(layer[i].length()){
01558 layer[i].sort(SortByWireId);
01559 sortByLocalId(layer[i]);
01560 AList<TMLink> tmp;
01561 findTwoHits(tmp,layer[i],allStereoList);
01562 if(tmp.length()){
01563 layer[i].removeAll();
01564 allFixedWires.append(tmp);
01565
01566 if(i<4)fixedWires[0].append(tmp);
01567 else if(i<8)fixedWires[1].append(tmp);
01568 else if(i<12)fixedWires[2].append(tmp);
01569 else if(i<16)fixedWires[3].append(tmp);
01570 else if(i<20)fixedWires[4].append(tmp);
01571 else fixedWires[5].append(tmp);
01572 }else{
01573 if(i<4)nonFixedWires[0].append(layer[i]);
01574 else if(i<8)nonFixedWires[1].append(layer[i]);
01575 else if(i<12)nonFixedWires[2].append(layer[i]);
01576 else if(i<16)nonFixedWires[3].append(layer[i]);
01577 else if(i<20)nonFixedWires[4].append(layer[i]);
01578 else nonFixedWires[5].append(layer[i]);
01579 }
01580 }
01581 }
01582
01583 #if DEBUG_CURL_DUMP
01584 std::cout << "(TBuilderCurl) 1st fixed & non-fixed wires selection:" << std::endl;
01585 std::cout << "(TBuilderCurl) all fixed wires # = " << allFixedWires.length() << std::endl;
01586 std::cout << "(TBuilderCurl) fixed wires # = ("
01587 << fixedWires[0].length() << ", "
01588 << fixedWires[1].length() << ", "
01589 << fixedWires[2].length() << ", "
01590 << fixedWires[3].length() << ", "
01591 << fixedWires[4].length() << ", "
01592 << fixedWires[5].length() << ")" << std::endl;
01593 std::cout << "(TBuilderCurl) non fixed wires # = ("
01594 << nonFixedWires[0].length() << ", "
01595 << nonFixedWires[1].length() << ", "
01596 << nonFixedWires[2].length() << ", "
01597 << nonFixedWires[3].length() << ", "
01598 << nonFixedWires[4].length() << ", "
01599 << nonFixedWires[5].length() << ")" << std::endl;
01600 #if 0
01601 for(unsigned i=0;i<allFixedWires.length();++i)
01602 std::cout << i << ": LocalID/LayerID = " << allFixedWires[i]->wire()->localId()
01603 << "/" << allFixedWires[i]->wire()->layerId()
01604 << ", LR = " << allFixedWires[i]->leftRight() << std::endl;
01605 #endif
01606 #endif
01607
01608 int createdLine = 0;
01609 int overCounter = 0;
01610 AList<TMLink> goodWires;
01611 #if 1
01612 if(allFixedWires.length() >= 5){
01613 selectGoodWires(allFixedWires,goodWires);
01614 if(goodWires.length() >= 5){
01615 fitLine(goodWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01616 if(fabs(good_b) < 10.)createdLine = 1;
01617 }
01618 }
01619 #endif
01620 #if 1
01621 if(createdLine == 0){
01622
01623
01624 double Q = track.charge();
01625 unsigned isIncreased = 0;
01626 for(int sl=0;sl<6;++sl){
01627 if(fixedWires[sl].length() >= 1 &&
01628 nonFixedWires[sl].length() >= 1){
01629 isIncreased = 1;
01630 unsigned bestNCorrectLR = 0;
01631 double bestR;
01632 HepPoint3D bestC;
01633 for(int i=0;i<fixedWires[sl].length();++i){
01634 int LR = fixedWires[sl][i]->leftRight() == 0 ? -1 : 1;
01635 HepPoint3D center;
01636 double radius;
01637 calVirtualCircle(*fixedWires[sl][i],track,LR,center,radius);
01638 unsigned nCorrectLR = 0;
01639 for(int j=0;j<fixedWires[sl].length();++j){
01640 if(i != j){
01641 int tmpIsOuter = 1;
01642 if((fixedWires[sl][j]->wire()->xyPosition()-center).mag()-radius < 0.)tmpIsOuter = -1;
01643 if(Q > 0. && tmpIsOuter == 1 && fixedWires[sl][j]->leftRight() == 0)++nCorrectLR;
01644 else if(Q > 0. && tmpIsOuter == -1 && fixedWires[sl][j]->leftRight() == 1)++nCorrectLR;
01645 else if(Q < 0. && tmpIsOuter == 1 && fixedWires[sl][j]->leftRight() == 1)++nCorrectLR;
01646 else if(Q < 0. && tmpIsOuter == -1 && fixedWires[sl][j]->leftRight() == 0)++nCorrectLR;
01647 }
01648 }
01649 if(i == 0 || nCorrectLR > bestNCorrectLR){
01650 bestNCorrectLR = nCorrectLR;
01651 bestR = radius;
01652 bestC = center;
01653 }
01654 if(bestNCorrectLR == fixedWires[sl].length()-1)break;
01655 }
01656 for(int i=0;i<nonFixedWires[sl].length();++i){
01657 int isOuter = 1;
01658 if((nonFixedWires[sl][i]->wire()->xyPosition()-bestC).mag()-bestR < 0.)isOuter = -1;
01659 if(Q > 0. && isOuter == 1){
01660 nonFixedWires[sl][i]->position(nonFixedWires[sl][i]->arcZ(0));
01661 nonFixedWires[sl][i]->leftRight(0);
01662 }else if(Q > 0. && isOuter == -1){
01663 nonFixedWires[sl][i]->position(nonFixedWires[sl][i]->arcZ(1));
01664 nonFixedWires[sl][i]->leftRight(1);
01665 }else if(Q < 0. && isOuter == 1){
01666 nonFixedWires[sl][i]->position(nonFixedWires[sl][i]->arcZ(1));
01667 nonFixedWires[sl][i]->leftRight(1);
01668 }else if(Q < 0. && isOuter == -1){
01669 nonFixedWires[sl][i]->position(nonFixedWires[sl][i]->arcZ(0));
01670 nonFixedWires[sl][i]->leftRight(0);
01671 }
01672 }
01673 allFixedWires.append(nonFixedWires[sl]);
01674 fixedWires[sl].append(nonFixedWires[sl]);
01675 nonFixedWires[sl].removeAll();
01676 }
01677 }
01678
01679 #if DEBUG_CURL_DUMP
01680 std::cout << "(TBuilderCurl) 2nd fixed & non-fixed wires selection:" << std::endl;
01681 std::cout << "(TBuilderCurl) all fixed wires # = " << allFixedWires.length() << std::endl;
01682 std::cout << "(TBuilderCurl) fixed wires # = ("
01683 << fixedWires[0].length() << ", "
01684 << fixedWires[1].length() << ", "
01685 << fixedWires[2].length() << ", "
01686 << fixedWires[3].length() << ", "
01687 << fixedWires[4].length() << ", "
01688 << fixedWires[5].length() << ")" << std::endl;
01689 std::cout << "(TBuilderCurl) non fixed wires # = ("
01690 << nonFixedWires[0].length() << ", "
01691 << nonFixedWires[1].length() << ", "
01692 << nonFixedWires[2].length() << ", "
01693 << nonFixedWires[3].length() << ", "
01694 << nonFixedWires[4].length() << ", "
01695 << nonFixedWires[5].length() << ")" << std::endl;
01696 #if 0
01697 for(unsigned i=0;i<allFixedWires.length();++i)
01698 std::cout << i << ": LocalID/LayerID = " << allFixedWires[i]->wire()->localId()
01699 << "/" << allFixedWires[i]->wire()->layerId()
01700 << ", LR = " << allFixedWires[i]->leftRight() << std::endl;
01701 #endif
01702 #endif
01703
01704 if(isIncreased == 1 && allFixedWires.length() >= 5){
01705 selectGoodWires(allFixedWires,goodWires);
01706 if(goodWires.length() >= 5){
01707 fitLine(goodWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01708 if(fabs(good_b) < 10.)createdLine = 1;
01709 }
01710 }
01711 }
01712 #endif
01713 #if 1
01714
01715 if(createdLine == 0){
01716
01717 int maxNonFixedLayerIndex[6] = { -1, -1, -1, -1, -1, -1 };
01718 int maxLength[6] = { 0, 0, 0, 0, 0, 0 };
01719 for(int l=0;l<24;++l){
01720 unsigned sl = 5;
01721 if(l<4)sl = 0;
01722 else if(l<8)sl = 1;
01723 else if(l<12)sl = 2;
01724 else if(l<16)sl = 3;
01725 else if(l<20)sl = 4;
01726 layer[l].remove(fixedWires[sl]);
01727 setLR(layer[l]);
01728 if(layer[l].length() && layer[l].length() > maxLength[sl]){
01729 maxLength[sl] = layer[l].length();
01730 maxNonFixedLayerIndex[sl] = l;
01731 }
01732 }
01733
01734 unsigned index = 0;
01735 unsigned nonFixedSuperLayerIndex[6] = { 0,0,0,0,0,0 };
01736 unsigned isIncreased = 0;
01737 for(unsigned i=0;i<6;++i){
01738 allFixedWires.append(nonFixedWires[i]);
01739 if(nonFixedWires[i].length()){
01740 isIncreased = 1;
01741 nonFixedSuperLayerIndex[index] = i;
01742 ++index;
01743 }
01744 }
01745
01746 if(isIncreased){
01747 do{
01748 moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[0]]],
01749 nonFixedWires[nonFixedSuperLayerIndex[0]],
01750 track);
01751 if(index > 1){
01752 setLR(nonFixedWires[nonFixedSuperLayerIndex[1]]);
01753 do{
01754 moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[1]]],
01755 nonFixedWires[nonFixedSuperLayerIndex[1]],
01756 track);
01757 if(index > 2){
01758 setLR(nonFixedWires[nonFixedSuperLayerIndex[2]]);
01759 do{
01760 moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[2]]],
01761 nonFixedWires[nonFixedSuperLayerIndex[2]],
01762 track);
01763 if(index > 3){
01764 setLR(nonFixedWires[nonFixedSuperLayerIndex[3]]);
01765 do{
01766 moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[3]]],
01767 nonFixedWires[nonFixedSuperLayerIndex[3]],
01768 track);
01769 if(index > 4){
01770 setLR(nonFixedWires[nonFixedSuperLayerIndex[4]]);
01771 do{
01772 moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[4]]],
01773 nonFixedWires[nonFixedSuperLayerIndex[4]],
01774 track);
01775 if(index > 5){
01776 setLR(nonFixedWires[nonFixedSuperLayerIndex[5]]);
01777 do{
01778 moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[5]]],
01779 nonFixedWires[nonFixedSuperLayerIndex[5]],
01780 track);
01781 fitLine2(allFixedWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01782 if(overCounter>10000)goto kokohe;
01783 }while(moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[5]]]));
01784 }else{
01785 fitLine2(allFixedWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01786 if(overCounter>10000)goto kokohe;
01787 }
01788 }while(moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[4]]]));
01789 }else{
01790 fitLine2(allFixedWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01791 if(overCounter>10000)goto kokohe;
01792 }
01793 }while(moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[3]]]));
01794 }else{
01795 fitLine2(allFixedWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01796 if(overCounter>10000)goto kokohe;
01797 }
01798 }while(moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[2]]]));
01799 }else{
01800 fitLine2(allFixedWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01801 if(overCounter>10000)goto kokohe;
01802 }
01803 }while(moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[1]]]));
01804 }else{
01805 fitLine2(allFixedWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01806 if(overCounter>10000)goto kokohe;
01807 }
01808 }while(moveLR(layer[maxNonFixedLayerIndex[nonFixedSuperLayerIndex[0]]]));
01809 kokohe:;
01810 }else if(allFixedWires.length() >= 3){
01811 fitLine2(allFixedWires, min_chi2, good_a, good_b, goodLine, goodPosition, overCounter);
01812 }
01813 }
01814 #endif
01815 for(unsigned i = 0, size = goodLine.length(); i < size; ++i){
01816 goodLine[i]->position(*(goodPosition[i]));
01817 }
01818 #if DEBUG_CURL_DUMP
01819 std::cout << "(TBuilderCurl) make a line from All SuperLayers." << std::endl;
01820 plotArcZ(goodLine, good_a, good_b, 0);
01821 #endif
01822 }
01823
01824 bool
01825 TBuilderCurl::fitWDD(double &xc, double &yc, double &r,
01826 AList<TMLink> &list) const {
01827 if(list.length() <= 3)return false;
01828 Lpav circle;
01829
01830 for(int i=0;i<list.length();++i){
01831 circle.add_point(list[i]->wire()->xyPosition().x(),
01832 list[i]->wire()->xyPosition().y(),1.0);
01833 }
01834 circle.add_point(0.,0.,1.0);
01835 if (circle.fit() < 0.0 || circle.kappa() == 0.0) return false;
01836 xc = circle.center()[0];
01837 yc = circle.center()[1];
01838 r = circle.radius();
01839 const int maxIte = 2;
01840 for(int ite=0;ite<maxIte;++ite){
01841 Lpav circle2;
01842 circle2.clear();
01843
01844 for(int i=0;i<list.length();++i){
01845 double R = sqrt((list[i]->wire()->xyPosition().x()-xc)*(list[i]->wire()->xyPosition().x()-xc)+
01846 (list[i]->wire()->xyPosition().y()-yc)*(list[i]->wire()->xyPosition().y()-yc));
01847 if(R == 0.)continue;
01848 double U = 1./R;
01849 double dir = R > r ? -1. : 1.;
01850 double X = xc+(list[i]->wire()->xyPosition().x()-xc)*U*(R+dir*list[i]->hit()->drift());
01851 double Y = yc+(list[i]->wire()->xyPosition().y()-yc)*U*(R+dir*list[i]->hit()->drift());
01852 circle2.add_point(X,Y,1.0);
01853 }
01854 circle2.add_point(0.,0.,1.0);
01855 if (circle2.fit() < 0.0 || circle2.kappa() == 0.0) return false;
01856 xc = circle2.center()[0];
01857 yc = circle2.center()[1];
01858 r = circle2.radius();
01859
01860 }
01861 return true;
01862 }
01863
01864 int
01865 TBuilderCurl::stereoHit(double &xc, double &yc, double &r, double &q,
01866 AList<TMLink> & list) const
01867 {
01868 if(list.length() == 0)return -1;
01869
01870 HepPoint3D center(xc, yc, 0.);
01871 HepPoint3D tmp(-999., -999., 0.);
01872 for(unsigned i = 0, size = list.length(); i < size; ++i){
01873 TMDCWireHit &h = *const_cast<TMDCWireHit*>(list[i]->hit());
01874 HepVector3D X = 0.5*(h.wire()->forwardPosition() +
01875 h.wire()->backwardPosition());
01876 HepVector3D x = HepVector3D(X.x(), X.y(), 0.);
01877 HepVector3D w = x - center;
01878 HepVector3D V = h.wire()->direction();
01879 HepVector3D v = HepVector3D(V.x(), V.y(), 0.);
01880 double vmag2 = v.mag2();
01881 double vmag = sqrt(vmag2);
01882
01883 for(unsigned j = 0; j < 4; ++j)
01884 list[i]->arcZ(tmp,j);
01885
01886
01887 if (vmag == 0.) continue;
01888
01889 double drift = h.drift(WireHitLeft);
01890 double R[2] = {r + drift, r - drift};
01891 double wv = w.dot(v);
01892 double d2[2];
01893 d2[0] = vmag2*R[0]*R[0] + (wv*wv - vmag2*w.mag2());
01894 d2[1] = vmag2*R[1]*R[1] + (wv*wv - vmag2*w.mag2());
01895
01896 if (d2[0] < 0. && d2[1] < 0.) continue;
01897
01898 bool ok_inner(true);
01899 bool ok_outer(true);
01900 double d[2] = {-1., -1.};
01901
01902 if(d2[0] >= 0.){
01903 d[0] = sqrt(d2[0]);
01904 }else{
01905 ok_outer = false;
01906 }
01907 if(d2[1] >= 0.){
01908 d[1] = sqrt(d2[1]);
01909 }else{
01910 ok_inner = false;
01911 }
01912
01913
01914 double l[2][2];
01915 double z[2][2];
01916
01917 if(ok_outer){
01918 l[0][0] = (- wv + d[0]) / vmag2;
01919 l[1][0] = (- wv - d[0]) / vmag2;
01920 z[0][0] = X.z() + l[0][0]*V.z();
01921 z[1][0] = X.z() + l[1][0]*V.z();
01922 }
01923
01924 if(ok_inner){
01925 l[0][1] = (- wv + d[1]) / vmag2;
01926 l[1][1] = (- wv - d[1]) / vmag2;
01927 z[0][1] = X.z() + l[0][1]*V.z();
01928 z[1][1] = X.z() + l[1][1]*V.z();
01929 }
01930
01931
01932 HepVector3D p[2][2];
01933 if(ok_outer){
01934 p[0][0] = x + l[0][0] * v;
01935 p[1][0] = x + l[1][0] * v;
01936 HepVector3D tmp_pc = p[0][0] - center;
01937 HepVector3D pc0 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01938 p[0][0] -= drift/pc0.mag()*pc0;
01939 tmp_pc = p[1][0] - center;
01940 HepVector3D pc1 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01941 p[1][0] -= drift/pc1.mag()*pc1;
01942 }
01943 if(ok_inner){
01944 p[0][1] = x + l[0][1] * v;
01945 p[1][1] = x + l[1][1] * v;
01946 HepVector3D tmp_pc = p[0][1] - center;
01947 HepVector3D pc0 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01948 p[0][1] += drift/pc0.mag()*pc0;
01949 tmp_pc = p[1][1] - center;
01950 HepVector3D pc1 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01951 p[1][1] += drift/pc1.mag()*pc1;
01952 }
01953
01954
01955 bool ok_xy[2][2];
01956 if(ok_outer){
01957 ok_xy[0][0] = true;
01958 ok_xy[1][0] = true;
01959 }else{
01960 ok_xy[0][0] = false;
01961 ok_xy[1][0] = false;
01962 }
01963 if(ok_inner){
01964 ok_xy[0][1] = true;
01965 ok_xy[1][1] = true;
01966 }else{
01967 ok_xy[0][1] = false;
01968 ok_xy[1][1] = false;
01969 }
01970 if(ok_outer){
01971 if (q * (center.x() * p[0][0].y() - center.y() * p[0][0].x()) < 0.)
01972 ok_xy[0][0] = false;
01973 if (q * (center.x() * p[1][0].y() - center.y() * p[1][0].x()) < 0.)
01974 ok_xy[1][0] = false;
01975 }
01976 if(ok_inner){
01977 if (q * (center.x() * p[0][1].y() - center.y() * p[0][1].x()) < 0.)
01978 ok_xy[0][1] = false;
01979 if (q * (center.x() * p[1][1].y() - center.y() * p[1][1].x()) < 0.)
01980 ok_xy[1][1] = false;
01981 }
01982 if(!ok_inner && ok_outer && (!ok_xy[0][0]) && (!ok_xy[1][0])){
01983 continue;
01984 }
01985 if(ok_inner && !ok_outer && (!ok_xy[0][1]) && (!ok_xy[1][1])){
01986 continue;
01987 }
01988
01989
01990
01991 if(ok_xy[0][0]){
01992 if (z[0][0] < h.wire()->backwardPosition().z() ||
01993 z[0][0] > h.wire()->forwardPosition().z()) ok_xy[0][0] = false;
01994 }
01995 if(ok_xy[1][0]){
01996 if (z[1][0] < h.wire()->backwardPosition().z() ||
01997 z[1][0] > h.wire()->forwardPosition().z()) ok_xy[1][0] = false;
01998 }
01999 if(ok_xy[0][1]){
02000 if (z[0][1] < h.wire()->backwardPosition().z() ||
02001 z[0][1] > h.wire()->forwardPosition().z()) ok_xy[0][1] = false;
02002 }
02003 if(ok_xy[1][1]){
02004 if (z[1][1] < h.wire()->backwardPosition().z() ||
02005 z[1][1] > h.wire()->forwardPosition().z()) ok_xy[1][1] = false;
02006 }
02007 if ((!ok_xy[0][0]) && (!ok_xy[1][0]) &&
02008 (!ok_xy[0][1]) && (!ok_xy[1][1])){
02009 continue;
02010 }
02011
02012 double cosdPhi, dPhi;
02013
02014 unsigned indexL = 0;
02015 unsigned indexR = 0;
02016
02017
02018
02019 if(ok_xy[0][0]){
02020
02021 cosdPhi = - center.dot((p[0][0] - center).unit()) / center.mag();
02022 if(fabs(cosdPhi) < 1.0){
02023 dPhi = acos(cosdPhi);
02024 }else if(cosdPhi >= 1.0){
02025 dPhi = 0.;
02026 }else{
02027 dPhi = M_PI;
02028 }
02029
02030
02031
02032 if(q > 0){
02033
02034 if(indexL == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[0][0], 0.), 0);
02035 else list[i]->arcZ(HepPoint3D(r*dPhi, z[0][0], 0.), 2);
02036 ++indexL;
02037 }else{
02038
02039 if(indexR == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[0][0], 0.), 1);
02040 else list[i]->arcZ(HepPoint3D(r*dPhi, z[0][0], 0.), 3);
02041 ++indexR;
02042 }
02043 }
02044 if(ok_xy[1][0]){
02045
02046 cosdPhi = - center.dot((p[1][0] - center).unit()) / center.mag();
02047 if(fabs(cosdPhi) < 1.0){
02048 dPhi = acos(cosdPhi);
02049 }else if(cosdPhi >= 1.0){
02050 dPhi = 0.;
02051 }else{
02052 dPhi = M_PI;
02053 }
02054
02055
02056
02057 if(q > 0){
02058
02059 if(indexL == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[1][0], 0.), 0);
02060 else list[i]->arcZ(HepPoint3D(r*dPhi, z[1][0], 0.), 2);
02061 ++indexL;
02062 }else{
02063
02064 if(indexR == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[1][0], 0.), 1);
02065 else list[i]->arcZ(HepPoint3D(r*dPhi, z[1][0], 0.), 3);
02066 ++indexR;
02067 }
02068 }
02069 if(ok_xy[0][1]){
02070
02071 cosdPhi = - center.dot((p[0][1] - center).unit()) / center.mag();
02072 if(fabs(cosdPhi) < 1.0){
02073 dPhi = acos(cosdPhi);
02074 }else if(cosdPhi >= 1.0){
02075 dPhi = 0.;
02076 }else{
02077 dPhi = M_PI;
02078 }
02079
02080
02081
02082 if(q > 0){
02083
02084 if(indexR == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[0][1], 0.), 1);
02085 else list[i]->arcZ(HepPoint3D(r*dPhi, z[0][1], 0.), 3);
02086 ++indexR;
02087 }else{
02088
02089 if(indexL == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[0][1], 0.), 0);
02090 else list[i]->arcZ(HepPoint3D(r*dPhi, z[0][1], 0.), 2);
02091 ++indexL;
02092 }
02093 }
02094 if(ok_xy[1][1]){
02095
02096 cosdPhi = - center.dot((p[1][1] - center).unit()) / center.mag();
02097 if(fabs(cosdPhi) < 1.0){
02098 dPhi = acos(cosdPhi);
02099 }else if(cosdPhi >= 1.0){
02100 dPhi = 0.;
02101 }else{
02102 dPhi = M_PI;
02103 }
02104
02105
02106
02107 if(q > 0){
02108
02109 if(indexR == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[1][1], 0.), 1);
02110 else list[i]->arcZ(HepPoint3D(r*dPhi, z[1][1], 0.), 3);
02111 ++indexR;
02112 }else{
02113
02114 if(indexL == 0)list[i]->arcZ(HepPoint3D(r*dPhi, z[1][1], 0.), 0);
02115 else list[i]->arcZ(HepPoint3D(r*dPhi, z[1][1], 0.), 2);
02116 ++indexL;
02117 }
02118 }
02119 }
02120 return 0;
02121 }
02122
02123 void
02124 TBuilderCurl::setArcZ(TTrack &track, AList<TMLink> &slayer,
02125 AList<TMLink> &alayer0,AList<TMLink> &alayer1,
02126 unsigned ip) const {
02127 AList<TMLink> tmp = alayer0;
02128 tmp.append(alayer1);
02129 double xc,yc,r;
02130 if(fitWDD(xc,yc,r,tmp)){
02131 double q = track.charge();
02132 stereoHit(xc,yc,r,q,slayer);
02133 }
02134 }
02135
02136 void
02137 TBuilderCurl::setArcZ(TTrack &track, AList<TMLink> &slayer,
02138 AList<TMLink> &alayer0,AList<TMLink> &alayer1,
02139 AList<TMLink> &alayer2,
02140 unsigned ip) const {
02141 AList<TMLink> tmp = alayer0;
02142 tmp.append(alayer1);
02143 tmp.append(alayer2);
02144 double xc,yc,r;
02145 if(fitWDD(xc,yc,r,tmp)){
02146 double q = track.charge();
02147 stereoHit(xc,yc,r,q,slayer);
02148 }
02149 }
02150
02151 void
02152 TBuilderCurl::setArcZ(TTrack &track, AList<TMLink> &slayer,
02153 AList<TMLink> &alayer0,AList<TMLink> &alayer1,
02154 AList<TMLink> &alayer2,AList<TMLink> &alayer3,
02155 unsigned ip) const {
02156 AList<TMLink> tmp = alayer0;
02157 tmp.append(alayer1);
02158 tmp.append(alayer2);
02159 tmp.append(alayer3);
02160 double xc,yc,r;
02161 if(fitWDD(xc,yc,r,tmp)){
02162 double q = track.charge();
02163 stereoHit(xc,yc,r,q,slayer);
02164 }
02165 }
02166
02167 void
02168 TBuilderCurl::setArcZ(TTrack &track, AList<TMLink> &slayer,
02169 AList<TMLink> &alayer0,AList<TMLink> &alayer1,
02170 AList<TMLink> &alayer2,AList<TMLink> &alayer3,
02171 AList<TMLink> &alayer4,
02172 unsigned ip) const {
02173 AList<TMLink> tmp = alayer0;
02174 tmp.append(alayer1);
02175 tmp.append(alayer2);
02176 tmp.append(alayer3);
02177 tmp.append(alayer4);
02178 double xc,yc,r;
02179 if(fitWDD(xc,yc,r,tmp)){
02180 double q = track.charge();
02181 stereoHit(xc,yc,r,q,slayer);
02182 }
02183 }
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204 #undef DEBUG_CURL_DUMP
02205 #undef DEBUG_CURL_GNUPLOT
02206 #undef DEBUG_CURL_MC
02207
02208