CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/SimG4CMS/Calo/src/HFShowerLibrary.cc

Go to the documentation of this file.
00001 
00002 // File: HFShowerLibrary.cc
00003 // Description: Shower library for Very forward hadron calorimeter
00005 
00006 #include "SimG4CMS/Calo/interface/HFShowerLibrary.h"
00007 #include "SimDataFormats/CaloHit/interface/HFShowerLibraryEventInfo.h"
00008 #include "DetectorDescription/Core/interface/DDFilter.h"
00009 #include "DetectorDescription/Core/interface/DDFilteredView.h"
00010 #include "DetectorDescription/Core/interface/DDValue.h"
00011 
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 
00014 #include "G4VPhysicalVolume.hh"
00015 #include "G4NavigationHistory.hh"
00016 #include "G4Step.hh"
00017 #include "G4Track.hh"
00018 #include "Randomize.hh"
00019 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00020 
00021 //#define DebugLog
00022 
00023 HFShowerLibrary::HFShowerLibrary(std::string & name, const DDCompactView & cpv,
00024                                  edm::ParameterSet const & p) : fibre(0),hf(0),
00025                                                                 emBranch(0),
00026                                                                 hadBranch(0),
00027                                                                 npe(0) {
00028   
00029 
00030   edm::ParameterSet m_HF  = p.getParameter<edm::ParameterSet>("HFShower");
00031   probMax                 = m_HF.getParameter<double>("ProbMax");
00032 
00033   edm::ParameterSet m_HS= p.getParameter<edm::ParameterSet>("HFShowerLibrary");
00034   edm::FileInPath fp       = m_HS.getParameter<edm::FileInPath>("FileName");
00035   std::string pTreeName    = fp.fullPath();
00036   backProb                 = m_HS.getParameter<double>("BackProbability");  
00037   std::string emName       = m_HS.getParameter<std::string>("TreeEMID");
00038   std::string hadName      = m_HS.getParameter<std::string>("TreeHadID");
00039   std::string branchEvInfo = m_HS.getUntrackedParameter<std::string>("BranchEvt","HFShowerLibraryEventInfos_hfshowerlib_HFShowerLibraryEventInfo");
00040   std::string branchPre    = m_HS.getUntrackedParameter<std::string>("BranchPre","HFShowerPhotons_hfshowerlib_");
00041   std::string branchPost   = m_HS.getUntrackedParameter<std::string>("BranchPost","_R.obj");
00042   verbose                  = m_HS.getUntrackedParameter<bool>("Verbosity",false);
00043   applyFidCut              = m_HS.getParameter<bool>("ApplyFiducialCut");
00044 
00045   if (pTreeName.find(".") == 0) pTreeName.erase(0,2);
00046   const char* nTree = pTreeName.c_str();
00047   hf                = TFile::Open(nTree);
00048 
00049   if (!hf->IsOpen()) { 
00050     edm::LogError("HFShower") << "HFShowerLibrary: opening " << nTree 
00051                               << " failed";
00052     throw cms::Exception("Unknown", "HFShowerLibrary") 
00053       << "Opening of " << pTreeName << " fails\n";
00054   } else {
00055     edm::LogInfo("HFShower") << "HFShowerLibrary: opening " << nTree 
00056                              << " successfully"; 
00057   }
00058 
00059   TTree* event = (TTree *) hf ->Get("Events");
00060   if (event) {
00061     std::string info = branchEvInfo + branchPost;
00062     TBranch *evtInfo = event->GetBranch(info.c_str());
00063     if (evtInfo) {
00064       loadEventInfo(evtInfo);
00065     } else {
00066       edm::LogError("HFShower") << "HFShowerLibrary: HFShowerLibrayEventInfo"
00067                                 << " Branch does not exist in Event";
00068       throw cms::Exception("Unknown", "HFShowerLibrary")
00069         << "Event information absent\n";
00070     }
00071   } else {
00072     edm::LogError("HFShower") << "HFShowerLibrary: Events Tree does not "
00073                               << "exist";
00074     throw cms::Exception("Unknown", "HFShowerLibrary")
00075       << "Events tree absent\n";
00076   }
00077   
00078   edm::LogInfo("HFShower") << "HFShowerLibrary: Library " << libVers 
00079                            << " ListVersion "   << listVersion 
00080                            << " Events Total " << totEvents << " and "
00081                            << evtPerBin << " per bin";
00082   edm::LogInfo("HFShower") << "HFShowerLibrary: Energies (GeV) with " 
00083                            << nMomBin   << " bins";
00084   for (int i=0; i<nMomBin; i++)
00085     edm::LogInfo("HFShower") << "HFShowerLibrary: pmom[" << i << "] = "
00086                              << pmom[i]/GeV << " GeV";
00087 
00088   std::string nameBr = branchPre + emName + branchPost;
00089   emBranch         = event->GetBranch(nameBr.c_str());
00090   if (verbose) emBranch->Print();
00091   nameBr           = branchPre + hadName + branchPost;
00092   hadBranch        = event->GetBranch(nameBr.c_str());
00093   if (verbose) hadBranch->Print();
00094   edm::LogInfo("HFShower") << "HFShowerLibrary:Branch " << emName 
00095                            << " has " << emBranch->GetEntries() 
00096                            << " entries and Branch " << hadName 
00097                            << " has " << hadBranch->GetEntries() 
00098                            << " entries";
00099   edm::LogInfo("HFShower") << "HFShowerLibrary::No packing information -"
00100                            << " Assume x, y, z are not in packed form";
00101 
00102   edm::LogInfo("HFShower") << "HFShowerLibrary: Maximum probability cut off " 
00103                            << probMax << "  Back propagation of light prob. "
00104                            << backProb ;
00105   
00106   G4String attribute = "ReadOutName";
00107   G4String value     = name;
00108   DDSpecificsFilter filter;
00109   DDValue           ddv(attribute,value,0);
00110   filter.setCriteria(ddv,DDSpecificsFilter::equals);
00111   DDFilteredView fv(cpv);
00112   fv.addFilter(filter);
00113   bool dodet = fv.firstChild();
00114   if (dodet) {
00115     DDsvalues_type sv(fv.mergedSpecifics());
00116 
00117     //Radius (minimum and maximum)
00118     int nR     = -1;
00119     std::vector<double> rTable = getDDDArray("rTable",sv,nR);
00120     rMin = rTable[0];
00121     rMax = rTable[nR-1];
00122     edm::LogInfo("HFShower") << "HFShowerLibrary: rMIN " << rMin/cm 
00123                              << " cm and rMax " << rMax/cm;
00124 
00125     //Delta phi
00126     int nEta   = -1;
00127     std::vector<double> etaTable = getDDDArray("etaTable",sv,nEta);
00128     int nPhi   = nEta + nR - 2;
00129     std::vector<double> phibin   = getDDDArray("phibin",sv,nPhi);
00130     dphi       = phibin[nEta-1];
00131     edm::LogInfo("HFShower") << "HFShowerLibrary: (Half) Phi Width of wedge " 
00132                              << dphi/deg;
00133 
00134     //Special Geometry parameters
00135     int ngpar = 7;
00136     gpar      = getDDDArray("gparHF",sv,ngpar);
00137     edm::LogInfo("HFShower") << "HFShowerLibrary: " << ngpar << " gpar (cm)";
00138     for (int ig=0; ig<ngpar; ig++)
00139       edm::LogInfo("HFShower") << "HFShowerLibrary: gpar[" << ig << "] = "
00140                                << gpar[ig]/cm << " cm";
00141   } else {
00142     edm::LogError("HFShower") << "HFShowerLibrary: cannot get filtered "
00143                               << " view for " << attribute << " matching "
00144                               << name;
00145     throw cms::Exception("Unknown", "HFShowerLibrary")
00146       << "cannot match " << attribute << " to " << name <<"\n";
00147   }
00148   
00149   fibre = new HFFibre(name, cpv, p);
00150   emPDG = epPDG = gammaPDG = 0;
00151   pi0PDG = etaPDG = nuePDG = numuPDG = nutauPDG= 0;
00152   anuePDG= anumuPDG = anutauPDG = geantinoPDG = 0;
00153 }
00154 
00155 HFShowerLibrary::~HFShowerLibrary() {
00156   if (hf)     hf->Close();
00157   if (fibre)  delete   fibre;  fibre  = 0;
00158 }
00159 
00160 void HFShowerLibrary::initRun(G4ParticleTable * theParticleTable) {
00161 
00162   G4String parName;
00163   emPDG = theParticleTable->FindParticle(parName="e-")->GetPDGEncoding();
00164   epPDG = theParticleTable->FindParticle(parName="e+")->GetPDGEncoding();
00165   gammaPDG = theParticleTable->FindParticle(parName="gamma")->GetPDGEncoding();
00166   pi0PDG = theParticleTable->FindParticle(parName="pi0")->GetPDGEncoding();
00167   etaPDG = theParticleTable->FindParticle(parName="eta")->GetPDGEncoding();
00168   nuePDG = theParticleTable->FindParticle(parName="nu_e")->GetPDGEncoding();
00169   numuPDG = theParticleTable->FindParticle(parName="nu_mu")->GetPDGEncoding();
00170   nutauPDG= theParticleTable->FindParticle(parName="nu_tau")->GetPDGEncoding();
00171   anuePDG = theParticleTable->FindParticle(parName="anti_nu_e")->GetPDGEncoding();
00172   anumuPDG= theParticleTable->FindParticle(parName="anti_nu_mu")->GetPDGEncoding();
00173   anutauPDG= theParticleTable->FindParticle(parName="anti_nu_tau")->GetPDGEncoding();
00174   geantinoPDG= theParticleTable->FindParticle(parName="geantino")->GetPDGEncoding();
00175 #ifdef DebugLog
00176   edm::LogInfo("HFShower") << "HFShowerLibrary: Particle codes for e- = " 
00177                            << emPDG << ", e+ = " << epPDG << ", gamma = " 
00178                            << gammaPDG << ", pi0 = " << pi0PDG << ", eta = " 
00179                            << etaPDG << ", geantino = " << geantinoPDG 
00180                            << "\n        nu_e = " << nuePDG << ", nu_mu = " 
00181                            << numuPDG << ", nu_tau = " << nutauPDG 
00182                            << ", anti_nu_e = " << anuePDG << ", anti_nu_mu = " 
00183                            << anumuPDG << ", anti_nu_tau = " << anutauPDG;
00184 #endif
00185 }
00186 
00187 
00188 std::vector<HFShowerLibrary::Hit> HFShowerLibrary::getHits(G4Step * aStep,
00189                                                            bool & ok,
00190                                                            double weight,
00191                                                            bool onlyLong) {
00192 
00193   G4StepPoint * preStepPoint  = aStep->GetPreStepPoint(); 
00194   G4StepPoint * postStepPoint = aStep->GetPostStepPoint(); 
00195   G4Track *     track    = aStep->GetTrack();
00196   // Get Z-direction 
00197   const G4DynamicParticle *aParticle = track->GetDynamicParticle();
00198   G4ThreeVector momDir = aParticle->GetMomentumDirection();
00199   //  double mom = aParticle->GetTotalMomentum();
00200 
00201   G4ThreeVector hitPoint = preStepPoint->GetPosition();   
00202   G4String      partType = track->GetDefinition()->GetParticleName();
00203   int           parCode  = track->GetDefinition()->GetPDGEncoding();
00204 
00205   std::vector<HFShowerLibrary::Hit> hit;
00206   ok = false;
00207   if (parCode == pi0PDG || parCode == etaPDG || parCode == nuePDG ||
00208       parCode == numuPDG || parCode == nutauPDG || parCode == anuePDG ||
00209       parCode == anumuPDG || parCode == anutauPDG || parCode == geantinoPDG) 
00210     return hit;
00211   ok = true;
00212 
00213   double tSlice = (postStepPoint->GetGlobalTime())/nanosecond;
00214   double pin    = preStepPoint->GetTotalEnergy();
00215   double pz     = momDir.z(); 
00216   double zint   = hitPoint.z(); 
00217 
00218   // if particle moves from interaction point or "backwards (halo)
00219   int backward = 0;
00220   if (pz * zint < 0.) backward = 1;
00221   
00222   double sphi   = sin(momDir.phi());
00223   double cphi   = cos(momDir.phi());
00224   double ctheta = cos(momDir.theta());
00225   double stheta = sin(momDir.theta());
00226 
00227 #ifdef DebugLog
00228   G4ThreeVector localPos = preStepPoint->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
00229   double zoff   = localPos.z() + 0.5*gpar[1];
00230   //  if (zoff < 0) zoff = 0;
00231   edm::LogInfo("HFShower") << "HFShowerLibrary: getHits " << partType
00232                            << " of energy " << pin/GeV << " GeV"
00233                            << "  dir.orts " << momDir.x() << ", " <<momDir.y() 
00234                            << ", " << momDir.z() << "  Pos x,y,z = " 
00235                            << hitPoint.x() << "," << hitPoint.y() << "," 
00236                            << hitPoint.z() << " (" << zoff 
00237                            << ")   sphi,cphi,stheta,ctheta  = " << sphi 
00238                            << ","  << cphi << ", " << stheta << "," << ctheta; 
00239 #endif    
00240                        
00241   if (parCode == emPDG || parCode == epPDG || parCode == gammaPDG ) {
00242     if (pin<pmom[nMomBin-1]) {
00243       interpolate(0, pin);
00244     } else {
00245       extrapolate(0, pin);
00246     }
00247   } else {
00248     if (pin<pmom[nMomBin-1]) {
00249       interpolate(1, pin);
00250     } else {
00251       extrapolate(1, pin);
00252     }
00253   }
00254     
00255   int nHit = 0;
00256   HFShowerLibrary::Hit oneHit;
00257   for (int i = 0; i < npe; i++) {
00258     double zv = std::abs(pe[i].z()); // abs local z  
00259 #ifdef DebugLog
00260     edm::LogInfo("HFShower") << "HFShowerLibrary: Hit " << i << " " << pe[i] << " zv " << zv;
00261 #endif
00262     if (zv <= gpar[1] && pe[i].lambda() > 0 && 
00263         (pe[i].z() >= 0 || (zv > gpar[0] && (!onlyLong)))) {
00264       int depth = 1;
00265       if (onlyLong) {
00266       } else if (backward == 0) {    // fully valid only for "front" particles
00267         if (pe[i].z() < 0) depth = 2;// with "front"-simulated shower lib.
00268       } else {                       // for "backward" particles - almost equal
00269         double r = G4UniformRand();  // share between L and S fibers
00270         if (r > 0.5) depth = 2;
00271       } 
00272       
00273 
00274       // Updated coordinate transformation from local
00275       //  back to global using two Euler angles: phi and theta
00276       double pex = pe[i].x();
00277       double pey = pe[i].y();
00278 
00279       double xx = pex*ctheta*cphi - pey*sphi + zv*stheta*cphi; 
00280       double yy = pex*ctheta*sphi + pey*cphi + zv*stheta*sphi;
00281       double zz = -pex*stheta + zv*ctheta;
00282 
00283       G4ThreeVector pos  = hitPoint + G4ThreeVector(xx,yy,zz);
00284       zv = std::abs(pos.z()) - gpar[4] - 0.5*gpar[1];
00285       G4ThreeVector lpos = G4ThreeVector(pos.x(),pos.y(),zv);
00286 
00287       zv = fibre->zShift(lpos,depth,0);     // distance to PMT !
00288 
00289       double r  = pos.perp();
00290       double p  = fibre->attLength(pe[i].lambda());
00291       double fi = pos.phi();
00292       if (fi < 0) fi += twopi;
00293       int    isect = int(fi/dphi) + 1;
00294       isect        = (isect + 1) / 2;
00295       double dfi   = ((isect*2-1)*dphi - fi);
00296       if (dfi < 0) dfi = -dfi;
00297       double dfir  = r * sin(dfi);
00298 #ifdef DebugLog
00299       edm::LogInfo("HFShower") << "HFShowerLibrary: Position shift " << xx 
00300                                << ", " << yy << ", "  << zz << ": " << pos 
00301                                << " R " << r << " Phi " << fi << " Section " 
00302                                << isect << " R*Dfi " << dfir << " Dist " << zv;
00303 #endif
00304       zz           = std::abs(pos.z());
00305       double r1    = G4UniformRand();
00306       double r2    = G4UniformRand();
00307       double r3    = -9999.;
00308       if (backward)     r3    = G4UniformRand();
00309       if (!applyFidCut) dfir += gpar[5];
00310 
00311 #ifdef DebugLog
00312       edm::LogInfo("HFShower") << "HFShowerLibrary: rLimits " << rInside(r)
00313                                << " attenuation " << r1 <<":" << exp(-p*zv) 
00314                                << " r2 " << r2 << " r3 " << r3 << " rDfi "  
00315                                << gpar[5] << " zz " 
00316                                << zz << " zLim " << gpar[4] << ":" 
00317                                << gpar[4]+gpar[1] << "\n"
00318                                << "  rInside(r) :" << rInside(r) 
00319                                << "  r1 <= exp(-p*zv) :" <<  (r1 <= exp(-p*zv))
00320                                << "  r2 <= probMax :"    <<  (r2 <= probMax*weight)
00321                                << "  r3 <= backProb :"   <<  (r3 <= backProb) 
00322                                << "  dfir > gpar[5] :"   <<  (dfir > gpar[5])
00323                                << "  zz >= gpar[4] :"    <<  (zz >= gpar[4])
00324                                << "  zz <= gpar[4]+gpar[1] :" 
00325                                << (zz <= gpar[4]+gpar[1]);   
00326 #endif
00327       if (rInside(r) && r1 <= exp(-p*zv) && r2 <= probMax*weight && 
00328           dfir > gpar[5] && zz >= gpar[4] && zz <= gpar[4]+gpar[1] && 
00329           r3 <= backProb && (depth != 2 || zz >= gpar[4]+gpar[0])) {
00330         oneHit.position = pos;
00331         oneHit.depth    = depth;
00332         oneHit.time     = (tSlice+(pe[i].t())+(fibre->tShift(lpos,depth,1)));
00333         hit.push_back(oneHit);
00334 #ifdef DebugLog
00335         edm::LogInfo("HFShower") << "HFShowerLibrary: Final Hit " << nHit 
00336                                  <<" position " << (hit[nHit].position) 
00337                                  << " Depth " << (hit[nHit].depth) <<" Time " 
00338                                  << tSlice << ":" << pe[i].t() << ":" 
00339                                  << fibre->tShift(lpos,depth,1) << ":" 
00340                                  << (hit[nHit].time);
00341 #endif
00342         nHit++;
00343       }
00344 #ifdef DebugLog
00345       else  LogDebug("HFShower") << "HFShowerLibrary: REJECTED !!!";
00346 #endif
00347       if (onlyLong && zz >= gpar[4]+gpar[0] && zz <= gpar[4]+gpar[1]) {
00348         r1    = G4UniformRand();
00349         r2    = G4UniformRand();
00350         if (rInside(r) && r1 <= exp(-p*zv) && r2 <= probMax && dfir > gpar[5]){
00351           oneHit.position = pos;
00352           oneHit.depth    = 2;
00353           oneHit.time     = (tSlice+(pe[i].t())+(fibre->tShift(lpos,2,1)));
00354           hit.push_back(oneHit);
00355 #ifdef DebugLog
00356           edm::LogInfo("HFShower") << "HFShowerLibrary: Final Hit " << nHit 
00357                                    << " position " << (hit[nHit].position) 
00358                                    << " Depth " << (hit[nHit].depth) <<" Time "
00359                                    << tSlice << ":" << pe[i].t() << ":" 
00360                                    << fibre->tShift(lpos,2,1) << ":" 
00361                                    << (hit[nHit].time);
00362 #endif
00363           nHit++;
00364         }
00365       }
00366     }
00367   }
00368 
00369 #ifdef DebugLog
00370   edm::LogInfo("HFShower") << "HFShowerLibrary: Total Hits " << nHit
00371                            << " out of " << npe << " PE";
00372 #endif
00373   if (nHit > npe && !onlyLong)
00374     edm::LogWarning("HFShower") << "HFShowerLibrary: Hit buffer " << npe 
00375                                 << " smaller than " << nHit << " Hits";
00376   return hit;
00377 
00378 }
00379 
00380 bool HFShowerLibrary::rInside(double r) {
00381 
00382   if (r >= rMin && r <= rMax) return true;
00383   else                        return false;
00384 }
00385 
00386 void HFShowerLibrary::getRecord(int type, int record) {
00387 
00388   int nrc     = record-1;
00389   photon.clear();
00390   if (type > 0) {
00391     hadBranch->SetAddress(&photon);
00392     hadBranch->GetEntry(nrc);
00393   } else {
00394     emBranch->SetAddress(&photon);
00395     emBranch->GetEntry(nrc);
00396   }
00397 #ifdef DebugLog
00398   int nPhoton = photon.size();
00399   LogDebug("HFShower") << "HFShowerLibrary::getRecord: Record " << record
00400                        << " of type " << type << " with " << nPhoton 
00401                        << " photons";
00402   for (int j = 0; j < nPhoton; j++) 
00403     LogDebug("HFShower") << "Photon " << j << " " << photon[j];
00404 #endif
00405 }
00406 
00407 void HFShowerLibrary::loadEventInfo(TBranch* branch) {
00408 
00409   std::vector<HFShowerLibraryEventInfo> eventInfoCollection;
00410   branch->SetAddress(&eventInfoCollection);
00411   branch->GetEntry(0);
00412   edm::LogInfo("HFShower") << "HFShowerLibrary::loadEventInfo loads "
00413                            << " EventInfo Collection of size "
00414                            << eventInfoCollection.size() << " records";
00415   totEvents   = eventInfoCollection[0].totalEvents();
00416   nMomBin     = eventInfoCollection[0].numberOfBins();
00417   evtPerBin   = eventInfoCollection[0].eventsPerBin();
00418   libVers     = eventInfoCollection[0].showerLibraryVersion();
00419   listVersion = eventInfoCollection[0].physListVersion();
00420   pmom        = eventInfoCollection[0].energyBins();
00421   for (unsigned int i=0; i<pmom.size(); i++) 
00422     pmom[i] *= GeV;
00423 }
00424 
00425 void HFShowerLibrary::interpolate(int type, double pin) {
00426 
00427 #ifdef DebugLog
00428   LogDebug("HFShower") << "HFShowerLibrary:: Interpolate for Energy " <<pin/GeV
00429                        << " GeV with " << nMomBin << " momentum bins and " 
00430                        << evtPerBin << " entries/bin -- total " << totEvents;
00431 #endif
00432   int irc[2];
00433   double w = 0.;
00434   double r = G4UniformRand();
00435 
00436   if (pin<pmom[0]) {
00437     w = pin/pmom[0];
00438     irc[1] = int(evtPerBin*r) + 1;
00439     irc[0] = 0;
00440   } else {
00441     for (int j=0; j<nMomBin-1; j++) {
00442       if (pin >= pmom[j] && pin < pmom[j+1]) {
00443         w = (pin-pmom[j])/(pmom[j+1]-pmom[j]);
00444         if (j == nMomBin-2) { 
00445           irc[1] = int(evtPerBin*0.5*r);
00446         } else {
00447           irc[1] = int(evtPerBin*r);
00448         }
00449         irc[1] += (j+1)*evtPerBin + 1;
00450         r = G4UniformRand();
00451         irc[0] = int(evtPerBin*r) + 1 + j*evtPerBin;
00452         if (irc[0]<0) {
00453           edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[0] = "
00454                                       << irc[0] << " now set to 0";
00455           irc[0] = 0;
00456         } else if (irc[0] > totEvents) {
00457           edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[0] = "
00458                                       << irc[0] << " now set to "<< totEvents;
00459           irc[0] = totEvents;
00460         }
00461       }
00462     }
00463   }
00464   if (irc[1]<1) {
00465     edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[1] = " 
00466                                 << irc[1] << " now set to 1";
00467     irc[1] = 1;
00468   } else if (irc[1] > totEvents) {
00469     edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[1] = " 
00470                                 << irc[1] << " now set to "<< totEvents;
00471     irc[1] = totEvents;
00472   }
00473 
00474 #ifdef DebugLog
00475   LogDebug("HFShower") << "HFShowerLibrary:: Select records " << irc[0] 
00476                        << " and " << irc[1] << " with weights " << 1-w 
00477                        << " and " << w;
00478 #endif
00479   pe.clear(); 
00480   npe       = 0;
00481   int npold = 0;
00482   for (int ir=0; ir < 2; ir++) {
00483     if (irc[ir]>0) {
00484       getRecord (type, irc[ir]);
00485       int nPhoton = photon.size();
00486       npold      += nPhoton;
00487       for (int j=0; j<nPhoton; j++) {
00488         r = G4UniformRand();
00489         if ((ir==0 && r > w) || (ir > 0 && r < w)) {
00490           storePhoton (j);
00491         }
00492       }
00493     }
00494   }
00495 
00496   if (npe > npold || (npold == 0 && irc[0] > 0)) 
00497     edm::LogWarning("HFShower") << "HFShowerLibrary: Interpolation Warning =="
00498                                 << " records " << irc[0] << " and " << irc[1]
00499                                 << " gives a buffer of " << npold 
00500                                 << " photons and fills " << npe << " *****";
00501 #ifdef DebugLog
00502   else
00503     LogDebug("HFShower") << "HFShowerLibrary: Interpolation == records " 
00504                          << irc[0] << " and " << irc[1] << " gives a "
00505                          << "buffer of " << npold << " photons and fills "
00506                          << npe << " PE";
00507   for (int j=0; j<npe; j++)
00508     LogDebug("HFShower") << "Photon " << j << " " << pe[j];
00509 #endif
00510 }
00511 
00512 void HFShowerLibrary::extrapolate(int type, double pin) {
00513 
00514   int nrec   = int(pin/pmom[nMomBin-1]);
00515   double w   = (pin - pmom[nMomBin-1]*nrec)/pmom[nMomBin-1];
00516   nrec++;
00517 #ifdef DebugLog
00518   LogDebug("HFShower") << "HFShowerLibrary:: Extrapolate for Energy " << pin 
00519                        << " GeV with " << nMomBin << " momentum bins and " 
00520                        << evtPerBin << " entries/bin -- total " << totEvents 
00521                        << " using " << nrec << " records";
00522 #endif
00523   std::vector<int> irc(nrec);
00524 
00525   for (int ir=0; ir<nrec; ir++) {
00526     double r = G4UniformRand();
00527     irc[ir] = int(evtPerBin*0.5*r) +(nMomBin-1)*evtPerBin + 1;
00528     if (irc[ir]<1) {
00529       edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[" << ir 
00530                                   << "] = " << irc[ir] << " now set to 1";
00531       irc[ir] = 1;
00532     } else if (irc[ir] > totEvents) {
00533       edm::LogWarning("HFShower") << "HFShowerLibrary:: Illegal irc[" << ir 
00534                                   << "] = " << irc[ir] << " now set to "
00535                                   << totEvents;
00536       irc[ir] = totEvents;
00537 #ifdef DebugLog
00538     } else {
00539       LogDebug("HFShower") << "HFShowerLibrary::Extrapolation use irc[" 
00540                            << ir  << "] = " << irc[ir];
00541 #endif
00542     }
00543   }
00544 
00545   pe.clear(); 
00546   npe       = 0;
00547   int npold = 0;
00548   for (int ir=0; ir<nrec; ir++) {
00549     if (irc[ir]>0) {
00550       getRecord (type, irc[ir]);
00551       int nPhoton = photon.size();
00552       npold      += nPhoton;
00553       for (int j=0; j<nPhoton; j++) {
00554         double r = G4UniformRand();
00555         if (ir != nrec-1 || r < w) {
00556           storePhoton (j);
00557         }
00558       }
00559 #ifdef DebugLog
00560       LogDebug("HFShower") << "HFShowerLibrary: Record [" << ir << "] = " 
00561                            << irc[ir] << " npold = " << npold;
00562 #endif
00563     }
00564   }
00565 #ifdef DebugLog
00566   LogDebug("HFShower") << "HFShowerLibrary:: uses " << npold << " photons";
00567 #endif
00568 
00569   if (npe > npold || npold == 0)
00570     edm::LogWarning("HFShower") << "HFShowerLibrary: Extrapolation Warning == "
00571                                 << nrec << " records " << irc[0] << ", " 
00572                                 << irc[1] << ", ... gives a buffer of " <<npold
00573                                 << " photons and fills " << npe 
00574                                 << " *****";
00575 #ifdef DebugLog
00576   else
00577     LogDebug("HFShower") << "HFShowerLibrary: Extrapolation == " << nrec
00578                          << " records " << irc[0] << ", " << irc[1] 
00579                          << ", ... gives a buffer of " << npold 
00580                          << " photons and fills " << npe << " PE";
00581   for (int j=0; j<npe; j++)
00582     LogDebug("HFShower") << "Photon " << j << " " << pe[j];
00583 #endif
00584 }
00585 
00586 void HFShowerLibrary::storePhoton(int j) {
00587 
00588   pe.push_back(photon[j]);
00589 #ifdef DebugLog
00590   LogDebug("HFShower") << "HFShowerLibrary: storePhoton " << j << " npe " 
00591                        << npe << " " << pe[npe];
00592 #endif
00593   npe++;
00594 }
00595 
00596 std::vector<double> HFShowerLibrary::getDDDArray(const std::string & str, 
00597                                                  const DDsvalues_type & sv, 
00598                                                  int & nmin) {
00599 
00600 #ifdef DebugLog
00601   LogDebug("HFShower") << "HFShowerLibrary:getDDDArray called for " << str 
00602                        << " with nMin " << nmin;
00603 #endif
00604   DDValue value(str);
00605   if (DDfetch(&sv,value)) {
00606 #ifdef DebugLog
00607     LogDebug("HFShower") << value;
00608 #endif
00609     const std::vector<double> & fvec = value.doubles();
00610     int nval = fvec.size();
00611     if (nmin > 0) {
00612       if (nval < nmin) {
00613         edm::LogError("HFShower") << "HFShowerLibrary : # of " << str 
00614                                   << " bins " << nval << " < " << nmin 
00615                                   << " ==> illegal";
00616         throw cms::Exception("Unknown", "HFShowerLibrary")
00617           << "nval < nmin for array " << str << "\n";
00618       }
00619     } else {
00620       if (nval < 2) {
00621         edm::LogError("HFShower") << "HFShowerLibrary : # of " << str 
00622                                   << " bins " << nval << " < 2 ==> illegal"
00623                                   << " (nmin=" << nmin << ")";
00624         throw cms::Exception("Unknown", "HFShowerLibrary")
00625           << "nval < 2 for array " << str << "\n";
00626       }
00627     }
00628     nmin = nval;
00629 
00630     return fvec;
00631   } else {
00632     edm::LogError("HFShower") << "HFShowerLibrary : cannot get array " << str;
00633     throw cms::Exception("Unknown", "HFShowerLibrary") 
00634       << "cannot get array " << str << "\n";
00635   }
00636 }