00001 #include "RecoTracker/SpecialSeedGenerators/interface/CtfSpecialSeedGenerator.h"
00002
00003 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00004 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00005 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00006 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00007 #include "DataFormats/GeometrySurface/interface/RectangularPlaneBounds.h"
00008 #include "TrackingTools/GeomPropagators/interface/StraightLinePlaneCrossing.h"
00009
00010 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionProducerFactory.h"
00011 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegion.h"
00012 #include "RecoTracker/TkTrackingRegions/interface/OrderedHitsGeneratorFactory.h"
00013 #include "RecoTracker/TkSeedingLayers/interface/OrderedSeedingHits.h"
00014
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016
00017 #include "RecoTracker/SpecialSeedGenerators/interface/ClusterChecker.h"
00018
00019 using namespace ctfseeding;
00020
00021 CtfSpecialSeedGenerator::CtfSpecialSeedGenerator(const edm::ParameterSet& conf):
00022 conf_(conf),
00023 requireBOFF(conf.getParameter<bool>("requireBOFF")),
00024 theMaxSeeds(conf.getParameter<int32_t>("maxSeeds"))
00025 {
00026 useScintillatorsConstraint = conf_.getParameter<bool>("UseScintillatorsConstraint");
00027 edm::LogVerbatim("CtfSpecialSeedGenerator") << "Constructing CtfSpecialSeedGenerator";
00028 produces<TrajectorySeedCollection>();
00029 theSeedBuilder =0;
00030 theRegionProducer =0;
00031 }
00032
00033 CtfSpecialSeedGenerator::~CtfSpecialSeedGenerator(){
00034 }
00035
00036 void CtfSpecialSeedGenerator::endRun(edm::Run &, edm::EventSetup const&){
00037 if (theSeedBuilder) { delete theSeedBuilder; theSeedBuilder = 0; }
00038 if (theRegionProducer) { delete theRegionProducer; theRegionProducer = 0; }
00039 std::vector<OrderedHitsGenerator*>::iterator iGen;
00040 for (iGen = theGenerators.begin(); iGen != theGenerators.end(); iGen++){
00041 delete (*iGen);
00042 }
00043 theGenerators.clear();
00044 }
00045
00046 void CtfSpecialSeedGenerator::beginRun(edm::Run &, const edm::EventSetup& iSetup){
00047 std::string builderName = conf_.getParameter<std::string>("TTRHBuilder");
00048 iSetup.get<TransientRecHitRecord>().get(builderName,theBuilder);
00049
00050 iSetup.get<IdealMagneticFieldRecord>().get(theMagfield);
00051 iSetup.get<TrackerDigiGeometryRecord>().get(theTracker);
00052
00053 edm::LogVerbatim("CtfSpecialSeedGenerator") << "Initializing...";
00054 if (useScintillatorsConstraint){
00055 edm::ParameterSet upperScintPar = conf_.getParameter<edm::ParameterSet>("UpperScintillatorParameters");
00056 edm::ParameterSet lowerScintPar = conf_.getParameter<edm::ParameterSet>("LowerScintillatorParameters");
00057 RectangularPlaneBounds upperBounds(upperScintPar.getParameter<double>("WidthInX"),
00058 upperScintPar.getParameter<double>("LenghtInZ"),
00059 1);
00060 GlobalPoint upperPosition(upperScintPar.getParameter<double>("GlobalX"),
00061 upperScintPar.getParameter<double>("GlobalY"),
00062 upperScintPar.getParameter<double>("GlobalZ"));
00063 edm::LogVerbatim("CtfSpecialSeedGenerator")
00064 << "Upper Scintillator position x, y, z " << upperPosition.x()
00065 << ", " << upperPosition.y() << ", " << upperPosition.z();
00066 RectangularPlaneBounds lowerBounds(lowerScintPar.getParameter<double>("WidthInX"),
00067 lowerScintPar.getParameter<double>("LenghtInZ"),
00068 1);
00069 GlobalPoint lowerPosition(lowerScintPar.getParameter<double>("GlobalX"),
00070 lowerScintPar.getParameter<double>("GlobalY"),
00071 lowerScintPar.getParameter<double>("GlobalZ"));
00072 edm::LogVerbatim("CtfSpecialSeedGenerator")
00073 << "Lower Scintillator position x, y, z " << lowerPosition.x()
00074 << ", " << lowerPosition.y() << ", " << lowerPosition.z() ;
00075 TkRotation<float> rot(1,0,0,0,0,1,0,1,0);
00076 upperScintillator = BoundPlane::build(upperPosition, rot, &upperBounds);
00077 lowerScintillator = BoundPlane::build(lowerPosition, rot, &lowerBounds);
00078 }
00079 edm::ParameterSet regfactoryPSet = conf_.getParameter<edm::ParameterSet>("RegionFactoryPSet");
00080 std::string regfactoryName = regfactoryPSet.getParameter<std::string>("ComponentName");
00081 theRegionProducer = TrackingRegionProducerFactory::get()->create(regfactoryName,regfactoryPSet);
00082
00083 edm::ESHandle<Propagator> propagatorAlongHandle;
00084 iSetup.get<TrackingComponentsRecord>().get("PropagatorWithMaterial",propagatorAlongHandle);
00085 edm::ESHandle<Propagator> propagatorOppositeHandle;
00086 iSetup.get<TrackingComponentsRecord>().get("PropagatorWithMaterialOpposite",propagatorOppositeHandle);
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 std::vector<edm::ParameterSet> pSets = conf_.getParameter<std::vector<edm::ParameterSet> >("OrderedHitsFactoryPSets");
00110 std::vector<edm::ParameterSet>::const_iterator iPSet;
00111 for (iPSet = pSets.begin(); iPSet != pSets.end(); iPSet++){
00112 std::string hitsfactoryName = iPSet->getParameter<std::string>("ComponentName");
00113 theGenerators.push_back(OrderedHitsGeneratorFactory::get()->create( hitsfactoryName, *iPSet));
00114 std::string propagationDirection = iPSet->getParameter<std::string>("PropagationDirection");
00115 if (propagationDirection == "alongMomentum") thePropDirs.push_back(alongMomentum);
00116 else thePropDirs.push_back(oppositeToMomentum);
00117 std::string navigationDirection = iPSet->getParameter<std::string>("NavigationDirection");
00118 if (navigationDirection == "insideOut") theNavDirs.push_back(insideOut);
00119 else theNavDirs.push_back(outsideIn);
00120 edm::LogVerbatim("CtfSpecialSeedGenerator") << "hitsGenerator done";
00121 }
00122 bool setMomentum = conf_.getParameter<bool>("SetMomentum");
00123 std::vector<int> charges;
00124 if (setMomentum){
00125 charges = conf_.getParameter<std::vector<int> >("Charges");
00126 }
00127 theSeedBuilder = new SeedFromGenericPairOrTriplet(theMagfield.product(),
00128 theTracker.product(),
00129 theBuilder.product(),
00130 propagatorAlongHandle.product(),
00131 propagatorOppositeHandle.product(),
00132 charges,
00133 setMomentum,
00134 conf_.getParameter<double>("ErrorRescaling"));
00135 double p = 1;
00136 if (setMomentum) {
00137 p = conf_.getParameter<double>("SeedMomentum");
00138 theSeedBuilder->setMomentumTo(p);
00139 }
00140
00141 }
00142
00143 void CtfSpecialSeedGenerator::produce(edm::Event& e, const edm::EventSetup& iSetup)
00144 {
00145
00146 std::auto_ptr<TrajectorySeedCollection> output(new TrajectorySeedCollection);
00147
00148
00149 ClusterChecker check(conf_);
00150 if ( !requireBOFF || (theMagfield->inTesla(GlobalPoint(0,0,0)).mag() == 0.00) ) {
00151 size_t clustsOrZero = check.tooManyClusters(e);
00152 if (!clustsOrZero){
00153 bool ok = run(iSetup, e, *output);
00154 if (!ok) { ; }
00155 } else edm::LogError("TooManyClusters") << "Found too many clusters (" << clustsOrZero << "), bailing out.\n";
00156 }
00157
00158
00159 edm::LogVerbatim("CtfSpecialSeedGenerator") << " number of seeds = "<< output->size();
00160 e.put(output);
00161 }
00162
00163 bool CtfSpecialSeedGenerator::run(const edm::EventSetup& iSetup,
00164 const edm::Event& e,
00165 TrajectorySeedCollection& output){
00166 std::vector<TrackingRegion*> regions = theRegionProducer->regions(e, iSetup);
00167 std::vector<TrackingRegion*>::const_iterator iReg;
00168 bool ok = true;
00169 for (iReg = regions.begin(); iReg != regions.end(); iReg++){
00170 if(!theSeedBuilder->momentumFromPSet()) theSeedBuilder->setMomentumTo((*iReg)->ptMin());
00171 std::vector<OrderedHitsGenerator*>::const_iterator iGen;
00172 int i = 0;
00173 for (iGen = theGenerators.begin(); iGen != theGenerators.end(); iGen++){
00174 ok = buildSeeds(iSetup,
00175 e,
00176 (*iGen)->run(**iReg, e, iSetup),
00177 theNavDirs[i],
00178 thePropDirs[i],
00179 output);
00180 i++;
00181 if (!ok) break;
00182 }
00183 if (!ok) break;
00184 }
00185
00186 for (std::vector<TrackingRegion*>::iterator iReg = regions.begin(); iReg != regions.end(); iReg++){
00187 delete *iReg;
00188 }
00189 return ok;
00190 }
00191
00192 bool CtfSpecialSeedGenerator::buildSeeds(const edm::EventSetup& iSetup,
00193 const edm::Event& e,
00194 const OrderedSeedingHits& osh,
00195 const NavigationDirection& navdir,
00196 const PropagationDirection& dir,
00197 TrajectorySeedCollection& output){
00198
00199 edm::LogInfo("CtfSpecialSeedGenerator")<<"osh.size() " << osh.size();
00200 for (unsigned int i = 0; i < osh.size(); i++){
00201 SeedingHitSet shs = osh[i];
00202 if (preliminaryCheck(shs)){
00203 std::vector<TrajectorySeed*> seeds = theSeedBuilder->seed(shs,
00204 dir,
00205 navdir,
00206 iSetup);
00207 for (std::vector<TrajectorySeed*>::const_iterator iSeed = seeds.begin(); iSeed != seeds.end(); iSeed++){
00208 if (!*iSeed) {edm::LogError("CtfSpecialSeedGenerator")<<"a seed pointer is null. skipping.";continue;}
00209 if (postCheck(**iSeed)){
00210 output.push_back(**iSeed);
00211 }
00212 delete *iSeed;
00213 edm::LogVerbatim("CtfSpecialSeedGenerator") << "Seed built";
00214 }
00215 }
00216 }
00217 if ((theMaxSeeds > 0) && (output.size() > size_t(theMaxSeeds))) {
00218 edm::LogWarning("TooManySeeds") << "Too many seeds ("<< output.size() <<"), bailing out.\n";
00219 output.clear();
00220 return false;
00221 }
00222 return true;
00223 }
00224
00225 bool CtfSpecialSeedGenerator::preliminaryCheck(const SeedingHitSet& shs){
00226 std::vector<std::pair<unsigned int, unsigned int> > vSubdetLayer;
00227
00228 bool checkHitsAtPositiveY = conf_.getParameter<bool>("SeedsFromPositiveY");
00229
00230 bool checkHitsAtNegativeY = conf_.getParameter<bool>("SeedsFromNegativeY");
00231
00232 bool checkHitsOnDifferentLayers = conf_.getParameter<bool>("CheckHitsAreOnDifferentLayers");
00233 unsigned int nHits = shs.size();
00234 for (unsigned int iHit=0; iHit < nHits; ++iHit) {
00235
00236 const TrackingRecHit * trh = shs[iHit]->hit();
00237 TransientTrackingRecHit::RecHitPointer recHit = theBuilder->build(trh);
00238 GlobalPoint hitPos = recHit->globalPosition();
00239
00240
00241 if (checkHitsAtPositiveY){ if (hitPos.y() < 0) return false;}
00242
00243 if (checkHitsAtNegativeY){ if (hitPos.y() > 0) return false;}
00244
00245
00246
00247 unsigned int subid=(*trh).geographicalId().subdetId();
00248 unsigned int layer = 0;
00249 if (subid == StripSubdetector::TIB){
00250 TIBDetId tibId((*trh).geographicalId());
00251 layer = tibId.layer();
00252 } else if (subid == StripSubdetector::TID){
00253 TIDDetId tidId((*trh).geographicalId());
00254 layer = tidId.wheel();
00255 } else if (subid == StripSubdetector::TOB){
00256 TOBDetId tobId((*trh).geographicalId());
00257 layer = tobId.layer();
00258 } else if (subid == StripSubdetector::TEC){
00259 TECDetId tecId((*trh).geographicalId());
00260 layer = tecId.wheel();
00261 }
00262 std::vector<std::pair<unsigned int, unsigned int> >::const_iterator iter;
00263
00264 if (checkHitsOnDifferentLayers){
00265
00266 for (iter = vSubdetLayer.begin(); iter != vSubdetLayer.end(); iter++){
00267 if (iter->first == subid && iter->second == layer) return false;
00268 }
00269
00270
00271
00272
00273
00274 }
00275
00276 vSubdetLayer.push_back(std::make_pair(subid, layer));
00277 }
00278 return true;
00279 }
00280
00281
00282 bool CtfSpecialSeedGenerator::postCheck(const TrajectorySeed& seed){
00283 if (!useScintillatorsConstraint) return true;
00284
00285 PTrajectoryStateOnDet pstate = seed.startingState();
00286 TrajectoryStateOnSurface theTSOS = trajectoryStateTransform::transientState(pstate,
00287 &(theTracker->idToDet(DetId(pstate.detId()))->surface()),
00288 &(*theMagfield));
00289 FreeTrajectoryState* state = theTSOS.freeState();
00290 StraightLinePlaneCrossing planeCrossingLower( Basic3DVector<float>(state->position()),
00291 Basic3DVector<float>(state->momentum()),
00292 alongMomentum);
00293 StraightLinePlaneCrossing planeCrossingUpper( Basic3DVector<float>(state->position()),
00294 Basic3DVector<float>(state->momentum()),
00295 oppositeToMomentum);
00296 std::pair<bool,StraightLinePlaneCrossing::PositionType> positionUpper =
00297 planeCrossingUpper.position(*upperScintillator);
00298 std::pair<bool,StraightLinePlaneCrossing::PositionType> positionLower =
00299 planeCrossingLower.position(*lowerScintillator);
00300 if (!(positionUpper.first && positionLower.first)) {
00301 edm::LogVerbatim("CtfSpecialSeedGenerator::checkDirection")
00302 << "Scintillator plane not crossed";
00303 return false;
00304 }
00305 LocalPoint positionUpperLocal = upperScintillator->toLocal((GlobalPoint)(positionUpper.second));
00306 LocalPoint positionLowerLocal = lowerScintillator->toLocal((GlobalPoint)(positionLower.second));
00307 if (upperScintillator->bounds().inside(positionUpperLocal) &&
00308 lowerScintillator->bounds().inside(positionLowerLocal)) {
00309 edm::LogVerbatim("CtfSpecialSeedGenerator::checkDirection")
00310 << "position on Upper scintillator "
00311 << positionUpper.second;
00312 edm::LogVerbatim("CtfSpecialSeedGenerator::checkDirection")
00313 << "position on Lower scintillator "
00314 << positionLower.second;
00315
00316 return true;
00317 }
00318 edm::LogVerbatim("CtfSpecialSeedGenerator::checkDirection")
00319 << "scintillator not crossed in bounds: position on Upper scintillator "
00320 << positionUpper.second << " position on Lower scintillator " << positionLower.second;
00321 return false;
00322 }
00323
00324