Revision d7a041971d224681ae21de6feeb5fcf82f71a631 authored by Carsten Burgard on 15 December 2023, 15:25:58 UTC, committed by Jonas Rembser on 19 December 2023, 22:02:43 UTC
In the current implementation, shapesys with no valid data (all
constraints constant) are written out in an invalid way, making it
impossible for the reader to then instantiate the correct number of
parameters. This PR fixes this by forcing the write-out of data with
all-zeros for such invalid shapesys. Alternatively, one could imagine
dropping these shapesys completely, but that's maybe something of a
policy decision that I don't want to make in a bugfix patch :)
1 parent 8f21f0b
Raw File
TGeoVolume.h
// @(#)root/geom:$Id$
// Author: Andrei Gheata   30/05/02

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
// Author :                  date : Wed 24 Oct 2001 01:39:36 PM CEST

#ifndef ROOT_TGeoVolume
#define ROOT_TGeoVolume

#include "TNamed.h"
#include "TGeoAtt.h"
#include "TAttLine.h"
#include "TAttFill.h"
#include "TAtt3D.h"
#include "TObjArray.h"
#include "TGeoMedium.h"
#include "TGeoShape.h"
#include <mutex>
#include <vector>

// forward declarations
class TH2F;
class TGeoNode;
class TGeoMatrix;
class TGeoPatternFinder;
class TGeoVoxelFinder;
class TGeoManager;
class TGeoExtension;

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoVolume - base class representing a single volume having a shape    //
//   and a medium.                                                        //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoVolume : public TNamed, public TGeoAtt, public TAttLine, public TAttFill, public TAtt3D {
protected:
   TObjArray *fNodes;                // array of nodes inside this volume
   TGeoShape *fShape;                // shape
   TGeoMedium *fMedium;              // tracking medium
   static TGeoMedium *fgDummyMedium; //! dummy medium
   TGeoPatternFinder *fFinder;       // finder object for divisions
   TGeoVoxelFinder *fVoxels;         // finder object for bounding boxes
   TGeoManager *fGeoManager;         //! pointer to TGeoManager owning this volume

   TObject *fField;               //! just a hook for now
   TString fOption;               //! option - if any
   Int_t fNumber;                 //  volume serial number in the list of volumes
   Int_t fNtotal;                 // total number of physical nodes
   Int_t fRefCount;               // reference counter
   Char_t fTransparency;          // transparency setting
   TGeoExtension *fUserExtension; //! Transient user-defined extension to volumes
   TGeoExtension *fFWExtension;   //! Transient framework-defined extension to volumes

private:
   TGeoVolume(const TGeoVolume &) = delete;
   TGeoVolume &operator=(const TGeoVolume &) = delete;

public:
   virtual void ClearThreadData() const;
   virtual void CreateThreadData(Int_t nthreads);

