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

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 // $Id: TBuilderCurl.cxx,v 1.21 2012/05/28 05:16:29 maoh Exp $
00003 //-----------------------------------------------------------------------------
00004 // Filename : TBuilderCurl.cc
00005 // Section  : Tracking
00006 // Owner    : Yoshi Iwasaki
00007 // Email    : yoshihito.iwasaki@kek.jp
00008 //-----------------------------------------------------------------------------
00009 // Description : A class to build a curl track.
00010 //               See http://bsunsrv1.kek.jp/~yiwasaki/tracking/
00011 //-----------------------------------------------------------------------------
00012 
00013 //#ifdef TRKRECO_DEBUG_DETAIL
00014 //#define TRKRECO_DEBUG
00015 //#endif
00016 #include "TrkReco/TBuilderCurl.h"
00017 #include "TrkReco/TMLink.h"
00018 #include "TrkReco/TTrack.h"
00019 #include "TrackUtil/Lpav.h"
00020 //#include "TrkReco/Lpav.h"
00021 //#include "TrkReco/TSvdFinder.h"
00022 //#include "TrkReco/TSvdHit.h"
00023 
00024 #include "TrkReco/TMLine.h"
00025 #include "TrkReco/TRobustLineFitter.h"
00026 
00027 // Following 3 parameters : (0,0,0) is best!
00028 // Other cases are for the development.
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 //#include MDC_H
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 //#include "tables/belletdf.h"
00055 //#include "tables/bestdf.h"
00056 static int debugMcFlag = 1;
00057 #endif
00058 
00059 TBuilderCurl::TBuilderCurl(const std::string & name)
00060 : TBuilder0(name),
00061   _fitter("TBuilderCurl Fitter"){
00062  
00063   //jialk
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 //  if(m_param.ON_CORRECTION){
00071 //    _fitter.sag(true);
00072 //    _fitter.propagation(true);
00073 //    _fitter.tof(true);
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   //  if(m_param.SVD_RECONSTRUCTION){
00083   //    delete m_svdFinder;
00084   //    delete m_svdAssociator;
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 //  if(m_param.ON_CORRECTION){
00102 //    _fitter.sag(true);
00103 //    _fitter.propagation(true);
00104 //    _fitter.tof(true);
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   //  if(m_param.SVD_RECONSTRUCTION){
00113   //m_svdAssociator = new TSvdAssociator(-1.*(m_param.MIN_SVD_ELECTRONS),
00114   //                                     m_param.MIN_SVD_ELECTRONS);
00115   //}
00116 }
00117 
00118 // Stereo Finder For Curl Tracks : by jtanaka == from here ==
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 //...............Main Part.....................
00131 //.............................................
00132 
00133 bool
00134 TBuilderCurl::buildStereo(TTrack & track,
00135                           double &dZ,
00136                           double &tanL) const {
00137 /*  
00138  if(!(m_param.SVD_RECONSTRUCTION))return false;
00139 
00140 #if 0
00141   double q = 1.;
00142   if(track.helix().kappa()<0.)q = -1.;
00143   double h[5], chisq;
00144   if(m_svdFinder->recTrk(track.helix().center().x(),
00145                          track.helix().center().y(),
00146                          fabs(track.helix().radius()),
00147                          q,
00148                          0.2,
00149                          h[0], h[1], h[2], h[3], h[4], chisq)){
00150 #if 0
00151     std::cout << "SVD = "
00152          << h[0] << " "
00153          << h[1] << " "
00154          << h[2] << " "
00155          << h[3] << " "
00156          << h[4];
00157     std::cout << ", chi2 = " << chisq << " pt=" << 1./h[2] << std::endl;
00158 #endif
00159     dZ   = h[3];
00160     tanL = h[4];
00161     return true;
00162   }else{
00163     //std::cout << "SVD Fail....." << std::endl;
00164     return false;
00165   }
00166 #else
00167   Helix th(track.helix());
00168   th.pivot(HepPoint3D(0.,0.,0.));
00169   AList<TSvdHit> cand;
00170   if(m_svdAssociator->recTrk(th,dZ,tanL,0.5,-1.0,cand,0.5)){
00171     //std::cout << "SVD " << dZ << " " << tanL << std::endl;
00172     return true;
00173   }else{
00174     //std::cout << "SVD..." << std::endl;
00175     return false;
00176   }
00177 #endif
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;// not MC
00196 #endif
00197 
00198   AList<TMLink> list = stereoList;
00199   unsigned nList = list.length();
00200 
00201   //...gets stereo wires from track.links
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     // set LR 2
00216     (track.links())[i]->leftRight(2);  // returns left-right. 0:left, 1:right, 2:wire
00217   }
00218   for(unsigned i = 0, size = list.length(); i < size; ++i){    
00219     track._links.remove(list[i]);
00220     // set LR 2
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   //...calculates a circle.
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   //...using SVD   //....Liuqg
00253   //double dZSVD, tanLSVD;
00254   //bool initWithSVD = buildStereo(track, dZSVD, tanLSVD);
00255 
00256   //...sets arc and z pairs of each stereo hit wire.
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){ // stereo >=2 && axial >= 3
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   //...separates
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   // makes a line.
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   // refits
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   //...appends at last chance
00325   unsigned nGoodL = goodL.length();
00326   list.remove(goodL);
00327   AList<TMLink> goodL2;
00328   if(m_param.CURL_VERSION == 0){ // default
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{ // in case of bad result of robustLineFitter. (2001/04/04)
00333       appendPoints(list, goodL2,
00334                    goodA, goodB, track, m_param.Z_DIFF_FOR_LAST_ATTEND);    
00335     }
00336   }else{
00337     // same with b20010409_2122 at least
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   //...refits
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   //...makes 3D tracks
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   //...sets initial values
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    // tmpA[2] = tmpQ*Helix::ConstantAlpha/r2D;
00376    // tmpA[2] = tmpQ*333.564095/r2D;
00377     tmpA[2] = tmpQ*(333.564095/(-1000*(m_pmgnIMF->getReferField())))/r2D;
00378 //cout<<"TBuilderCurl::tmpA[2]: "<<(333.564095/(-1000*(m_pmgnIMF->getReferField())))<<endl;
00379     tmpA[0] = xc2D/cos(tmpA[1]) - tmpQ*r2D;
00380     //std::cout << yc2D/sin(tmpA[1])-tmpQ*r2D << std::endl;
00381     //std::cout << a[0] << " -0- " << tmpA[0] << std::endl;
00382     //std::cout << a[1] << " -1- " << tmpA[1] << std::endl;
00383     //std::cout << a[2] << " -2- " << tmpA[2] << std::endl;
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 //Liuqg
00391 /*  if(initWithSVD){ // use SVD initial values if possible.
00392     a[3] = dZSVD;
00393     a[4] = tanLSVD;
00394   }
00395 */
00396   if(m_param.CURL_VERSION == 0){
00397     if(fabs(a[3]) > 10. && fabs(goodB) < 10.){ // 50cm --> 10cm @ 2001/04/04
00398       // use initial values when results of RobustFit is bad.
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   /* std::cout << "1st : "
00420        << track.helix().a()[0] << " " << track.helix().a()[1] << " "
00421        << track.helix().a()[2] << " " << track.helix().a()[3] << " "
00422        << track.helix().a()[4] << std::endl; */
00423 
00424 #if 1
00425 //  if(m_param.ON_CORRECTION){
00426 //    _fitter.sag();
00427 //    _fitter.propagation();
00428 //    _fitter.tof();
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   //...fits
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.  || // 50cm
00445                fabs(track.helix().a()[2]) > 100. || // 0.01GeV
00446                fabs(track.helix().a()[2]) < 0.1) ){ // 10GeV
00447     // in strange case, set "correction" of wires OFF
00448     // and then fit with the initial values.
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       //_fitter.sag();
00454       //_fitter.propagation();
00455       //_fitter.tof();
00456       track._helix->a(a);
00457       //std::cout << "ON --> OFF" << std::endl;
00458     }else{
00459       return NULL;
00460     }
00461   }
00462 
00463   /* std::cout << "2nd : "
00464        << track.helix().a()[0] << " " << track.helix().a()[1] << " "
00465        << track.helix().a()[2] << " " << track.helix().a()[3] << " "
00466        << track.helix().a()[4] << std::endl; */
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     //if(!(track.links()[i]->hit()->state() & WireHitFittingValid))
00520     //std::cout << "No-Valid For Fit!" << std::endl;
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     //if(!(track.links()[i]->hit()->state() & WireHitFittingValid))
00547     //std::cout << "No-Valid For Fit!" << std::endl;
00548   }
00549 #endif
00550 
00551   /* std::cout << "3rd : "
00552        << track.helix().a()[0] << " " << track.helix().a()[1] << " "
00553        << track.helix().a()[2] << " " << track.helix().a()[3] << " "
00554        << track.helix().a()[4] << std::endl; */
00555 
00556   //...tests
00557   if (track.nLinks() < 5){ // axial + stereo >= 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 || // Pt >= 5MeV
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   //...replaces init helix if dz is bad.
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 //.............Set Arc and Z Part..............
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 //Liuqg  
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 //.............Append Points(last).............
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 //..............Line Fit Part..................
00780 //.............................................
00781 
00782 int
00783 doLineFit(AList<TMLink> &points, 
00784           double &m_a, double &m_b, double &chi2, double &nhits,
00785           int ipC = 1)   //Liuqg, IP Constraint
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;// IP Constraint
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   // OLD
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.){ // with IP
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 //.................Check Part..................
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;// hard coding
00890   return 0;
00891 }
00892 
00893 //.............................................
00894 //.............Checker(Debuger)................
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     //difficult!! --> puls offset
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 /*  if(layerId < 15)maxLocalId = 79;
00998   else if(layerId >= 15)maxLocalId = 127;
00999   else if(layerId >= 23)maxLocalId = 159;
01000   else if(layerId >= 32)maxLocalId = 207;
01001   else if(layerId >= 41)maxLocalId = 255;
01002 */
01003 //Liuqg in this class, the parameter of superlayer changed to layerid.
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; //former
01028   AList<TMLink> lList; //later
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 //....................MC............................
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     /* std::cout << list[i]->wire()->id() << ": " 
01077          << point.x() << " "
01078          << point.y() << " "
01079          << (list[i]->hit()->mc()->datcdc()->m_zin+
01080          list[i]->hit()->mc()->datcdc()->m_zout)*0.5 << std::endl; */
01081   }
01082   //std::cout << "A# = " << track.links().length() << ", S# = " << list.length() << std::endl;
01083   double xc2D;
01084   double yc2D;
01085   double r2D;
01086   bool err2D = fitWDD(xc2D,yc2D,r2D,track.links()); // axial only
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    // tmpA[2] = tmpQ*Helix::ConstantAlpha/r2D;
01103    // tmpA[2] = tmpQ*333.564095/r2D;
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   //...fits
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   //track._helix->a(a); // re-write
01135 
01136   //...checks
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 //....................Plot..........................
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   //#if 1
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       //if(flag && !debugMcFlag)std::cout << std::endl;
01173       //if(flag && debugMcFlag){
01174       //std::cout << " Z(true) = " << (tmpLine[ii]->hit()->mc()->datcdc()->m_zin+
01175       //                          tmpLine[ii]->hit()->mc()->datcdc()->m_zout)*0.5;
01176       //std::cout << " HepTrackID = " << tmpLine[ii]->hit()->mc()->hep()->id() << std::endl;
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 /*  unsigned maxLocalId = 79;
01263   if(superLayerId == 3)maxLocalId = 127;
01264   else if(superLayerId == 5)maxLocalId = 159;
01265   else if(superLayerId == 7)maxLocalId = 207;
01266   else if(superLayerId == 9)maxLocalId = 255;
01267   return maxLocalId;
01268 */
01269 //changed to BESiii, Liuqg
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){ // R : ox, Dose a wire exist at "x"?
01293     findId = maxLocalId;
01294     if(localId != 0)findId = localId-1;
01295   }else if(lr == -1){ // L : xo, Dose a wire exist at "x"?
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   //...finds "two" seq. and isolated hits.
01317   //...and then sets LR for selected hits.
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; //origin is == 1, Liuqg 060921
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){ // xuox
01336         hitsOnLayer[0]->leftRight(1); // R
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){ // xoux
01346         hitsOnLayer[0]->leftRight(0); // L
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){ // xoox
01363         hitsOnLayer[0]->leftRight(1); // R
01364         hitsOnLayer[0]->position(hitsOnLayer[0]->arcZ(1));
01365         hitsOnLayer[1]->leftRight(0); // L
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){ // oxoox
01385         hitsOnLayer[0]->leftRight(1); // R
01386         hitsOnLayer[0]->position(hitsOnLayer[0]->arcZ(1));
01387         hitsOnLayer[1]->leftRight(0); // L
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){ // xooxo
01404         hitsOnLayer[1]->leftRight(1); // R
01405         hitsOnLayer[1]->position(hitsOnLayer[1]->arcZ(1));
01406         hitsOnLayer[2]->leftRight(0); // L
01407         hitsOnLayer[2]->position(hitsOnLayer[2]->arcZ(0));
01408         twoOnLayer.append(hitsOnLayer[1]);
01409         twoOnLayer.append(hitsOnLayer[2]);
01410       }
01411     }
01412   }
01413   /* if(twoOnLayer.length() != 0){
01414     std::cout << "TWO " << twoOnLayer.length() << std::endl;
01415     } */
01416 }
01417 
01418 void
01419 setLR(AList<TMLink> &hitsOnLayer, unsigned LR = 0){
01420   // LR = 0 : L
01421   //    = 1 : R
01422   for(unsigned i=0;i<hitsOnLayer.length();++i){
01423     if(LR == 0){
01424       hitsOnLayer[i]->leftRight(0); // L
01425       hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(0));
01426     }else{
01427       hitsOnLayer[i]->leftRight(1); // R
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   // ex) LLLL --> LLLR --> LLRR --> LRRR --> RRRR
01438   if(hitsOnLayer[nHits-1]->leftRight() == 1)return false; // All R
01439   for(unsigned i=0;i<nHits;++i){
01440     if(hitsOnLayer[i]->leftRight() == 0){ // L
01441       hitsOnLayer[i]->leftRight(1); // R
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 &center, 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; // Inner
01478   else if(Q < 0. && LR == -1)isOuter = -1; // Inner
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   // new center(virtual)
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   //...finds "ref" from hits.
01501   // ex) LLLL|, LLL|R, LL|RR, L|RRR, |RRRR
01502   int LR = -1; // L
01503   TMLink ref;
01504   if(hits[nHits-1]->leftRight() == 1){ // All R
01505     LR = 1; // R
01506     ref = *hits[nHits-1];
01507   }
01508   for(unsigned i=0;i<nHits;++i){
01509     if(hits[i]->leftRight() == 0){ // L
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)); // L
01525       hitsOnLayer[i]->leftRight(0); // L
01526     }else if(Q > 0. && isOuter == -1){
01527       hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(1)); // R
01528       hitsOnLayer[i]->leftRight(1); // R
01529     }else if(Q < 0. && isOuter == 1){
01530       hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(1)); // R
01531       hitsOnLayer[i]->leftRight(1); // R
01532     }else if(Q < 0. && isOuter == -1){
01533       hitsOnLayer[i]->position(hitsOnLayer[i]->arcZ(0)); // L
01534       hitsOnLayer[i]->leftRight(0); // L
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]; //Liuqg, origin is 18.
01547   AList<TMLink> layerOrg[24]; //Liuqg, origin is 18.
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]; // each superlayer    origin is 5,Liuqg 060920
01554   AList<TMLink> nonFixedWires[6]; // each superlayer    origin is 5,Liuqg 060920
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]); // chiisai-jun but kyoukai fukin ha sukoshi kufuu shite iru.
01560       AList<TMLink> tmp;
01561       findTwoHits(tmp,layer[i],allStereoList);
01562       if(tmp.length()){
01563         layer[i].removeAll();
01564         allFixedWires.append(tmp);
01565 //the following parameters have been changed, liuqg 060919
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 /* in detail */ 
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 /* in detail */
01606 #endif
01607 
01608   int createdLine = 0;
01609   int overCounter = 0;
01610   AList<TMLink> goodWires;
01611 #if 1 /* fastest finder */
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 /* fastest finder */
01620 #if 1 /* faster finder */
01621   if(createdLine == 0){
01622     // Q > 0 : Outer = L, Inner = R
01623     // Q < 0 : Outer = R, Inner = L
01624     double Q = track.charge();
01625     unsigned isIncreased = 0;
01626     for(int sl=0;sl<6;++sl){        //origin is 5, Liuqg 060919
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)); // L
01661             nonFixedWires[sl][i]->leftRight(0); // L
01662           }else if(Q > 0. && isOuter == -1){
01663             nonFixedWires[sl][i]->position(nonFixedWires[sl][i]->arcZ(1)); // R
01664             nonFixedWires[sl][i]->leftRight(1); // R
01665           }else if(Q < 0. && isOuter == 1){
01666             nonFixedWires[sl][i]->position(nonFixedWires[sl][i]->arcZ(1)); // R
01667             nonFixedWires[sl][i]->leftRight(1); // R
01668           }else if(Q < 0. && isOuter == -1){
01669             nonFixedWires[sl][i]->position(nonFixedWires[sl][i]->arcZ(0)); // L
01670             nonFixedWires[sl][i]->leftRight(0); // L
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 /* in detail */ 
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 /* in detail */
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 /* faster finder */
01713 #if 1 /* slow finder */
01714   // 2000/1/27...very slow but unlike an infinity loop
01715   if(createdLine == 0){
01716     // nonFixed Wires
01717     int maxNonFixedLayerIndex[6] = { -1, -1, -1, -1, -1, -1 }; //origin is 5, Liuqg 060919
01718     int maxLength[6] = { 0, 0, 0, 0, 0, 0 }; //origin is 5, Liuqg 060919
01719     for(int l=0;l<24;++l){
01720       unsigned sl = 5; // superlayer id, changed by Liuqg
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]); // set All 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 };   //origin is 5, Liuqg 060919
01736     unsigned isIncreased = 0;
01737     for(unsigned i=0;i<6;++i){  //origin is 5, Liuqg 060919
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 /* slow finder */
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   // MDC
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); // IP Constraint
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     // MDC
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); // IP Constraint
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     //std::cout << xc << ", " << yc << " : " << r << std::endl;
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     //...temporary
01883     for(unsigned j = 0; j < 4; ++j)
01884       list[i]->arcZ(tmp,j);
01885     
01886     //...stereo?
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()); //...= v^2*(r^2 - w^2*sin()^2)...outer
01894     d2[1] = vmag2*R[1]*R[1] + (wv*wv - vmag2*w.mag2()); //...= v^2*(r^2 - w^2*sin()^2)...inner
01895     //...No crossing in R/Phi plane...
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     //...outer
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     //...Cal. length and z to crossing points...
01914     double l[2][2];
01915     double z[2][2];
01916     //...outer
01917     if(ok_outer){
01918       l[0][0] = (- wv + d[0]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() + (r^2 - w^2*sin()^2)^0.5)/v
01919       l[1][0] = (- wv - d[0]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() - (r^2 - w^2*sin()^2)^0.5)/v
01920       z[0][0] = X.z() + l[0][0]*V.z();
01921       z[1][0] = X.z() + l[1][0]*V.z();
01922     }
01923     //...inner
01924     if(ok_inner){
01925       l[0][1] = (- wv + d[1]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() + (r^2 - w^2*sin()^2)^0.5)/v
01926       l[1][1] = (- wv - d[1]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() - (r^2 - w^2*sin()^2)^0.5)/v
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     //...Cal. xy position of crossing points...
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     //...Check r-phi...
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     //...Check z position...
01990 //Liuqg060925, change temporary! these should be changed to bes3, reference is in TTrack::szPosition!!! 
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     //unsigned index = 0;
02014     unsigned indexL = 0;
02015     unsigned indexR = 0;
02016     //std::cout << "Stereo " << std::endl;
02017     // Q > 0 : Outer = L, Inner = R
02018     // Q < 0 : Outer = R, Inner = L
02019     if(ok_xy[0][0]){
02020       //...cal. arc length...
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       //list[i]->arcZ(HepPoint3D(r*dPhi, z[0][0], 0.), index);
02030       //std::cout << r*dPhi << ", " << z[0][0] << std::endl;
02031       //++index;
02032       if(q > 0){
02033         //std::cout << "Outer L" << std::endl;
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         //std::cout << "Outer R" << std::endl;
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       //...cal. arc length...
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       //list[i]->arcZ(HepPoint3D(r*dPhi, z[1][0], 0.), index);
02055       //std::cout << r*dPhi << ", " << z[1][0] << std::endl;
02056       //++index;
02057       if(q > 0){
02058         //std::cout << "Outer L" << std::endl;
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         //std::cout << "Outer R" << std::endl;
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       //...cal. arc length...
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       //list[i]->arcZ(HepPoint3D(r*dPhi, z[0][1], 0.), index);
02080       //std::cout << r*dPhi << ", " << z[0][1] << std::endl;
02081       //++index;
02082       if(q > 0){
02083         //std::cout << "Inner R" << std::endl;
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         //std::cout << "Inner L" << std::endl;
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       //...cal. arc length...
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       //list[i]->arcZ(HepPoint3D(r*dPhi, z[1][1], 0.), index);
02105       //std::cout << r*dPhi << ", " << z[1][1] << std::endl;
02106       //++index;
02107       if(q > 0){
02108         //std::cout << "Inner R" << std::endl;
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         //std::cout << "Inner L" << std::endl;
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 /*void
02186 TBuilderCurl::setArcZ(TTrack &track, AList<TMLink> &slayer,
02187                       AList<TMLink> &alayer0,AList<TMLink> &alayer1,
02188                       AList<TMLink> &alayer2,AList<TMLink> &alayer3,
02189                       AList<TMLink> &alayer4,AList<TMLink> &alayer5,
02190                       unsigned ip) const {
02191   AList<TMLink> tmp = alayer0;
02192   tmp.append(alayer1);
02193   tmp.append(alayer2);
02194   tmp.append(alayer3);
02195   tmp.append(alayer4);
02196   tmp.append(alayer5);
02197   double xc,yc,r;
02198   if(fitWDD(xc,yc,r,tmp)){
02199     double q = track.charge();
02200     stereoHit(xc,yc,r,q,slayer);
02201   }
02202 }
02203 */
02204 #undef DEBUG_CURL_DUMP
02205 #undef DEBUG_CURL_GNUPLOT
02206 #undef DEBUG_CURL_MC
02207 
02208 // End === Stereo Finder For Curl Tracks : by jtanaka ===

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