File indexing completed on 2024-06-26 07:05:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "eicsmear/smear/Detector.h"
0011
0012 #include <algorithm>
0013 #include <functional>
0014 #include <list>
0015 #include <memory>
0016 #include <vector>
0017
0018 #include "eicsmear/erhic/EventDis.h"
0019 #include "eicsmear/smear/EventSmear.h"
0020 #include "eicsmear/erhic/Kinematics.h"
0021 #include "eicsmear/smear/ParticleMCS.h"
0022 #include "eicsmear/smear/Smearer.h"
0023 #include "eicsmear/erhic/VirtualParticle.h"
0024
0025 using std::cout;
0026 using std::cerr;
0027 using std::endl;
0028
0029 namespace Smear {
0030
0031 Detector::Detector()
0032 : useNM(false)
0033 , useJB(false)
0034 , useDA(false) {
0035 }
0036
0037 Detector::Detector(const Detector& other)
0038 : TObject(other) {
0039 useNM = other.useNM;
0040 useJB = other.useJB;
0041 useDA = other.useDA;
0042 Devices = other.CopyDevices();
0043 LegacyMode = other.GetLegacyMode();
0044 }
0045
0046 Detector& Detector::operator=(const Detector& that) {
0047 if (this != &that) {
0048 useNM = that.useNM;
0049 useJB = that.useJB;
0050 useDA = that.useDA;
0051 Devices = that.CopyDevices();
0052 LegacyMode = that.GetLegacyMode();
0053 }
0054 return *this;
0055 }
0056
0057 Detector::~Detector() {
0058 DeleteAllDevices();
0059 }
0060
0061 void Detector::DeleteAllDevices() {
0062 for (unsigned i(0); i < GetNDevices(); i++) {
0063 delete Devices.at(i);
0064 Devices.at(i) = NULL;
0065 }
0066 Devices.clear();
0067 }
0068
0069 void Detector::AddDevice(Smearer& dev) {
0070 Devices.push_back(dev.Clone());
0071 }
0072
0073 void Detector::SetEventKinematicsCalculator(TString s) {
0074 s.ToLower();
0075 useNM = s.Contains("nm") || s.Contains("null");
0076 useJB = s.Contains("jb") || s.Contains("jacquet");
0077 useDA = s.Contains("da") || s.Contains("double");
0078 }
0079
0080 Smearer* Detector::GetDevice(int n) {
0081 Smearer* smearer(NULL);
0082 if (unsigned(n) < Devices.size()) {
0083 smearer = Devices.at(n);
0084 }
0085 return smearer;
0086 }
0087
0088 void Detector::FillEventKinematics(Event* eventS) {
0089 if (!(useNM || useJB || useDA)) {
0090 return;
0091 }
0092
0093
0094
0095
0096
0097 const ParticleMCS* scattered = eventS->ScatteredLepton();
0098 typedef std::unique_ptr<erhic::DisKinematics> KinPtr;
0099 if (useNM && scattered) {
0100 KinPtr kin(erhic::LeptonKinematicsComputer(*eventS).Calculate());
0101 if (kin.get()) {
0102 eventS->SetLeptonKinematics(*kin);
0103 }
0104 } else {
0105 eventS->SetLeptonKinematics( erhic::DisKinematics(-1., -1., -1., -1., -1.));
0106 }
0107 if (useJB) {
0108 KinPtr kin(erhic::JacquetBlondelComputer(*eventS).Calculate());
0109 if (kin.get()) {
0110 eventS->SetJacquetBlondelKinematics(*kin);
0111 }
0112 }
0113 if (useDA && scattered) {
0114 KinPtr kin(erhic::DoubleAngleComputer(*eventS).Calculate());
0115 if (kin.get()) {
0116 eventS->SetDoubleAngleKinematics(*kin);
0117 }
0118 }
0119 }
0120
0121 std::list<Smearer*> Detector::Accept(const erhic::VirtualParticle& p) const {
0122 std::list<Smearer*> devices;
0123
0124
0125 if (p.GetStatus() == 1) {
0126 std::vector<Smearer*>::const_iterator iter;
0127 for (iter = Devices.begin(); iter != Devices.end(); ++iter) {
0128
0129 if ((*iter)->Accept.Is(p)) {
0130 devices.push_back(*iter);
0131 }
0132 }
0133 }
0134 return devices;
0135 }
0136
0137 ParticleMCS* Detector::Smear(const erhic::VirtualParticle& prt) const {
0138
0139
0140 std::list<Smearer*> devices = Accept(prt);
0141 ParticleMCS* prtOut(NULL);
0142 if (!devices.empty()) {
0143
0144
0145 prtOut = new ParticleMCS();
0146 prtOut->SetSmeared();
0147 std::list<Smearer*>::iterator iter;
0148 for (iter = devices.begin(); iter != devices.end(); ++iter) {
0149 (*iter)->Smear(prt, *prtOut);
0150 }
0151
0152 if (LegacyMode){
0153
0154 prtOut->SetPx( prtOut->GetP() * sin(prtOut->GetTheta()) * cos(prtOut->GetPhi()));
0155 prtOut->SetPy( prtOut->GetP() * sin(prtOut->GetTheta()) * sin(prtOut->GetPhi()));
0156 prtOut->SetPt( sqrt(pow(prtOut->GetPx(), 2.) + pow(prtOut->GetPy(), 2.)));
0157 prtOut->SetPz( prtOut->GetP() * cos(prtOut->GetTheta()));
0158
0159 } else {
0160
0161
0162
0163 if ( !prtOut->IsSmeared() ) throw std::runtime_error ("particle seems to be not smeared?!");
0164
0165
0166 int MomComponentsChanged = prtOut->IsPSmeared() + prtOut->IsPtSmeared() + prtOut->IsPxSmeared() + prtOut->IsPySmeared() + prtOut->IsPzSmeared();
0167 int AngComponentsChanged = prtOut->IsPhiSmeared() + prtOut->IsThetaSmeared();
0168
0169 if ( MomComponentsChanged==0 ){
0170
0171
0172 if ( !prtOut->IsPhiSmeared() ) {
0173 cerr << "Phi always needs to be smeared (at least with sigma=0)" << endl;
0174 cerr << "For legacy smear scripts, use det.SetLegacyMode ( true );" << endl;
0175 throw std::runtime_error ("Failed consistency check in Detector::Smear()");
0176 }
0177 if ( !prtOut->IsThetaSmeared() ){
0178 cerr << "Theta always needs to be smeared (at least with sigma=0)" << endl;
0179 cerr << "For legacy smear scripts, use det.SetLegacyMode ( true );" << endl;
0180 throw std::runtime_error ("Failed consistency check in Detector::Smear()");
0181 }
0182 } else if ( MomComponentsChanged + AngComponentsChanged != 3){
0183
0184 cerr << "Expected 0 (excluding phi, theta) or exactly 3 (excluding phi, theta) smeared momentum quantities." << endl;
0185 cerr << "For legacy smear scripts, use det.SetLegacyMode ( true );" << endl;
0186 cerr << "MomComponentsChanged = " << MomComponentsChanged << endl;
0187 cerr << prt.GetEta() << endl;
0188 cerr << prtOut->IsPSmeared() << endl;
0189 cerr << prtOut->IsPtSmeared() << endl;
0190 cerr << prtOut->IsPxSmeared() << endl;
0191 cerr << prtOut->IsPySmeared() << endl;
0192 cerr << prtOut->IsPzSmeared() << endl;
0193 cerr << "AngComponentsChanged = " << AngComponentsChanged << endl;
0194 cerr << " pid : " << prt.Id() << endl;
0195 throw std::runtime_error ("Failed consistency check in Detector::Smear()");
0196 } else {
0197
0198
0199
0200
0201
0202
0203
0204 if ( prtOut->IsPxSmeared() ^ prtOut->IsPySmeared() ) {
0205 cerr << "Smearing only one out of px, py is not supported. Please contact the authors." << endl;
0206 cerr << "For legacy smear scripts, use det.SetLegacyMode ( true );" << endl;
0207 throw std::runtime_error ("Failed consistency check in Detector::Smear()");
0208 }
0209
0210 if ( prtOut->IsPxSmeared() && prtOut->IsPySmeared() ) {
0211 if ( prtOut->IsPhiSmeared() ) {
0212 cerr << "Smearing px, py, and phi is inconsistent" << endl;
0213 cerr << "For legacy smear scripts, use det.SetLegacyMode ( true );" << endl;
0214 throw std::runtime_error ("Failed consistency check in Detector::Smear()");
0215 }
0216 if ( prtOut->IsPtSmeared() ) {
0217 cerr << "Smearing px, py, and pt is inconsistent" << endl;
0218 cerr << "For legacy smear scripts, use det.SetLegacyMode ( true );" << endl;
0219 throw std::runtime_error ("Failed consistency check in Detector::Smear()");
0220 }
0221
0222
0223 prtOut->SetPhi( std::atan2( prtOut->GetPy(),prtOut->GetPx() ) );
0224 prtOut->SetPt( std::sqrt( std::pow( prtOut->GetPx(),2) + std::pow( prtOut->GetPy(),2) ) );
0225
0226
0227 if ( prtOut->IsPzSmeared() ){
0228 prtOut->SetTheta( std::atan2(prtOut->GetPt() ,prtOut->GetPz() ) );
0229 prtOut->SetP( std::sqrt( std::pow( prtOut->GetPt(),2) + std::pow( prtOut->GetPz(),2) ) );
0230 }
0231
0232 if ( prtOut->IsPSmeared() ){
0233 if ( prtOut->GetP() < prtOut->GetPt() ) prtOut->SetP(prtOut->GetPt(), false);
0234 prtOut->SetTheta( std::atan2(prtOut->GetPt() ,prtOut->GetPz() ) );
0235 prtOut->SetPz( std::sqrt( std::pow(prtOut->GetP(), 2.) - std::pow(prtOut->GetPt(), 2.)) );
0236 }
0237
0238 if ( prtOut->IsThetaSmeared() ){
0239
0240
0241 assert ( fabs(std::tan(prtOut->GetTheta())) > 1e-8 );
0242 prtOut->SetPz( prtOut->GetPt() / std::tan(prtOut->GetTheta()) );
0243 prtOut->SetP( std::sqrt( std::pow( prtOut->GetPt(),2) + std::pow( prtOut->GetPz(),2) ) );
0244 }
0245
0246 }
0247
0248
0249
0250
0251 if ( !prtOut->IsPhiSmeared() ) {
0252 cerr << "Momentum components are smeared, but neither phi nor px and py are." << endl;
0253 cerr << "For legacy smear scripts, use det.SetLegacyMode ( true );" << endl;
0254 throw std::runtime_error ("Failed consistency check in Detector::Smear()");
0255 }
0256
0257
0258
0259 if ( !prtOut->IsPxSmeared() && !prtOut->IsPySmeared() ) {
0260
0261
0262
0263 if(prtOut->IsPSmeared() && prtOut->IsThetaSmeared() ) {
0264
0265 prtOut->SetPt ( prtOut->GetP() * std::sin(prtOut->GetTheta()));
0266 prtOut->SetPz ( prtOut->GetP() * std::cos(prtOut->GetTheta()));
0267
0268 } else if( prtOut->IsPSmeared() && prtOut->IsPtSmeared() ) {
0269 if ( prtOut->GetP() < prtOut->GetPt() ) prtOut->SetP(prtOut->GetPt(), false);
0270 prtOut->SetPz( std::sqrt(std::pow(prtOut->GetP(), 2) - std::pow(prtOut->GetPt(), 2)));
0271 prtOut->SetTheta ( std::atan2(prtOut->GetPt(),prtOut->GetPz()));
0272
0273 } else if(prtOut->IsPzSmeared() && prtOut->IsPtSmeared() ) {
0274
0275 prtOut->SetP( std::sqrt(std::pow(prtOut->GetPt(), 2) + std::pow(prtOut->GetPz(), 2)));
0276 prtOut->SetTheta ( std::atan2(prtOut->GetPt(),prtOut->GetPz()));
0277
0278 } else if(prtOut->IsThetaSmeared() && prtOut->IsPtSmeared()) {
0279
0280
0281 assert ( fabs(std::tan(prtOut->GetTheta())) > 1e-8 );
0282 prtOut->SetPz( prtOut->GetPt() / std::tan(prtOut->GetTheta()) );
0283 prtOut->SetP( std::sqrt(std::pow(prtOut->GetPt(), 2) + std::pow(prtOut->GetPz(), 2)));
0284
0285 } else if(prtOut->IsPSmeared() && prtOut->IsPzSmeared()) {
0286 if ( prtOut->GetP() < std::abs(prtOut->GetPz()) ) prtOut->SetP( std::abs(prtOut->GetPz()), false);
0287 prtOut->SetPt( std::sqrt(std::pow(prtOut->GetP(), 2) - std::pow(prtOut->GetPz(), 2)));
0288 prtOut->SetTheta( std::atan2(prtOut->GetPt() ,prtOut->GetPz() ) );
0289
0290 } else if(prtOut->IsThetaSmeared() && prtOut->IsPzSmeared()) {
0291
0292 prtOut->SetPt( prtOut->GetPz() * std::tan(prtOut->GetTheta()));
0293 prtOut->SetP( std::sqrt( std::pow( prtOut->GetPt(),2) + std::pow( prtOut->GetPz(),2) ) );
0294 }
0295
0296 prtOut->SetPx (prtOut->GetP() * std::sin(prtOut->GetTheta()) * std::cos(prtOut->GetPhi()));
0297 prtOut->SetPy (prtOut->GetP() * std::sin(prtOut->GetTheta()) * std::sin(prtOut->GetPhi()));
0298
0299 }
0300
0301 }
0302
0303 }
0304 }
0305
0306
0307 return prtOut;
0308
0309 }
0310
0311 std::vector<Smearer*> Detector::CopyDevices() const {
0312 std::vector<Smearer*> copies;
0313 for ( std::vector<Smearer*>::const_iterator it = Devices.begin();
0314 it!=Devices.end();
0315 ++it ){
0316 copies.push_back ( (*it)->Clone(""));
0317 }
0318 return copies;
0319 }
0320
0321 void Detector::Print(Option_t* o) const {
0322 for (unsigned i(0); i < GetNDevices(); ++i) {
0323 Devices.at(i)->Print(o);
0324 }
0325 }
0326
0327 void Detector::SetLegacyMode( const bool mode ){
0328 LegacyMode = mode;
0329 if ( LegacyMode ){
0330 std::cout << "Warning: Turning on legacy mode, i.e. deactivating consistency checks and momentum regularization in Smear(). Use only for legacy smear scripts from earlier versions (<~1.0.4)" << endl;
0331 }
0332 }
0333
0334 bool Detector::GetLegacyMode() const {
0335 return LegacyMode;
0336 }
0337
0338 }