00001 #include "BDSBunchUserFile.hh"
00002 #include "G4ParticleDefinition.hh"
00003 #include "G4ParticleTable.hh"
00004 #include "BDSDebug.hh"
00005 #include "BDSExecOptions.hh"
00006
00007 BDSBunchUserFile::BDSBunchUserFile():nlinesIgnore(0){
00008 #ifdef BDSDEBUG
00009 G4cout << __METHOD_NAME__ << G4endl;
00010 #endif
00011 }
00012
00013 BDSBunchUserFile::~BDSBunchUserFile(){
00014 #ifdef BDSDEBUG
00015 G4cout << __METHOD_NAME__ << G4endl;
00016 #endif
00017 CloseBunchFile();
00018 }
00019
00020 void BDSBunchUserFile::OpenBunchFile(){
00021 #ifdef BDSDEBUG
00022 G4cout << __METHOD_NAME__ << G4endl;
00023 #endif
00024 InputBunchFile.open(distribFile);
00025 if(!InputBunchFile.good()){
00026 G4cerr<<"Cannot open bunch file "<< distribFile <<G4endl;
00027 exit(1);
00028 }
00029 }
00030
00031 void BDSBunchUserFile::CloseBunchFile(){
00032 #ifdef BDSDEBUG
00033 G4cout << __METHOD_NAME__ << G4endl;
00034 #endif
00035 InputBunchFile.close();
00036 }
00037
00038 void BDSBunchUserFile::ParseFileFormat(){
00039 #ifdef BDSDEBUG
00040 G4cout << __METHOD_NAME__ << G4endl;
00041 #endif
00042 G4String unparsed_str = bunchFormat;
00043 G4int pos = unparsed_str.find(":");
00044
00045 struct BDSBunchUserFile::Doublet sd;
00046
00047 while(pos > 0){
00048 pos = unparsed_str.find(":");
00049 G4String token = unparsed_str.substr(0,pos);
00050
00051 unparsed_str = unparsed_str.substr(pos+1);
00052 #ifdef BDSDEBUG
00053 G4cout<< __METHOD_NAME__ <<"token -> "<<token<<G4endl;
00054 G4cout<< __METHOD_NAME__ <<"token.substr(0,1) -> " << token.substr(0,1) << G4endl;
00055 G4cout<< __METHOD_NAME__ <<"unparsed_str -> "<<unparsed_str<<G4endl;
00056 G4cout<< __METHOD_NAME__ <<"pos -> "<<pos<<G4endl;
00057 #endif
00058 if(token.substr(0,1)=="E" || token.substr(0,1)=="P") {
00059 G4String name = token.substr(0,1);
00060 #ifdef BDSDEBUG
00061 G4cout<< __METHOD_NAME__ << name << "!"<<G4endl;
00062 #endif
00063 G4String rest = token.substr(1);
00064 #ifdef BDSDEBUG
00065 G4cout<< __METHOD_NAME__ <<"rest ->"<<rest<<G4endl;
00066 #endif
00067 G4int pos1 = rest.find("[");
00068 G4int pos2 = rest.find("]");
00069 if(pos1 < 0 || pos2 < 0) {
00070 G4cerr<<"unit format wrong!!!"<<G4endl;
00071 } else {
00072 G4String fmt = rest.substr(pos1+1,pos2-1);
00073 #ifdef BDSDEBUG
00074 G4cout<< __METHOD_NAME__ <<"fmt ->"<<fmt<<G4endl;
00075 #endif
00076 sd.name = name;
00077 sd.unit = ParseEnergyUnit(fmt);
00078 fields.push_back(sd);
00079 }
00080 } else if(token.substr(0,1)=="t") {
00081 #ifdef BDSDEBUG
00082 G4cout<< __METHOD_NAME__ <<"t!"<<G4endl;
00083 #endif
00084 G4String rest = token.substr(1);
00085 #ifdef BDSDEBUG
00086 G4cout<< __METHOD_NAME__ <<"rest ->"<<rest<<G4endl;
00087 #endif
00088 G4int pos1 = rest.find("[");
00089 G4int pos2 = rest.find("]");
00090 if(pos1 < 0 || pos2 < 0) {
00091 G4cerr<<"unit format wrong!!!"<<G4endl;
00092 } else {
00093 G4String fmt = rest.substr(pos1+1,pos2-1);
00094 #ifdef BDSDEBUG
00095 G4cout<< __METHOD_NAME__ <<"fmt ->"<<fmt<<G4endl;
00096 #endif
00097 sd.name = "t";
00098 sd.unit = ParseTimeUnit(fmt);
00099 fields.push_back(sd);
00100 }
00101 } else if( ( token.substr(0,1)=="x" && token.substr(1,1)!="p" ) ||
00102 ( token.substr(0,1)=="y" && token.substr(1,1)!="p" ) ||
00103 ( token.substr(0,1)=="z" && token.substr(1,1)!="p" ) ) {
00104 G4String name = token.substr(0,1);
00105 #ifdef BDSDEBUG
00106 G4cout<< __METHOD_NAME__ << name << "!"<<G4endl;
00107 #endif
00108 G4String rest = token.substr(1);
00109 #ifdef BDSDEBUG
00110 G4cout<< __METHOD_NAME__ <<"rest ->"<<rest<<G4endl;
00111 #endif
00112 G4int pos1 = rest.find("[");
00113 G4int pos2 = rest.find("]");
00114 if(pos1 < 0 || pos2 < 0) {
00115 G4cerr<<"unit format wrong!!!"<<G4endl;
00116 } else {
00117 G4String fmt = rest.substr(pos1+1,pos2-1);
00118 #ifdef BDSDEBUG
00119 G4cout<< __METHOD_NAME__ <<"fmt ->"<<fmt<<G4endl;
00120 #endif
00121 sd.name=name;
00122 sd.unit=ParseLengthUnit(fmt);
00123 fields.push_back(sd);
00124 }
00125 } else if ( (token.substr(0,2)=="xp") ||
00126 (token.substr(0,2)=="yp") ||
00127 (token.substr(0,2)=="zp") ) {
00128 G4String name = token.substr(0,2);
00129 #ifdef BDSDEBUG
00130 G4cout<< __METHOD_NAME__ << name << "!"<<G4endl;
00131 #endif
00132 G4String rest = token.substr(2);
00133 #ifdef BDSDEBUG
00134 G4cout<< __METHOD_NAME__ <<"rest ->"<<rest<<G4endl;
00135 #endif
00136 G4int pos1 = rest.find("[");
00137 G4int pos2 = rest.find("]");
00138 if(pos1 < 0 || pos2 < 0) {
00139 G4cerr<<"unit format wrong!!!"<<G4endl;
00140 } else {
00141 G4String fmt = rest.substr(pos1+1,pos2-1);
00142 #ifdef BDSDEBUG
00143 G4cout<< __METHOD_NAME__ <<"fmt ->"<<fmt<<G4endl;
00144 #endif
00145 sd.name=name;
00146 sd.unit=ParseAngleUnit(fmt);
00147 fields.push_back(sd);
00148 }
00149 }else if(token.substr(0,2)=="pt") {
00150 #ifdef BDSDEBUG
00151 G4cout<< __METHOD_NAME__ <<"pt!"<<G4endl;
00152 #endif
00153 sd.name="pt";
00154 sd.unit=1;
00155 fields.push_back(sd);
00156 } else if(token.substr(0,1)=="w") {
00157 #ifdef BDSDEBUG
00158 G4cout<< __METHOD_NAME__ <<"weight!"<<G4endl;
00159 #endif
00160 sd.name="weight";
00161 sd.unit=1;
00162 fields.push_back(sd);
00163 } else if (token.substr(0,1)=="-") {
00164
00165 #ifdef BDSDEBUG
00166 G4cout<< __METHOD_NAME__ << "skip token " <<G4endl;
00167 #endif
00168 sd.name="skip";
00169 sd.unit=1;
00170 fields.push_back(sd);
00171 } else {
00172 G4cerr << "Cannot determine bunch data format" << G4endl; exit(1);
00173 }
00174 }
00175 return;
00176 }
00177
00178 void BDSBunchUserFile::skip(G4int nvalues){
00179 G4double dummy_val;
00180 for(G4int i=0;i<nvalues;i++) ReadValue(dummy_val);
00181 }
00182
00183 void BDSBunchUserFile::SetDistribFile(G4String filename){
00184 G4String fullPATH = BDSExecOptions::Instance()->GetBDSIMPATH();
00185 distribFile = fullPATH + filename;
00186 }
00187
00188 void BDSBunchUserFile::SetOptions(struct Options &opt) {
00189 BDSBunchInterface::SetOptions(opt);
00190 SetDistribFile((G4String)opt.distribFile);
00191 SetBunchFormat((G4String)opt.distribFileFormat);
00192 SetNLinesIgnore(opt.nlinesIgnore);
00193 ParseFileFormat();
00194 OpenBunchFile();
00195 return;
00196 }
00197
00198 G4double BDSBunchUserFile::ParseEnergyUnit(G4String &fmt)
00199 {
00200 G4double unit=1.;
00201 if(fmt=="GeV") unit=1;
00202 else if(fmt=="MeV") unit=1.e-3;
00203 else if(fmt=="KeV") unit=1.e-6;
00204 else if(fmt=="eV") unit=1.e-9;
00205 else {
00206 G4cout << __METHOD_NAME__ << "Unrecognised energy unit! " << fmt << G4endl;
00207 exit(1);
00208 }
00209 return unit;
00210 }
00211
00212 G4double BDSBunchUserFile::ParseLengthUnit(G4String &fmt)
00213 {
00214 G4double unit=1.;
00215 if(fmt=="m") unit=1;
00216 else if(fmt=="cm") unit=1.e-2;
00217 else if(fmt=="mm") unit=1.e-3;
00218 else if(fmt=="mum" || fmt=="um") unit=1.e-6;
00219 else if(fmt=="nm") unit=1.e-9;
00220 else {
00221 G4cout << __METHOD_NAME__ << "Unrecognised length unit! " << fmt << G4endl;
00222 exit(1);
00223 }
00224 return unit;
00225 }
00226
00227 G4double BDSBunchUserFile::ParseAngleUnit(G4String &fmt)
00228 {
00229 G4double unit=1.;
00230 if(fmt=="rad") unit=1;
00231 else if(fmt=="mrad") unit=1.e-3;
00232 else if(fmt=="murad" || fmt=="urad") unit=1.e-6;
00233 else {
00234 G4cout << __METHOD_NAME__ << "Unrecognised angle unit! " << fmt << G4endl;
00235 exit(1);
00236 }
00237 return unit;
00238 }
00239
00240 G4double BDSBunchUserFile::ParseTimeUnit(G4String &fmt)
00241 {
00242 G4double unit=1.;
00243 if(fmt=="s") unit=1;
00244 else if(fmt=="ms") unit=1.e-3;
00245 else if(fmt=="mus" || fmt=="us") unit=1.e-6;
00246 else if(fmt=="ns") unit=1.e-9;
00247 else if(fmt=="mm/c") unit=(CLHEP::mm/CLHEP::c_light)/CLHEP::s;
00248 else if(fmt=="nm/c") unit=(CLHEP::nm/CLHEP::c_light)/CLHEP::s;
00249 else {
00250 G4cout << __METHOD_NAME__ << "Unrecognised time unit! " << fmt << G4endl;
00251 exit(1);
00252 }
00253 return unit;
00254 }
00255
00256 void BDSBunchUserFile::GetNextParticle(G4double& x0, G4double& y0, G4double& z0,
00257 G4double& xp, G4double& yp, G4double& zp,
00258 G4double& t , G4double& E, G4double& weight) {
00259
00260 E = x0 = y0 = z0 = xp = yp = zp = t = 0;
00261 weight = 1;
00262
00263 bool zpdef = false;
00264 bool tdef = false;
00265
00266 G4int type;
00267
00268
00269 #ifdef BDSDEBUG
00270 G4cout << __METHOD_NAME__ << "UDEF_BUNCH: skipping " << nlinesIgnore << " lines" << G4endl;
00271 #endif
00272 skip((G4int)(nlinesIgnore * fields.size()));
00273
00274 std::list<struct BDSBunchUserFile::Doublet>::iterator it;
00275 for(it=fields.begin();it!=fields.end();it++)
00276 {
00277 #ifdef BDSDEBUG
00278 G4cout<< __METHOD_NAME__ <<it->name<<" -> "<<it->unit<<G4endl;
00279 #endif
00280 if(it->name=="E") {
00281 ReadValue(E); E *= ( CLHEP::GeV * it->unit );
00282 #ifdef BDSDEBUG
00283 G4cout << "******** Particle Mass = " << BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass() << G4endl;
00284 G4cout << "******** Particle Total Energy = " << E << G4endl;
00285 #endif
00286 E-=BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
00287 #ifdef BDSDEBUG
00288 G4cout << "******** Particle Kinetic Energy = " << E << G4endl;
00289 G4cout<< __METHOD_NAME__ << E <<G4endl;
00290 #endif
00291 }
00292 else if(it->name=="P") {
00293 G4double P=0;
00294 ReadValue(P); P *= ( CLHEP::GeV * it->unit );
00295 G4double particleMass = BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
00296 G4double totalEnergy = sqrt(P*P + particleMass*particleMass);
00297 E = totalEnergy - particleMass;
00298 #ifdef BDSDEBUG
00299 G4cout << "******** Particle Mass = " << particleMass << G4endl;
00300 G4cout << "******** Particle Total Energy = " << totalEnergy << G4endl;
00301 G4cout << "******** Particle Kinetic Energy = " << E << G4endl;
00302 G4cout<< __METHOD_NAME__ << E <<G4endl;
00303 #endif
00304 }
00305 else if(it->name=="t") { ReadValue(t); t *= ( CLHEP::s * it->unit ); tdef = true; }
00306 else if(it->name=="x") { ReadValue(x0); x0 *= ( CLHEP::m * it->unit );
00307 #ifdef BDSDEBUG
00308 G4cout<< __METHOD_NAME__ << x0 <<G4endl;
00309 #endif
00310 }
00311 else if(it->name=="y") {
00312 ReadValue(y0); y0 *= ( CLHEP::m * it->unit );
00313 #ifdef BDSDEBUG
00314 G4cout<< __METHOD_NAME__ << y0 <<G4endl;
00315 #endif
00316 }
00317 else if(it->name=="z") {
00318 ReadValue(z0); z0 *= ( CLHEP::m * it->unit );
00319 #ifdef BDSDEBUG
00320 G4cout<< __METHOD_NAME__ << z0 <<G4endl;
00321 #endif
00322 }
00323 else if(it->name=="xp") { ReadValue(xp); xp *= ( CLHEP::radian * it->unit ); }
00324 else if(it->name=="yp") { ReadValue(yp); yp *= ( CLHEP::radian * it->unit ); }
00325 else if(it->name=="zp") { ReadValue(zp); zp *= ( CLHEP::radian * it->unit ); zpdef = true;}
00326 else if(it->name=="pt") {
00327 ReadValue(type);
00328 if(InputBunchFile.good()){
00329 BDSGlobalConstants::Instance()->SetParticleName(G4ParticleTable::GetParticleTable()->FindParticle(type)->GetParticleName());
00330 BDSGlobalConstants::Instance()->SetParticleDefinition(G4ParticleTable::
00331 GetParticleTable()
00332 ->FindParticle(type));
00333 if(!BDSGlobalConstants::Instance()->GetParticleDefinition())
00334 {
00335 G4Exception("Particle not found, quitting!", "-1", FatalErrorInArgument, "");
00336 exit(1);
00337 }
00338 }
00339 }
00340 else if(it->name=="weight") ReadValue(weight);
00341
00342 else if(it->name=="skip") {double dummy; ReadValue(dummy);}
00343
00344
00345 if (!zpdef) zp = CalculateZp(xp,yp,1);
00346
00347 if (!tdef) t=0;
00348
00349
00350
00351 }
00352
00353 z0=z0+Z0*CLHEP::m;
00354 }
00355
00356 template <typename Type> G4bool BDSBunchUserFile::ReadValue(Type &value){
00357 InputBunchFile>>value;
00358 if (InputBunchFile.eof()){
00359
00360 G4cout << __METHOD_NAME__ << "End of file reached. Returning to beginning of file." << G4endl;
00361 CloseBunchFile();
00362 OpenBunchFile();
00363 InputBunchFile>>value;
00364 }
00365 return !InputBunchFile.eof();
00366 }