src/BDSOutput.cc

00001 #include "BDSExecOptions.hh"
00002 #include "BDSOutput.hh"
00003 #include "BDSSamplerSD.hh"
00004 #include <ctime>
00005 
00006 // extern G4String outputFilename;
00007 
00008 BDSOutput::BDSOutput():outputFileNumber(1)
00009 {
00010   format = _ASCII; // default - write an ascii file
00011 #ifdef USE_ROOT
00012 #ifdef DEBUG
00013   G4cout << __METHOD_NAME__ << " - USE_ROOT is defined." << G4endl;
00014 #endif
00015   theRootOutputFile = NULL;
00016   EnergyLossHisto = NULL;
00017   PrecisionRegionEnergyLossTree = NULL;
00018   EnergyLossTree = NULL;
00019 #endif
00020 }
00021 
00022 BDSOutput::BDSOutput(BDSOutputFormat fmt):format(fmt),outputFileNumber(1)
00023 {
00024 #ifdef USE_ROOT
00025 #ifdef DEBUG
00026   G4cout << __METHOD_NAME__ << " - USE_ROOT is defined." << G4endl;
00027 #endif
00028   theRootOutputFile = NULL;
00029   EnergyLossHisto = NULL;
00030   PrecisionRegionEnergyLossTree = NULL;
00031   EnergyLossTree = NULL;
00032 #endif
00033 }
00034 
00035 BDSOutput::~BDSOutput()
00036 {
00037   if(format==_ASCII){
00038     of.close();
00039     ofEloss.close();
00040   }
00041 #ifdef USE_ROOT
00042   if(format==_ROOT){
00043     if (theRootOutputFile && theRootOutputFile->IsOpen()) {
00044       theRootOutputFile->Close();
00046       delete theRootOutputFile;
00047     }
00048   }
00049 #endif
00050 }
00051 
00052 void BDSOutput::SetFormat(BDSOutputFormat val)
00053 {
00054   format = val;
00055   time_t tm = time(NULL);
00056 
00057   if( format == _ASCII)
00058     {
00059       G4String filename = BDSExecOptions::Instance()->GetOutputFilename()+".txt";
00060       G4cout << __METHOD_NAME__ << "Output format ASCII, filename: "<<filename<<G4endl;
00061       of.open(filename);
00062       of<<"### BDSIM output created "<<ctime(&tm)<<" ####"<<G4endl;
00063       of<<"# PT E[GeV] X[mum] Y[mum] Z[m] Xp[rad] Yp[rad]  NEvent Weight ParentID TrackID"<<G4endl;
00064       G4String filenameEloss = BDSExecOptions::Instance()->GetOutputFilename()+".eloss.txt";
00065       G4cout << __METHOD_NAME__ << "Eloss output format ASCII, filename: "<<filenameEloss<<G4endl;
00066       ofEloss.open(filenameEloss);
00067       ofEloss<<"### BDSIM eloss output created "<<ctime(&tm)<<" ####"<<G4endl;
00068       ofEloss<<"#Energy loss: Z[m] E[GeV] partID weight"<<G4endl;
00069 
00070     }
00071   if( format == _ROOT)
00072     {
00073       G4cout<<"output format ROOT"<<G4endl;
00074     }
00075 }
00076 
00077 // output initialization (ROOT only)
00078 void BDSOutput::Init(G4int FileNum)
00079 {
00080 #ifdef USE_ROOT
00081   if(format != _ROOT) return;
00082 
00083   // set up the root file
00084   G4String _filename = BDSExecOptions::Instance()->GetOutputFilename() + "_" 
00085     + BDSGlobalConstants::Instance()->StringFromInt(FileNum) + ".root";
00086   
00087   G4cout<<"Setting up new file: "<<_filename<<G4endl;
00088   theRootOutputFile=new TFile(_filename,"RECREATE", "BDS output file");
00089 
00090   //build sampler tree
00091   for(G4int i=0;i<BDSSampler::GetNSamplers();i++)
00092     {
00093       //G4String name="samp"+BDSGlobalConstants::Instance()->StringFromInt(i+1);
00094       G4String name=SampName[i];
00095       TTree* SamplerTree = new TTree(name, "Sampler output");
00096       
00097       SamplerTree->Branch("E0",&E0,"E0 (GeV)/F");
00098       SamplerTree->Branch("x0",&x0,"x0 (mum)/F");
00099       SamplerTree->Branch("y0",&y0,"y0 (mum)/F");
00100       SamplerTree->Branch("z0",&z0,"z0 (m)/F");
00101       SamplerTree->Branch("xp0",&xp0,"xp0 (rad)/F");
00102       SamplerTree->Branch("yp0",&yp0,"yp0 (rad)/F");
00103       SamplerTree->Branch("zp0",&zp0,"zp0 (rad)/F");
00104       SamplerTree->Branch("t0",&t0,"t0 (ns)/F");
00105 
00106       SamplerTree->Branch("E",&E,"E (GeV)/F");
00107       SamplerTree->Branch("x",&x,"x (mum)/F");
00108       SamplerTree->Branch("y",&y,"y (mum)/F");
00109       SamplerTree->Branch("z",&z,"z (m)/F");
00110       SamplerTree->Branch("xp",&xp,"xp (rad)/F");
00111       SamplerTree->Branch("yp",&yp,"yp (rad)/F");
00112       SamplerTree->Branch("zp",&zp,"zp (rad)/F");
00113       SamplerTree->Branch("t",&t,"t (ns)/F");
00114 
00115       SamplerTree->Branch("X",&X,"X (mum)/F");
00116       SamplerTree->Branch("Y",&Y,"Y (mum)/F");
00117       SamplerTree->Branch("Z",&Z,"Z (m)/F");
00118       SamplerTree->Branch("Xp",&Xp,"Xp (rad)/F");
00119       SamplerTree->Branch("Yp",&Yp,"Yp (rad)/F");
00120       SamplerTree->Branch("Zp",&Zp,"Zp (rad)/F");
00121 
00122       SamplerTree->Branch("s",&s,"s (m)/F");
00123 
00124       SamplerTree->Branch("weight",&weight,"weight/F");
00125       SamplerTree->Branch("partID",&part,"partID/I");
00126       SamplerTree->Branch("nEvent",&nev,"nEvent/I");
00127       SamplerTree->Branch("parentID",&pID,"parentID/I");
00128       SamplerTree->Branch("trackID",&track_id,"trackID/I");
00129     }
00130   for(G4int i=0;i<BDSSamplerCylinder::GetNSamplers();i++)
00131     {
00132       //G4String name="samp"+BDSGlobalConstants::Instance()->StringFromInt(i+1);
00133       G4String name=CSampName[i];
00134       TTree* SamplerTree = new TTree(name, "Sampler output");
00135       
00136       SamplerTree->Branch("E0",&E0,"E0 (GeV)/F");
00137       SamplerTree->Branch("x0",&x0,"x0 (mum)/F");
00138       SamplerTree->Branch("y0",&y0,"y0 (mum)/F");
00139       SamplerTree->Branch("z0",&z0,"z0 (m)/F");
00140       SamplerTree->Branch("xp0",&xp0,"xp0 (rad)/F");
00141       SamplerTree->Branch("yp0",&yp0,"yp0 (rad)/F");
00142       SamplerTree->Branch("zp0",&zp0,"zp0 (rad)/F");
00143       SamplerTree->Branch("t0",&t0,"t0 (ns)/F");
00144 
00145       SamplerTree->Branch("E",&E,"E (GeV)/F");
00146       SamplerTree->Branch("x",&x,"x (mum)/F");
00147       SamplerTree->Branch("y",&y,"y (mum)/F");
00148       SamplerTree->Branch("z",&z,"z (m)/F");
00149       SamplerTree->Branch("xp",&xp,"xp (rad)/F");
00150       SamplerTree->Branch("yp",&yp,"yp (rad)/F");
00151       SamplerTree->Branch("zp",&zp,"zp (rad)/F");
00152       SamplerTree->Branch("t",&t,"t (ns)/F");
00153 
00154       SamplerTree->Branch("X",&X,"X (mum)/F");
00155       SamplerTree->Branch("Y",&Y,"Y (mum)/F");
00156       SamplerTree->Branch("Z",&Z,"Z (m)/F");
00157       SamplerTree->Branch("Xp",&Xp,"Xp (rad)/F");
00158       SamplerTree->Branch("Yp",&Yp,"Yp (rad)/F");
00159       SamplerTree->Branch("Zp",&Zp,"Zp (rad)/F");
00160 
00161       SamplerTree->Branch("s",&s,"s (m)/F");
00162 
00163       SamplerTree->Branch("weight",&weight,"weight/F");
00164       SamplerTree->Branch("partID",&part,"partID/I");
00165       SamplerTree->Branch("nEvent",&nev,"nEvent/I");
00166       SamplerTree->Branch("parentID",&pID,"parentID/I");
00167       SamplerTree->Branch("trackID",&track_id,"trackID/I");
00168     }
00169 
00170   if(BDSGlobalConstants::Instance()->GetStoreTrajectory() || BDSGlobalConstants::Instance()->GetStoreMuonTrajectories() || BDSGlobalConstants::Instance()->GetStoreNeutronTrajectories()) 
00171     // create a tree with trajectories
00172     {
00173       //G4cout<<"BDSOutput::storing trajectories set"<<G4endl;
00174       TTree* TrajTree = new TTree("Trajectories", "Trajectories");
00175       TrajTree->Branch("x",&x,"x (mum)/F");
00176       TrajTree->Branch("y",&y,"y (mum)/F");
00177       TrajTree->Branch("z",&z,"z (m)/F");
00178       TrajTree->Branch("part",&part,"part/I");
00179     }
00180 
00181   // build energy loss histogram
00182   G4int nBins = G4int(zMax/(BDSGlobalConstants::Instance()->GetElossHistoBinWidth()*m));
00183   G4double wx=(BDSGlobalConstants::Instance()->GetTunnelRadius()+BDSGlobalConstants::Instance()->GetTunnelOffsetX())*2;
00184   G4double wy=(BDSGlobalConstants::Instance()->GetTunnelRadius()+BDSGlobalConstants::Instance()->GetTunnelOffsetY())*2;
00185   G4double bs=BDSGlobalConstants::Instance()->GetComponentBoxSize();
00186   G4double wmax=std::max(wx,wy);
00187   wmax=std::max(wmax,bs);
00188 
00189   EnergyLossHisto = new TH1F("ElossHisto", "Energy Loss",nBins,0.,zMax/m);
00190   EnergyLossTree= new TTree("ElossTree", "Energy Loss");
00191   EnergyLossTree->Branch("z",&z_el,"z (m)/F");
00192   EnergyLossTree->Branch("E",&E_el,"E (GeV)/F");
00193 
00194   PrecisionRegionEnergyLossTree= new TTree("PrecisionRegionElossTree", "Energy Loss");//"x:y:z:E:partID:parentID:weight:volumeName");
00195   PrecisionRegionEnergyLossTree->Branch("x",&x_el_p,"x (m)/F");
00196   PrecisionRegionEnergyLossTree->Branch("y",&y_el_p,"y (m)/F");
00197   PrecisionRegionEnergyLossTree->Branch("z",&z_el_p,"z (m)/F");
00198   PrecisionRegionEnergyLossTree->Branch("E",&E_el_p,"E (GeV)/F");
00199   PrecisionRegionEnergyLossTree->Branch("weight",&weight_el_p,"weight/F");
00200   PrecisionRegionEnergyLossTree->Branch("partID",&part_el_p,"partID/I");
00201   PrecisionRegionEnergyLossTree->Branch("volumeName",&volumeName_el_p,"volumeName/C");
00202 #endif // USE_ROOT
00203 }
00204 
00205 void BDSOutput::WriteHits(BDSSamplerHitsCollection *hc)
00206 {
00207   if( format == _ASCII) {
00208     
00209     //of<<"#hits (PDGtype  E[GeV],x[micron],y[micron],z[m],x'[rad],y'[rad]):"<<G4endl;
00210     int G4precision = G4cout.precision();
00211     G4cout.precision(15);
00212     
00213     for (G4int i=0; i<hc->entries(); i++)
00214       {
00215         of<<(*hc)[i]->GetPDGtype()
00216           <<" "
00217           <<(*hc)[i]->GetMom()/GeV
00218           <<" "
00219           <<(*hc)[i]->GetX()/micrometer
00220           <<" "
00221           <<(*hc)[i]->GetY()/micrometer
00222           <<" "
00223           <<(*hc)[i]->GetS() / m
00224           <<" "
00225           <<(*hc)[i]->GetXPrime() / radian
00226           <<" "
00227           <<(*hc)[i]->GetYPrime() / radian
00228           <<" "
00229           <<(*hc)[i]->GetEventNo() 
00230           <<" "
00231           <<(*hc)[i]->GetWeight()
00232           <<" "
00233           <<(*hc)[i]->GetParentID()
00234           <<" "
00235           <<(*hc)[i]->GetTrackID()
00236           <<G4endl;
00237       }
00238     
00239 //    of<<G4endl; // remove whitespace in output file when no events hit sampler
00240       of.flush();
00241     //of<<"end of hits collection"<<G4endl;
00242       
00243       // set precision back
00244       G4cout.precision(G4precision);
00245   }
00246   
00247   if( format == _ROOT) {
00248 #ifdef USE_ROOT
00249     G4String name;
00250     
00251     G4cout << __METHOD_NAME__ << " hc->endtries() = " << hc->entries() << G4endl;
00252     for (G4int i=0; i<hc->entries(); i++)
00253       {
00254         G4cout << __METHOD_NAME__ << " filling tree with entry number " << i << G4endl;
00255         //if ((*hc)[i]->GetType()=="plane") 
00256         //name="samp";
00257         //else if ((*hc)[i]->GetType()=="cylinder")
00258         //name ="cyln";
00259         //name="samp" + BDSGlobalConstants::Instance()->StringFromInt((*hc)[i]->GetNumber());
00260         
00261         TTree* sTree=(TTree*)gDirectory->Get((*hc)[i]->GetName());
00262         
00263         if(!sTree) G4Exception("BDSOutput: ROOT Sampler not found!", "-1", FatalException, "");
00264         
00265         E0=(*hc)[i]->GetInitMom() / GeV;
00266         x0=(*hc)[i]->GetInitX() / micrometer;
00267         y0=(*hc)[i]->GetInitY() / micrometer;
00268         z0=(*hc)[i]->GetInitZ() / m;
00269         xp0=(*hc)[i]->GetInitXPrime() / radian;
00270         yp0=(*hc)[i]->GetInitYPrime() / radian;
00271         zp0=(*hc)[i]->GetInitZPrime() / radian;
00272         t0=(*hc)[i]->GetInitT() / ns;
00273         
00274         E=(*hc)[i]->GetMom() / GeV;
00275         //Edep=(*hc)[i]->GetEdep() / GeV;
00276         x=(*hc)[i]->GetX() / micrometer;
00277         y=(*hc)[i]->GetY() / micrometer;
00278         z=(*hc)[i]->GetZ() / m;
00279         xp=(*hc)[i]->GetXPrime() / radian;
00280         yp=(*hc)[i]->GetYPrime() / radian;
00281         zp=(*hc)[i]->GetZPrime() / radian;
00282         t=(*hc)[i]->GetT() / ns;
00283         
00284         X=(*hc)[i]->GetGlobalX() / m;
00285         Y=(*hc)[i]->GetGlobalY() / m;
00286         Z=(*hc)[i]->GetGlobalZ() / m;
00287         Xp=(*hc)[i]->GetGlobalXPrime() / radian;
00288         Yp=(*hc)[i]->GetGlobalYPrime() / radian;
00289         Zp=(*hc)[i]->GetGlobalZPrime() / radian;
00290         
00291         s=(*hc)[i]->GetS() / m;
00292         
00293         weight=(*hc)[i]->GetWeight();
00294         part=(*hc)[i]->GetPDGtype(); 
00295         nev=(*hc)[i]->GetEventNo(); 
00296         pID=(*hc)[i]->GetParentID(); 
00297         track_id=(*hc)[i]->GetTrackID();
00298 
00299 #ifdef DEBUG
00300         G4cout << __METHOD_NAME__ << "z=" << (*hc)[i]->GetZ() / m << "\n" <<
00301           "track_id=" << (*hc)[i]->GetTrackID() << G4endl;
00302         G4cout << __METHOD_NAME__ << " - filling tree: " << sTree->GetName();
00303         G4cout << " # entries before fill = " << sTree->GetEntries() << G4endl;
00304 #endif
00305         sTree->Fill();
00306 #ifdef DEBUG
00307         G4cout << " # entries after fill = " << sTree->GetEntries() << G4endl;
00308 #endif
00309       }
00310 #endif
00311   }
00312 }
00313 
00314 G4int BDSOutput::WriteTrajectory(std::vector<G4VTrajectory*> TrajVec){
00315   //  G4cout<<"a trajectory stored..."<<G4endl;
00316   
00317   //  G4int tID;
00318   G4TrajectoryPoint* TrajPoint;
00319   G4ThreeVector TrajPos;
00320   
00321 #ifdef USE_ROOT
00322   TTree* TrajTree;
00323     
00324   G4String name = "Trajectories";
00325   
00326   TrajTree=(TTree*)gDirectory->Get(name);
00327 
00328   if(TrajTree == NULL) { G4cerr<<"TrajTree=NULL"<<G4endl; return -1;}
00329 #endif
00330   
00331   
00332   if(TrajVec.size())
00333     {
00334       std::vector<G4VTrajectory*>::iterator iT;
00335       
00336       for(iT=TrajVec.begin();iT<TrajVec.end();iT++)
00337         {
00338           G4Trajectory* Traj=(G4Trajectory*)(*iT);
00339           
00340           //      tID=Traj->GetTrackID();             
00341           part = Traj->GetPDGEncoding();
00342           
00343           for(G4int j=0; j<Traj->GetPointEntries(); j++)
00344             {
00345               TrajPoint=(G4TrajectoryPoint*)Traj->GetPoint(j);
00346               TrajPos=TrajPoint->GetPosition();
00347               
00348               x = TrajPos.x() / m;
00349               y = TrajPos.y() / m;
00350               z = TrajPos.z() / m;
00351               
00352 #ifdef USE_ROOT
00353               if( format == _ROOT) 
00354                 TrajTree->Fill();
00355 #endif
00356               
00357               //G4cout<<"TrajPos="<<TrajPos<<G4endl;
00358             }
00359         }
00360     }
00361   
00362   return 0;
00363 }
00364 
00365 // write a trajectory to a root/ascii file
00366 G4int BDSOutput::WriteTrajectory(TrajectoryVector* TrajVec)
00367 {
00368 //  G4cout<<"a trajectory stored..."<<G4endl;
00369   
00370 //  G4int tID;
00371   G4TrajectoryPoint* TrajPoint;
00372   G4ThreeVector TrajPos;
00373 
00374 #ifdef USE_ROOT
00375   TTree* TrajTree;
00376     
00377   G4String name = "Trajectories";
00378       
00379   TrajTree=(TTree*)gDirectory->Get(name);
00380 
00381   if(TrajTree == NULL) { G4cerr<<"TrajTree=NULL"<<G4endl; return -1;}
00382 #endif
00383 
00384 
00385   if(TrajVec)
00386     {
00387       TrajectoryVector::iterator iT;
00388       
00389       for(iT=TrajVec->begin();iT<TrajVec->end();iT++)
00390         {
00391           G4Trajectory* Traj=(G4Trajectory*)(*iT);
00392           
00393           //      tID=Traj->GetTrackID();             
00394           part = Traj->GetPDGEncoding();
00395           
00396           for(G4int j=0; j<Traj->GetPointEntries(); j++)
00397             {
00398               TrajPoint=(G4TrajectoryPoint*)Traj->GetPoint(j);
00399               TrajPos=TrajPoint->GetPosition();
00400               
00401               x = TrajPos.x() / m;
00402               y = TrajPos.y() / m;
00403               z = TrajPos.z() / m;
00404 
00405 #ifdef USE_ROOT
00406               if( format == _ROOT) 
00407                 TrajTree->Fill();
00408 #endif
00409 
00410               //G4cout<<"TrajPos="<<TrajPos<<G4endl;
00411             }
00412         }
00413     }
00414   
00415   return 0;
00416 }
00417 
00418 // make energy loss histo
00419 
00420 void BDSOutput::WriteEnergyLoss(BDSEnergyCounterHitsCollection* hc)
00421 {
00422   if( format == _ROOT) {
00423 #ifdef USE_ROOT
00424     G4int n_hit = hc->entries();
00425     for (G4int i=0;i<n_hit;i++)
00426       {
00427         //all regions fill the energy loss tree....
00428         E_el=(*hc)[i]->GetEnergy()/GeV;
00429         z_el=(*hc)[i]->GetEnergyWeightedZ()*10*(1e-6)/(cm*E_el);
00430         EnergyLossHisto->Fill(z_el,E_el);
00431         EnergyLossTree->Fill();
00432 
00433         if((*hc)[i]->GetPrecisionRegion()){ //Only the precision region fills this tree, preserving every hit, its position and weight, instead of summing weighted energy in each beam line component.
00434           weight_el_p=(*hc)[i]->GetWeight();
00435           E_el_p=((*hc)[i]->GetEnergy()/GeV)/weight_el_p;
00436           x_el_p=((*hc)[i]->GetEnergyWeightedX()/(cm*1e5*E_el_p))/weight_el_p;
00437           y_el_p=((*hc)[i]->GetEnergyWeightedY()*10/(cm*E_el_p))/weight_el_p;
00438           z_el_p=((*hc)[i]->GetEnergyWeightedZ()*10*(1e-6)/(cm*E_el_p))/weight_el_p;
00439           part_el_p=(*hc)[i]->GetPartID();
00440           G4String temp = (*hc)[i]->GetName()+'\0';
00441           strcpy(volumeName_el_p,temp.c_str());
00442           PrecisionRegionEnergyLossTree->Fill();
00443         }
00444         
00445       }
00446 #endif
00447   }
00448 
00449  if( format == _ASCII) {
00450     G4int n_hit = hc->entries();
00451 
00452     for (G4int i=0;i<n_hit;i++)
00453       {
00454         G4double Energy=(*hc)[i]->GetEnergy();
00455         G4double Zpos=(*hc)[i]->GetZ();
00456         G4int partID = (*hc)[i]->GetPartID();
00457         G4double weight = (*hc)[i]->GetWeight();
00458 
00459         ofEloss<< Zpos/m<<"  "<<Energy/GeV<<"  "<<partID<<"  " <<weight<<G4endl;
00460       }
00461     ofEloss.flush();
00462  }
00463 }
00464 
00465 // write some comments to the output file
00466 // only for ASCII output
00467 void BDSOutput::Echo(G4String str)
00468 {
00469   if(format == _ASCII)  of<<"#"<<str<<G4endl;
00470   else // default
00471     G4cout<<"#"<<str<<G4endl;
00472 }
00473 
00474 //G4int BDSOutput::Commit(G4int FileNum)
00475 G4int BDSOutput::Commit()
00476 {
00477 #ifdef USE_ROOT
00478   Write();
00479   Init(outputFileNumber++);
00480 #endif
00481   return 0;
00482 }
00483 
00484 void BDSOutput::Write()
00485 {
00486 #ifdef USE_ROOT
00487   if(format == _ROOT){
00488     if(theRootOutputFile->IsOpen())
00489       {
00490         G4cout << __METHOD_NAME__ << " writing to root file..." << G4endl;
00491         //Dump all other quantities to file...
00492         theRootOutputFile->Write();
00493         //      G4cout << __METHOD_NAME__ << " closing root file..." << G4endl;
00494         theRootOutputFile->Close();
00495         //      G4cout << __METHOD_NAME__ << " deleting root file..." << G4endl;
00496         delete theRootOutputFile;
00497         //      G4cout << __METHOD_NAME__ << " setting root file to NULL..." << G4endl;
00498         theRootOutputFile=NULL;
00499       }
00500   }
00501 #endif
00502 }

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7