void KVSpectroDetector::AddAbsorber(const Char_t* material, TGeoShape* shape, TGeoMatrix* matrix, Bool_t active){ // Add an absorber material defined as a daughter volume TGeoVolume. // This volume is defined by its material and its shape. // It is positioned by supplying a geometrical transformation, with // respect to the local reference frame of the detector. // By default the volume is referenced as "inactive". // If the volume is not the first absorber or if the matrix is not null // the volume is put in an assembly of volumes TGeoVolumeAssembly. // // Input: material - material of the absorber. The list of available // materials can be found with // det->GetRangeTable()->GetListOfMaterials()->ls() // where det is a KVSpectroDetector or another // object inheriting from KVMaterial. // If material is empty, the name of the detector // is used. // shape - shape of the volume. // matrix - matrix of the geometrical transformation. // active - kTRUE if the absorber is active, kFALSE othewise. TString vol_name; vol_name.Form("%s_%d_%s",GetName(),fNumVol++,material); TGeoVolume* vol = GetGeoVolume(vol_name.Data(), material, shape); if(!vol){ Error("AddAbsorber","Impossible to build the volume"); return; } AddAbsorber(vol,matrix,active); }
KVHarpeeSi::KVHarpeeSi(UInt_t number, Float_t thick) : KVVAMOSDetector(number, "Si") { // Make a silicon detector of Harpee. // Type of detector: "SI" // Label of detector: "SI" init(); SetType("SI"); SetLabel("SI"); SetName(GetArrayName()); Float_t w = 1.; // width Float_t h = 1.; // height Float_t th = thick * KVUnits::um; // thickness Double_t dx = w / 2; Double_t dy = h / 2; Double_t dz = th / 2; fTotThick += th; // adding the absorber TGeoShape* shape = new TGeoBBox(dx, dy, dz); AddAbsorber("Si", shape, 0, kTRUE); }
KVBIC::KVBIC(Float_t pressure, Float_t bomb): KVChIo() { //BIC detector. //Give pressure in Torr // //Segmentation index = 1 //because particles passing through BIC can only hit 1 detector - SIB - behind it //this is analogous to the Si-CsI telescopes of ring 1. //The type of these detectors is "BIC" //Pressure units are Torr SetType("BIC"); SetSegment(1); fLinCal = 0; fBomb = bomb; //build detector AddAbsorber(new KVMaterial("Myl", 1.5 * KVUnits::um)); //mylar entry window Float_t e = GetEffectiveEntryThickness(); KVMaterial* gas = new KVMaterial("CF4", e * KVUnits::mm, pressure); AddAbsorber(gas); //gas between two windows AddAbsorber(new KVMaterial("Myl", 1.0 * KVUnits::um)); //interior window gas = new KVMaterial("CF4", 60 * KVUnits::mm, pressure); AddAbsorber(gas); //main body of gas SetActiveLayer(gas); //active layer - energy loss is measured AddAbsorber(new KVMaterial("Myl", 1.0 * KVUnits::um)); //2nd interor window gas = new KVMaterial("CF4", e * KVUnits::mm, pressure); AddAbsorber(gas); //gas between two exit windows AddAbsorber(new KVMaterial("Myl", 1.5 * KVUnits::um)); //exit window }
//______________________________________________________________________________ KVChIo::KVChIo(Float_t pressure, Float_t thick):KVINDRADetector("Myl", 2.5*KVUnits::um) { // Make an INDRA ChIo: 2.5micron mylar windows enclosing 'thick' cm of C3F8, // give gas pressure in mbar // By default 'thick'=5cm // The type of these detectors is "CI" //gas layer KVMaterial *mat = new KVMaterial("C3F8", thick, pressure*KVUnits::mbar); AddAbsorber(mat); SetActiveLayer(mat); //gas is the active layer // mylar for second window mat = new KVMaterial("Myl", 2.5*KVUnits::um); AddAbsorber(mat); SetType("CI"); init(); }
Bool_t KVSpectroDetector::BuildGeoVolume(TEnv *infos, TGeoVolume *ref_vol){ // Build the detector geometry (i.e. the volumes) from informations loaded // in a TEnv object. // // If the detector has already a volume, i.e. the detector is // already built then this method does nothing. // The volumes will be placed inside the ref_vol if it is given in input. if(GetAbsGeoVolume()){ Error("BuildGeoFromFile","Volume already existing"); return kFALSE; } const Char_t *infotype[] = {"NABS","WIDTH","HEIGHT","X","Y","Z"}; Binary8_t errorbit; Int_t Nbit = 0; TString miss; Int_t Nabs = GetDetectorEnv(infotype[Nbit++],-1,infos); if(Nabs < 0 ) errorbit.SetBit(Nbit-1); Double_t width = GetDetectorEnv(infotype[Nbit++],-1.,infos); if(width < 0 ) errorbit.SetBit(Nbit-1); Double_t height = GetDetectorEnv(infotype[Nbit++],-1.,infos); if(height < 0 ) errorbit.SetBit(Nbit-1); Double_t pos[3]; // X, Y, Z of the detector origine in the reference volume // This positions have to be present if ref_vol is defined if( ref_vol ){ for(Int_t i=0; i<3; i++){ pos[i] = GetDetectorEnv(infotype[Nbit++],-666.,infos); if( pos[i] <= -666 ) errorbit.SetBit(Nbit-1); } } // check if main informations are not missing if( errorbit.Value() ){ for(Int_t i=0; i<Nbit; i++){ if( !errorbit.TestBit(i) ) continue; miss += ( miss.IsNull() ? "" : "; " ); miss += infotype[i]; } Error("BuildGeoVolume","Missing geometry informations (%s) for detector %s", miss.Data(), GetName()); return kFALSE; } KVNumberList activeabs( GetDetectorEnv("ACTIVEABS","",infos) ); Double_t thick_tot = 0; Double_t thick[Nabs]; TString mat[Nabs], type; miss = ""; // look at information concerning layers (thickness, material, ...) for(Int_t i=0; i<Nabs; i++){ type.Form("ABS.%d.MATERIAL",i+1); mat[i] = GetDetectorEnv(type.Data(),"",infos); if(mat[i].IsNull() ){ miss += ( miss.IsNull() ? "" : "; " ); miss += type; } type.Form("ABS.%d.THICK",i+1); thick[i] = GetDetectorEnv(type.Data(),-1.,infos); if(thick[i] < 0 ) { miss += ( miss.IsNull() ? "" : "; " ); miss += type; } thick_tot+= thick[i]; } if( !miss.IsNull() ){ Error("BuildGeoVolume","Missing geometry informations (%s) for absorbers of detector %s", miss.Data(), GetName()); return kFALSE; } // build volumes TGeoShape *shape = NULL; TString tmp; for(Int_t i=0; i<Nabs; i++){ fTotThick+=thick[i]; // box shape of the absorber shape = new TGeoBBox( width/2, height/2, thick[i]/2 ); // build and position absorber in mother volume. // Reference is the center of absorber Double_t ztrans = (thick[i]-thick_tot)/2; for(Int_t j=0; j<Nabs-1;j++) ztrans+= (j<i)*thick[j]; tmp.Form( "%s_mat%d_tr", GetName(), i+1 ); TGeoTranslation* tr = ( ztrans ? new TGeoTranslation(tmp.Data(), 0.,0.,ztrans) : NULL ); AddAbsorber(mat[i].Data(),shape,tr, activeabs.Contains( i+1 )); } // incline of the detector around X axis Double_t Xincline = GetDetectorEnv("INCLINE.X",0.,infos); if( Xincline ){ TGeoVolume *vol_as= gGeoManager->MakeVolumeAssembly(Form("%s_%d",GetName(),fNumVol++)); tmp.Form( "%s_rot_x", GetName() ); TGeoRotation *rot = new TGeoRotation( tmp.Data(), 0. , Xincline, 0. ); vol_as->AddNode( GetAbsGeoVolume(), 1, rot ); SetAbsGeoVolume( vol_as ); } UpdateVolumeAndNodeNames(); if( !ref_vol ) return kTRUE; Double_t ref_pos[3]; // Xref, Yref, Zref for(Int_t i=0; i<3; i++){ type.Form("REF.%c",'X'+i); ref_pos[i] = GetDetectorEnv(type.Data(),0.,infos); pos[i] -= ref_pos[i]; } // place the detector in the reference volume 'ref_vol' tmp.Form( "%s_tr", GetName() ); TGeoTranslation* ref_tr = new TGeoTranslation( tmp.Data(), pos[0], pos[1], pos[2] ); ref_vol->AddNode( GetAbsGeoVolume(), 1, ref_tr ); // Set at this last node the name of the volume // otherwise the detector name returned by a KVGeoNavigator will have an // extra number at the end (corresponding to the number of the node) ((TGeoNodeMatrix* )ref_vol->GetNodes()->Last())->SetName( GetAbsGeoVolume()->GetName() ); return kTRUE; }
KVHarpeeIC::KVHarpeeIC(UInt_t number, Float_t pressure, Float_t temp, Float_t thick) : KVVAMOSDetector(number, "C4H10") { // Make the ionisation chamber of Harpee composed by: // - one 1.5 mylar window; // - 3 volumes of C4H10 with thicknesses (2*dz): 2.068 cm, thick, 1.278 cm. // By default thick=10.457 cm; // Only the 2nd gaz volume is "active". // // The width (2*dx) of this detector is ??? and the height (2*dy) is ???. // The ionisation chamber is closed with the silicon wall in Harpee. // // Input: pressure - pressure of the gaz in mbar // temp - temperature of the gaz in degrees celsius. // Default temperature = 19°C // thick - the thickness in cm of the 2nd volume of gaz. Warning("KVHarpeeIC", "Check if the width, the height and the thickness are correct in this constructor"); init(); SetType("CHI"); SetLabel("CHI"); SetName(GetArrayName()); // number of absorber Int_t Nabs = 4; // material of each absorber const Char_t* mat[] = {"Myl", "C4H10", "C4H10", "C4H10"}; // thickness of each absorber Float_t th[] = { static_cast<Float_t>(1.5 * KVUnits::um), static_cast<Float_t>(2.068 * KVUnits::cm), static_cast<Float_t>(thick * KVUnits::cm), static_cast<Float_t>(1.278 * KVUnits::cm) }; // active absorber flag Bool_t active[] = { kFALSE, kFALSE, kTRUE, kFALSE}; // width and height of the detector. TO BE VERIFIED Float_t w = 40 * KVUnits::cm; Float_t h = 12 * KVUnits::cm; // total thickness of the detector Float_t wtot = 0; for (Int_t i = 0; i < Nabs; i++) wtot += th[i]; // pressure and temperature of the detector SetPressure(pressure * KVUnits::mbar); SetTemperature(temp); // Adding the absorbers TGeoShape* shape = NULL; for (Int_t i = 0; i < Nabs; i++) { Double_t dx = w / 2; Double_t dy = h / 2; Double_t dz = th[i] / 2; fTotThick += th[i]; // box shape of the absorber shape = new TGeoBBox(dx, dy, dz); // build and position absorber in mother volume. // Reference is the center of absorber Double_t ztrans = dz - wtot / 2; for (Int_t j = 0; j < Nabs - 1; j++) ztrans += (j < i) * th[j]; TGeoTranslation* tr = new TGeoTranslation(0., 0., ztrans); AddAbsorber(mat[i], shape, tr, active[i]); } }