/* Copyright 2008-2010, Technische Universitaet Muenchen, Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch This file is part of GENFIT. GENFIT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GENFIT 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GENFIT. If not, see . */ #include "MeasurementCreator.h" #include #include #include #include #include #include #include #include #include #include namespace genfit { MeasurementCreator::MeasurementCreator() : trackModel_(NULL), resolution_(0.01), resolutionWire_(0.1), outlierProb_(0), outlierRange_(2), thetaDetPlane_(90), phiDetPlane_(0), wireCounter_(0), wireDir_(0.,0.,1.), minDrift_(0), maxDrift_(2), idealLRResolution_(true), useSkew_(false), skewAngle_(5), nSuperLayer_(5), measurementCounter_(0), debug_(false) { ; } std::vector MeasurementCreator::create(eMeasurementType type, double tracklength, bool& outlier, int& lr) { outlier = false; lr = 0; std::vector retVal; genfit::AbsMeasurement* measurement; TVector3 point, dir; trackModel_->getPosDir(tracklength, point, dir); TVector3 planeNorm(dir); planeNorm.SetTheta(thetaDetPlane_*TMath::Pi()/180); planeNorm.SetPhi(planeNorm.Phi()+phiDetPlane_); static const TVector3 z(0,0,1); static const TVector3 x(1,0,0); TVector3 currentWireDir(wireDir_); TVector3 wirePerp; if (type == Wire || type == WirePoint){ // skew layers if (useSkew_ && (int)((double)wireCounter_/(double)nSuperLayer_)%2 == 1) { TVector3 perp(wireDir_.Cross(dir)); if ((int)((double)wireCounter_/(double)nSuperLayer_)%4 == 1){ currentWireDir.Rotate(skewAngle_*TMath::Pi()/180, wireDir_.Cross(perp)); } else currentWireDir.Rotate(-skewAngle_*TMath::Pi()/180, wireDir_.Cross(perp)); } currentWireDir.SetMag(1.); // left/right lr = 1; wirePerp = dir.Cross(currentWireDir); if (gRandom->Uniform(-1,1) >= 0) { wirePerp *= -1.; lr = -1; } wirePerp.SetMag(gRandom->Uniform(minDrift_, maxDrift_)); } if (outlierProb_ > gRandom->Uniform(1.)) { outlier = true; if(debug_) std::cerr << "create outlier" << std::endl; } switch(type){ case Pixel: { if (debug_) std::cerr << "create PixHit" << std::endl; genfit::SharedPlanePtr plane(new genfit::DetPlane(point, planeNorm.Cross(z), (planeNorm.Cross(z)).Cross(planeNorm))); TVectorD hitCoords(2); if (outlier) { hitCoords(0) = gRandom->Uniform(-outlierRange_, outlierRange_); hitCoords(1) = gRandom->Uniform(-outlierRange_, outlierRange_); } else { hitCoords(0) = gRandom->Gaus(0,resolution_); hitCoords(1) = gRandom->Gaus(0,resolution_); } TMatrixDSym hitCov(2); hitCov(0,0) = resolution_*resolution_; hitCov(1,1) = resolution_*resolution_; measurement = new genfit::PlanarMeasurement(hitCoords, hitCov, int(type), measurementCounter_, nullptr); static_cast(measurement)->setPlane(plane, measurementCounter_); retVal.push_back(measurement); } break; case Spacepoint: { if (debug_) std::cerr << "create SpacepointHit" << std::endl; TVectorD hitCoords(3); if (outlier) { hitCoords(0) = gRandom->Uniform(point.X()-outlierRange_, point.X()+outlierRange_); hitCoords(1) = gRandom->Uniform(point.Y()-outlierRange_, point.Y()+outlierRange_); hitCoords(2) = gRandom->Uniform(point.Z()-outlierRange_, point.Z()+outlierRange_); } else { hitCoords(0) = gRandom->Gaus(point.X(),resolution_); hitCoords(1) = gRandom->Gaus(point.Y(),resolution_); hitCoords(2) = gRandom->Gaus(point.Z(),resolution_); } TMatrixDSym hitCov(3); hitCov(0,0) = resolution_*resolution_; hitCov(1,1) = resolution_*resolution_; hitCov(2,2) = resolution_*resolution_; measurement = new genfit::SpacepointMeasurement(hitCoords, hitCov, int(type), measurementCounter_, nullptr); retVal.push_back(measurement); } break; case ProlateSpacepoint: { if (debug_) std::cerr << "create ProlateSpacepointHit" << std::endl; TVectorD hitCoords(3); if (outlier) { hitCoords(0) = gRandom->Uniform(point.X()-outlierRange_, point.X()+outlierRange_); hitCoords(1) = gRandom->Uniform(point.Y()-outlierRange_, point.Y()+outlierRange_); hitCoords(2) = gRandom->Uniform(point.Z()-outlierRange_, point.Z()+outlierRange_); } else { hitCoords(0) = point.X(); hitCoords(1) = point.Y(); hitCoords(2) = point.Z(); } TMatrixDSym hitCov(3); hitCov(0,0) = resolution_*resolution_; hitCov(1,1) = resolution_*resolution_; hitCov(2,2) = resolutionWire_*resolutionWire_; // rotation matrix TVector3 xp = currentWireDir.Orthogonal(); xp.SetMag(1); TVector3 yp = currentWireDir.Cross(xp); yp.SetMag(1); TMatrixD rot(3,3); rot(0,0) = xp.X(); rot(0,1) = yp.X(); rot(0,2) = currentWireDir.X(); rot(1,0) = xp.Y(); rot(1,1) = yp.Y(); rot(1,2) = currentWireDir.Y(); rot(2,0) = xp.Z(); rot(2,1) = yp.Z(); rot(2,2) = currentWireDir.Z(); // smear TVectorD smearVec(3); smearVec(0) = resolution_; smearVec(1) = resolution_; smearVec(2) = resolutionWire_; smearVec *= rot; if (!outlier) { hitCoords(0) += gRandom->Gaus(0, smearVec(0)); hitCoords(1) += gRandom->Gaus(0, smearVec(1)); hitCoords(2) += gRandom->Gaus(0, smearVec(2)); } // rotate cov hitCov.Similarity(rot); measurement = new genfit::ProlateSpacepointMeasurement(hitCoords, hitCov, int(type), measurementCounter_, nullptr); static_cast(measurement)->setLargestErrorDirection(currentWireDir); retVal.push_back(measurement); } break; case StripU: case StripV: case StripUV : { if (debug_) std::cerr << "create StripHit" << std::endl; TVector3 vU, vV; vU = planeNorm.Cross(z); vV = (planeNorm.Cross(z)).Cross(planeNorm); genfit::SharedPlanePtr plane(new genfit::DetPlane(point, vU, vV)); TVectorD hitCoords(1); if (outlier) hitCoords(0) = gRandom->Uniform(-outlierRange_, outlierRange_); else hitCoords(0) = gRandom->Gaus(0,resolution_); TMatrixDSym hitCov(1); hitCov(0,0) = resolution_*resolution_; measurement = new genfit::PlanarMeasurement(hitCoords, hitCov, int(type), measurementCounter_, nullptr); static_cast(measurement)->setPlane(plane, measurementCounter_); if (type == StripV) static_cast(measurement)->setStripV(); retVal.push_back(measurement); if (type == StripUV) { if (outlier) hitCoords(0) = gRandom->Uniform(-outlierRange_, outlierRange_); else hitCoords(0) = gRandom->Gaus(0,resolution_); hitCov(0,0) = resolution_*resolution_; measurement = new genfit::PlanarMeasurement(hitCoords, hitCov, int(type), measurementCounter_, nullptr); static_cast(measurement)->setPlane(plane, measurementCounter_); static_cast(measurement)->setStripV(); retVal.push_back(measurement); } } break; case Wire: { if (debug_) std::cerr << "create WireHit" << std::endl; if (outlier) { wirePerp.SetMag(gRandom->Uniform(outlierRange_)); } TVectorD hitCoords(7); hitCoords(0) = (point-wirePerp-currentWireDir).X(); hitCoords(1) = (point-wirePerp-currentWireDir).Y(); hitCoords(2) = (point-wirePerp-currentWireDir).Z(); hitCoords(3) = (point-wirePerp+currentWireDir).X(); hitCoords(4) = (point-wirePerp+currentWireDir).Y(); hitCoords(5) = (point-wirePerp+currentWireDir).Z(); if (outlier) hitCoords(6) = gRandom->Uniform(outlierRange_); else hitCoords(6) = gRandom->Gaus(wirePerp.Mag(), resolution_); TMatrixDSym hitCov(7); hitCov(6,6) = resolution_*resolution_; measurement = new genfit::WireMeasurement(hitCoords, hitCov, int(type), measurementCounter_, nullptr); if (idealLRResolution_){ static_cast(measurement)->setLeftRightResolution(lr); } ++wireCounter_; retVal.push_back(measurement); } break; case WirePoint: { if (debug_) std::cerr << "create WirePointHit" << std::endl; if (outlier) { wirePerp.SetMag(gRandom->Uniform(outlierRange_)); } TVectorD hitCoords(8); hitCoords(0) = (point-wirePerp-currentWireDir).X(); hitCoords(1) = (point-wirePerp-currentWireDir).Y(); hitCoords(2) = (point-wirePerp-currentWireDir).Z(); hitCoords(3) = (point-wirePerp+currentWireDir).X(); hitCoords(4) = (point-wirePerp+currentWireDir).Y(); hitCoords(5) = (point-wirePerp+currentWireDir).Z(); if (outlier) { hitCoords(6) = gRandom->Uniform(outlierRange_); hitCoords(7) = gRandom->Uniform(currentWireDir.Mag()-outlierRange_, currentWireDir.Mag()+outlierRange_); } else { hitCoords(6) = gRandom->Gaus(wirePerp.Mag(), resolution_); hitCoords(7) = gRandom->Gaus(currentWireDir.Mag(), resolutionWire_); } TMatrixDSym hitCov(8); hitCov(6,6) = resolution_*resolution_; hitCov(7,7) = resolutionWire_*resolutionWire_; measurement = new genfit::WirePointMeasurement(hitCoords, hitCov, int(type), measurementCounter_, nullptr); if (idealLRResolution_){ static_cast(measurement)->setLeftRightResolution(lr); } ++wireCounter_; retVal.push_back(measurement); } break; default: std::cerr << "measurement type not defined!" << std::endl; exit(0); } return retVal; } void MeasurementCreator::reset() { wireCounter_ = 0; measurementCounter_ = 0; } } /* End of namespace genfit */