00001 #include "Validation/Geometry/interface/MaterialBudgetForward.h"
00002
00003 #include "FWCore/Utilities/interface/Exception.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include "FWCore/ServiceRegistry/interface/Service.h"
00006 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00007
00008 #include "SimG4Core/Notification/interface/BeginOfRun.h"
00009 #include "SimG4Core/Notification/interface/BeginOfTrack.h"
00010 #include "SimG4Core/Notification/interface/EndOfTrack.h"
00011
00012 #include "G4LogicalVolumeStore.hh"
00013 #include "G4Step.hh"
00014 #include "G4Track.hh"
00015
00016 #include <iostream>
00017
00018 const int MaterialBudgetForward::maxSet;
00019
00020 MaterialBudgetForward::MaterialBudgetForward(const edm::ParameterSet& p) {
00021
00022 edm::ParameterSet m_p = p.getParameter<edm::ParameterSet>("MaterialBudgetForward");
00023 detTypes = m_p.getParameter<std::vector<std::string> >("DetectorTypes");
00024 constituents = m_p.getParameter<std::vector<int> >("Constituents");
00025 stackOrder = m_p.getParameter<std::vector<int> >("StackOrder");
00026 detNames = m_p.getParameter<std::vector<std::string> >("DetectorNames");
00027 detLevels = m_p.getParameter<std::vector<int> >("DetectorLevels");
00028 etaRegions = m_p.getParameter<std::vector<double> >("EtaBoundaries");
00029 regionTypes = m_p.getParameter<std::vector<int> >("RegionTypes");
00030 boundaries = m_p.getParameter<std::vector<double> >("Boundaries");
00031 edm::LogInfo("MaterialBudget") << "MaterialBudgetForward initialized for "
00032 << detTypes.size() << " detector types";
00033 unsigned int nc = 0;
00034 for (unsigned int ii=0; ii<detTypes.size(); ++ii) {
00035 edm::LogInfo("MaterialBudget") << "Type[" << ii << "] : " << detTypes[ii]
00036 << " with " << constituents[ii] <<", order "
00037 << stackOrder[ii] << " constituents --> ";
00038 for (int kk=0; kk<constituents[ii]; ++kk) {
00039 std::string name = "Unknown"; int level = -1;
00040 if (nc < detNames.size()) {
00041 name = detNames[nc]; level = detLevels[nc]; ++nc;
00042 }
00043 edm::LogInfo("MaterialBudget") << " Constituent[" << kk << "]: "
00044 << name << " at level " << level;
00045 }
00046 }
00047 edm::LogInfo("MaterialBudget") << "MaterialBudgetForward Stop condition for "
00048 << etaRegions.size() << " eta regions";
00049 for (unsigned int ii=0; ii<etaRegions.size(); ++ii) {
00050 edm::LogInfo("MaterialBudget") << "Region[" << ii << "] : Eta < "
00051 << etaRegions[ii] << " boundary type "
00052 << regionTypes[ii] << " limit "
00053 << boundaries[ii];
00054 }
00055 book(m_p);
00056 }
00057
00058 MaterialBudgetForward::~MaterialBudgetForward() {
00059 }
00060
00061 void MaterialBudgetForward::update(const BeginOfRun* ) {
00062
00063 const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
00064 std::vector<G4LogicalVolume *>::const_iterator lvcite;
00065
00066 unsigned int kount=detNames.size();
00067 for (unsigned int ii=0; ii<kount; ++ii)
00068 logVolumes.push_back(0);
00069
00070 for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
00071 for (unsigned int ii=0; ii<detNames.size(); ++ii) {
00072 if (strcmp(detNames[ii].c_str(),(*lvcite)->GetName().c_str()) == 0) {
00073 logVolumes[ii] = (*lvcite);
00074 kount--;
00075 break;
00076 }
00077 }
00078 if (kount <= 0) break;
00079 }
00080 edm::LogInfo("MaterialBudget") << "MaterialBudgetForward::Finds "
00081 << detNames.size()-kount << " out of "
00082 << detNames.size() << " LV addresses";
00083 for (unsigned int ii=0; ii<detNames.size(); ++ii) {
00084 std::string name("Unknown");
00085 if (logVolumes[ii] != 0) name = logVolumes[ii]->GetName();
00086 edm::LogInfo("MaterialBudget") << "LV[" << ii << "] : " << detNames[ii]
00087 << " Address " << logVolumes[ii] << " | "
00088 << name;
00089 }
00090
00091 for (unsigned int ii=0; ii<(detTypes.size()+1); ++ii) {
00092 stepLen.push_back(0); radLen.push_back(0); intLen.push_back(0);
00093 }
00094 stackOrder.push_back(0);
00095 }
00096
00097 void MaterialBudgetForward::update(const BeginOfTrack* trk) {
00098
00099 for (unsigned int ii=0; ii<(detTypes.size()+1); ++ii) {
00100 stepLen[ii] = 0; radLen[ii] = 0; intLen[ii] = 0;
00101 }
00102
00103 const G4Track * aTrack = (*trk)();
00104 const G4ThreeVector& mom = aTrack->GetMomentum() ;
00105 if (mom.theta() != 0 ) {
00106 eta = mom.eta();
00107 } else {
00108 eta = -99;
00109 }
00110 phi = mom.phi();
00111 stepT = 0;
00112
00113 double theEnergy = aTrack->GetTotalEnergy();
00114 int theID = (int)(aTrack->GetDefinition()->GetPDGEncoding());
00115 LogDebug("MaterialBudget") << "MaterialBudgetHcalHistos: Track "
00116 << aTrack->GetTrackID() << " Code " << theID
00117 << " Energy " <<theEnergy/CLHEP::GeV<<" GeV; Eta "
00118 << eta << " Phi " << phi/CLHEP::deg << " PT "
00119 << mom.perp()/CLHEP::GeV << " GeV *****";
00120 }
00121
00122 void MaterialBudgetForward::update(const G4Step* aStep) {
00123
00124
00125 G4Material * material = aStep->GetPreStepPoint()->GetMaterial();
00126 double step = aStep->GetStepLength();
00127 double radl = material->GetRadlen();
00128 double intl = material->GetNuclearInterLength();
00129
00130 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
00131 unsigned int indx = detTypes.size();
00132 unsigned int nc = 0;
00133 for (unsigned int ii=0; ii<detTypes.size(); ++ii) {
00134 for (int kk=0; kk<constituents[ii]; ++kk) {
00135 if (detLevels[nc+kk] <= (int)((touch->GetHistoryDepth())+1)) {
00136 int jj = (int)((touch->GetHistoryDepth())+1)-detLevels[nc+kk];
00137 if ((touch->GetVolume(jj)->GetLogicalVolume()) == logVolumes[nc+kk]) {
00138 indx = ii;
00139 break;
00140 }
00141 }
00142 }
00143 nc += (unsigned int)(constituents[ii]);
00144 if (indx == ii) break;
00145 }
00146
00147 stepT += step;
00148 stepLen[indx] = stepT;
00149 radLen[indx] += (step/radl);
00150 intLen[indx] += (step/intl);
00151 LogDebug("MaterialBudget") << "MaterialBudgetForward::Step in "
00152 << touch->GetVolume(0)->GetLogicalVolume()->GetName()
00153 << " Index " << indx <<" Step " << step <<" RadL "
00154 << step/radl << " IntL " << step/intl;
00155
00156
00157 if (stopAfter(aStep)) {
00158 G4Track* track = aStep->GetTrack();
00159 track->SetTrackStatus( fStopAndKill );
00160 }
00161 }
00162
00163
00164 void MaterialBudgetForward::update(const EndOfTrack* trk) {
00165
00166 for (unsigned int ii=0; ii<detTypes.size(); ++ii) {
00167 for (unsigned int jj=0; jj<=detTypes.size(); ++jj) {
00168 if (stackOrder[jj] == (int)(ii+1)) {
00169 for (unsigned int kk=0; kk<=detTypes.size(); ++kk) {
00170 if (stackOrder[kk] == (int)(ii)) {
00171 radLen[jj] += radLen[kk];
00172 intLen[jj] += intLen[kk];
00173 LogDebug("MaterialBudget") << "MaterialBudgetForward::Add " << kk
00174 << ":" << stackOrder[kk] << " to "
00175 << jj <<":" << stackOrder[jj] <<" RadL "
00176 << radLen[kk] << " : " << radLen[jj]
00177 << " IntL " << intLen[kk] << " : "
00178 << intLen[jj] <<" StepL " << stepLen[kk]
00179 << " : " << stepLen[jj];
00180 break;
00181 }
00182 }
00183 break;
00184 }
00185 }
00186 }
00187
00188 for (unsigned int ii=0; ii<=detTypes.size(); ++ii) {
00189 me100[ii]->Fill(eta, radLen[ii]);
00190 me200[ii]->Fill(eta, intLen[ii]);
00191 me300[ii]->Fill(eta, stepLen[ii]);
00192 me400[ii]->Fill(eta);
00193 me500[ii]->Fill(eta, phi, radLen[ii]);
00194 me600[ii]->Fill(eta, phi, intLen[ii]);
00195 me700[ii]->Fill(eta, phi, stepLen[ii]);
00196 me800[ii]->Fill(eta, phi);
00197
00198 std::string name("Unknown");
00199 if (ii < detTypes.size()) name = detTypes[ii];
00200 LogDebug("MaterialBudget") << "MaterialBudgetForward::Volume[" << ii
00201 << "]: " << name << " == Step " << stepLen[ii]
00202 << " RadL " << radLen[ii] << " IntL "
00203 << intLen[ii];
00204 }
00205 }
00206
00207 void MaterialBudgetForward::book(const edm::ParameterSet& m_p) {
00208
00209
00210 edm::Service<TFileService> tfile;
00211
00212 if ( !tfile.isAvailable() )
00213 throw cms::Exception("BadConfig") << "TFileService unavailable: "
00214 << "please add it to config file";
00215
00216 int binEta = m_p.getUntrackedParameter<int>("NBinEta", 320);
00217 int binPhi = m_p.getUntrackedParameter<int>("NBinPhi", 180);
00218 double minEta = m_p.getUntrackedParameter<double>("MinEta",-8.0);
00219 double maxEta = m_p.getUntrackedParameter<double>("MaxEta", 8.0);
00220 double maxPhi = CLHEP::pi;
00221 edm::LogInfo("MaterialBudget") << "MaterialBudgetForward: Booking user "
00222 << "histos === with " << binEta << " bins "
00223 << "in eta from " << minEta << " to "
00224 << maxEta << " and " << binPhi << " bins "
00225 << "in phi from " << -maxPhi << " to "
00226 << maxPhi;
00227
00228 char name[20], title[80];
00229 std::string named;
00230 for (int i=0; i<std::min((int)(detTypes.size()+1),maxSet); i++) {
00231 if (i >= (int)(detTypes.size())) named = "Unknown";
00232 else named = detTypes[i];
00233 sprintf(name, "%d", i+100);
00234 sprintf(title, "MB(X0) prof Eta in %s", named.c_str());
00235 me100[i] = tfile->make<TProfile>(name, title, binEta, minEta, maxEta);
00236 sprintf(name, "%d", i+200);
00237 sprintf(title, "MB(L0) prof Eta in %s", named.c_str());
00238 me200[i] = tfile->make<TProfile>(name, title, binEta, minEta, maxEta);
00239 sprintf(name, "%d", i+300);
00240 sprintf(title, "MB(Step) prof Eta in %s", named.c_str());
00241 me300[i] = tfile->make<TProfile>(name, title, binEta, minEta, maxEta);
00242 sprintf(name, "%d", i+400);
00243 sprintf(title, "Eta in %s", named.c_str());
00244 me400[i] = tfile->make<TH1F>(name, title, binEta, minEta, maxEta);
00245 sprintf(name, "%d", i+500);
00246 sprintf(title, "MB(X0) prof Eta Phi in %s", named.c_str());
00247 me500[i] = tfile->make<TProfile2D>(name, title, binEta/2, minEta, maxEta,
00248 binPhi/2, -maxPhi, maxPhi);
00249 sprintf(name, "%d", i+600);
00250 sprintf(title, "MB(L0) prof Eta Phi in %s", named.c_str());
00251 me600[i]= tfile->make<TProfile2D>(name, title, binEta/2, minEta, maxEta,
00252 binPhi/2, -maxPhi, maxPhi);
00253 sprintf(name, "%d", i+700);
00254 sprintf(title, "MB(Step) prof Eta Phi in %s", named.c_str());
00255 me700[i]= tfile->make<TProfile2D>(name, title, binEta/2, minEta, maxEta,
00256 binPhi/2, -maxPhi, maxPhi);
00257 sprintf(name, "%d", i+800);
00258 sprintf(title, "Eta vs Phi in %s", named.c_str());
00259 me800[i]= tfile->make<TH2F>(name, title, binEta/2, minEta, maxEta,
00260 binPhi/2, -maxPhi, maxPhi);
00261 }
00262
00263 edm::LogInfo("MaterialBudget") << "MaterialBudgetForward: Booking user "
00264 << "histos done ===";
00265
00266 }
00267
00268 bool MaterialBudgetForward::stopAfter(const G4Step* aStep) {
00269
00270 G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
00271 if (aStep->GetPostStepPoint() != 0)
00272 hitPoint = aStep->GetPostStepPoint()->GetPosition();
00273 double rr = hitPoint.perp();
00274 double zz = std::abs(hitPoint.z());
00275
00276 bool flag(false);
00277 for (unsigned int ii=0; ii<etaRegions.size(); ++ii) {
00278
00279 if (fabs(eta) < etaRegions[ii]) {
00280 if (regionTypes[ii] == 0) {
00281 if (rr >= boundaries[ii]-0.001) flag = true;
00282 } else {
00283 if (zz >= boundaries[ii]-0.001) flag = true;
00284 }
00285 if (flag)
00286 LogDebug("MaterialBudget") <<" MaterialBudgetForward::Stop after R = "
00287 << rr << " and Z = " << zz;
00288 break;
00289 }
00290 }
00291
00292 return flag;
00293 }