/* Copyright (C) 2009 Matthias Kretz This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) version 3. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define USE_ARBB #include "Reconstructor.h" #include "AliHLTTPCCATracker.h" #include "AliHLTTPCCARow.h" #include "AliHLTTPCCANeighboursFinder.h" #include "AliHLTTPCCANeighboursCleaner.h" #include "AliHLTTPCCAStartHitsFinder.h" #include "AliHLTTPCCATrackletConstructor.h" #include "AliHLTTPCCATrackletSelector.h" #include "AliHLTTPCCASliceOutput.h" #include "AliHLTTPCCAParamArBB.h" #include "TStopwatch.h" #include "tsc.h" #include using arbb::value; #ifdef DRAW3 #include "AliHLTTPCCADisplay.h" #include "TApplication.h" #endif //DRAW3 #ifdef DRAW2 #include "AliHLTTPCCADisplay.h" #include "TApplication.h" #endif //DRAW2 #ifdef DRAW #include "AliHLTTPCCADisplay.h" #include "TApplication.h" #endif //DRAW #ifdef DUMP_LINKS #include extern void dumpLinksFile( std::fstream &file, int sliceNumber ); template static inline UInt_t nextMultipleOf( UInt_t value ) { STATIC_ASSERT( ( X & ( X - 1 ) ) == 0, X_needs_to_be_a_multiple_of_2 ); const Int_t offset = value & ( X - 1 ); if ( offset > 0 ) { return value + X - offset; } return value; } #include #include #endif #ifdef DUMP_TC_OUTPUT #include #include #include #include "AliHLTTPCCATracklet.h" extern void dumpTrackletconstructionFile( std::fstream &file, int sliceNumber ); #endif // reconstruct tracks in slice #undef USE_TIMERS // TODO void AliHLTTPCCATracker::Reconstructor::execute_ArBB( nested_my& rows_ArBB, const dense& rowsX, const AliHLTTPCCAParamArBB& sliceParam, AliHLTTPCCATrack_ArBB& tracks, AliHLTTPCCAStartHitId_ArBB::TDense<1>& startHits_ArBB ) { dense rowsNHits = rows_ArBB.lengths(); // unset all links { AliHLTTPCCARowHit::TDense<1> rows_tmp = rows_ArBB.flatten(); const dense minusOne = fill( -1, rows_tmp.length() ); rows_tmp.SetLinkUp( minusOne ); rows_tmp.SetLinkDn( minusOne ); rows_ArBB = reshape_nested_lengths_my( rows_tmp, rowsNHits ); } for (int iter = 0; iter < 2; iter++) { #ifdef USE_TIMERS timer.Start(); tsc.Start(); #endif // USE_TIMERS AliHLTTPCCATracker::NeighboursFinder neighboursFinder( iter, rows_ArBB, rowsX ); neighboursFinder.execute(); #ifdef USE_TIMERS tsc.Stop(); timer.Stop(); d->fTimers[0] += timer.RealTime(); d->fTimers[4] += tsc.Cycles(); #endif // USE_TIMERS #ifdef USE_TIMERS timer.Start(); #endif // USE_TIMERS AliHLTTPCCANeighboursCleaner neighboursCleaner( rows_ArBB ); neighboursCleaner.run(); #ifdef USE_TIMERS timer.Stop(); d->fTimers[10] += timer.RealTime(); #endif // USE_TIMERS #ifdef USE_TIMERS timer.Start(); #endif // USE_TIMERS AliHLTTPCCAStartHitsFinder startHitsFinder( rows_ArBB, startHits_ArBB ); startHitsFinder.run( iter ); #ifdef USE_TIMERS timer.Stop(); d->fTimers[3] += timer.RealTime(); #endif // USE_TIMERS } // for iter #ifdef USE_TIMERS timer.Start(); tsc.Start(); #endif // USE_TIMERS #ifdef USE_ARBB // save found start hits info const THitI_ArBB NTracklets = startHits_ArBB.length(); _if ( NTracklets > 0 ) { startHits_ArBB.Sort(); } _end_if; #endif // USE_ARBB AliHLTTPCCATrackletVector_ArBB trackletVectors_ArBB( NTracklets ); _if ( NTracklets > 0) { AliHLTTPCCATrackletConstructor trackletConstructor( rows_ArBB, rowsX, sliceParam, startHits_ArBB, trackletVectors_ArBB ); trackletConstructor.run(); } _end_if; #ifdef USE_TIMERS tsc.Stop(); timer.Stop(); d->fTimers[1] = timer.RealTime(); d->fTimers[6] = tsc.Cycles(); #endif // USE_TIMERS #ifdef USE_TIMERS timer.Start(); tsc.Start(); #endif // USE_TIMERS _if ( NTracklets > 0 ) { AliHLTTPCCATrackletSelector trackletSelector( rows_ArBB, trackletVectors_ArBB, tracks ); trackletSelector.run(); } _end_if; } // void AliHLTTPCCATracker::execute_ArBB #ifdef USE_TBB tbb::task *AliHLTTPCCATracker::Reconstructor::execute() #else //USE_TBB int AliHLTTPCCATracker::Reconstructor::execute() #endif //USE_TBB { d->fTimers[0] = 0; // NeighboursFinder d->fTimers[1] = 0; // TrackletConstructor d->fTimers[2] = 0; // TrackletSelector d->fTimers[3] = 0; // StartHitsFinder d->fTimers[4] = 0; // NeighboursFinder cycles d->fTimers[5] = 0; // write output d->fTimers[6] = 0; // TrackletConstructor cycles d->fTimers[7] = 0; // TrackletSelector cycles d->fTimers[10] = 0; // NeighboursCleaner d->fNTracklets = 0; if ( d->fData.NumberOfHits() < 1 ) { d->RecalculateTrackMemorySize( 1, 1 ); d->fTrackMemory = new char[d->fTrackMemorySize + 1600]; // TODO rid of 1600 d->SetPointersTracks( 1, 1 ); // set pointers for tracks d->fOutput->SetNTracks( 0 ); d->fOutput->SetNTrackClusters( 0 ); return 0; } #ifdef USE_TIMERS TStopwatch timer; TimeStampCounter tsc; #endif // USE_TIMERS // initialize the slice tracker's number of tracklets to 0 #ifdef USE_TBB CAMath::AtomicExch( d->NTracklets(), 0 ); #else //USE_TBB d->SetNTracklets(0); #endif //USE_TBB #ifndef NDEBUG // check of isUsed for ( int rowIndex = 0; rowIndex < d->Param().NRows(); ++rowIndex ) { const AliHLTTPCCARow &row = d->fData.Row( rowIndex ); const unsigned numberOfHits = row.NHits(); for ( unsigned int i = 0; i < numberOfHits; i += short_v::Size ) { const ushort_v hitIndexes = ushort_v( Vc::IndexesFromZero ) + i; const short_m validHitsMask = (hitIndexes < numberOfHits); const short_v isUsed = short_v( d->fData.HitDataIsUsed( row ), static_cast(hitIndexes), validHitsMask); ASSERT( ((isUsed == short_v( Vc::Zero )) && validHitsMask) == validHitsMask, isUsed << validHitsMask); } } #endif // NDEBUG d->fData.ClearHitWeights(); // get rows hits const int NRows = AliHLTTPCCAParameters::NumberOfRows; short *nHits = new short[NRows]; for (int iR = 0; iR < NRows; iR++) { const AliHLTTPCCARow &row = d->fData.Row( iR ); nHits[(iR)] = row.NHits(); } dense rowsNHits; bind( rowsNHits, nHits, NRows ); // get rows info dense rowsX; bind( rowsX, const_cast(d->fData.RowX()), NRows ); int nAllHits = 0; for (int i = 0; i < AliHLTTPCCAParameters::NumberOfRows; i++) { const AliHLTTPCCARow &row = d->fData.Row( i ); nAllHits += row.NHits(); } dense row_tmp; const std::size_t pitchF = sizeof(float); const std::size_t pitchS = sizeof(short); const AliHLTTPCCARow &row = d->fData.Row( 0 ); bind( row_tmp, nAllHits, const_cast( d->fData.HitDataY(row) ), pitchF, const_cast( d->fData.HitDataZ(row) ), pitchF, const_cast( d->fData.HitLinkDownData(row) ), pitchS, const_cast( d->fData.HitLinkUpData(row) ), pitchS, const_cast( d->fData.HitDataIsUsed(row) ), pitchS, const_cast( d->fData.HitWeightData(row) ), pitchS ); nested_my rows_ArBB = reshape_nested_lengths_my( row_tmp, rowsNHits ); // slice param AliHLTTPCCAParamArBB sliceParam(d->Param()); // out data AliHLTTPCCAStartHitId_ArBB::TDense<1> startHits_ArBB; AliHLTTPCCATrack_ArBB tracks; #if 1 execute_ArBB( rows_ArBB, rowsX, sliceParam, tracks, startHits_ArBB ); #else call(execute_ArBB)( rows_ArBB, rowsX, sliceParam, tracks, startHits_ArBB ); #endif *d->NTracklets() = value(startHits_ArBB.length()); d->fTrackletVectors.Resize( ( d->fNTracklets + short_v::Size - 1 ) / short_v::Size); if (*d->NTracklets() > 0 ) { // save data arbb::const_range trRangeNHits = tracks.NumberOfHits().read_only_range(); const int nTracks = value(tracks.NumberOfHits().length()); d->fTracks.resize( nTracks ); d->fNTrackHits = 0; // fNumberOfTracks = nTracks + 1 - recycleBinsize; // TODO d->fNumberOfTracks = nTracks; for ( int iT = 0; iT < nTracks; ++iT ) { d->fTracks[iT] = new Track; AliHLTTPCCATrack &track = *d->fTracks[iT]; track.SetNumberOfHits(trRangeNHits[iT]); d->fNTrackHits += track.NumberOfHits(); for ( int k = 0; k < 5; ++k ) { track.Param().SetPar( k, value( tracks.Param().Par(k)[iT]) ); // TODO range } for ( int k = 0; k < 15; ++k ) track.Param().SetCov( k, value( tracks.Param().Cov(k)[iT]) ); track.Param().SetX ( value( tracks.Param().X()[iT] ) ); track.Param().SetSignCosPhi( value( tracks.Param().SignCosPhi()[iT] ) ); track.Param().SetChi2 ( value( tracks.Param().Chi2()[iT] ) ); track.Param().SetNDF ( value( tracks.Param().NDF()[iT] ) ); for ( int iH = 0; iH < track.NumberOfHits(); ++iH ) { track.HitIdArray()[iH].Set( value( tracks.HitId(iH).Row()[iT] ), value( tracks.HitId(iH).Hit()[iT] ) ); } // iH } // iT } else { d->fNTrackHits = 0; d->fTracks.resize( 0 ); d->fNumberOfTracks = 0; } #ifdef USE_TIMERS tsc.Stop(); timer.Stop(); d->fTimers[2] = timer.RealTime(); d->fTimers[7] = tsc.Cycles(); #endif // USE_TIMERS { d->RecalculateTrackMemorySize( d->fNTracklets, d->fNTrackHits ); // to calculate the size d->fTrackMemory = new char[d->fTrackMemorySize + 1600]; // TODO rid of 1600 d->SetPointersTracks( d->fNTracklets, d->fNTrackHits ); // set pointers for hits } //std::cout<<"Slice "<WriteOutput(); #ifdef USE_ARBB // save info for link performance for ( int i = 0; i < AliHLTTPCCAParameters::NumberOfRows; ++i ) { const AliHLTTPCCARow &row = d->fData.Row( i ); if ( value(rows_ArBB.lengths()[i] <= 0) ) { continue; } const AliHLTTPCCARowHit::TDense<1> row2 = rows_ArBB.segment(i); for ( int hit = 0; hit < row.NHits(); ++hit ) { const_cast(d->fData.HitLinkUpData( row ))[hit] = value(row2.LinkUp()[hit]); } } if( *d->NTracklets() > 0 ){ // save found start hits info AliHLTTPCCAStartHitId *const startHits = d->TrackletStartHits();// + *d->NTracklets(); // room for new start hits arbb::const_range rowRange = startHits_ArBB.Row().read_only_range(); arbb::const_range hitRange = startHits_ArBB.Hit().read_only_range(); arbb::const_range lengthRange = startHits_ArBB.Length().read_only_range(); for( int i = 0; i < *d->NTracklets(); ++i ) { // TODO hitsStartOffset startHits[i].fRow = (rowRange[i]); startHits[i].fHit = (hitRange[i]); startHits[i].fLength = (lengthRange[i]); } } #endif // USE_ARBB return 0; }