+
+ // draw hits
+
+ for( Int_t iRow=0; iRow<fSlice->Param().NRows(); iRow++ ){
+ const AliHLTTPCCARow &row = fSlice->Row(iRow);
+ for( Int_t ih=0; ih<row.NHits(); ih++ ){
+ DrawSliceHit( iRow, ih, color, width );
+ }
+ }
+}
+
+
+void AliHLTTPCCADisplay::DrawSliceLink( Int_t iRow, Int_t iHit, Int_t colorUp, Int_t colorDn, Int_t width )
+{
+ // draw link between clusters
+
+ if( !fPerf || !fGB) return;
+ AliHLTTPCCAGBTracker &tracker = *fGB;
+ if( width<0 ) width = 1.;
+ fLine.SetLineWidth( width );
+ Int_t colUp = colorUp>=0 ? colorUp :kMagenta;
+ Int_t colDn = colorDn>=0 ? colorDn :kBlack;
+ if( iRow<1 || iRow>=fSlice->Param().NRows()-1 ) return;
+
+ const AliHLTTPCCARow& row = fSlice->Row(iRow);
+ const AliHLTTPCCARow& rowUp = fSlice->Row(iRow+1);
+ const AliHLTTPCCARow& rowDn = fSlice->Row(iRow-1);
+
+ Int_t id = fSlice->HitInputIDs()[row.FirstHit()+iHit];
+ AliHLTTPCCAGBHit &h = tracker.Hits()[tracker.FirstSliceHit()[fSlice->Param().ISlice()]+id];
+ Short_t iUp = ((Short_t*)(fSlice->RowData() + row.FullOffset()))[row.FullLinkOffset()+iHit];
+ Short_t iDn = ((Short_t*)(fSlice->RowData() + row.FullOffset()))[row.FullLinkOffset()+row.NHits()+iHit];
+
+ if( iUp>=0){
+ Int_t id1 =fSlice->HitInputIDs()[rowUp.FirstHit()+iUp];
+ AliHLTTPCCAGBHit &h1 = tracker.Hits()[tracker.FirstSliceHit()[fSlice->Param().ISlice()]+id1];
+ Double_t vx, vy, vx1, vy1;
+ Slice2View( h.X(), h.Y(), &vx, &vy );
+ Slice2View( h1.X(), h1.Y(), &vx1, &vy1 );
+ fLine.SetLineColor( colUp );
+ fYX->cd();
+ fLine.DrawLine(vx-.1,vy,vx1-.1,vy1);
+ fZX->cd();
+ fLine.DrawLine(h.Z()-1.,vy,h1.Z()-1.,vy1);
+ }
+ if( iDn>=0){
+ Int_t id1 =fSlice->HitInputIDs()[rowDn.FirstHit()+iDn];
+ AliHLTTPCCAGBHit &h1 = tracker.Hits()[tracker.FirstSliceHit()[fSlice->Param().ISlice()]+id1];
+ Double_t vx, vy, vx1, vy1;
+ Slice2View( h.X(), h.Y(), &vx, &vy );
+ Slice2View( h1.X(), h1.Y(), &vx1, &vy1 );
+ fLine.SetLineColor( colDn );
+ fYX->cd();
+ fLine.DrawLine(vx+.1,vy,vx1+.1,vy1);
+ fZX->cd();
+ fLine.DrawLine(h.Z()+1.,vy,h1.Z()+1.,vy1);
+ }
+}
+
+
+void AliHLTTPCCADisplay::DrawSliceLinks( Int_t colorUp, Int_t colorDn, Int_t width )
+{
+ // draw links between clusters
+
+ for( Int_t iRow=1; iRow<fSlice->Param().NRows()-1; iRow++){
+ const AliHLTTPCCARow& row = fSlice->Row(iRow);
+ for( Int_t ih=0; ih<row.NHits(); ih++ ){
+ DrawSliceLink( iRow, ih, colorUp, colorDn, width );
+ }
+ }
+}
+
+
+
+Int_t AliHLTTPCCADisplay::GetTrackMC( const AliHLTTPCCADisplayTmpHit *vHits, Int_t NHits )
+{
+ // get MC label for the track
+
+ AliHLTTPCCAGBTracker &tracker = *fGB;
+
+ Int_t label = -1;
+ Double_t purity = 0;
+ Int_t *lb = new Int_t[NHits*3];
+ Int_t nla=0;
+ //std::cout<<"\n\nTrack hits mc: "<<std::endl;
+ for( Int_t ihit=0; ihit<NHits; ihit++){
+ AliHLTTPCCAGBHit &h = tracker.Hits()[vHits[ihit].ID()];
+ AliHLTTPCCAPerformance::AliHLTTPCCAHitLabel &l = fPerf->HitLabels()[h.ID()];
+ if(l.fLab[0]>=0 ) lb[nla++]= l.fLab[0];
+ if(l.fLab[1]>=0 ) lb[nla++]= l.fLab[1];
+ if(l.fLab[2]>=0 ) lb[nla++]= l.fLab[2];
+ //std::cout<<ihit<<": "<<l.fLab[0]<<" "<<l.fLab[1]<<" "<<l.fLab[2]<<std::endl;
+ }
+ sort( lb, lb+nla );
+ Int_t labmax = -1, labcur=-1, lmax = 0, lcurr=0, nh=0;
+ //std::cout<<"MC track IDs :"<<std::endl;
+ for( Int_t i=0; i<nla; i++ ){
+ if( lb[i]!=labcur ){
+ if( 0 && i>0 && lb[i-1]>=0 ){
+ AliHLTTPCCAMCTrack &mc = fPerf->MCTracks()[lb[i-1]];
+ std::cout<<lb[i-1]<<": nhits="<<nh<<", pdg="<< mc.PDG()<<", Pt="<<mc.Pt()<<", P="<<mc.P()
+ <<", par="<<mc.Par()[0]<<" "<<mc.Par()[1]<<" "<<mc.Par()[2]
+ <<" "<<mc.Par()[3]<<" "<<mc.Par()[4]<<" "<<mc.Par()[5]<<" "<<mc.Par()[6]<<std::endl;
+
+ }
+ nh=0;
+ if( labcur>=0 && lmax<lcurr ){
+ lmax = lcurr;
+ labmax = labcur;
+ }
+ labcur = lb[i];
+ lcurr = 0;
+ }
+ lcurr++;
+ nh++;
+ }
+ if( 0 && nla-1>0 && lb[nla-1]>=0 ){
+ AliHLTTPCCAMCTrack &mc = fPerf->MCTracks()[lb[nla-1]];
+ std::cout<<lb[nla-1]<<": nhits="<<nh<<", pdg="<< mc.PDG()<<", Pt="<<mc.Pt()<<", P="<<mc.P()
+ <<", par="<<mc.Par()[0]<<" "<<mc.Par()[1]<<" "<<mc.Par()[2]
+ <<" "<<mc.Par()[3]<<" "<<mc.Par()[4]<<" "<<mc.Par()[5]<<" "<<mc.Par()[6]<<std::endl;
+
+ }
+ if( labcur>=0 && lmax<lcurr ){
+ lmax = lcurr;
+ labmax = labcur;
+ }
+ lmax = 0;
+ for( Int_t ihit=0; ihit<NHits; ihit++){
+ AliHLTTPCCAGBHit &h = tracker.Hits()[vHits[ihit].ID()];
+ AliHLTTPCCAPerformance::AliHLTTPCCAHitLabel &l = fPerf->HitLabels()[h.ID()];
+ if( l.fLab[0] == labmax || l.fLab[1] == labmax || l.fLab[2] == labmax
+ ) lmax++;
+ }
+ label = labmax;
+ purity = ( (NHits>0) ?double(lmax)/double(NHits) :0 );
+ if( lb ) delete[] lb;
+ if( purity<.9 ) label = -1;
+ return label;
+}
+
+Bool_t AliHLTTPCCADisplay::DrawTrack( AliHLTTPCCATrackParam t, Double_t Alpha, const AliHLTTPCCADisplayTmpHit *vHits,
+ Int_t NHits, Int_t color, Int_t width, Bool_t pPoint )
+{
+ // draw track
+
+ if(NHits<2 ) return 0;
+
+ AliHLTTPCCAGBTracker &tracker = *fGB;
+ if( width<0 ) width = 2;
+
+ if(fDrawOnlyRef ){
+ Int_t lab = GetTrackMC(vHits, NHits);
+ if( lab<0 ) return 0;
+ AliHLTTPCCAMCTrack &mc = fPerf->MCTracks()[lab];
+ if(mc.P()<1) return 0;
+ }
+
+ if( color < 0 ){
+ //color = GetColorZ( (vz[0]+vz[mHits-1])/2. );
+ //color = GetColorK(t.GetKappa());
+ Int_t lab = GetTrackMC(vHits, NHits);
+ color = GetColor( lab +1 );
+ if( lab>=0 ){
+ AliHLTTPCCAMCTrack &mc = fPerf->MCTracks()[lab];
+ if( mc.P()>=1. ) color = kRed;
+ }
+ }
+
+ if( t.SinPhi()>.999 ) t.SetSinPhi( .999 );
+ else if( t.SinPhi()<-.999 ) t.SetSinPhi( -.999 );
+
+ // Int_t iSlice = fSlice->Param().ISlice();
+
+ //sort(vHits, vHits + NHits, AliHLTTPCCADisplayTmpHit::CompareHitZ );
+
+ Double_t vx[2000], vy[2000], vz[2000];
+ Int_t mHits = 0;
+
+ //Int_t oldSlice = -1;
+ Double_t alpha = ( TMath::Abs(Alpha+1)<1.e-4 ) ?fSlice->Param().Alpha() :Alpha;
+ AliHLTTPCCATrackParam tt = t;
+
+ for( Int_t iHit=0; iHit<NHits; iHit++ ){
+
+ AliHLTTPCCAGBHit &h = tracker.Hits()[vHits[iHit].ID()];
+
+ Double_t hCos = TMath::Cos( alpha - tracker.Slices()[h.ISlice()].Param().Alpha());
+ Double_t hSin = TMath::Sin( alpha - tracker.Slices()[h.ISlice()].Param().Alpha());
+ Double_t x0=h.X(), y0=h.Y(), z1=h.Z();
+ Double_t x1 = x0*hCos + y0*hSin;
+ Double_t y1 = y0*hCos - x0*hSin;
+
+ {
+ Double_t dx = x1-tt.X();
+ Double_t dy = y1-tt.Y();
+ if( dx*dx+dy*dy>1. ){
+ Double_t dalpha = TMath::ATan2( dy, dx );
+ if( tt.Rotate(dalpha ) ){
+ alpha+=dalpha;
+ hCos = TMath::Cos( alpha - tracker.Slices()[h.ISlice()].Param().Alpha());
+ hSin = TMath::Sin( alpha - tracker.Slices()[h.ISlice()].Param().Alpha());
+ x1 = x0*hCos + y0*hSin;
+ y1 = y0*hCos - x0*hSin;
+ }
+ }
+ }
+ SetSliceTransform( alpha );
+
+ //t.GetDCAPoint( x1, y1, z1, x1, y1, z1 );
+ std::cout<<"mark 3"<<std::endl;
+ Bool_t ok = tt.TransportToX(x1,.999);
+ std::cout<<"mark 4"<<std::endl;
+ if( 1||ok ){
+ x1 = tt.X();
+ y1 = tt.Y();
+ z1 = tt.Z();
+ }
+
+ Slice2View(x1, y1, &x1, &y1 );
+ vx[mHits] = x1;
+ vy[mHits] = y1;
+ vz[mHits] = z1;
+ mHits++;
+ for( int j=0; j<0; j++ ){
+ x0=h.X()+j; y0=h.Y(); z1=h.Z();
+ x1 = x0*hCos + y0*hSin;
+ y1 = y0*hCos - x0*hSin;
+ ok = tt.TransportToX(x1,.999);
+ if( ok ){
+ x1 = tt.X();
+ y1 = tt.Y();
+ z1 = tt.Z();
+ }
+
+ Slice2View(x1, y1, &x1, &y1 );
+ vx[mHits] = x1;
+ vy[mHits] = y1;
+ vz[mHits] = z1;
+ mHits++;
+ }
+ }
+ if( pPoint ){
+ Double_t x1=t.X(), y1=t.Y(), z1=t.Z();
+ Double_t a = ( TMath::Abs(Alpha+1)<1.e-4 ) ?fSlice->Param().Alpha() :Alpha;
+ SetSliceTransform( a );
+
+ Slice2View(x1, y1, &x1, &y1 );
+ Double_t dx = x1 - vx[0];
+ Double_t dy = y1 - vy[0];
+ //std::cout<<x1<<" "<<y1<<" "<<vx[0]<<" "<<vy[0]<<" "<<dx<<" "<<dy<<std::endl;
+ Double_t d0 = dx*dx + dy*dy;
+ dx = x1 - vx[mHits-1];
+ dy = y1 - vy[mHits-1];
+ //std::cout<<x1<<" "<<y1<<" "<<vx[mHits-1]<<" "<<vy[mHits-1]<<" "<<dx<<" "<<dy<<std::endl;
+ Double_t d1 = dx*dx + dy*dy;
+ //std::cout<<"d0, d1="<<d0<<" "<<d1<<std::endl;
+ if( d1<d0 ){
+ vx[mHits] = x1;
+ vy[mHits] = y1;
+ vz[mHits] = z1;
+ mHits++;
+ } else {
+ for( Int_t i = mHits; i>0; i-- ){
+ vx[i] = vx[i-1];
+ vy[i] = vy[i-1];
+ vz[i] = vz[i-1];
+ }
+ vx[0] = x1;
+ vy[0] = y1;
+ vz[0] = z1;
+ mHits++;
+ }
+ }
+
+