// compilation: // g++ `root-config --cflags` CAonline.cpp `root-config --glibs` -std=c++11 // run: // /a.out #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; const double t_min = 1e-6; const double t_max = 1e-3; const double energy = 1.5; const double mass = 0.938; const int n_steps = 100; const int delta_t = (t_max - t_min)/(double)n_steps; double last_percent(-1.); class THit{ public: int col; int row; double x; double y; double z; int time; int event; int plane; int MCtrk; int id; THit():col(0),row(0), x(0), y(0), z(0), time(0), event(0), plane(0), MCtrk(-1), id(-1){ ; } }; typedef vector THits; THits generate_hits(); class TCell{ // stores index for a hit upstream and downstream public: int ihit_upstream; int ihit_downstream; // double dxdz; // direction of the cell in xz plane // double dydz; // direction of the cell in yz plane int pv; //cell position in evolution }; typedef vector TCells; class TBreakingAngle{ public: int icell_upstream; int icell_downstream; double angle_dxdz; double angle_dydz; }; typedef vector TBreakingAngles; class TTrack{ public: THits hits; // hits assigned to the track TCells cells; // cells indexing the hits above TVector3 point; //starting point TVector3 dir; //direction double covmtx[6][6]; double chi2; vector kinkAx;// breaking angles in x vector kinkAy;// breaking angles in y void SetCovMtx(double fcovmtx[6][6]){ for(int i=0;i<6;i++){ for(int j=0;j<6;j++){ covmtx[i][j] = fcovmtx[i][j]; } } } // void SetChi2(double fchi){chi2 = fchi;} // calculate distance from hit to this trk std::pair distance_hit_trk(const THit& hit) { double dX = hit.x - point.X()+dir.X()*(-hit.z+point.Z()); double dY = hit.y - point.Y()+dir.Y()*(-hit.z+point.Z()); pair dist; dist.first = dX; dist.second = dY; return dist; } }; typedef vector TTracks; //bool BreakingAngle(const TCell& icellup, const TCell& icelldo, const THits& hits){ bool Neighbours(const THit& hit0, const THit& hit1, const THit& hit2){ //hit0 = common hit between cells // double Ax = hits[icellup.ihit_downstream].x - hits[icellup.ihit_upstream].x; // double Ay = hits[icellup.ihit_downstream].y - hits[icellup.ihit_upstream].y; // double Az = hits[icellup.ihit_downstream].z - hits[icellup.ihit_upstream].z; // double Bx = hits[icelldo.ihit_downstream].x - hits[icelldo.ihit_upstream].x; // double By = hits[icelldo.ihit_downstream].y - hits[icelldo.ihit_upstream].y; // double Bz = hits[icelldo.ihit_downstream].z - hits[icelldo.ihit_upstream].z; double Ax = hit0.x - hit1.x; double Ay = hit0.y - hit1.y; double Az = hit0.z - hit1.z; double Bx = hit2.x - hit0.x; double By = hit2.y - hit0.y; double Bz = hit2.z - hit0.z; // cout<<"Az ="< pstate; // if(cells.size()>0) cout<<"BEFORE: "<0) cout<<"--------------------"<0){ cout<0){ //search for the last connected cell for (int icell2 = 0; icell2 < cells.size(); icell2++){ if(cells[icell1].ihit_downstream == cells[icell2].ihit_upstream){ bool stline = Neighbours(hits[cells[icell2].ihit_upstream], hits[cells[icell2].ihit_downstream], hits[cells[icell1].ihit_upstream]); //hit0 = common hit between cells // if(stline) if(stline && (cells[icell1].pv-cells[icell2].pv)==1){ // if(stline && (cells[icell1].pv-cells[icell2].pv)>0){ // cout<ang) brang_min=ang; // trk_cand_brang.push_back(ang); cells[icell0].pv = cells[icell0].pv-1; cells[icell1].pv = cells[icell1].pv-1; cells[icell2].pv = cells[icell2].pv-1; // cout<<", "<ang) brang_min=ang; // trk_cand_brang.push_back(ang); cells[icell0].pv = cells[icell0].pv-1; cells[icell1].pv = cells[icell1].pv-1; } } } } // trackcells.clear(); // trackhits.clear(); // } //pick up the best candidate from tmp // for (int itrk=0; itrk remove one with the largest breaking angles sum // not equal number of hits in tracks -> remove one with smallest number of hits // bool ch_smth=true; for(int iiter=0;iiter<2*trk_cand.size();iiter++){ // if(!ch_smth) break; // cout<<"=== Iter "<hits.size()=3){ // vector trk_h; // for(int ihit=0;ihithits.size();ihit++){ // trk_h // } // } //for (int itrk=0; itrkClear(); // if(fVerbose>2) cout<<"line3Dfit with SEED is used (multiple scattering taking into account by kinks)"<GetN(); Double_t ErrX1 = gr->GetErrorX(0); Double_t ErrY1 = gr->GetErrorY(0); Double_t ErrZ1 = gr->GetErrorZ(0); TVector3 ErrPosSeed(ErrX1,ErrY1,ErrZ1); Double_t ErrX2 = gr->GetErrorX(2); Double_t ErrY2 = gr->GetErrorY(2); Double_t ErrZ2 = gr->GetErrorY(2); Double_t errRx = 1*TMath::Hypot(ErrX1,ErrX2); Double_t errRy = 1*TMath::Hypot(ErrY1,ErrY2); Double_t errRz = 1*TMath::Hypot(ErrZ1,ErrZ2); fmin->SetObjectFit(gr); fmin->SetFCN(*LocalFCN_MS); Double_t arglist[100]; arglist[0] = 1; // fmin->ExecuteCommand("SET PRINT",arglist,10);//output // fmin->ExecuteCommand("SET PRINT",arglist,0);//no output ((TFitterMinuit*)fmin->GetFitter())->SetPrintLevel(0); //if(fVerbose>5){ cout<<"Number of hits = "<SetParameter(0,"x0",pStart[0],pStartErr[0],0,0); fmin->SetParameter(1,"Ax",pStart[1],pStartErr[1],0,0); fmin->SetParameter(2,"y0",pStart[2],pStartErr[2],0,0); fmin->SetParameter(3,"Ay",pStart[3],pStartErr[3],0,0); fmin->SetParameter(4,"z0",pStart[4],0,0,0); fmin->SetParameter(5,"Az",pStart[5],0,0,0); fmin->SetParameter(6,"al0x",pStart[6],1e-4*fsigmaMS,0,0); fmin->SetParameter(7,"al1x",pStart[7],1e-4*fsigmaMS,0,0); fmin->SetParameter(8,"al2x",pStart[8],1e-4*fsigmaMS,0,0); fmin->SetParameter(9,"al3x",pStart[9],1e-4*fsigmaMS,0,0); fmin->SetParameter(10,"al0y",pStart[10],1e-4*fsigmaMS,0,0); fmin->SetParameter(11,"al1y",pStart[11],1e-4*fsigmaMS,0,0); fmin->SetParameter(12,"al2y",pStart[12],1e-4*fsigmaMS,0,0); fmin->SetParameter(13,"al3y",pStart[13],1e-4*fsigmaMS,0,0); // fmin->FixParameter(6); // fmin->FixParameter(10); fmin->FixParameter(9); fmin->FixParameter(13); // if(Npoint<4){ // fmin->FixParameter(8); // fmin->FixParameter(12); // } // //TEST // fmin->FixParameter(7); fmin->FixParameter(8); fmin->FixParameter(9); // fmin->FixParameter(11); fmin->FixParameter(12); fmin->FixParameter(13); double recpres = 1e-7; // Now ready for minimization step arglist[0] = 5000; // arglist[0] = 2; arglist[1] = recpres; fmin->ExecuteCommand("MIGRAD", arglist,3); fmin->ExecuteCommand("SET PRI", arglist,5); ///Get results --------------------------------------------- int nvpar,nparx; double amin,edm, errdef; fmin->GetStats(amin,edm,errdef,nvpar,nparx); if(edm>1e2*recpres) return 1e6; // if(fVerbose>1){ cout<<"------------- Final result ---------------- "<PrintResults(fVerbose,amin); fmin->PrintResults(0,amin); // } // if(fVerbose>1){ // cout<<"------------- Final result ---------------- "<PrintResults(1,amin); // } Double_t fitparerr[nparams]; // get fit parameters for (int i = 0; i GetParameter(i); fitparerr[i] = fmin->GetParError(i); } for(size_t i=0;i<6;i++){ for(size_t j=0;j<6;j++){ (*covmatrix)(i,j)= fmin->GetCovarianceMatrixElement(i,j); } } if((fitpar[1]*fitpar[1]+fitpar[3]*fitpar[3])<1.){ fitpar[5]=sqrt(1-fitpar[1]*fitpar[1]-fitpar[3]*fitpar[3]); } else{ fitpar[5]=0; amin=1e9; } //!!!!!!!!!!!!!!!!!! z0, dz weren't fitted (*covmatrix)(4,4) = (gr->GetErrorZ(0)*gr->GetErrorZ(0))/12.; double dp5_dp1 = fitpar[1]/fitpar[5]; double dp5_dp3 = fitpar[3]/fitpar[5]; double errdz2 = pow(dp5_dp1,2)*(*covmatrix)(1,1) + pow(dp5_dp3,2)*(*covmatrix)(3,3) + 2*fabs(dp5_dp1*dp5_dp3*(*covmatrix)(1,3)); (*covmatrix)(5,5) = errdz2; //!!!!!!!!!!!!!!!!!! Double_t chi2 = amin/(2.*Npoint-4); ///------------------------------------------------------------- // if(fVerbose>2){ // falx0a = fitpar[6]; // ferralx0a = fitparerr[6]; // falx1a = fitpar[8]; // ferralx1a = fitparerr[8]; // falx2a = fitpar[10]; // ferralx2a = fitparerr[10]; // falx3a = fitpar[12]; // ferralx3a = fitparerr[12]; // faly0a = fitpar[14]; // ferraly0a = fitparerr[14]; // faly1a = fitpar[16]; // ferraly1a = fitparerr[16]; // faly2a = fitpar[18]; // ferraly2a = fitparerr[18]; // faly3a = fitpar[20]; // ferraly3a = fitparerr[20]; // falx0b = fitpar[7]; // ferralx0b = fitparerr[7]; // falx1b = fitpar[9]; // ferralx1b = fitparerr[9]; // falx2b = fitpar[11]; // ferralx2b = fitparerr[11]; // falx3b = fitpar[13]; // ferralx3b = fitparerr[13]; // faly0b = fitpar[15]; // ferraly0b = fitparerr[15]; // faly1b = fitpar[17]; // ferraly1b = fitparerr[17]; // faly2b = fitpar[19]; // ferraly2b = fitparerr[19]; // faly3b = fitpar[21]; // ferraly3b = fitparerr[21]; // fnpoints = Npoint; // fchi2 = chi2; // fzhit0 = (gr->GetZ())[0]; // ttal->Fill(); // } fmin->Clear(); //delete min; return chi2; } void FitTracks(TTracks &tracks){ //for (auto itrack = tracks.begin(); itrack != tracks.end(); itrack++){ // THits hits_trk = itrack->hits; for (int itrk=0; itrk=0; ihit--){ //loop over hits in trk, hits saved starting from the last plane // TVector3 addPos(hits_trk[ihit].x,hits_trk[ihit].y,hits_trk[ihit].z); fitme.SetPoint(gl_h, hits_trk[ihit].x, hits_trk[ihit].y, hits_trk[ihit].z); fitme.SetPointError(gl_h,2.3e-5,2.3e-5,1.5e-4);//80/sqrt(12), 80/sqrt(12), sensor thickness 150 mkm gl_h++; cout<<"Add hit with "<point = FitPoint; tracks[itrk].point = FitPoint; tracks[itrk].dir = FitDir; tracks[itrk].SetCovMtx(COVmatrixPosMom); tracks[itrk].chi2 = accuracy; // fmin->SetParameter(6,"al0x",pStart[6],1e-4*fsigmaMS,0,0); // fmin->SetParameter(7,"al1x",pStart[8],1e-4*fsigmaMS,0,0); // fmin->SetParameter(8,"al2x",pStart[10],1e-4*fsigmaMS,0,0); // fmin->SetParameter(9,"al3x",pStart[12],1e-4*fsigmaMS,0,0); // fmin->SetParameter(10,"al0y",pStart[14],1e-4*fsigmaMS,0,0); // fmin->SetParameter(11,"al1y",pStart[16],1e-4*fsigmaMS,0,0); // fmin->SetParameter(12,"al2y",pStart[18],1e-4*fsigmaMS,0,0); // fmin->SetParameter(13,"al3y",pStart[20],1e-4*fsigmaMS,0,0); for(int ip=6;ip<10;ip++) tracks[itrk].kinkAx.push_back(parFit[ip]); for(int ip=10;ip<14;ip++) tracks[itrk].kinkAy.push_back(parFit[ip]); // cout<<"chi2 = "< (len * percent)) { progress += "="; } else { progress += " "; } } cout << "[" << progress << "] " << (static_cast (100 * percent)) << "%"; flush( cout); // Required. last_percent = percent; } void track_finder(){ TCanvas canvas_distributions("canvas_distributions", "distributions", 800, 800); TH2F* hist_XY[4]; hist_XY[0] = new TH2F("hist_XY_plane_0", "xy distribution at plane 0", 49, -2e-3, 2e-3, 49, -2e-3, 2e-3); hist_XY[1] = new TH2F("hist_XY_plane_1", "xy distribution at plane 1", 49, -2e-3, 2e-3, 49, -2e-3, 2e-3); hist_XY[2] = new TH2F("hist_XY_plane_2", "xy distribution at plane 2", 49, -2e-3, 2e-3, 49, -2e-3, 2e-3); hist_XY[3] = new TH2F("hist_XY_plane_3", "xy distribution at plane 3", 49, -2e-3, 2e-3, 49, -2e-3, 2e-3); TH2F* hist_dxdz[2]; // breaking angles between planes hist_dxdz[0] = new TH2F("hist_dxdz_plane_012", "dx/dz and dy/dz distribution between plane 0,1 and 2", 49, -2e-2, 2e-2, 49, -2e-2, 2e-2); hist_dxdz[1] = new TH2F("hist_dxdz_plane_123", "dx/dz and dy/dz distribution between plane 1,2 and 3", 49, -2e-2, 2e-2, 49, -2e-2, 2e-2); // hist_dxdz[2] = new TH2F("hist_dxdz_plane_23", "dxdz distribution between plane 2 and 3", 49, -2e-2, 2e-2, 49, -2e-2, 2e-2); TH2F* hist_dxdz_track; // breaking angles between planes hist_dxdz_track = new TH2F("hist_dxdz_track", "dx/dz and dy/dz direction distribution", 49, -0.02, 0.02, 49, -0.02, 0.02); TH1F *hist_breakang_trk = new TH1F("hist_breakang_trk",";breaking angle, rad",1e2,0,2e-4); //TH2I *hist_trk_mult = new TH2I("hist_trk_mult",";MC trks(>2hits)/ev; REC.trks/ev",20,0,20,20,0,20); TH2I *hist_trk_mult = new TH2I("hist_trk_mult",";MC trks/ev; REC.trks/ev",15,0,15,15,0,15); TH1F *hist_hits_trk = new TH1F("hist_hits_trk","; hits/REC.trk",6,0,6); TH1F *hist_hits_mctrk = new TH1F("hist_hits_mctrk","; hits/trk",6,0,6); TH1I *hist_trks_pure = new TH1I("hist_trks_pure","; number of MCids/REC.trk",10,0,10); TH1F *hist_trks_chi2 = new TH1F("hist_trks_chi2","; #chi^{2}",1e2,0,1e1); TH2F* hist_kink[4]; hist_kink[0] = new TH2F("hist_kink_0", "kink angles on plane 0; #alpha_{x}, #murad; #alpha_{y}, #murad",1e2,-3e3,3e3,1e2,-3e3,3e3); hist_kink[1] = new TH2F("hist_kink_1", "kink angles on plane 1; #alpha_{x}, #murad; #alpha_{y}, #murad",1e2,-3e3,3e3,1e2,-3e3,3e3); hist_kink[2] = new TH2F("hist_kink_2", "kink angles on plane 2; #alpha_{x}, #murad; #alpha_{y}, #murad",1e2,-3e3,3e3,1e2,-3e3,3e3); hist_kink[3] = new TH2F("hist_kink_3", "kink angles on plane 3; #alpha_{x}, #murad; #alpha_{y}, #murad",1e2,-3e3,3e3,1e2,-3e3,3e3); TH2F* hist_hit_residuals[4]; hist_hit_residuals[0] = new TH2F("hist_hit_residuals_0", "residuals between hit and track on plane 0; #delta_{x}, #mum; #delta_{y}, #mum",1e2,-1e3,1e3,1e2,-1e3,1e3); hist_hit_residuals[1] = new TH2F("hist_hit_residuals_1", "residuals between hit and track on plane 1; #delta_{x}, #mum; #delta_{y}, #mum",1e2,-1e3,1e3,1e2,-1e3,1e3); hist_hit_residuals[2] = new TH2F("hist_hit_residuals_2", "residuals between hit and track on plane 2; #delta_{x}, #mum; #delta_{y}, #mum",1e2,-1e3,1e3,1e2,-1e3,1e3); hist_hit_residuals[3] = new TH2F("hist_hit_residuals_3", "residuals between hit and track on plane 3; #delta_{x}, #mum; #delta_{y}, #mum",1e2,-1e3,1e3,1e2,-1e3,1e3); int mean_hits(0); int mean_tracks(0); // int nevents = 1000000; int nevents = 10000; for (int ievent = 0; ievent < nevents; ievent++){ cout<<"------ Event "<< ievent<<" ------- "<plane]->Fill(ihit->x, ihit->y); } mean_hits += hits.size(); int MCMCtrks=0;//number of MC trks left hits in LMD if((hits.size())>1){ cout<<"MC MC ids: "< MCMCids; MCMCids.push_back(hits[0].MCtrk); int MCcount=0; for (auto ihit = hits.begin()+1; ihit != hits.end(); ihit++){ int MCtrk_cur = ihit->MCtrk; cout<<" "<2){ // MCMCtrks++; MCcount=0;//reset counter } }//loop over hits cout<MCtrk<MCtrk){ MCpos=ihit->MCtrk; cout<<"MC trk with "<Fill(counthit); counthit=1; // ch_mctrk=true; } else{ counthit++; } } cout<<"[last] MC trk with "<Fill(counthit);//pick up the last MCtrk // if(counthit>2) MCMCtrks++; //MCMCtrks = MCMCids.size(); } TTracks tracks = SearchTracks(hits); FitTracks(tracks);//TEST FIT int ntrks = tracks.size(); mean_tracks += ntrks; if(ntrks>0) hist_trk_mult->Fill(MCMCtrks,ntrks); if(MCMCtrks==1 && ntrks<1 && hits.size()>2) cout<<"WTF?! MC="<hits.size()< dist = itrack->distance_hit_trk(itrack->hits[ihit]); hist_hit_residuals[itrack->hits[ihit].plane]->Fill(1e6*dist.first,1e6*dist.second); } double dxdz_mean(0); double dydz_mean(0); for (auto icell = itrack->cells.begin(); icell != itrack->cells.end(); icell++){ int hit_do = icell->ihit_downstream; int hit_up = icell->ihit_upstream; double dz = (hits[hit_do].z - hits[hit_up].z); double dxdz = (hits[hit_do].x - hits[hit_up].x) / dz; double dydz = (hits[hit_do].y - hits[hit_up].y) / dz; dxdz_mean += dxdz; dydz_mean += dydz; } dxdz_mean /= itrack->cells.size(); dydz_mean /= itrack->cells.size(); hist_dxdz_track->Fill(dxdz_mean, dydz_mean); double breaking_ang = BreakingAngle(*itrack); hist_breakang_trk->Fill(breaking_ang); //check tracks THits trkhits = itrack->hits; vector MCids; cout<<"MC ids: "<MCtrk; cout<<" "<Draw("colz"); } canvas_distributions.Print("hit_ditros.pdf("); canvas_distributions.cd(2); hist_dxdz_track->Draw("colz"); canvas_distributions.cd(3); // hist_trk_mult->Draw("colz"); // hist_breakang_trk->Draw(); gPad->Clear(); canvas_distributions.cd(4); // hist_breakang_trk->Draw(); gPad->Clear(); canvas_distributions.cd(1); gPad->SetLogy(); hist_breakang_trk->Draw(); canvas_distributions.Print("hit_ditros.pdf("); canvas_distributions.cd(1); // gPad->SetLogy(); hist_hits_mctrk->SetLineWidth(2); hist_hits_mctrk->Draw(); hist_hits_trk->SetLineColor(2); hist_hits_trk->SetLineWidth(2); hist_hits_trk->Draw("same"); TLegend* leg = new TLegend(0.15, 0.8, .3, .99); leg->AddEntry(hist_hits_mctrk, "MC", "l"); leg->AddEntry(hist_hits_trk, "REC", "l"); leg->Draw(); // gPad->Clear(); canvas_distributions.cd(2); // gPad->SetLogy(); TH1F *hist_h_trk=(TH1F*)hist_hits_trk->Clone(); hist_h_trk->SetName("hist_h_trk"); hist_h_trk->Divide(hist_hits_mctrk); hist_h_trk->GetYaxis()->SetTitle("REC/MC"); // hist_h_trk->GetYaxis()->SetRangeUser(0.8,1.5); hist_h_trk->Draw(); canvas_distributions.cd(4); gPad->SetLogy(); hist_trks_pure->Draw(); // gPad->Clear(); canvas_distributions.cd(3); hist_trk_mult->Draw("colz"); // gPad->Clear(); canvas_distributions.Print("hit_ditros.pdf("); canvas_distributions.cd(1); gPad->SetLogy(0); hist_kink[1]->Draw("LEGO2Z"); canvas_distributions.cd(2); hist_kink[2]->Draw("LEGO2Z"); canvas_distributions.cd(3); hist_trks_chi2->Draw(); canvas_distributions.cd(4); gPad->Clear(); //hist_kink[3]->Draw("LEGO"); canvas_distributions.Print("hit_ditros.pdf("); for (int iplane = 0; iplane < 4; iplane++){ canvas_distributions.cd(iplane+1); gPad->SetLogy(0); hist_hit_residuals[iplane]->Draw("colz"); } canvas_distributions.Print("hit_ditros.pdf)"); TFile *f = new TFile("hit_ditros.root","RECREATE"); hist_trk_mult->Write(); hist_h_trk->Write(); hist_hits_trk->Write(); hist_hits_mctrk->Write(); leg->Write(); hist_breakang_trk->Write(); hist_trks_pure->Write(); hist_trks_chi2->Write(); for(int ip=0;ip<4;ip++){ hist_kink[ip]->Write(); hist_hit_residuals[ip]->Write(); } f->Close(); //print values---------------------- //Nmc = number of MC trks with >= 3 hits //Nperfect = number of REC tracks with 100% hits of one MC trk //Nrec = total number of REC tracks //Nperfect/Nmc = efficiency; (Nrec-Nperfect)/Nmc = fake; (Nmc-Nperfect)/Nmc = missed double Nmc = hist_hits_mctrk->GetBinContent(4)+hist_hits_mctrk->GetBinContent(5); double Nperfect = hist_trks_pure->GetBinContent(2); double Nrec = hist_trks_pure->GetEntries(); cout<<"Nmc = "<Gaus(dxdz_mean, dxdz_sigma); double dydz = gRandom->Gaus(dydz_mean, dydz_sigma); TVector3 dir(0., 0., momentum); dir.SetXYZ(dxdz, dydz, momentum); TVector3 pos(gRandom->Uniform(-posx, posx), gRandom->Uniform(-posy, posy), 0.); // m // cout<<"POSITION ("<Gaus(0,theta_0_slicon)); double l_x = dir.X()*dir.X()+dir.Z()*dir.Z(); double x_new = sqrt(l_x / (1/(tan_theta_new*tan_theta_new)+1)); // recover the lost sign if (tan_theta_new < 0 && x_new > 0) x_new = -x_new; double z_new = sqrt(l_x - x_new*x_new); dir.SetX(x_new); dir.SetZ(z_new); // same smearing procedure in the yz plane tan_theta_new = tan(atan(dir.Y()/dir.Z())+gRandom->Gaus(0,theta_0_slicon)); double l_y = dir.Y()*dir.Y()+dir.Z()*dir.Z(); double y_new = sqrt(l_y / (1/(tan_theta_new*tan_theta_new)+1)); // recover the lost sign if (tan_theta_new < 0 && y_new > 0) y_new = -y_new; z_new = sqrt(l_y - y_new*y_new); dir.SetY(y_new); dir.SetZ(z_new); } //else { // break; //} } // cout<<" "< #include int main(void) { track_finder(); return 0; }