public:
   enum EGeoVolumeTypes {
      kVolumeReplicated = BIT(14),
      kVolumeSelected = BIT(15),
      kVolumeDiv = BIT(16),
      kVolumeOverlap = BIT(17),
      kVolumeImportNodes = BIT(18),
      kVolumeMulti = BIT(19),
      kVoxelsXYZ = BIT(20), // not used
      kVoxelsCyl = BIT(21), // not used
      kVolumeClone = BIT(22),
      kVolumeAdded = BIT(23),
      kVolumeOC = BIT(21) // overlapping candidates
   };
   // constructors
   TGeoVolume();
   TGeoVolume(const char *name, const TGeoShape *shape, const TGeoMedium *med = nullptr);

   // destructor
   ~TGeoVolume() override;
   // methods
   virtual void cd(Int_t inode) const;
   void Browse(TBrowser *b) override;
   Double_t Capacity() const;
   void CheckShapes();
   void ClearNodes() { fNodes = nullptr; }
   void ClearShape();
   void CleanAll();
   virtual TGeoVolume *CloneVolume() const;
   void CloneNodesAndConnect(TGeoVolume *newmother) const;
   void CheckGeometry(Int_t nrays = 1, Double_t startx = 0, Double_t starty = 0, Double_t startz = 0) const;
   void CheckOverlaps(Double_t ovlp = 0.1, Option_t *option = "") const;         // *MENU*
   void CheckShape(Int_t testNo, Int_t nsamples = 10000, Option_t *option = ""); // *MENU*
   Int_t CountNodes(Int_t nlevels = 1000, Int_t option = 0);
   Bool_t Contains(const Double_t *point) const { return fShape->Contains(point); }
   static void CreateDummyMedium();
   static TGeoMedium *DummyMedium();
   virtual Bool_t IsAssembly() const;
   Bool_t IsFolder() const override;
   Bool_t IsRunTime() const { return fShape->IsRunTimeShape(); }
   virtual Bool_t IsVolumeMulti() const { return kFALSE; }
   virtual TGeoNode *
   AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat = nullptr, Option_t *option = ""); // most general case
   void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset = 0, Option_t *option = "");
   virtual void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat = nullptr, Option_t *option = "");

   virtual TGeoVolume *Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step,
                              Int_t numed = 0, Option_t *option = "");
   Int_t DistancetoPrimitive(Int_t px, Int_t py) override;
   void Draw(Option_t *option = "") override;    // *MENU*
   virtual void DrawOnly(Option_t *option = ""); // *MENU*
   TH2F *LegoPlot(Int_t ntheta = 20, Double_t themin = 0., Double_t themax = 180., Int_t nphi = 60,
                  Double_t phimin = 0., Double_t phimax = 360., Double_t rmin = 0., Double_t rmax = 9999999,
                  Option_t *option = ""); // *MENU*
   void Paint(Option_t *option = "") override;
   void Print(Option_t *option = "") const override; // *MENU*
   void PrintNodes() const;
   void PrintVoxels() const; // *MENU*
   void ReplayCreation(const TGeoVolume *other);
   void SetUserExtension(TGeoExtension *ext);
   void SetFWExtension(TGeoExtension *ext);
   Int_t GetRefCount() const { return fRefCount; }
   TGeoExtension *GetUserExtension() const { return fUserExtension; }
   TGeoExtension *GetFWExtension() const { return fFWExtension; }
   TGeoExtension *GrabUserExtension() const;
   TGeoExtension *GrabFWExtension() const;
   void Grab() { fRefCount++; }
   void Release()
   {
      fRefCount--;
      if (fRefCount == 0)
         delete this;
   }
   void ExecuteEvent(Int_t event, Int_t px, Int_t py) override;

   Bool_t IsActive() const { return TGeoAtt::IsActive(); }
   Bool_t IsActiveDaughters() const { return TGeoAtt::IsActiveDaughters(); }
   Bool_t IsAdded() const { return TObject::TestBit(kVolumeAdded); }
   Bool_t IsOverlappingCandidate() const { return TObject::TestBit(kVolumeOC); }
   Bool_t IsReplicated() const { return TObject::TestBit(kVolumeReplicated); }
   Bool_t IsSelected() const { return TObject::TestBit(kVolumeSelected); }
   Bool_t IsCylVoxels() const { return TObject::TestBit(kVoxelsCyl); }
   Bool_t IsXYZVoxels() const { return TObject::TestBit(kVoxelsXYZ); }
   Bool_t IsTopVolume() const;
   Bool_t IsValid() const { return fShape->IsValid(); }
   virtual Bool_t IsVisible() const { return TGeoAtt::IsVisible(); }
   Bool_t IsVisibleDaughters() const { return TGeoAtt::IsVisDaughters(); }
   Bool_t IsVisContainers() const { return TGeoAtt::IsVisContainers(); }
   Bool_t IsVisLeaves() const { return TGeoAtt::IsVisLeaves(); }
   Bool_t IsVisOnly() const { return TGeoAtt::IsVisOnly(); }
   Bool_t IsAllInvisible() const;
   Bool_t IsRaytracing() const;
   static TGeoVolume *Import(const char *filename, const char *name = "", Option_t *option = "");
   Int_t Export(const char *filename, const char *name = "", Option_t *option = "");
   TGeoNode *FindNode(const char *name) const;
   void FindOverlaps() const;
   Bool_t FindMatrixOfDaughterVolume(TGeoVolume *vol) const;
   virtual Int_t GetCurrentNodeIndex() const { return -1; }
   virtual Int_t GetNextNodeIndex() const { return -1; }
   TObjArray *GetNodes() { return fNodes; }
   Int_t GetNdaughters() const;
   Int_t GetNtotal() const { return fNtotal; }
   virtual Int_t GetByteCount() const;
   TGeoManager *GetGeoManager() const { return fGeoManager; }
   TGeoMaterial *GetMaterial() const { return GetMedium()->GetMaterial(); }
   TGeoMedium *GetMedium() const { return (fMedium) ? fMedium : DummyMedium(); }
   TObject *GetField() const { return fField; }
   TGeoPatternFinder *GetFinder() const { return fFinder; }
   TGeoVoxelFinder *GetVoxels() const;
   const char *GetIconName() const override { return fShape->GetName(); }
   Int_t GetIndex(const TGeoNode *node) const;
   TGeoNode *GetNode(const char *name) const;
   TGeoNode *GetNode(Int_t i) const { return (TGeoNode *)fNodes->UncheckedAt(i); }
   Int_t GetNodeIndex(const TGeoNode *node, Int_t *check_list, Int_t ncheck) const;
   Int_t GetNumber() const { return fNumber; }
   char *GetObjectInfo(Int_t px, Int_t py) const override;
   Bool_t GetOptimalVoxels() const;
   Option_t *GetOption() const override { return fOption.Data(); }
   const char *GetPointerName() const;
   Char_t GetTransparency() const;
   TGeoShape *GetShape() const { return fShape; }
   void GrabFocus(); // *MENU*
   void Gsord(Int_t /*iaxis*/) {}
   Bool_t IsStyleDefault() const;
   void InspectMaterial() const;                         // *MENU*
   void InspectShape() const { fShape->InspectShape(); } // *MENU*
   virtual TGeoVolume *MakeCopyVolume(TGeoShape *newshape);
   void MakeCopyNodes(const TGeoVolume *other);
   TGeoVolume *MakeReflectedVolume(const char *newname = "") const;
   Bool_t OptimizeVoxels();                                           // *MENU*
   void RandomPoints(Int_t npoints = 1000000, Option_t *option = ""); // *MENU*
   void RandomRays(Int_t nrays = 10000, Double_t startx = 0, Double_t starty = 0, Double_t startz = 0,
                   const char *target_vol = nullptr, Bool_t check_norm = kFALSE); // *MENU*
   void Raytrace(Bool_t flag = kTRUE);                                            // *TOGGLE* *GETTER=IsRaytracing
   void RegisterYourself(Option_t *option = "");
   void RemoveNode(TGeoNode *node);
   TGeoNode *ReplaceNode(TGeoNode *nodeorig, TGeoShape *newshape = nullptr, TGeoMatrix *newpos = nullptr,
                         TGeoMedium *newmed = nullptr);
   void ResetTransparency(Char_t transparency = -1); // *MENU*
   void SaveAs(const char *filename, Option_t *option = "") const override; // *MENU*
   void SavePrimitive(std::ostream &out, Option_t *option = "") override;
   void SelectVolume(Bool_t clear = kFALSE);
   void SetActivity(Bool_t flag = kTRUE) { TGeoAtt::SetActivity(flag); }
   void SetActiveDaughters(Bool_t flag = kTRUE) { TGeoAtt::SetActiveDaughters(flag); }
   void SetAsTopVolume(); // *TOGGLE* *GETTER=IsTopVolume
   void SetAdded() { TObject::SetBit(kVolumeAdded); }
   void SetReplicated() { TObject::SetBit(kVolumeReplicated); }
   void SetCurrentPoint(Double_t x, Double_t y, Double_t z);
   void SetCylVoxels(Bool_t flag = kTRUE)
   {
      TObject::SetBit(kVoxelsCyl, flag);
      TObject::SetBit(kVoxelsXYZ, !flag);
   }
   void SetNodes(TObjArray *nodes)
   {
      fNodes = nodes;
      TObject::SetBit(kVolumeImportNodes);
   }
   void SetOverlappingCandidate(Bool_t flag) { TObject::SetBit(kVolumeOC, flag); }
   void SetShape(const TGeoShape *shape);
   void SetTransparency(Char_t transparency = 0); // *MENU*
   void SetField(TObject *field) { fField = field; }
   void SetOption(const char *option);
   void SetAttVisibility(Bool_t vis) { TGeoAtt::SetVisibility(vis); }
   void SetVisibility(Bool_t vis = kTRUE) override;     // *TOGGLE* *GETTER=IsVisible
   void SetVisContainers(Bool_t flag = kTRUE) override; // *TOGGLE* *GETTER=IsVisContainers
   void SetVisLeaves(Bool_t flag = kTRUE) override;     // *TOGGLE* *GETTER=IsVisLeaves
   void SetVisOnly(Bool_t flag = kTRUE) override;       // *TOGGLE* *GETTER=IsVisOnly
   void SetLineColor(Color_t lcolor) override;
   void SetLineStyle(Style_t lstyle) override;
   void SetLineWidth(Width_t lwidth) override;
   void SetInvisible() { SetVisibility(kFALSE); }
   virtual void SetMedium(TGeoMedium *medium) { fMedium = medium; }
   void SetVoxelFinder(TGeoVoxelFinder *finder) { fVoxels = finder; }
   void SetFinder(TGeoPatternFinder *finder) { fFinder = finder; }
   void SetNumber(Int_t number) { fNumber = number; }
   void SetNtotal(Int_t ntotal) { fNtotal = ntotal; }
   void SortNodes();
   void UnmarkSaved();
   Bool_t Valid() const;
   void VisibleDaughters(Bool_t vis = kTRUE); // *TOGGLE* *GETTER=IsVisibleDaughters
   void InvisibleAll(Bool_t flag = kTRUE);    // *TOGGLE* *GETTER=IsAllInvisible
   void Voxelize(Option_t *option);
   Double_t Weight(Double_t precision = 0.01, Option_t *option = "va"); // *MENU*
   Double_t WeightA() const;

   ClassDefOverride(TGeoVolume, 7)              // geometry volume descriptor
};

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoVolumeMulti - class storing a list of volumes that have to         //
//   be handled together at build time                                   //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoVolumeMulti : public TGeoVolume {
private:
   TObjArray *fVolumes;        // list of volumes
   TGeoVolumeMulti *fDivision; // division of this volume
   Int_t fNumed;               // medium number for divisions
   Int_t fNdiv;                // number of divisions
   Int_t fAxis;                // axis of division
   Double_t fStart;            // division start offset
   Double_t fStep;             // division step
   Bool_t fAttSet;             // flag attributes set

   TGeoVolumeMulti(const TGeoVolumeMulti &) = delete;
   TGeoVolumeMulti &operator=(const TGeoVolumeMulti &) = delete;

