src/BDSBunch.cc

00001 #include "BDSBunch.hh"
00002 
00003 #include <iostream>
00004 #include <cmath>
00005 #include <cstdlib>
00006 
00007 #include "BDSExecOptions.hh"
00008 #include "BDSGlobalConstants.hh"
00009 #include "parser/gmad.h"
00010 
00011 // CLHEP from Geant4
00012 #include "Randomize.hh"
00013 // CLHEP
00014 #include "CLHEP/RandomObjects/RandMultiGauss.h"
00015 
00016 #define DEBUG 1 
00017 
00018 // distribution type
00019 
00020 enum {
00021   _REFERENCE = 0,
00022   _GAUSSIAN = 1,
00023   _RING = 2,
00024   _SQUARE = 3,
00025   _CIRCLE = 4,
00026   _GUINEAPIG_BUNCH = 5,
00027   _GUINEAPIG_PAIRS = 6,
00028   _GUINEAPIG_SLAC = 7,
00029   _CAIN = 8,
00030   _ESHELL = 9,
00031   _GAUSSIAN_TWISS = 10,
00032   _GAUSSIAN_MATRIX = 11,
00033   _UDEF = 32
00034 };
00035 
00036 BDSBunch::BDSBunch():  
00037   distribType(-1),X0(0.0),Y0(0.0),Z0(0.0),T0(0.0),Xp0(0.0),Yp0(0.0),Zp0(1.0),
00038   sigmaX(0.0),sigmaY(0.0),sigmaT(0.0),sigmaXp(0.0),sigmaYp(0.0),
00039   rMin(0.0),rMax(0.0),shellx(0.0),shelly(0.0),shellxp(0.0),shellyp(0.0),
00040   betaX(0.0),betaY(0.0),alphaX(0.0),alphaY(0.0),emitX(0.0),emitY(0.0),
00041   energySpread(0.0),nlinesIgnore(0),partId(0)
00042 { 
00043   verbose            = BDSExecOptions::Instance()->GetVerbose();
00044   verboseStep        = BDSExecOptions::Instance()->GetVerboseStep();
00045   verboseEvent       = BDSExecOptions::Instance()->GetVerboseEvent();
00046   verboseEventNumber = BDSExecOptions::Instance()->GetVerboseEventNumber();
00047   nptwiss            = BDSExecOptions::Instance()->GetNPTwiss();
00048 
00049   // Instantiate random number generators
00050   GaussGen = new CLHEP::RandGauss(*CLHEP::HepRandom::getTheEngine());
00051   FlatGen  = new CLHEP::RandFlat(*CLHEP::HepRandom::getTheEngine());
00052   GaussMultiGen = NULL;
00053 
00054   // Instantiate vector and matrix for gaussian sigma matrix generation
00055   meansGM = CLHEP::HepVector(6);
00056   sigmaGM = CLHEP::HepSymMatrix(6);
00057 }
00058 
00059 BDSBunch::~BDSBunch()
00060 {
00061   // Delete random number generators
00062   delete GaussGen;
00063   delete FlatGen;
00064   delete GaussMultiGen;
00065 }
00066 
00067 // set options from gmad
00068 
00069 void BDSBunch::skip(G4int nvalues){
00070   G4double dummy_val;
00071   for(G4int i=0;i<nvalues;i++) ReadValue(dummy_val);
00072 }
00073 
00074 void BDSBunch::SetOptions(struct Options& opt)
00075 {
00076   std::map<const G4String, int, strCmp> distType;
00077   distType["reference"]=_REFERENCE;             // Reference orbit
00078   distType["gauss"]=_GAUSSIAN;                  // Gaussian with only diagonal sigma matrix
00079   distType["ring"]=_RING;                       // Ring in cannonical phase space
00080   distType["square"]=_SQUARE;                   // Square phase space (flat)
00081   distType["circle"]=_CIRCLE;                   // Circular phase space (flat) 
00082   distType["guineapig_bunch"]=_GUINEAPIG_BUNCH; // (LC) Bunch bunch collision 
00083   distType["guineapig_pairs"]=_GUINEAPIG_PAIRS; // (LC) Electron and positron pair from bunch bunch collision
00084   distType["guineapig_slac"]=_GUINEAPIG_SLAC;   // (LC) SLAC variant of same code
00085   distType["cain"]=_CAIN;                       // (LC) Bunch bunch collision
00086   distType["eshell"]=_ESHELL;                   // ?? 
00087   distType["gausstwiss"]=_GAUSSIAN_TWISS;       // Normal Gaussian Twiss 
00088   distType["gaussmatrix"]=_GAUSSIAN_MATRIX;     // Normal Gaussian sigma matrix
00089 
00090   nlinesIgnore = opt.nlinesIgnore;
00091   inputfile=opt.distribFile;
00092   //#define _skip(nvalues) for(G4int i=0;i<nvalues;i++) ReadValue(dummy_val);
00093   
00094   // twiss parameters - set always if present
00095   SetBetaX(opt.betx);
00096   SetBetaY(opt.bety);
00097   SetAlphaX(opt.alfx);
00098   SetAlphaY(opt.alfy);
00099   SetEmitX(opt.emitx);
00100   SetEmitY(opt.emity);
00101   
00102   std::map<const G4String,int>::iterator iter;
00103   iter = distType.find(opt.distribType);
00104   if(iter!=distType.end()) 
00105     distribType = (*iter).second;
00106   else {
00107     distribType = _UDEF;
00108     G4cerr << "WARNING bunch distribution type UNKNOWN: " << opt.distribType << G4endl;
00109   }
00110 #ifdef DEBUG 
00111   G4cout<< "BDSBunch::SetOptions> distrType : "<<opt.distribType<<G4endl;
00112 #endif
00113   //
00114   // global parameters
00115   //
00116   X0 = opt.X0;
00117   Y0 = opt.Y0;
00118   Z0 = opt.Z0;
00119   T0 = opt.T0;
00120   Xp0 = opt.Xp0;
00121   Yp0 = opt.Yp0;
00122   if (opt.Zp0 < 0)
00123     Zp0 = -sqrt(1.-Xp0*Xp0-Yp0*Yp0);
00124   else
00125     Zp0 = sqrt(1.-Xp0*Xp0-Yp0*Yp0);
00126   
00127   
00128   //
00129   // specific parameters which depend on distribution type
00130   //
00131   switch(distribType){
00132   
00133   case _REFERENCE :
00134     {
00135       SetSigmaX(0.0); 
00136       SetSigmaY(0.0);
00137       SetSigmaXp(0.0);
00138       SetSigmaYp(0.0);
00139       SetSigmaT(opt.sigmaT);
00140       SetEnergySpread(opt.sigmaE);          
00141       break;
00142     }
00143 
00144   case _GAUSSIAN:
00145     {
00146       SetSigmaX(opt.sigmaX); 
00147       SetSigmaY(opt.sigmaY);
00148       SetSigmaXp(opt.sigmaXp);
00149       SetSigmaYp(opt.sigmaYp);
00150       SetSigmaT(opt.sigmaT);
00151       SetEnergySpread(opt.sigmaE);
00152       break;
00153     } 
00154 
00155   case _GAUSSIAN_TWISS:
00156     {
00157       SetSigmaT(opt.sigmaT);
00158       SetEnergySpread(opt.sigmaE);
00159       break;
00160     } 
00161 
00162   case _GAUSSIAN_MATRIX:
00163     {       
00164 #ifdef DEBUG
00165       G4cout<< "BDSBunch::SetOptions> case _GAUSSIAN_MATRIX " << G4endl;      
00166       G4cout<< "BDSBunch::SetOptions> " << X0 << " " << Xp0 << " " << Y0 << " " << Yp0 << " " << T0 << G4endl;
00167 #endif      
00168 
00169 
00170       // set means
00171       meansGM[0] = X0;
00172       meansGM[1] = Xp0;
00173       meansGM[2] = Y0;
00174       meansGM[3] = Yp0;
00175       meansGM[4] = T0;
00176       meansGM[5] = 1;
00177         
00178       // set sigma matrix for generation
00179       sigmaGM[0][0] = opt.sigma11;
00180       sigmaGM[0][1] = opt.sigma12;
00181       sigmaGM[0][2] = opt.sigma13;
00182       sigmaGM[0][3] = opt.sigma14;
00183       sigmaGM[0][4] = opt.sigma15;
00184       sigmaGM[0][5] = opt.sigma16;
00185 
00186       sigmaGM[1][1] = opt.sigma22;
00187       sigmaGM[1][2] = opt.sigma23;
00188       sigmaGM[1][3] = opt.sigma24;
00189       sigmaGM[1][4] = opt.sigma25;
00190       sigmaGM[1][5] = opt.sigma26;
00191 
00192       sigmaGM[2][2] = opt.sigma33;
00193       sigmaGM[2][3] = opt.sigma34;
00194       sigmaGM[2][4] = opt.sigma35;
00195       sigmaGM[2][5] = opt.sigma36;
00196 
00197       sigmaGM[3][3] = opt.sigma44;
00198       sigmaGM[3][4] = opt.sigma45;
00199       sigmaGM[3][5] = opt.sigma46;
00200 
00201       sigmaGM[4][4] = opt.sigma55;
00202       sigmaGM[4][5] = opt.sigma56;
00203 
00204       sigmaGM[5][5] = opt.sigma66;
00205 
00206       // Set gauss sigmas for consistency 
00207       
00208 
00209       // Set sigma T 
00210       SetSigmaT(sqrt(opt.sigma55));
00211        
00212       // Set energy spread
00213       SetEnergySpread(sqrt(opt.sigma66));
00214       
00215       // make gaussian generator 
00216       GaussMultiGen = new CLHEP::RandMultiGauss(*CLHEP::HepRandom::getTheEngine(),
00217                                                 meansGM,sigmaGM);   
00218 
00219 #ifdef DEBUG
00220       G4cout<< "BDSBunch::SetOptions> case _GAUSSIAN_MATRIX break " << G4endl;      
00221 #endif                                                 
00222 
00223       break;
00224     }
00225     
00226   case _RING:
00227     {
00228       rMin = opt.Rmin;
00229       rMax = opt.Rmax;
00230       SetEnergySpread(opt.sigmaE);
00231       break;
00232     } 
00233     
00234   case _ESHELL:
00235     {
00236       shellx = opt.shellX;
00237       shelly = opt.shellY;
00238       shellxp = opt.shellXp;
00239       shellyp = opt.shellYp;
00240       SetEnergySpread(opt.sigmaE);
00241       break;
00242     }
00243     
00244   case _GUINEAPIG_BUNCH:
00245     {
00246       OpenBunchFile();
00247 #ifdef DEBUG 
00248       G4cout<< "BDSBunch : " <<"GUINEAPIG_BUNCH: skipping "<<nlinesIgnore<<"  lines"<<G4endl;
00249 #endif
00250       skip(nlinesIgnore * 6);
00251       break;
00252     } 
00253     
00254   case _GUINEAPIG_SLAC:
00255     {
00256       OpenBunchFile();
00257 #ifdef DEBUG 
00258       G4cout<< "BDSBunch : " <<"GUINEAPIG_SLAC: skipping "<<nlinesIgnore<<"  lines"<<G4endl;
00259 #endif
00260       skip(nlinesIgnore * 6);
00261       break;
00262     } 
00263 
00264   case _GUINEAPIG_PAIRS:
00265     {
00266       OpenBunchFile();
00267 #ifdef DEBUG 
00268       G4cout<< "BDSBunch : " <<"GUINEAPIG_PAIRS: skipping "<<nlinesIgnore<<"  lines"<<G4endl;
00269 #endif
00270       skip(nlinesIgnore * 7);
00271       break;
00272     }
00273     
00274   case _CAIN:
00275     {
00276       OpenBunchFile();
00277 #ifdef DEBUG 
00278       G4cout<< "BDSBunch : " <<"CAIN: skipping "<<nlinesIgnore<<"  lines"<<G4endl;
00279 #endif
00280       skip(nlinesIgnore * 14);
00281       break;
00282     } 
00283     //else
00284     //assuming the format is "field[unit]:field[unit]:..." - User Defined
00285   case _UDEF:
00286   default:
00287     {
00288       distribType = _UDEF; 
00289       
00290       // construct the list of read attributes
00291       
00292       G4String unparsed_str = opt.distribType; 
00293       G4int pos = unparsed_str.find(":");
00294       
00295       struct BDSBunch::Doublet sd;
00296       
00297       while(pos > 0)
00298         {
00299           pos = unparsed_str.find(":");
00300           G4String token = unparsed_str.substr(0,pos);
00301 
00302 
00303           unparsed_str = unparsed_str.substr(pos+1);
00304 #ifdef DEBUG 
00305           G4cout<< "BDSBunch : " <<"token ->"<<token<<G4endl;
00306           G4cout<< "BDSBunch : token.substr(0,1) -> " << token.substr(0,1) << G4endl;
00307           G4cout<< "BDSBunch : " <<"unparsed_str ->"<<unparsed_str<<G4endl;
00308           G4cout<< "BDSBunch : " <<"pos ->"<<pos<<G4endl;
00309 #endif
00310           if(token.substr(0,1)=="E") {
00311 #ifdef DEBUG 
00312             G4cout<< "BDSBunch : " <<"E!"<<G4endl;
00313 #endif
00314             G4String rest = token.substr(1);
00315 #ifdef DEBUG 
00316             G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00317 #endif
00318             G4int pos1 = rest.find("[");
00319             G4int pos2 = rest.find("]");
00320             if(pos1 < 0 || pos2 < 0) {
00321               G4cerr<<"unit format wrong!!!"<<G4endl;
00322             } else {
00323               G4String fmt = rest.substr(pos1+1,pos2-1);
00324 #ifdef DEBUG 
00325               G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00326 #endif
00327               sd.name = "E"; 
00328               
00329               if(fmt=="GeV") sd.unit=1;
00330               if(fmt=="MeV") sd.unit=1.e-3;
00331               if(fmt=="KeV") sd.unit=1.e-6;
00332               if(fmt=="eV") sd.unit=1.e-9;
00333               
00334               fields.push_back(sd);
00335             }
00336           } else if(token.substr(0,1)=="t") {
00337 #ifdef DEBUG 
00338             G4cout<< "BDSBunch : " <<"t!"<<G4endl;
00339 #endif
00340             G4String rest = token.substr(1);
00341 #ifdef DEBUG 
00342             G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00343 #endif
00344             G4int pos1 = rest.find("[");
00345             G4int pos2 = rest.find("]");
00346             if(pos1 < 0 || pos2 < 0) {
00347               G4cerr<<"unit format wrong!!!"<<G4endl;
00348             } else {
00349               G4String fmt = rest.substr(pos1+1,pos2-1);
00350 #ifdef DEBUG 
00351               G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00352 #endif
00353               sd.name = "t"; 
00354               
00355               if(fmt=="s") sd.unit=1;
00356               if(fmt=="ms") sd.unit=1.e-3;
00357               if(fmt=="mus") sd.unit=1.e-6;
00358               if(fmt=="ns") sd.unit=1.e-9;
00359               if(fmt=="mm/c") sd.unit=(mm/c_light)/s;
00360               if(fmt=="nm/c") sd.unit=(nm/c_light)/s;
00361               
00362               fields.push_back(sd);
00363               
00364             }
00365           } else if( (token.substr(0,1)=="x") && (token.substr(1,1)!="p") ) {
00366 #ifdef DEBUG 
00367             G4cout<< "BDSBunch : " <<"x!"<<G4endl;
00368 #endif
00369             G4String rest = token.substr(1);
00370 #ifdef DEBUG 
00371             G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00372 #endif
00373             G4int pos1 = rest.find("[");
00374             G4int pos2 = rest.find("]");
00375             if(pos1 < 0 || pos2 < 0) {
00376               G4cerr<<"unit format wrong!!!"<<G4endl;
00377             } else {
00378               G4String fmt = rest.substr(pos1+1,pos2-1);
00379 #ifdef DEBUG 
00380               G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00381 #endif
00382               sd.name="x";
00383               
00384               if(fmt=="m") sd.unit=1;
00385               if(fmt=="cm") sd.unit=1.e-2;
00386               if(fmt=="mm") sd.unit=1.e-3;
00387               if(fmt=="mum") sd.unit=1.e-6;
00388               if(fmt=="nm") sd.unit=1.e-9;
00389               
00390               fields.push_back(sd);
00391               
00392             }
00393           }else if(token.substr(0,1)=="y" && token.substr(1,1)!="p" ) {
00394 #ifdef DEBUG 
00395             G4cout<< "BDSBunch : " <<"y!"<<G4endl;
00396 #endif
00397             G4String rest = token.substr(1);
00398 #ifdef DEBUG 
00399             G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00400 #endif
00401             G4int pos1 = rest.find("[");
00402             G4int pos2 = rest.find("]");
00403             if(pos1 < 0 || pos2 < 0) {
00404               G4cerr<<"unit format wrong!!!"<<G4endl;
00405             } else {
00406               G4String fmt = rest.substr(pos1+1,pos2-1);
00407 #ifdef DEBUG 
00408               G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00409 #endif
00410               sd.name="y";
00411               
00412               if(fmt=="m") sd.unit=1;
00413               if(fmt=="cm") sd.unit=1.e-2;
00414               if(fmt=="mm") sd.unit=1.e-3;
00415               if(fmt=="mum") sd.unit=1.e-6;
00416               if(fmt=="nm") sd.unit=1.e-9;
00417               
00418               fields.push_back(sd);
00419             }
00420           }else if(token.substr(0,1)=="z" && token.substr(1,1)!="p" ) {
00421 #ifdef DEBUG 
00422               G4cout<< "BDSBunch : " <<"z!"<<G4endl;
00423 #endif
00424               G4String rest = token.substr(1);
00425 #ifdef DEBUG 
00426               G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00427 #endif
00428               G4int pos1 = rest.find("[");
00429               G4int pos2 = rest.find("]");
00430               if(pos1 < 0 || pos2 < 0) {
00431                 G4cerr<<"unit format wrong!!!"<<G4endl;
00432               } else {
00433                 G4String fmt = rest.substr(pos1+1,pos2-1);
00434 #ifdef DEBUG 
00435                 G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00436 #endif
00437                 sd.name="z";
00438                 
00439                 if(fmt=="m") sd.unit=1;
00440                 if(fmt=="cm") sd.unit=1.e-2;
00441                 if(fmt=="mm") sd.unit=1.e-3;
00442                 if(fmt=="mum") sd.unit=1.e-6;
00443                 if(fmt=="nm") sd.unit=1.e-9;
00444                 
00445                 fields.push_back(sd);
00446               }
00447           } else if(token.substr(0,2)=="xp") {
00448 #ifdef DEBUG 
00449             G4cout<< "BDSBunch : " <<"xp!"<<G4endl;
00450 #endif
00451             G4String rest = token.substr(2);
00452 #ifdef DEBUG 
00453             G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00454 #endif
00455             G4int pos1 = rest.find("[");
00456             G4int pos2 = rest.find("]");
00457             if(pos1 < 0 || pos2 < 0) {
00458               G4cerr<<"unit format wrong!!!"<<G4endl;
00459             } else {
00460               G4String fmt = rest.substr(pos1+1,pos2-1);
00461 #ifdef DEBUG 
00462               G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00463 #endif
00464               sd.name="xp";
00465               
00466               if(fmt=="rad") sd.unit=1;
00467               if(fmt=="mrad") sd.unit=1.e-3;
00468               if(fmt=="murad") sd.unit=1.e-6;
00469               
00470               fields.push_back(sd);
00471               
00472             }
00473           }else if(token.substr(0,2)=="yp") {
00474 #ifdef DEBUG 
00475             G4cout<< "BDSBunch : " <<"yp!"<<G4endl;
00476 #endif
00477             G4String rest = token.substr(2);
00478 #ifdef DEBUG 
00479             G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00480 #endif
00481             G4int pos1 = rest.find("[");
00482             G4int pos2 = rest.find("]");
00483             if(pos1 < 0 || pos2 < 0) {
00484               G4cerr<<"unit format wrong!!!"<<G4endl;
00485             } else {
00486               G4String fmt = rest.substr(pos1+1,pos2-1);
00487 #ifdef DEBUG 
00488               G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00489 #endif
00490               sd.name="yp";
00491               
00492               if(fmt=="rad") sd.unit=1;
00493               if(fmt=="mrad") sd.unit=1.e-3;
00494               if(fmt=="murad") sd.unit=1.e-6;
00495               
00496               fields.push_back(sd);
00497             }
00498           } else if(token.substr(0,2)=="zp") {
00499 #ifdef DEBUG 
00500             G4cout<< "BDSBunch : " <<"zp!"<<G4endl;
00501 #endif
00502             G4String rest = token.substr(2);
00503 #ifdef DEBUG 
00504             G4cout<< "BDSBunch : " <<"rest ->"<<rest<<G4endl;
00505 #endif
00506             G4int pos1 = rest.find("[");
00507             G4int pos2 = rest.find("]");
00508             if(pos1 < 0 || pos2 < 0) {
00509               G4cerr<<"unit format wrong!!!"<<G4endl;
00510             } else {
00511               G4String fmt = rest.substr(pos1+1,pos2-1);
00512 #ifdef DEBUG 
00513               G4cout<< "BDSBunch : " <<"fmt ->"<<fmt<<G4endl;
00514 #endif
00515               sd.name="zp";
00516               
00517               if(fmt=="rad") sd.unit=1;
00518               if(fmt=="mrad") sd.unit=1.e-3;
00519               if(fmt=="murad") sd.unit=1.e-3;
00520               
00521               fields.push_back(sd);
00522             }
00523           }else if(token.substr(0,2)=="pt") {
00524 #ifdef DEBUG 
00525             G4cout<< "BDSBunch : " <<"pt!"<<G4endl;
00526 #endif
00527             sd.name="pt";
00528             sd.unit=1;
00529             fields.push_back(sd);
00530           } else if(token.substr(0,1)=="w") {
00531 #ifdef DEBUG 
00532             G4cout<< "BDSBunch : " <<"weight!"<<G4endl;
00533 #endif
00534             sd.name="weight";
00535             sd.unit=1;
00536             fields.push_back(sd);
00537           } else {
00538             G4cerr << "Cannot determine bunch data format" << G4endl; exit(1);
00539           }
00540         } 
00541       OpenBunchFile();
00542     }
00543   }
00544   return;  
00545 }
00546 
00547 // get initial bunch distribution parameters in Gaussian case 
00548 G4double BDSBunch::GetSigmaT() 
00549 {
00550   return sigmaT;
00551 } 
00552 
00553 G4double BDSBunch::GetSigmaX()
00554 {
00555 
00556   return sigmaX;
00557 }
00558  
00559 G4double BDSBunch::GetSigmaY()
00560 {
00561   return sigmaY;
00562 } 
00563 
00564 G4double BDSBunch::GetSigmaXp()
00565 {
00566   return sigmaXp;
00567 }
00568 
00569 G4double BDSBunch::GetSigmaYp()
00570 {
00571   return sigmaYp;
00572 }
00573 
00574 // generate primary coordinates
00575 
00576 G4double BDSBunch::GetNextX()
00577 {
00578   return sigmaX * GaussGen->shoot() * m;
00579 } 
00580 
00581 G4double BDSBunch::GetNextY()
00582 {
00583   return sigmaY * GaussGen->shoot() * m;
00584 }
00585 
00586 G4double BDSBunch::GetNextZ()
00587 {
00588   return 0;
00589 }
00590 
00591 
00592 
00593 G4double BDSBunch::GetNextXp()
00594 {
00595   return sigmaXp * GaussGen->shoot();
00596 }
00597 
00598 G4double BDSBunch::GetNextYp()
00599 {
00600   return sigmaYp * GaussGen->shoot();
00601 }
00602 
00603 G4double BDSBunch::GetNextT()
00604 {
00605   return - sigmaT* (1.-2.*GaussGen->shoot());
00606 }
00607 
00608 
00609 void BDSBunch::GetNextParticle(G4double& x0,G4double& y0,G4double& z0,
00610                                G4double& xp,G4double& yp,G4double& zp,
00611                                G4double& t, G4double& E, G4double &weight)
00612 {
00613 
00614 #ifdef DEBUG 
00615   G4cout<< "BDSBunch::GetNextParticle> Twiss : " << betaX  << " " << betaY  << " " 
00616                                                  << alphaX << " " << alphaY << " "
00617                                                  << emitX  << " " << emitY  << G4endl;
00618 #endif
00619   if(verboseStep) G4cout<< "BDSBunch : " <<"distribution type: "<<distribType<<G4endl;
00620 
00621   double r, phi;
00622   // Rescale must be at the top of GetNextParticle
00623 
00624   if(BDSGlobalConstants::Instance()->isReference && partId<nptwiss){
00625     G4double phiX= twopi * G4UniformRand();
00626     G4double phiY= twopi * G4UniformRand();
00627     //    G4double ex=-log(G4UniformRand())*emitX;
00628     //    G4double ey=-log(G4UniformRand())*emitY;
00629     G4double ex=std::abs(GaussGen->shoot()*emitX);
00630     G4double ey=std::abs(GaussGen->shoot()*emitY);
00631     x0=sqrt(2*ex*betaX)*sin(phiX);
00632     xp=sqrt(2*ex/betaX)*(cos(phiX)-alphaX*sin(phiX));
00633     y0=sqrt(2*ey*betaY)*sin(phiY);
00634     yp=sqrt(2*ey/betaY)*(cos(phiY)-alphaY*sin(phiY)); 
00635     z0 = Z0 * m + (T0 - sigmaT * (1.-2.*GaussGen->shoot())) * c_light * s;
00636     if (Zp0<0)
00637       zp = -sqrt(1.-xp*xp -yp*yp);
00638     else
00639       zp = sqrt(1.-xp*xp -yp*yp);
00640     t = 0; 
00641     E = BDSGlobalConstants::Instance()->GetBeamKineticEnergy();
00642     ++partId;
00643     return;
00644   }
00645   
00646   if(BDSGlobalConstants::Instance()->DoTwiss() && partId<nptwiss)
00647     {
00648       // temp numbers - to be replaced by parsed parameters
00649 
00650       
00651       G4double sigx = sqrt(betaX*emitX);
00652       G4double sigxp= sqrt(emitX / betaX);
00653       
00654       G4double sigy = sqrt(betaY*emitY);
00655       G4double sigyp= sqrt(emitY / betaY);
00656       
00657       partId++;
00658       
00659       G4double phase_factor = 1 / ( (nptwiss/2.) - 1.0 );
00660       if(partId<=nptwiss/2) //primary - xx' ellipse
00661         {
00662           x0 = sigx * cos(partId* 2 * pi*phase_factor);
00663           xp = -sigxp * ( -1*alphaX * cos(partId * 2 * pi*phase_factor )
00664                           + sin(partId * 2 * pi*phase_factor ) );
00665           y0 = 0;
00666           yp = 0;
00667         }
00668       else if(partId<=nptwiss) //primary - yy' ellipse
00669         {
00670           x0 = 0;
00671           xp = 0;
00672           y0 = sigy * cos( (partId-nptwiss/2)*2*pi*phase_factor);
00673           yp = -sigyp * ( -1*alphaY * cos( (partId-nptwiss/2) * 2 * pi*phase_factor)
00674                           + sin( (partId-nptwiss/2) * 2 * pi*phase_factor) );
00675         }
00676       //tmp - check units of above equations!!
00677       x0*=m;
00678       y0*=m;
00679       xp*=radian;
00680       yp*=radian;
00681       
00682       E = BDSGlobalConstants::Instance()->GetBeamTotalEnergy() - BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
00683       zp = sqrt(1-xp*xp-yp*yp);
00684       t=0;
00685       z0=0;
00686       
00687 #ifdef DEBUG
00688         G4cout << "x: " << x0/micrometer << " xp: " << xp/radian << G4endl;
00689         G4cout << "y: " << y0/micrometer << " yp: " << yp/radian << G4endl;
00690         G4cout << "z: " << z0/micrometer << " zp: " << zp/radian << G4endl;
00691 #endif
00692         return;
00693     } //end doTwiss && partId<nptwiss
00694   
00695  
00696  
00697   switch(distribType){
00698   case _REFERENCE: 
00699     {
00700       x0 = (X0 + 0.0) * m;
00701       y0 = (Y0 + 0.0) * m;
00702       z0 = (Z0 + 0.0) * m;
00703       xp = (Xp0 + 0.0)*rad;
00704       yp = (Yp0 + 0.0)*rad;
00705       if (Zp0<0)
00706         zp = -sqrt(1.-xp*xp -yp*yp);
00707       else
00708         zp = sqrt(1.-xp*xp -yp*yp);      
00709       t  = 0.0; 
00710       E = BDSGlobalConstants::Instance()->GetBeamKineticEnergy();
00711       weight = 1.0;
00712       break;
00713     }
00714   case _GAUSSIAN:
00715     {
00716       x0 = X0 * m;
00717       y0 = Y0 * m;
00718       z0 = Z0 * m;
00719       xp = Xp0 * rad;
00720       yp = Yp0 * rad;
00721       z0 = Z0 * m + (T0 - sigmaT * (1.-2.*GaussGen->shoot())) * c_light * s;
00722 
00723       if(sigmaX !=0) x0  += sigmaX * GaussGen->shoot() * m;
00724       if(sigmaY !=0) y0  += sigmaY * GaussGen->shoot() * m;
00725       if(sigmaXp !=0) xp += sigmaXp * GaussGen->shoot() * rad;
00726       if(sigmaYp !=0) yp += sigmaYp * GaussGen->shoot() * rad;
00727 
00728       if (Zp0<0)
00729         zp = -sqrt(1.-xp*xp -yp*yp);
00730       else
00731         zp = sqrt(1.-xp*xp -yp*yp);
00732       t = 0;
00733       E = BDSGlobalConstants::Instance()->GetBeamKineticEnergy() * (1 + energySpread * GaussGen->shoot());
00734 
00735 #ifdef DEBUG 
00736       G4cout<< "BDSBunch : " <<"GAUSSIAN: "<<G4endl
00737             <<" X0= "<<X0<<" m"<<G4endl
00738             <<" Y0= "<<Y0<<" m"<<G4endl
00739             <<" Z0= "<<Z0<<" m"<<G4endl
00740             <<" T0= "<<T0<<" s"<<G4endl
00741             <<" Xp0= "<<Xp0<<G4endl
00742             <<" Yp0= "<<Yp0<<G4endl
00743             <<" Zp0= "<<Zp0<<G4endl
00744             <<" sigmaX= "<<sigmaX<<" m"<<G4endl
00745             <<" sigmaY= "<<sigmaY<<" m"<<G4endl
00746             <<" sigmaXp= "<<sigmaXp<<G4endl
00747             <<" sigmaYp= "<<sigmaYp<<G4endl
00748             <<" sigmaT= "<<sigmaT<<"s"<<G4endl
00749             <<" relative energy spread= "<<energySpread<<G4endl
00750 
00751             <<G4endl
00752             <<" x0= "<<x0<<" m"<<G4endl
00753             <<" y0= "<<y0<<" m"<<G4endl
00754             <<" z0= "<<z0<<" m"<<G4endl
00755             <<" t= "<<t<<" s"<<G4endl
00756             <<" xp= "<<xp<<G4endl
00757             <<" yp= "<<yp<<G4endl
00758             <<" zp= "<<zp<<G4endl
00759             <<" E= "<<E<<G4endl;
00760 #endif
00761 
00762 
00763       break;
00764     }
00765   case _GAUSSIAN_TWISS:
00766     {
00767 #ifdef DEBUG 
00768       G4cout<<"GAUSSIAN_TWISS: "<<G4endl
00769             // <<" X0= "<<X0<<" m"<<G4endl
00770             // <<" Y0= "<<Y0<<" m"<<G4endl
00771             // <<" Z0= "<<Z0<<" m"<<G4endl
00772             <<" T0= "<<T0<<" s"<<G4endl
00773             // <<" Xp0= "<<Xp0<<G4endl
00774             // <<" Yp0= "<<Yp0<<G4endl
00775             // <<" Zp0= "<<Zp0<<G4endl
00776             <<" alphaX= "<<alphaX<<" m"<<G4endl
00777             <<" alphaY= "<<alphaY<<" m"<<G4endl
00778             <<" betaX= "<<betaX<<G4endl
00779             <<" betaY= "<<betaY<<G4endl
00780             <<" emitX= "<<emitX<<G4endl
00781             <<" emitY= "<<emitY<<G4endl
00782             <<" sigmaT= "<<sigmaT<<"s"<<G4endl
00783             <<" relative energy spread= "<<energySpread<<G4endl;
00784 #endif
00785 
00786       if (betaX==0) G4cerr << __METHOD_NAME__ << "WARNING betaX equal to 0, xp NaN, division by zero! " << G4endl;
00787       if (betaY==0) G4cerr << __METHOD_NAME__ << "WARNING betaY equal to 0, yp NaN, division by zero! " << G4endl;
00788 
00789       G4double phiX= twopi * G4UniformRand();
00790       G4double phiY= twopi * G4UniformRand();
00791       //      G4double ex=-log(G4UniformRand())*emitX;
00792       //      G4double ey=-log(G4UniformRand())*emitY;
00793       G4double ex=std::abs(GaussGen->shoot()*emitX);
00794       G4double ey=std::abs(GaussGen->shoot()*emitY);
00795       x0=sqrt(2*ex*betaX)*sin(phiX)*m;
00796       xp=sqrt(2*ex/betaX)*(cos(phiX)-alphaX*sin(phiX))*rad;
00797       y0=sqrt(2*ey*betaY)*sin(phiY)*m;
00798       yp=sqrt(2*ey/betaY)*(cos(phiY)-alphaY*sin(phiY))*rad;
00799       z0 = Z0 * m + (T0 - sigmaT * (1.-2.*GaussGen->shoot())) * c_light * s;
00800 
00801       if (Zp0<0)
00802         zp = -sqrt(1.-xp*xp -yp*yp);
00803       else
00804         zp = sqrt(1.-xp*xp -yp*yp);
00805       t = 0; // (T0 - sigmaT * (1.-2.*GaussGen->shoot())) * s;
00806       E = BDSGlobalConstants::Instance()->GetBeamKineticEnergy() * (1 + energySpread * GaussGen->shoot());
00807       break;
00808     }
00809   case _GAUSSIAN_MATRIX :
00810     {
00811 #ifdef DEBUG 
00812       G4cout<< "BDSBunch::GetNextParticle> V0 : " << X0 << " " << Xp0 << " " << Y0 << " " << Yp0 << " " << T0 << G4endl;
00813 #endif
00814 
00815       CLHEP::HepVector v = GaussMultiGen->fire();
00816       x0 = v[0]*m;
00817       xp = v[1]*rad;
00818       y0 = v[2]*m;
00819       yp = v[3]*rad;
00820       t  = v[4];
00821       z0 = Z0*m + t*c_light;
00822       E  = BDSGlobalConstants::Instance()->GetBeamKineticEnergy() * v[5];
00823       
00824       if (Zp0<0)
00825         zp = -sqrt(1.-xp*xp -yp*yp);
00826       else
00827         zp =  sqrt(1.-xp*xp -yp*yp);
00828 
00829 #ifdef DEBUG 
00830       G4cout<< "BDSBunch::GetNextParticle>" << " GAUSSIAN_MATRIX : "<<G4endl
00831             <<" x0= "<<x0<<" m"<<G4endl
00832             <<" y0= "<<y0<<" m"<<G4endl
00833             <<" z0= "<<z0<<" m"<<G4endl
00834             <<" t= "<<t<<" s"<<G4endl
00835             <<" xp= "<<xp<<G4endl
00836             <<" yp= "<<yp<<G4endl
00837             <<" zp= "<<zp<<G4endl
00838             <<" E= "<<E<<G4endl;
00839 #endif
00840       break;
00841     }
00842 
00843   case _RING:
00844     {
00845 #ifdef DEBUG 
00846       G4cout<< "BDSBunch : " <<"RING: "<<G4endl
00847             <<" X0= "<<X0<<" m"<<G4endl
00848             <<" Y0= "<<Y0<<" m"<<G4endl
00849             <<" Z0= "<<Z0<<" m"<<G4endl
00850             <<" T0= "<<T0<<" s"<<G4endl
00851             <<" Xp0= "<<Xp0<<G4endl
00852             <<" Yp0= "<<Yp0<<G4endl
00853             <<" Zp0= "<<Zp0<<G4endl
00854             <<" rMin= "<<rMin<<" m"<<G4endl
00855             <<" rMax= "<<rMax<<" m"<<G4endl
00856             <<" relative energy spread= "<<energySpread<<G4endl;
00857 #endif
00858      
00859      
00860      r = ( rMin + (rMax - rMin) *  rand() / RAND_MAX );
00861      phi = 2 * pi * rand() / RAND_MAX;
00862      
00863      x0 = ( X0 + r * sin(phi) ) * m;
00864      y0 = ( Y0 + r * cos(phi) ) * m;
00865      z0 = Z0 * m;
00866      xp = Xp0 * rad;
00867      yp = Yp0 * rad;
00868      if (Zp0<0)
00869        zp = -sqrt(1.-xp*xp -yp*yp);
00870      else
00871        zp = sqrt(1.-xp*xp -yp*yp);
00872      t = T0 * s;
00873      E = BDSGlobalConstants::Instance()->GetBeamKineticEnergy()
00874        * (1 + energySpread/2. * (1. -2. * FlatGen->shoot()));
00875      break;
00876     }
00877   case _ESHELL:
00878     {// generate elliptical shell - first generate on S1 and then transform into ellipse
00879       
00880 #ifdef DEBUG 
00881       G4cout<< "BDSBunch : " <<"SHELL: " 
00882             <<" X0= " <<X0<<" m"<<G4endl
00883             <<" Y0= " <<Y0<<" m"<<G4endl
00884             <<" Z0= " <<Z0<<" m"<<G4endl
00885             <<" T0= " <<T0<<" s"<<G4endl
00886             <<" Xp0= " <<Xp0<<G4endl
00887             <<" Yp0= " <<Yp0<<G4endl
00888             <<" Zp0= " <<Zp0<<G4endl
00889             <<" shellX= " <<shellx<<" m"<<G4endl
00890             <<" shellY= " <<shelly<<" m"<<G4endl
00891             <<" shellXp= " <<shellxp<<G4endl
00892             <<" shellYp= " <<shellyp<<G4endl
00893             <<" relative energy spread= "<<energySpread<<G4endl;
00894 #endif
00895       
00896       phi = 2 * pi * FlatGen->shoot();
00897       
00898       x0 = (X0 + sin(phi) * shellx) * m;
00899       xp = Xp0 + cos(phi) * shellxp;
00900       
00901       phi = 2 * pi * FlatGen->shoot();
00902       
00903       y0 = (Y0 + sin(phi) * shelly) * m;
00904       yp = Yp0 + cos(phi) * shellyp;
00905       
00906       z0 = Z0 * m;
00907       if (Zp0<0)
00908         zp = -sqrt(1.-xp*xp -yp*yp);
00909       else
00910         zp = sqrt(1.-xp*xp -yp*yp);
00911       
00912       t = T0 * s;
00913       E = BDSGlobalConstants::Instance()->GetBeamKineticEnergy()
00914         * (1 + energySpread/2. * (1. -2. * FlatGen->shoot()));
00915       break;
00916     }
00917    
00918   case _GUINEAPIG_BUNCH:
00919     {
00920       if(ReadValue(E))
00921         {
00922          ReadValue(x0);
00923          ReadValue(y0);
00924          ReadValue(z0);
00925          ReadValue(xp);
00926          ReadValue(yp);
00927          
00928          E*=GeV;
00929          x0*= micrometer;
00930          y0*= micrometer;
00931          z0*= micrometer;
00932          xp*=1.e-6*radian;
00933          yp*=1.e-6*radian;
00934          zp=sqrt(1.-xp*xp -yp*yp);  
00935          t=0; 
00936          // use the Kinetic energy:
00937          E-=BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
00938         }
00939       break;
00940     }
00941   case _GUINEAPIG_SLAC:
00942     {
00943       if(ReadValue(E))
00944         {
00945           ReadValue(xp);
00946           ReadValue(yp);
00947           ReadValue(z0);
00948           ReadValue(x0);
00949           ReadValue(y0);
00950           
00951           E*=GeV;
00952           x0*= nanometer;
00953           y0*= nanometer;
00954           z0*= micrometer;
00955           xp*=radian;
00956           yp*=radian;
00957           zp=sqrt(1.-xp*xp -yp*yp);  
00958           t=0; 
00959           weight=1;
00960           // use the Kinetic energy:
00961           E-=BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
00962         }
00963       else{
00964         InputBunchFile.clear();
00965         InputBunchFile.seekg(0);
00966         skip(nlinesIgnore * 6);
00967         GetNextParticle(x0,y0,z0,xp,yp,zp,t,E,weight);
00968       }
00969       break;
00970     }
00971   case _GUINEAPIG_PAIRS:
00972     {
00973       if(ReadValue(E))
00974         {
00975           ReadValue(xp);
00976           ReadValue(yp);
00977           ReadValue(zp);
00978           ReadValue(x0);
00979           ReadValue(y0);
00980           ReadValue(z0);
00981           if(E>0) BDSGlobalConstants::Instance()->SetParticleDefinition(G4ParticleTable::
00982                                                     GetParticleTable()
00983                                                     ->FindParticle("e-"));
00984           if(E<0) BDSGlobalConstants::Instance()->SetParticleDefinition(G4ParticleTable::
00985                                                     GetParticleTable()
00986                                                     ->FindParticle("e+"));
00987           E=fabs(E)*GeV;
00988           x0*= nanometer;
00989           y0*= nanometer;
00990           z0*= nanometer;
00991           xp*=radian;
00992           yp*=radian;
00993           zp*=radian;
00994           // Using the sign of the pair file zp
00995           // but calculating zp more accurately
00996           if(zp<0) zp = -sqrt(1-(xp*xp+yp*yp));
00997           else zp = sqrt(1-(xp*xp+yp*yp));
00998           t=0; 
00999           // use the Kinetic energy:
01000           E-=BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
01001         }
01002       break;
01003     }
01004   case _CAIN:
01005     {// Note that for the CAIN input the following variables are read in but NOT used by BDSIM:
01006      //     generation, weight, spin_x, spin_y, spin_z
01007       
01008       G4int type;
01009       G4int gen;
01010       G4int pos;
01011       G4double weight; // JS: weight overwrites output parameter!
01012       G4double part_mass;
01013       G4double px,py,pz;
01014       G4double sx;
01015       G4double sy;
01016       G4double sz;
01017       G4String dbl_var;
01018       G4String rep = 'E';      
01019       
01020       if(ReadValue(type))
01021         {
01022           
01023           ReadValue(gen); // Read in but not currently used
01024           
01025           ReadValue(dbl_var);
01026           if(dbl_var.contains('D'))
01027             {
01028               pos = dbl_var.first('D');
01029               weight = atof( dbl_var.replace(pos,1,rep.data(),1) );
01030             }
01031           else weight = atof(dbl_var);
01032           // weight read in but not currently used
01033           
01034           ReadValue(dbl_var);
01035           if(dbl_var.contains('D'))
01036             {
01037               pos = dbl_var.first('D');
01038               t = atof( dbl_var.replace(pos,1,rep.data(),1) );
01039             }
01040           else t = atof(dbl_var);
01041           
01042           ReadValue(dbl_var);
01043           if(dbl_var.contains('D'))
01044             {
01045               pos = dbl_var.first('D');
01046               x0 = atof( dbl_var.replace(pos,1,rep.data(),1) );
01047             }
01048           else x0 = atof(dbl_var);
01049           
01050           ReadValue(dbl_var);
01051           if(dbl_var.contains('D'))
01052             {
01053               pos = dbl_var.first('D');
01054               y0 = atof( dbl_var.replace(pos,1,rep.data(),1) );
01055             }
01056           else y0 = atof(dbl_var);
01057           
01058           ReadValue(dbl_var);
01059           if(dbl_var.contains('D'))
01060             {
01061               pos = dbl_var.first('D');
01062               z0 = atof( dbl_var.replace(pos,1,rep.data(),1) );
01063             }
01064           else z0 = atof(dbl_var);
01065           
01066           ReadValue(dbl_var);
01067           if(dbl_var.contains('D'))
01068             {
01069               pos = dbl_var.first('D');
01070               E = atof( dbl_var.replace(pos,1,rep.data(),1) );
01071             }
01072           else E = atof(dbl_var);
01073           
01074           ReadValue(dbl_var);
01075           if(dbl_var.contains('D'))
01076             {
01077               pos = dbl_var.first('D');
01078               px = atof( dbl_var.replace(pos,1,rep.data(),1) );
01079             }
01080           else px = atof(dbl_var);
01081           
01082           ReadValue(dbl_var);
01083           if(dbl_var.contains('D'))
01084             {
01085               pos = dbl_var.first('D');
01086               py = atof( dbl_var.replace(pos,1,rep.data(),1) );
01087             }
01088           else py = atof(dbl_var);
01089           
01090           ReadValue(dbl_var);
01091           if(dbl_var.contains('D'))
01092             {
01093               pos = dbl_var.first('D');
01094               pz = atof( dbl_var.replace(pos,1,rep.data(),1) );
01095             }
01096           else pz = atof(dbl_var);
01097           
01098           // Spin Components read in - but not currently used
01099           ReadValue(sx);
01100           ReadValue(sy);
01101           ReadValue(sz);
01102           
01103           if(type==1) 
01104             BDSGlobalConstants::Instance()->SetParticleDefinition(G4ParticleTable::
01105                                               GetParticleTable()
01106                                               ->FindParticle("gamma"));
01107           else if(type==2) 
01108             BDSGlobalConstants::Instance()->SetParticleDefinition(G4ParticleTable::
01109                                               GetParticleTable()
01110                                               ->FindParticle("e-"));
01111           
01112           else if(type==3) 
01113             BDSGlobalConstants::Instance()->SetParticleDefinition(G4ParticleTable::
01114                                               GetParticleTable()
01115                                               ->FindParticle("e+"));
01116           
01117           t*= m/c_light;
01118           x0*= m;
01119           y0*= m;
01120           z0*= m;
01121           E*=eV;
01122           px*=eV/c_light;
01123           py*=eV/c_light;
01124           pz*=eV/c_light;
01125           
01126           part_mass = BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
01127           // use the Kinetic energy:
01128           E-=part_mass;
01129           
01130           // calculate the momentum direction needed for BDSPrimaryGenerator
01131           xp = px*c_light / sqrt(E*E + 2*E*part_mass);
01132           yp = py*c_light / sqrt(E*E + 2*E*part_mass);
01133           zp = pz*c_light / sqrt(E*E + 2*E*part_mass);
01134           
01135 #ifdef DEBUG 
01136           G4cout << "Bunch input was: " << G4endl;
01137           G4cout << type << "\t"
01138                  << gen << "\t"
01139                  << weight << "\t"
01140                  << t/m << "\t"
01141                  << x0/m << "\t"
01142                  << y0/m << "\t"
01143                  << z0/m << "\t"
01144                  << E/eV << "\t"
01145                  << px/(eV/c_light) << "\t"
01146                  << py/(eV/c_light) << "\t"
01147                  << pz/(eV/c_light) << "\t"
01148                  << sx << "\t"
01149                  << sy << "\t"
01150                  << sz << "\t"
01151                  << xp << "\t"
01152                  << yp << "\t"
01153                  << zp << "\t"
01154                  << G4endl << G4endl;
01155 #endif
01156         }
01157       break;
01158     }
01159   case _UDEF:
01160     {
01161       E = x0 = y0 = z0 = xp = yp = zp = 0;
01162 
01163       bool zpdef = false; //keeps record whether zp has been read from file
01164       bool tdef = false; //keeps record whether t has been read from file
01165 
01166      
01167       G4int type;
01168 
01169       //Skip the a number of lines defined by the user option.
01170 #ifdef DEBUG 
01171       G4cout<< "BDSBunch : " <<"UDEF_BUNCH: skipping "<<nlinesIgnore<<"  lines"<<G4endl;
01172 #endif
01173       skip((G4int)(nlinesIgnore * fields.size()));
01174      
01175       std::list<struct BDSBunch::Doublet>::iterator it;
01176      for(it=fields.begin();it!=fields.end();it++)
01177        {
01178 #ifdef DEBUG 
01179          G4cout<< "BDSBunch : " <<it->name<<"  ->  "<<it->unit<<G4endl;
01180 #endif
01181          if(it->name=="E") { ReadValue(E); E *= ( GeV * it->unit ); 
01182 #ifdef DEBUG 
01183          G4cout << "******** Particle Mass = " << BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass() << G4endl;
01184          G4cout << "******** Particle Total Energy = " << E << G4endl;
01185          
01186          E-=BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGMass();
01187          G4cout << "******** Particle Kinetic Energy = " << E << G4endl;
01188          
01189          G4cout<< "BDSBunch : " << E <<G4endl;
01190 #endif
01191          }
01192          if(it->name=="t") { ReadValue(t); t *= ( s * it->unit ); tdef = true; }
01193          if(it->name=="x") { ReadValue(x0); x0 *= ( m * it->unit ); 
01194 #ifdef DEBUG 
01195            G4cout<< "BDSBunch : " << x0 <<G4endl;
01196 #endif
01197          }
01198          if(it->name=="y") { 
01199            ReadValue(y0); y0 *= ( m * it->unit ); 
01200 #ifdef DEBUG 
01201            G4cout<< "BDSBunch : " << y0 <<G4endl;
01202 #endif
01203          }
01204          if(it->name=="z") { 
01205            ReadValue(z0); z0 *= ( m * it->unit ); 
01206 #ifdef DEBUG 
01207            G4cout<< "BDSBunch : " << z0 <<G4endl;
01208 #endif
01209          }
01210          if(it->name=="xp") { ReadValue(xp); xp *= ( radian * it->unit ); }
01211          if(it->name=="yp") { ReadValue(yp); yp *= ( radian * it->unit ); }
01212          if(it->name=="zp") { ReadValue(zp); zp *= ( radian * it->unit ); zpdef = true;}
01213          if(it->name=="pt") {
01214            ReadValue(type);
01215            if(InputBunchFile.good()){
01216              BDSGlobalConstants::Instance()->SetParticleName(G4ParticleTable::GetParticleTable()->FindParticle(type)->GetParticleName());
01217              BDSGlobalConstants::Instance()->SetParticleDefinition(G4ParticleTable::
01218                                                GetParticleTable()
01219                                                ->FindParticle(type));
01220              if(!BDSGlobalConstants::Instance()->GetParticleDefinition()) 
01221                {
01222                  G4Exception("Particle not found, quitting!", "-1", FatalErrorInArgument, "");
01223                  exit(1);
01224                }
01225            }
01226          }
01227          if(it->name=="weight") {ReadValue(weight);
01228 #ifdef DEBUG 
01229            G4cout<< "BDSBunch : " << weight <<G4endl;
01230 #endif
01231          }
01232 
01233          // compute zp from xp and yp if it hasn't been read from file
01234          if (!zpdef) zp=sqrt(1.-xp*xp -yp*yp);
01235          // compute t from z0 if it hasn't been read from file
01236          if (!tdef) t=0; 
01237          // use the Kinetic energy:
01238          //          if(BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGEncoding() != 22){
01239          //}
01240        }
01241      //Add the global offset Z
01242      z0=z0+Z0*m;
01243      break;
01244     }
01245   default:
01246     {
01247       G4Exception("BDSBunch: Unknown distribution file type!", "-1", FatalErrorInArgument, "");
01248     }
01249   }
01250 }
01251 
01252 
01253 G4double BDSBunch::GetEmitX()
01254 {
01255   return emitX;
01256 }
01257 
01258 G4double BDSBunch::GetEmitY()
01259 {
01260   return emitY;
01261 }
01262 
01263 G4double BDSBunch::GetAlphaX()
01264 {
01265   return alphaX;
01266 }
01267 
01268 G4double BDSBunch::GetAlphaY()
01269 {
01270   return alphaY;
01271 }
01272 
01273 G4double BDSBunch::GetBetaX()
01274 {
01275   return betaX;
01276 }
01277 
01278 G4double BDSBunch::GetBetaY()
01279 {
01280   return betaY;
01281 }
01282 
01283 
01284 
01285 // set initial bunch distribution parameters in Gaussian case 
01286 void BDSBunch::SetSigmaT(double val) 
01287 {
01288   sigmaT= val;
01289 } 
01290 
01291 void BDSBunch::SetSigmaX(double val)
01292 { 
01293   sigmaX = val;
01294 }
01295  
01296 void BDSBunch::SetSigmaY(double val)
01297 {
01298   sigmaY = val;
01299 } 
01300 
01301 void BDSBunch::SetSigmaXp(double val)
01302 {
01303   sigmaXp = val;
01304 }
01305 
01306 void BDSBunch::SetSigmaYp(double val)
01307 {
01308   sigmaYp = val;
01309 }
01310 
01311 void BDSBunch::SetX0(double val)
01312 {
01313   X0 = val;
01314 } 
01315 
01316 void BDSBunch::SetY0(double val)
01317 {
01318   Y0 = val;
01319 }
01320 
01321 void BDSBunch::SetXp0(double val)
01322 {
01323   Xp0 = val;
01324 }
01325 
01326 void BDSBunch::SetYp0(double val)
01327 {
01328   Yp0 = val;
01329 }
01330 
01331 void BDSBunch::SetEmitX(double val)
01332 {
01333   emitX = val;
01334 }
01335 
01336 void BDSBunch::SetEmitY(double val)
01337 {
01338   emitY = val;
01339 }
01340 
01341 void BDSBunch::SetAlphaX(double val)
01342 {
01343   alphaX = val;
01344 }
01345 
01346 void BDSBunch::SetAlphaY(double val)
01347 {
01348   alphaY = val;
01349 }
01350 
01351 void BDSBunch::SetBetaX(double val)
01352 {
01353   betaX = val;
01354 }
01355 
01356 void BDSBunch::SetBetaY(double val)
01357 {
01358   betaY = val;
01359 }
01360 
01361 void BDSBunch::SetEnergySpread(double val)
01362 {
01363   energySpread = val;
01364 }
01365 
01366 template <typename Type> G4bool  BDSBunch::ReadValue(Type &value){
01367   InputBunchFile>>value; 
01368   if (InputBunchFile.eof()){ //If the end of the file is reached go back to the beginning of the file.
01369 #ifdef DEBUG
01370     G4cout << "BDSBunch.cc> End of file reached. Returning to beginning of file." << G4endl;
01371 #endif
01372     CloseBunchFile();
01373     OpenBunchFile();
01374     InputBunchFile>>value; 
01375   } 
01376 
01377   return !InputBunchFile.eof();
01378 }
01379 
01380 void BDSBunch::OpenBunchFile(){
01381   InputBunchFile.open(inputfile);
01382   if(!InputBunchFile.good()){ 
01383     G4cerr<<"Cannot open bunch file "<<inputfile<<G4endl; 
01384     exit(1); 
01385   } 
01386 }
01387 
01388 void BDSBunch::CloseBunchFile(){
01389   InputBunchFile.close();
01390 }

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7