//-*- Mode: C++ -*- // ***************************************************************************** // * // @Autors: I.Kulakov; M.Zyzak; I.Kisel * // @e-mail: I.Kulakov@gsi.de; M.Zyzak@gsi.de; I.Kisel@compeng.uni-frankfurt.de * // * // ***************************************************************************** #ifndef ITSCAHITSV_H #define ITSCAHITSV_H #include using std::vector; // #include "ITSCAStationArray.h" #include "AliHLTTPCCAGBHit.h" #include "ITSCATES.h" #include "ITSCAHits.h" class ITSCAHitV { public: ITSCAHitV(): fIStation(-1), fId(Vc::Zero), fX0(Vc::Zero), fX1(Vc::Zero), fX2(Vc::Zero), fErr2X1(Vc::Zero), fErr2X2(Vc::Zero), fAngle(Vc::Zero), fIsUsed(false){} ITSCAHitV( const AliHLTTPCCAGBHit** hits, const ushort_v& ids, const sfloat_m& valid ); ITSCAHitV( const ITSCAHit* hits, const sfloat_m& valid ); sfloat_m IsValid() const { return fIStation >= 0; } char IStation() const { const sfloat_m v = IsValid(); assert(!v.isEmpty()); return fIStation[v.firstOne()]; } short_v IStations() const { return fIStation; } // is not needed by tracker ushort_v Id() const { return fId; }; sfloat_v X0() const { return fX0; } sfloat_v X1() const { return fX1; } sfloat_v X2() const { return fX2; } sfloat_v FStrip() const { return GetStripsValue( fFStripP ); }; sfloat_v BStrip() const { return GetStripsValue( fBStripP ); }; sfloat_v Err2X1() const { return fErr2X1; } sfloat_v Err2X2() const { return fErr2X2; } sfloat_v Angle() const { return fAngle; } private: sfloat_v GetStripsValue( ITSCAStrip* const strip[sfloat_v::Size] ) const { sfloat_v::Memory r; foreach_bit(unsigned short iV, IsValid()) { r[iV] = *(strip[iV]); } return sfloat_v(r); }; // sfloat_m GetStripsIsUsed( ITSCAStrip* const strip[sfloat_v::Size] ) const { // sfloat_v::Memory r; // r = sfloat_v(Vc::Zero); // foreach_bit(unsigned short iV, IsValid()) { // r[iV] = int(strip[iV]->IsUsed()); // } // return sfloat_v(r) == Vc::One; // }; ITSCAStrip* fFStripP[sfloat_v::Size]; // TODO simdize ITSCAStrip* fBStripP[sfloat_v::Size]; short_v fIStation; ushort_v fId; // index of hits in an input array sfloat_v fX0, fX1, fX2; // local coordinates. X0 is normal to module, X2 is paralel to magnetic field sfloat_v fErr2X1, fErr2X2; // errors squared sfloat_v fAngle; // direction of hit station. Angle between normal and vertical axis. This angle defines local CS of the hit sfloat_m fIsUsed; }; template class ITSCAElementsOnStation; template<> class ITSCAElementsOnStation: public vector { public: char& IStation() { return fISta; } const char& IStation() const { return fISta; } private: char fISta; }; class ITSCAHitsV { // same as in ITSCAStationArray public: typedef ITSCAHitV T; ITSCAElementsOnStation& OnStation(char i) { assert((unsigned char)i& OnStation(char i) const { assert((unsigned char)i& operator[](char i) { assert((unsigned char)i < fElement.size() ); return fElement[i]; } const ITSCAElementsOnStation& operator[](char i) const { assert((unsigned char)i > fElement; // hits on stations }; inline ITSCAHitV::ITSCAHitV( const AliHLTTPCCAGBHit** hits, const ushort_v& ids, const sfloat_m& valid ) :fId(ids), fIsUsed(false) { short_v::Memory mIStation; mIStation = short_v( -1 ); sfloat_v::Memory mX1, mX2, mX0; sfloat_v::Memory mErr2X1, mErr2X2; sfloat_v::Memory mAlpha; foreach_bit(unsigned short iV, valid) { const AliHLTTPCCAGBHit& h = *(hits[iV]); mIStation[iV] = h.IRow(); h.GetLocalX0X1X2( mX0[iV], mX1[iV], mX2[iV] ); mErr2X1[iV] = h.Err2X1(); mErr2X2[iV] = h.Err2X2(); mAlpha[iV] = h.Angle(); fFStripP[iV] = h.FStripP(); fBStripP[iV] = h.BStripP(); } fIStation = short_v(mIStation); fX1 = sfloat_v(mX1); fX2 = sfloat_v(mX2); fX0 = sfloat_v(mX0); fErr2X1 = sfloat_v(mErr2X1); fErr2X2 = sfloat_v(mErr2X2); fAngle = sfloat_v(mAlpha); } inline ITSCAHitV::ITSCAHitV( const ITSCAHit* hits, const sfloat_m& valid ) { short_v::Memory mIStation; mIStation = short_v( -1 ); ushort_v::Memory mId; sfloat_v::Memory mX1, mX2, mX0; sfloat_v::Memory mErr2X1, mErr2X2; sfloat_v::Memory mAlpha; sfloat_v::Memory mIsUsed; foreach_bit(unsigned short iV, valid) { const ITSCAHit& h = hits[iV]; mId[iV] = h.Id(); mIStation[iV] = h.IStation(); mX1[iV] = h.X1(); mX2[iV] = h.X2(); mX0[iV] = h.X0(); mErr2X1[iV] = h.Err2X1(); mErr2X2[iV] = h.Err2X2(); mAlpha[iV] = h.Angle(); fFStripP[iV] = h.FStripP(); fBStripP[iV] = h.BStripP(); mIsUsed[iV] = h.IsUsed() ? 1.f : 0.f; } fIStation = short_v(mIStation); fX1 = sfloat_v(mX1); fX2 = sfloat_v(mX2); fX0 = sfloat_v(mX0); fErr2X1 = sfloat_v(mErr2X1); fErr2X2 = sfloat_v(mErr2X2); fAngle = sfloat_v(mAlpha); fIsUsed = (sfloat_v(mIsUsed) == 1.f); } inline ITSCAHitsV::ITSCAHitsV( const ITSCAHits& hits ) { fElement.resize( hits.NStations() ); for( int i = 0; i < hits.NStations(); ++i ) { fElement[i].IStation() = i; const ITSCAElementsOnStation& hs = hits.OnStation(i); for( unsigned int iH = 0; iH < hs.size(); iH += sfloat_v::Size ) { sfloat_m valid = static_cast(ushort_v::IndexesFromZero() < ushort_v(hs.size() - iH) ); fElement[i].push_back( ITSCAHitV( &(hs[iH]), valid ) ); } } } inline void ITSCAHitsV::Clean() { // remove used hits TODO // for( unsigned int i = 0; i < fElement.size(); ++i ) { // ITSCAElementsOnStation& hits = fElement[i]; // ITSCAElementsOnStation tmp; // tmp.IStation() = i; // tmp.resize( hits.size() ); // for( unsigned int iH = 0; iH < hits.size(); ++iH ) { // if ( hits[iH].IsUsed() ) continue; // tmp.push_back( hits[iH] ); // } // hits = tmp; // tmp.clear(); // } } #endif