#ifndef L1HitArea_H #define L1HitArea_H #include "L1Grid.h" #include "CbmL1Def.h" struct L1Grid; class L1Row; class L1SliceData; class L1HitArea { public: L1HitArea( const L1Grid & grid, float y, float z, float dy, float dz ); /** * look up the next hit in the requested area. * Sets h to the coordinates and returns the index for the hit data */ bool GetNext( THitI& i ); protected: const L1Grid &fGrid; unsigned short fBZmax; // maximal Z bin index unsigned short fWidthBinsY; // Y distance of bin indexes unsigned int fFirstBinCurZLine; // minimum index for unsigned short fIz; // current Z bin index (incremented while iterating) THitI fHitYlst; // last possible hit index in current z-line THitI fIh; // hit index iterating inside the bins int fNy; // Number of bins in Y direction }; inline L1HitArea::L1HitArea( const L1Grid & grid, float y, float z, float dy, float dz ) : fGrid( grid ), fHitYlst( 0 ), fIh( 0 ), fNy( fGrid.Ny() ) { const float minY = y - dy; const float maxY = y + dy; const float minZ = z - dz; const float maxZ = z + dz; unsigned short bYmin, bZmin, bYmax; // boundary bin indexes fGrid.GetBinBounded( minY, minZ, bYmin, bZmin ); fGrid.GetBinBounded( maxY, maxZ, bYmax, fBZmax ); fWidthBinsY = ( bYmax - bYmin + 1 ); // bin index span in y direction fFirstBinCurZLine = ( bZmin * fNy + bYmin ); // same as grid.GetBin(fMinY, fMinZ), i.e. the smallest bin index of interest // fFirstBinCurZLine + fWidthBinsY - 1 then is the largest bin index of interest with the same Z // fGrid.GetBinBounds( fFirstBinCurZLine, y, dy, z, dz ); fIz = bZmin; fIh = fGrid.FirstHitInBin( fFirstBinCurZLine ); fHitYlst = fGrid.FirstHitInBin( fFirstBinCurZLine + fWidthBinsY ); // const unsigned int hitLst = fGrid.FirstHitInBin( fBZmax * fNy + bZmin + 1 ); // cout << fIh << " " << hitLst << endl; // if ( fIh >= hitLst ) fIz = fBZmax + 1; // finish area in one step // cout // << fBZmax << " " << fWidthBinsY << " " << fFirstBinCurZLine << " " << fIz << " " << fHitYlst << " " << fIh << endl; // dbg // << "HitArea created:\n" // << y << " " << z << endl // << "bYmin: " << bYmin << "\n" // << "bZmin: " << bZmin << "\n" // << "bYmax: " << bYmax << "\n" // << "fBZmax: " << fBZmax << "\n" // << "fWidthBinsY: " << fWidthBinsY << "\n" // << "fFirstBinCurZLine: " << fFirstBinCurZLine << "\n" // << "fIz: " << fIz << "\n" // << "fHitYlst: " << fHitYlst << "\n" // << "fIh: " << fIh << "\n" // << "fNy: " << fNy << "\n" // << "Nz " << fGrid.Nz() << std::endl; L1_ASSERT ( fFirstBinCurZLine + fWidthBinsY < fGrid.N()+1, fFirstBinCurZLine + fWidthBinsY << " < " << fGrid.N()); } inline bool L1HitArea::GetNext( THitI& i ) { bool yIndexOutOfRange = fIh >= fHitYlst; // current y is not in the area bool nextZIndexOutOfRange = (fIz >= fBZmax); // there isn't any new z-line if ( yIndexOutOfRange && nextZIndexOutOfRange ) { // all iterators are over the end return false; } // at least one entry in the vector has (fIh >= fHitYlst && fIz < fBZmax) bool needNextZ = yIndexOutOfRange && !nextZIndexOutOfRange; // skip as long as fIh is outside of the interesting bin y-index while ( ISLIKELY( needNextZ ) ) { //ISLIKELY to speed the programm and optimise the use of registers fIz++; // get new z-line // num++; // get next hit fFirstBinCurZLine += fNy; fIh = fGrid.FirstHitInBin( fFirstBinCurZLine ); // get first hit in cell, if z-line is new fHitYlst = fGrid.FirstHitInBin( fFirstBinCurZLine + fWidthBinsY ); yIndexOutOfRange = fIh >= fHitYlst; nextZIndexOutOfRange = (fIz >= fBZmax); needNextZ = yIndexOutOfRange && !nextZIndexOutOfRange; } //cout<>k; fIz = bZmin; fIt = bTmin; fIh = fGrid.FirstHitInBin( fFirstBinCurZLine ); // cout<= hitLst ) fIz = fBZmax + 1; // finish area in one step // cout // << fBZmax << " " << fWidthBinsY << " " << fFirstBinCurZLine << " " << fIz << " " << fHitYlst << " " << fIh << endl; // dbg // << "HitArea created:\n" // << y << " " << z << endl // << "bYmin: " << bYmin << "\n" // << "bZmin: " << bZmin << "\n" // << "bYmax: " << bYmax << "\n" // << "fBZmax: " << fBZmax << "\n" // << "fWidthBinsY: " << fWidthBinsY << "\n" // << "fFirstBinCurZLine: " << fFirstBinCurZLine << "\n" // << "fIz: " << fIz << "\n" // << "fHitYlst: " << fHitYlst << "\n" // << "fIh: " << fIh << "\n" // << "fNy: " << fNy << "\n" // << "Nz " << fGrid.Nz() << std::endl; L1_ASSERT ( fFirstBinCurZLine + fWidthBinsY < fGrid.N()+1, fFirstBinCurZLine + fWidthBinsY << " < " << fGrid.N()); } inline bool L1HitAreaTime::GetNext( THitI& i ) { bool yIndexOutOfRange = fIh >= fHitYlst; // current y is not in the area bool nextZIndexOutOfRange = (fIz >= fBZmax); // there isn't any new z-line bool nextTIndexOutOfRange = (fIt >= fBTmax); // there isn't any new z-line // cout<= fHitYlst && fIz < fBZmax) bool needNextZ = yIndexOutOfRange && !nextZIndexOutOfRange; bool needNextT = yIndexOutOfRange && nextZIndexOutOfRange && !nextTIndexOutOfRange; while ( ISLIKELY (( needNextZ ) ||( needNextT ))) { //ISLIKELY to speed the programm and optimise the use of registers if (needNextT) { fIt++; //fIndZmin+= fNy*fNz; fIz = fBZmin; //fBZmax+= fNy*fNz; fFirstBinCurZLine = (fIt * fNy * fNz + fBZmin * fNy + fBYmin ); fIh = fGrid.FirstHitInBin( fFirstBinCurZLine ); // get first hit in cell, if z-line is new fHitYlst = fGrid.FirstHitInBin( fFirstBinCurZLine + fWidthBinsY ); } else { // yIndexOutOfRange = fIh >= fHitYlst; fIz++; // get new z-line // num++; // get next hit fFirstBinCurZLine += fNy; fIh = fGrid.FirstHitInBin( fFirstBinCurZLine ); // get first hit in cell, if z-line is new fHitYlst = fGrid.FirstHitInBin( fFirstBinCurZLine + fWidthBinsY ); // cout<= fHitYlst; nextZIndexOutOfRange = (fIz >= fBZmax); needNextZ = yIndexOutOfRange && !nextZIndexOutOfRange; nextTIndexOutOfRange = (fIt >= fBTmax); //cout<