00001 #include "BDSExecOptions.hh"
00002 #include "BDSOutput.hh"
00003 #include "BDSSamplerSD.hh"
00004 #include <ctime>
00005
00006
00007
00008 BDSOutput::BDSOutput():outputFileNumber(1)
00009 {
00010 format = _ASCII;
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
00078 void BDSOutput::Init(G4int FileNum)
00079 {
00080 #ifdef USE_ROOT
00081 if(format != _ROOT) return;
00082
00083
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
00091 for(G4int i=0;i<BDSSampler::GetNSamplers();i++)
00092 {
00093
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
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
00172 {
00173
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
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");
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
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
00240 of.flush();
00241
00242
00243
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
00256
00257
00258
00259
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
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
00316
00317
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
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
00358 }
00359 }
00360 }
00361
00362 return 0;
00363 }
00364
00365
00366 G4int BDSOutput::WriteTrajectory(TrajectoryVector* TrajVec)
00367 {
00368
00369
00370
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
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
00411 }
00412 }
00413 }
00414
00415 return 0;
00416 }
00417
00418
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
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()){
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
00466
00467 void BDSOutput::Echo(G4String str)
00468 {
00469 if(format == _ASCII) of<<"#"<<str<<G4endl;
00470 else
00471 G4cout<<"#"<<str<<G4endl;
00472 }
00473
00474
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
00492 theRootOutputFile->Write();
00493
00494 theRootOutputFile->Close();
00495
00496 delete theRootOutputFile;
00497
00498 theRootOutputFile=NULL;
00499 }
00500 }
00501 #endif
00502 }