#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __GNUC__ #define UNUSED __attribute__((unused)) #else #define UNUSED #endif using namespace std; namespace RAT { void GeoCerenkovSourceFactory::Construct(DBLinkPtr table, UNUSED const bool checkOverlaps){ string neck_index = "ChSrce_neck"; string flange_index = "ChSrce_flange"; string endcap_index = "ChSrce_endcap"; string weight_cylinder_index = "ChSrce_weight_cylinder"; string top_index = "ChSrce_top"; string acrylic_ball_index = "ChSrce_AcrylicSource"; string paint_layer_index = "ChSrce_PaintLayer"; string decay_chamber_index = "ChSrce_DecayChamber"; string body_index = "ChSrce_Body"; string cavity_index = "ChSrce_cavity"; string window_index = "ChSrce_Window"; string pmt_index = "ChSrce_PMT"; string pmt_base_index = "ChSrce_PMT_base"; string pmt_can_index = "ChSrce_PMT_can"; string motherName = table->GetS("mother"); G4VPhysicalVolume *motherPhys = Detector::FindPhysicalVolume(motherName); // find the position of the source // allow user to specify position from the macro file const vector &pos = table->GetDArray("position"); G4ThreeVector position(pos[0], pos[1], pos[2]); // check to make sure the user did not try to set the old position fields checkFieldDoesNotExist(table, "x_position"); checkFieldDoesNotExist(table, "y_position"); checkFieldDoesNotExist(table, "z_position"); // Grab values needed to build the acrylic ball float acrylic_ball_thickness = table->GetD("acrylic_ball_thickness"); string acrylic_ball_material = table->GetS("acrylic_ball_material"); const vector &acrylic_ball_colour = table->GetFArrayFromD("acrylic_ball_colour"); // get values needed to build the paint layer float paint_layer_thickness = table->GetD("paint_layer_thickness"); string paint_layer_material = table->GetS("paint_layer_material"); const vector &paint_layer_colour = table->GetFArrayFromD("paint_layer_colour"); //get values needed to build the decay chamber float decay_chamber_radius = table->GetD("decay_chamber_radius"); string decay_chamber_material = table->GetS("decay_chamber_material"); const vector &decay_chamber_colour = table->GetFArrayFromD("decay_chamber_colour"); //get values needed to build the body float neck_r_max = table->GetD("neck_r_max"); float neck_size_z = table->GetD("neck_size_z"); float flange_r_max = table->GetD("flange_r_max"); float flange_size_z = table->GetD("flange_size_z"); float endcap_r_max = table->GetD("endcap_r_max"); float endcap_size_z = table->GetD("endcap_size_z"); float weight_cylinder_r_max = table->GetD("weight_cylinder_r_max"); float weight_cylinder_size_z = table->GetD("weight_cylinder_size_z"); float top_r_max = table->GetD("top_r_max"); float top_size_z = table->GetD("top_size_z"); float body_thickness = table->GetD("body_thickness"); string body_material = table->GetS("body_material"); const vector &body_colour = table->GetFArrayFromD("body_colour"); //get values needed to build the cavity string cavity_material = table->GetS("cavity_material"); const vector &cavity_colour = table->GetFArrayFromD("cavity_colour"); //get values needed to build the window float window_r_max = table->GetD("window_r_max"); float window_size_z = table->GetD("window_size_z"); string window_material = table->GetS("window_material"); const vector &window_colour = table->GetFArrayFromD("window_colour"); //get values needed to build the pmt float pmt_r_max = table->GetD("pmt_r_max"); float pmt_size_z = table->GetD("pmt_size_z"); string pmt_material = table->GetS("pmt_material"); const vector &pmt_colour = table->GetFArrayFromD("pmt_colour"); //get values needed to build the pmt base float pmt_base_r_max = table->GetD("pmt_base_r_max"); float pmt_base_size_z = table->GetD("pmt_base_size_z"); string pmt_base_material = table->GetS("pmt_base_material"); const vector &pmt_base_colour = table->GetFArrayFromD("pmt_base_colour"); //get values needed to build the pmt can float pmt_can_thickness = table->GetD("pmt_can_thickness"); string pmt_can_material = table->GetS("pmt_can_material"); const vector &pmt_can_colour = table->GetFArrayFromD("pmt_can_colour"); //calculate the radius of the paint layer float paint_layer_radius = decay_chamber_radius + paint_layer_thickness; //calculate the radius of the acrylic sphere float acrylic_ball_radius = paint_layer_radius + acrylic_ball_thickness; //calculate the position of neck the wrt the default position float z = sqrt(decay_chamber_radius*decay_chamber_radius - neck_r_max*neck_r_max); G4ThreeVector neck_pos(0.0, 0.0 , z+neck_size_z); //calculate the position of the flange wrt the default position G4ThreeVector flange_pos(0.0, 0.0, neck_pos.z() + neck_size_z + flange_size_z); //get the position for the window wrt the neck's position G4ThreeVector window_pos(0.0, 0.0, window_size_z - neck_size_z); //get the position for the endcap wrt the default position G4ThreeVector endcap_pos(0.0, 0.0, flange_pos.z() + flange_size_z + endcap_size_z); //get the position for the weight cylinder wrt the default position G4ThreeVector weight_cylinder_pos(0.0, 0.0, endcap_pos.z() + endcap_size_z + weight_cylinder_size_z); //get the position for the top wrt the default position G4ThreeVector top_pos(0.0, 0.0, weight_cylinder_pos.z() + weight_cylinder_size_z + top_size_z); //get the position for the pmt wrt to the cavity's position G4ThreeVector pmt_pos(0.0, 0.0, -neck_size_z + window_size_z + pmt_size_z); //get the position for the pmt base wrt to the cavity's position G4ThreeVector pmt_base_pos(0.0, 0.0, pmt_pos.z() + pmt_size_z + pmt_base_size_z); //create the solid for the neck G4Tubs *neck_solid = new G4Tubs(neck_index, 0.0, neck_r_max, neck_size_z, 0.0, 360.0); //create the solid for the flange G4Tubs *flange_solid = new G4Tubs(flange_index, 0.0, flange_r_max, flange_size_z, 0.0, 360.0); //create the solid for the acrylic ball G4Orb *ab_1 = new G4Orb(acrylic_ball_index + "_1", acrylic_ball_radius); G4SubtractionSolid *ab_2 = new G4SubtractionSolid(acrylic_ball_index + "_2", ab_1, neck_solid, NULL, neck_pos); G4SubtractionSolid *acrylic_ball_solid = new G4SubtractionSolid(acrylic_ball_index, ab_2, flange_solid, NULL, flange_pos); //create the solid for the paint layer G4Orb *pl_1 = new G4Orb(paint_layer_index + "_1", paint_layer_radius); G4SubtractionSolid *paint_layer_solid = new G4SubtractionSolid(paint_layer_index, pl_1, neck_solid, NULL, neck_pos); //create the solid for the decay chamber G4Orb *dc_1 = new G4Orb(decay_chamber_index + "_1", decay_chamber_radius); G4SubtractionSolid *decay_chamber_solid = new G4SubtractionSolid(decay_chamber_index, dc_1, neck_solid, NULL, neck_pos); //create the solid for the window G4Tubs *window_solid = new G4Tubs(window_index, 0.0, window_r_max, window_size_z, 0.0, 360.0); //create the solid for the body G4Tubs *endcap_solid = new G4Tubs(endcap_index, 0.0, endcap_r_max, endcap_size_z, 0.0, 360.0); G4Tubs *weight_cylinder_solid = new G4Tubs(weight_cylinder_index, 0.0, weight_cylinder_r_max, weight_cylinder_size_z, 0.0, 360.0); G4Tubs *top_solid = new G4Tubs(top_index, 0.0, top_r_max, top_size_z, 0.0, 360.0); G4UnionSolid *nf = new G4UnionSolid("ChSrce_nf", neck_solid, flange_solid, NULL, flange_pos-neck_pos); G4UnionSolid *nfe = new G4UnionSolid("ChSrce_nfe", nf, endcap_solid, NULL, endcap_pos-neck_pos); G4UnionSolid *nfew = new G4UnionSolid("ChSrce_nfew", nfe, weight_cylinder_solid, NULL, weight_cylinder_pos-neck_pos); G4UnionSolid *body_solid = new G4UnionSolid(body_index, nfew, top_solid, NULL, top_pos-neck_pos); //create the solid for the cavity G4Tubs *neck_cavity_solid = new G4Tubs(neck_index + "_cavity", 0.0, neck_r_max - body_thickness, neck_size_z, 0.0, 360.0); G4Tubs *flange_cavity_solid = new G4Tubs(flange_index + "_cavity", 0.0, flange_r_max - body_thickness, flange_size_z, 0.0, 360.0); G4Tubs *endcap_cavity_solid = new G4Tubs(endcap_index + "_cavity", 0.0, endcap_r_max - body_thickness, endcap_size_z, 0.0, 360.0); G4Tubs *weight_cavity_cylinder_solid = new G4Tubs(weight_cylinder_index + "_cavity", 0.0, weight_cylinder_r_max - body_thickness, weight_cylinder_size_z, 0.0, 360.0); G4UnionSolid *cnf = new G4UnionSolid("ChSrce_cnf", neck_cavity_solid, flange_cavity_solid, NULL, flange_pos-neck_pos); G4UnionSolid *cnfe = new G4UnionSolid("ChSrce_cnfe", cnf, endcap_cavity_solid, NULL, endcap_pos-neck_pos); G4UnionSolid *cnfew = new G4UnionSolid("ChSrce_cnfew", cnfe, weight_cavity_cylinder_solid, NULL, weight_cylinder_pos-neck_pos); G4SubtractionSolid *cavity_solid = new G4SubtractionSolid(cavity_index, cnfew, window_solid, NULL, window_pos); //create the pmt solids G4Tubs *pmt_solid = new G4Tubs(pmt_index, 0.0, pmt_r_max, pmt_size_z, 0.0, 360.0); G4Tubs *pmt_base_solid = new G4Tubs(pmt_base_index, 0.0, pmt_base_r_max, pmt_base_size_z, 0.0, 360.0); G4Tubs *pmt_can_1 = new G4Tubs(pmt_can_index+"_1", 0.0, pmt_r_max+pmt_can_thickness, pmt_size_z, 0.0, 360.0); G4Tubs *pmt_can_2 = new G4Tubs(pmt_can_index+"_2", 0.0, pmt_base_r_max+pmt_can_thickness, pmt_base_size_z + pmt_can_thickness, 0.0, 360.0); G4UnionSolid *pmt_can_solid = new G4UnionSolid(pmt_can_index, pmt_can_1, pmt_can_2, NULL, pmt_base_pos - pmt_pos); //get materials G4Material *acrylic_ball_mat = G4Material::GetMaterial(acrylic_ball_material); G4Material *paint_layer_mat = G4Material::GetMaterial(paint_layer_material); G4Material *decay_chamber_mat = G4Material::GetMaterial(decay_chamber_material); G4Material *body_mat = G4Material::GetMaterial(body_material); G4Material *window_mat = G4Material::GetMaterial(window_material); G4Material *cavity_mat = G4Material::GetMaterial(cavity_material); G4Material *pmt_mat = G4Material::GetMaterial(pmt_material); G4Material *pmt_base_mat = G4Material::GetMaterial(pmt_base_material); G4Material *pmt_can_mat = G4Material::GetMaterial(pmt_can_material); //make logical volumes G4LogicalVolume *acrylic_ball_log = new G4LogicalVolume(acrylic_ball_solid, acrylic_ball_mat, acrylic_ball_index); G4LogicalVolume *paint_layer_log = new G4LogicalVolume(paint_layer_solid, paint_layer_mat, paint_layer_index); G4LogicalVolume *decay_chamber_log = new G4LogicalVolume(decay_chamber_solid, decay_chamber_mat, decay_chamber_index); G4LogicalVolume *body_log = new G4LogicalVolume(body_solid, body_mat, body_index); G4LogicalVolume *window_log = new G4LogicalVolume(window_solid, window_mat, window_index); G4LogicalVolume *cavity_log = new G4LogicalVolume(cavity_solid, cavity_mat, cavity_index); G4LogicalVolume *pmt_can_log = new G4LogicalVolume(pmt_can_solid, pmt_can_mat, pmt_can_index); G4LogicalVolume *pmt_log = new G4LogicalVolume(pmt_solid, pmt_mat, pmt_index); G4LogicalVolume *pmt_base_log = new G4LogicalVolume(pmt_base_solid, pmt_base_mat, pmt_base_index); //set colours acrylic_ball_log->SetVisAttributes(getColour(acrylic_ball_colour)); paint_layer_log->SetVisAttributes(getColour(paint_layer_colour)); decay_chamber_log->SetVisAttributes(getColour(decay_chamber_colour)); body_log->SetVisAttributes(getColour(body_colour)); window_log->SetVisAttributes(getColour(window_colour)); cavity_log->SetVisAttributes(getColour(cavity_colour)); pmt_can_log->SetVisAttributes(getColour(pmt_can_colour)); pmt_log->SetVisAttributes(getColour(pmt_colour)); pmt_base_log->SetVisAttributes(getColour(pmt_base_colour)); //place the physical volumes in the space new G4PVPlacement(NULL, position, acrylic_ball_index, acrylic_ball_log, motherPhys, false, 0); new G4PVPlacement(NULL, G4ThreeVector(0,0,0), paint_layer_log, paint_layer_index, acrylic_ball_log, false, 0); new G4PVPlacement(NULL, G4ThreeVector(0,0,0), decay_chamber_log, decay_chamber_index, paint_layer_log, false, 0); new G4PVPlacement(NULL, position + neck_pos, body_index, body_log, motherPhys, false, 0); new G4PVPlacement(NULL, G4ThreeVector(0,0,0), cavity_log, cavity_index, body_log, false, 0); new G4PVPlacement(NULL, window_pos, window_log, window_index, body_log, false, 0); new G4PVPlacement(NULL, pmt_pos, pmt_can_log, pmt_can_index, cavity_log, false, 0); new G4PVPlacement(NULL, G4ThreeVector(0,0,0), pmt_log, pmt_index, pmt_can_log, false, 0); new G4PVPlacement(NULL, pmt_base_pos-pmt_pos, pmt_base_log, pmt_base_index, pmt_can_log, false, 0); return; } G4VisAttributes* GeoCerenkovSourceFactory::getColour(std::vector colour) { if(colour.size() == 3) return new G4VisAttributes(G4Colour(colour[0], colour[1], colour[2])); else return new G4VisAttributes(G4Colour()); } void GeoCerenkovSourceFactory::checkFieldDoesNotExist(DBLinkPtr table, std::string field) { try { table->GetD(field); Log::Die("Cereknov source error: Field '" + field + "' no longer used.\n" + "\t\t\t Use the 'position' field instead"); } catch(DBNotFoundError &e) {} } } // namespace RAT