void KVVAMOSReconGeoNavigator::ParticleEntersNewVolume(KVNucleus* nuc) { // Overrides method in KVGeoNavigator base class. // Every time a particle enters a new volume, we check the material to see // if it is known (i.e. contained in the range table fRangeTable). // If so, then we calculate the step through the material (STEP) of the nucleus // and the distance (DPATH in cm) between the intersection point at the focal plane // and the point at the entrance of the volume if it is the first active volume of a detector. // DPATH has the sign + if the volume is behind the focal plane or - if it // is at the front of it. // KVVAMOSReconNuc* rnuc = (KVVAMOSReconNuc*)nuc; // stop the propagation if the current volume is the stopping detector // of the nucleus but after the process of this volume if (rnuc->GetStoppingDetector()) { TGeoVolume* stopVol = (TGeoVolume*)((KVVAMOSDetector*)rnuc->GetStoppingDetector())->GetActiveVolumes()->Last(); if (GetCurrentVolume() == stopVol) SetStopPropagation(); } if (fDoNothing) return; TGeoMaterial* material = GetCurrentVolume()->GetMaterial(); KVIonRangeTableMaterial* irmat = 0; // skip the process if the current material is unkown if ((irmat = fRangeTable->GetMaterial(material))) { KVString dname; Bool_t multi; TString absorber_name; Bool_t is_active = kFALSE; if (GetCurrentDetectorNameAndVolume(dname, multi)) { is_active = kTRUE; if (multi) { absorber_name.Form("%s/%s", dname.Data(), GetCurrentNode()->GetName()); is_active = absorber_name.Contains("ACTIVE_"); } else absorber_name = dname; } else absorber_name = irmat->GetName(); // Coordinates of the vector between the intersection point at the // focal plane and the point at the entrance of the current detector Double_t X = GetEntryPoint().X() - fOrigine.X(); Double_t Y = GetEntryPoint().Y() - fOrigine.Y(); Double_t Z = GetEntryPoint().Z() - fOrigine.Z(); // Norm of this vector. The signe gives an infomation about the detector position // (1: behind; -1: in front of) with respect to the focal plane. Double_t Delta = TMath::Sign(1., Z) * TMath::Sqrt(X * X + Y * Y + Z * Z); if ((fCalib & kECalib) || (fCalib & kTCalib)) { if (fE > 1e-3) { // velocity before material Double_t Vi = nuc->GetVelocity().Mag(); // energy lost in the material Double_t DE = irmat->GetLinearDeltaEOfIon( nuc->GetZ(), nuc->GetA(), fE, GetStepSize(), 0., material->GetTemperature(), material->GetPressure()); fE -= DE; nuc->SetEnergy(fE); //set flag to say that particle has been slowed down nuc->SetIsDetected(); // velocity after material Double_t Vf = nuc->GetVelocity().Mag(); if (fCalib & kTCalib) { //from current start point to the entrance point fTOF += (Delta - fStartPath) / Vi; fStartPath = Delta; //nuc->GetParameters()->SetValue(Form("TOF:%s",absorber_name.Data()), fTOF); if (is_active) nuc->GetParameters()->SetValue(Form("TOF:%s", dname.Data()), fTOF); else if ((fCalib & kFullTCalib) == kFullTCalib) nuc->GetParameters()->SetValue(Form("TOF:%s", absorber_name.Data()), fTOF); // from the entrance to the exit of the material Double_t step = GetStepSize(); fTOF += CalculateLinearDeltaT(Vi, Vf, step); fStartPath += step; } if (fCalib & kECalib) { if (is_active) nuc->GetParameters()->SetValue(Form("DE:%s", dname.Data()), DE); else if ((fCalib & kFullECalib) == kFullECalib) nuc->GetParameters()->SetValue(Form("DE:%s", absorber_name.Data()), DE); } } } if (is_active) nuc->GetParameters()->SetValue(Form("DPATH:%s", dname.Data()), Delta); else if ((fCalib & kFullTCalib) == kFullTCalib) nuc->GetParameters()->SetValue(Form("DPATH:%s", absorber_name.Data()), Delta); nuc->GetParameters()->SetValue(Form("STEP:%s", absorber_name.Data()), GetStepSize()); } }
KVDetector* KVGeoImport::GetCurrentDetector() { // Returns pointer to KVDetector corresponding to current location // in geometry. Detector is created and added to array if needed. // We also set up any geometry structure elements (from nodes beginning with "STRUCT_") KVString detector_name; Bool_t multilay; TGeoVolume* detector_volume = GetCurrentDetectorNameAndVolume(detector_name,multilay); // failed to identify current volume as part of a detector if(!detector_volume) return 0; // has detector already been built ? if not, do it now KVDetector* det = fArray->GetDetector(detector_name); if(!fCreateArray){ if(det){ // set matrix & shape for entrance window if not done yet if(!det->GetEntranceWindowMatrix()){ det->SetEntranceWindowMatrix(GetCurrentMatrix()); det->SetEntranceWindowShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // set matrix & shape for active layer det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } } } else { if(!det) { det = BuildDetector(detector_name, detector_volume); if(det) { // Setting the entrance window shape and matrix // ============================================ // for consistency, the matrix and shape MUST correspond // i.e. we cannot have the matrix corresponding to the entrance window // of a multilayer detector and the shape corresponding to the // whole detector (all layers) - otherwise, calculation of points // on detector entrance window will be false! // Info("GetCurrentDetector","Setting EW matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetEntranceWindowMatrix(GetCurrentMatrix()); det->SetEntranceWindowShape((TGeoBBox*)GetCurrentVolume()->GetShape()); TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // first layer of detector (or only layer) is also active layer // Info("GetCurrentDetector","and also setting active layer matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } fArray->Add(det); Int_t nstruc = CurrentStructures().GetEntries(); if(nstruc){ // Build and add geometry structure elements KVGeoStrucElement* ELEM = fArray; for(register int i=0;i<nstruc;i++){ KVGeoStrucElement* elem = (KVGeoStrucElement*)CurrentStructures()[i]; KVGeoStrucElement* nextELEM = ELEM->GetStructure(elem->GetName()); if(!nextELEM){ // make new structure nextELEM = new KVGeoStrucElement(elem->GetName(), elem->GetType()); nextELEM->SetNumber(elem->GetNumber()); ELEM->Add(nextELEM); } ELEM=nextELEM; } // add detector to last structure ELEM->Add(det); } } } else { // Detector already built, are we now in its active layer ? TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // Info("GetCurrentDetector","Setting active layer matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } } } return det; }