public:
   TGeoVolumeMulti();
   TGeoVolumeMulti(const char *name, TGeoMedium *med = nullptr);
   ~TGeoVolumeMulti() override;

   void AddVolume(TGeoVolume *vol);
   TGeoVolume *GetVolume(Int_t id) const { return (TGeoVolume *)fVolumes->At(id); }
   TGeoNode *
   AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option = "") override; // most general case
   void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option = "") override;
   TGeoVolume *Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed = 0,
                      Option_t *option = "") override;
   TGeoShape *GetLastShape() const;
   Int_t GetNvolumes() const { return fVolumes->GetEntriesFast(); }
   Int_t GetAxis() const { return fNdiv; }
   Int_t GetNdiv() const { return fNdiv; }
   Double_t GetStart() const { return fStart; }
   Double_t GetStep() const { return fStep; }
   Bool_t IsVolumeMulti() const override { return kTRUE; }
   TGeoVolume *MakeCopyVolume(TGeoShape *newshape) override;
   void SetLineColor(Color_t lcolor) override;
   void SetLineStyle(Style_t lstyle) override;
   void SetLineWidth(Width_t lwidth) override;
   void SetMedium(TGeoMedium *medium) override;
   void SetVisibility(Bool_t vis = kTRUE) override;

   ClassDefOverride(TGeoVolumeMulti, 3) // class to handle multiple volumes in one step
};

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoVolumeAssembly - special assembly of volumes. The assembly has no  //
//   medium and its shape is the union of all component shapes            //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoVolumeAssembly : public TGeoVolume {
public:
   struct ThreadData_t {
      Int_t fCurrent; //! index of current selected node
      Int_t fNext;    //! index of next node to be entered

      ThreadData_t();
      ~ThreadData_t();
   };

   ThreadData_t &GetThreadData() const;
   void ClearThreadData() const override;
   void CreateThreadData(Int_t nthreads) override;

