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;
}
Esempio n. 2
0
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;

}
Esempio n. 4
0
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);

}