//----------------------------------------------------------- // File and Version Information: // // // Description: // Implementation of class FieldCylGrid // see FieldCylGrid.h for details // // Environment: // Software developed for the PANDA Detector at FAIR. // // Author List: // Cristoforo Simonetto TUM (original author) // Felix Boehmer TUM // //----------------------------------------------------------- // This Class' Header ------------------ #include "PndTpcFieldCylGrid.h" // Collaborating Class Headers -------- #include #include "TError.h" // Class Member definitions ----------- template PndTpcFieldCylGrid::PndTpcFieldCylGrid(const t& nominalValue, const double MinR, const double MinZ, const double SpacingR, const double SpacingZ, const TVector3& RelPosition, std::vector*>* pGrid) : PndTpcAbsField(nominalValue, RelPosition), fpGrid(pGrid), fminX(MinR), fminZ(MinZ), fspacingX(SpacingR), fspacingZ(SpacingZ) { evalMaxPoint(); } template PndTpcFieldCylGrid::PndTpcFieldCylGrid(const PndTpcFieldCylGrid& aFCG): PndTpcAbsField(aFCG.nominal(), aFCG.relPosition()) { fpGrid = new std::vector*>(*aFCG.fpGrid); fminX = aFCG.minR(); fminZ = aFCG.minZ(); fspacingX = aFCG.spacingR(); fspacingZ = aFCG.spacingZ(); evalMaxPoint(); } template PndTpcFieldCylGrid::~PndTpcFieldCylGrid() { deleteGrid(); //PndTpcFieldCylGrid has ownership of this pointer } // Operators ---------------------------------------------------------------- // template // PndTpcFieldCylGrid::PndTpcFieldCylGrid& // PndTpcFieldCylGrid::operator=(const PndTpcFieldCylGrid& aFCG) // { // delete fpGrid; // PndTpcAbsField::operator=(aFCG); // // like the copy constructor // fpGrid = new std::vector*>(*aFCG.fpGrid); // fminX = aFCG.minR(); // fminZ = aFCG.minZ(); // fspacingX = aFCG.spacingR(); // fspacingZ = aFCG.spacingZ(); // evalMaxPoint(); // return(*this); // } template void PndTpcFieldCylGrid::print(std::ostream& s) const { s << "PndTpcFieldCylGrid\n" << "nominal="<nominal()<<"\n" << "scale=" <scale()<< "\n" << "minX="<nominal().X()<<", "<nominal().Y() <<", "<nominal().Z() << ")\n" << "scale=" <scale()<< "\n" << "minX="<nominal()); } TVector3 aPoint = point - this->relPosition(); // find grid point next to us double phi = aPoint.Phi(); aPoint.RotateZ(-phi); double difX = aPoint.X()-fminX; double difZ = aPoint.Z()-fminZ; int xIndex = (int)std::floor( difX / fspacingX ); int zIndex = (int)std::floor( difZ / fspacingZ ); //actual deviations from the grid-field's "center of mass" double dx = difX - (xIndex + 0.5)*fspacingX; double dz = difZ - (zIndex + 0.5)*fspacingZ; const t Value = startInterpolation(xIndex, zIndex, dx, dz); return (rotate(Value, phi)); } template t PndTpcFieldCylGrid::startInterpolation(int& xBin, int& zBin, double dx, double dz) const { //determine the grid rectangle aPoint lies in and define //the surrounding 4 rectangles counter-clockwise if(dx < 0) xBin--; if(dz < 0) zBin--; if(dx>=0 && dz>=0) return (interpolate(xBin, zBin, dx, dz)); if(dx>=0 && dz<0) return (interpolate(xBin, zBin, dx, dz+fspacingZ)); if(dx<0 && dz<0) return (interpolate(xBin, zBin, dx+fspacingX, dz+fspacingZ)); if(dx<0 && dz>=0) return (interpolate(xBin, zBin, dx+fspacingX, dz)); } template t PndTpcFieldCylGrid::interpolate(int& xBin, int& zBin, double fdx, double fdz) const { double dx = fdx; double dz = fdz; if (zBin<0) //catch the cases we are out of bound { zBin++; return (interpolate(xBin, zBin, dx, 0)); } if (zBin==(int)fpGrid->at(0)->size()-1) dz = 0; if (xBin<0) { xBin++; return (interpolate(xBin, zBin, 0, dz)); } if (xBin==(int)fpGrid->size()-1) dx = 0; t b1, b2, b3, b4; //the 4 surrounding fpGrid values double U = dx/fspacingX; //normalize to binWidth double T = dz/fspacingZ; b1 = *(fpGrid->at(xBin)->at(zBin)); //starting grid-bin, ok in any case if(dx==0 && dz==0) return b1; //no interpolation at all. if(dx==0) { b2 = *(fpGrid->at(xBin)->at(zBin+1)); return (1-T)*b1 + T*b2; } if(dz==0) { b4 = *(fpGrid->at(xBin+1)->at(zBin)); return (1-U)*b1 + U*b4; } //the general case, we are not at the boundaries of the grid b2 = *(fpGrid->at(xBin)->at(zBin+1)); b3 = *(fpGrid->at(xBin+1)->at(zBin+1)); b4 = *(fpGrid->at(xBin+1)->at(zBin)); return ((1-T)*(1-U)*b1 + T*(1-U)*b2 + T*U*b3 + (1-T)*U*b4); } template void PndTpcFieldCylGrid::deleteGrid() { if(fpGrid == 0) return; for(unsigned int i=0; isize(); i++) for(unsigned int j=0; jat(0)->size(); j++) delete fpGrid->at(i)->at(j); for(unsigned int i=0; isize(); i++) delete fpGrid->at(i); delete fpGrid; } template class PndTpcFieldCylGrid; template class PndTpcFieldCylGrid; //Update 29.06.07, fboehmer: Greatly improved interpolation