Exemplo n.º 1
0
void KVGeoImport::ParticleEntersNewVolume(KVNucleus *)
{
    // All detectors crossed by the particle's trajectory are added to the multidetector
    // and the groups (KVGroup) of aligned detectors are set up

    KVDetector* detector = GetCurrentDetector();
    if(!detector) return;
	 Bool_t group_inconsistency = kFALSE;
    if(fCreateArray){
        if(!fCurrentGroup){
            if(detector->GetGroup()) {
                fCurrentGroup=detector->GetGroup();
            }
            else {
                fCurrentGroup = new KVGroup;
                fCurrentGroup->SetNumber(++fGroupNumber);
                fCurrentGroup->Add(detector);
                fArray->Add(fCurrentGroup);
            }
        }
        else
        {
            KVGroup* det_group = detector->GetGroup();
            if(!det_group) {
                fCurrentGroup->Add(detector);
            }
            else {
                if(det_group!=fCurrentGroup){
//                     Warning("ParticleEntersNewVolume",
//                             "Detector %s : already belongs to %s, now seems to be in %s",
//                             detector->GetName(), det_group->GetName(),
//                             fCurrentGroup->GetName());
						  group_inconsistency = kTRUE;
					 }
            }
        }
    }
    detector->GetNode()->SetName(detector->GetName());
	 if(fLastDetector && detector!=fLastDetector && !group_inconsistency) {
        fLastDetector->GetNode()->AddBehind(detector);
        detector->GetNode()->AddInFront(fLastDetector);
    }
    fLastDetector = detector;
}
Exemplo n.º 2
0
void KVINDRA::CreateROOTGeometry()
{
   // Overrides KVASMultiDetArray::CreateGeoManager in order to use INDRAGeometryBuilder
   // which builds the TGeo representation of INDRA using the Y. Huguet CAO data.
   //
   // The optional arguments (dx,dy,dz) are the half-lengths in centimetres of the "world"/"top" volume
   // into which all the detectors of the array are placed. This should be big enough so that all detectors
   // fit in. The default values of 500 give a "world" which is a cube 1000cmx1000cmx1000cm (with sides
   // going from -500cm to +500cm on each axis).
   //
   // If closegeo=kFALSE we leave the geometry open for other structures to be added.

   if (!IsBuilt()) {
      Error("CreateROOTGeometry", "gIndra has to be build first");
      return;
   }
   if (!GetNavigator()) {
      //Error("CreateROOTGeometry","No existing navigator"); return;
      SetNavigator(new KVRangeTableGeoNavigator(gGeoManager, KVMaterial::GetRangeTable()));
      GetNavigator()->SetNameCorrespondanceList("INDRA.names");
   }

   // set up shape & matrix pointers in detectors
   Info("CreateROOTGeometry", "Scanning geometry shapes and matrices...");
   KVGeoImport gimp(gGeoManager, KVMaterial::GetRangeTable(), this, kFALSE);
   gimp.SetNameCorrespondanceList("INDRA.names");
   KVEvent* evt = new KVEvent();
   KVNucleus* nuc = evt->AddParticle();
   nuc->SetZAandE(1, 1, 1);
   KVINDRADetector* det;
   TIter next(GetDetectors());
   Int_t nrootgeo = 0;
   while ((det = (KVINDRADetector*)next())) {
      nuc->SetTheta(det->GetTheta());
      nuc->SetPhi(det->GetPhi());
      gimp.SetLastDetector(0);
      gimp.PropagateEvent(evt);
      if (!(det->GetActiveLayerShape() && det->GetActiveLayerMatrix())) {
         Info("CreateROOTGeometry", "Volume checking for %s", det->GetName());
         Double_t theta0 = det->GetTheta();
         Double_t phi0 = det->GetPhi();
         for (Double_t TH = theta0 - 0.5; TH <= theta0 + 0.5; TH += 0.1) {
            for (Double_t PH = phi0 - 10; PH <= phi0 + 10; PH += 1) {
               nuc->SetTheta(TH);
               nuc->SetPhi(PH);
               gimp.SetLastDetector(0);
               gimp.PropagateEvent(evt);
               if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()) break;
            }
            if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix()) break;
         }
      }
      if (!(det->GetActiveLayerShape() && det->GetActiveLayerMatrix())) {
         Info("CreateROOTGeometry", "Volume checking failed for : %s", det->GetName());
      }
      // check etalon trajectories (if etalons are present)
      if (det->GetActiveLayerShape() && det->GetActiveLayerMatrix() && det->GetRingNumber() > 9) {
         if (GetDetector(Form("SI75_%d", det->GetRingNumber())) || GetDetector(Form("SILI_%d", det->GetRingNumber()))) {
            if ((det->IsCalled("CSI_1002") || det->IsCalled("CSI_1102")
                  || det->IsCalled("CSI_1202") || det->IsCalled("CSI_1304")
                  || det->IsCalled("CSI_1403") || det->IsCalled("CSI_1503")
                  || det->IsCalled("CSI_1602") || det->IsCalled("CSI_1702"))
                  && det->GetNode()->GetNDetsInFront() < 2) {
               Info("CreateROOTGeometry", "Trajectory checking for %s", det->GetName());
               Double_t theta0 = det->GetTheta();
               Double_t phi0 = det->GetPhi();
               for (Double_t TH = theta0 - 0.5; TH <= theta0 + 0.5; TH += 0.1) {
                  for (Double_t PH = phi0 - 10; PH <= phi0 + 10; PH += 1) {
                     nuc->SetTheta(TH);
                     nuc->SetPhi(PH);
                     gimp.SetLastDetector(0);
                     gimp.PropagateEvent(evt);
                     if (det->GetNode()->GetNDetsInFront() == 2) break;
                  }
                  if (det->GetNode()->GetNDetsInFront() == 2) break;
               }
            }
         }
      }
      nrootgeo += (det->GetActiveLayerShape() && det->GetActiveLayerMatrix());
   }
   delete evt;

   Info("CreateROOTGeometry", "ROOT geometry initialised for %d/%d detectors", nrootgeo, GetDetectors()->GetEntries());

   // Set up trajectories
   TIter it(GetDetectors());
   KVDetector* d;
   while ((d = (KVDetector*)it())) d->GetNode()->RehashLists();// make sure detector nodes are correct
   AssociateTrajectoriesAndNodes();
   DeduceGroupsFromTrajectories();
   FillTrajectoryIDTelescopeLists();
   CalculateReconstructionTrajectories();
   GetNavigator()->AbsorbDetectorPaths(&gimp);
}