protected:
   mutable std::vector<ThreadData_t *> fThreadData; //! Thread specific data vector
   mutable Int_t fThreadSize;                       //! Thread vector size
   mutable std::mutex fMutex;                       //! Mutex for concurrent operations

private:
   TGeoVolumeAssembly(const TGeoVolumeAssembly &) = delete;
   TGeoVolumeAssembly &operator=(const TGeoVolumeAssembly &) = delete;

public:
   TGeoVolumeAssembly();
   TGeoVolumeAssembly(const char *name);
   ~TGeoVolumeAssembly() override;

   TGeoNode *AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat = nullptr, Option_t *option = "") override;
   void AddNodeOverlap(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t *option) override;
   TGeoVolume *CloneVolume() const override;
   TGeoVolume *Divide(const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step, Int_t numed = 0,
                      Option_t *option = "") override;
   TGeoVolume *Divide(TGeoVolume *cell, TGeoPatternFinder *pattern, Option_t *option = "spacedout");
   void DrawOnly(Option_t *) override {}
   Int_t GetCurrentNodeIndex() const override;
   Int_t GetNextNodeIndex() const override;
   Bool_t IsAssembly() const override { return kTRUE; }
   Bool_t IsVisible() const override { return kFALSE; }
   static TGeoVolumeAssembly *MakeAssemblyFromVolume(TGeoVolume *vol);
   void SetCurrentNodeIndex(Int_t index);
   void SetNextNodeIndex(Int_t index);

   ClassDefOverride(TGeoVolumeAssembly, 2) // an assembly of volumes
};

inline Int_t TGeoVolume::GetNdaughters() const
{
   if (!fNodes)
      return 0;
   return (fNodes->GetEntriesFast());
}

inline Char_t TGeoVolume::GetTransparency() const
{
   // If the transparency is (-1), the old default handling is applied
   if ( fTransparency >= 0 ) return fTransparency;
   return !fMedium ? 0 : fMedium->GetMaterial()->GetTransparency();
}

inline void TGeoVolume::SetTransparency(Char_t transparency)
{
   if (fMedium)  {
      fMedium->GetMaterial()->SetTransparency(transparency);
   }
}

inline void TGeoVolume::ResetTransparency(Char_t transparency)
{
   fTransparency = transparency;
}

#endif
back to top