00001
00002
00003 #include "VisReco/Analyzer/interface/VisMuon.h"
00004 #include "VisReco/Analyzer/interface/IguanaService.h"
00005 #include "DataFormats/GeometrySurface/interface/PlaneBuilder.h"
00006 #include "DataFormats/MuonReco/interface/Muon.h"
00007 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00008 #include "DataFormats/MuonReco/interface/MuonChamberMatch.h"
00009 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
00010 #include "DataFormats/TrackReco/interface/Track.h"
00011 #include "DataFormats/TrackReco/interface/TrackBase.h"
00012 #include "FWCore/Framework/interface/Event.h"
00013 #include "FWCore/Framework/interface/ESHandle.h"
00014 #include "FWCore/Framework/interface/EventSetup.h"
00015 #include "FWCore/Framework/interface/MakerMacros.h"
00016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00017 #include "FWCore/ServiceRegistry/interface/Service.h"
00018 #include "FWCore/Utilities/interface/Exception.h"
00019 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00020 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00021 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00022 #include "Iguana/Framework/interface/IgCollection.h"
00023 #include <iostream>
00024 #include <sstream>
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 using namespace edm::service;
00037
00038 VisMuon::VisMuon (const edm::ParameterSet& iConfig)
00039 : inputTag_ (iConfig.getParameter<edm::InputTag>("visMuonTag")),
00040 in_ (iConfig.getUntrackedParameter<double>( "propagatorIn", 0.0)),
00041 out_ (iConfig.getUntrackedParameter<double>( "propagatorOut", 0.0)),
00042 step_ (iConfig.getUntrackedParameter<double>( "propagatorStep", 0.05))
00043 {}
00044
00045 void
00046 VisMuon::analyze (const edm::Event& event, const edm::EventSetup& eventSetup)
00047 {
00048 edm::Service<IguanaService> config;
00049 if (! config.isAvailable ())
00050 {
00051 throw cms::Exception ("Configuration")
00052 << "VisMuon requires the IguanaService\n"
00053 "which is not present in the configuration file.\n"
00054 "You must add the service in the configuration file\n"
00055 "or remove the module that requires it";
00056 }
00057
00058 edm::Handle<reco::MuonCollection> collection;
00059
00060 eventSetup.get<IdealMagneticFieldRecord> ().get (field_);
00061 event.getByLabel (inputTag_, collection);
00062
00063 if (collection.isValid ())
00064 {
00065 storage_ = config->storage ();
00066 IgCollection &icollection = storage_->getCollection ("Muons_V1");
00067 IgProperty PT = icollection.addProperty ("pt", 0.0);
00068 IgProperty CHARGE = icollection.addProperty ("charge", 0.0);
00069 IgProperty RP = icollection.addProperty ("rp", IgV3d ());
00070 IgProperty PHI = icollection.addProperty ("phi", 0.0);
00071 IgProperty ETA = icollection.addProperty ("eta", 0.0);
00072 IgProperty T_PT = icollection.addProperty ("tracker_pt", 0.0);
00073 IgProperty S_PT = icollection.addProperty ("standalone_pt", 0.0);
00074 IgProperty G_PT = icollection.addProperty ("global_pt", 0.0);
00075 IgProperty CALO_E = icollection.addProperty ("calo_energy", 0.0);
00076
00077 IgCollection &points = storage_->getCollection("Points_V1");
00078 IgProperty POS = points.addProperty("pos", IgV3d());
00079
00080 IgCollection &detIds = storage_->getCollection("DetIds_V1");
00081 IgProperty DETID = detIds.addProperty ("detid", int (0));
00082
00083 IgAssociationSet &muonDetIds = storage_->getAssociationSet("MuonDetIds_V1");
00084
00085 reco::MuonCollection::const_iterator it = collection->begin ();
00086 reco::MuonCollection::const_iterator end = collection->end ();
00087 for (; it != end; ++it)
00088 {
00089 IgCollectionItem imuon = icollection.create ();
00090 float charge = (*it).charge ();
00091 float pt = (*it).pt();
00092 imuon [PT] = static_cast<double>(pt);
00093 imuon [CHARGE] = static_cast<double>(charge);
00094 imuon [RP] = IgV3d (static_cast<double>((*it).vx ()/100.), static_cast<double>((*it).vy()/100.), static_cast<double>((*it).vz()/100.));
00095 imuon [PHI] = static_cast<double>((*it).phi ());
00096 imuon [ETA] = static_cast<double>((*it).eta ());
00097
00098 if ((*it).isMatchesValid ())
00099 {
00100 const std::vector<reco::MuonChamberMatch> &dets = (*it).matches ();
00101 for (std::vector<reco::MuonChamberMatch>::const_iterator dit = dets.begin (), ditEnd = dets.end (); dit != ditEnd; ++dit)
00102 {
00103 IgCollectionItem idetId = detIds.create ();
00104 idetId[DETID] = static_cast<int>((*dit).id);
00105 muonDetIds.associate (imuon, idetId);
00106 }
00107 }
00108 if ((*it).innerTrack ().isNonnull ())
00109 {
00110 double pt = (*it).innerTrack ()->pt ();
00111 imuon[T_PT] = static_cast<double>(pt);
00112 IgAssociationSet &muonTrackerPoints = storage_->getAssociationSet("MuonTrackerPoints_V1");
00113 refitTrack (imuon, muonTrackerPoints, (*it).innerTrack (), in_, out_, step_);
00114 }
00115
00116 if ((*it).outerTrack ().isNonnull ())
00117 {
00118 double pt = (*it).outerTrack ()->pt ();
00119 imuon[S_PT] = static_cast<double>(pt);
00120 IgAssociationSet &muonStandalonePoints = storage_->getAssociationSet("MuonStandalonePoints_V1");
00121 refitTrack (imuon, muonStandalonePoints, (*it).outerTrack (), in_, out_, step_);
00122 }
00123
00124 if ((*it).globalTrack ().isNonnull ())
00125 {
00126 double pt = (*it).globalTrack ()->pt ();
00127 imuon[G_PT] = static_cast<double>(pt);
00128 IgAssociationSet &muonGlobalPoints = storage_->getAssociationSet("MuonGlobalPoints_V1");
00129 refitTrack (imuon, muonGlobalPoints, (*it).globalTrack (), in_, out_, step_);
00130 }
00131
00132 if ((*it).isEnergyValid ())
00133 {
00134 float e = (*it).calEnergy ().tower;
00135 imuon[CALO_E] = static_cast<double>(e);
00136 }
00137 }
00138 }
00139 else
00140 {
00141
00142 std::string error = "### Error: Muons "
00143 + edm::TypeID (typeid (reco::MuonCollection)).friendlyClassName () + ":"
00144 + inputTag_.label() + ":"
00145 + inputTag_.instance() + ":"
00146 + inputTag_.process() + " are not found.";
00147
00148 IgDataStorage *storage = config->storage ();
00149 IgCollection &collection = storage->getCollection ("Errors_V1");
00150 IgProperty errorMsg = collection.addProperty ("Error", std::string ());
00151 IgCollectionItem item = collection.create ();
00152 item ["Error"] = error;
00153 }
00154 }
00155
00156 void
00157 VisMuon::refitTrack (IgCollectionItem &imuon, IgAssociationSet &association, reco::TrackRef track, double in, double out, double step)
00158 {
00159 if (track.isNonnull () && field_.isValid ())
00160 {
00161 IgCollection &points = storage_->getCollection("Points_V1");
00162
00163 reco::TransientTrack aRealTrack (track, &*field_);
00164
00165
00166 SteppingHelixPropagator propagator (&*field_, alongMomentum);
00167 SteppingHelixPropagator reversePropagator (&*field_, oppositeToMomentum);
00168 GlobalPoint gPin ((*track).innerPosition ().x (),
00169 (*track).innerPosition ().y (),
00170 (*track).innerPosition ().z ());
00171 GlobalPoint gPout ((*track).outerPosition ().x (),
00172 (*track).outerPosition ().y (),
00173 (*track).outerPosition ().z ());
00174 GlobalVector InOutVector = (gPout - gPin);
00175
00176
00177
00178 GlobalVector zAxis = InOutVector.unit();
00179
00180 GlobalVector xAxis;
00181 if (zAxis.x() != 0 || zAxis.y() != 0)
00182 {
00183
00184 xAxis = GlobalVector (-zAxis.y(), zAxis.x(), 0).unit();
00185 }
00186 else {
00187 xAxis = GlobalVector( 1, 0, 0);
00188 }
00189
00190 GlobalVector yAxis( zAxis.cross( xAxis));
00191 Surface::RotationType rot( xAxis.x(), xAxis.y(), xAxis.z(),
00192 yAxis.x(), yAxis.y(), yAxis.z(),
00193 zAxis.x(), zAxis.y(), zAxis.z());
00194
00195
00196 int nSteps = 0;
00197 int nStepsInside = 0;
00198 int nStepsOutside = 0;
00199 GlobalVector StepVector;
00200 if( step > 0.01 ) {
00201 StepVector = InOutVector * step;
00202 nSteps = int (0.5 + 1.0/step);
00203 nStepsInside = int (0.5 + in/step);
00204 nStepsOutside = int (0.5 + out/step);
00205 } else {
00206 StepVector = InOutVector * 0.01;
00207 nSteps = 100;
00208 nStepsInside = int (0.5 + in*100);
00209 nStepsOutside = int (0.5 + out*100);
00210 }
00211
00212 GlobalVector gVin ((*track).innerMomentum ().x (),
00213 (*track).innerMomentum ().y (),
00214 (*track).innerMomentum ().z ());
00215 GlobalVector gVout ((*track).outerMomentum ().x (),
00216 (*track).outerMomentum ().y (),
00217 (*track).outerMomentum ().z ());
00218 GlobalTrajectoryParameters GTPin (gPin, gVin, aRealTrack.impactPointTSCP ().charge (), &*field_);
00219 FreeTrajectoryState FTSin (GTPin);
00220 GlobalTrajectoryParameters GTPout (gPout, gVout, aRealTrack.impactPointTSCP ().charge (), &*field_);
00221 FreeTrajectoryState FTSout (GTPout);
00222
00223 int nGood = 0;
00224 int nBad = 0;
00225
00226
00227 GlobalPoint GP = gPin;
00228 GP -= nStepsInside * StepVector;
00229 Basic3DVector<float> Basic3DV (StepVector.x (), StepVector.y (), StepVector.z ());
00230 for (int istep = 0; istep < nStepsInside; ++istep)
00231 {
00232 GP += StepVector;
00233 Surface::PositionType pos (GP.x (), GP.y (), GP.z ());
00234 PlaneBuilder::ReturnType SteppingPlane = PlaneBuilder ().plane (pos, rot);
00235 TrajectoryStateOnSurface trj = reversePropagator.propagate (FTSin, *SteppingPlane);
00236 if (trj.isValid ())
00237 {
00238 float x = trj.globalPosition ().x () / 100.0;
00239 float y = trj.globalPosition ().y () / 100.0;
00240 float z = trj.globalPosition ().z () / 100.0;
00241 IgCollectionItem ipoint = points.create ();
00242 ipoint["pos"] = IgV3d (static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
00243 association.associate (imuon, ipoint);
00244 nGood++;
00245 }
00246 else
00247 {
00248 nBad++;
00249 }
00250 }
00251
00252
00253 GP = gPin - StepVector;
00254 float w = 0;
00255 for (int istep = 0; istep < nSteps+1 ; ++istep)
00256 {
00257 GP += StepVector;
00258 Surface::PositionType pos (GP.x (), GP.y (), GP.z ());
00259 PlaneBuilder::ReturnType SteppingPlane = PlaneBuilder ().plane (pos, rot);
00260 TrajectoryStateOnSurface trj_in = propagator.propagate (FTSin, *SteppingPlane);
00261 TrajectoryStateOnSurface trj_out = reversePropagator.propagate (FTSout, *SteppingPlane);
00262 if (trj_in.isValid () && trj_out.isValid ())
00263 {
00264 float x1 = trj_in.globalPosition ().x () / 100.0;
00265 float y1 = trj_in.globalPosition ().y () / 100.0;
00266 float z1 = trj_in.globalPosition ().z () / 100.0;
00267
00268 float x2 = trj_out.globalPosition ().x () / 100.0;
00269 float y2 = trj_out.globalPosition ().y () / 100.0;
00270 float z2 = trj_out.globalPosition ().z () / 100.0;
00271
00272 float ww = w<0.4999 ? ww = w : ww=1.0-w;
00273 float w2 = 0.5*ww*ww/((1.0-ww)*(1.0-ww));
00274 if(w>0.4999) w2=1.0-w2;
00275
00276 float x = (1.0-w2)*x1 + w2*x2;
00277 float y = (1.0-w2)*y1 + w2*y2;
00278 float z = (1.0-w2)*z1 + w2*z2;
00279
00280 IgCollectionItem ipoint = points.create ();
00281 ipoint["pos"] = IgV3d (static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
00282 association.associate (imuon, ipoint);
00283 nGood++;
00284 }
00285 else
00286 {
00287 nBad++;
00288 }
00289 w += 1.0/float(nSteps);
00290 }
00291
00292 GP = gPout;
00293 for (int istep = 0; istep < nStepsOutside; ++istep)
00294 {
00295 GP += StepVector;
00296 Surface::PositionType pos (GP.x (), GP.y (), GP.z ());
00297 PlaneBuilder::ReturnType SteppingPlane = PlaneBuilder ().plane (pos, rot);
00298 TrajectoryStateOnSurface trj = propagator.propagate (FTSout, *SteppingPlane);
00299 if (trj.isValid ())
00300 {
00301 float x = trj.globalPosition ().x () / 100.0;
00302 float y = trj.globalPosition ().y () / 100.0;
00303 float z = trj.globalPosition ().z () / 100.0;
00304 IgCollectionItem ipoint = points.create ();
00305 ipoint["pos"] = IgV3d (static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
00306 association.associate (imuon, ipoint);
00307 nGood++;
00308 }
00309 else
00310 {
00311 nBad++;
00312 }
00313 }
00314 }
00315 }
00316
00317 DEFINE_FWK_MODULE(VisMuon);