示例#1
0
//_______________________________________________________________________________________
void MakeFourView(TVirtualPad *pad=0)
{
//  Creates 4 pads view of the pad (or qPad)
//   ------------------------------
//   |              |             |
//   |              |             |
//   |              |             |
//   |    Front     |   Top       |
//   |    view      |   view      |
//   |              |             |
//   |              |             |
//   |              |             |
//   ---------------+-------------
//   |              |             |
//   |              |             |
//   |              |             |
//   |    Side      |  Spacial    |
//   |    view      |   view      |
//   |              |             |
//   |              |             |
//   |              |             |
//   ------------------------------
// begin_html  <P ALIGN=CENTER> <IMG SRC="gif/FourStarView.gif" ></P> end_html
//
  TVirtualPad *thisPad = pad;
  if (!thisPad) thisPad = qPad();
  TView *view = 0; 
  TList *thisPrimitives = 0; 
  if (thisPad && (thisPrimitives = thisPad->GetListOfPrimitives()) && (view =  thisPad->GetView()) ) 
  {
    Double_t min[3],max[3];
    view->GetRange(min,max);
    Int_t system = view->GetSystem();
    TCanvas *c = new TCanvas(" 4 views", thisPad->GetTitle(),600,600);
    c->Divide(2,2);
    TIter *next=  new TIter(thisPrimitives);
    for (int i =1; i <= 4; i++) {
      c->cd(i);
      TList *newPrimitives = qPad()->GetListOfPrimitives();
      TObject *obj = 0;
      while (obj = next->Next()) newPrimitives->Add(obj);
      TView *newView = new TView(system);
      newView->SetRange(min,max);
      next->Reset();
   }
   delete next;
   // set separate view;
   // Fron view
    Int_t j = 1;
    c->cd(j++); FrontView();
    c->cd(j++); TopView();
    c->cd(j++); SideView();
    c->cd(j++); RotateView(-30.0,60.0,0);
    c->Modified();
    c->Update();
  }
}
示例#2
0
文件: pl3.C 项目: camsonne/g4sbsDDVCS
 void pl3() {
      TCanvas *c1 = new TCanvas("c1");
      TView *view = TView::CreateView(1);
      view->SetRange(0,0,0,2,2,2);
      const Int_t n = 100;
      TPolyLine3D *l = new TPolyLine3D(n);
      for (Int_t i=0;i<n;i++) {
         Double_t x = 2*gRandom->Rndm();
         Double_t y = 2*gRandom->Rndm();
         Double_t z = 2*gRandom->Rndm();
         l->SetPoint(i,x,y,z);
      }
      l->Draw();
   }
