Пример #1
0
void KVSpectroDetector::AddAbsorberLayer( TGeoVolume *vol, Bool_t active){
 	// Add an absorber layer to the detector made from the shape of the
 	// volume.
    // If active = kTRUE the layer is set active.

    TGeoMaterial* material = vol->GetMaterial();
    KVIonRangeTableMaterial* irmat = KVMaterial::GetRangeTable()->GetMaterial(material);
    if(!irmat){
        Warning("AddAbsorberLayer", "Unknown material %s/%s used in layer %s of detector %s",
                material->GetName(), material->GetTitle(), vol->GetName(), GetName());
        return;
    }
    TGeoBBox* sh = dynamic_cast<TGeoBBox*>(vol->GetShape());
    if(!sh) {
        Warning("AddAbsorberLayer", "Unknown shape class %s used in layer %s of detector %s",
                vol->GetShape()->ClassName(), vol->GetName(), GetName());
        return; // just in case - for now, all shapes derive from TGeoBBox...
    }
    Double_t width = 2.*sh->GetDZ(); // thickness in centimetres
    KVMaterial* absorber;
    if( irmat->IsGas() ){
        Double_t p = material->GetPressure();
        Double_t T = material->GetTemperature();
        absorber = new KVMaterial(irmat->GetType(), width, p, T);
    }
    else
        absorber = new KVMaterial(irmat->GetType(), width);
	KVDetector::AddAbsorber(absorber);
	ClearHits();
    if( active ) SetActiveLayer( GetListOfAbsorbers()->GetEntries()-1 );
}
Пример #2
0
void KVGeoImport::AddLayer(KVDetector *det, TGeoVolume *vol)
{
    // Add an absorber layer to the detector
    // Volumes representing 'active' layers in detectors must have names
    // which begin with "ACTIVE_"

    TString vnom = vol->GetName();
    // exclude dead zone layers
    if(vnom.BeginsWith("DEADZONE")) return;
    TGeoMaterial* material = vol->GetMaterial();
    KVIonRangeTableMaterial* irmat = fRangeTable->GetMaterial(material);
    if(!irmat){
        Warning("AddLayer", "Unknown material %s/%s used in layer %s of detector %s",
                material->GetName(), material->GetTitle(), vol->GetName(), det->GetName());
        return;
    }
    TGeoBBox* sh = dynamic_cast<TGeoBBox*>(vol->GetShape());
    if(!sh) {
        Warning("AddLayer", "Unknown shape class %s used in layer %s of detector %s",
                vol->GetShape()->ClassName(), vol->GetName(), det->GetName());
        return; // just in case - for now, all shapes derive from TGeoBBox...
    }
    Double_t width = 2.*sh->GetDZ(); // thickness in centimetres
    KVMaterial* absorber;
    if( irmat->IsGas() ){
        Double_t p = material->GetPressure();
        Double_t T = material->GetTemperature();
        absorber = new KVMaterial(irmat->GetType(), width, p, T);
    }
    else
        absorber = new KVMaterial(irmat->GetType(), width);
    det->AddAbsorber(absorber);
    if(vnom.BeginsWith("ACTIVE_")) det->SetActiveLayer( det->GetListOfAbsorbers()->GetEntries()-1 );
}
Пример #3
0
void KVIonRangeTable::SetTemperatureAndPressure(const Char_t*material, Double_t temperature, Double_t pressure)
{
   // Set temperature (in degrees celsius) and pressure (in torr) for a given
   // material. This has no effect except for gaseous materials, for which T & P
   // determine the density (in g/cm**3).

   KVIonRangeTableMaterial* M = GetMaterial(material);
   if (M) M->SetTemperatureAndPressure(temperature, pressure);
}
Пример #4
0
Double_t KVIonRangeTable::GetZ(const Char_t* material)
{
   // Return atomic number of a material in the range table.
   // "material" can be either the type or the name of the material.
   // Prints a warning and returns 0 if material is unknown.

   KVIonRangeTableMaterial* M = GetMaterial(material);
   if (!M) {
      Warning("GetZ", "Material %s is unknown. Returned Z = 0.", material);
      return 0.0;
   }
   return M->GetZ();
}
Пример #5
0
TObjArray* KVRangeYanez::GetListOfMaterials()
{
   // Create and fill a list of all materials for which range tables exist.
   // Each entry is a TNamed with the name and type (title) of the material.
   // User's responsibility to delete list after use (it owns its objects).

   TObjArray* list = new TObjArray(fMaterials->GetEntries());
   list->SetOwner(kTRUE);
   TIter next(fMaterials);
   KVIonRangeTableMaterial* mat;
   while ((mat = (KVIonRangeTableMaterial*)next())) {
      list->Add(new TNamed(mat->GetName(), mat->GetType()));
   }
   return list;
}
Пример #6
0
void KVRangeYanez::AddElementalMaterial(Int_t z, Int_t a)
{
   // Adds a material composed of a single isotope of a chemical element.
   // If the isotope (a) is not specified, we create a material containing the naturally
   // occuring isotopes of the given element, weighted according to their abundance.
   // If the mass is given, the material symbol will be "AX" where X is the symbol for the element
   //    e.g. "48Ca",  "124Sn", etc.
   // and the material name will be "Xxx-A" where Xxx is the name of the element
   //    e.g. "Calcium-48", "Tin-124", etc.
   // Otherwise, we just use the element symbol and name for naturally-occurring
   // mixtures of atomic elements ("Ca", "Calcium", etc.).

   KVIonRangeTableMaterial* mat;
   if (!a) {
      mat = MakeNaturallyOccuringElementMixture(z);
   } else {
      if (!gNDTManager) {
         Error("AddElementalMaterial",
               "Nuclear data tables have not been initialised");
         return;
      }
      KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, a, "ElementDensity");
      if (!ed) {
         Error("AddElementalMaterial",
               "No element found in ElementDensity NDT-table with Z=%d", z);
         return;
      }
      TString state = "solid";
      if (ed->IsGas()) state = "gas";
      mat = new KVRangeYanezMaterial(this, Form("%s-%d", ed->GetElementName(), a),
                                     Form("%d%s", a, ed->GetElementSymbol()),
                                     state, ed->GetValue(), z, a);
      mat->Initialize();
   }
   CheckMaterialsList();
   fMaterials->Add(mat);
   mat->ls();
}
KVIonRangeTableMaterial::KVIonRangeTableMaterial(const KVIonRangeTableMaterial& obj)  : KVBase(),
   fTable(0),
   fState("unknown"),
   fComposition(0),
   fCompound(kFALSE),
   fMixture(kFALSE),
   fDens(0.),
   fZmat(0),
   fAmat(0),
   fMoleWt(0),
   fDeltaE(0),
   fEres(0),
   fRange(0),
   fStopping(0)
{
   // Copy constructor
   // This ctor is used to make a copy of an existing object (for example
   // when a method returns an object), and it is always a good idea to
   // implement it.
   // If your class allocates memory in its constructor(s) then it is ESSENTIAL :-)

   obj.Copy(*this);
}
Пример #8
0
TGeoMedium* KVSpectroDetector::GetGeoMedium(const Char_t* mat_name){
	// By default, return pointer to TGeoMedium corresponding to this KVMaterial.
	// If argument "mat_name" is given, a pointer to a medium is return for this material.
	// mat_name = "Vacuum" is a special case: if the "Vacuum" does not exist, we create it.
	//
	// Instance of geometry manager class TGeoManager must be created before calling this
	// method, otherwise 0x0 will be returned.
	// If the required TGeoMedium is not already available in the TGeoManager, we create
	// a new TGeoMedium corresponding to the material given in argument.

	if( !gGeoManager ) return NULL;


   	TString medName, matName;
	if( !strcmp(mat_name,"") ){
   		// for gaseous materials, the TGeoMedium/Material name is of the form
   		//      gasname_pressure
   		// e.g. C3F8_37.5 for C3F8 gas at 37.5 torr
   		// each gas with different pressure has to have a separate TGeoMaterial/Medium
   		matName = GetName();
    	KVIonRangeTableMaterial* irmat = KVMaterial::GetRangeTable()->GetMaterial(matName.Data());
   		if(irmat->IsGas()) medName.Form("%s_%f", matName.Data(), GetPressure());
   		else medName = GetName();
  	} 
	else{
		matName = mat_name;
		medName = mat_name;
 	}

	TGeoMedium* gmed = gGeoManager->GetMedium( medName);
	if( gmed ) return gmed;

	TGeoMaterial *gmat = gGeoManager->GetMaterial( medName);
	if( !gmat ){
 		if( !strcmp(matName.Data(), "Vacuum") ){
			// create material
			gmat = new TGeoMaterial("Vacuum",0,0,0 );
		}
		else{
			// create material
			gmat = GetRangeTable()->GetTGeoMaterial(matName.Data());
			if(!gmat){
				Error("GetGeoMedium","Material %s is nowhere to be found in %s"
						,matName.Data(),GetRangeTable()->GetName());
				return NULL;
			}
			gmat->SetPressure( GetPressure() );
			gmat->SetTemperature( GetTemperature() );
			gmat->SetTransparency(0);
      	}
	}

	// For the moment the names of material and medium do not
	// depend on the temperature of the material.
	gmat->SetName(medName);
    gmat->SetTitle(matName);

	// create medium
	TGeoMedium* lastmed = (TGeoMedium*)gGeoManager->GetListOfMedia()->Last();
	Int_t numed = (lastmed ? lastmed->GetId()+1 : 0); // static counter variable used to number media
	gmed = new TGeoMedium( medName, numed, gmat );
	numed+=1;

	return gmed;
}
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());

   }
}