00001
00002
00003
00004
00005 #include "AtlfastAlgs/JetCalibrator.h"
00006 #include "AtlfastAlgs/GlobalEventData.h"
00007 #include "AtlfastUtils/IsAssociated.h"
00008
00009
00010 #include "AtlfastUtils/JetVisitor.h"
00011 #include "AtlfastUtils/ClusEcalEtSumVisitor.h"
00012 #include "AtlfastUtils/ClusHcalEtSumVisitor.h"
00013
00014
00015 #include "AtlfastEvent/Jet.h"
00016 #include "AtlfastEvent/ICell.h"
00017 #include "AtlfastEvent/CollectionDefs.h"
00018 #include "AtlfastEvent/ReconstructedParticle.h"
00019 #include "AtlfastEvent/ParticleCodes.h"
00020 #include "AtlfastEvent/MsgStreamDefs.h"
00021 #include "AtlfastEvent/Cluster.h"
00022 #include "AtlfastEvent/MCparticleCollection.h"
00023
00024 #include "AtlfastUtils/TesIO.h"
00025 #include "AtlfastUtils/HeaderPrinter.h"
00026 #include "AtlfastUtils/FunctionObjects.h"
00027 #include "AtlfastEvent/SimpleKinematic.h"
00028
00029 #include <cmath>
00030 #include <algorithm>
00031 #include <numeric>
00032 #include <assert.h>
00033
00034
00035 #include "GaudiKernel/DataSvc.h"
00036 #include "GaudiKernel/ISvcLocator.h"
00037 #include "GaudiKernel/MsgStream.h"
00038
00039
00040
00041
00042 #include "GeneratorObjects/McEventCollection.h"
00043 #include "HepMC/GenEvent.h"
00044 #include "HepMC/GenVertex.h"
00045
00046
00047 namespace Atlfast{
00048
00049
00050
00051
00052
00053
00054 JetCalibrator::JetCalibrator
00055 ( const std::string& name, ISvcLocator* pSvcLocator )
00056 : Algorithm( name, pSvcLocator )
00057 , m_tesIO( 0 ) {
00058
00059
00060
00061
00062 m_inputLocation = "/Event/AtlfastJets";
00063 m_outputLocation = "/Event/AtlfastCalibratedJets";
00064
00065
00066
00067 declareProperty( "InputLocation", m_inputLocation ) ;
00068 declareProperty( "OutputLocation", m_outputLocation ) ;
00069 }
00070
00071 JetCalibrator::~JetCalibrator() {
00072
00073 MsgStream log( messageService(), name() ) ;
00074 log << MSG::INFO << "Destructor Called" << endreq;
00075
00076 if (m_tesIO) {
00077 delete m_tesIO;
00078 }
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 StatusCode JetCalibrator::initialize(){
00088 MsgStream log( messageService(), name() ) ;
00089
00090 GlobalEventData* ged = GlobalEventData::Instance();
00091 m_mcLocation = ged -> mcLocation();
00092
00093
00094 m_tesIO = new TesIO(m_mcLocation, ged->justHardScatter());
00095
00096 HeaderPrinter hp("Atlfast JetCalibrator:", log);
00097
00098 hp.add("TES Locations: ");
00099 hp.add(" Uncalibrated Jets from ", m_inputLocation);
00100 hp.add(" Calibrated Jets to ", m_outputLocation);
00101 hp.print();
00102
00103
00104 return StatusCode::SUCCESS ;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113 StatusCode JetCalibrator::finalize(){
00114
00115 MsgStream log( messageService(), name() ) ;
00116 log << MSG::INFO << "finalizing" << endreq;
00117 return StatusCode::SUCCESS ;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 StatusCode JetCalibrator::execute( ){
00127
00128 MsgStream log( messageService(), name() ) ;
00129
00130 std::string mess;
00131
00132
00133
00134 JetCollection* calibratedJets=new JetCollection;
00135 JetVector uncalibratedJets;
00136
00137 if( ! m_tesIO->copy<JetCollection> ( uncalibratedJets, m_inputLocation ) ) {
00138 log << MSG::INFO << "No Jets in TES " << endreq;
00139 } else {
00140 log << MSG::DEBUG << uncalibratedJets.size()<<" Uncalibrated Jets from TES " << endreq;
00141 }
00142
00143 JetVector::iterator src;
00144 for(src = uncalibratedJets.begin(); src != uncalibratedJets.end(); ++src) {
00145
00146
00147 m_jetVisitor = SimpleAssocsDispatcher(*src, JetVisitor());
00148
00149 Jet* jet = new Jet(**src);
00150
00151
00152
00153 bool hasAssociatedMuons = IsAssociated<ReconstructedParticle>(*src);
00154 ReconstructedParticleVector muons;
00155 if ( hasAssociatedMuons ){
00156
00157 ReconstructedParticle rp;
00158 muons = m_jetVisitor.typeVector(rp);
00159
00160
00161 this->undoMuons(jet, muons);
00162 }
00163
00164
00165
00166 this->calibrate(jet);
00167
00168
00169 if ( hasAssociatedMuons ){
00170
00171 this->addMuons(jet, muons);
00172 }
00173
00174
00175 log << MSG::DEBUG << "Pushing back a calibrated Jet" << endreq;
00176 calibratedJets->push_back( jet );
00177 log<<MSG::DEBUG<<"jet "<<*jet<<endreq;
00178
00179 }
00180
00181
00182
00183
00184 TesIoStat stat;
00185 log<<MSG::DEBUG<<"Storing "<< calibratedJets->size() <<" Jets"<<endreq;
00186 stat = m_tesIO->store( calibratedJets, m_outputLocation ) ;
00187 if(!stat){
00188 log<<MSG::ERROR<<"Could not store jets"<<endreq;
00189 return stat;
00190 }
00191 return StatusCode::SUCCESS;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 void JetCalibrator::calibrate ( Jet* jet )
00201 {
00202
00203 MsgStream log( messageService(), name() ) ;
00204
00205 Cluster* cp(0);
00206
00207 ClusterVector clusters = m_jetVisitor.typeVector(*cp);
00208
00209 ClusterVector::const_iterator cItr = clusters.begin();
00210
00211
00212
00213
00214
00215 TwoCptCell tCC;
00216
00217 ClusEcalEtSumVisitor
00218 eEtVisitor = SimpleAssocsDispatcher((*cItr), ClusEcalEtSumVisitor(*cItr));
00219
00220 ClusHcalEtSumVisitor
00221 hEtVisitor = SimpleAssocsDispatcher((*cItr), ClusHcalEtSumVisitor(*cItr));
00222
00223 double eClusEt = eEtVisitor.getSum(tCC);
00224 double hClusEt = hEtVisitor.getSum(tCC);
00225
00226
00227
00228 log << MSG::DEBUG << "Cluster : " << (*cItr)->eT() << endreq;
00229 log << MSG::DEBUG << "E/H cal : " << eClusEt << " / " <<hClusEt<< endreq;
00230 log << MSG::DEBUG << "Delta Et: " << (*cItr)->eT()-eClusEt-hClusEt << endreq;
00231 log << MSG::DEBUG << "alpha/beta: " << alpha((*cItr)->eta(),(eClusEt+hClusEt))
00232 << " / " << beta((*cItr)->eta(),(eClusEt+hClusEt)) << endreq;
00233
00234
00235 log << MSG::DEBUG << "Ecal: " << endreq;
00236 log << MSG::DEBUG << " Cluster Core : " << eEtVisitor.getCore(tCC) << endreq;
00237 log << MSG::DEBUG << " Cluster Isolation Ring : " << eEtVisitor.getIsolRing(tCC) << endreq;
00238 log << MSG::DEBUG << "Hcal: " << endreq;
00239 log << MSG::DEBUG << " Cluster Core : " << hEtVisitor.getCore(tCC) << endreq;
00240 log << MSG::DEBUG << " Cluster Isolation Ring : " << hEtVisitor.getIsolRing(tCC) << endreq;
00241
00242 double clusEt = alpha( (*cItr)->eta(), (eClusEt+hClusEt) ) * eClusEt
00243 + beta( (*cItr)->eta(), (eClusEt+hClusEt) ) * hClusEt
00244 + ( (*cItr)->eT() - (eClusEt+hClusEt) );
00245
00246 log << MSG::DEBUG << " --> Calibrated Cluster Et : " << clusEt << endreq;
00247 log << MSG::DEBUG << " --> Scale -> CalibratedEt/UncalibrateEt : "
00248 << clusEt/(*cItr)->eT() << endreq;
00249
00250
00251 jet->setMomentum( ( clusEt/(jet->eT()) ) * jet->momentum() );
00252
00253 log << MSG::DEBUG << "Calibrated Jet: " << jet << endreq ;
00254
00255 }
00256
00257
00258
00259
00260
00261 double JetCalibrator::alpha(double eta, double et)
00262 {
00263
00264
00265 et = et/GeV;
00266
00267 double a1[21]={-0.0235573, -0.0149172, -0.0112624, -0.00620699, -0.0184942,
00268 -0.0102938, -0.0180827, -0.00621978, -0.0297793, -0.0278862,
00269 -0.0117897, -0.0232403, -0.0379402, -0.0250858, -0.0303011,
00270 -0.0347847, -0.0374433, -0.121275, -0.0740044, -0.156905, -0.0339867};
00271
00272 double a2[21]={ 0.0525405, 0.0511558, 0.0431571, 0.0529257, 0.0509096,
00273 0.0491337, 0.0759449, 0.0426821, 0.0712299, 0.0776627,
00274 0.054591, 0.0640166, 0.0533651, 0.0723055, 0.0992998,
00275 0.0918459, 0.0838721, 0.138749, 0.136141, 0.261209, 0.0605451};
00276
00277 double a3[21]={ 1.01634, 1.01021, 1.01848, 1.00097, 1.02683,
00278 1.04378, 1.02553, 1.03694, 1.03106, 1.01113,
00279 1.02839, 1.05985, 1.14132, 1.11199, 1.03202,
00280 1.00291, 1.02473, 1.05478, 1.00299, 1.04378, 0.986938};
00281
00282 double y;
00283 if (std::abs(eta)<=1.0){
00284 int i = int( std::abs(eta)/0.1 );
00285 double x = (et>10)? et : 10;
00286 y = a2[i]*std::exp(a1[i]*x)+a3[i];
00287 } else if (std::abs(eta)<=3.2){
00288 int i = 10 + int( (std::abs(eta)-1.0)/0.2 );
00289 double x = (et>10)? et : 10;
00290 y = a2[i]*std::exp(a1[i]*x)+a3[i];
00291 } else {
00292 y = 1;
00293 }
00294
00295
00296
00297 return (y>1)? y/GeV : 1.0/GeV;
00298 }
00299
00300 double JetCalibrator::beta(double eta, double et)
00301 {
00302
00303
00304 et = et/GeV;
00305
00306 double b1[21]={-0.0163571, -0.0419745, -0.0172721, -0.0635324, -0.0137478,
00307 -0.0272831, -0.0164739, -0.0226414, -0.0407372, -0.0303132,
00308 -0.0274939, -0.0230969, -0.0112391, -0.0295145, -0.0802241,
00309 -0.0119718, -0.0192763, -0.0325638, -0.01964, -0.0187867, -0.0341681};
00310
00311 double b2[21]={ 0.116963, 0.184845, 0.108203, 0.258461, 0.0990949,
00312 0.11335, 0.0541237, 0.109091, 0.144866, 0.106829,
00313 0.0942077, 0.0960772, 0.133047, 0.0779446, 0.151293,
00314 0.0855836, 0.07601, 0.121707, 0.11542, 0.111608, 0.133449};
00315
00316 double b3[21]={ 1.05823, 1.06982, 1.04692, 1.08131, 1.04635,
00317 1.05313, 1.06387, 1.04447, 1.05965, 1.06855,
00318 1.05192, 1.04673, 1.08641, 1.29738, 1.33545,
00319 1.30941, 1.3002, 1.30029, 1.24078, 1.27179, 1.239};
00320
00321 double y;
00322 if (std::abs(eta)<=1.0){
00323 int i = int( std::abs(eta)/0.1 );
00324 double x = (et>10)? et : 10;
00325 y = b2[i]*std::exp(b1[i]*x)+b3[i];
00326 } else if (std::abs(eta)<=3.2){
00327 int i = 10 + int( (std::abs(eta)-1.0)/0.2 );
00328 double x = (et>10)? et : 10;
00329 y = b2[i]*std::exp(b1[i]*x)+b3[i];
00330 } else {
00331 y = 1;
00332 }
00333
00334
00335
00336 return (y>1)? y/GeV : 1.0/GeV;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 void JetCalibrator::undoMuons(Jet* jet, ReconstructedParticleVector& muons )
00350 {
00351
00352 if (muons.size() == 0) return;
00353
00354 MsgStream log( messageService(), name() ) ;
00355
00356 ReconstructedParticleVector::const_iterator first = muons.begin() ;
00357 ReconstructedParticleVector::const_iterator last = muons.end() ;
00358 ReconstructedParticleVector::const_iterator itr;
00359 for (itr=first; itr!=last; ++itr) {
00360 log << MSG::DEBUG
00361 << "undoing muon with momentum: "
00362 << (*itr)->momentum()
00363 << endreq;
00364
00365 log << MSG::DEBUG << "Old jet momentum: " << *jet << endreq;
00366 jet->setMomentum(jet->momentum() - (*itr)->momentum());
00367 log << MSG::DEBUG << "New jet momentum: " << *jet << endreq ;
00368 }
00369
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 void JetCalibrator::addMuons(Jet* jet, ReconstructedParticleVector& muons )
00382 {
00383
00384 if (muons.size() == 0) return;
00385
00386 MsgStream log( messageService(), name() ) ;
00387
00388
00389 IAOO* ia = jet;
00390
00391 ReconstructedParticleVector::const_iterator first = muons.begin() ;
00392 ReconstructedParticleVector::const_iterator last = muons.end() ;
00393 ReconstructedParticleVector::const_iterator itr;
00394 for (itr=first; itr!=last; ++itr) {
00395 log << MSG::DEBUG
00396 << "Adding muon with momentum: "
00397 << (*itr)->momentum()
00398 << endreq;
00399
00400 log << MSG::DEBUG << "Old jet momentum: " << *jet << endreq;
00401 jet->setMomentum(jet->momentum() + (*itr)->momentum());
00402 log << MSG::DEBUG << "New jet momentum: " << *jet << endreq ;
00403
00404
00405 ia->associate(*itr);
00406 }
00407
00408 }
00409
00410
00411
00412
00413
00414 }
00415
00416
00417