Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:21:44

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 /// \file medical/DICOM/include/DicomPhantomZSliceHeader.hh
0028 /// \brief Definition of the DicomPhantomZSliceHeader class
0029 //
0030 
0031 #ifndef DicomPhantomZSliceHeader_h
0032 #define DicomPhantomZSliceHeader_h 1
0033 
0034 #include "globals.hh"
0035 
0036 #include <fstream>
0037 #include <vector>
0038 
0039 class G4material;
0040 
0041 //*******************************************************
0042 /// DicomPhantomZSliceHeader class
0043 ///
0044 /// Contains the meta data information corresponding to one or several
0045 /// Z slices (number of voxels, dimension)
0046 ///
0047 /// History: 30.11.07  First version
0048 /// \author  P. Arce
0049 //*******************************************************
0050 
0051 class DicomPhantomZSliceHeader
0052 {
0053   public:
0054     DicomPhantomZSliceHeader(const G4String&);
0055 
0056     DicomPhantomZSliceHeader(const DicomPhantomZSliceHeader&) = default;
0057     // build object copying an existing one (except Z dimensions)
0058 
0059     DicomPhantomZSliceHeader(std::ifstream& fin);
0060     // build object reading data from a file
0061 
0062     ~DicomPhantomZSliceHeader();
0063 
0064     // Get and set methods
0065     G4int GetNoVoxelsX() const { return fNoVoxelsX; };
0066     G4int GetNoVoxelsY() const { return fNoVoxelsY; };
0067     G4int GetNoVoxelsZ() const { return fNoVoxelsZ; };
0068     G4int GetNoVoxels() const { return fNoVoxelsX * fNoVoxelsY * fNoVoxelsZ; };
0069 
0070     G4double GetMinX() const { return fMinX; };
0071     G4double GetMinY() const { return fMinY; };
0072     G4double GetMinZ() const { return fMinZ; };
0073     G4double GetMaxX() const { return fMaxX; };
0074     G4double GetMaxY() const { return fMaxY; };
0075     G4double GetMaxZ() const { return fMaxZ; };
0076 
0077     G4double GetVoxelHalfX() const { return (fMaxX - fMinX) / fNoVoxelsX / 2.; };
0078     G4double GetVoxelHalfY() const { return (fMaxY - fMinY) / fNoVoxelsY / 2.; };
0079     G4double GetVoxelHalfZ() const { return (fMaxZ - fMinZ) / fNoVoxelsZ / 2.; };
0080 
0081     const std::vector<G4String>& GetMaterialNames() const { return fMaterialNames; };
0082 
0083     void SetNoVoxelsX(const G4int& val) { fNoVoxelsX = val; }
0084     void SetNoVoxelsY(const G4int& val) { fNoVoxelsY = val; }
0085     void SetNoVoxelsZ(const G4int& val) { fNoVoxelsZ = val; }
0086 
0087     void SetMinX(const G4double& val) { fMinX = val; };
0088     void SetMaxX(const G4double& val) { fMaxX = val; };
0089     void SetMinY(const G4double& val) { fMinY = val; };
0090     void SetMaxY(const G4double& val) { fMaxY = val; };
0091     void SetMinZ(const G4double& val) { fMinZ = val; };
0092     void SetMaxZ(const G4double& val) { fMaxZ = val; };
0093 
0094     void SetMaterialNames(std::vector<G4String>& mn) { fMaterialNames = mn; }
0095 
0096     void operator+=(const DicomPhantomZSliceHeader& rhs);
0097     DicomPhantomZSliceHeader operator+(const DicomPhantomZSliceHeader& rhs);
0098     // add two slices that have the same dimensions, merging them in Z
0099 
0100     //=================================================================
0101     //  NEW REVISION ( Jonathan Madsen - jonathan.madsen@cern.ch )
0102     //  December 2012
0103     //
0104     //  New data handling format -> movement away from file-based to class based
0105     //      -- If density and mate ID data is not present -> read from file
0106     //
0107     //  REASONING:
0108     //      --  DICOM data can contain inconsistencies, handling via class
0109     //    instead of via file
0110     //          allows safe/easy modification
0111     //
0112     //  Adding Data to densities and fMateIDs
0113     //
0114     void SetFilename(const G4String& val) { fFilename = val; }
0115     void SetSliceLocation(const G4double& val) { fSliceLocation = val; }
0116     void AddMaterial(const G4String& val) { fMaterialNames.push_back(val); }
0117 
0118     const G4double& GetSliceLocation() const { return fSliceLocation; }
0119 
0120     void AddRow()
0121     {
0122       fValues.push_back(std::vector<G4double>(0));
0123       fMateIDs.push_back(std::vector<G4int>(0));
0124     }
0125 
0126     void AddValue(G4double val)
0127     {
0128       (fValues.size() > 0) ? fValues.back().push_back(val)
0129                            : fValues.push_back(std::vector<G4double>(1, val));
0130     }
0131     void AddValue(const std::vector<G4double>& val) { fValues.push_back(val); }
0132     void AddValue(const std::vector<std::vector<G4double>>& val)
0133     {
0134       for (unsigned int i = 0; i < val.size(); ++i) {
0135         fValues.push_back(val.at(i));
0136       }
0137     }
0138 
0139     void AddMateID(G4int val)
0140     {
0141       (fMateIDs.size() > 0) ? fMateIDs.back().push_back(val)
0142                             : fMateIDs.push_back(std::vector<G4int>(1, val));
0143     }
0144     void AddMateID(const std::vector<G4int>& val) { fMateIDs.push_back(val); }
0145     void AddMateID(const std::vector<std::vector<G4int>>& val)
0146     {
0147       for (unsigned int i = 0; i < val.size(); ++i) {
0148         fMateIDs.push_back(val.at(i));
0149       }
0150     }
0151 
0152     const std::vector<std::vector<G4double>>& GetValues() const { return fValues; }
0153     const std::vector<std::vector<G4int>>& GetMateIDs() const { return fMateIDs; }
0154 
0155     void DumpToFile();
0156     void ReadDataFromFile();
0157 
0158     void DumpExcessMemory()
0159     {
0160       if (fFilename.length() != 0) {
0161         fValues.clear();
0162         fMateIDs.clear();
0163       }
0164     }
0165 
0166     void FlipData();
0167 
0168   private:
0169     inline G4bool IsInteger(const G4String&);
0170     template<typename T>
0171     inline void Print(std::ostream&, const std::vector<T>&, const G4String&, G4int breakLine = -1);
0172     template<typename T>
0173     inline T G4s2n(const G4String&);
0174     template<typename T>
0175     inline bool CheckConsistency(const T&, const T&, G4String);
0176     //
0177     //  END NEW REVISION
0178     //=======================================================================
0179 
0180   private:
0181     G4bool CheckMaterialExists(const G4String& mateName);
0182     // check that material read exists as a G4Material
0183 
0184   private:
0185     G4int fNoVoxelsX, fNoVoxelsY, fNoVoxelsZ;  // number of voxels in each dimensions
0186     G4double fMinX, fMinY, fMinZ;  // minimum extension of voxels (position of wall)
0187     G4double fMaxX, fMaxY, fMaxZ;  // maximum extension of voxels (position of wall)
0188 
0189     std::vector<G4String> fMaterialNames;  // list of material names
0190 
0191     G4String fFilename;
0192     std::vector<std::vector<G4double>> fValues;
0193     std::vector<std::vector<G4int>> fMateIDs;
0194     G4double fSliceLocation;
0195 };
0196 
0197 //============================================================================
0198 // This function flips all the data
0199 // Otherwise, the image is upside-down
0200 inline void DicomPhantomZSliceHeader::FlipData()
0201 {
0202   std::reverse(fValues.begin(), fValues.end());
0203   std::reverse(fMateIDs.begin(), fMateIDs.end());
0204 }
0205 //=============================================================================
0206 inline G4bool DicomPhantomZSliceHeader::IsInteger(const G4String& str)
0207 {
0208   return (str.find_first_not_of("0123456789") == std::string::npos) ? true : false;
0209 }
0210 //============================================================================
0211 template<typename T>
0212 inline T DicomPhantomZSliceHeader::G4s2n(const G4String& str)
0213 {
0214   std::istringstream iss(str);
0215   T val;
0216   iss >> val;
0217   return val;
0218 }
0219 
0220 //============================================================================
0221 template<typename T>
0222 inline bool DicomPhantomZSliceHeader::CheckConsistency(const T& val1, const T& val2,
0223                                                        G4String category)
0224 {
0225   if (val1 != val2) {
0226     G4Exception("DicomPhantomSliceZHeader::CheckConsistency",
0227                 "Consistency Mismatch : Keeping previous value if nonzero", JustWarning,
0228                 category.c_str());
0229     return false;
0230   }
0231   return true;
0232 }
0233 //============================================================================
0234 template<typename T>
0235 inline void DicomPhantomZSliceHeader::Print(std::ostream& out, const std::vector<T>& val,
0236                                             const G4String& delim, G4int breakLine)
0237 {
0238   for (unsigned int i = 0; i < val.size(); ++i) {
0239     out << val.at(i);
0240     if (breakLine < 0) {
0241       if (i + 1 < val.size()) {
0242         out << delim;
0243       }
0244       else {
0245         out << G4endl;
0246       }
0247     }
0248     else {
0249       ((i != 0 && i % breakLine == 0) ? (out << G4endl) : (out << delim));
0250     }
0251   }
0252 }
0253 //==========================================================================
0254 
0255 #endif