void drawing_pion_decay(){

	double Pi_lifetime = 0.26033e-6; //s
	double c = 3e8;//m/s
	TCanvas *c1 = new TCanvas("test", "test");
	TRandom *r = new TRandom();
	

	TView *view = TView::CreateView(1, 0, 0);
	view->ShowAxis();
	view->SetRange(-5, -5, 0, 5, 5, 10);
	
	

	for (int i = 0; i < 100; ++i)
	{
		double px = 0.3;
		double py = 0.3;
		double pz = -1; // GeV
		double energy = sqrt(px*px+py*py+pz*pz+M_pion*M_pion);
		
		//life time
		double t = r->Exp(Pi_lifetime);
		//decay length
		double gamma = energy/M_pion;
		double length = c*t*gamma/1e3;
		// decay position
		double vx = 0;
		double vy = 0;
		double vz = 10 - length;

		TLorentzVector pion(px, py, pz, energy);

		double decay_particle_mass[2] = {M_muon, M_neu};
		TGenPhaseSpace event;
		event.SetDecay(pion, 2, decay_particle_mass);
		event.Generate();

		TLorentzVector Muon = *(event.GetDecay(0));
		TLorentzVector Neu = *(event.GetDecay(1));
		
		plot_particle(Muon, vx, vy, vz, 2);
		plot_particle(Neu, vx, vy, vz, 4);


	}


}
示例#4
0
//_______________________________________________________________________________________
static void Inscrease3DScale()
{
  TVirtualPad *thisPad = qPad();
  if (thisPad) {
    TView *view = thisPad->GetView(); 
    if (!view) return;
    Double_t min[3],max[3];
    view->GetRange(min,max);
    int i;
    for (i=0;i<3; i++) {max[i] *= 0.8; min[i]=max[i]*0.1;}
    view->SetRange(min,max);
    thisPad->Modified();
    thisPad->Update();
  }
}
示例#5
0
//_______________________________________________________________________________________
static void Centered3DImages()
{
  // This macro prints out the sizes of the sekected 3d pad
  TVirtualPad *thisPad = qPad();
  if (thisPad) {
    TView *view = thisPad->GetView(); 
    if (!view) return;
    Double_t min[3],max[3];
    view->GetRange(min,max);
    int i;
    for (i=0;i<3; i++) min[i]=-max[i];
    view->SetRange(min,max);
    thisPad->Modified();
    thisPad->Update();
 }
}
示例#6
0
//_______________________________________________________________________________________
static void AdjustScales()
{
  TVirtualPad *thisPad = qPad();
  if (thisPad) {
    TView *view = thisPad->GetView(); 
    if (!view) return;
    Double_t min[3],max[3];
    view->GetRange(min,max);
    int i;
    Double_t maxSide = 0;
    // Find the largest side
    for (i=0;i<3; i++) maxSide = TMath::Max(maxSide,max[i]-min[i]);
    //Adjust scales:
    for (i=0;i<3; i++) max[i] += maxSide - (max[i]-min[i]);
    view->SetRange(min,max);
    thisPad->Modified();
    thisPad->Update();
 }
}
示例#7
0
void spheres(Int_t nspheres=20, Int_t npoints=100000) {
   // generate random points uniformly distributed over the surface
   // of spheres generated at random positions.

   TCanvas *c1 = new TCanvas("c1","spheres",600,600);
   c1->SetFillColor(kBlack);
   TView *view = new TView(1);
   Double_t k=0.8;
   view->SetRange( -k, -k, -k, k, k, k);
   
   //generate sphere coordinates and radius
   TRandom r;
   if (nspheres <=0) nspheres = 10;
   Double_t *xs = new Double_t[nspheres];
   Double_t *ys = new Double_t[nspheres];
   Double_t *zs = new Double_t[nspheres];
   Double_t *rs = new Double_t[nspheres];
   Int_t i;
   for (i=0;i<nspheres;i++) {
      xs[i] = r.Uniform(-1,1);
      ys[i] = r.Uniform(-1,1);
      zs[i] = r.Uniform(-1,1);
      rs[i] = r.Uniform(0.05,0.25);
   }

   //generate points
   TPolyMarker3D *pm = new TPolyMarker3D(npoints);
   pm->SetMarkerColor(kRed);
   Double_t x,y,z;
   for (Int_t j=0;j<npoints;j++) {
       i = (Int_t)r.Uniform(0,nspheres);  //choose sphere
       r.Sphere(x,y,z,rs[i]);
       pm->SetPoint(j,xs[i]+x, ys[i]+y,zs[i]+z);
   }
   
   delete [] xs;
   delete [] ys;
   delete [] zs;
   delete [] rs;
    
   pm->Draw();
}
示例#8
0
void RootWImage::setCanvas(TCanvas* myCanvas) {
  if (myCanvas_) delete myCanvas_;
  myCanvas_ = (TCanvas*)myCanvas->DrawClone();
  std::ostringstream canvasName("");
  //int myNumber = imageNameCounter_[name_]++; //##########
  canvasName << "canvas" << setfill('0') << setw(3) << imageCounter_;
  myCanvas_->SetName(canvasName.str().c_str());
  TView* myView = myCanvas->GetView();
  if (myView) {
    TView* newView = myCanvas_->GetView();
    if (newView) {
      double min[3], max[3];
      Int_t irep;
      newView->SetView(myView->GetLongitude(),
		       myView->GetLatitude(),
		       myView->GetPsi(), irep);
      myView->GetRange(min, max);
      newView->SetRange(min, max);
    }
  }
}
示例#9
0
文件: sphere.C 项目: omazapa/RootMpi
void sphere()
{
   /********************/
   /*Mpi initialization*/
   /********************/
   ROOT::Mpi::TEnvironment env(gApplication->Argc(), gApplication->Argv());
   ROOT::Mpi::TIntraCommunicator world;

   /*********************************/
   /*Error control, need 4 processes*/
   /*********************************/   
   if(world.Size()!=4)
   {
      std::cout<<"Error: You need run with 4 processes exactly, the sphere was spplitted in four regions. \nExample: mpirun -np 4 root -l  sphere.C\n";
      std::cout.flush();
      world.Abort(ROOT::Mpi::ERR_SIZE);  
   }
   
   /*********************************************************************/
   /*Section to calculate volume with parallel multimensional integrator*/
   /*********************************************************************/   
   //integrator creation root's style
   ROOT::Math::Functor1D function(&sphere_function);

   ROOT::Math::Integrator integrator;
   integrator.SetFunction(function);

   //Mpi's integrator wrapper, integrator from ROOT in one dimension
   ROOT::Mpi::Math::TIntegratorWrapper MpiIntegrator(&integrator);

   //integrate in parallel and send the result to rank zero, intervar [0,radius]
   MpiIntegrator.Integrate(0, 0, radius);

   
   /*****************************************************************************************/
   /*this is the root process,calculate the surface z=+qsrt(1−(x2+b2)) for x∈[−1,0],y∈[−1,1]*/
   /*and recv the other surface regions in TPolyMarker3D object from others ranks           */
   /*****************************************************************************************/
   if (world.Rank() == 0) {
      gBenchmark->Start("sphere");
      // create and open a canvas
      TCanvas *canvas = new TCanvas("sphere", "sphere", 300, 10, 700, 500);
      canvas->SetFillColor(14);
      // creating view
      TView *view = TView::CreateView(1, 0, 0);
      view->RotateView(90,-10);
      view->SetRange(-radius*2, -radius*2, -2*radius, 2*radius, 2*radius, 2*radius);
      // create a PolyMarker3D for region/segment 1 calculate in rank 0(this rank)
      TPolyMarker3D *surfaceSeg13d = new TPolyMarker3D();
      
      for (theta = 0; theta <0.5*M_PI ; theta+= delta) {
         for (phi = 0; phi <M_PI; phi += delta) {
	   
	   x=radius*cos(theta)*sin(phi);
	   y=radius*sin(theta)*sin(phi);
	   z=radius*cos(phi);
            // set points
            surfaceSeg13d->SetPoint(point, x, y, z);
            point++;
         }
      }
      // set marker size, color & style
      surfaceSeg13d->SetMarkerSize(1);
      surfaceSeg13d->SetMarkerColor(world.Rank() + world.Size());
      surfaceSeg13d->SetMarkerStyle(1);
      //drawing region 1
      surfaceSeg13d->Draw();

      //getting region 2 from rank 1
      TPolyMarker3D *surfaceSeg23d = new TPolyMarker3D;
      world.RecvObject(1, 1, *surfaceSeg23d);
      surfaceSeg23d->Draw();

      //getting region 3 from rank 2
      TPolyMarker3D *surfaceSeg33d = new TPolyMarker3D;
      world.RecvObject(2, 1, *surfaceSeg33d);
      surfaceSeg33d->Draw();

      //getting region 4 from rank 3
      TPolyMarker3D *surfaceSeg43d = new TPolyMarker3D;
      world.RecvObject(3, 1, *surfaceSeg43d);
      surfaceSeg43d->Draw();

      Char_t timeStr[60];
      Char_t pointsStr[100];
      Char_t radiusStr[100];
      Char_t deltaStr[100];
      gBenchmark->Show("sphere");

      Float_t ct = gBenchmark->GetCpuTime("sphere");
      sprintf(timeStr, "Execution time: %g sec.", ct);
      sprintf(radiusStr, "Radius : %g", radius);
      sprintf(deltaStr, "Delta : %g", delta);
      sprintf(pointsStr, "Total surface points : %g", point*4);
      
      TPaveText *text = new TPaveText(0.1, 0.6, 0.9, 0.99);
      text->SetFillColor(42);
      text->AddText("ROOTMpi example: sphere.C");
      text->AddText(timeStr);
      text->AddText(radiusStr);
      text->AddText(deltaStr);
      text->AddText(pointsStr);
      text->Draw();
      
      //sphere volume  V=(4/3)*pi*r3
      //and compare the result integration's volume
      Char_t volumeStr[100];
      Double_t volume= MpiIntegrator.Result();
      Double_t volumeTeo=(4/3.0)*M_PI*(radius*radius*radius);
      
      sprintf(volumeStr, "Volumen with integration = %.15g \nVolumen with (4/3)*pi*r3 = %.15g", volume,volumeTeo);
      
      TPaveText *volumeText = new TPaveText(-0.1, -0.81, -0.9, -0.97);
      volumeText->SetFillColor(41);
      volumeText->SetTextAlign(11);
      volumeText->AddText(volumeStr);
      volumeText->Draw();
   }
   /*************************************************************************/
   /*this rank calculate the surface for theta ∈[0.5pi,pi] and phi ∈[0,pi]  */
   /*and send the surface regions in TPolyMarker3D object to rank root zero */
   /*************************************************************************/
   if (world.Rank() == 1) {
      TPolyMarker3D *surfaceSeg23d = new TPolyMarker3D();

      for (theta = 0.5*M_PI; theta <M_PI ; theta+= delta) {
         for (phi = 0; phi <M_PI; phi += delta) {
	   
	   x=radius*cos(theta)*sin(phi);
	   y=radius*sin(theta)*sin(phi);
	   z=radius*cos(phi);
            // set points
            surfaceSeg23d->SetPoint(point, x, y, z);
            point++;
         }
      }
      // set marker size, color & style
      surfaceSeg23d->SetMarkerSize(1);
      surfaceSeg23d->SetMarkerColor(world.Rank() + world.Size());
      surfaceSeg23d->SetMarkerStyle(1);
      //send surface points to root process
      world.SendObject(0, 1, *surfaceSeg23d);
   }
   /*************************************************************************/
   /*this rank calculate the surface for theta ∈[pi,1.5pi] and phi ∈[0,pi]  */
   /*and send the surface regions in TPolyMarker3D object to rank root zero */
   /*************************************************************************/
   if (world.Rank() == 2) {
      TPolyMarker3D *surfaceSeg33d = new TPolyMarker3D();
      for (theta = M_PI; theta <1.5*M_PI ; theta+= delta) {
         for (phi = 0; phi <M_PI; phi += delta) {
	   
	   x=radius*cos(theta)*sin(phi);
	   y=radius*sin(theta)*sin(phi);
	   z=radius*cos(phi);
            // set points
            surfaceSeg33d->SetPoint(point, x, y, z);
            point++;
         }
      }
      // set marker size, color & style
      surfaceSeg33d->SetMarkerSize(1);
      surfaceSeg33d->SetMarkerColor(world.Rank() + world.Size());
      surfaceSeg33d->SetMarkerStyle(1);
      //send surface points to root process
      world.SendObject(0, 1, *surfaceSeg33d);
   }
   /*************************************************************************/
   /*this rank calculate the surface for theta ∈[1.5pi,2pi] and phi ∈[0,pi]  */
   /*and send the surface regions in TPolyMarker3D object to rank root zero */
   /*************************************************************************/
   if (world.Rank() == 3) {
      TPolyMarker3D *surfaceSeg43d = new TPolyMarker3D();
      for (theta = 1.5*M_PI; theta <2*M_PI ; theta+= delta) {
         for (phi = 0; phi <M_PI; phi += delta) {
	   
	   x=radius*cos(theta)*sin(phi);
	   y=radius*sin(theta)*sin(phi);
	   z=radius*cos(phi);
            // set points
            surfaceSeg43d->SetPoint(point, x, y, z);
            point++;
         }
      }
      // set marker size, color & style
      surfaceSeg43d->SetMarkerSize(1);
      surfaceSeg43d->SetMarkerColor(world.Rank() + world.Size());
      surfaceSeg43d->SetMarkerStyle(1);
      //send surface points to root process
      world.SendObject(0, 1, *surfaceSeg43d);
   }
}
示例#10
0
//_____________________________________________________________________________
Int_t AliTRDdisplayDigits3D(Int_t event = 0, Int_t thresh = 4
                          , Bool_t sdigits = kFALSE) 
{
  //  
  //  TRD digits display
  //
  //  Input parameter:
  //    <event>   : Event number 
  //    <thresh>  : Threshold to suppress the noise
  //    <sdigits> : If kTRUE it will display summable digits, normal digits otherwise.
  //                The signal event is displayed in yellow.
  //

  Char_t *inputFile = "galice.root";

  // Define the objects
  AliTRDv1       *trd;
  AliTRDgeometry *geo;

  TString       evfoldname = AliConfig::GetDefaultEventFolderName();
  AliRunLoader *runLoader  = AliRunLoader::GetRunLoader(evfoldname);
  if (!runLoader) {
    runLoader = AliRunLoader::Open(inputFile
                                  ,AliConfig::GetDefaultEventFolderName()
                                  ,"UPDATE");
  }
  if (!runLoader) {
    printf("Can not open session for file %s.",inputFile);
    return kFALSE;
  }
   
  if (!runLoader->GetAliRun()) {
    runLoader->LoadgAlice();
  }
  gAlice = runLoader->GetAliRun();  
  if (!gAlice) {
    printf("Could not find AliRun object.\n");
    return kFALSE;
  }

  runLoader->GetEvent(event);
  
  AliLoader *loader = runLoader->GetLoader("TRDLoader");
  if (!loader) {
    printf("Can not get TRD loader from Run Loader");
  }
  loader->LoadDigits();
  
  // Get the pointer to the detector object
  trd = (AliTRDv1*) gAlice->GetDetector("TRD");

  // Get the pointer to the geometry object
  if (trd) {
    geo = trd->GetGeometry();
  }
  else {
    printf("Cannot find the geometry\n");
    return 1;
  }

  AliCDBManager *cdbManager  = AliCDBManager::Instance();
  cdbManager->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
  AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
  calibration->SetRun(0);

  TCanvas *c1 = new TCanvas("digits","TRD digits display",0,0,700,730);
  TView   *v  = new TView(1);
  v->SetRange(-430,-560,-430,430,560,1710);
  v->SetParallel();
  c1->Clear();
  c1->SetFillColor(1);
  c1->SetTheta(90.0);
  c1->SetPhi(0.0);

  Int_t markerColorSignal = 2;
  Int_t markerColorBgnd   = 7;
  Int_t markerColorMerged = 5;
  Int_t mask              = 10000000;

  // Create the digits manager
  AliTRDdigitsManager *digitsManager = new AliTRDdigitsManager();
  digitsManager->SetSDigits(sdigits);

  // Read the digits from the file
  if (sdigits) {
    digitsManager->ReadDigits(loader->TreeS());
  }
  else {
    if (!loader->TreeD()) {
      printf("mist\n");
      return kFALSE;
    }
    digitsManager->ReadDigits(loader->TreeD());
  }

  Int_t totalsignal = 0;
  Int_t totalbgnd   = 0;
  Int_t totalmerged = 0;
  Int_t timeMax     = calibration->GetNumberOfTimeBins();

  // Loop through all detectors
  for (Int_t idet = 0; idet < geo->Ndet(); idet++) {

    printf("<AliTRDdisplayDigits3D> Loading detector %d\n",idet);
    AliTRDdataArrayI *digits  = digitsManager->GetDigits(idet);
    digits->Expand();

    Int_t isec    = geo->GetSector(idet);
    Int_t icha    = geo->GetChamber(idet);
    Int_t ipla    = geo->GetPlane(idet);
    AliTRDpadPlane *padPlane = new AliTRDpadPlane(ipla,icha);
    Int_t  rowMax = padPlane->GetNrows();
    Int_t  colMax = padPlane->GetNcols();

    Int_t ndigits = digits->GetOverThreshold(thresh);

    if (ndigits > 0) {

      TPolyMarker3D *pmSignal = new TPolyMarker3D(ndigits);
      Int_t isignal = 0;

      for (Int_t time = 0; time < timeMax; time++) {
        for (Int_t  col = 0;  col <  colMax;  col++) {
          for (Int_t  row = 0;  row <  rowMax;  row++) {

            Int_t amp = digits->GetDataUnchecked(row,col,time);

            if (amp > thresh) {
          
              Double_t glb[3];
              Double_t loc[3];

              loc[0] = row;
              loc[1] = col;
              loc[2] = time;
              geo->Local2Global(idet,loc,glb);
              Double_t x = glb[0];
              Double_t y = glb[1];
              Double_t z = glb[2];

              pmSignal->SetPoint(isignal,x,y,z);
              isignal++;
              totalsignal++;

	    }

	  }
        }
      }

      digits->Compress(1,0);

      pmSignal->SetMarkerSize(1); 
      pmSignal->SetMarkerColor(markerColorSignal);
      pmSignal->SetMarkerStyle(1);
      pmSignal->Draw();
   
    }

  }

  delete padPlane;

  TGeometry *geoAlice = gAlice->GetGeometry();
  TNode     *main     = (TNode *) ((geoAlice->GetListOfNodes())->First());
  TIter      next(main->GetListOfNodes());
  TNode     *module   = 0;
  while ((module = (TNode *) next())) {
    Char_t ch[100];
    sprintf(ch,"%s\n",module->GetTitle());
    if ((ch[0] == 'T') && ((ch[1] == 'R') || (ch[1] == 'P'))) {
      module->SetVisibility( 3);
    }
    else {
      module->SetVisibility(-1);
    }
  }
      
  geoAlice->Draw("same");

  c1->Modified(); 
  c1->Update(); 

  return 0;

}
示例#11
0
文件: tornado.C 项目: My-Source/root
void tornado() {
//Show 3-d polymarkers
// To see the output of this macro, click begin_html <a href="gif/tornado.gif" >here</a> end_html
//Author: Rene Brun
   
    gBenchmark->Start("tornado");

    double PI = 3.141592653;
    int d = 16;
    int numberOfPoints=200;
    int numberOfCircles=40;

    // create and open a canvas
    TCanvas *sky = new TCanvas( "sky", "Tornado", 300, 10, 700, 500 );
    sky->SetFillColor(14);

    // creating view
    TView *view = TView::CreateView(1,0,0);
    float range = numberOfCircles*d;
    view->SetRange( 0, 0, 0, 4.0*range, 2.0*range, range );

    for( int j = d; j < numberOfCircles*d; j += d ) {

        // create a PolyMarker3D
        TPolyMarker3D *pm3d = new TPolyMarker3D( numberOfPoints );

        float x, y, z;

        // set points
        for( int i = 1; i < numberOfPoints; i++ ) {
            float csin = sin(2*PI / (double)numberOfPoints  * (double)i) + 1;
            float ccos = cos(2*PI / (double)numberOfPoints  * (double)i) + 1;
            float esin = sin(2*PI / (double)(numberOfCircles*d) * (double)j) + 1;
            x = j * ( csin + esin );
            y = j * ccos;
            z = j;
            pm3d->SetPoint( i, x, y, z );
        }

        // set marker size, color & style
        pm3d->SetMarkerSize( 1 );
        pm3d->SetMarkerColor( 2 + ( d == ( j & d ) ) );
        pm3d->SetMarkerStyle( 3 );

        //draw
        pm3d->Draw();
    }

    char timeStr[60];
    gBenchmark->Show("tornado");

    Float_t ct = gBenchmark->GetCpuTime("tornado");
    sprintf( timeStr, "Execution time: %g sec.", ct);

    TPaveText *text = new TPaveText( 0.1, 0.81, 0.9, 0.97 );
    text->SetFillColor( 42 );
    text->AddText("ROOT example: tornado.C");
    text->AddText(timeStr);
    text->Draw();
    sky->Update();
}
示例#12
0
void xtruSamples()
{
// Draw a sample of TXTRU shapes some convex, concave (and possibly malformed)
// Change Bool_t's to test alternative specifications
// Author: Robert Hatcher ([email protected]) 2000.09.06

// One normally specifies the x-y points in counter-clockwise order;
// flip this to TRUE to test that it doesn't matter.
  Bool_t makecw      = kFALSE;

// One normally specifies the z points in increasing z order;
// flip this to TRUE to test that it doesn't matter.
  Bool_t reversez    = kFALSE;

// One shouldn't be creating malformed polygons
// but to test what happens when one does here's a flag.
// The effect will be only apparent in solid rendering mode
  Bool_t domalformed = kFALSE;
//  domalformed = kTRUE;

  c1 = new TCanvas("c1","sample TXTRU Shapes",200,10,640,640);

// Create a new geometry
  TGeometry* geom = new TGeometry("sample","sample");
  geom->cd();

// Define the complexity of the drawing
  Float_t zseg   = 6;  // either 2 or 6
  Int_t extravis = 0;  // make extra z "arrow" visible

  Float_t unit = 1;

// Create a large BRIK to embed things into
  Float_t bigdim = 12.5*unit;
  TBRIK* world = new TBRIK("world","world","void",bigdim,bigdim,bigdim);

  // Create the main node, make it invisible
  TNode* worldnode = new TNode("worldnode","world node",world);
  worldnode->SetVisibility(0);
  worldnode->cd();

// Canonical shape ... gets further modified by scale factors
// to create convex (and malformed) versions
  Float_t x[] = { -0.50, -1.20,  1.20,  0.50,  0.50,  1.20, -1.20, -0.50 };
  Float_t y[] = { -0.75, -2.00, -2.00, -0.75,  0.75,  2.00,  2.00,  0.75 };
  Float_t z[] = { -0.50, -1.50, -1.50,  1.50,  1.50,  0.50 };
  Float_t s[] = {  0.50,  1.00,  1.50,  1.50,  1.00,  0.50 };
  Int_t   nxy = sizeof(x)/sizeof(Float_t);
  Float_t convexscale[] = { 7.0, -1.0, 1.5 };

  Int_t icolor[] = { 1, 2, 3, 2, 2, 2, 4, 2, 6 };

// xycase and zcase:  0=convex, 1=malformed, 2=concave
// this will either create a 2x2 matrix of shapes
// or a 3x3 array (if displaying malformed versions)
  for (Int_t zcase = 0; zcase<3; zcase++) {
     if (zcase == 1 && !domalformed) continue;
     for (Int_t xycase = 0; xycase<3; xycase++) {
        if (xycase == 1 && !domalformed) continue;

        Char_t *name = "txtruXYZ";
        sprintf(name,"txtru%1d%1d%1d",xycase,zcase,zseg);
        TXTRU* mytxtru = new TXTRU(name,name,"void",8,2);

        Int_t i, j;
        Float_t xsign = (makecw) ? -1 : 1;
        Float_t zsign = (reversez) ? -1 : 1;

        // set the vertex points
        for (i=0; i<nxy; i++) {
           Float_t xtmp = x[i]*xsign;
           Float_t ytmp = y[i];
           if (i==0||i==3||i==4||i==7) xtmp *= convexscale[xycase];
           if (xycase==2) xtmp *=2;
           mytxtru->DefineVertex(i,xtmp,ytmp);
        }
        // set the z segment positions and scales
        for (i=0, j=0; i<zseg; i++) {
           Float_t ztmp = z[i]*zsign;
           if (i==0||i==5) ztmp *= convexscale[zcase];
           if (zcase==2) ztmp *= 2.5;
           if (zseg>2 && zcase!=2 && (i==1||i==4)) continue;
           mytxtru->DefineSection(j,ztmp,s[i]);
           j++;
        }

        TNode* txtrunode = new TNode(name,name,mytxtru);
        txtrunode->SetLineColor(icolor[3*zcase+xycase]);
        Float_t pos_scale = (domalformed) ? 10 : 6;
        Float_t xpos = (xycase-1)*pos_scale*unit;
        Float_t ypos = (zcase-1)*pos_scale*unit;
        txtrunode->SetPosition(xpos,ypos,0.);
     }
  }


// Some extra shapes to show the direction of "z"
  Float_t zhalf = 0.5*bigdim;
  Float_t rmax = 0.03*bigdim;
  TCONE* zcone = new TCONE("zcone","zcone","void",zhalf,0.,rmax,0.,0.);
  zcone->SetVisibility(extravis);
  TNode* zconenode = new TNode("zconenode","zconenode",zcone);
  zconenode->SetLineColor(3);

  Float_t dzstub = 2*rmax; 
  TBRIK* zbrik = new TBRIK("zbrik","zbrik","void",rmax,rmax,dzstub);
  zbrik->SetVisibility(extravis);
  TNode* zbriknode = new TNode("zbriknode","zbriknode",zbrik);
  zbriknode->SetPosition(0.,0.,zhalf+dzstub);
  zbriknode->SetLineColor(3);

//  geom->ls();

  geom->Draw();

// Tweak the pad so that it displays the entire geometry undistorted
  TVirtualPad *thisPad = gPad;
  if (thisPad) {
    TView *view = thisPad->GetView(); 
    if (!view) return;
    Double_t min[3],max[3],center[3];
    view->GetRange(min,max);
    int i;
    // Find the boxed center
    for (i=0;i<3; i++) center[i] = 0.5*(max[i]+min[i]);
    Double_t maxSide = 0;
    // Find the largest side
    for (i=0;i<3; i++) maxSide = TMath::Max(maxSide,max[i]-center[i]);
    file://Adjust scales:
    for (i=0;i<3; i++) {
       max[i] = center[i] + maxSide;
       min[i] = center[i] - maxSide;
    }
    view->SetRange(min,max);
    thisPad->Modified();
    thisPad->Update();
  }

}