TGeoVolume* create_new_tof_module(Int_t modType) { Int_t cType = CounterTypeInModule[modType]; Float_t dx=Module_Size_X[modType]; Float_t dy=Module_Size_Y[modType]; Float_t dz=Module_Size_Z[modType]; Float_t width_aluxl=Module_Thick_Alu_X_left; Float_t width_aluxr=Module_Thick_Alu_X_right; Float_t width_aluy=Module_Thick_Alu_Y; Float_t width_aluz=Module_Thick_Alu_Z; Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left)/2; Float_t dxpos=CounterXDistance[modType]; Float_t startxpos=CounterXStartPosition[modType]; Float_t dzoff=CounterZDistance[modType]; Float_t rotangle=CounterRotationAngle[modType]; TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); TString moduleName = Form("module_%d", modType); TGeoBBox* module_box = new TGeoBBox("", dx/2., dy/2., dz/2.); TGeoVolume* module = new TGeoVolume(moduleName, module_box, boxVolMed); module->SetLineColor(kGreen); // set line color for the alu box module->SetTransparency(20); // set transparency for the TOF TGeoBBox* gas_box = new TGeoBBox("", (dx-(width_aluxl+width_aluxr))/2., (dy-2*width_aluy)/2., (dz-2*width_aluz)/2.); TGeoVolume* gas_box_vol = new TGeoVolume("gas_box", gas_box, noActiveGasVolMed); gas_box_vol->SetLineColor(kBlue); // set line color for the alu box gas_box_vol->SetTransparency(50); // set transparency for the TOF TGeoTranslation* gas_box_trans = new TGeoTranslation("", shift_gas_box, 0., 0.); module->AddNode(gas_box_vol, 0, gas_box_trans); for (Int_t j=0; j< NCounterInModule[modType]; j++){ //loop over counters (modules) Float_t zpos; if (0 == modType || 3 == modType || 4 == modType || 5 == modType) { zpos = dzoff *=-1; } else { zpos = 0.; } TGeoTranslation* counter_trans = new TGeoTranslation("", startxpos+ j*dxpos , 0.0 , zpos); TGeoRotation* counter_rot = new TGeoRotation(); counter_rot->RotateY(rotangle); TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans); } return module; }
drawFGT(TString volName="") { gSystem->Load("libGeom"); gSystem->Load("libGdml"); TGeoManager::Import("fgt.gdml"); gGeoManager->DefaultColors(); bool allSolid=true; char topVol[] ="volWorld"; //char topVol[] ="volDetEnclosure"; //char topVol[] ="volDetector"; //char topVol[] ="volMuIDDownstream"; //char topVol[] ="volMuIDBarrel"; //char topVol[] ="volRPCMod"; //char topVol[] ="volRPCTray_End"; //char topVol[] ="volECALDownstream"; //char topVol[] ="volECALUpstream"; //char topVol[] ="volBarrelECAL"; //char topVol[] ="volSBPlane"; //char topVol[] ="volSTT"; //char topVol[] ="volSTPlaneTarget"; //char topVol[] ="volSTPlaneRadiator"; //char topVol[] ="volTargetPlaneArgon"; gGeoManager->GetVolume("volDetEnclosure")->SetLineColor(kGray); gGeoManager->GetVolume("volDetEnclosure")->SetVisibility(1); gGeoManager->GetVolume("volDetEnclosure")->SetTransparency(20); gGeoManager->GetVolume("volDirtLayer")->SetTransparency(20); gGeoManager->GetVolume("volServiceBuilding")->SetLineColor(kGray); gGeoManager->GetVolume("volServiceBuilding")->SetVisibility(1); gGeoManager->GetVolume("volServiceBuilding")->SetTransparency(20); gGeoManager->GetVolume("volSky")->SetLineColor(kWhite); gGeoManager->GetVolume("volSky")->SetVisibility(1); gGeoManager->GetVolume("volSky")->SetTransparency(20); gGeoManager->GetVolume("volMagnet")->SetLineColor(kGreen-1); gGeoManager->GetVolume("volMagnet")->SetVisibility(1); if(!allSolid) gGeoManager->GetVolume("volMagnet")->SetTransparency(10); gGeoManager->GetVolume("volECALBarrelMod")->SetLineColor(kRed); gGeoManager->GetVolume("volECALBarrelMod")->SetVisibility(1); if(!allSolid) gGeoManager->GetVolume("volECALBarrelMod")->SetTransparency(75); gGeoManager->GetVolume("volSBPlane")->SetLineColor(kRed-3); gGeoManager->GetVolume("volSBPlane")->SetVisibility(1); if(!allSolid) gGeoManager->GetVolume("volSBPlane")->SetTransparency(80); /* gGeoManager->GetVolume("volECALUpstream")->SetLineColor(kYellow-3); gGeoManager->GetVolume("volECALUpstream")->SetVisibility(1); gGeoManager->GetVolume("volECALUpstream")->SetTransparency(20); gGeoManager->GetVolume("volECALDownstream")->SetLineColor(kYellow-3); gGeoManager->GetVolume("volECALDownstream")->SetVisibility(1); gGeoManager->GetVolume("volECALDownstream")->SetTransparency(20); */ TObjArray* va = gGeoManager->GetListOfVolumes(); int nv = va->GetEntries(); for (int i=0; i<nv; ++i) { TGeoVolume* v = (TGeoVolume*)va->At(i); std::string m(v->GetMaterial()->GetName()); //cout << v->GetMaterial()->GetName() << endl; int lc, vi, tr, vd; if (m == "Scintillator") { lc = kGreen-7 ; vi = 1; tr = 0; vd = 1; v->SetLineColor(lc); v->SetVisibility(vi); v->VisibleDaughters(vd); v->SetTransparency(tr); } //else { // continue; //std::cout << "'" << m << "' has no defaults" << std::endl; //lc = kOrange; vi = 0; tr = 50; vd = 1; //} } //gGeoManager->GetTopNode(); gGeoManager->CheckOverlaps(1e-5,"d"); gGeoManager->PrintOverlaps(); //gGeoManager->FindVolumeFast(topVol)->CheckOverlaps(1e-5,"d"); //gGeoManager->FindVolumeFast(topVol)->GetNode(0)->PrintOverlaps(); gGeoManager->SetMaxVisNodes(70000); gGeoManager->FindVolumeFast(topVol)->Draw("ogl"); TFile *tf = new TFile("drawFGT.root", "RECREATE"); gGeoManager->Write(); tf->Close(); }
TGeoVolume* create_new_counter(Int_t modType) { //glass Float_t gdx=Glass_X[modType]; Float_t gdy=Glass_Y[modType]; Float_t gdz=Glass_Z[modType]; //gas gap Int_t nstrips=NumberOfReadoutStrips[modType]; Int_t ngaps=NumberOfGaps[modType]; Float_t ggdx=GasGap_X[modType]; Float_t ggdy=GasGap_Y[modType]; Float_t ggdz=GasGap_Z[modType]; Float_t gsdx=ggdx/(Float_t)(nstrips); // electronics //pcb dimensions Float_t dxe=Electronics_X[modType]; Float_t dye=Electronics_Y[modType]; Float_t dze=Electronics_Z[modType]; Float_t yele=gdy/2.+dye/2.; // counter size (calculate from glas, gap and electronics sizes) Float_t cdx = TMath::Max(gdx, ggdx); cdx = TMath::Max(cdx, dxe)+ 0.2; Float_t cdy = TMath::Max(gdy, ggdy) + 2*dye + 0.2; Float_t cdz = ngaps * (gdz+ggdz) + gdz + 0.2; //calculate thickness and first position in coonter of single stack Float_t dzpos=gdz+ggdz; Float_t startzposglas=(-cdz+gdz)/2.; Float_t startzposgas=-cdz/2.+ gdz + ggdz/2.; // needed materials TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); // define counter volume TGeoBBox* counter_box = new TGeoBBox("", cdx/2., cdy/2., cdz/2.); TGeoVolume* counter = new TGeoVolume("counter", counter_box, noActiveGasVolMed); counter->SetLineColor(kCyan); // set line color for the counter counter->SetTransparency(70); // set transparency for the TOF // define single glass plate volume TGeoBBox* glass_plate = new TGeoBBox("", gdx/2., gdy/2., gdz/2.); TGeoVolume* glass_plate_vol = new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate glass_plate_vol->SetTransparency(20); // set transparency for the TOF // define single gas gap volume TGeoBBox* gas_gap = new TGeoBBox("", ggdx/2., ggdy/2., ggdz/2.); TGeoVolume* gas_gap_vol = new TGeoVolume("Gap", gas_gap, activeGasVolMed); gas_gap_vol->Divide("Cell",1,nstrips,-ggdx/2.,0); gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap gas_gap_vol->SetTransparency(99); // set transparency for the TOF // place 8 gas gaps and 9 glas plates in the counter for( Int_t igap = 0; igap < ngaps; igap++) { Float_t zpos_glas = startzposglas + igap*dzpos; Float_t zpos_gas = startzposgas + igap*dzpos; // cout <<"Zpos(Glas): "<< zpos_glas << endl; // cout <<"Zpos(Gas): "<< zpos_gas << endl; TGeoTranslation* glass_plate_trans = new TGeoTranslation("", 0., 0., zpos_glas); TGeoTranslation* gas_gap_trans = new TGeoTranslation("", 0., 0., zpos_gas); counter->AddNode(glass_plate_vol, igap, glass_plate_trans); counter->AddNode(gas_gap_vol, igap, gas_gap_trans); } Float_t zpos_glas = startzposglas + (ngaps+1)*dzpos; TGeoTranslation* glass_plate_trans = new TGeoTranslation("", 0., 0., zpos_glas); counter->AddNode(glass_plate_vol, ngaps, glass_plate_trans); // create and place the electronics above and below the glas stack TGeoBBox* pcb = new TGeoBBox("", dxe/2., dye/2., dze/2.); TGeoVolume* pcb_vol = new TGeoVolume("pcb", pcb, electronicsVolMed); pcb_vol->SetLineColor(kCyan); // set line color for electronics pcb_vol->SetTransparency(10); // set transparency for the TOF for (Int_t l=0; l<2; l++){ yele *= -1.; TGeoTranslation* pcb_trans = new TGeoTranslation("", 0., yele, 0.); counter->AddNode(pcb_vol, l, pcb_trans); } return counter; }
int main(int argc, char * argv[]) { TApplication app("app", &argc, argv); plottingEngine.SetDefaultStyle(); const bool debug = true; // Load the field map. ComponentAnsys123* fm = new ComponentAnsys123(); const std::string efile = "ELIST.lis"; const std::string nfile = "NLIST.lis"; const std::string mfile = "MPLIST.lis"; const std::string sfile = "PRNSOL.lis"; fm->Initialise(efile, nfile, mfile, sfile, "mm"); fm->EnableMirrorPeriodicityX(); fm->EnableMirrorPeriodicityY(); fm->PrintRange(); // Dimensions of the GEM const double pitch = 0.014; const double kapton = 50.e-4; const double metal = 5.e-4; const double outdia = 70.e-4; const double middia = 50.e-4; const bool plotField = false; if (plotField) { ViewField* fieldView = new ViewField(); fieldView->SetComponent(fm); fieldView->SetPlane(0., -1., 0., 0., 0., 0.); fieldView->SetArea(-pitch / 2., -0.02, pitch / 2., 0.02); fieldView->SetVoltageRange(-160., 160.); TCanvas* cF = new TCanvas(); fieldView->SetCanvas(cF); fieldView->PlotContour(); } // Setup the gas. MediumMagboltz* gas = new MediumMagboltz(); gas->SetComposition("ar", 70., "co2", 30.); gas->SetTemperature(293.15); gas->SetPressure(760.); gas->EnableDebugging(); gas->Initialise(); gas->DisableDebugging(); // Set the Penning transfer efficiency. const double rPenning = 0.57; const double lambdaPenning = 0.; gas->EnablePenningTransfer(rPenning, lambdaPenning, "ar"); // Load the ion mobilities. gas->LoadIonMobility("IonMobility_Ar+_Ar.txt"); // Associate the gas with the corresponding field map material. const int nMaterials = fm->GetNumberOfMaterials(); for (int i = 0; i < nMaterials; ++i) { const double eps = fm->GetPermittivity(i); if (fabs(eps - 1.) < 1.e-3) fm->SetMedium(i, gas); } fm->PrintMaterials(); // Create the sensor. Sensor* sensor = new Sensor(); sensor->AddComponent(fm); sensor->SetArea(-5 * pitch, -5 * pitch, -0.03, 5 * pitch, 5 * pitch, 0.03); AvalancheMicroscopic* aval = new AvalancheMicroscopic(); aval->SetSensor(sensor); AvalancheMC* drift = new AvalancheMC(); drift->SetSensor(sensor); drift->SetDistanceSteps(2.e-4); const bool plotDrift = true; ViewDrift* driftView = new ViewDrift(); if (plotDrift) { driftView->SetArea(-2 * pitch, -2 * pitch, -0.02, 2 * pitch, 2 * pitch, 0.02); // Plot every 10 collisions (in microscopic tracking). aval->SetCollisionSteps(10); aval->EnablePlotting(driftView); drift->EnablePlotting(driftView); } // Histograms int nBinsGain = 100; double gmin = 0.; double gmax = 100.; TH1F* hElectrons = new TH1F("hElectrons", "Number of electrons", nBinsGain, gmin, gmax); TH1F* hIons = new TH1F("hIons", "Number of ions", nBinsGain, gmin, gmax); int nBinsChrg = 100; TH1F* hChrgE = new TH1F("hChrgE", "Electrons on plastic", nBinsChrg, -0.5e4 * kapton, 0.5e4 * kapton); TH1F* hChrgI = new TH1F("hChrgI", "Ions on plastic", nBinsChrg, -0.5e4 * kapton, 0.5e4 * kapton); double sumIonsTotal = 0.; double sumIonsDrift = 0.; double sumIonsPlastic = 0.; double sumElectronsTotal = 0.; double sumElectronsPlastic = 0.; double sumElectronsUpperMetal = 0.; double sumElectronsLowerMetal = 0.; double sumElectronsTransfer = 0.; double sumElectronsOther = 0.; const int nEvents = 10; for (int i = nEvents; i--;) { if (debug || i % 10 == 0) std::cout << i << "/" << nEvents << "\n"; // Randomize the initial position. const double smear = pitch / 2.; double x0 = -smear + RndmUniform() * smear; double y0 = -smear + RndmUniform() * smear; double z0 = 0.025; double t0 = 0.; double e0 = 0.1; aval->AvalancheElectron(x0, y0, z0, t0, e0, 0., 0., 0.); int ne = 0, ni = 0; aval->GetAvalancheSize(ne, ni); hElectrons->Fill(ne); hIons->Fill(ni); const int np = aval->GetNumberOfElectronEndpoints(); double xe1, ye1, ze1, te1, e1; double xe2, ye2, ze2, te2, e2; double xi1, yi1, zi1, ti1; double xi2, yi2, zi2, ti2; int status; for (int j = np; j--;) { aval->GetElectronEndpoint(j, xe1, ye1, ze1, te1, e1, xe2, ye2, ze2, te2, e2, status); sumElectronsTotal += 1.; if (ze2 > -kapton / 2. && ze2 < kapton / 2.) { hChrgE->Fill(ze2 * 1.e4); sumElectronsPlastic += 1.; } else if (ze2 >= kapton / 2. && ze2 <= kapton / 2. + metal) { sumElectronsUpperMetal += 1.; } else if (ze2 <= -kapton / 2. && ze2 >= -kapton / 2. - metal) { sumElectronsLowerMetal += 1.; } else if (ze2 < -kapton / 2. - metal) { sumElectronsTransfer += 1.; } else { sumElectronsOther += 1.; } drift->DriftIon(xe1, ye1, ze1, te1); drift->GetIonEndpoint(0, xi1, yi1, zi1, ti1, xi2, yi2, zi2, ti2, status); if (zi1 < 0.01) { sumIonsTotal += 1.; if (zi2 > 0.01) sumIonsDrift += 1.; } if (zi2 > -kapton / 2. && zi2 < kapton / 2.) { hChrgI->Fill(zi2 * 1.e4); sumIonsPlastic += 1.; } } } double fFeedback = 0.; if (sumIonsTotal > 0.) fFeedback = sumIonsDrift / sumIonsTotal; std::cout << "Fraction of ions drifting back: " << fFeedback << "\n"; const double neMean = hElectrons->GetMean(); std::cout << "Mean number of electrons: " << neMean << "\n"; const double niMean = hIons->GetMean(); std::cout << "Mean number of ions: " << niMean << "\n"; std::cout << "Mean number of electrons on plastic: " << sumElectronsPlastic / nEvents << "\n"; std::cout << "Mean number of ions on plastic: " << sumIonsPlastic / nEvents << "\n"; std::cout << "Electron endpoints:\n"; const double fUpperMetal = sumElectronsUpperMetal / sumElectronsTotal; const double fPlastic = sumElectronsPlastic / sumElectronsTotal; const double fLowerMetal = sumElectronsLowerMetal / sumElectronsTotal; const double fTransfer = sumElectronsTransfer / sumElectronsTotal; const double fOther = sumElectronsOther / sumElectronsTotal; std::cout << " upper metal: " << fUpperMetal * 100. << "%\n"; std::cout << " plastic: " << fPlastic * 100. << "%\n"; std::cout << " lower metal: " << fLowerMetal * 100. << "%\n"; std::cout << " transfer: " << fTransfer * 100. << "%\n"; std::cout << " other: " << fOther * 100. << "%\n"; TCanvas* cD = new TCanvas(); const bool plotGeo = true; if (plotGeo && plotDrift) { // Build the geometry in Root. TGeoManager* geoman = new TGeoManager("world", "geometry"); TGeoMaterial* matVacuum = new TGeoMaterial("Vacuum", 0, 0, 0); TGeoMedium* medVacuum = new TGeoMedium("Vacuum", 1, matVacuum); TGeoMaterial* matKapton = new TGeoMaterial("Kapton", 12, 6, 1.42); TGeoMedium* medKapton = new TGeoMedium("Kapton", 2, matKapton); TGeoMaterial* matCopper = new TGeoMaterial("Copper", 63, 29, 8.94); TGeoMedium* medCopper = new TGeoMedium("Copper", 3, matCopper); TGeoVolume* volTop = geoman->MakeBox("TOP", medVacuum, pitch, pitch, 0.02); volTop->SetVisibility(0); TGeoBBox* shpKapton = new TGeoBBox("K", pitch / 2., pitch / 2., kapton / 2.); TGeoPcon* shpHole = new TGeoPcon("H", 0., 360., 3); shpHole->DefineSection(0, -kapton / 2., 0., outdia / 2.); shpHole->DefineSection(1, 0., 0., middia / 2.); shpHole->DefineSection(2, kapton / 2., 0., outdia / 2.); TGeoCompositeShape* shpGem = new TGeoCompositeShape("G", "K - H"); TGeoVolume* volKapton = new TGeoVolume("Kapton", shpGem, medKapton); volKapton->SetLineColor(kGreen); volKapton->SetTransparency(50); TGeoBBox* shpMetal = new TGeoBBox("M", pitch / 2., pitch / 2., metal / 2.); TGeoTube* shpTube = new TGeoTube("T", 0., outdia / 2., metal / 2.); TGeoCompositeShape* shpElectrode = new TGeoCompositeShape("E", "M - T"); TGeoVolume* volElectrode = new TGeoVolume("Electrode", shpElectrode, medCopper); volElectrode->SetLineColor(kBlue); volElectrode->SetTransparency(50); TGeoVolumeAssembly* volGem = new TGeoVolumeAssembly("Gem"); const double shift = 0.5 * (metal + kapton); volGem->AddNode(volKapton, 1); volGem->AddNode(volElectrode, 2, new TGeoTranslation(0., 0., shift)); volGem->AddNode(volElectrode, 3, new TGeoTranslation(0., 0., -shift)); volTop->AddNode(volGem, 1); volTop->AddNode(volGem, 2, new TGeoTranslation(-pitch, 0., 0.)); volTop->AddNode(volGem, 3, new TGeoTranslation(+pitch, 0., 0.)); volTop->AddNode(volGem, 4, new TGeoTranslation(-pitch / 2., sqrt(3) * pitch / 2., 0.)); volTop->AddNode(volGem, 5, new TGeoTranslation(+pitch / 2., sqrt(3) * pitch / 2., 0.)); volTop->AddNode(volGem, 6, new TGeoTranslation(-pitch / 2., -sqrt(3) * pitch / 2., 0.)); volTop->AddNode(volGem, 7, new TGeoTranslation(+pitch / 2., -sqrt(3) * pitch / 2., 0.)); geoman->SetVerboseLevel(0); geoman->SetTopVolume(volTop); geoman->CloseGeometry(); geoman->CheckOverlaps(0.1e-4); geoman->SetNmeshPoints(100000); cD->cd(); geoman->GetTopVolume()->Draw("ogl"); } if (plotDrift) { driftView->SetCanvas(cD); driftView->Plot(); } const bool plotHistogram = true; if (plotHistogram) { TCanvas* cH = new TCanvas("cH", "Histograms", 800, 700); cH->Divide(2, 2); cH->cd(1); hElectrons->Draw(); cH->cd(2); hIons->Draw(); cH->cd(3); hChrgE->Draw(); cH->cd(4); hChrgI->Draw(); } app.Run(kTRUE); }