#include "sr1DetectorConstruction.hh" #include "sr1DetectorMessenger.hh" #include "sr1MagneticField.hh" #include "sr1TabulatedField3D.hh" #include "sr1TabulatedField2D.hh" #include "sr1TabulatedElementField2Df.hh" // Read a 2D axial field map folded along r-axis (only positive z) #include "sr1TabulatedElementField2D.hh" // Read a 2D axial field map #include "sr1TabulatedElementField3D.hh" // Read a 3D field map ///#include "sr1Axial2DElField.hh" // ADDED to account for Gumplinger field method #include "sr1UniformField.hh" // Uniform EM field (B,E) #include "sr1GaussianField.hh" //#include "G4EqMagElectricField.hh" //Added by TS to account for electrical fields //#include "G4UniformElectricField.hh" //#include "G4ElectricField.hh" #include "sr1ScintSD.hh" #include "sr1EventAction.hh" #include "G4GeometryManager.hh" #include "G4PhysicalVolumeStore.hh" #include "G4LogicalVolumeStore.hh" #include "G4SolidStore.hh" #include "G4SDManager.hh" #include "G4PVParameterised.hh" #include "G4UnionSolid.hh" #include "G4IntersectionSolid.hh" #include "G4SubtractionSolid.hh" //#include "G4BooleanSolid.hh" #include "G4Material.hh" #include "G4NistManager.hh" #include "G4Box.hh" #include "G4Cons.hh" #include "G4LogicalVolume.hh" #include "G4PVPlacement.hh" #include "G4Tubs.hh" #include "G4Sphere.hh" #include "G4Trd.hh" #include "G4PVDivision.hh" #include "G4ChordFinder.hh" #include "G4Mag_SpinEqRhs.hh" #include "G4ClassicalRK4.hh" #include "G4MagIntegratorStepper.hh" #include "G4TransportationManager.hh" //#include "G4FieldManager.hh" //#include "G4FieldTrack.hh" //cks for visualisation #include "G4PropagatorInField.hh" //cks for visualisation #include "G4UserLimits.hh" // In order to implement overlaping field as was done by // Gumplinger in examples/extended/field/field04/ #include "F04GlobalField.hh" #include "G4VisAttributes.hh" #include "G4Colour.hh" #include "G4ios.hh" #include "sr1RootOutput.hh" //cks for storing some info in the Root output file #include "sr1Parameters.hh" #include "sr1ErrorMessage.hh" #include "sr1SteppingAction.hh" // CHANGED. TS: What is its purpose? //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... sr1DetectorConstruction::sr1DetectorConstruction() :parameterFileName("Unset"), checkOverlap(true), aScintSD(0) { DefineMaterials(); detectorMessenger = new sr1DetectorMessenger(this); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... sr1DetectorConstruction::~sr1DetectorConstruction() { delete detectorMessenger; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... #include "G4LogicalVolumeStore.hh" G4VPhysicalVolume* sr1DetectorConstruction::Construct() { // Clean old geometry, if any // G4GeometryManager::GetInstance()->OpenGeometry(); G4PhysicalVolumeStore::GetInstance()->Clean(); G4LogicalVolumeStore::GetInstance()->Clean(); G4SolidStore::GetInstance()->Clean(); ///G4cout<< "Parameter file name = "<sr1Error(FATAL,eMessage,false); } } else ReportGeometryProblem(line); pFieldMgr->SetDetectorField(sr1Field); G4Mag_SpinEqRhs *Mag_SpinEqRhs; G4MagIntegratorStepper* pStepper; Mag_SpinEqRhs = new G4Mag_SpinEqRhs(sr1Field); pStepper = new G4ClassicalRK4(Mag_SpinEqRhs,12); G4ChordFinder *pChordFinder = new G4ChordFinder(sr1Field,0.01*mm,pStepper); pFieldMgr->SetChordFinder(pChordFinder ); pointerToField[nameOfField]=pFieldMgr; } else if(strcmp(tmpString2,"electric")==0){ } } else if (strcmp(tmpString1,"construct")==0){ float x1=0,x2=0,x3=0,x4=0,x5=0,x6=0,x7=0; float posx,posy,posz; char name[100]; char mothersName[100]; char material[100]; // G4CSGSolid* solid=NULL; G4VSolid* solid=NULL; G4String solidName="sol_"; char rotMatrix[100]="norot"; char sensitiveDet[100]="dead"; int volumeID=0; char actualFieldName[100]="nofield"; if (strcmp(tmpString2,"tubs")==0){ sscanf(&line[0],"%*s %*s %*s %s %g %g %g %g %g %s %g %g %g %s %s", name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix); sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName); solidName+=name; solid = new G4Tubs(solidName,x1*mm,x2*mm,x3*mm,x4*deg,x5*deg); } else if (strcmp(tmpString2,"box")==0){ sscanf(&line[0],"%*s %*s %*s %s %g %g %g %s %g %g %g %s %s", name,&x1,&x2,&x3,material,&posx,&posy,&posz,mothersName,rotMatrix); sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName); solidName+=name; solid = new G4Box(solidName,x1*mm,x2*mm,x3*mm); } //Addition of Cones - TS else if (strcmp(tmpString2,"cones")==0){ sscanf(&line[0],"%*s %*s %*s %s %g %g %g %g %g %g %g %s %g %*g %*g %*s %*s", name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,material,&posx); sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*s %*g %g %g %s %s %s %d %s",&posy,&posz,mothersName,rotMatrix,sensitiveDet,&volumeID,actualFieldName); solidName+=name; solid = new G4Cons(solidName,x1*mm,x2*mm,x3*mm,x4*mm,x5*mm,x6*deg,x7*deg); } else if (strcmp(tmpString2,"sphere")==0){ sscanf(&line[0],"%*s %*s %*s %s %g %g %g %g %g %g %s %g %g %g %s %s", name,&x1,&x2,&x3,&x4,&x5,&x6,material,&posx,&posy,&posz,mothersName,rotMatrix); sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName); solidName+=name; solid = new G4Sphere(solidName,x1*mm,x2*mm,x3*deg,x4*deg,x5*deg,x6*deg); } /*! TS else if (strcmp(tmpString2,"uprofile")==0){ // Create a U-profile geometry. x1, x2, x3 define the outer dimensions of the U-profile (as a box), // x4 is the wall thickness of the U-profile. The centre of the U-profile // is in the centre of the box defined by x1,x2,x3. sscanf(&line[0],"%*s %*s %*s %s %g %g %g %g %s %g %g %g %s %s", name,&x1,&x2,&x3,&x4,material,&posx,&posy,&posz,mothersName,rotMatrix); sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName); solidName+=name; G4double roundingErr=0.01*mm; G4Box* box1 = new G4Box("Box1",x1*mm,x2*mm,x3*mm); G4Box* box2 = new G4Box("Box2",(x1-x4)*mm,(x2-x4/2.+roundingErr)*mm,x3*mm); G4RotationMatrix rot(0,0,0); G4ThreeVector zTrans(0,x4/2.*mm,0); G4Transform3D transform(rot,zTrans); solid = new G4SubtractionSolid(solidName, box1, box2, transform); } else if (strcmp(tmpString2,"alcSupportPlate")==0){ // Create an ALC holder geometry: x1 half-width of the holder (as a box), // x2 half-height of the spacer sscanf(&line[0],"%*s %*s %*s %s %g %g %g %g %s %g %g %g %s %s", name,&x1,&x2,&x3,&x4,material,&posx,&posy,&posz,mothersName,rotMatrix); sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName); solidName+=name; G4Box* box1 = new G4Box("Box1",x1*mm,4.7*mm,130*mm); G4Box* box2 = new G4Box("Box2",(x1-0.4)*mm,3*mm,130*mm); G4RotationMatrix rot(0,0,0); G4ThreeVector zTrans(0,1.3*mm,0); G4Transform3D transform(rot,zTrans); G4SubtractionSolid* solid_1 = new G4SubtractionSolid("Drzak", box1, box2, transform); if (x2!=0) { G4Box* box3 = new G4Box("Box3",12.5*mm,4.5*mm,4*mm); G4ThreeVector zTrans2(0,(-4.7-x2)*mm,0); G4Transform3D transform2(rot,zTrans2); solid = new G4UnionSolid("solidName", solid_1, box3, transform2); } else { solid = solid_1; } } TS: These solids are not used by sr1 */ else if (strcmp(tmpString2,"tubsbox")==0){ // Create a tube, from which center a box is cut out. x1=box half-width; x2,x3,x4,x5 define the tube. sscanf(&line[0],"%*s %*s %*s %s %g %g %g %g %g %s %g %g %g %s", name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName); sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName); solidName+=name; G4double roundingErr=0.01*mm; // to avoid some displaying problems of the subtracted volumes G4Box* solidInnerDetBox = new G4Box("SolidInnerDetBox",x1*mm,x1*mm,x3*mm+roundingErr); G4Tubs* solidOuterDetTube = new G4Tubs("SolidInnerDetTube",0.*mm,x2*mm,x3*mm,x4*deg,x5*deg); solid = new G4SubtractionSolid(solidName, solidOuterDetTube, solidInnerDetBox); } else if (strcmp(tmpString2,"tubsboxsegm")==0){ // Create a volume that looks like an intersection of tube and box. char orientation[100]; sscanf(&line[0],"%*s %*s %*s %s %s %g %g %g %g %g %s %g %g %g %s", name,orientation,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName); sscanf(&line[0],"%*s %*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName); solidName+=name; G4double roundingErr=0.01*mm; // to avoid some displaying problems of the subtracted volumes G4Box* solidDetBox = new G4Box("SolidDetBox",x2*mm,x2*mm,x3*mm+roundingErr); G4Tubs* solidDetTube = new G4Tubs("SolidDetTube",0.*mm,x2*mm,x3*mm,x4*deg,x5*deg); G4RotationMatrix* yRot = new G4RotationMatrix; G4ThreeVector zTrans; // if (strcmp(orientation,"D")==0) zTrans=G4ThreeVector(-x1*mm,-3*x1*mm,0); // else if (strcmp(orientation,"U")==0) zTrans=G4ThreeVector(x1*mm,3*x1*mm,0); // else if (strcmp(orientation,"R")==0) zTrans=G4ThreeVector(-3*x1*mm,x1*mm,0); // else if (strcmp(orientation,"L")==0) zTrans=G4ThreeVector(3*x1*mm,-x1*mm,0); if (strcmp(orientation,"D")==0) zTrans=G4ThreeVector((x1-x2)*mm,(-x1-x2)*mm,0); else if (strcmp(orientation,"U")==0) zTrans=G4ThreeVector((x2-x1)*mm,(x1+x2)*mm,0); else if (strcmp(orientation,"R")==0) zTrans=G4ThreeVector((-x1-x2)*mm,(x2-x1)*mm,0); else if (strcmp(orientation,"L")==0) zTrans=G4ThreeVector((x1+x2)*mm,(x1-x2)*mm,0); else { G4cout<<"Unknown orientation of the tubsboxsegm volume!!" <<" orientation="<SetLogicalVolumeAsSpecialSaveVolume(logicName,volumeID); sr1RootOutput::GetRootInstance()->SetSpecialSaveVolumeDefined(); } } // Unless specified as "dead", set the volume sensitive volume: if (strcmp(sensitiveDet,"dead")) { if (strcmp(sensitiveDet,"sr1/ScintSD")==0) { if(!aScintSD) { G4SDManager* SDman = G4SDManager::GetSDMpointer(); G4String scintSDname = sensitiveDet; aScintSD = new sr1ScintSD( scintSDname ); SDman->AddNewDetector( aScintSD ); G4cout<<"sr1DetectorConstruction.cc: aScintSD added: "<GetFullPathName()<SetSensitiveDetector( aScintSD ); } else { G4cout<<" sr1DetectorConstruction.cc: unknown sensitive detector \""<SetVolumeIDMapping(logicName,volumeID); } } else if (strcmp(tmpString1,"visattributes")==0){ sscanf(&line[0],"%*s %*s %*s %s",tmpString3); if (strncmp(tmpString2,"log_",4)==0) { G4LogicalVolume* pLogVol = FindLogicalVolume(tmpString2); if (pLogVol==NULL) { G4cout << "ERROR! sr1DetectorConstruction::Construct(): Logical Volume \"" << tmpString2 <<"\" not found!"<size(); i++) { G4LogicalVolume* pLogVol=pLogStore->at(i); G4String materialName=pLogVol->GetMaterial()->GetName(); if (tmpString2==materialName) { SetColourOfLogicalVolume(pLogVol,tmpString3); } } } } // if (strcmp(tmpString3,"red" )==0) {pLogVol->SetVisAttributes(G4Colour(1,0,0));} // else if (strcmp(tmpString3,"green" )==0) {pLogVol->SetVisAttributes(G4Colour(0,1,0));} // else if (strcmp(tmpString3,"blue" )==0) {pLogVol->SetVisAttributes(G4Colour(0,0,1));} // else if (strcmp(tmpString3,"white" )==0) {pLogVol->SetVisAttributes(G4Colour(1,1,1));} // else if (strcmp(tmpString3,"yellow" )==0) {pLogVol->SetVisAttributes(G4Colour(1,1,0));} // else if (strcmp(tmpString3,"black" )==0) {pLogVol->SetVisAttributes(G4Colour(0,0,0));} // else if (strcmp(tmpString3,"gray" )==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0.5,0.5));} // else if (strcmp(tmpString3,"cyan" )==0) {pLogVol->SetVisAttributes(G4Colour(0,1,1));} // else if (strcmp(tmpString3,"magenta")==0) {pLogVol->SetVisAttributes(G4Colour(1,0,1));} // else if (strcmp(tmpString3,"invisible" )==0) {pLogVol->SetVisAttributes(G4VisAttributes::Invisible);} // else { // G4cout<<"ERROR: sr1DetectorConstruction.cc unknown G4VisAttributes requested:"<SetVisAttributes(tmpVisAttributes); } // else if (strcmp(tmpString1,"setsensitive")==0){ // G4SDManager* SDman = G4SDManager::GetSDMpointer(); // if (strcmp(tmpString2,"sr1/ScintSD")==0) { // G4String scintSDname = tmpString2; //"sr1/ScintSD"; // if(!aScintSD) { // aScintSD = new sr1ScintSD( scintSDname ); // SDman->AddNewDetector( aScintSD ); // G4cout<<"sr1DetectorConstruction.cc: aScintSD added: "<GetFullPathName()<SetSensitiveDetector( aScintSD ); // myRootOutput->SetSensitiveDetectorMapping(tmpString3,volumeID); // } // else if (strcmp(tmpString2,"dummy")==0) { // int volumeID; // sscanf(&line[0],"%*s %*s %*s %s %d",tmpString3,&volumeID); // myRootOutput->SetSensitiveDetectorMapping(tmpString3,volumeID); // } // else { // G4cout<<" sr1DetectorConstruction.cc: unknown sensitive detector \""<sr1Error(FATAL,eMessage,false); } strcpy(howIsTheFieldDefined,"GLOBAL_FIELD"); // ensure the global field is initialized // perhaps should be placed at some separate position ? (void)F04GlobalField::getObject(); char typeOfField[100]="Unset"; float pp1=0; float pp2=0; float pp3=0; sscanf(&line[0],"%*s %*s %*s %g %g %g %s",&pp1,&pp2,&pp3,typeOfField); G4ThreeVector position = G4ThreeVector(pp1,pp2,pp3); ///sscanf(&line[0],"%*s %*s %*s %s",typeOfField); //typeOfField = uniform, gaussian, or fromfile float fieldValue = 0.000000001; float fieldValueFinal = 0; int fieldNrOfSteps = 0; // if (strcmp(tmpString2,"magnetic")==0){ if (strcmp(typeOfField,"fromfile")==0) { char fieldInputFileName[100]; char fieldTableType[100]; char fieldType; char logicalVolumeName[100]; ///sscanf(&line[0],"%*s %*s %*s %*g %*g %*g %*s %s %s %s %g %g %d", /// fieldTableType,fieldInputFileName,logicalVolumeName, /// &fieldValue,&fieldValueFinal,&fieldNrOfSteps); sscanf(&line[0],"%*s %*s %*s %*g %*g %*g %*s %s %s %s %g %g %d", fieldTableType, fieldInputFileName, logicalVolumeName, &fieldValue, &fieldValueFinal, &fieldNrOfSteps); // Read type of field, either electric E, or magnetic B and set // accordingly a used-defined DEFAULT unit: E -> kV/mm (0.001), B -> T (0.001) fieldType = fieldTableType[2]; G4double EMfieldUnit = 1.; if (fieldType == 'E') {EMfieldUnit = kilovolt/mm;}// = 0.001 -> MV is default in G4 (mm is def. length unit) else if (fieldType == 'B') {EMfieldUnit = tesla;} // = 0.001 -> kT is default in G4! ///G4cout<< "Assumed " << fieldType <<"-field unit: "<< EMfieldUnit << G4endl; if ((fieldType != 'E') && (fieldType != 'B')) { sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): unknown type of the tabulated field \"%c\" .",fieldType); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } ///sscanf(&line[0],"%*s %*s %*s %*s %s %s %s %g %g %d",fieldTableType,fieldInputFileName,logicalVolumeName, /// &fieldValue,&fieldValueFinal,&fieldNrOfSteps); // Find out the logical volume, to which the field will be placed: G4LogicalVolume* logVol = FindLogicalVolume(logicalVolumeName); if (logVol==NULL) { sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): GLOBAL FIELD: Logical volume \"%s\" not found.", logicalVolumeName); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } // Find the coordinates of the volume in its mother // First construct the name of the physical volume out of the logical volume name: ///G4String stringLogName=logicalVolumeName; ///int lastLocation = stringLogName.size () - 1; ///G4String physicalVolumeName = "phys" + stringLogName.substr(3,lastLocation); // G4cout<<"physicalVolumeName="<GetVolume(physicalVolumeName); ///if (physVol==NULL) { /// sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): GLOBAL FIELD: Physical volume \"%s\" not found.", /// physicalVolumeName.c_str()); /// sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); ///} ///G4ThreeVector position = physVol->GetObjectTranslation(); ///G4cout<<"position of the volume "<SetElementFieldName(tmpString2); if (fieldNrOfSteps>0) { myElementTableField->SetEventNrDependentField(fieldValue*EMfieldUnit,fieldValueFinal*EMfieldUnit,fieldNrOfSteps); } } //* --- Changed by TS to check error in field steps /* sr1Axial2DElField* myElementTableField = /// CHECK WHETHER CORRECT!! TS new sr1Axial2DElField(fieldInputFileName, fieldValue*kilovolt, 10*cm, 0.00001, logVol, position); myElementTableField->SetElementFieldName(tmpString2); if (fieldNrOfSteps>0) { myElementTableField->SetEventNrDependentField(fieldValue*tesla,fieldValueFinal*kilovolt,fieldNrOfSteps); ///myElementTableField->SetEventNrDependentField(true,fieldValue*tesla,fieldValueFinal*tesla,fieldNrOfSteps); } // FieldList* fields = F04GlobalField::getObject()->getFields(); // if (fields) { // G4cout<<"Kamil: Detector construction HHHHHH fields->size()="<size()<SetElementFieldName(tmpString2); if (fieldNrOfSteps>0) { myElementTableField->SetEventNrDependentField(fieldValue*EMfieldUnit,fieldValueFinal*EMfieldUnit,fieldNrOfSteps); } } } else if (strncmp(fieldTableType,"3D",2)==0) { //G4cout << "Field unit in 3D field map: " << EMfieldUnit << " - Field type: "<< fieldType << G4endl; //else if (strcmp(fieldTableType,"3D")==0) { sr1TabulatedElementField3D* myElementTableField = ///new sr1TabulatedElementField3D(fieldInputFileName, fieldValue*tesla, 1*m, 1., logVol, position); new sr1TabulatedElementField3D(fieldInputFileName, fieldType, fieldValue*EMfieldUnit, logVol, position); myElementTableField->SetElementFieldName(tmpString2); if (fieldNrOfSteps>0) { myElementTableField->SetEventNrDependentField(fieldValue*EMfieldUnit,fieldValueFinal*EMfieldUnit,fieldNrOfSteps); } } else { sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): unknown type of the tabulated field \"%s\" .",fieldTableType); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } } else if (strcmp(typeOfField,"uniform")==0) { //// G4cout<<"Uniform field through global F04 call."<sr1Error(FATAL,eMessage,false); } */ float fieldValue[6]; char logicalVolumeName[100]; sscanf(&line[0],"%*s %*s %*s %*g %*g %*g %*s %s %g %g %g %g %g %g", ////// %g %d", ///sscanf(&line[0],"%*s %*s %*s %*g %*g %*g %*s %s %g %g %d", /// logicalVolumeName, &fieldValue,&fieldValueFinal,&fieldNrOfSteps); logicalVolumeName, &fieldValue[0],&fieldValue[1],&fieldValue[2],&fieldValue[3],&fieldValue[4],&fieldValue[5]);///,&fieldValueFinal,&fieldNrOfSteps); ///sscanf(&line[0],"%*s %*s %*s %*s %s %s %s %g %g %d",fieldTableType,fieldInputFileName,logicalVolumeName, /// &fieldValue,&fieldValueFinal,&fieldNrOfSteps); // Find out the logical volume, to which the field will be placed: //sscanf(&line[0],"%*s %*s %*s %*s %s %g %g %d", logicalVolumeName, &fieldValue, &fieldValueFinal,&fieldNrOfSteps); // Find out the logical volume, to which the field will be placed: G4LogicalVolume* logVol = FindLogicalVolume(logicalVolumeName); if (logVol==NULL) { sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): GLOBAL FIELD: Logical volume \"%s\" not found.", logicalVolumeName); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } /* ATTENTION!! THIS PIECE OF CODE WAS CAUSING PROBLEMS WITH FIELD NESTING! // Find the coordinates of the volume in its mother // First construct the name of the physical volume out of the logical volume name: G4String stringLogName = logicalVolumeName; int lastLocation = stringLogName.size () - 1; G4String physicalVolumeName = "phys" + stringLogName.substr(3,lastLocation); // G4cout<<"physicalVolumeName="<GetVolume(physicalVolumeName); if (physVol==NULL) { sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): GLOBAL FIELD: Physical volume \"%s\" not found.", physicalVolumeName.c_str()); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } G4ThreeVector position = physVol->GetObjectTranslation(); G4cout<<"The position of the volume "<GetName()<SetElementFieldName(tmpString2); ///NOT NEEDED /// if (fieldNrOfSteps>0) { /// myElementField->SetEventNrDependentField(fieldValue*tesla,fieldValueFinal*tesla,fieldNrOfSteps); ///myElementField->SetEventNrDependentField(true,fieldValue*tesla,fieldValueFinal*tesla,fieldNrOfSteps); /// } ////// THE FOLLOWING LINES ARE ONLY FOR CHECKS. TONI FieldList* fields = F04GlobalField::getObject()->getFields(); if (fields) { ////// G4cout<<"Toni: Detector construction HHHHHH fields->size()="<size()<sr1Error(FATAL,eMessage,false); } /// if (strcmp(tmpString2,"uniform")==0){ /// nParameters=sscanf(&line[0],"%*s %*s %*s %g %g %d",&fieldValue,&fieldValueFinal,&fieldNrOfSteps); /// SetUniformMagField(fieldValue*tesla); /// G4cout<<"sr1DetectorConstruction.cc: Uniform Magnetic field set to "<GetFieldManager(); G4PropagatorInField* propagMgr = G4TransportationManager::GetTransportationManager()->GetPropagatorInField(); if (fieldMgr==NULL) { ReportProblemInStearingFile(line); sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): G4FieldManager not found: fieldMgr=NULL"); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } if (propagMgr==NULL) { ReportProblemInStearingFile(line); sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): G4PropagatorInField not found: propagMgr=NULL"); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } else { char parameterName[100]; float parameterValue; sscanf(&line[0],"%*s %*s %*s %s %g",parameterName,¶meterValue); if (strcmp(parameterName,"SetDeltaIntersection")==0){ fieldMgr->SetDeltaIntersection(parameterValue*mm); } else if (strcmp(parameterName,"SetDeltaOneStep")==0){ fieldMgr->SetDeltaOneStep(parameterValue*mm); } else if (strcmp(parameterName,"SetMinimumEpsilonStep")==0){ fieldMgr->SetMinimumEpsilonStep(parameterValue); } else if (strcmp(parameterName,"SetMaximumEpsilonStep")==0){ fieldMgr->SetMaximumEpsilonStep(parameterValue); } else if (strcmp(parameterName,"SetLargestAcceptableStep")==0) { propagMgr->SetLargestAcceptableStep(parameterValue*mm); } else if (strcmp(parameterName,"SetMaxLoopCount")==0) {propagMgr->SetMaxLoopCount(int(parameterValue)); } else { G4cout<<"sr1DetectorConstruction.cc: ERROR: Unknown parameterName \"" <GetFieldManager(); G4PropagatorInField* propagMgr = G4TransportationManager::GetTransportationManager()->GetPropagatorInField(); if (fieldMgr==NULL) { G4cout<<"sr1DetectorConstruction: ERROR: Field manager not found!"<AddPointForFieldTesting(G4ThreeVector(p0,p1,p2)); ///myGlobalField->GetFieldValue(point,Bfi); ///printf (" Magnetic Field at %f, %f, %f mm is B= %10.10f, %10.10f, %10.10f tesla.\n", /// point[0]/mm,point[1]/mm,point[2]/mm,Bfi[0]/tesla,Bfi[1]/tesla,Bfi[2]/tesla); } else { sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): printFieldValueAtPoint requested, but field not found"); sr1ErrorMessage::GetInstance()->sr1Error(SERIOUS,eMessage,false); } } } else {ReportGeometryProblem(line);} } //! END OF GUMPLINGER IMPORTED CODE! TS else if (strcmp(tmpString1,"magneticfield")==0){ //else if (strcmp(tmpString1,"magneticfield")==0) - OLD METHOD //check that the field has not been defined in some other way if (strcmp(howIsTheFieldDefined,"GLOBAL_FIELD")==0) { sprintf(eMessage,"sr1DetectorConstruction.cc::Construct(): Field is already defined! howIsTheFieldDefined=\"%s\" .", howIsTheFieldDefined); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } strcpy(howIsTheFieldDefined,"DIFFERENT_FIELDS"); float fieldValue=0.000000001; float fieldValueFinal=0; int fieldNrOfSteps=0; float fieldOption=0; G4int nParameters=0; if (strcmp(tmpString2,"uniform")==0){ fieldOption=1; nParameters=sscanf(&line[0],"%*s %*s %*s %g %g %d",&fieldValue,&fieldValueFinal,&fieldNrOfSteps); SetUniformMagField(fieldValue*tesla); G4cout<<"sr1DetectorConstruction.cc: Uniform Magnetic field set to "<SetPositionOffset(offset); } } else if (strcmp(tmpString2,"setOffsetOf3DField")==0){ float x,y,z; sscanf(&line[0],"%*s %*s %*s %g %g %g", &x, &y, &z); double offset[4]; offset[0]=x*mm; offset[1]=y*mm; offset[2]=z*mm; offset[3]=0; if (sr1TabulatedField3D::GetInstance()==NULL) {G4cout<<"WWWWWWWWWWWWWWWWWWWWWWWWWW"<SetPositionOffset(offset); } } else if (strcmp(tmpString2,"setparameter")==0){ // Set the accuracy parameters for the magnetic field // First check that the magnetic field already exists: G4FieldManager* fieldMgr = G4TransportationManager::GetTransportationManager()->GetFieldManager(); G4PropagatorInField* propagMgr = G4TransportationManager::GetTransportationManager()->GetPropagatorInField(); if (fieldMgr==NULL) { G4cout<SetDeltaIntersection(parameterValue*mm); } else if (strcmp(parameterName,"SetDeltaOneStep")==0){ fieldMgr->SetDeltaOneStep(parameterValue*mm); } else if (strcmp(parameterName,"SetMinimumEpsilonStep")==0){ fieldMgr->SetMinimumEpsilonStep(parameterValue); } else if (strcmp(parameterName,"SetMaximumEpsilonStep")==0){ fieldMgr->SetMaximumEpsilonStep(parameterValue); } else if (strcmp(parameterName,"SetLargestAcceptableStep")==0) { propagMgr->SetLargestAcceptableStep(parameterValue*mm); } else if (strcmp(parameterName,"SetMaxLoopCount")==0) {propagMgr->SetMaxLoopCount(int(parameterValue)); } else { G4cout<<"sr1DetectorConstruction.cc: ERROR: Unknown parameterName \"" <GetFieldManager(); G4PropagatorInField* propagMgr = G4TransportationManager::GetTransportationManager()->GetPropagatorInField(); if (fieldMgr==NULL) { G4cout<<"sr1DetectorConstruction: ERROR: Field manager not found!"<GetFieldManager(); if(!fieldMgr->DoesFieldChangeEnergy()) { //then we have a magnetic field const G4Field *myfield; myfield = fieldMgr->GetDetectorField(); myfield -> GetFieldValue(point,Bfi); printf (" Magnetic Field at %f, %f, %f mm is B= %10.10f, %10.10f, %10.10f tesla.\n", point[0]/mm,point[1]/mm,point[2]/mm,Bfi[0]/tesla,Bfi[1]/tesla,Bfi[2]/tesla); } } else {ReportGeometryProblem(line);} if (nParameters>0) { // nParameters is >0 only if "uniform", "gaussian" or "fromfile" // (avoids reseting the stored values for other steering options) myRootOutput->StoreGeantParameter(0,fieldOption); // store the information about the fieldOption to Root output myRootOutput->StoreGeantParameter(1,fieldValue); // store the information about the fieldValue to Root output } // If requested, set the parameters for the time dependent magnetic field. sr1EventAction* pointerToEventAction = sr1EventAction::GetInstance(); if (nParameters>2) { pointerToEventAction->SetTimeDependentField(true,fieldValue*tesla,fieldValueFinal*tesla,fieldNrOfSteps); } else { if ((strcmp(tmpString2,"uniform")==0)||(strcmp(tmpString2,"gaussian")==0)||(strcmp(tmpString2,"fromfile")==0)) { // The following line is needed just to properly fill the fieldValue into the Root output. pointerToEventAction->SetTimeDependentField(false,fieldValue*tesla,fieldValue*tesla,1); } } } //! Set range cut for a given volume, if requested by the macro file - Added by TS else if (strcmp(tmpString1,"SetUserMinEkine")==0){ G4LogicalVolume* pLogVol = FindLogicalVolume(tmpString2); if (pLogVol==NULL) { G4cout << "ERROR! sr1DetectorConstruction::Construct(): Logical Volume \"" << tmpString3 <<"\" not found!"< minEnergy value ignored"<SetUserMinEkine(minEnergy*eV); pLogVol->SetUserLimits(User_lim); G4cout<<"\nsr1DetectorConstruction.cc: Energy limit in "< maxStep value ignored"<SetSensitiveDetector( aScintSD ); } else { pLogVol->SetUserLimits(new G4UserLimits(maxStep*mm)); G4cout<<"sr1DetectorConstruction.cc: Range cut in "< SetMyTypeOfProcesses(tmpString2); } else if (strcmp(tmpString1,"storeOnlyEventsWithHits")==0){ if (strcmp(tmpString2,"false")==0){ sr1Parameters::storeOnlyEventsWithHits = false; } } else if (strcmp(tmpString1,"storeOnlyTheFirstTimeHit")==0){ if (strcmp(tmpString2,"true")==0){ sr1Parameters::storeOnlyTheFirstTimeHit = true; } } else if (strcmp(tmpString1,"signalSeparationTime")==0){ float timeSeparation; sscanf(&line[0],"%*s %*s %g",&timeSeparation); sr1Parameters::signalSeparationTime = timeSeparation*nanosecond; } //! TS: added to include Muonium formation and processes in the C-foil - by default true else if (strcmp(tmpString1,"includeMuoniumProcesses")==0){ if (strcmp(tmpString2,"false")==0){ sr1Parameters::includeMuoniumProcesses = false; G4cout<<"\nIgnoring Muonium formation and other Mu processes.\n"<FindOrBuildElement("Fe"); G4Element* Ni = man->FindOrBuildElement("Ni"); // Elements required for Brass G4Element* Cu = man->FindOrBuildElement("Cu"); G4Element* Zn = man->FindOrBuildElement("Zn"); // Elements required for MCPglass G4Element* Pb = man->FindOrBuildElement("Pb"); G4Element* O = man->FindOrBuildElement("O" ); G4Element* Si = man->FindOrBuildElement("Si"); G4Element* K = man->FindOrBuildElement("K" ); G4Element* Rb = man->FindOrBuildElement("Rb"); G4Element* Ba = man->FindOrBuildElement("Ba"); G4Element* As = man->FindOrBuildElement("As"); G4Element* Cs = man->FindOrBuildElement("Cs"); G4Element* Na = man->FindOrBuildElement("Na"); // Elements required for Macor G4Element* B = man->FindOrBuildElement("B" ); G4Element* Al = man->FindOrBuildElement("Al"); G4Element* Mg = man->FindOrBuildElement("Mg"); // compounds required for MCP Macor G4Material* MgO = new G4Material("MgO", 3.60*g/cm3, ncomponents=2); MgO->AddElement(Mg, natoms=1); MgO->AddElement(O, natoms=1); G4Material* SiO2 = new G4Material("SiO2", 2.533*g/cm3, ncomponents=2); // quartz SiO2->AddElement(O, natoms=2); SiO2->AddElement(Si, natoms=1); G4Material* Al2O3 = new G4Material("Al2O3", 3.985*g/cm3, ncomponents=2); // saphire Al2O3->AddElement (Al, natoms=2); Al2O3->AddElement (O, natoms=3); G4Material* K2O = new G4Material("K2O", 2.350*g/cm3, ncomponents=2); K2O->AddElement(O, natoms=1); K2O->AddElement(K, natoms=2); G4Material* B2O3 = new G4Material("B2O3", 2.550*g/cm3, ncomponents=2); B2O3->AddElement (B, natoms=2); B2O3->AddElement (O, natoms=3); // Define materials from Elements: Case 2 - mixture by fractional mass G4Material* brass = // Common Brass new G4Material("Brass", density=8.40*g/cm3, ncomponents=2); brass->AddElement(Zn, fractionmass=30*perCent); brass->AddElement(Cu, fractionmass=70*perCent); G4Material* steel = // Stainless Steel new G4Material("Steel", density=7.93*g/cm3, ncomponents=3); steel->AddElement(Ni, fractionmass=0.11); steel->AddElement(Cr, fractionmass=0.18); steel->AddElement(Fe, fractionmass=0.71); G4Material* macor= // Macor (used in the MCP detector) new G4Material("Macor", density=2.52*g/cm3, ncomponents=5); macor->AddMaterial(SiO2, fractionmass=0.470); // quartz macor->AddMaterial(MgO, fractionmass=0.180); macor->AddMaterial(Al2O3,fractionmass=0.170); // saphire macor->AddMaterial(K2O, fractionmass=0.105); macor->AddMaterial(B2O3, fractionmass=0.075); G4Material* mcpglass = // Glass of the Multi Channel Plate new G4Material("MCPglass", density=2.0*g/cm3, ncomponents=9); mcpglass->AddElement(Pb, fractionmass= 0.480); mcpglass->AddElement(O, fractionmass= 0.258); mcpglass->AddElement(Si, fractionmass= 0.182); mcpglass->AddElement(K, fractionmass= 0.042); mcpglass->AddElement(Rb, fractionmass= 0.018); mcpglass->AddElement(Ba, fractionmass= 0.013); mcpglass->AddElement(As, fractionmass= 0.004); mcpglass->AddElement(Cs, fractionmass= 0.002); mcpglass->AddElement(Na, fractionmass= 0.001); } //G4cout<<"Materials successfully defined."<DefineWorldVolume(Construct()); } void sr1DetectorConstruction::SetUniformMagField(G4double fieldValue) { // If we want a uniform field along z G4FieldManager *pFieldMgr; sr1MagneticField* sr1UniformField= new sr1MagneticField(); sr1UniformField->SetFieldValue(fieldValue); pFieldMgr=G4TransportationManager::GetTransportationManager()->GetFieldManager(); G4Mag_SpinEqRhs *Mag_SpinEqRhs; G4MagIntegratorStepper* pStepper; Mag_SpinEqRhs = new G4Mag_SpinEqRhs(sr1UniformField); pStepper = new G4ClassicalRK4(Mag_SpinEqRhs,12); G4cout<< "DeltaStep "<GetDeltaOneStep()/mm <<"mm" <SetChordFinder( pChordFinder ); pFieldMgr->SetDetectorField(sr1UniformField); // store the pointer to the sr1MagneticField in the event action, which is needed for // the time dependent magnetic field. sr1EventAction* pointerToEventAction = sr1EventAction::GetInstance(); pointerToEventAction->SetPointerToMusrUniformField(sr1UniformField); // G4PropagatorInField* fieldPropagator // = G4TransportationManager::GetTransportationManager() // ->GetPropagatorInField(); // fieldPropagator->SetMinimumEpsilonStep(1.e-5*mm); // fieldPropagator->SetMaximumEpsilonStep(1.e-2*mm); //cks For better visualisation of the tracks in low density materials use SetLargestAcceptableStep() // G4TransportationManager* tmanager = G4TransportationManager::GetTransportationManager(); // // tmanager->GetPropagatorInField()->SetLargestAcceptableStep(1*mm); // // tmanager->GetPropagatorInField()->SetLargestAcceptableStep(2000*mm); // if (largestAcceptableStep>0.000000001*mm) { // tmanager->GetPropagatorInField()->SetLargestAcceptableStep(largestAcceptableStep); // } // G4double LargestAcceptableStep=tmanager->GetPropagatorInField()->GetLargestAcceptableStep(); // G4cout<< "GetLargestAcceptableStep()="<SetPointerToTabulatedField3D(myMusrField); } else if (strcmp(fieldTableType,"2D")==0) { sr1TabulatedField2D* myMusrField = new sr1TabulatedField2D(inputFileName, fieldValue, 1*cm, 0.00001); sr1Field = myMusrField; pointerToEventAction->SetPointerToTabulatedField2D(myMusrField); } else { char eMessage[200]; sprintf(eMessage,"sr1DetectorConstruction.cc::SetMagField(): unknown type of the tabulated field \"%s\" .",fieldTableType); sr1ErrorMessage::GetInstance()->sr1Error(FATAL,eMessage,false); } // // just to test the values of the field // for (int i=0; i<2000; i++) { // double point[4]={0,0,i-1000,0}; // // double point[4]={-50,50,-50,0}; // double Bfi[3]={0,0,0}; // sr1Field->GetFieldValue(point,Bfi); // printf ("for point= %f %f %f B= %10.10f %10.10f %10.10f \n", // point[0],point[1],point[2],Bfi[0]/tesla,Bfi[1]/tesla,Bfi[2]/tesla); // } pFieldMgr=G4TransportationManager::GetTransportationManager()->GetFieldManager(); G4Mag_SpinEqRhs *Mag_SpinEqRhs; G4MagIntegratorStepper* pStepper; Mag_SpinEqRhs = new G4Mag_SpinEqRhs(sr1Field); pStepper = new G4ClassicalRK4(Mag_SpinEqRhs,12); G4cout<< "DeltaStep "<GetDeltaOneStep()/mm <<"mm" <SetChordFinder( pChordFinder ); pFieldMgr->SetDetectorField(sr1Field); } // void sr1DetectorConstruction::SetGaussianMagField(G4double fieldValue, G4double fieldSigma, G4double dummy) { void sr1DetectorConstruction::SetGaussianMagField(G4ThreeVector inputParam) { //------------ Field along z, which changes intensity as a (gaussian) function of R G4FieldManager *pFieldMgr; // G4double fieldRMS=100*mm; G4double fieldValue=inputParam.x()*tesla; G4double fieldSigma=inputParam.y()*mm; G4MagneticField* sr1Field= new sr1GaussianField(fieldValue,fieldSigma); pFieldMgr=G4TransportationManager::GetTransportationManager()->GetFieldManager(); G4Mag_SpinEqRhs *Mag_SpinEqRhs; G4MagIntegratorStepper* pStepper; Mag_SpinEqRhs = new G4Mag_SpinEqRhs(sr1Field); pStepper = new G4ClassicalRK4(Mag_SpinEqRhs,12); G4cout<< "DeltaStep "<GetDeltaOneStep()/mm <<"mm" <SetChordFinder( pChordFinder ); pFieldMgr->SetDetectorField(sr1Field); } void sr1DetectorConstruction::ReportGeometryProblem(char myString[501]) { G4cout<<"\nE R R O R in sr1DetectorConstruction.cc: " <<"Unknown keyword requested in \""<< parameterFileName <<"\" :"<FindOrBuildMaterial(materialName); //Material=G4Material::GetMaterial(materialName); //! } if (Material==NULL) { G4cout<<"\nE R R O R in sr1DetectorConstruction.cc::CharToMaterial " <<"Unknown material requested:"<entries(); i++) { for (unsigned int i=0; isize(); i++) { G4LogicalVolume* pLogVol=pLogStore->at(i); G4String iLogName=pLogVol->GetName(); if (iLogName==LogicalVolumeName) { return pLogVol; } } } return NULL; } void sr1DetectorConstruction::SetColourOfLogicalVolume(G4LogicalVolume* pLogVol,char* colour) { if (pLogVol!=NULL) { if (strcmp(colour,"red" )==0) {pLogVol->SetVisAttributes(G4Colour(1,0,0));} else if (strcmp(colour,"green" )==0) {pLogVol->SetVisAttributes(G4Colour(0,1,0));} else if (strcmp(colour,"blue" )==0) {pLogVol->SetVisAttributes(G4Colour(0,0,1));} else if (strcmp(colour,"white" )==0) {pLogVol->SetVisAttributes(G4Colour(1,1,1));} else if (strcmp(colour,"yellow" )==0) {pLogVol->SetVisAttributes(G4Colour(1,1,0));} else if (strcmp(colour,"black" )==0) {pLogVol->SetVisAttributes(G4Colour(0,0,0));} else if (strcmp(colour,"gray" )==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0.5,0.5));} else if (strcmp(colour,"cyan" )==0) {pLogVol->SetVisAttributes(G4Colour(0,1,1));} else if (strcmp(colour,"magenta")==0) {pLogVol->SetVisAttributes(G4Colour(1,0,1));} else if (strcmp(colour,"invisible" )==0) {pLogVol->SetVisAttributes(G4VisAttributes::Invisible);} else if (strcmp(colour,"blue_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.80,0.83,1));} else if (strcmp(colour,"lightblue")==0) {pLogVol->SetVisAttributes(G4Colour(0,0.5,1));} else if (strcmp(colour,"darkblue")==0) {pLogVol->SetVisAttributes(G4Colour(0,0.25,0.5));} else if (strcmp(colour,"fblue_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.85,.88,0.92));} else if (strcmp(colour,"oxsteel")==0) {pLogVol->SetVisAttributes(G4Colour(0.9,0.8,0.75));} else if (strcmp(colour,"darkred")==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0,0));} else if (strcmp(colour,"MCP_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0.2,.7));} else if (strcmp(colour,"MACOR_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.9,0.9,.1));} else if (strcmp(colour,"SCINT_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0.5,.75));} else if (strcmp(colour,"dSCINT_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.3,0.3,0.3));} else if (strcmp(colour,"VTBB_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.9,0.9,.9));} else if (strcmp(colour,"Grid_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.87,0.72,0.53));} //burlywood else if (strcmp(colour,"RA_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.8549,0.6471,0.1255));} //goldenrod else { G4cout<<"ERROR: sr1DetectorConstruction::SetColourOfLogicalVolume: unknown colour requested: "<