00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 const int DEBUG = 0;
00020
00021
00022
00023 #include "BDSGlobalConstants.hh"
00024
00025 #include "BDSDetectorConstruction.hh"
00026
00027 #include "G4UserLimits.hh"
00028
00029 #include "G4Region.hh"
00030 #include "G4ProductionCuts.hh"
00031
00032 #include "G4Tubs.hh"
00033 #include "G4Box.hh"
00034 #include "G4LogicalVolume.hh"
00035 #include "G4PVPlacement.hh"
00036 #include "G4UniformMagField.hh"
00037 #include "G4FieldManager.hh"
00038 #include "G4TransportationManager.hh"
00039 #include "G4PropagatorInField.hh"
00040 #include "G4SDManager.hh"
00041 #include "G4RunManager.hh"
00042
00043 #include "G4VisAttributes.hh"
00044 #include "G4Colour.hh"
00045 #include "globals.hh"
00046 #include "G4ios.hh"
00047 #include <iostream>
00048 #include <list>
00049 #include <map>
00050 #include "BDSAcceleratorComponent.hh"
00051
00052 #include "G4Navigator.hh"
00053 #include "G4UniformMagField.hh"
00054
00055 #include "G4Material.hh"
00056 #include "BDSEnergyCounterSD.hh"
00057
00058
00059 #include "BDSBeamPipe.hh"
00060 #include "BDSDrift.hh"
00061 #include "BDSSectorBend.hh"
00062 #include "BDSRBend.hh"
00063 #include "BDSKicker.hh"
00064 #include "BDSQuadrupole.hh"
00065 #include "BDSSextupole.hh"
00066
00067 #include "BDSOctupole.hh"
00068 #include "BDSDecapole.hh"
00069 #include "BDSTMultipole.hh"
00070 #include "BDSRfCavity.hh"
00071 #include "BDSSolenoid.hh"
00072 #include "BDSSampler.hh"
00073 #include "BDSSamplerCylinder.hh"
00074 #include "BDSDump.hh"
00075 #include "BDSLaserWire.hh"
00076 #include "BDSLWCalorimeter.hh"
00077 #include "BDSMuSpoiler.hh"
00078 #include "BDSTransform3D.hh"
00079 #include "BDSElement.hh"
00080 #include "BDSComponentOffset.hh"
00081 #include "BDSCollimator.hh"
00082
00083
00084 #include "BDSOutput.hh"
00085
00086
00087 #include "G4MagneticField.hh"
00088
00089
00090 #include "parser/gmad.h"
00091 #include "ggmad.hh"
00092
00093 using namespace std;
00094
00095
00096
00097
00098 typedef list<BDSAcceleratorComponent*> BDSBeamline;
00099 BDSBeamline theBeamline;
00100
00101 typedef list<BDSEnergyCounterSD*> ECList;
00102 ECList* theECList;
00103
00104 BDSMaterials* theMaterials;
00105
00106 extern BDSGlobalConstants* BDSGlobals;
00107
00108
00109
00110 G4double BDSLocalRadiusOfCurvature=DBL_MAX;
00111
00112
00113 G4Material* aMaterial;
00114 extern G4double NumSpoilerRadLen;
00115
00116 typedef std::map<G4String,int> LogVolCountMap;
00117 LogVolCountMap* LogVolCount;
00118
00119 typedef std::map<G4String,G4LogicalVolume*> LogVolMap;
00120 LogVolMap* LogVol;
00121
00122 G4RotationMatrix* RotY90=new G4RotationMatrix();
00123 G4RotationMatrix* RotYM90=new G4RotationMatrix();
00124
00125 G4Navigator* StepperNavigator;
00126 G4Navigator* QuadNavigator;
00127
00128
00129 G4FieldManager* theOuterFieldManager;
00130
00131 extern BDSOutput bdsOutput;
00132 extern G4bool verbose;
00133 extern G4bool outline;
00134
00135
00136
00137
00138 BDSDetectorConstruction::BDSDetectorConstruction()
00139 {
00140 G4double pi_ov_2 = asin(1.);
00141
00142 RotY90->rotateY(pi_ov_2);
00143 RotYM90->rotateY(-pi_ov_2);
00144 }
00145
00146
00147
00148 G4VPhysicalVolume* BDSDetectorConstruction::Construct()
00149 {
00150 theECList=new ECList;
00151
00152 LogVolCount=new LogVolCountMap();
00153
00154 LogVol=new LogVolMap();
00155
00156 theMaterials=new BDSMaterials();
00157
00158 if (verbose || DEBUG) G4cout << "-->starting BDS construction \n"<<G4endl;
00159
00160 return ConstructBDS(beamline_list);
00161
00162 }
00163
00164
00165 G4VPhysicalVolume* BDSDetectorConstruction::ConstructBDS(list<struct Element>& beamline_list)
00166 {
00167
00168
00169
00170 G4cout.precision(10);
00171
00172
00173
00174
00175
00176 list<struct Element>::iterator it;
00177
00178
00179 if (verbose || DEBUG) G4cout << "parsing the atom list..."<< G4endl;
00180 for(it = atom_list.begin();it!=atom_list.end();it++)
00181 {
00182 if (DEBUG) G4cout << "---->adding Atom, "
00183 << "name= " << (*it).name << " "
00184 << "symbol= " << (*it).symbol << " "
00185 << "Z= " << (*it).Z << " "
00186 << "A= " << (*it).A << "g/mole "
00187 << G4endl;
00188
00189 theMaterials->AddElement((*it).name,(*it).symbol,(*it).Z,(*it).A);
00190 }
00191 if (verbose || DEBUG) G4cout << "size of atom list: "<< atom_list.size() << G4endl;
00192
00193
00194
00195
00196
00197 if (verbose || DEBUG) G4cout << "parsing the material list..."<< G4endl;
00198 for(it = material_list.begin();it!=material_list.end();it++)
00199 {
00200 if((*it).Z != 0) {
00201 if (DEBUG) G4cout << "---->adding Material, "
00202 << "name= "<< (*it).name << " "
00203 << "Z= " << (*it).Z << " "
00204 << "A= " << (*it).A << "g/mole "
00205 << "density= "<< (*it).density << "g/cm3 "
00206 << G4endl;
00207
00208 theMaterials->AddMaterial((*it).name,(*it).Z,(*it).A,(*it).density);
00209 }
00210 else if((*it).components.size() != 0){
00211
00212 G4State itsState;
00213 if ((*it).state=="solid") itsState = kStateSolid;
00214 else
00215 if ((*it).state=="liquid") itsState = kStateLiquid;
00216 else
00217 if ((*it).state=="gas") itsState = kStateGas;
00218 else {
00219 G4cout << "Unknown material state "<< (*it).state
00220 << ", setting it to default (solid)"
00221 << G4endl;
00222 (*it).state="solid";
00223 itsState = kStateSolid;
00224 }
00225
00226 if((*it).componentsWeights.size()==(*it).components.size()) {
00227
00228 if (DEBUG) G4cout << "---->adding Material, "
00229 << "name= "<< (*it).name << " "
00230 << "density= "<< (*it).density << "g/cm3 "
00231 << "state= " << (*it).state << " "
00232 << "T= " << (*it).temper << "K "
00233 << "P= " << (*it).pressure << "atm "
00234 << "ncomponents= " << (*it).components.size() << " "
00235 << G4endl;
00236
00237 theMaterials->AddMaterial((*it).name,
00238 (*it).density,
00239 itsState,
00240 (*it).temper,
00241 (*it).pressure,
00242 (*it).components,
00243 (*it).componentsWeights);
00244 }
00245 else if((*it).componentsFractions.size()==(*it).components.size()) {
00246
00247 if (DEBUG) G4cout << "---->adding Material, "
00248 << "name= "<< (*it).name << " "
00249 << "density= "<< (*it).density << "g/cm3 "
00250 << "state= " << (*it).state << " "
00251 << "T= " << (*it).temper << "K "
00252 << "P= " << (*it).pressure << "atm "
00253 << "ncomponents= " << (*it).components.size() << " "
00254 << G4endl;
00255
00256 theMaterials->AddMaterial((*it).name,
00257 (*it).density,
00258 itsState,
00259 (*it).temper,
00260 (*it).pressure,
00261 (*it).components,
00262 (*it).componentsFractions);
00263 }
00264 else {
00265 G4Exception("Badly defined material - number of components is not equal to number of weights or mass fractions!");
00266 exit(1);
00267 }
00268 }
00269 else {
00270 G4Exception("Badly defined material - need more information!");
00271 exit(1);
00272 }
00273 }
00274 if (verbose || DEBUG) G4cout << "size of material list: "<< material_list.size() << G4endl;
00275
00276
00277
00278
00279
00280 SetMagField(0.0);
00281
00282
00283
00284
00285
00286
00287
00288 G4double charge = BDSGlobals->GetParticleDefinition()->GetPDGCharge();
00289
00290 G4double momentum = BDSGlobals->GetBeamMomentum();
00291
00292 G4double brho = ( (momentum/GeV) / (0.299792458 * charge));
00293
00294 brho *= (tesla*m);
00295 if (verbose || DEBUG) G4cout << "Rigidity (Brho) : "<< fabs(brho)/(tesla*m) << " T*m"<<G4endl;
00296
00297
00298
00299
00300
00301 G4double bpRad=BDSGlobals->GetBeampipeRadius();
00302 if (verbose || DEBUG) G4cout<<"Default pipe outer radius= "<<bpRad/m<< "m"
00303 << G4endl;
00304
00305
00306
00307
00308
00309 G4double FeRad = bpRad;
00310 if (verbose || DEBUG) G4cout<<"Default magnet inner radius= "<<FeRad/m<< "m"
00311 << G4endl;
00312
00313
00314
00315 G4double bField;
00316 G4double bPrime;
00317 G4double bDoublePrime;
00318 G4double bTriplePrime;
00319
00320
00321
00322 G4double synch_factor = 1;
00323
00324
00325
00326 G4double samplerLength = 1.E-11 * m;
00327
00328
00329
00330
00331
00332 G4bool added_comp = false;
00333 if (verbose || DEBUG) G4cout << "parsing the beamline element list..."<< G4endl;
00334 for(it = beamline_list.begin();it!=beamline_list.end();it++)
00335 {
00336 added_comp = false;
00337
00338 if((*it).type==_SAMPLER ) {
00339 if(DEBUG) G4cout << "---->adding Sampler,"
00340 << " name= " << (*it).name
00341 << G4endl;
00342
00343 theBeamline.push_back(new BDSSampler( (*it).name,
00344 samplerLength ) );
00345 bdsOutput.nSamplers++;
00346
00347 added_comp=true;
00348 }
00349
00350 if((*it).type==_CSAMPLER ) {
00351
00352
00353 if( (*it).l < 1.E-4 ) (*it).l = 1.0 ;
00354
00355 if(DEBUG) G4cout << "---->adding CSampler,"
00356 << " name= " << (*it).name
00357 << " l= " << (*it).l << "m"
00358 << " r= " << (*it).r << "m"
00359 << G4endl;
00360
00361 theBeamline.push_back(new BDSSamplerCylinder( (*it).name,
00362 (*it).l * m,
00363 (*it).r * m ) );
00364 bdsOutput.nSamplers++;
00365
00366 added_comp=true;
00367 }
00368
00369 if((*it).type==_DUMP ) {
00370 if(DEBUG) G4cout << "---->adding Dump,"
00371 << " name= " << (*it).name
00372 << G4endl;
00373
00374 theBeamline.push_back(new BDSDump( (*it).name,
00375 samplerLength ) );
00376
00377 added_comp=true;
00378 }
00379
00380 if((*it).type==_DRIFT ) {
00381 G4double aper = bpRad;
00382 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00383
00384 if((*it).l > 0)
00385 {
00386 if(DEBUG) G4cout << "---->adding Drift,"
00387 << " name= " << (*it).name
00388 << " l= " << (*it).l << "m"
00389 << " aper= " << aper/m << "m"
00390 << G4endl;
00391
00392 theBeamline.push_back(new BDSDrift( (*it).name,
00393 (*it).l*m,
00394 aper ) );
00395 added_comp=true;
00396 } else {
00397 G4cerr << "---->NOT adding Drift,"
00398 << " name= " << (*it).name
00399 << ", TOO SHORT LENGTH:"
00400 << " l= " << (*it).l << "m"
00401 << G4endl;
00402 }
00403 }
00404
00405 if((*it).type==_RF ) {
00406 G4double aper = bpRad;
00407 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00408
00409 if((*it).l > 0)
00410 {
00411 if(DEBUG) G4cout << "---->adding RF,"
00412 << " name= " << (*it).name
00413 << " l= " << (*it).l << "m"
00414 << " aper= " << aper/m << "m"
00415 << " grad= " << (*it).gradient << "MV/m"
00416 << G4endl;
00417
00418 theBeamline.push_back(new BDSRfCavity( (*it).name,
00419 (*it).l * m,
00420 aper,
00421 (*it).gradient,
00422 (*it).material ) );
00423 added_comp=true;
00424 } else {
00425 G4cerr << "---->NOT adding RF,"
00426 << " name= " << (*it).name
00427 << ", TOO SHORT LENGTH:"
00428 << " l= " << (*it).l << "m"
00429 << G4endl;
00430 }
00431 }
00432
00433 if((*it).type==_SBEND ) {
00434
00435
00436
00437
00438 G4double aper = bpRad;
00439 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00440
00441 FeRad = aper;
00442
00443 if( (*it).outR < aper/m)
00444 {
00445 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00446 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00447 G4cerr << (*it).name << ": setting outer radius to default = "
00448 << "aper+22*cm"<<G4endl;
00449 (*it).outR = aper/m + 0.22;
00450 }
00451
00452
00453 G4double length = (*it).l*m;
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 if((*it).B != 0){
00467
00468 bField = (*it).B * tesla;
00469 (*it).angle = - bField * length / brho;
00470 }
00471 else{
00472 (*it).angle *= -1;
00473
00474 bField = - brho * (*it).angle / length;
00475 (*it).B = bField/tesla;
00476 }
00477
00478
00479
00480
00481
00482 bPrime = - brho * ((*it).k1 / (m*m)) * synch_factor;
00483
00484 if( fabs((*it).angle) < 1.e-7 * rad) {
00485 if(DEBUG)
00486 G4cerr << "---->NOT adding Sbend,"
00487 << " name= " << (*it).name
00488 << ", TOO SMALL ANGLE"
00489 << " angle= " << (*it).angle << "rad"
00490 << ": REPLACED WITH Drift,"
00491 << " l= " << length/m << "m"
00492 << " aper= " << aper/m << "m"
00493 << G4endl;
00494
00495 theBeamline.push_back(new BDSDrift( (*it).name,
00496 length,
00497 aper ) );
00498 }
00499 else {
00500 if(DEBUG) G4cout << "---->adding Sbend "
00501 << " name= " << (*it).name
00502 << " l= " << length/m << "m"
00503 << " angle= " << (*it).angle << "rad"
00504 << " B= " << bField/tesla << "T"
00505 << " B'= " << bPrime/(tesla/m) << "T/m"
00506 << " tilt= " << (*it).tilt
00507 << " aper= " << aper/m << "m"
00508 << " outR= " << (*it).outR << "m"
00509 << " FeRad= " << FeRad/m << "m"
00510 << " material= " << (*it).material
00511 << G4endl;
00512
00513
00514
00515
00516 length *= sin((*it).angle/2.0) / ((*it).angle/2.0);
00517
00518 theBeamline.push_back(new BDSRBend( (*it).name,
00519 length,
00520 aper,
00521 FeRad,
00522 bField,
00523 (*it).angle,
00524 (*it).outR*m,
00525 (*it).tilt,
00526 bPrime,
00527 (*it).material ) );
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 }
00541
00542 added_comp=true;
00543 }
00544
00545 if((*it).type==_RBEND ) {
00546
00547
00548
00549
00550 G4double aper = bpRad;
00551 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00552
00553 FeRad = aper;
00554
00555 if( (*it).outR < aper/m)
00556 {
00557 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00558 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00559 G4cerr << (*it).name << ": setting outer radius to default = "
00560 << "aper+22*cm"<<G4endl;
00561 (*it).outR = aper/m + 0.22;
00562 }
00563
00564 G4double length = (*it).l*m;
00565
00566
00567
00568
00569
00570
00571 if((*it).B != 0){
00572
00573 bField = (*it).B * tesla;
00574 G4double rho = brho/bField;
00575
00576 (*it).angle = - 2.0*asin(length/2.0/rho);
00577 }
00578 else{
00579 (*it).angle *= -1;
00580
00581
00582 G4double arclength = 0.5*length * (*it).angle / sin((*it).angle/2.0);
00583
00584 bField = - brho * (*it).angle / arclength;
00585 (*it).B = bField/tesla;
00586 }
00587
00588
00589
00590
00591
00592 bPrime = - brho * ((*it).k1 / (m*m)) * synch_factor;
00593
00594 if( fabs((*it).angle) < 1.e-7 * rad) {
00595 if(DEBUG)
00596 G4cerr << "---->NOT adding Rbend,"
00597 << " name= " << (*it).name
00598 << ", TOO SMALL ANGLE"
00599 << " angle= " << (*it).angle << "rad"
00600 << ": REPLACED WITH Drift,"
00601 << " l= " << length/m << "m"
00602 << " aper= " << aper/m << "m"
00603 << G4endl;
00604
00605 theBeamline.push_back(new BDSDrift( (*it).name,
00606 length,
00607 aper ) );
00608 }
00609 else {
00610 if(DEBUG) G4cout << "---->adding Rbend,"
00611 << " name= " << (*it).name
00612 << " l= " << length/m << "m"
00613 << " angle= " << (*it).angle << "rad"
00614 << " B= " << bField/tesla << "T"
00615 << " B'= " << bPrime/(tesla/m) << "T/m"
00616 << " tilt= " << (*it).tilt
00617 << " aper= " << aper/m << "m"
00618 << " outR= " << (*it).outR << "m"
00619 << " FeRad= " << FeRad/m << "m"
00620 << " material= " << (*it).material
00621 << G4endl;
00622
00623 theBeamline.push_back(new BDSRBend( (*it).name,
00624 length,
00625 aper,
00626 FeRad,
00627 bField,
00628 (*it).angle,
00629 (*it).outR*m,
00630 (*it).tilt,
00631 bPrime,
00632 (*it).material ) );
00633 }
00634
00635 added_comp=true;
00636 }
00637
00638 if((*it).type==_HKICK ) {
00639
00640
00641
00642
00643 G4double aper = bpRad;
00644 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00645
00646 FeRad = aper;
00647
00648 if( (*it).outR < aper/m)
00649 {
00650 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00651 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00652 G4cerr << (*it).name << ": setting outer radius to default = "
00653 << "aper+22*cm"<<G4endl;
00654 (*it).outR = aper/m + 0.22;
00655 }
00656
00657 G4double length = (*it).l*m;
00658
00659
00660
00661
00662 if((*it).B != 0){
00663
00664 bField = (*it).B * tesla;
00665 (*it).angle = -bField * length / brho;
00666 }
00667 else{
00668
00669 bField = - brho * (*it).angle / length;
00670 (*it).B = bField/tesla;
00671 }
00672
00673
00674
00675
00676
00677 bPrime = - brho * ((*it).k1 / (m*m)) * synch_factor;
00678
00679 if( fabs((*it).angle) < 1.e-7 * rad ) {
00680 G4cerr << "---->NOT adding Hkick,"
00681 << " name= " << (*it).name
00682 << ", TOO SMALL ANGLE"
00683 << " angle= " << (*it).angle << "rad"
00684 << ": REPLACED WITH Drift,"
00685 << " l= " << length/m << "m"
00686 << " aper= " << aper/m << "m"
00687 << G4endl;
00688
00689 theBeamline.push_back(new BDSDrift( (*it).name,
00690 length,
00691 aper ) );
00692 }
00693 else {
00694 if(DEBUG) G4cout << "---->adding HKick,"
00695 << " name= " << (*it).name
00696 << " l= " << length/m << "m"
00697 << " angle= " << (*it).angle << "rad"
00698 << " B= " << bField/tesla << "T"
00699 << " B'= " << bPrime/(tesla/m) << "T/m"
00700 << " tilt= " << (*it).tilt
00701 << " aper= " << aper/m << "m"
00702 << " outR= " << (*it).outR << "m"
00703 << " FeRad= " << FeRad/m << "m"
00704 << " material= " << (*it).material
00705 << G4endl;
00706
00707 theBeamline.push_back(new BDSKicker( (*it).name,
00708 length,
00709 aper,
00710 FeRad,
00711 bField,
00712 (*it).angle,
00713 (*it).outR*m,
00714 (*it).tilt,
00715 bPrime,
00716 (*it).material ) );
00717 }
00718
00719 added_comp=true;
00720 }
00721
00722 if((*it).type==_VKICK ) {
00723
00724
00725
00726
00727 G4double aper = bpRad;
00728 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00729
00730 FeRad = aper;
00731
00732 if( (*it).outR < aper/m)
00733 {
00734 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00735 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00736 G4cerr << (*it).name << ": setting outer radius to default = "
00737 << "aper+22*cm"<<G4endl;
00738 (*it).outR = aper/m + 0.22;
00739 }
00740
00741 G4double length = (*it).l*m;
00742
00743
00744
00745
00746 if((*it).B != 0){
00747
00748 bField = (*it).B * tesla;
00749 (*it).angle = -bField * length / brho;
00750 }
00751 else{
00752
00753 bField = - brho * (*it).angle / length;
00754 (*it).B = bField/tesla;
00755 }
00756
00757
00758
00759
00760
00761 bPrime = - brho * ((*it).k1 / (m*m)) * synch_factor;
00762
00763 if( fabs((*it).angle) < 1.e-7 * rad ) {
00764 G4cerr << "---->NOT adding Vkick,"
00765 << " name= " << (*it).name
00766 << ", TOO SMALL ANGLE"
00767 << " angle= " << (*it).angle << "rad"
00768 << ": REPLACED WITH Drift,"
00769 << " l= " << (*it).l << "m"
00770 << " aper= " << aper/m << "m"
00771 << G4endl;
00772
00773 theBeamline.push_back(new BDSDrift( (*it).name,
00774 (*it).l * m,
00775 aper ) );
00776 }
00777 else {
00778 if(DEBUG) G4cout << "---->adding VKick,"
00779 << " name= " << (*it).name
00780 << " l= " << (*it).l << "m"
00781 << " angle= " << (*it).angle << "rad"
00782 << " B= " << bField/tesla << "T"
00783 << " B'= " << bPrime/(tesla/m) << "T/m"
00784 << " tilt= " << (*it).tilt
00785 << " aper= " << aper/m << "m"
00786 << " outR= " << (*it).outR << "m"
00787 << " FeRad= " << FeRad/m << "m"
00788 << " material= " << (*it).material
00789 << G4endl;
00790
00791 theBeamline.push_back(new BDSKicker( (*it).name,
00792 (*it).l * m,
00793 aper,
00794 FeRad,
00795 bField,
00796 (*it).angle,
00797 (*it).outR * m,
00798 pi/2,
00799 bPrime,
00800 (*it).material ) );
00801 }
00802
00803 added_comp=true;
00804 }
00805
00806
00807 if((*it).type==_QUAD ) {
00808
00809
00810
00811
00812 G4double aper = bpRad;
00813 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00814
00815 FeRad = aper;
00816
00817 if( (*it).outR < aper/m)
00818 {
00819 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00820 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00821 G4cerr << (*it).name << ": setting outer radius to default = "
00822 << "aper+22*cm"<<G4endl;
00823 (*it).outR = aper/m + 0.22;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832 bPrime = - brho * ((*it).k1 / (m*m)) * synch_factor;
00833
00834 if(DEBUG) G4cout << "---->adding Quadrupole,"
00835 << " name= " << (*it).name
00836 << " l= " << (*it).l << "m"
00837 << " k1= " << (*it).k1 << "m^-2"
00838 << " brho= " << fabs(brho)/(tesla*m) << "T*m"
00839 << " B'= " << bPrime/(tesla/m) << "T/m"
00840 << " aper= " << aper/m << "m"
00841 << " outR= " << (*it).outR << "m"
00842 << " FeRad= " << FeRad/m << "m"
00843 << " material= " << (*it).material
00844 << G4endl;
00845
00846 theBeamline.push_back(new BDSQuadrupole( (*it).name,
00847 (*it).l * m,
00848 aper,
00849 FeRad,
00850 bPrime,
00851 (*it).tilt,
00852 (*it).outR * m,
00853 (*it).material,
00854 (*it).spec ) );
00855
00856 added_comp=true;
00857 }
00858
00859 if((*it).type==_SEXTUPOLE ) {
00860
00861
00862
00863
00864 G4double aper = bpRad;
00865 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00866
00867 FeRad = aper;
00868
00869 if( (*it).outR < aper/m)
00870 {
00871 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00872 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00873 G4cerr << (*it).name << ": setting outer radius to default = "
00874 << "aper+22*cm"<<G4endl;
00875 (*it).outR = aper/m + 0.22;
00876 }
00877
00878
00879
00880
00881
00882
00883
00884 bDoublePrime = - brho * ((*it).k2 / (m*m*m)) * synch_factor;
00885
00886 if(DEBUG) G4cout << "---->adding Sextupole,"
00887 << " name= " << (*it).name
00888 << " l= " << (*it).l << "m"
00889 << " k2= " << (*it).k2 << "m^-3"
00890 << " brho= " << fabs(brho)/(tesla*m) << "T*m"
00891 << " B''= " << bDoublePrime/(tesla/(m*m)) << "T/m^2"
00892 << " aper= " << aper/m << "m"
00893 << " outR= " << (*it).outR << "m"
00894 << " FeRad= " << FeRad/m << "m"
00895 << " material= " << (*it).material
00896 << G4endl;
00897
00898 theBeamline.push_back(new BDSSextupole( (*it).name,
00899 (*it).l * m,
00900 aper,
00901 FeRad,
00902 bDoublePrime,
00903 (*it).tilt,
00904 (*it).outR * m,
00905 (*it).material ) );
00906
00907 added_comp=true;
00908 }
00909
00910 if((*it).type==_OCTUPOLE ) {
00911
00912
00913
00914
00915 G4double aper = bpRad;
00916 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00917
00918 FeRad = aper;
00919
00920 if( (*it).outR < aper/m)
00921 {
00922 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00923 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00924 G4cerr << (*it).name << ": setting outer radius to default = "
00925 << "aper+22*cm"<<G4endl;
00926 (*it).outR = aper/m + 0.22;
00927 }
00928
00929
00930
00931
00932
00933
00934
00935 bTriplePrime = - brho * ((*it).k3 / (m*m*m*m)) * synch_factor;
00936
00937 if(DEBUG) G4cout << "---->adding Octupole,"
00938 << " name= " << (*it).name
00939 << " l= " << (*it).l << "m"
00940 << " k3= " << (*it).k3 << "m^-4"
00941 << " brho= " << fabs(brho)/(tesla*m) << "T*m"
00942 << " B'''= " << bTriplePrime/(tesla/(m*m*m)) << "T/m^3"
00943 << " aper= " << aper/m << "m"
00944 << " outR= " << (*it).outR << "m"
00945 << " FeRad= " << FeRad/m << "m"
00946 << " material= " << (*it).material
00947 << G4endl;
00948
00949 theBeamline.push_back(new BDSOctupole( (*it).name,
00950 (*it).l * m,
00951 aper,
00952 FeRad,
00953 bTriplePrime,
00954 (*it).tilt,
00955 (*it).outR * m,
00956 (*it).material ) );
00957
00958 added_comp=true;
00959 }
00960
00961 if((*it).type==_MULT ) {
00962
00963
00964
00965
00966 G4double aper = bpRad;
00967 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
00968
00969 FeRad = aper;
00970
00971 if( (*it).outR < aper/m)
00972 {
00973 G4cerr << (*it).name << ": outer radius smaller than aperture: "
00974 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
00975 G4cerr << (*it).name << ": setting outer radius to default = "
00976 << "aper+22*cm"<<G4endl;
00977 (*it).outR = aper/m + 0.22;
00978 }
00979
00980 if(DEBUG) G4cout << "---->adding Multipole,"
00981 << " name= " << (*it).name
00982 << " l= " << (*it).l << "m"
00983 << " aper= " << aper/m << "m"
00984 << " outR= " << (*it).outR << "m"
00985 << " FeRad= " << FeRad/m << "m"
00986 << " material= " << (*it).material
00987 << G4endl;
00988
00989
00990
00991
00992
00993 list<double>::iterator kit;
00994
00995 if(DEBUG) G4cout << " knl={ ";
00996 for(kit=(it->knl).begin();kit!=(it->knl).end();kit++)
00997 {
00998 if(DEBUG) G4cout<<(*kit)<<", ";
00999 (*kit) /= (*it).l;
01000 }
01001 if(DEBUG) G4cout << " }";
01002
01003 if(DEBUG) G4cout << " ksl={ ";
01004 for(kit=(it->ksl).begin();kit!=(it->ksl).end();kit++)
01005 {
01006 if(DEBUG) G4cout<<(*kit)<<" ";
01007 (*kit) /= (*it).l;
01008 }
01009 if(DEBUG) G4cout << " }" << G4endl;
01010
01011 theBeamline.push_back(new BDSTMultipole( (*it).name,
01012 (*it).l * m,
01013 aper,
01014 FeRad,
01015 (*it).outR*m,
01016 it->knl,
01017 it->ksl,
01018 (*it).material ) );
01019
01020 added_comp=true;
01021 }
01022
01023 if((*it).type==_ELEMENT ) {
01024
01025
01026
01027
01028 G4double aper = bpRad;
01029 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 if(DEBUG) G4cout << "---->adding Element,"
01042 << " name= " << (*it).name
01043 << " l= " << (*it).l << "m"
01044 << " aper= " << aper/m << "m"
01045 << " outR= " << (*it).outR << "m"
01046 << G4endl;
01047
01048 theBeamline.push_back(new BDSElement( (*it).name,
01049 (*it).geometryFile,
01050 (*it).bmapFile,
01051 (*it).l * m,
01052 aper,
01053 (*it).outR*m ) );
01054
01055 added_comp=true;
01056 }
01057
01058 if((*it).type==_SOLENOID ) {
01059
01060
01061
01062
01063 G4double aper = bpRad;
01064 if( (*it).aper > 1.e-10*m ) aper = (*it).aper * m;
01065
01066 FeRad = aper;
01067
01068 if( (*it).outR < aper/m)
01069 {
01070 G4cerr << (*it).name << ": outer radius smaller than aperture: "
01071 << "aper= "<<aper/m<<"m outR= "<<(*it).outR<<"m"<<G4endl;
01072 G4cerr << (*it).name << ": setting outer radius to default = "
01073 << "aper+22*cm"<<G4endl;
01074 (*it).outR = aper/m + 0.22;
01075 }
01076
01077
01078
01079
01080
01081
01082 G4double bField;
01083 if((*it).B != 0){
01084 bField = (*it).B * tesla;
01085 (*it).ks = (bField/brho) / m;
01086 }
01087 else{
01088 bField = ((*it).ks/m) * brho;
01089 (*it).B = bField/tesla;
01090 }
01091
01092 if(DEBUG) G4cout << "---->adding Solenoid,"
01093 << " name= " << (*it).name
01094 << " l= " << (*it).l << "m"
01095 << " ks= " << (*it).ks << "m^-1"
01096 << " brho= " << fabs(brho)/(tesla*m) << "T*m"
01097 << " B= " << bField/tesla << "T"
01098 << " aper= " << aper/m << "m"
01099 << " outR= " << (*it).outR << "m"
01100 << " FeRad= " << FeRad/m << "m"
01101 << " material= " << (*it).material
01102 << G4endl;
01103
01104 theBeamline.push_back(new BDSSolenoid( (*it).name,
01105 (*it).l * m,
01106 aper,
01107 FeRad,
01108 bField,
01109 (*it).outR*m,
01110 (*it).material,
01111 (*it).spec ) );
01112
01113 added_comp=true;
01114 }
01115
01116 if((*it).type==_ECOL ) {
01117
01118 G4Material* theMaterial;
01119 if((*it).material != "")
01120 theMaterial = theMaterials->GetMaterial( (*it).material );
01121 else
01122 theMaterial = theMaterials->GetMaterial( "Graphite" );
01123
01124 if(DEBUG) G4cout << "---->adding Ecol,"
01125 << " name= " << (*it).name
01126 << " xaper= " << (*it).xsize <<"m"
01127 << " yaper= " << (*it).ysize <<"m"
01128 << " material= " << (*it).material
01129 << G4endl;
01130
01131 theBeamline.push_back(new BDSCollimator((*it).name,
01132 (*it).l * m,
01133 bpRad,
01134 (*it).xsize * m,
01135 (*it).ysize * m,
01136 _ECOL,
01137 theMaterial,
01138 (*it).outR*m) );
01139
01140 added_comp=true;
01141 }
01142
01143 if((*it).type==_RCOL ) {
01144
01145 G4Material* theMaterial;
01146 if((*it).material != "")
01147 theMaterial = theMaterials->GetMaterial( (*it).material );
01148 else
01149 theMaterial = theMaterials->GetMaterial( "Graphite" );
01150
01151 if(DEBUG) G4cout << "---->adding Rcol,"
01152 << " name= " << (*it).name
01153 << " xaper= " << (*it).xsize <<"m"
01154 << " yaper= " << (*it).ysize <<"m"
01155 << " material= " << (*it).material
01156 << G4endl;
01157
01158 theBeamline.push_back(new BDSCollimator( (*it).name,
01159 (*it).l * m,
01160 bpRad,
01161 (*it).xsize * m,
01162 (*it).ysize * m,
01163 _RCOL,
01164 theMaterial,
01165 (*it).outR*m) );
01166
01167 added_comp=true;
01168 }
01169
01170 if((*it).type==_LASER ) {
01171 if((*it).l == 0) (*it).l = 1e-8;
01172
01173 if(DEBUG) G4cout << "---->adding Laser,"
01174 << " name= "<< (*it).name
01175 << " l=" << (*it).l/m<<"m"
01176 << " lambda= " << (*it).waveLength/m << "m"
01177 << " xSigma= " << (*it).xsize/m << "m"
01178 << " ySigma= " << (*it).ysize/m << "m"
01179 << " xdir= " << (*it).xdir
01180 << " ydir= " << (*it).ydir
01181 << " zdir= " << (*it).zdir
01182 << G4endl;
01183
01184 G4ThreeVector direction =
01185 G4ThreeVector((*it).xdir,(*it).ydir,(*it).zdir);
01186 G4ThreeVector position = G4ThreeVector(0,0,0);
01187
01188 theBeamline.push_back(new BDSLaserWire( (*it).name,
01189 (*it).l * m,
01190 (*it).waveLength * m,
01191 direction,
01192 position ) );
01193
01194 added_comp=true;
01195 }
01196
01197 if((*it).type==_TRANSFORM3D ) {
01198
01199 if(DEBUG) G4cout << "---->adding Transform3d,"
01200 << " name= " << (*it).name
01201 << " xdir= " << (*it).xdir/m << "m"
01202 << " ydir= " << (*it).ydir/m << "m"
01203 << " zdir= " << (*it).zdir/m << "m"
01204 << " phi= " << (*it).phi/rad << "rad"
01205 << " theta= " << (*it).theta/rad << "rad"
01206 << " psi= " << (*it).psi/rad << "rad"
01207 << G4endl;
01208
01209 theBeamline.push_back(new BDSTransform3D( (*it).name,
01210 (*it).xdir *m,
01211 (*it).ydir *m,
01212 (*it).zdir *m,
01213 (*it).phi *rad,
01214 (*it).theta *rad,
01215 (*it).psi *rad ) );
01216
01217
01218 added_comp=true;
01219 }
01220
01221 if(added_comp)
01222 {
01223 list<BDSAcceleratorComponent*>::iterator curr = theBeamline.end();
01224 curr--;
01225
01226 (*curr)->SetK1((*it).k1);
01227 (*curr)->SetK2((*it).k2);
01228 (*curr)->SetK3((*it).k3);
01229 }
01230 }
01231
01232
01233 if (verbose || DEBUG) G4cout << "size of beamline element list: "<< beamline_list.size() << G4endl;
01234
01235
01236
01237
01238
01239
01240 if (verbose || DEBUG) G4cout << "now constructing geometry" << G4endl;
01241
01242 list<BDSAcceleratorComponent*>::const_iterator iBeam;
01243
01244 G4ThreeVector rtot = G4ThreeVector(0.,0.,0.);
01245 G4ThreeVector rlast = G4ThreeVector(0.,0.,0.);
01246 G4ThreeVector rmin = G4ThreeVector(0.,0.,0.);
01247 G4ThreeVector rmax = G4ThreeVector(0.,0.,0.);
01248
01249 G4ThreeVector localX = G4ThreeVector(1,0,0);
01250 G4ThreeVector localY = G4ThreeVector(0,1,0);
01251 G4ThreeVector localZ = G4ThreeVector(0,0,1);
01252
01253 G4double s_tot = 0;
01254
01255
01256 for(iBeam=theBeamline.begin();iBeam!=theBeamline.end();iBeam++)
01257 {
01258
01259 if(DEBUG) G4cout << (*iBeam)->GetName() << " "
01260 << (*iBeam)->GetLength() << " "
01261 << (*iBeam)->GetAngle() << " "
01262 << G4endl;
01263
01264 (*iBeam)->SetSPos(s_tot+(*iBeam)->GetArcLength()/2.0);
01265
01266
01267 if(( (*iBeam)->GetType() != "sampler") || ( (*iBeam)->GetLength() <= samplerLength ) )
01268 {
01269 s_tot+= (*iBeam)->GetArcLength();
01270
01271 G4double angle=(*iBeam)->GetAngle();
01272 if(!angle && (*iBeam)->GetType()=="transform3d")
01273 angle=(*iBeam)->GetPhi();
01274 G4double theta=(*iBeam)->GetTheta();
01275 G4double psi=(*iBeam)->GetPsi();
01276
01277
01278 localX.rotate(psi,localZ);
01279 localY.rotate(psi,localZ);
01280 localZ.rotate(psi,localZ);
01281
01282 localX.rotate(angle,localY);
01283 localY.rotate(angle,localY);
01284 localZ.rotate(angle,localY);
01285
01286 localX.rotate(theta,localX);
01287 localY.rotate(theta,localX);
01288 localZ.rotate(theta,localX);
01289
01290
01291 rtot += localZ * (*iBeam)->GetZLength();
01292 if(DEBUG)
01293 G4cout << (*iBeam)->GetType() << " " << rtot << G4endl;
01294 }
01295
01296 if(rmax(0)<rtot(0)) rmax(0) = rtot(0);
01297 if(rmax(1)<rtot(1)) rmax(1) = rtot(1);
01298 if(rmax(2)<rtot(2)) rmax(2) = rtot(2);
01299
01300 if(rmin(0)>rtot(0)) rmin(0) = rtot(0);
01301 if(rmin(1)>rtot(1)) rmin(1) = rtot(1);
01302 if(rmin(2)>rtot(2)) rmin(2) = rtot(2);
01303 }
01304
01305
01306 BDSGlobals->SetTotalS(s_tot);
01307
01308
01309
01310
01311
01312 G4String LocalName="World";
01313
01314 G4double WorldSizeX = 1 * ( (fabs(rmin(0)) + fabs(rmax(0)) ) + 5*BDSGlobals->GetComponentBoxSize());
01315 G4double WorldSizeY = 1 * ( (fabs(rmin(1)) + fabs(rmax(1)) ) + 5*BDSGlobals->GetComponentBoxSize());
01316 G4double WorldSizeZ = 1 * ( (fabs(rmin(2)) + fabs(rmax(2)) ) + 5*BDSGlobals->GetComponentBoxSize());
01317
01318
01319 if(verbose || DEBUG)
01320 {
01321 G4cout<<"minX="<<rmin(0)/m<<"m"<<" maxX="<<rmax(0)/m<<" m"<<G4endl;
01322 G4cout<<"minY="<<rmin(1)/m<<"m"<<" maxY="<<rmax(1)/m<<" m"<<G4endl;
01323 G4cout<<"minZ="<<rmin(2)/m<<"m"<<" maxZ="<<rmax(2)/m<<" m"<<G4endl;
01324
01325 G4cout<<"box size="<<BDSGlobals->GetComponentBoxSize()/m<<" m"<<G4endl;
01326 G4cout<<"s_tot="<<s_tot/m<<" m"<<G4endl;
01327 }
01328
01329 bdsOutput.zMax=s_tot;
01330
01331 solidWorld = new G4Box("World", WorldSizeX, WorldSizeY, WorldSizeZ);
01332
01333 logicWorld = new G4LogicalVolume(solidWorld,
01334 theMaterials->GetMaterial("Vacuum"),
01335 "World");
01336
01337 logicWorld->SetVisAttributes (G4VisAttributes::Invisible);
01338
01339 if (DEBUG) logicWorld->SetVisAttributes(new G4VisAttributes(true));
01340
01341
01342
01343 G4UserLimits* WorldUserLimits =new G4UserLimits();
01344 WorldUserLimits->SetMaxAllowedStep(100*m);
01345 logicWorld->SetUserLimits(WorldUserLimits);
01346
01347
01348 G4cout<<"Charged Thresholdcut="<<BDSGlobals->GetThresholdCutCharged()/GeV<<" GeV"<<G4endl;
01349 G4cout<<"Photon Thresholdcut="<<BDSGlobals->GetThresholdCutPhotons()/GeV<<" GeV"<<G4endl;
01350
01351
01352 G4cout<<"Creating regions..."<<G4endl;
01353
01354 G4Region* precisionRegion = new G4Region("precision");
01355
01356 G4ProductionCuts* theProductionCuts = new G4ProductionCuts();
01357
01358 if(BDSGlobals->GetProdCutPhotonsP()>0)
01359 theProductionCuts->SetProductionCut(BDSGlobals->GetProdCutPhotonsP(),"gamma");
01360
01361 if(BDSGlobals->GetProdCutElectronsP()>0)
01362 theProductionCuts->SetProductionCut(BDSGlobals->GetProdCutElectronsP(),"e-");
01363
01364 if(BDSGlobals->GetProdCutPositronsP()>0)
01365 theProductionCuts->SetProductionCut(BDSGlobals->GetProdCutPositronsP(),"e+");
01366
01367 precisionRegion->SetProductionCuts(theProductionCuts);
01368
01369
01370
01371 physiWorld = new G4PVPlacement(0,
01372 0,
01373 logicWorld,
01374 LocalName,
01375 NULL,
01376 false,
01377 0);
01378
01379
01380
01381
01382 G4SDManager* SDman = G4SDManager::GetSDMpointer();
01383
01384 G4bool use_graphics=true;
01385 G4ThreeVector TargetPos;
01386
01387
01388 G4cout.precision(15);
01389
01390 if(DEBUG) G4cout<<" total length="<<s_tot/m<<G4endl;
01391
01392
01393 for(iBeam=theBeamline.begin();iBeam!=theBeamline.end();iBeam++){
01394
01395
01396 if((*iBeam)->GetLength()!=0.)
01397 {
01398 G4String logVolName = (*iBeam)->GetMarkerLogicalVolume()->GetName();
01399 (*LogVolCount)[logVolName]=1;
01400 }
01401 }
01402
01403 if (verbose || DEBUG) G4cout<<"starting placement procedure "<<G4endl;
01404
01405 rtot = G4ThreeVector(0.,0.,0.);
01406 localX = G4ThreeVector(1.,0.,0.);
01407 localY = G4ThreeVector(0.,1.,0.);
01408 localZ = G4ThreeVector(0.,0.,1.);
01409
01410 G4RotationMatrix globalRotation;
01411
01412 for(iBeam=theBeamline.begin();iBeam!=theBeamline.end();iBeam++)
01413 {
01414
01415
01416 G4double angle=(*iBeam)->GetAngle();
01417 G4double theta=(*iBeam)->GetTheta();
01418 G4double psi = (*iBeam)->GetPsi();
01419 G4double tilt = (*iBeam)->GetTilt();
01420 G4double phi = (*iBeam)->GetPhi();
01421 G4double length = (*iBeam)->GetZLength();
01422
01423 if( (*iBeam)->GetType() == "transform3d")
01424 {
01425
01426 if(DEBUG) G4cout<<"transform3d : "<<phi<<" "<<theta<<" "<<psi<<G4endl;
01427
01428
01429 rtot(0) += (*iBeam)->GetXOffset();
01430 rtot(1) += (*iBeam)->GetYOffset();
01431 rtot(2) += (*iBeam)->GetZOffset();
01432
01433 rlast(0) += (*iBeam)->GetXOffset();
01434 rlast(1) += (*iBeam)->GetYOffset();
01435 rlast(2) += (*iBeam)->GetZOffset();
01436
01437 globalRotation.rotate(psi,localZ);
01438 localX.rotate(psi,localZ);
01439 localY.rotate(psi,localZ);
01440
01441 globalRotation.rotate(phi,localY);
01442 localX.rotate(phi,localY);
01443 localZ.rotate(phi,localY);
01444
01445 globalRotation.rotate(theta,localX);
01446 localY.rotate(theta,localX);
01447 localZ.rotate(theta,localX);
01448
01449 continue;
01450 }
01451
01452
01453 G4RotationMatrix *rotateComponent = new G4RotationMatrix;
01454
01455
01456 if((*iBeam)->GetType() == "sbend" || (*iBeam)->GetType() == "rbend" )
01457 {
01458 globalRotation.rotate(tilt,localZ);
01459 localX.rotate(tilt,localZ);
01460 localY.rotate(tilt,localZ);
01461 }
01462 else
01463 rotateComponent->rotateZ(tilt);
01464
01465
01466 G4ThreeVector zHalfAngle = localZ;
01467
01468 if((*iBeam)->GetType() == "sbend" || (*iBeam)->GetType() == "rbend")
01469 zHalfAngle.rotate(angle/2,localY);
01470
01471 if(DEBUG)
01472 {
01473 G4cout<<"zHalfAngle="<<zHalfAngle<<G4endl;
01474 G4cout<<"localZ="<<localZ<<G4endl;
01475 G4cout<<"localX="<<localX<<G4endl;
01476 G4cout<<"localY="<<localY<<G4endl;
01477 G4cout<<"rlast="<<rlast<<G4endl;
01478 }
01479
01480
01481 TargetPos = rlast + zHalfAngle * ( length/2 + BDSGlobals->GetLengthSafety()/2 ) ;
01482
01483 if(DEBUG) G4cout<<"TargetPos="<<TargetPos<<G4endl;
01484
01485
01486 if( ( ( (*iBeam)->GetType() != "sampler") || ( length <= samplerLength ) ) && ( (*iBeam)->GetType()!=_ELEMENT ))
01487 {
01488 if(DEBUG) G4cout << (*iBeam)->GetType() << " "
01489 << (*iBeam)->GetName() << " "
01490 << G4endl;
01491 rtot = rlast + zHalfAngle * ( length/2 + BDSGlobals->GetLengthSafety()/2 );
01492 rlast = rtot + zHalfAngle * ( length/2 + BDSGlobals->GetLengthSafety()/2 );
01493 }
01494
01495
01496 rotateComponent->transform(globalRotation);
01497
01498 rotateComponent->invert();
01499
01500
01501
01502
01503
01504 if( (*iBeam)->GetType() == "sbend" || (*iBeam)->GetType() == "rbend")
01505 {
01506 globalRotation.rotate(angle,localY);
01507 localX.rotate(angle,localY);
01508 localZ.rotate(angle,localY);
01509
01510
01511 globalRotation.rotate(theta,localX);
01512 localY.rotate(theta,localX);
01513 localZ.rotate(theta,localX);
01514
01515
01516 rotateComponent->rotateY(-pi/2-angle/2);
01517 }
01518
01519
01520
01521
01522
01523 if(length!=0.){
01524
01525 G4LogicalVolume* LocalLogVol=(*iBeam)->GetMarkerLogicalVolume();
01526
01527 G4String LogVolName=LocalLogVol->GetName();
01528 int nCopy=(*LogVolCount)[LogVolName]-1;
01529 (*LogVolCount)[LogVolName]++;
01530
01531
01532
01533 if((*iBeam)->GetType() == _ELEMENT)
01534 {
01535
01536 LocalLogVol->SetRegion(precisionRegion);
01537 precisionRegion->AddRootLogicalVolume(LocalLogVol);
01538 }
01539
01540
01541
01542 (*iBeam)->SetCopyNumber(nCopy);
01543 G4LogicalVolume* SensVol=(*iBeam)->GetSensitiveVolume();
01544
01545 if(SensVol)
01546 {
01547 BDSEnergyCounterSD* ECounter=new BDSEnergyCounterSD(LogVolName);
01548 (*iBeam)->SetBDSEnergyCounter(ECounter);
01549 SensVol->SetSensitiveDetector(ECounter);
01550 SDman->AddNewDetector(ECounter);
01551 theECList->push_back(ECounter);
01552 }
01553
01554 vector<G4LogicalVolume*> MultipleSensVols = (*iBeam)->GetMultipleSensitiveVolumes();
01555 if((*iBeam)->GetType()!="sampler" && MultipleSensVols.size()>0)
01556 {
01557 for(G4int i=0; i<(G4int)MultipleSensVols.size(); i++)
01558 {
01559 BDSEnergyCounterSD* ECounter=
01560 new BDSEnergyCounterSD(LogVolName+BDSGlobals->StringFromInt(i));
01561 (*iBeam)->SetBDSEnergyCounter(ECounter);
01562 MultipleSensVols.at(i)->SetSensitiveDetector(ECounter);
01563 SDman->AddNewDetector(ECounter);
01564 theECList->push_back(ECounter);
01565 }
01566 }
01567
01568 if((*iBeam)->GetType()=="sampler") {
01569 LocalName=(*iBeam)->GetName()+"_phys";
01570 bdsOutput.SampName.push_back(LocalName + "_" + BDSGlobals->StringFromInt(nCopy+1));
01571 } else {
01572
01573
01574 LocalName=(*iBeam)->GetName()+"_phys";
01575 }
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603 (*iBeam)->AlignComponent(
01604 rlast,
01605 rotateComponent,
01606 globalRotation,
01607 rtot,
01608 rlast,
01609 localX,
01610 localY,
01611 localZ);
01612
01613
01614 G4PVPlacement* PhysiComponentPlace =
01615 new G4PVPlacement(
01616 rotateComponent,
01617 TargetPos,
01618 LocalName,
01619 LocalLogVol,
01620 physiWorld,
01621 false,
01622 nCopy);
01623
01624 (*iBeam)->PrepareField(PhysiComponentPlace);
01625
01626 if(use_graphics)
01627 {
01628 (*iBeam)->GetVisAttributes()->SetVisibility(false);
01629
01630 (*iBeam)->GetMarkerLogicalVolume()->
01631 SetVisAttributes((*iBeam)->GetVisAttributes());
01632 }
01633
01634 }
01635 }
01636
01637
01638 for(it = beamline_list.begin();it!=beamline_list.end();it++)
01639 {
01640
01641 if((*it).type==_TUNNEL ) {
01642 G4cout<<"BUILDING TUNNEL : "<<(*it).l<<" "<<(*it).name<<G4endl;
01643
01644 G4String gFormat="", gFile="";
01645 G4String geometry = (*it).geometryFile;
01646
01647
01648 G4int pos = geometry.find(":");
01649
01650 if(pos<0) {
01651 G4cerr<<"WARNING: invalid geometry reference format : "<<geometry<<endl;
01652 gFormat="none";
01653 }
01654
01655 else {
01656 gFormat = geometry.substr(0,pos);
01657 gFile = geometry.substr(pos+1,geometry.length() - pos);
01658 }
01659
01660 G4cout<<"placing components\n: geometry format - "<<gFormat<<G4endl<<
01661 "file - "<<gFile<<G4endl;
01662
01663 GGmadDriver *ggmad;
01664
01665 if(gFormat=="gmad") {
01666
01667 ggmad = new GGmadDriver(gFile);
01668 ggmad->Construct(logicWorld);
01669
01670
01671 } else G4cerr<<"Tunnel won't be build! "<<endl;
01672 }
01673
01674 }
01675
01676
01677 beamline_list.clear();
01678
01679
01680
01681
01682
01683
01684 if(verbose || DEBUG) G4cout<<"end placement, size="<<theBeamline.size()<<G4endl;
01685
01686 if(verbose || DEBUG) G4cout<<"Detector Construction done"<<G4endl;
01687
01688 if(DEBUG) G4cout << *(G4Material::GetMaterialTable()) << G4endl;
01689
01690 return physiWorld;
01691 }
01692
01693
01694
01695
01696
01697 void BDSDetectorConstruction::SetMagField(const G4double fieldValue)
01698 {
01699
01700 G4FieldManager* fieldMgr =
01701 G4TransportationManager::GetTransportationManager()->GetFieldManager();
01702 magField = new G4UniformMagField(G4ThreeVector(0.,fieldValue,0.));
01703 fieldMgr->SetDetectorField(magField);
01704 fieldMgr->CreateChordFinder(magField);
01705
01706 }
01707
01708
01709
01710 void BDSDetectorConstruction::UpdateGeometry()
01711 {
01712 G4RunManager::GetRunManager()->DefineWorldVolume(ConstructBDS(beamline_list));
01713 }
01714
01715
01716 BDSDetectorConstruction::~BDSDetectorConstruction()
01717 {
01718 LogVolCount->clear();
01719 delete LogVolCount;
01720
01721 LogVolMap::iterator iter;
01722 for(iter=LogVol->begin();iter!=LogVol->end();iter++){
01723 delete (*iter).second;
01724 }
01725 LogVol->clear();
01726 delete LogVol;
01727
01728 delete theMaterials;
01729 }
01730
01731