#include "StripTrackerConstruction.hh" #include "StripTrackerMessenger.hh" #include "G4Material.hh" #include "G4VSolid.hh" #include "G4Box.hh" #include "G4Tubs.hh" #include "G4Sphere.hh" #include "G4SubtractionSolid.hh" #include "G4UnionSolid.hh" #include "G4LogicalVolume.hh" #include "G4PVPlacement.hh" #include "G4PVReplica.hh" #include "G4GeometryTolerance.hh" #include "G4GeometryManager.hh" #include "G4NistManager.hh" #include "G4VisAttributes.hh" #include "G4Colour.hh" #include "StripSD.hh" #include "G4SDManager.hh" #include "G4UserLimits.hh" #include "G4SystemOfUnits.hh" #include #include "G4LogicalVolumeStore.hh" #include "G4Ellipsoid.hh" #include "MaterialDefinitions.hh" #include "G4PhysicalVolumeStore.hh" #include #include StripTrackerConstruction::StripTrackerConstruction() { //Create a messanger (defines custom UI commands) messenger = new StripTrackerMessenger(this); //--------- Material definition --------- DefineMaterials(); //--------- Sizes of the principal geometrical components (solids) --------- ComputeParameters(); /// ConstructStripTracker(); } StripTrackerConstruction::~StripTrackerConstruction() { delete messenger; } void StripTrackerConstruction::DefineMaterials() { // //Get Materials from NIST database // G4NistManager* man = G4NistManager::Instance(); // man->SetVerbose(0); // // // define NIST materials // air = man->FindOrBuildMaterial("G4_AIR"); // silicon = man->FindOrBuildMaterial("G4_Si"); // vacuum = man->FindOrBuildMaterial("G4_Galactic"); // perspex = man->FindOrBuildMaterial("G4_PLEXIGLASS"); // water = man->FindOrBuildMaterial("G4_WATER"); MaterialDefinitions* materialDefinition = new MaterialDefinitions(); materialDefinition->DefineMaterials(); air = materialDefinition->GetMaterial("Air"); silicon = materialDefinition->GetMaterial("Silicon"); vacuum = materialDefinition->GetMaterial("Vacuum"); perspex = materialDefinition->GetMaterial("Perspex"); water = materialDefinition->GetMaterial("Water"); al = materialDefinition->GetMaterial("Aluminum"); brass = materialDefinition->GetMaterial("Brass"); /* world_material = air; det_material = silicon; phantom_material = water; calorimeter_material = perspex;*/ } void StripTrackerConstruction::ComputeParameters() { //This function defines the defaults //of the geometry construction // ** general ** noOfSensorStrips = 1024; teleStripPitch = 90.8 * um; //teleStripPitch = 80.0 * um; //ALiBaVa sensorStripLength = 96.*mm; sensorThickness = 150.*um; noOfSensorPlanes = 16; //Used by RunAction to print out no. of detectors //in future make this adjustable in macro // default valus used to set the positions of the sensors inter_plane_dist = 12.*mm; inter_module_dist = 100.*mm; phantom_gap = 80.*mm; halfPhantomSizeZ = 35*mm; // calculate the sensor positions CalculateSensorPositions(); // Geometry taken from StripUnitArrangement_ImpactOnRecon.pdf document // and assumung minimum possible distance between planes as 10mm // ** Si beam telescope ** // 07/10/14 removed this as new way of defining implimented by JT // pos_x1_Sensor = G4ThreeVector(0., 0., 10.*mm); //Need to set in macro file using set and get // pos_u1_Sensor = G4ThreeVector(0., 0., 20.*mm); //functions already available // pos_v1_Sensor = G4ThreeVector(0., 0., 30.*mm); // // pos_x2_Sensor = G4ThreeVector(0., 0., 50.*mm); // pos_u2_Sensor = G4ThreeVector(0., 0., 60.*mm); // pos_v2_Sensor = G4ThreeVector(0., 0., 70.*mm); // // pos_TruthPlane_I = G4ThreeVector(0., 0., 75.*mm); // pos_TruthPlane_O = G4ThreeVector(0., 0., 285.*mm); // // pos_x3_Sensor = G4ThreeVector(0., 0., 290.*mm); // pos_u3_Sensor = G4ThreeVector(0., 0., 300.*mm); // pos_v3_Sensor = G4ThreeVector(0., 0., 310.*mm); // // pos_x4_Sensor = G4ThreeVector(0., 0., 330.*mm); // pos_u4_Sensor = G4ThreeVector(0., 0., 340.*mm); // pos_v4_Sensor = G4ThreeVector(0., 0., 350.*mm); // ** world ** halfWorldLengthXY = noOfSensorStrips*teleStripPitch; // // /// halfWorldLengthXY = sensorStripLength * 2; halfWorldLengthZ = (pos_v4_Sensor.z() - pos_x1_Sensor.z())*1.1; // TP changed 07/10/14 to match from JT update // halfWorldLengthXY = 0.5* m; // halfWorldLengthZ = 1.0* m; //Device under test (DUT) is_x1_PlaneDUT = true; //Flag turns Silcon planes into strip sensors, is_u1_PlaneDUT = true; //set to true by macro file, can be left false is_v1_PlaneDUT = true; //here. is_x2_PlaneDUT = true; //Flag turns Silcon planes into strip sensors, is_u2_PlaneDUT = true; //set to true by macro file, can be left false is_v2_PlaneDUT = true; //here. is_TP1_DUT = true; is_TP2_DUT = true; is_TP3_DUT = true; is_TP4_DUT = true; is_x3_PlaneDUT = true; //Flag turns Silcon planes into strip sensors, is_u3_PlaneDUT = true; //set to true by macro file, can be left false is_v3_PlaneDUT = true; //here. is_x4_PlaneDUT = true; //Flag turns Silcon planes into strip sensors, is_u4_PlaneDUT = true; //set to true by macro file, can be left false is_v4_PlaneDUT = true; //here. x1_SensorTheta = 0.*deg; //Set rotation of planes 60deg for PRaVDA det u1_SensorTheta = 0.*deg; //set by macro file, can be left as 0deg here. v1_SensorTheta = -0.*deg; x2_SensorTheta = 0.*deg; //Set rotation of planes 60deg for PRaVDA det u2_SensorTheta = 0.*deg; //set by macro file, can be left as 0deg here. v2_SensorTheta = -0.*deg; TP1_Theta = 0.*deg; TP2_Theta = 0.*deg; TP3_Theta = 0.*deg; TP4_Theta = 0.*deg; x3_SensorTheta = 0.*deg; //Set rotation of planes 60deg for PRaVDA det u3_SensorTheta = 0.*deg; //set by macro file, can be left as 0deg here. v3_SensorTheta = -0.*deg; x4_SensorTheta = 0.*deg; //Set rotation of planes 60deg for PRaVDA det u4_SensorTheta = 0.*deg; //set by macro file, can be left as 0deg here. v4_SensorTheta = -0.*deg; phantomTheta = 0.*deg; //Set rotation of phantom for CT mode, //set by macro file, can be left as 0deg here. } void StripTrackerConstruction::CalculateSensorPositions(G4ThreeVector zeroPoint)// = G4ThreeVector(0,0,0*mm)) { assert(inter_plane_dist>=12.0*mm); // strips are place relative to the phantom position // for now this is set to be 0,0,0 but will be changable //Incoming tracker pos_x1_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() - 0.5*phantom_gap - inter_plane_dist*4 - inter_module_dist); pos_u1_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() - 0.5*phantom_gap - inter_plane_dist*3 - inter_module_dist); pos_v1_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() - 0.5*phantom_gap - inter_plane_dist*2 - inter_module_dist); pos_x2_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() - 0.5*phantom_gap - inter_plane_dist*2); pos_u2_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() - 0.5*phantom_gap - inter_plane_dist); pos_v2_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() - 0.5*phantom_gap); //Incoming truth planes fixed at 1mm after last tracker plane from phantom and 1mm before phantom surface pos_TP1 = G4ThreeVector(0., 0., zeroPoint.getZ() - 0.5*phantom_gap + 1.0*mm); //1mm after v2 plane pos_TP2 = G4ThreeVector(0., 0., zeroPoint.getZ() - halfPhantomSizeZ - 1.0*mm); //1mm from phantom surface //Outgoing tracker pos_x3_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() + 0.5*phantom_gap); pos_u3_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() +0.5*phantom_gap + inter_plane_dist); pos_v3_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() + 0.5*phantom_gap + inter_plane_dist*2); //Outgoing truth planes fixed at 1mm from phantom surface and 1mm before next tracker plane after phantom pos_TP3 = G4ThreeVector(0., 0., zeroPoint.getZ() + halfPhantomSizeZ + 1.0*mm); //1mm from phantom surface pos_TP4 = G4ThreeVector(0., 0., zeroPoint.getZ() + 0.5*phantom_gap - 1.0*mm); //1mm before x3 plane pos_x4_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() + 0.5*phantom_gap + inter_plane_dist*2 + inter_module_dist); pos_u4_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() + 0.5*phantom_gap + inter_plane_dist*3 + inter_module_dist); pos_v4_Sensor = G4ThreeVector(0., 0., zeroPoint.getZ() + 0.5*phantom_gap + inter_plane_dist*4 + inter_module_dist); // print out the parameters which will be used G4cout << "\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" << "@@@@@@@@@@ Strip Tracker Positions @@@@@@@@@\n" << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n" << "Phantom Centre = " << zeroPoint/mm << " mm\n" << "Phantom Gap = " << phantom_gap/mm << " mm\n" << "Plane Separation = " << inter_plane_dist/mm << " mm\n" << "Module Separation = " << inter_module_dist/mm << " mm\n" << "pos_x1_Sensor = " << pos_x1_Sensor/mm << " mm\n" << "pos_u1_Sensor = " << pos_u1_Sensor/mm << " mm\n" << "pos_v1_Sensor = " << pos_v1_Sensor/mm << " mm\n" << "pos_x2_Sensor = " << pos_x2_Sensor/mm << " mm\n" << "pos_u2_Sensor = " << pos_u2_Sensor/mm << " mm\n" << "pos_v2_Sensor = " << pos_v2_Sensor/mm << " mm\n" << "pos_x3_Sensor = " << pos_x3_Sensor/mm << " mm\n" << "pos_u3_Sensor = " << pos_u3_Sensor/mm << " mm\n" << "pos_v3_Sensor = " << pos_v3_Sensor/mm << " mm\n" << "pos_x4_Sensor = " << pos_x4_Sensor/mm << " mm\n" << "pos_u4_Sensor = " << pos_u4_Sensor/mm << " mm\n" << "pos_v4_Sensor = " << pos_v4_Sensor/mm << " mm\n" << "pos_TP1 = " << pos_TP1/mm << " mm\n" << "pos_TP2 = " << pos_TP2/mm << " mm\n" << "pos_TP3 = " << pos_TP3/mm << " mm\n" << "pos_TP4 = " << pos_TP4/mm << " mm\n" << G4endl; } void StripTrackerConstruction::ConstructVolumes(G4LogicalVolume* lv) { //This function is called by G4 when the detector is to be created //Definitions of Solids, Logical Volumes, Physical Volumes G4Color green(0.0,1.0,0.0), blue(0.0,0.0,1.0), brown(0.4,0.4,0.1), white(1.0,1.0,1.0), red(1.0,0.0,0.0), yellow(1.0,1.0,0.0); //------------------------------ // World //------------------------------ //G4GeometryManager::GetInstance()->SetWorldMaximumExtent(2.*halfWorldLength); //G4cout << "Computed tolerance = " // << G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()/mm // << " mm" << G4endl; logicWorld= lv; logicWorld -> SetVisAttributes (G4VisAttributes::Invisible); // Must place the World Physical volume unrotated at (0,0,0). /// G4VPhysicalVolume * physiWorld = new G4PVPlacement(0, // no rotation /// G4ThreeVector(), // at (0,0,0) /// logicWorld, // its logical volume/ /// "StripTracker", // its name /// lWorld, // its mother volume /// false, // no boolean operations /// 0); // copy number //------------------------------ // Phantom //------------------------------ ////Box //G4double halfPhantomSizeXY = 5.0*cm; //G4double halfPhantomSizeZ = 5.0*cm; //G4Box * solidPhantom= new G4Box("phantom",halfPhantomSizeXY,halfPhantomSizeXY,halfPhantomSizeZ); // ////Cylinder // G4double innerRadius = 1.*cm; // //G4double innerRadius = 0.*cm; // G4double outerRadius = 4.5*cm; // G4double hz = 10.0*cm; // G4double startAngle = 0.*deg; // //G4double spanningAngle = 360.*deg; // G4double spanningAngle = 300.*deg; //pacman phantom // G4Tubs* solidPhantom = new G4Tubs("phantom",innerRadius,outerRadius,hz,startAngle,spanningAngle); // // // G4RotationMatrix * phantom_rm = new G4RotationMatrix; // phantom_rm->rotateZ(phantomTheta); // G4LogicalVolume * logicPhantom = new G4LogicalVolume( solidPhantom, /*perspex*/ water, "Phantom"); // physi_phantom = new G4PVPlacement(phantom_rm, // pos_phantom, // logicPhantom, // "Phantom_1", // logicWorld, // false, // 0); // G4VSolid* phantom = new G4Ellipsoid("phantom", 4.5*cm, 4.5*cm, 4.5*cm); // // // place the phantom with the dose voxel removed // G4LogicalVolume *tracker_phantom_log = new G4LogicalVolume(phantom, water, "tracker_phantom_log"); // physi_phantom = new G4PVPlacement(0,G4ThreeVector(0.0,0.0,15*cm),tracker_phantom_log,"phantom", logicWorld,false,0); //------------------------------ // Tracker //------------------------------ // searches for the phantom and sets the zero point to this // also extracts the outer radius of the spherical phantom to set the halfPhantomSizeZ G4VPhysicalVolume* phantom = G4PhysicalVolumeStore::GetInstance()->GetVolume("Phantom"); phantom_pos = G4ThreeVector(0,0,0); if(phantom) { phantom_pos = phantom->GetObjectTranslation(); G4LogicalVolume* phantom_log = phantom->GetLogicalVolume(); if(phantom_log) { // get the phantom and cast as a sphere so can extract the radius G4Sphere* phantom_solid = static_cast(phantom_log->GetSolid()); if(phantom_solid) { halfPhantomSizeZ = phantom_solid->GetOuterRadius(); } } } G4cout << "##### " << phantom_pos << G4endl; G4cout << "#####" << halfPhantomSizeZ << G4endl; // recalculate the sensor positions incase changed by messenger class CalculateSensorPositions(phantom_pos); // write the Parameters to the ROOT tree for TrackerGeometry WriteSensorPositions("TrackerGeometry"); //Define tracker parameters and planes G4double halfSensorSizeX = noOfSensorStrips*teleStripPitch/2.; G4double halfSensorSizeY = sensorStripLength/2.; G4double halfSensorSizeZ = sensorThickness/2.; G4Box * solidSensor = new G4Box("Sensor", halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4LogicalVolume * logicSensorPlane = new G4LogicalVolume(solidSensor, //its solid silicon, //its material "SensorPlane"); //its name //Define rotations for each sensor x=0deg,u=60deg,v=-60deg G4RotationMatrix * rm1 = new G4RotationMatrix; G4RotationMatrix * rm2 = new G4RotationMatrix; G4RotationMatrix * rm3 = new G4RotationMatrix; G4RotationMatrix * rm4 = new G4RotationMatrix; G4RotationMatrix * rm5 = new G4RotationMatrix; G4RotationMatrix * rm6 = new G4RotationMatrix; G4RotationMatrix * rm7 = new G4RotationMatrix; G4RotationMatrix * rm8 = new G4RotationMatrix; G4RotationMatrix * rm9 = new G4RotationMatrix; G4RotationMatrix * rm10 = new G4RotationMatrix; G4RotationMatrix * rm11 = new G4RotationMatrix; G4RotationMatrix * rm12 = new G4RotationMatrix; G4double halfSensorStripSizeX = teleStripPitch/2.; G4double halfSensorStripSizeY = sensorStripLength/2.; G4double halfSensorStripSizeZ = sensorThickness/2.; //Device under Test - replaces Plane of Si Beam Telescope G4Box * solid_x1_Sensor = new G4Box("x1_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_u1_Sensor = new G4Box("u1_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_v1_Sensor = new G4Box("v1_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_x2_Sensor = new G4Box("x2_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_u2_Sensor = new G4Box("u2_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_v2_Sensor = new G4Box("v2_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_TP1 = new G4Box("TP1",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_TP2 = new G4Box("TP2",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_TP3 = new G4Box("TP3",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_TP4 = new G4Box("TP4",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_x3_Sensor = new G4Box("x3_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_u3_Sensor = new G4Box("u3_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_v3_Sensor = new G4Box("v3_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_x4_Sensor = new G4Box("x4_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_u4_Sensor = new G4Box("u4_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4Box * solid_v4_Sensor = new G4Box("v4_Sensor",halfSensorSizeX,halfSensorSizeY,halfSensorSizeZ); G4LogicalVolume * logic_x1_SensorPlane = new G4LogicalVolume(solid_x1_Sensor, //its solid silicon, //its material "x1_SensorPlane"); //its name G4LogicalVolume * logic_u1_SensorPlane = new G4LogicalVolume(solid_u1_Sensor, //its solid silicon, //its material "u1_SensorPlane"); //its name G4LogicalVolume * logic_v1_SensorPlane = new G4LogicalVolume(solid_v1_Sensor, //its solid silicon, //its material "v1_SensorPlane"); //its name G4LogicalVolume * logic_x2_SensorPlane = new G4LogicalVolume(solid_x2_Sensor, //its solid silicon, //its material "x2_SensorPlane"); //its name G4LogicalVolume * logic_u2_SensorPlane = new G4LogicalVolume(solid_u2_Sensor, //its solid silicon, //its material "u2_SensorPlane"); //its name G4LogicalVolume * logic_v2_SensorPlane = new G4LogicalVolume(solid_v2_Sensor, //its solid silicon, //its material "v2_SensorPlane"); //its name G4LogicalVolume * logic_TP1 = new G4LogicalVolume(solid_TP1, //its solid air, //its material "_TP1"); //its name G4LogicalVolume * logic_TP2 = new G4LogicalVolume(solid_TP2, //its solid air, //its material "_TP2"); //its name G4LogicalVolume * logic_TP3 = new G4LogicalVolume(solid_TP3, //its solid air, //its material "_TP3"); //its name G4LogicalVolume * logic_TP4 = new G4LogicalVolume(solid_TP4, //its solid air, //its material "_TP4"); //its name G4LogicalVolume * logic_x3_SensorPlane = new G4LogicalVolume(solid_x3_Sensor, //its solid silicon, //its material "x3_SensorPlane"); //its name G4LogicalVolume * logic_u3_SensorPlane = new G4LogicalVolume(solid_u3_Sensor, //its solid silicon, //its material "u3_SensorPlane"); //its name G4LogicalVolume * logic_v3_SensorPlane = new G4LogicalVolume(solid_v3_Sensor, //its solid silicon, //its material "v3_SensorPlane"); //its name G4LogicalVolume * logic_x4_SensorPlane = new G4LogicalVolume(solid_x4_Sensor, //its solid silicon, //its material "x4_SensorPlane"); //its name G4LogicalVolume * logic_u4_SensorPlane = new G4LogicalVolume(solid_u4_Sensor, //its solid silicon, //its material "u4_SensorPlane"); //its name G4LogicalVolume * logic_v4_SensorPlane = new G4LogicalVolume(solid_v4_Sensor, //its solid silicon, //its material "v4_SensorPlane"); //its name //******************************* FIRST TRACKER MODULE ********************************// //1st Plane of Si Beam Telescope if ( is_x1_PlaneDUT ) { G4cout << "Building Device Under Test setup: x1 plane is replaced by DUT" << G4endl; rm1->rotateZ(x1_SensorTheta); physi_x1_Sensor = new G4PVPlacement(rm1, pos_x1_Sensor, logic_x1_SensorPlane, "DeviceUnderTest_x1", logicWorld, false, 0); //Build Strips G4Box * solid_x1_SensorStrip = new G4Box("x1_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_x1_SensorStrip = new G4LogicalVolume(solid_x1_SensorStrip,silicon,"x1_SensorStrip"); physi_x1_SensorStrip = new G4PVReplica("x1_SensorStrip", //its name logic_x1_SensorStrip, //its logical volume logic_x1_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_x1_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_x1_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm1->rotateZ(x1_SensorTheta); physi_x1_Sensor = new G4PVPlacement(rm1, //rotation pos_x1_Sensor, logicSensorPlane, //its logical volume "x1_Sensor", //its name logicWorld, //its mother volume false, //no boolean operation 0); //copy number } //2nd Plane of Si Beam Telescope if ( is_u1_PlaneDUT ) { G4cout << "Building Device Under Test setup: u1 plane is replaced by DUT" << G4endl; rm2->rotateZ(u1_SensorTheta); physi_u1_Sensor = new G4PVPlacement(rm2, pos_u1_Sensor, logic_u1_SensorPlane, "DeviceUnderTest_u1", logicWorld, false, 1); //Build Strips G4Box * solid_u1_SensorStrip = new G4Box("u1_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_u1_SensorStrip = new G4LogicalVolume(solid_u1_SensorStrip,silicon,"u1_SensorStrip"); physi_u1_SensorStrip = new G4PVReplica("u1_SensorStrip", //its name logic_u1_SensorStrip, //its logical volume logic_u1_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_u1_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_u1_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm2->rotateZ(u1_SensorTheta); physi_u1_Sensor = new G4PVPlacement(rm2, pos_u1_Sensor, logicSensorPlane, "u1_Sensor", logicWorld, false, 1); //copy number } //3rd Plane of Si Beam Telescope if ( is_v1_PlaneDUT ) { G4cout << "Building Device Under Test setup: v1 plane is replaced by DUT" << G4endl; rm3->rotateZ(v1_SensorTheta); physi_v1_Sensor = new G4PVPlacement(rm3, pos_v1_Sensor, logic_v1_SensorPlane, "DeviceUnderTest_v1", logicWorld, false, 2); //Build Strips G4Box * solid_v1_SensorStrip = new G4Box("v1_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_v1_SensorStrip = new G4LogicalVolume(solid_v1_SensorStrip,silicon,"v1_SensorStrip"); physi_v1_SensorStrip = new G4PVReplica("v1_SensorStrip", //its name logic_v1_SensorStrip, //its logical volume logic_v1_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_v1_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_v1_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm3->rotateZ(v1_SensorTheta); physi_v1_Sensor = new G4PVPlacement(rm3, pos_v1_Sensor, logicSensorPlane, "v1_Sensor", logicWorld, false, 2); //copy number } //******************************* SECOND TRACKER MODULE ********************************// //4th Plane of Si Beam Telescope if ( is_x2_PlaneDUT ) { G4cout << "Building Device Under Test setup: x2 plane is replaced by DUT" << G4endl; rm4->rotateZ(x2_SensorTheta); physi_x2_Sensor = new G4PVPlacement(rm4, pos_x2_Sensor, logic_x2_SensorPlane, "DeviceUnderTest_x2", logicWorld, false, 3); //Build Strips G4Box * solid_x2_SensorStrip = new G4Box("x2_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_x2_SensorStrip = new G4LogicalVolume(solid_x2_SensorStrip,silicon,"x2_SensorStrip"); physi_x2_SensorStrip = new G4PVReplica("x2_SensorStrip", //its name logic_x2_SensorStrip, //its logical volume logic_x2_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_x2_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_x2_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm4->rotateZ(x2_SensorTheta); physi_x2_Sensor = new G4PVPlacement(rm4, //rotation pos_x2_Sensor, logicSensorPlane, //its logical volume "x2_Sensor", //its name logicWorld, //its mother volume false, //no boolean operation 3); //copy number } //5th Plane of Si Beam Telescope if ( is_u2_PlaneDUT ) { G4cout << "Building Device Under Test setup: u2 plane is replaced by DUT" << G4endl; rm5->rotateZ(u2_SensorTheta); physi_u2_Sensor = new G4PVPlacement(rm5, pos_u2_Sensor, logic_u2_SensorPlane, "DeviceUnderTest_u2", logicWorld, false, 4); //Build Strips G4Box * solid_u2_SensorStrip = new G4Box("u2_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_u2_SensorStrip = new G4LogicalVolume(solid_u2_SensorStrip,silicon,"u2_SensorStrip"); physi_u2_SensorStrip = new G4PVReplica("u2_SensorStrip", //its name logic_u2_SensorStrip, //its logical volume logic_u2_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_u2_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_u2_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm5->rotateZ(u2_SensorTheta); physi_u2_Sensor = new G4PVPlacement(rm5, pos_u2_Sensor, logicSensorPlane, "u2_Sensor", logicWorld, false, 4); //copy number } //6th Plane of Si Beam Telescope if ( is_v2_PlaneDUT ) { G4cout << "Building Device Under Test setup: v2 plane is replaced by DUT" << G4endl; rm6->rotateZ(v2_SensorTheta); physi_v2_Sensor = new G4PVPlacement(rm6, pos_v2_Sensor, logic_v2_SensorPlane, "DeviceUnderTest_v2", logicWorld, false, 5); //Build Strips G4Box * solid_v2_SensorStrip = new G4Box("v2_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_v2_SensorStrip = new G4LogicalVolume(solid_v2_SensorStrip,silicon,"v2_SensorStrip"); physi_v2_SensorStrip = new G4PVReplica("v2_SensorStrip", //its name logic_v2_SensorStrip, //its logical volume logic_v2_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_v2_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_v2_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm6->rotateZ(v2_SensorTheta); physi_v2_Sensor = new G4PVPlacement(rm6, pos_v2_Sensor, logicSensorPlane, "v2_Sensor", logicWorld, false, 5); //copy number } //******************************* Truth Plane 1 ********************************// //Plane used to obtain truth information not affected by MCS if ( is_TP1_DUT ) { G4cout << "Building Device Under Test setup: TP1 is replaced by DUT" << G4endl; if ( is_TP1_DUT ) { //rm1->rotateY(TP1_Theta); //rm1->rotateX(TP1_Theta); rm1->rotateZ(TP1_Theta); physi_TP1 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP1, logic_TP1, "DeviceUnderTest_TP1", logicWorld, false, 6); //Build Strips G4Box * solid_TP1_Strip = new G4Box("TP1_Strip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_TP1_Strip = new G4LogicalVolume(solid_TP1_Strip,air,"TP1_SensorStrip"); physi_TP1_Strip = new G4PVReplica("TP1_SensorStrip", //its name logic_TP1_Strip, //its logical volume logic_TP1, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_TP1 -> SetVisAttributes(new G4VisAttributes(white)); logic_TP1_Strip -> SetVisAttributes(new G4VisAttributes(white)); } } else //Construct as plane of silicon without strips { //rm1->rotateY(TP1_Theta); //rm1->rotateX(TP1_Theta); rm1->rotateZ(TP1_Theta); physi_TP1 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP1, logic_TP1, //its logical volume "TP1", //its name logicWorld, //its mother volume false, //no boolean operation 6); //copy number } //******************************* Truth Plane 2 ********************************// //Plane used to obtain truth information not affected by MCS if ( is_TP2_DUT ) { G4cout << "Building Device Under Test setup: TP2 is replaced by DUT" << G4endl; if ( is_TP2_DUT ) { //rm1->rotateY(TP2_Theta); //rm1->rotateX(TP2_Theta); rm1->rotateZ(TP2_Theta); physi_TP2 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP2, logic_TP2, "DeviceUnderTest_TP2", logicWorld, false, 7); //Build Strips G4Box * solid_TP2_Strip = new G4Box("TP2_Strip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_TP2_Strip = new G4LogicalVolume(solid_TP2_Strip,air,"TP2_SensorStrip"); physi_TP2_Strip = new G4PVReplica("TP2_SensorStrip", //its name logic_TP2_Strip, //its logical volume logic_TP2, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_TP2 -> SetVisAttributes(new G4VisAttributes(white)); logic_TP2_Strip -> SetVisAttributes(new G4VisAttributes(white)); } } else //Construct as plane of silicon without strips { //rm1->rotateY(TP2_Theta); //rm1->rotateX(TP2_Theta); rm1->rotateZ(TP2_Theta); physi_TP2 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP2, logic_TP2, //its logical volume "TP2", //its name logicWorld, //its mother volume false, //no boolean operation 7); //copy number } //******************************* Truth Plane 3 ********************************// //Plane used to obtain truth information not affected by MCS if ( is_TP3_DUT ) { G4cout << "Building Device Under Test setup: TP3 is replaced by DUT" << G4endl; if ( is_TP3_DUT ) { //rm1->rotateY(TP3_Theta); //rm1->rotateX(TP3_Theta); rm1->rotateZ(TP3_Theta); physi_TP3 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP3, logic_TP3, "DeviceUnderTest_TP3", logicWorld, false, 8); //Build Strips G4Box * solid_TP3_Strip = new G4Box("TP3_Strip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_TP3_Strip = new G4LogicalVolume(solid_TP3_Strip,air,"TP3_SensorStrip"); physi_TP3_Strip = new G4PVReplica("TP3_SensorStrip", //its name logic_TP3_Strip, //its logical volume logic_TP3, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_TP3 -> SetVisAttributes(new G4VisAttributes(white)); logic_TP3_Strip -> SetVisAttributes(new G4VisAttributes(white)); } } else //Construct as plane of silicon without strips { //rm1->rotateY(TP3_Theta); //rm1->rotateX(TP3_Theta); rm1->rotateZ(TP3_Theta); physi_TP3 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP3, logic_TP3, //its logical volume "TP3", //its name logicWorld, //its mother volume false, //no boolean operation 8); //copy number } //******************************* Truth Plane 4 ********************************// //Plane used to obtain truth information not affected by MCS if ( is_TP4_DUT ) { G4cout << "Building Device Under Test setup: TP4 is replaced by DUT" << G4endl; if ( is_TP4_DUT ) { //rm1->rotateY(TP4_Theta); //rm1->rotateX(TP4_Theta); rm1->rotateZ(TP4_Theta); physi_TP4 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP4, logic_TP4, "DeviceUnderTest_TP4", logicWorld, false, 9); //Build Strips G4Box * solid_TP4_Strip = new G4Box("TP4_Strip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_TP4_Strip = new G4LogicalVolume(solid_TP4_Strip,air,"TP4_SensorStrip"); physi_TP4_Strip = new G4PVReplica("TP4_SensorStrip", //its name logic_TP4_Strip, //its logical volume logic_TP4, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_TP4 -> SetVisAttributes(new G4VisAttributes(white)); logic_TP4_Strip -> SetVisAttributes(new G4VisAttributes(white)); } } else //Construct as plane of silicon without strips { //rm1->rotateY(TP4_Theta); //rm1->rotateX(TP4_Theta); rm1->rotateZ(TP4_Theta); physi_TP4 = new G4PVPlacement(rm1, //rotation (keep same as x planes theta = 0) pos_TP4, logic_TP4, //its logical volume "TP4", //its name logicWorld, //its mother volume false, //no boolean operation 9); //copy number } //******************************* THIRD TRACKER MODULE ********************************// //7th Plane of Si Beam Telescope if ( is_x3_PlaneDUT ) { G4cout << "Building Device Under Test setup: x3 plane is replaced by DUT" << G4endl; rm7->rotateZ(x3_SensorTheta); physi_x3_Sensor = new G4PVPlacement(rm7, pos_x3_Sensor, logic_x3_SensorPlane, "DeviceUnderTest_x3", logicWorld, false, 10); //Build Strips G4Box * solid_x3_SensorStrip = new G4Box("x3_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_x3_SensorStrip = new G4LogicalVolume(solid_x3_SensorStrip,silicon,"x3_SensorStrip"); physi_x3_SensorStrip = new G4PVReplica("x3_SensorStrip", //its name logic_x3_SensorStrip, //its logical volume logic_x3_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_x3_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_x3_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm7->rotateZ(x3_SensorTheta); physi_x3_Sensor = new G4PVPlacement(rm7, //rotation pos_x3_Sensor, logicSensorPlane, //its logical volume "x3_Sensor", //its name logicWorld, //its mother volume false, //no boolean operation 10); //copy number } //8th Plane of Si Beam Telescope if ( is_u3_PlaneDUT ) { G4cout << "Building Device Under Test setup: u3 plane is replaced by DUT" << G4endl; rm8->rotateZ(u3_SensorTheta); physi_u3_Sensor = new G4PVPlacement(rm8, pos_u3_Sensor, logic_u3_SensorPlane, "DeviceUnderTest_u3", logicWorld, false, 11); //Build Strips G4Box * solid_u3_SensorStrip = new G4Box("u3_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_u3_SensorStrip = new G4LogicalVolume(solid_u3_SensorStrip,silicon,"u3_SensorStrip"); physi_u3_SensorStrip = new G4PVReplica("u3_SensorStrip", //its name logic_u3_SensorStrip, //its logical volume logic_u3_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_u3_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_u3_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm8->rotateZ(u3_SensorTheta); physi_u3_Sensor = new G4PVPlacement(rm8, pos_u3_Sensor, logicSensorPlane, "u3_Sensor", logicWorld, false, 11); //copy number } //9th Plane of Si Beam Telescope if ( is_v3_PlaneDUT ) { G4cout << "Building Device Under Test setup: v3 plane is replaced by DUT" << G4endl; rm9->rotateZ(v3_SensorTheta); physi_v3_Sensor = new G4PVPlacement(rm9, pos_v3_Sensor, logic_v3_SensorPlane, "DeviceUnderTest_v3", logicWorld, false, 12); //Build Strips G4Box * solid_v3_SensorStrip = new G4Box("v3_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_v3_SensorStrip = new G4LogicalVolume(solid_v3_SensorStrip,silicon,"v3_SensorStrip"); physi_v3_SensorStrip = new G4PVReplica("v3_SensorStrip", //its name logic_v3_SensorStrip, //its logical volume logic_v3_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_v3_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_v3_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm9->rotateZ(v3_SensorTheta); physi_v3_Sensor = new G4PVPlacement(rm9, pos_v3_Sensor, logicSensorPlane, "v3_Sensor", logicWorld, false, 12); //copy number } //******************************* FOURTH TRACKER MODULE ********************************// //10th Plane of Si Beam Telescope if ( is_x4_PlaneDUT ) { G4cout << "Building Device Under Test setup: x4 plane is replaced by DUT" << G4endl; rm10->rotateZ(x4_SensorTheta); physi_x4_Sensor = new G4PVPlacement(rm10, pos_x4_Sensor, logic_x4_SensorPlane, "DeviceUnderTest_x4", logicWorld, false, 13); //Build Strips G4Box * solid_x4_SensorStrip = new G4Box("x4_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_x4_SensorStrip = new G4LogicalVolume(solid_x4_SensorStrip,silicon,"x4_SensorStrip"); physi_x4_SensorStrip = new G4PVReplica("x4_SensorStrip", //its name logic_x4_SensorStrip, //its logical volume logic_x4_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_x4_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_x4_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm10->rotateZ(x4_SensorTheta); physi_x4_Sensor = new G4PVPlacement(rm10, //rotation pos_x4_Sensor, logicSensorPlane, //its logical volume "x4_Sensor", //its name logicWorld, //its mother volume false, //no boolean operation 13); //copy number } //11th Plane of Si Beam Telescope if ( is_u4_PlaneDUT ) { G4cout << "Building Device Under Test setup: u4 plane is replaced by DUT" << G4endl; rm11->rotateZ(u4_SensorTheta); physi_u4_Sensor = new G4PVPlacement(rm11, pos_u4_Sensor, logic_u4_SensorPlane, "DeviceUnderTest_u4", logicWorld, false, 14); //Build Strips G4Box * solid_u4_SensorStrip = new G4Box("u4_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_u4_SensorStrip = new G4LogicalVolume(solid_u4_SensorStrip,silicon,"u4_SensorStrip"); physi_u4_SensorStrip = new G4PVReplica("u4_SensorStrip", //its name logic_u4_SensorStrip, //its logical volume logic_u4_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_u4_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_u4_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { rm11->rotateZ(u4_SensorTheta); physi_u4_Sensor = new G4PVPlacement(rm11, pos_u4_Sensor, logicSensorPlane, "u4_Sensor", logicWorld, false, 14); //copy number } //12th Plane of Si Beam Telescope if ( is_v4_PlaneDUT ) { G4cout << "Building Device Under Test setup: v4 plane is replaced by DUT" << G4endl; rm12->rotateZ(v4_SensorTheta); physi_v4_Sensor = new G4PVPlacement(rm12, pos_v4_Sensor, logic_v4_SensorPlane, "DeviceUnderTest_v4", logicWorld, false, 15); //Build Strips G4Box * solid_v4_SensorStrip = new G4Box("v4_SensorStrip", halfSensorStripSizeX,halfSensorStripSizeY,halfSensorStripSizeZ); G4LogicalVolume * logic_v4_SensorStrip = new G4LogicalVolume(solid_v4_SensorStrip,silicon,"v4_SensorStrip"); physi_v4_SensorStrip = new G4PVReplica("v4_SensorStrip", //its name logic_v4_SensorStrip, //its logical volume logic_v4_SensorPlane, //its mother kXAxis, //axis of replication noOfSensorStrips, //number of replica teleStripPitch); //width of replica logic_v4_SensorPlane -> SetVisAttributes(new G4VisAttributes(yellow)); logic_v4_SensorStrip -> SetVisAttributes(new G4VisAttributes(red)); } else //Construct as plane of silicon without strips { //rm12->rotateY(v4_SensorTheta); //rm12->rotateX(v4_SensorTheta); rm12->rotateZ(v4_SensorTheta); physi_v4_Sensor = new G4PVPlacement(rm12, pos_v4_Sensor, logicSensorPlane, "v4_Sensor", logicWorld, false, 15); //copy number } //--------- Visualization attributes ------------------------------- logicWorld->SetVisAttributes(new G4VisAttributes(white)); logicWorld->SetVisAttributes(G4VisAttributes::Invisible); ///G4VisAttributes * PhantomVisAtt = new G4VisAttributes(green); ///PhantomVisAtt->SetForceWireframe(true); // Set the forced wireframe style ///logicPhantom->SetVisAttributes(PhantomVisAtt); //G4double minStep = 0.2*um; //Smaller steps results in better energy loss values (lower fluctuation) //G4double minTrack = 0.2*um; //G4UserLimits* stepLimitMin = new G4UserLimits(minStep); /*G4UserLimits(G4double uStepMax = DBL_MAX, G4double uTrakMax = DBL_MAX, G4double uTimeMax = DBL_MAX, G4double uEkinMin = 0.,G4double uRangMin = 0. );*/ G4double uStepMin = 0.2*um; G4double uTrakMin = 0.2*um; G4UserLimits* stepLimitMin = new G4UserLimits(uStepMin,uTrakMin); logic_x1_SensorPlane->SetUserLimits(stepLimitMin); logic_u1_SensorPlane->SetUserLimits(stepLimitMin); logic_v1_SensorPlane->SetUserLimits(stepLimitMin); logic_x2_SensorPlane->SetUserLimits(stepLimitMin); logic_u2_SensorPlane->SetUserLimits(stepLimitMin); logic_v2_SensorPlane->SetUserLimits(stepLimitMin); ///logic_TruthPlane_I->SetUserLimits(stepLimitMin); ///logic_TruthPlane_O->SetUserLimits(stepLimitMin); logic_TP1->SetUserLimits(stepLimitMin); logic_TP2->SetUserLimits(stepLimitMin); logic_TP3->SetUserLimits(stepLimitMin); logic_TP4->SetUserLimits(stepLimitMin); logic_x3_SensorPlane->SetUserLimits(stepLimitMin); logic_u3_SensorPlane->SetUserLimits(stepLimitMin); logic_v3_SensorPlane->SetUserLimits(stepLimitMin); logic_x4_SensorPlane->SetUserLimits(stepLimitMin); logic_u4_SensorPlane->SetUserLimits(stepLimitMin); logic_v4_SensorPlane->SetUserLimits(stepLimitMin); stiff = 0; ConstructStiffener("Stiffener_x1",rm1,pos_x1_Sensor,0); ConstructStiffener("Stiffener_u1",rm2,pos_u1_Sensor,1); ConstructStiffener("Stiffener_v1",rm3,pos_v1_Sensor,2); ConstructStiffener("Stiffener_x2",rm4,pos_x2_Sensor,3); ConstructStiffener("Stiffener_u2",rm5,pos_u2_Sensor,4); ConstructStiffener("Stiffener_v2",rm6,pos_v2_Sensor,5); ConstructStiffener("Stiffener_x3",rm7,pos_x3_Sensor,10); ConstructStiffener("Stiffener_u3",rm8,pos_u3_Sensor,11); ConstructStiffener("Stiffener_v3",rm9,pos_v3_Sensor,12); ConstructStiffener("Stiffener_x4",rm10,pos_x4_Sensor,13); ConstructStiffener("Stiffener_u3",rm11,pos_u4_Sensor,14); ConstructStiffener("Stiffener_v4",rm12,pos_v4_Sensor,15); ConstructCase("StripModule1",pos_u1_Sensor); ConstructCase("StripModule2",pos_u2_Sensor); ConstructCase("StripModule3",pos_u3_Sensor); ConstructCase("StripModule4",pos_u4_Sensor); // shield frame before u3_sensor // the back part of the box G4double ShieldZ = 10.0*mm; G4double ShieldX = 12.0*cm; G4double ShieldY = 12.0*cm; G4Box* shield_back = new G4Box("shield_back",ShieldX/2.0,ShieldY/2.0,ShieldZ/2.0); // the front part of the box ShieldZ= 5.0*mm; ShieldX=100.0*mm; ShieldY=100.0*mm; G4Box* shield_front = new G4Box("shield_front", ShieldX/2.0, ShieldY/2.0, ShieldZ/2.0); G4UnionSolid* shield = new G4UnionSolid("shield", shield_back, shield_front, 0, G4ThreeVector(0.0*mm, 0.0*mm, 7.5*mm)); G4Tubs* shield_hole = new G4Tubs("shield_box", 0*mm, 95.0*mm/2.0, 20.0*mm/1.99, 0, 360*deg); G4SubtractionSolid* frame = new G4SubtractionSolid("ShieldFrame",shield,shield_hole); G4VisAttributes* frameVis = new G4VisAttributes(); frameVis->SetColour(181.0/255.0,166.0/255.0,66.0/255.0); G4LogicalVolume* frameLV1 = new G4LogicalVolume(frame, brass,"StripModule1Frame"); frameLV1->SetVisAttributes(frameVis); G4ThreeVector pos_frame = pos_u1_Sensor; pos_frame.setZ(pos_frame.getZ()-28*mm-5.0*mm); new G4PVPlacement(0,pos_frame,frameLV1,"StripModule1Frame",logicWorld,false,0); G4LogicalVolume* frameLV3 = new G4LogicalVolume(frame, brass,"StripModule3Frame"); frameLV3->SetVisAttributes(frameVis); pos_frame = pos_u3_Sensor; pos_frame.setZ(pos_frame.getZ()-28*mm-5.0*mm); new G4PVPlacement(0,pos_frame,frameLV3,"StripModule3Frame",logicWorld,false,0); // The perspex around the phantom // outer box G4Box* perspex_box = new G4Box("perspex_box", 120.0*mm/2.0, 120.0*mm/2.0, 65.0*mm/2.0); G4Box* perspex_hole = new G4Box("perspex_hole", 100.0*mm/2.0, 100.0*mm/2.0, 65.0*mm/1.99); G4SubtractionSolid* phantom_box = new G4SubtractionSolid("phantom_box", perspex_box, perspex_hole); G4LogicalVolume* phantom_boxLV = new G4LogicalVolume(phantom_box, perspex, "PhantomBox"); new G4PVPlacement(0, G4ThreeVector(0,0,pos_frame.getZ()-30.0*mm-7.5*mm), phantom_boxLV, "PhantomBox", logicWorld,false,0); //logicPhantom->SetUserLimits(stepLimitMax); //always return the physical World /// return physiWorld; } #include "G4VPhysicalVolume.hh" #include "G4UnionSolid.hh" void StripTrackerConstruction::ConstructStiffener(G4String PVname, G4RotationMatrix* rm, G4ThreeVector pos, G4int CopyNum) { G4cout << "Constructing " << PVname << G4endl; // adjust the position to front of stiffener pos = G4ThreeVector(pos.getX(), pos.getY(), pos.getZ()+6.0*mm-150*um); // create a world volume the shape of the stiffener but without inserts removed // need to remove the sensor whole so can read these out G4Tubs* sf = new G4Tubs("sf",0.0*mm, 250*mm, 12.0*mm/2.0, 0.0*deg,360*deg); //G4Box* b = new G4Box("b",50*mm,143*mm,12.0*mm/1.99); G4SubtractionSolid* world = 0; //world = new G4SubtractionSolid("world",sf,b,0,G4ThreeVector(255*mm,0*mm,0*mm)); //world = new G4SubtractionSolid("world",world,b,0,G4ThreeVector(-255*mm,0*mm,0*mm)); G4Box* h = new G4Box("h",49.0*mm,49.0*mm,12.0*mm/1.99); world = new G4SubtractionSolid("world",sf,h,0,G4ThreeVector(0*mm,0*mm,0*mm)); G4LogicalVolume* worldLV = new G4LogicalVolume(world,air,PVname+"World"); worldLV->SetVisAttributes(G4VisAttributes::GetInvisible()); new G4PVPlacement(rm, pos, worldLV, PVname+"World",logicWorld, false, CopyNum); if(stiff==0) { G4Tubs* sf = new G4Tubs("sf",0.0*mm, 250*mm, 12.0*mm/2.0, 0.0*deg,360*deg); G4Box* b = new G4Box("b",49.0*mm,49.0*mm,12.0*mm/1.99); stiff = new G4SubtractionSolid("stiff",sf,b); /* Uncomment if want the little holes in place G4Tubs* h = new G4Tubs("h",0.0*mm, 3.0*mm, 12.0*mm/1.99,0.0*deg,360*deg); stiff = new G4SubtractionSolid("stiff",stiff,h,0,G4ThreeVector(0*mm,85.0*mm,0*mm)); stiff = new G4SubtractionSolid("stiff",stiff,h,0,G4ThreeVector(0*mm,-85.0*mm,0*mm)); stiff = new G4SubtractionSolid("stiff",stiff,h,0,G4ThreeVector(147.2*mm/2.0,85.0*mm/2.0,0*mm)); stiff = new G4SubtractionSolid("stiff",stiff,h,0,G4ThreeVector(147.2*mm/2.0,-85.0*mm/2.0,0*mm)); stiff = new G4SubtractionSolid("stiff",stiff,h,0,G4ThreeVector(-147.2*mm/2.0,85.0*mm/2.0,0*mm)); stiff = new G4SubtractionSolid("stiff",stiff,h,0,G4ThreeVector(-147.2*mm/2.0,-85.0*mm/2.0,0*mm)); */ b = new G4Box("b",45.0*mm,40.5*mm,12.0*mm/1.99); stiff = new G4SubtractionSolid("stiff",stiff,b,0,G4ThreeVector(140*mm,0*mm,0*mm)); b = new G4Box("b",50*mm,143*mm,12.0*mm/1.99); stiff = new G4SubtractionSolid("stiff",stiff,b,0,G4ThreeVector(255*mm,0*mm,0*mm)); stiff = new G4SubtractionSolid("stiff",stiff,b,0,G4ThreeVector(-255*mm,0*mm,0*mm)); G4Box* r = new G4Box("r",120*mm,191*mm,5.6*mm); stiff = new G4SubtractionSolid("stiff",stiff,r,0,G4ThreeVector(42*mm,0.0,-4.2*mm)); } G4LogicalVolume* stiffLV = new G4LogicalVolume(stiff,al,PVname); new G4PVPlacement(0, G4ThreeVector(0,0,0),//pos, stiffLV, PVname, worldLV,//logicWorld, false, CopyNum); G4SubtractionSolid* PCB = 0; if(PCB==0) { G4Box* pcb = new G4Box("pcb",119*mm,190*mm,0.8*mm); G4Box* b = new G4Box("b",49.0*mm,49.0*mm,0.81*mm); PCB = new G4SubtractionSolid("PCB",pcb,b,0, G4ThreeVector(-42.0*mm,0.0*mm,0.0*mm)); } G4LogicalVolume* PCBLV = new G4LogicalVolume(PCB,al,"PCB"); G4VisAttributes* PCB_VisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0)); //green PCBLV-> SetVisAttributes(PCB_VisAtt); G4ThreeVector pos_pcb = G4ThreeVector(+42.0*mm,0,-1.0*mm-0.8*mm); G4double rot_angle = rm->thetaZ(); G4cout << "###" << rot_angle << G4endl; new G4PVPlacement(0, pos_pcb, PCBLV, "PCB", worldLV, false, CopyNum); G4UnionSolid* ASICs = 0; G4double ASIC_X = 5.204*mm; G4double ASIC_Y = 8.204*mm; G4double ASIC_Z = 0.76*mm; G4double ASIC_Sep = 3.43*mm; if(ASICs==0) { G4Box* asic = new G4Box("asic", ASIC_X/2,ASIC_Y/2,ASIC_Z/2); G4UnionSolid* asics = new G4UnionSolid("asics",asic,asic,0, G4ThreeVector(98*mm+ASIC_X+6.6*mm,0,0)); ASICs = new G4UnionSolid("ASICs", asics, asics, 0, G4ThreeVector(0,ASIC_Sep+ASIC_Y,0)); ASICs = new G4UnionSolid("ASICs", ASICs, ASICs, 0, G4ThreeVector(0,(ASIC_Sep+ASIC_Y)*2,0)); ASICs = new G4UnionSolid("ASICs", ASICs, ASICs, 0, G4ThreeVector(0,(ASIC_Sep+ASIC_Y)*4,0)); //ASICs = new G4UnionSolid("ASICs", ASICs, ASICs, 0, G4ThreeVector(100*mm+ASIC_X,50*mm-ASIC_Y,0)); } G4LogicalVolume* ASICsLV = new G4LogicalVolume(ASICs, air, "ASICs"); new G4PVPlacement(0,G4ThreeVector(-49*mm-ASIC_X/2-3.3*mm,-49*mm+ASIC_Y,-3.0*mm), ASICsLV, "ASICs", worldLV, false, CopyNum); } void StripTrackerConstruction::ConstructCase(G4String PVname, G4ThreeVector pos) { G4Box* outer = new G4Box("outerbox", 570.0*mm/2.0, 510.0*mm/2.0, 28*mm); G4Box* inner = new G4Box("innerbox", (570.0*mm/2.0)-5.0*mm, (510.0*mm/2.0)-5.0*mm, 28*mm-5.0*mm); G4SubtractionSolid* Case = new G4SubtractionSolid("Case", outer,inner); G4Box* holes = new G4Box("holes",50*mm,50*mm,29*mm); Case = new G4SubtractionSolid("Case",Case,holes); G4LogicalVolume* CaseLV = new G4LogicalVolume(Case,al,PVname); new G4PVPlacement(0,pos,CaseLV,PVname,logicWorld,false,0); } void StripTrackerConstruction::WriteSensorPositions(std::string tree_name) { std::string n_strips = "/det/n_strips"; std::string strip_pitch = "/det/strip_pitch"; std::string strip_length = "/det/strip_length"; std::string hPhantomSizeZ = "/geom/halfPhantomSizeZ"; std::string hCalorimeterSizeZ = "/geom/halfCalorimeterSizeZ"; std::string plane_d = "/geom/plane_dist"; std::string module_d = "/geom/module_dist"; std::string phantom_g = "/geom/phantom_gap"; std::string phantom_z = "/geom/phantom_z"; std::string x1_stereo = "/det/x1_Sensor/theta"; std::string u1_stereo = "/det/u1_Sensor/theta"; std::string v1_stereo = "/det/v1_Sensor/theta"; std::string x2_stereo = "/det/x2_Sensor/theta"; std::string u2_stereo = "/det/u2_Sensor/theta"; std::string v2_stereo = "/det/v2_Sensor/theta"; std::string x3_stereo = "/det/x3_Sensor/theta"; std::string u3_stereo = "/det/u3_Sensor/theta"; std::string v3_stereo = "/det/v3_Sensor/theta"; std::string x4_stereo = "/det/x4_Sensor/theta"; std::string u4_stereo = "/det/u4_Sensor/theta"; std::string v4_stereo = "/det/v4_Sensor/theta"; std::ofstream geom; geom.open((tree_name+".mac").c_str()); geom << n_strips << " " << noOfSensorStrips << "\n" << strip_pitch << " " << teleStripPitch/mm << " mm\n" << strip_length << " " << sensorStripLength/mm << " mm\n" << hPhantomSizeZ << " " << halfPhantomSizeZ/mm << " mm\n" << hCalorimeterSizeZ << " " << 125*mm << " mm\n" << plane_d << " " << inter_plane_dist/mm << " mm\n" << module_d << " " << inter_module_dist/mm << " mm\n" << phantom_g << " " << phantom_gap/mm << " mm\n" << phantom_z << " " << phantom_pos.z()/mm << " mm\n" << x1_stereo << " " << x1_SensorTheta/deg<< " deg\n" << u1_stereo << " " << u1_SensorTheta/deg<< " deg\n" << v1_stereo << " " << v1_SensorTheta/deg<< " deg\n" << x2_stereo << " " << x2_SensorTheta/deg<< " deg\n" << u2_stereo << " " << u2_SensorTheta/deg<< " deg\n" << v2_stereo << " " << v2_SensorTheta/deg<< " deg\n" << x3_stereo << " " << x3_SensorTheta/deg<< " deg\n" << u3_stereo << " " << u3_SensorTheta/deg<< " deg\n" << v3_stereo << " " << v3_SensorTheta/deg<< " deg\n" << x4_stereo << " " << x4_SensorTheta/deg<< " deg\n" << u4_stereo << " " << u4_SensorTheta/deg<< " deg\n" << v4_stereo << " " << v4_SensorTheta/deg<< " deg\n" << std::endl; geom.close(); } void StripTrackerConstruction::ConstructSDandField() { std::cout << "StripTrackerConstruction::ConstructSDandField()" << std::endl; //***********************************************************************************// // ---------------------------------------------------------- // -- Binding SensitiveDetector code to sensor strip volume: // -- Note that it is possible to set the sensitive detector // -- at construction of the G4LogicalVolume (fith argument // -- is a G4VSensitiveDetector*). // ---------------------------------------------------------- //Every time the /det/update command is executed this //method is called since geometry is recomputed. //However we do not need to create a new SD, but reuse the //already existing one static StripSD* sensitive_det_x1 = 0; static StripSD* sensitive_det_u1 = 0; static StripSD* sensitive_det_v1 = 0; static StripSD* sensitive_det_x2 = 0; static StripSD* sensitive_det_u2 = 0; static StripSD* sensitive_det_v2 = 0; static StripSD* sensitive_det_TP1 = 0; static StripSD* sensitive_det_TP2 = 0; static StripSD* sensitive_det_TP3 = 0; static StripSD* sensitive_det_TP4 = 0; static StripSD* sensitive_det_x3 = 0; static StripSD* sensitive_det_u3 = 0; static StripSD* sensitive_det_v3 = 0; static StripSD* sensitive_det_x4 = 0; static StripSD* sensitive_det_u4 = 0; static StripSD* sensitive_det_v4 = 0; G4SDManager* SDman = G4SDManager::GetSDMpointer(); sensitive_det_x1 = new StripSD("SiStrip_x1"); SDman->AddNewDetector(sensitive_det_x1); //if ( !sensitive_det_u1) // { sensitive_det_u1 = new StripSD("SiStrip_u1"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_u1); // } // if ( !sensitive_det_v1) { sensitive_det_v1 = new StripSD("SiStrip_v1"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_v1); } //if ( !sensitive_det_x2) { sensitive_det_x2 = new StripSD("SiStrip_x2"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_x2); } //if ( !sensitive_det_u2) { sensitive_det_u2 = new StripSD("SiStrip_u2"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_u2); } // if ( !sensitive_det_v2) { sensitive_det_v2 = new StripSD("SiStrip_v2"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_v2); } // if ( !sensitive_det_TP1) { sensitive_det_TP1 = new StripSD("AirStrip_TP1"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_TP1); } // if ( !sensitive_det_TP2) { sensitive_det_TP2 = new StripSD("AirStrip_TP2"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_TP2); } // if ( !sensitive_det_TP3) { sensitive_det_TP3 = new StripSD("AirStrip_TP3"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_TP3); } // if ( !sensitive_det_TP4) { sensitive_det_TP4 = new StripSD("AirStrip_TP4"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_TP4); } // if ( !sensitive_det_x3) { sensitive_det_x3 = new StripSD("SiStrip_x3"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_x3); } //if ( !sensitive_det_u3) { sensitive_det_u3 = new StripSD("SiStrip_u3"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_u3); } // if ( !sensitive_det_v3) { sensitive_det_v3 = new StripSD("SiStrip_v3"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_v3); } // if ( !sensitive_det_x4) { sensitive_det_x4 = new StripSD("SiStrip_x4"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_x4); } //if ( !sensitive_det_u4) { sensitive_det_u4 = new StripSD("SiStrip_u4"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_u4); } // if ( !sensitive_det_v4) { sensitive_det_v4 = new StripSD("SiStrip_v4"); //We register now the SD with the manager SDman->AddNewDetector(sensitive_det_v4); } //This part here is used to associated the sensitive detector to the //logical volume of a plane in case it is a DUT. //With DUT we need to attach to the logical volume of the strips the //sensitive detector, since we only have a pointer to the physical volume //of the plane we need to... // 1- First get the logical volume associated to a plane // 2- Get the first daughter associated to it: the strip // since strip is a replicated volume (G4PVReplica) there is // a single G4PhysicalVolume representing all replicas. // We actually need the LogicalVolume. // Thus we ask the first daughter ::GetDaughter(0) and ask the // associated logical volume if ( is_x1_PlaneDUT ) { const G4LogicalVolume* log = physi_x1_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_x1); } if ( is_u1_PlaneDUT ) { const G4LogicalVolume* log = physi_u1_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_u1); } if ( is_v1_PlaneDUT ) { const G4LogicalVolume* log = physi_v1_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_v1); } if ( is_x2_PlaneDUT ) { const G4LogicalVolume* log = physi_x2_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_x2); } if ( is_u2_PlaneDUT ) { const G4LogicalVolume* log = physi_u2_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_u2); } if ( is_v2_PlaneDUT ) { const G4LogicalVolume* log = physi_v2_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_v2); } if ( is_TP1_DUT ) { const G4LogicalVolume* log = physi_TP1->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_TP1); } if ( is_TP2_DUT ) { const G4LogicalVolume* log = physi_TP2->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_TP2); } if ( is_TP3_DUT ) { const G4LogicalVolume* log = physi_TP3->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_TP3); } if ( is_TP4_DUT ) { const G4LogicalVolume* log = physi_TP4->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_TP4); } if ( is_x3_PlaneDUT ) { const G4LogicalVolume* log = physi_x3_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_x3); } if ( is_u3_PlaneDUT ) { const G4LogicalVolume* log = physi_u3_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_u3); } if ( is_v3_PlaneDUT ) { const G4LogicalVolume* log = physi_v3_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_v3); } if ( is_x4_PlaneDUT ) { const G4LogicalVolume* log = physi_x4_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_x4); } if ( is_u4_PlaneDUT ) { const G4LogicalVolume* log = physi_u4_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_u4); } if ( is_v4_PlaneDUT ) { const G4LogicalVolume* log = physi_v4_Sensor->GetLogicalVolume(); log->GetDaughter(0)->GetLogicalVolume()->SetSensitiveDetector(sensitive_det_v4); } } #include "G4RunManager.hh" #include "G4PhysicalVolumeStore.hh" #include "G4LogicalVolumeStore.hh" #include "G4SolidStore.hh" //void StripTrackerConstruction::CleanGeometry() //{ // G4PhysicalVolumeStore* store = G4PhysicalVolumeStore::GetInstance(); // std::vector::iterator pos; // for(pos=store->begin(); pos!=store->end(); pos++) // { // std::cout << "StripTracker " << (*pos)->GetName() << std::endl; // if( (*pos)->GetName().Contains("Sensor")) // store->DeRegister((*pos)); // } void StripTrackerConstruction::UpdateGeometry() { // Cleanup old geometry G4GeometryManager::GetInstance()->OpenGeometry(); // G4PhysicalVolumeStore::GetInstance()->Clean(); // G4LogicalVolumeStore::GetInstance()->Clean(); // G4SolidStore::GetInstance()->Clean(); // ConstructVolumes(); // G4RotationMatrix * rm1 = new G4RotationMatrix; // rm1->rotateZ(45*deg); // physi_x1_Sensor->SetRotation(rm1); G4RunManager::GetRunManager()->GeometryHasBeenModified(); }