+ AliTRDcluster *cl3 = layer3[icl3];
+ if (!cl3) {
+ continue;
+ }
+ padlength[sLayer+3] = TMath::Sqrt(cl3->GetSigmaZ2() * 12.0);
+ ycl[sLayer+3] = cl3->GetY();
+ zcl[sLayer+3] = cl3->GetZ();
+ Float_t yymin0 = ycl[sLayer+3] - 1.0 - kMaxPhi * (xcl[sLayer+3]-xcl[sLayer+0]);
+ Float_t yymax0 = ycl[sLayer+3] + 1.0 + kMaxPhi * (xcl[sLayer+3]-xcl[sLayer+0]);
+ Int_t maxn0 = layer0;
+
+ for (Int_t icl0 = layer0.Find(yymin0); icl0 < maxn0; icl0++) {
+
+ AliTRDcluster *cl0 = layer0[icl0];
+ if (!cl0) {
+ continue;
+ }
+ if (cl3->IsUsed() && cl0->IsUsed()) {
+ continue;
+ }
+ ycl[sLayer+0] = cl0->GetY();
+ zcl[sLayer+0] = cl0->GetZ();
+ if (ycl[sLayer+0] > yymax0) {
+ break;
+ }
+ Double_t tanphi = (ycl[sLayer+3]-ycl[sLayer+0]) / (xcl[sLayer+3]-xcl[sLayer+0]);
+ if (TMath::Abs(tanphi) > kMaxPhi) {
+ continue;
+ }
+ Double_t tantheta = (zcl[sLayer+3]-zcl[sLayer+0]) / (xcl[sLayer+3]-xcl[sLayer+0]);
+ if (TMath::Abs(tantheta) > kMaxTheta) {
+ continue;
+ }
+ padlength[sLayer+0] = TMath::Sqrt(cl0->GetSigmaZ2() * 12.0);
+
+ // Expected position in 1 layer
+ Double_t y1exp = ycl[sLayer+0] + (tanphi) * (xcl[sLayer+1]-xcl[sLayer+0]);
+ Double_t z1exp = zcl[sLayer+0] + (tantheta) * (xcl[sLayer+1]-xcl[sLayer+0]);
+ Float_t yymin1 = y1exp - kRoad0y - tanphi;
+ Float_t yymax1 = y1exp + kRoad0y + tanphi;
+ Int_t maxn1 = layer1;
+
+ for (Int_t icl1 = layer1.Find(yymin1); icl1 < maxn1; icl1++) {
+
+ AliTRDcluster *cl1 = layer1[icl1];
+ if (!cl1) {
+ continue;
+ }
+ Int_t nusedCl = 0;
+ if (cl3->IsUsed()) nusedCl++;
+ if (cl0->IsUsed()) nusedCl++;
+ if (cl1->IsUsed()) nusedCl++;
+ if (nusedCl > 1) {
+ continue;
+ }
+ ycl[sLayer+1] = cl1->GetY();
+ zcl[sLayer+1] = cl1->GetZ();
+ if (ycl[sLayer+1] > yymax1) {
+ break;
+ }
+ if (TMath::Abs(ycl[sLayer+1]-y1exp) > kRoad0y+tanphi) {
+ continue;
+ }
+ if (TMath::Abs(zcl[sLayer+1]-z1exp) > kRoad0z) {
+ continue;
+ }
+ padlength[sLayer+1] = TMath::Sqrt(cl1->GetSigmaZ2() * 12.0);
+
+ Double_t y2exp = ycl[sLayer+0]+(tanphi) * (xcl[sLayer+2]-xcl[sLayer+0]) + (ycl[sLayer+1]-y1exp);
+ Double_t z2exp = zcl[sLayer+0]+(tantheta) * (xcl[sLayer+2]-xcl[sLayer+0]);
+ Int_t index2 = layer2.FindNearestCluster(y2exp,z2exp,kRoad1y,kRoad1z);
+ if (index2 <= 0) {
+ continue;
+ }
+ AliTRDcluster *cl2 = (AliTRDcluster *) GetCluster(index2);
+ padlength[sLayer+2] = TMath::Sqrt(cl2->GetSigmaZ2() * 12.0);
+ ycl[sLayer+2] = cl2->GetY();
+ zcl[sLayer+2] = cl2->GetZ();
+ if (TMath::Abs(cl2->GetZ()-z2exp) > kRoad0z) {
+ continue;
+ }
+
+ rieman.Reset();
+ rieman.AddPoint(xcl[sLayer+0],ycl[sLayer+0],zcl[sLayer+0],1,10);
+ rieman.AddPoint(xcl[sLayer+1],ycl[sLayer+1],zcl[sLayer+1],1,10);
+ rieman.AddPoint(xcl[sLayer+3],ycl[sLayer+3],zcl[sLayer+3],1,10);
+ rieman.AddPoint(xcl[sLayer+2],ycl[sLayer+2],zcl[sLayer+2],1,10);
+ rieman.Update();
+
+ // Reset fitter
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ cseed[iLayer].Reset();
+ }
+ chi2Z = 0.0;
+ chi2R = 0.0;
+
+ for (Int_t iLayer = 0; iLayer < 4; iLayer++) {
+ cseed[sLayer+iLayer].SetZref(0,rieman.GetZat(xcl[sLayer+iLayer]));
+ chi2Z += (cseed[sLayer+iLayer].GetZref(0)- zcl[sLayer+iLayer])
+ * (cseed[sLayer+iLayer].GetZref(0)- zcl[sLayer+iLayer]);
+ cseed[sLayer+iLayer].SetZref(1,rieman.GetDZat(xcl[sLayer+iLayer]));
+ cseed[sLayer+iLayer].SetYref(0,rieman.GetYat(xcl[sLayer+iLayer]));
+ chi2R += (cseed[sLayer+iLayer].GetYref(0)- ycl[sLayer+iLayer])
+ * (cseed[sLayer+iLayer].GetYref(0)- ycl[sLayer+iLayer]);
+ cseed[sLayer+iLayer].SetYref(1,rieman.GetDYat(xcl[sLayer+iLayer]));
+ }
+ if (TMath::Sqrt(chi2R) > 1.0/iter) {
+ continue;
+ }
+ if (TMath::Sqrt(chi2Z) > 7.0/iter) {
+ continue;
+ }
+
+ Float_t minmax[2] = { -100.0, 100.0 };
+ for (Int_t iLayer = 0; iLayer < 4; iLayer++) {
+ Float_t max = zcl[sLayer+iLayer]+padlength[sLayer+iLayer] * 0.5
+ + 1.0 - cseed[sLayer+iLayer].GetZref(0);
+ if (max < minmax[1]) {
+ minmax[1] = max;
+ }
+ Float_t min = zcl[sLayer+iLayer]-padlength[sLayer+iLayer] * 0.5
+ - 1.0 - cseed[sLayer+iLayer].GetZref(0);
+ if (min > minmax[0]) {
+ minmax[0] = min;
+ }
+ }
+
+ Bool_t isFake = kFALSE;
+ if (cl0->GetLabel(0) != cl3->GetLabel(0)) {
+ isFake = kTRUE;
+ }
+ if (cl1->GetLabel(0) != cl3->GetLabel(0)) {
+ isFake = kTRUE;
+ }
+ if (cl2->GetLabel(0) != cl3->GetLabel(0)) {
+ isFake = kTRUE;
+ }
+
+ if (AliTRDReconstructor::StreamLevel() > 0) {
+ if ((!isFake) || ((icl3%10) == 0)) { // Debugging print
+ TTreeSRedirector &cstream = *fDebugStreamer;
+ cstream << "Seeds0"
+ << "isFake=" << isFake
+ << "Cl0.=" << cl0
+ << "Cl1.=" << cl1
+ << "Cl2.=" << cl2
+ << "Cl3.=" << cl3
+ << "Xref=" << xref
+ << "X0=" << xcl[sLayer+0]
+ << "X1=" << xcl[sLayer+1]
+ << "X2=" << xcl[sLayer+2]
+ << "X3=" << xcl[sLayer+3]
+ << "Y2exp=" << y2exp
+ << "Z2exp=" << z2exp
+ << "Chi2R=" << chi2R
+ << "Chi2Z=" << chi2Z
+ << "Seed0.=" << &cseed[sLayer+0]
+ << "Seed1.=" << &cseed[sLayer+1]
+ << "Seed2.=" << &cseed[sLayer+2]
+ << "Seed3.=" << &cseed[sLayer+3]
+ << "Zmin=" << minmax[0]
+ << "Zmax=" << minmax[1]
+ << "\n";
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Fit seeding part
+ //
+ ////////////////////////////////////////////////////////////////////////////////////
+
+ cl[sLayer+0] = cl0;
+ cl[sLayer+1] = cl1;
+ cl[sLayer+2] = cl2;
+ cl[sLayer+3] = cl3;
+ Bool_t isOK = kTRUE;
+
+ for (Int_t jLayer = 0; jLayer < 4; jLayer++) {
+
+ cseed[sLayer+jLayer].SetTilt(hL[sLayer+jLayer]);
+ cseed[sLayer+jLayer].SetPadLength(padlength[sLayer+jLayer]);
+ cseed[sLayer+jLayer].SetX0(xcl[sLayer+jLayer]);
+
+ for (Int_t iter = 0; iter < 2; iter++) {
+
+ //
+ // In iteration 0 we try only one pad-row
+ // If quality not sufficient we try 2 pad-rows - about 5% of tracks cross 2 pad-rows
+ //
+ AliTRDseed tseed = cseed[sLayer+jLayer];
+ Float_t roadz = padlength[sLayer+jLayer] * 0.5;
+ if (iter > 0) {
+ roadz = padlength[sLayer+jLayer];
+ }
+
+ Float_t quality = 10000.0;
+
+ for (Int_t iTime = 2; iTime < 20; iTime++) {
+
+ AliTRDpropagationLayer &layer = *(fTrSec[ns]->GetLayer(layers[sLayer+jLayer][1]-iTime));
+ Double_t dxlayer = layer.GetX() - xcl[sLayer+jLayer];
+ Double_t zexp = cl[sLayer+jLayer]->GetZ();
+
+ if (iter > 0) {
+ // Try 2 pad-rows in second iteration
+ zexp = tseed.GetZref(0) + tseed.GetZref(1) * dxlayer;
+ if (zexp > cl[sLayer+jLayer]->GetZ()) {
+ zexp = cl[sLayer+jLayer]->GetZ() + padlength[sLayer+jLayer]*0.5;
+ }
+ if (zexp < cl[sLayer+jLayer]->GetZ()) {
+ zexp = cl[sLayer+jLayer]->GetZ() - padlength[sLayer+jLayer]*0.5;
+ }
+ }
+
+ Double_t yexp = tseed.GetYref(0) + tseed.GetYref(1) * dxlayer;
+ Int_t index = layer.FindNearestCluster(yexp,zexp,kRoad1y,roadz);
+ if (index <= 0) {
+ continue;
+ }
+ AliTRDcluster *cl = (AliTRDcluster *) GetCluster(index);
+
+ tseed.SetIndexes(iTime,index);
+ tseed.SetClusters(iTime,cl); // Register cluster
+ tseed.SetX(iTime,dxlayer); // Register cluster
+ tseed.SetY(iTime,cl->GetY()); // Register cluster
+ tseed.SetZ(iTime,cl->GetZ()); // Register cluster
+
+ }
+
+ tseed.Update();
+
+ // Count the number of clusters and distortions into quality
+ Float_t dangle = tseed.GetYfit(1) - tseed.GetYref(1);
+ Float_t tquality = (18.0 - tseed.GetN2()) / 2.0 + TMath::Abs(dangle) / 0.1
+ + TMath::Abs(tseed.GetYfit(0) - tseed.GetYref(0)) / 0.2
+ + 2.0 * TMath::Abs(tseed.GetMeanz() - tseed.GetZref(0)) / padlength[jLayer];
+ if ((iter == 0) && tseed.IsOK()) {
+ cseed[sLayer+jLayer] = tseed;
+ quality = tquality;
+ if (tquality < 5) {
+ break;
+ }
+ }
+ if (tseed.IsOK() && (tquality < quality)) {
+ cseed[sLayer+jLayer] = tseed;
+ }
+
+ } // Loop: iter
+
+ if (!cseed[sLayer+jLayer].IsOK()) {
+ isOK = kFALSE;
+ break;
+ }
+
+ cseed[sLayer+jLayer].CookLabels();
+ cseed[sLayer+jLayer].UpdateUsed();
+ nusedCl += cseed[sLayer+jLayer].GetNUsed();
+ if (nusedCl > 25) {
+ isOK = kFALSE;
+ break;
+ }
+
+ } // Loop: jLayer
+
+ if (!isOK) {
+ continue;
+ }
+ nclusters = 0;
+ for (Int_t iLayer = 0; iLayer < 4; iLayer++) {
+ if (cseed[sLayer+iLayer].IsOK()) {
+ nclusters += cseed[sLayer+iLayer].GetN2();
+ }
+ }
+
+ // Iteration 0
+ rieman.Reset();
+ for (Int_t iLayer = 0; iLayer < 4; iLayer++) {
+ rieman.AddPoint(xcl[sLayer+iLayer]
+ ,cseed[sLayer+iLayer].GetYfitR(0)
+ ,cseed[sLayer+iLayer].GetZProb()
+ ,1
+ ,10);
+ }
+ rieman.Update();
+
+ chi2R = 0.0;
+ chi2Z = 0.0;
+
+ for (Int_t iLayer = 0; iLayer < 4; iLayer++) {
+ cseed[sLayer+iLayer].SetYref(0,rieman.GetYat(xcl[sLayer+iLayer]));
+ chi2R += (cseed[sLayer+iLayer].GetYref(0) - cseed[sLayer+iLayer].GetYfitR(0))
+ * (cseed[sLayer+iLayer].GetYref(0) - cseed[sLayer+iLayer].GetYfitR(0));
+ cseed[sLayer+iLayer].SetYref(1,rieman.GetDYat(xcl[sLayer+iLayer]));
+ cseed[sLayer+iLayer].SetZref(0,rieman.GetZat(xcl[sLayer+iLayer]));
+ chi2Z += (cseed[sLayer+iLayer].GetZref(0) - cseed[sLayer+iLayer].GetMeanz())
+ * (cseed[sLayer+iLayer].GetZref(0) - cseed[sLayer+iLayer].GetMeanz());
+ cseed[sLayer+iLayer].SetZref(1,rieman.GetDZat(xcl[sLayer+iLayer]));
+ }
+ Double_t curv = rieman.GetC();
+
+ //
+ // Likelihoods
+ //
+ Double_t sumda = TMath::Abs(cseed[sLayer+0].GetYfitR(1) - cseed[sLayer+0].GetYref(1))
+ + TMath::Abs(cseed[sLayer+1].GetYfitR(1) - cseed[sLayer+1].GetYref(1))
+ + TMath::Abs(cseed[sLayer+2].GetYfitR(1) - cseed[sLayer+2].GetYref(1))
+ + TMath::Abs(cseed[sLayer+3].GetYfitR(1) - cseed[sLayer+3].GetYref(1));
+ Double_t likea = TMath::Exp(-sumda*10.6);
+ Double_t likechi2 = 0.0000000001;
+ if (chi2R < 0.5) {
+ likechi2 += TMath::Exp(-TMath::Sqrt(chi2R) * 7.73);
+ }
+ Double_t likechi2z = TMath::Exp(-chi2Z * 0.088) / TMath::Exp(-chi2Z * 0.019);
+ Double_t likeN = TMath::Exp(-(72 - nclusters) * 0.19);
+ Double_t like = likea * likechi2 * likechi2z * likeN;
+ Double_t likePrimY = TMath::Exp(-TMath::Abs(cseed[sLayer+0].GetYref(1) - 130.0*curv) * 1.9);
+ Double_t likePrimZ = TMath::Exp(-TMath::Abs(cseed[sLayer+0].GetZref(1)
+ - cseed[sLayer+0].GetZref(0) / xcl[sLayer+0]) * 5.9);
+ Double_t likePrim = TMath::Max(likePrimY*likePrimZ,0.0005);
+
+ seedquality[registered] = like;
+ seedlayer[registered] = sLayer;
+ if (TMath::Log(0.000000000000001 + like) < -15) {
+ continue;
+ }
+ AliTRDseed seedb[6];
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ seedb[iLayer] = cseed[iLayer];
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Full track fit part
+ //
+ ////////////////////////////////////////////////////////////////////////////////////
+
+ Int_t nlayers = 0;
+ Int_t nusedf = 0;
+ Int_t findable = 0;
+
+ //
+ // Add new layers - avoid long extrapolation
+ //
+ Int_t tLayer[2] = { 0, 0 };
+ if (sLayer == 2) {
+ tLayer[0] = 1;
+ tLayer[1] = 0;
+ }
+ if (sLayer == 1) {
+ tLayer[0] = 5;
+ tLayer[1] = 0;
+ }
+ if (sLayer == 0) {
+ tLayer[0] = 4;
+ tLayer[1] = 5;
+ }
+
+ for (Int_t iLayer = 0; iLayer < 2; iLayer++) {
+ Int_t jLayer = tLayer[iLayer]; // Set tracking layer
+ cseed[jLayer].Reset();
+ cseed[jLayer].SetTilt(hL[jLayer]);
+ cseed[jLayer].SetPadLength(padlength[jLayer]);
+ cseed[jLayer].SetX0(xcl[jLayer]);
+ // Get pad length and rough cluster
+ Int_t indexdummy = reflayers[jLayer]->FindNearestCluster(cseed[jLayer].GetYref(0)
+ ,cseed[jLayer].GetZref(0)
+ ,kRoad2y
+ ,kRoad2z);
+ if (indexdummy <= 0) {
+ continue;
+ }
+ AliTRDcluster *cldummy = (AliTRDcluster *) GetCluster(indexdummy);
+ padlength[jLayer] = TMath::Sqrt(cldummy->GetSigmaZ2() * 12.0);
+ }
+ AliTRDseed::FitRiemanTilt(cseed,kTRUE);
+
+ for (Int_t iLayer = 0; iLayer < 2; iLayer++) {
+
+ Int_t jLayer = tLayer[iLayer]; // set tracking layer
+ if ((jLayer == 0) && !(cseed[1].IsOK())) {
+ continue; // break not allowed
+ }
+ if ((jLayer == 5) && !(cseed[4].IsOK())) {
+ continue; // break not allowed
+ }
+ Float_t zexp = cseed[jLayer].GetZref(0);
+ Double_t zroad = padlength[jLayer] * 0.5 + 1.0;
+
+ for (Int_t iter = 0; iter < 2; iter++) {
+
+ AliTRDseed tseed = cseed[jLayer];
+ Float_t quality = 10000.0;
+
+ for (Int_t iTime = 2; iTime < 20; iTime++) {
+ AliTRDpropagationLayer &layer = *(fTrSec[ns]->GetLayer(layers[jLayer][1]-iTime));
+ Double_t dxlayer = layer.GetX()-xcl[jLayer];
+ Double_t yexp = tseed.GetYref(0) + tseed.GetYref(1) * dxlayer;
+ Float_t yroad = kRoad1y;
+ Int_t index = layer.FindNearestCluster(yexp,zexp,yroad,zroad);
+ if (index <= 0) {
+ continue;
+ }
+ AliTRDcluster *cl = (AliTRDcluster *) GetCluster(index);
+ tseed.SetIndexes(iTime,index);
+ tseed.SetClusters(iTime,cl); // Register cluster
+ tseed.SetX(iTime,dxlayer); // Register cluster
+ tseed.SetY(iTime,cl->GetY()); // Register cluster
+ tseed.SetZ(iTime,cl->GetZ()); // Register cluster
+ }
+
+ tseed.Update();
+ if (tseed.IsOK()) {
+ Float_t dangle = tseed.GetYfit(1) - tseed.GetYref(1);
+ Float_t tquality = (18.0 - tseed.GetN2())/2.0 + TMath::Abs(dangle) / 0.1
+ + TMath::Abs(tseed.GetYfit(0) - tseed.GetYref(0)) / 0.2
+ + 2.0 * TMath::Abs(tseed.GetMeanz() - tseed.GetZref(0)) / padlength[jLayer];
+ if (tquality < quality) {
+ cseed[jLayer] = tseed;
+ quality = tquality;
+ }
+ }
+
+ zroad *= 2.0;
+
+ } // Loop: iter
+
+ if ( cseed[jLayer].IsOK()) {
+ cseed[jLayer].CookLabels();
+ cseed[jLayer].UpdateUsed();
+ nusedf += cseed[jLayer].GetNUsed();
+ AliTRDseed::FitRiemanTilt(cseed,kTRUE);
+ }
+
+ } // Loop: iLayer
+
+ // Make copy
+ AliTRDseed bseed[6];
+ for (Int_t jLayer = 0; jLayer < 6; jLayer++) {
+ bseed[jLayer] = cseed[jLayer];
+ }
+ Float_t lastquality = 10000.0;
+ Float_t lastchi2 = 10000.0;
+ Float_t chi2 = 1000.0;
+
+ for (Int_t iter = 0; iter < 4; iter++) {
+
+ // Sort tracklets according "quality", try to "improve" 4 worst
+ Float_t sumquality = 0.0;
+ Float_t squality[6];
+ Int_t sortindexes[6];
+
+ for (Int_t jLayer = 0; jLayer < 6; jLayer++) {
+ if (bseed[jLayer].IsOK()) {
+ AliTRDseed &tseed = bseed[jLayer];
+ Double_t zcor = tseed.GetTilt() * (tseed.GetZProb() - tseed.GetZref(0));
+ Float_t dangle = tseed.GetYfit(1) - tseed.GetYref(1);
+ Float_t tquality = (18.0 - tseed.GetN2()) / 2.0 + TMath::Abs(dangle) / 0.1
+ + TMath::Abs(tseed.GetYfit(0) - (tseed.GetYref(0) - zcor)) / 0.2
+ + 2.0 * TMath::Abs(tseed.GetMeanz() - tseed.GetZref(0)) / padlength[jLayer];
+ squality[jLayer] = tquality;
+ }
+ else {
+ squality[jLayer] = -1.0;
+ }
+ sumquality +=squality[jLayer];
+ }
+
+ if ((sumquality >= lastquality) ||
+ (chi2 > lastchi2)) {
+ break;
+ }
+ lastquality = sumquality;
+ lastchi2 = chi2;
+ if (iter > 0) {
+ for (Int_t jLayer = 0; jLayer < 6; jLayer++) {
+ cseed[jLayer] = bseed[jLayer];
+ }
+ }
+ TMath::Sort(6,squality,sortindexes,kFALSE);
+
+ for (Int_t jLayer = 5; jLayer > 1; jLayer--) {
+
+ Int_t bLayer = sortindexes[jLayer];
+ AliTRDseed tseed = bseed[bLayer];
+
+ for (Int_t iTime = 2; iTime < 20; iTime++) {
+
+ AliTRDpropagationLayer &layer = *(fTrSec[ns]->GetLayer(layers[bLayer][1]-iTime));
+ Double_t dxlayer = layer.GetX() - xcl[bLayer];
+ Double_t zexp = tseed.GetZref(0);
+ Double_t zcor = tseed.GetTilt() * (tseed.GetZProb() - tseed.GetZref(0));
+ Float_t roadz = padlength[bLayer] + 1;
+ if (TMath::Abs(tseed.GetZProb() - zexp) > 0.5*padlength[bLayer]) {
+ roadz = padlength[bLayer] * 0.5;
+ }
+ if (tseed.GetZfit(1)*tseed.GetZref(1) < 0.0) {
+ roadz = padlength[bLayer] * 0.5;
+ }
+ if (TMath::Abs(tseed.GetZProb() - zexp) < 0.1*padlength[bLayer]) {
+ zexp = tseed.GetZProb();
+ roadz = padlength[bLayer] * 0.5;
+ }
+
+ Double_t yexp = tseed.GetYref(0) + tseed.GetYref(1) * dxlayer - zcor;
+ Int_t index = layer.FindNearestCluster(yexp,zexp,kRoad1y,roadz);
+ if (index <= 0) {
+ continue;
+ }
+ AliTRDcluster *cl = (AliTRDcluster *) GetCluster(index);
+
+ tseed.SetIndexes(iTime,index);
+ tseed.SetClusters(iTime,cl); // Register cluster
+ tseed.SetX(iTime,dxlayer); // Register cluster
+ tseed.SetY(iTime,cl->GetY()); // Register cluster
+ tseed.SetZ(iTime,cl->GetZ()); // Register cluster
+
+ }
+
+ tseed.Update();
+ if (tseed.IsOK()) {
+ Float_t dangle = tseed.GetYfit(1) - tseed.GetYref(1);
+ Double_t zcor = tseed.GetTilt() * (tseed.GetZProb() - tseed.GetZref(0));
+ Float_t tquality = (18.0 - tseed.GetN2()) / 2.0
+ + TMath::Abs(dangle) / 0.1
+ + TMath::Abs(tseed.GetYfit(0) - (tseed.GetYref(0) - zcor)) / 0.2
+ + 2.0 * TMath::Abs(tseed.GetMeanz() - tseed.GetZref(0)) / padlength[jLayer];
+ if (tquality<squality[bLayer]) {
+ bseed[bLayer] = tseed;
+ }
+ }
+
+ } // Loop: jLayer
+
+ chi2 = AliTRDseed::FitRiemanTilt(bseed,kTRUE);
+
+ } // Loop: iter
+
+ nclusters = 0;
+ nlayers = 0;
+ findable = 0;
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ if (TMath::Abs(cseed[iLayer].GetYref(0) / cseed[iLayer].GetX0()) < 0.15) {
+ findable++;
+ }
+ if (cseed[iLayer].IsOK()) {
+ nclusters += cseed[iLayer].GetN2();
+ nlayers++;
+ }
+ }
+ if (nlayers < 3) {
+ continue;
+ }
+ rieman.Reset();
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ if (cseed[iLayer].IsOK()) {
+ rieman.AddPoint(xcl[iLayer]
+ ,cseed[iLayer].GetYfitR(0)
+ ,cseed[iLayer].GetZProb()
+ ,1
+ ,10);
+ }
+ }
+ rieman.Update();
+
+ chi2RF = 0.0;
+ chi2ZF = 0.0;
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ if (cseed[iLayer].IsOK()) {
+ cseed[iLayer].SetYref(0,rieman.GetYat(xcl[iLayer]));
+ chi2RF += (cseed[iLayer].GetYref(0) - cseed[iLayer].GetYfitR(0))
+ * (cseed[iLayer].GetYref(0) - cseed[iLayer].GetYfitR(0));
+ cseed[iLayer].SetYref(1,rieman.GetDYat(xcl[iLayer]));
+ cseed[iLayer].SetZref(0,rieman.GetZat(xcl[iLayer]));
+ chi2ZF += (cseed[iLayer].GetZref(0) - cseed[iLayer].GetMeanz())
+ * (cseed[iLayer].GetZref(0) - cseed[iLayer].GetMeanz());
+ cseed[iLayer].SetZref(1,rieman.GetDZat(xcl[iLayer]));
+ }
+ }
+ chi2RF /= TMath::Max((nlayers - 3.0),1.0);
+ chi2ZF /= TMath::Max((nlayers - 3.0),1.0);
+ curv = rieman.GetC();
+
+ Double_t xref2 = (xcl[2] + xcl[3]) * 0.5; // Middle of the chamber
+ Double_t dzmf = rieman.GetDZat(xref2);
+ Double_t zmf = rieman.GetZat(xref2);
+
+ //
+ // Fit hyperplane
+ //
+ Int_t npointsT = 0;
+ fitterTC.ClearPoints();
+ fitterT2.ClearPoints();
+ rieman2.Reset();
+
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+
+ if (!cseed[iLayer].IsOK()) {
+ continue;
+ }
+
+ for (Int_t itime = 0; itime < 25; itime++) {
+
+ if (!cseed[iLayer].IsUsable(itime)) {
+ continue;
+ }
+ // X relative to the middle chamber
+ Double_t x = cseed[iLayer].GetX(itime) + cseed[iLayer].GetX0() - xref2;
+ Double_t y = cseed[iLayer].GetY(itime);
+ Double_t z = cseed[iLayer].GetZ(itime);
+ // ExB correction to the correction
+ // Tilted rieman
+ Double_t uvt[6];
+ // Global x
+ Double_t x2 = cseed[iLayer].GetX(itime) + cseed[iLayer].GetX0();
+ Double_t t = 1.0 / (x2*x2 + y*y);
+ uvt[1] = t; // t
+ uvt[0] = 2.0 * x2 * uvt[1]; // u
+ uvt[2] = 2.0 * hL[iLayer] * uvt[1];
+ uvt[3] = 2.0 * hL[iLayer] * x * uvt[1];
+ uvt[4] = 2.0 * (y + hL[iLayer]*z) * uvt[1];
+ Double_t error = 2.0 * 0.2 * uvt[1];
+ fitterT2.AddPoint(uvt,uvt[4],error);
+
+ //
+ // Constrained rieman
+ //
+ z = cseed[iLayer].GetZ(itime);
+ uvt[0] = 2.0 * x2 * t; // u
+ uvt[1] = 2.0 * hL[iLayer] * x2 * uvt[1];
+ uvt[2] = 2.0 * (y + hL[iLayer] * (z - GetZ())) * t;
+ fitterTC.AddPoint(uvt,uvt[2],error);
+ rieman2.AddPoint(x2,y,z,1,10);
+ npointsT++;
+
+ }
+
+ } // Loop: iLayer
+
+ rieman2.Update();
+ fitterTC.Eval();
+ fitterT2.Eval();
+ Double_t rpolz0 = fitterT2.GetParameter(3);
+ Double_t rpolz1 = fitterT2.GetParameter(4);
+
+ //
+ // Linear fitter - not possible to make boundaries
+ // Do not accept non possible z and dzdx combinations
+ //
+ Bool_t acceptablez = kTRUE;
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ if (cseed[iLayer].IsOK()) {
+ Double_t zT2 = rpolz0 + rpolz1 * (xcl[iLayer] - xref2);
+ if (TMath::Abs(cseed[iLayer].GetZProb() - zT2) > padlength[iLayer] * 0.5 + 1.0) {
+ acceptablez = kFALSE;
+ }
+ }
+ }
+ if (!acceptablez) {
+ fitterT2.FixParameter(3,zmf);
+ fitterT2.FixParameter(4,dzmf);
+ fitterT2.Eval();
+ fitterT2.ReleaseParameter(3);
+ fitterT2.ReleaseParameter(4);
+ rpolz0 = fitterT2.GetParameter(3);
+ rpolz1 = fitterT2.GetParameter(4);
+ }
+
+ Double_t chi2TR = fitterT2.GetChisquare() / Float_t(npointsT);
+ Double_t chi2TC = fitterTC.GetChisquare() / Float_t(npointsT);
+ Double_t polz1c = fitterTC.GetParameter(2);
+ Double_t polz0c = polz1c * xref2;
+ Double_t aC = fitterTC.GetParameter(0);
+ Double_t bC = fitterTC.GetParameter(1);
+ Double_t cC = aC / TMath::Sqrt(bC * bC + 1.0); // Curvature
+ Double_t aR = fitterT2.GetParameter(0);
+ Double_t bR = fitterT2.GetParameter(1);
+ Double_t dR = fitterT2.GetParameter(2);
+ Double_t cR = 1.0 + bR*bR - dR*aR;
+ Double_t dca = 0.0;
+ if (cR > 0.0) {
+ dca = -dR / (TMath::Sqrt(1.0 + bR*bR - dR*aR) + TMath::Sqrt(1.0 + bR*bR));
+ cR = aR / TMath::Sqrt(cR);
+ }
+
+ Double_t chi2ZT2 = 0.0;
+ Double_t chi2ZTC = 0.0;
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ if (cseed[iLayer].IsOK()) {
+ Double_t zT2 = rpolz0 + rpolz1 * (xcl[iLayer] - xref2);
+ Double_t zTC = polz0c + polz1c * (xcl[iLayer] - xref2);
+ chi2ZT2 += TMath::Abs(cseed[iLayer].GetMeanz() - zT2);
+ chi2ZTC += TMath::Abs(cseed[iLayer].GetMeanz() - zTC);
+ }
+ }
+ chi2ZT2 /= TMath::Max((nlayers - 3.0),1.0);
+ chi2ZTC /= TMath::Max((nlayers - 3.0),1.0);
+
+ AliTRDseed::FitRiemanTilt(cseed,kTRUE);
+ Float_t sumdaf = 0.0;
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ if (cseed[iLayer].IsOK()) {
+ sumdaf += TMath::Abs((cseed[iLayer].GetYfit(1) - cseed[iLayer].GetYref(1))
+ / cseed[iLayer].GetSigmaY2());
+ }
+ }
+ sumdaf /= Float_t (nlayers - 2.0);
+
+ //
+ // Likelihoods for full track
+ //
+ Double_t likezf = TMath::Exp(-chi2ZF * 0.14);
+ Double_t likechi2C = TMath::Exp(-chi2TC * 0.677);
+ Double_t likechi2TR = TMath::Exp(-chi2TR * 0.78);
+ Double_t likeaf = TMath::Exp(-sumdaf * 3.23);
+ seedquality2[registered] = likezf * likechi2TR * likeaf;
+
+ // Still needed ????
+// Bool_t isGold = kFALSE;
+//
+// if (nlayers == 6 && TMath::Log(0.000000001+seedquality2[index])<-5.) isGold =kTRUE; // gold
+// if (nlayers == findable && TMath::Log(0.000000001+seedquality2[index])<-4.) isGold =kTRUE; // gold
+// if (isGold &&nusedf<10){
+// for (Int_t jLayer=0;jLayer<6;jLayer++){
+// if ( seed[index][jLayer].IsOK()&&TMath::Abs(seed[index][jLayer].fYfit[1]-seed[index][jLayer].fYfit[1])<0.1)
+// seed[index][jLayer].UseClusters(); //sign gold
+// }
+// }
+
+ Int_t index0 = 0;
+ if (!cseed[0].IsOK()) {
+ index0 = 1;
+ if (!cseed[1].IsOK()) {
+ index0 = 2;
+ }
+ }
+ seedparams[registered][0] = cseed[index0].GetX0();
+ seedparams[registered][1] = cseed[index0].GetYref(0);
+ seedparams[registered][2] = cseed[index0].GetZref(0);
+ seedparams[registered][5] = cR;
+ seedparams[registered][3] = cseed[index0].GetX0() * cR - TMath::Sin(TMath::ATan(cseed[0].GetYref(1)));
+ seedparams[registered][4] = cseed[index0].GetZref(1)
+ / TMath::Sqrt(1.0 + cseed[index0].GetYref(1) * cseed[index0].GetYref(1));
+ seedparams[registered][6] = ns;
+
+ Int_t labels[12];
+ Int_t outlab[24];
+ Int_t nlab = 0;
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ if (!cseed[iLayer].IsOK()) {
+ continue;
+ }
+ if (cseed[iLayer].GetLabels(0) >= 0) {
+ labels[nlab] = cseed[iLayer].GetLabels(0);
+ nlab++;
+ }
+ if (cseed[iLayer].GetLabels(1) >= 0) {
+ labels[nlab] = cseed[iLayer].GetLabels(1);
+ nlab++;
+ }
+ }
+ Freq(nlab,labels,outlab,kFALSE);
+ Int_t label = outlab[0];
+ Int_t frequency = outlab[1];
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ cseed[iLayer].SetFreq(frequency);
+ cseed[iLayer].SetC(cR);
+ cseed[iLayer].SetCC(cC);
+ cseed[iLayer].SetChi2(chi2TR);
+ cseed[iLayer].SetChi2Z(chi2ZF);
+ }
+
+ // Debugging print
+ if (1 || (!isFake)) {
+ Float_t zvertex = GetZ();
+ TTreeSRedirector &cstream = *fDebugStreamer;
+ if (AliTRDReconstructor::StreamLevel() > 0) {
+ cstream << "Seeds1"
+ << "isFake=" << isFake
+ << "Vertex=" << zvertex
+ << "Rieman2.=" << &rieman2
+ << "Rieman.=" << &rieman
+ << "Xref=" << xref
+ << "X0=" << xcl[0]
+ << "X1=" << xcl[1]
+ << "X2=" << xcl[2]
+ << "X3=" << xcl[3]
+ << "X4=" << xcl[4]
+ << "X5=" << xcl[5]
+ << "Chi2R=" << chi2R
+ << "Chi2Z=" << chi2Z
+ << "Chi2RF=" << chi2RF // Chi2 of trackletes on full track
+ << "Chi2ZF=" << chi2ZF // Chi2 z on tracklets on full track
+ << "Chi2ZT2=" << chi2ZT2 // Chi2 z on tracklets on full track - rieman tilt
+ << "Chi2ZTC=" << chi2ZTC // Chi2 z on tracklets on full track - rieman tilt const
+ << "Chi2TR=" << chi2TR // Chi2 without vertex constrain
+ << "Chi2TC=" << chi2TC // Chi2 with vertex constrain
+ << "C=" << curv // Non constrained - no tilt correction
+ << "DR=" << dR // DR parameter - tilt correction
+ << "DCA=" << dca // DCA - tilt correction
+ << "CR=" << cR // Non constrained curvature - tilt correction
+ << "CC=" << cC // Constrained curvature
+ << "Polz0=" << polz0c
+ << "Polz1=" << polz1c
+ << "RPolz0=" << rpolz0
+ << "RPolz1=" << rpolz1
+ << "Ncl=" << nclusters
+ << "Nlayers=" << nlayers
+ << "NUsedS=" << nusedCl
+ << "NUsed=" << nusedf
+ << "Findable=" << findable
+ << "Like=" << like
+ << "LikePrim=" << likePrim
+ << "Likechi2C=" << likechi2C
+ << "Likechi2TR=" << likechi2TR
+ << "Likezf=" << likezf
+ << "LikeF=" << seedquality2[registered]
+ << "S0.=" << &cseed[0]
+ << "S1.=" << &cseed[1]
+ << "S2.=" << &cseed[2]
+ << "S3.=" << &cseed[3]
+ << "S4.=" << &cseed[4]
+ << "S5.=" << &cseed[5]
+ << "SB0.=" << &seedb[0]
+ << "SB1.=" << &seedb[1]
+ << "SB2.=" << &seedb[2]
+ << "SB3.=" << &seedb[3]
+ << "SB4.=" << &seedb[4]
+ << "SB5.=" << &seedb[5]
+ << "Label=" << label
+ << "Freq=" << frequency
+ << "sLayer=" << sLayer
+ << "\n";
+ }
+ }
+
+ if (registered<kMaxSeed - 1) {
+ registered++;
+ cseed = seed[registered];
+ }
+
+ } // End of loop over layer 1
+
+ } // End of loop over layer 0
+
+ } // End of loop over layer 3
+
+ } // End of loop over seeding time bins