diff --git a/Simulation/G4Utilities/Geo2G4/src/ExtParameterisedVolumeBuilder.cxx b/Simulation/G4Utilities/Geo2G4/src/ExtParameterisedVolumeBuilder.cxx index d9097e12d1b8b9869e96bebf03474dc611cf84a0..70a910407fd2f4dbf3d3a24004b4759d181a6166 100644 --- a/Simulation/G4Utilities/Geo2G4/src/ExtParameterisedVolumeBuilder.cxx +++ b/Simulation/G4Utilities/Geo2G4/src/ExtParameterisedVolumeBuilder.cxx @@ -41,120 +41,8 @@ ExtParameterisedVolumeBuilder::ExtParameterisedVolumeBuilder(std::string n): { } -//stolen from G4bool G4PVPlacement::CheckOverlaps, but revised so we can tell what it overlaps with... -//returns 0 if no overlap, overwise returns overlapping volume pointer...and whether it's with the mother... -G4VPhysicalVolume* check_overlap(G4VPhysicalVolume *me, int &mom){ - int res = 1000;//number of points to check per volume! - mom=-1;//will return whether it is the mom that is overlapping or not... - G4VSolid* solid = me->GetLogicalVolume()->GetSolid(); - G4LogicalVolume* motherLog = me->GetMotherLogical(); - //std::cout<<"check_overlap"<<std::endl; - if (!motherLog) { return 0; } - G4VSolid* motherSolid = motherLog->GetSolid(); - - // Create the transformation from daughter to mother - G4AffineTransform Tm( me->GetRotation(), me->GetTranslation() ); - std::cout<<"check_overlap for "<<me->GetName()<<" with "<<res<<" points"<<std::endl; - for (G4int n=0; n<res; n++) - { - // Generate a random point on the solid's surface - G4ThreeVector point = solid->GetPointOnSurface(); - - // Transform the generated point to the mother's coordinate system - G4ThreeVector mp = Tm.TransformPoint(point); - - // Checking overlaps with the mother volume - if (motherSolid->Inside(mp)==kOutside) - { - G4double distin = motherSolid->DistanceToIn(mp); - if (distin>0) - { - // std::ostringstream message; -// message << "Overlap with mother volume !" << G4endl -// << " Overlap is detected for volume " -// << me->GetName() << G4endl -// << " with its mother volume " -// << motherLog->GetName() << G4endl -// << " at mother local point " << mp << ", " -// << "overlapping by at least: " -// << G4BestUnit(distin, "Length"); - //G4Exception("G4PVPlacement::CheckOverlaps()","GeomVol1002", JustWarning, message); - mom=1; - return 0;//motherLog; - } - } - - // Checking overlaps with each 'sister' volume - for (G4int i=0; i<motherLog->GetNoDaughters(); i++) - { - G4VPhysicalVolume* daughter = motherLog->GetDaughter(i); - - if (daughter == me) { continue; } - - // Create the transformation for daughter volume and transform point - G4AffineTransform Td( daughter->GetRotation(), - daughter->GetTranslation() ); - G4ThreeVector md = Td.Inverse().TransformPoint(mp); - - G4VSolid* daughterSolid = daughter->GetLogicalVolume()->GetSolid(); - if (daughterSolid->Inside(md)==kInside) - { - G4double distout = daughterSolid->DistanceToOut(md); - if (distout>0) - { - // std::ostringstream message; -// message << "Overlap with volume already placed !" << G4endl -// << " Overlap is detected for volume " -// << me->GetName() << G4endl -// << " with " << daughter->GetName() << " volume's" -// << G4endl -// << " local point " << md << ", " -// << "overlapping by at least: " -// << G4BestUnit(distout,"Length"); -// G4Exception("G4PVPlacement::CheckOverlaps()", -// "GeomVol1002", JustWarning, message); - mom=0; - return daughter; - } - } - - // Now checking that 'sister' volume is not totally included and - // overlapping. Do it only once, for the first point generated - if (n==0) - { - // Generate a single point on the surface of the 'sister' volume - // and verify that the point is NOT inside the current volume - G4ThreeVector dPoint = daughterSolid->GetPointOnSurface(); - - // Transform the generated point to the mother's coordinate system - // and finally to current volume's coordinate system - G4ThreeVector mp2 = Td.TransformPoint(dPoint); - G4ThreeVector msi = Tm.Inverse().TransformPoint(mp2); - - if (solid->Inside(msi)==kInside) - { - // std::ostringstream message; -// message << "Overlap with volume already placed !" << G4endl -// << " Overlap is detected for volume " -// << me->GetName() << G4endl -// << " apparently fully encapsulating volume " -// << daughter->GetName() << G4endl -// << " at the same level !"; -// G4Exception("G4PVPlacement::CheckOverlaps()", -// "GeomVol1002", JustWarning, message); - mom=2; - return daughter; - } - } - } - } - return 0;//no overlap! -} - - G4LogicalVolume* ExtParameterisedVolumeBuilder::Build(const PVConstLink theGeoPhysVolume, OpticalVolumesMap* optical_volumes) const { - MsgStream log(msgSvc(),GetKey()); PVConstLink theGeoPhysChild; const GeoSerialTransformer* serialTransformerChild=0; G4LogicalVolume* theG4LogChild; @@ -273,173 +161,12 @@ G4LogicalVolume* ExtParameterisedVolumeBuilder::Build(const PVConstLink theGeoPh if (nameChild == "ANON") nameChild=theG4LogChild->GetName(); - log << MSG::DEBUG << "ACH655 Placing child: "<<nameChild<<"["<<id<<"]"<<" in mother "<<theG4LogVolume->GetName()<<endmsg; - - bool surfcheck=true; //whether to check for overlaps - bool doplace=true; - if ("TRT::MainRadiatorA"==nameChild && 16969==id) surfcheck=true; - if ("TRT::ThinRadiatorA"==nameChild && 16969==id) surfcheck=true; - if ("TRT::InnerSupportA"==nameChild && 16969==id) surfcheck=true; - if ("TRT::OuterSupportA"==nameChild && 16969==id) surfcheck=true; - if ("TRT::MiddleRadiatorA"==nameChild && 16969==id) surfcheck=true; - //if ("TRT::Straw"==nameChild) doplace=false;//don't build straws for now - //if ("TRT::StrawPlane"==nameChild && id!=2) doplace=false;//only build one strawplane for now - if (std::string(nameChild).find("LAr:")!=std::string::npos) surfcheck=false; - if (std::string(nameChild).find("Tile:")!=std::string::npos) surfcheck=false; - if (std::string(nameChild).find("DriftTube")!=std::string::npos) surfcheck=false; - if (std::string(nameChild).find("Muon:")!=std::string::npos) surfcheck=false; - if (std::string(theG4LogVolume->GetName()).find("Muon:")!=std::string::npos) surfcheck=false;//or if the mom is muon - if (std::string(nameChild).find("Pixel:")!=std::string::npos) surfcheck=false; - if (std::string(nameChild).find("SCT:")!=std::string::npos) surfcheck=false; - if (std::string(theG4LogVolume->GetName()).find("SCT:")!=std::string::npos) surfcheck=false;//or if the mom is sct - if (std::string(nameChild).find("_cut")!=std::string::npos) { - doplace=false;//don't add again for now, if we already cut it - log<<MSG::WARNING<<"Why is something that was cut already now being placed again?"<<endmsg; - } - bool dosurfcheckfuringplacement=false;//to run the printout in G4 for surfcheck placements - if (doplace) { - G4PhysicalVolumesPair pvPair = G4ReflectionFactory::Instance()->Place(theG4Position, - nameChild, - theG4LogChild, - theG4LogVolume, - false, - id, - surfcheck&&dosurfcheckfuringplacement); - - static int trytofixoverlaps=-1; - if (trytofixoverlaps<0) {//just check it once... - char* pTRY; pTRY=getenv("HAAS_TryToFixOverlaps"); - if (pTRY!=NULL) trytofixoverlaps=atoi(pTRY); else trytofixoverlaps=0; - log<<MSG::INFO<<"Try to fix overlaps: "<<trytofixoverlaps<<endmsg; - } - static int docheckoverlaps=-1; - if (docheckoverlaps<0) {//just check it once... - char* pTRY; pTRY=getenv("HAAS_CheckOverlaps"); - if (pTRY!=NULL) docheckoverlaps=atoi(pTRY); else docheckoverlaps=0; - log<<MSG::INFO<<"Check for overlaps: "<<docheckoverlaps<<endmsg; - } - - while (surfcheck){//keep looping until we break out... - bool triedtofix=false; - int mom=-2; G4VPhysicalVolume* other = 0; if (docheckoverlaps||trytofixoverlaps) {other=check_overlap(pvPair.first,mom);} - if (other){ - log<<MSG::INFO<<"ACH649 : "<<other->GetName()<<" is overlapping "<<pvPair.first->GetName()<<" and mom is "<<mom<<endmsg; - if (!trytofixoverlaps){ - static int ci = 0; std::string cis; std::stringstream cisout; - cisout<<"_cut"; cisout << ++ci; cis = cisout.str();//keep track of increasing cut N - - other->SetName(other->GetName()+cis); - pvPair.first->SetName(pvPair.first->GetName()+cis); - std::cout<<"Now have "<<pvPair.first->GetName()<<" and "<<other->GetName()<<std::endl; - break;// - } - } - else { - break;//no overlaps - } - if (other&&trytofixoverlaps){ - //do something to try to fix the overlap! - if (0==mom){ - static int ci = 0; std::string cis; std::stringstream cisout; - cisout<<"_cut"; cisout << ++ci; cis = cisout.str();//keep track of increasing cut N - - //easiest case, overlaping sisters within the same mother - //first make the new solid, via subtraction - G4RotationMatrix *myrot=new G4RotationMatrix();//initially Identity - if (other->GetRotation()) (*myrot)= *(other->GetRotation());//make sure it's not null - (*myrot)*=pvPair.first->GetObjectRotationValue();//straw rot * inverse support rot? - G4SubtractionSolid* cutout = new G4SubtractionSolid(pvPair.first->GetName()+cis, //TRT::InnerSupportB_cut5 - pvPair.first->GetLogicalVolume()->GetSolid(), //TRT::InnerSupportB solid - other->GetLogicalVolume()->GetSolid(), //TRT::StrawPlane solid - myrot,//made just above - other->GetTranslation() - pvPair.first->GetTranslation() //straw - support - ); - log<<MSG::INFO<<"ACH544 Replacing "<<pvPair.first->GetName()<<" volume of size " - <<pvPair.first->GetLogicalVolume()->GetSolid()->GetCubicVolume() - <<" with cutout volume "<<cutout->GetCubicVolume()<<endmsg; - - //then we copy the logical volume, since it will have a different (cutout) solid - G4LogicalVolume *lv=pvPair.first->GetLogicalVolume(); - std::cout<<"old name is "<<lv->GetName()<<" and cis is "<<cis<<std::endl; - G4LogicalVolume *lvnew = new G4LogicalVolume(cutout, lv->GetMaterial(), - lv->GetName()+cis, lv->GetFieldManager(), lv->GetSensitiveDetector(), lv->GetUserLimits() ); - - //copy the daughters of the old volume into the new volume - for (int d=0; d<lv->GetNoDaughters(); ++d){ - lvnew->AddDaughter(lv->GetDaughter(d)); - } - - //really we should copy the daughters too, and then do daughter->SetMotherLogical(pvPair.first->GetLogicalVolume()); !!! - //TODO... - log<<MSG::INFO<<"New LogicalVolume "<<lvnew->GetName()<<" has "<<lvnew->GetNoDaughters()<<" daughters"<<endmsg; - - //remove the old and make a new PhysicalVolume - G4String newvolname = pvPair.first->GetName()+cis; - pvPair.first->SetName(pvPair.first->GetName()+"_old"); - G4PhysicalVolumeStore::DeRegister(pvPair.first); - delete pvPair.first;//!!! - - G4PhysicalVolumesPair pvPair2 = G4ReflectionFactory::Instance()->Place(theG4Position, - newvolname, - lvnew, - theG4LogVolume, - false, - id, - true);//surfcheck&&dosurfcheckfuringplacement); - - other->SetName(other->GetName()+cis); - if (pvPair2.first) std::cout<<"Now have first volume "<<pvPair2.first->GetName()<<" and "<<other->GetName()<<std::endl; - if (pvPair2.second) std::cout<<"Now have second volume "<<pvPair2.first->GetName()<<" and "<<other->GetName()<<std::endl; - triedtofix=true; - pvPair.first=pvPair2.first;//for the next time through the while loop checking for more overlaps... - - } - else if (2==mom){ - //a sister is totally inside me? - } - else { - log<<MSG::ERROR<<" How can mom be "<<mom<<" here ???"<<endmsg; - } - // - - }//other - else if (mom==1 && trytofixoverlaps){ - log<<MSG::WARNING<<"ACH649 : overlapping pvPair first with mother (not fixing yet), " - <<pvPair.first->GetName()<<" and mom is "<<mom<<endmsg; - } - - if (pvPair.second){ - mom=-2; - other = check_overlap(pvPair.second,mom); - if (other){ - log<<MSG::WARNING<<"ACH649 : "<<other->GetName()<<" is overlapping pvPair second (not fixing yet), " - <<pvPair.second->GetName()<<" and mom is "<<mom<<endmsg; - } - else if (mom==1){ - log<<MSG::WARNING<<"ACH649 : overlapping pvPair second (not fixing yet), " - <<pvPair.second->GetName()<<" and mom is "<<mom<<endmsg; - } - } - - if (triedtofix){ - int mom2=-2; G4VPhysicalVolume* other2 = check_overlap(pvPair.first,mom2);//recheck! - if (other2){ - log<<MSG::INFO<<"ACH644 : "<<other2->GetName()<<" is still overlapping "<<pvPair.first->GetName()<<" and mom2 is "<<mom2<<endmsg; - //try again... - } - else if (mom2==1){ - log<<MSG::WARNING<<"ACH644 : overlapping pvPair first with mother STILL "<<pvPair.first->GetName()<<" and mom2 is "<<mom2<<endmsg; - break;//not fixing it yet... - } - else{ - log<<MSG::INFO<<"ACH644 : no overlaps for "<<pvPair.first->GetName()<<" now and mom2 is "<<mom2<<endmsg; - break;//good jorb! - } - } - - }//while surfcheck - - + G4PhysicalVolumesPair pvPair = G4ReflectionFactory::Instance()->Place(theG4Position, + nameChild, + theG4LogChild, + theG4LogVolume, + false, + id); // if GeoModel volume is optical store it in the map if(optical_volumes!=0) @@ -449,7 +176,6 @@ G4LogicalVolume* ExtParameterisedVolumeBuilder::Build(const PVConstLink theGeoPh if(opticalGeoPhysChild) (*optical_volumes)[opticalGeoPhysChild] = pvPair.first; } - }//doplace } av.next();