File indexing completed on 2025-02-23 09:21:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include "DicomPhantomZSliceHeader.hh"
0032
0033 #include "G4GeometryTolerance.hh"
0034 #include "G4LogicalVolume.hh"
0035 #include "G4Material.hh"
0036 #include "G4MaterialTable.hh"
0037 #include "G4NistManager.hh"
0038 #include "globals.hh"
0039
0040
0041 DicomPhantomZSliceHeader::DicomPhantomZSliceHeader(const G4String& fname)
0042 : fNoVoxelsX(0),
0043 fNoVoxelsY(0),
0044 fNoVoxelsZ(0),
0045 fMinX(0),
0046 fMinY(0),
0047 fMinZ(0),
0048 fMaxX(0),
0049 fMaxY(0),
0050 fMaxZ(0),
0051 fFilename(fname),
0052 fSliceLocation(0)
0053 {}
0054
0055
0056 DicomPhantomZSliceHeader::~DicomPhantomZSliceHeader() {}
0057
0058
0059 DicomPhantomZSliceHeader::DicomPhantomZSliceHeader(std::ifstream& fin)
0060 {
0061
0062 G4int nmate;
0063 G4String mateindex;
0064 G4String matename;
0065 fin >> nmate;
0066 #ifdef G4VERBOSE
0067 G4cout << " DicomPhantomZSliceHeader reading number of materials " << nmate << G4endl;
0068 #endif
0069
0070 for (G4int im = 0; im < nmate; im++) {
0071 fin >> mateindex >> matename;
0072 #ifdef G4VERBOSE
0073
0074
0075 #endif
0076
0077 if (!CheckMaterialExists(matename)) {
0078 G4Exception("DicomPhantomZSliceHeader::DicomPhantomZSliceHeader",
0079 "A material is found in file that is not built in the C++ code",
0080 FatalErrorInArgument, matename.c_str());
0081 }
0082
0083 fMaterialNames.push_back(matename);
0084 }
0085
0086
0087 fin >> fNoVoxelsX >> fNoVoxelsY >> fNoVoxelsZ;
0088 #ifdef G4VERBOSE
0089 G4cout << " Number of voxels " << fNoVoxelsX << " " << fNoVoxelsY << " " << fNoVoxelsZ << G4endl;
0090 #endif
0091
0092
0093 fin >> fMinX >> fMaxX;
0094 fin >> fMinY >> fMaxY;
0095 fin >> fMinZ >> fMaxZ;
0096 #ifdef G4VERBOSE
0097 G4cout << " Extension in X " << fMinX << " " << fMaxX << G4endl << " Extension in Y " << fMinY
0098 << " " << fMaxY << G4endl << " Extension in Z " << fMinZ << " " << fMaxZ << G4endl;
0099 #endif
0100
0101 fSliceLocation = 0.5 * (fMinZ + fMaxZ);
0102 }
0103
0104
0105 G4bool DicomPhantomZSliceHeader::CheckMaterialExists(const G4String& mateName)
0106 {
0107 const G4MaterialTable* matTab = G4Material::GetMaterialTable();
0108 std::vector<G4Material*>::const_iterator matite;
0109 for (matite = matTab->begin(); matite != matTab->end(); ++matite) {
0110 if ((*matite)->GetName() == mateName) {
0111 return true;
0112 }
0113 }
0114
0115 G4Material* g4mate = G4NistManager::Instance()->FindOrBuildMaterial(mateName);
0116 if (g4mate) {
0117 return false;
0118 }
0119 else {
0120 return true;
0121 }
0122 }
0123
0124
0125 void DicomPhantomZSliceHeader::operator+=(const DicomPhantomZSliceHeader& rhs)
0126 {
0127 *this = *this + rhs;
0128 }
0129
0130
0131 DicomPhantomZSliceHeader DicomPhantomZSliceHeader::operator+(const DicomPhantomZSliceHeader& rhs)
0132 {
0133
0134 if (fNoVoxelsX != rhs.GetNoVoxelsX() || fNoVoxelsY != rhs.GetNoVoxelsY()) {
0135 G4cerr << "DicomPhantomZSliceHeader error adding two slice headers:\
0136 !!! Different number of voxels: "
0137 << " X= " << fNoVoxelsX << " =? " << rhs.GetNoVoxelsX() << " Y= " << fNoVoxelsY
0138 << " =? " << rhs.GetNoVoxelsY() << " Z= " << fNoVoxelsZ << " =? " << rhs.GetNoVoxelsZ()
0139 << G4endl;
0140 G4Exception("DicomPhantomZSliceHeader::DicomPhantomZSliceHeader", "", FatalErrorInArgument, "");
0141 }
0142
0143 if (fMinX != rhs.GetMinX() || fMaxX != rhs.GetMaxX() || fMinY != rhs.GetMinY()
0144 || fMaxY != rhs.GetMaxY())
0145 {
0146 G4cerr << "DicomPhantomZSliceHeader error adding two slice headers:\
0147 !!! Different extensions: "
0148 << " Xmin= " << fMinX << " =? " << rhs.GetMinX() << " Xmax= " << fMaxX << " =? "
0149 << rhs.GetMaxX() << " Ymin= " << fMinY << " =? " << rhs.GetMinY() << " Ymax= " << fMaxY
0150 << " =? " << rhs.GetMaxY() << G4endl;
0151 G4Exception("DicomPhantomZSliceHeader::operator+", "", FatalErrorInArgument, "");
0152 }
0153
0154
0155 std::vector<G4String> fMaterialNames2 = rhs.GetMaterialNames();
0156 if (fMaterialNames.size() != fMaterialNames2.size()) {
0157 G4cerr << "DicomPhantomZSliceHeader error adding two slice headers:\
0158 !!! Different number of materials: "
0159 << fMaterialNames.size() << " =? " << fMaterialNames2.size() << G4endl;
0160 G4Exception("DicomPhantomZSliceHeader::operator+", "", FatalErrorInArgument, "");
0161 }
0162 for (unsigned int ii = 0; ii < fMaterialNames.size(); ii++) {
0163 if (fMaterialNames[ii] != fMaterialNames2[ii]) {
0164 G4cerr << "DicomPhantomZSliceHeader error adding two slice headers:\
0165 !!! Different material number "
0166 << ii << " : " << fMaterialNames[ii] << " =? " << fMaterialNames2[ii] << G4endl;
0167 G4Exception("DicomPhantomZSliceHeader::operator+", "", FatalErrorInArgument, "");
0168 }
0169 }
0170
0171
0172 if (std::fabs(fMinZ - rhs.GetMaxZ()) > G4GeometryTolerance::GetInstance()->GetRadialTolerance()
0173 && std::fabs(fMaxZ - rhs.GetMinZ())
0174 > G4GeometryTolerance::GetInstance()->GetRadialTolerance())
0175 {
0176 G4cerr << "DicomPhantomZSliceHeader error adding two slice headers:!!!\
0177 Slices are not contiguous in Z "
0178 << " Zmin= " << fMinZ << " & " << rhs.GetMinZ() << " Zmax= " << fMaxZ << " & "
0179 << rhs.GetMaxZ() << G4endl;
0180 G4Exception("DicomPhantomZSliceHeader::operator+", "", FatalErrorInArgument, "");
0181 }
0182
0183
0184 DicomPhantomZSliceHeader temp(*this);
0185
0186
0187 temp.SetMinZ(std::min(fMinZ, rhs.GetMinZ()));
0188 temp.SetMaxZ(std::max(fMaxZ, rhs.GetMaxZ()));
0189 temp.SetNoVoxelsZ(fNoVoxelsZ + rhs.GetNoVoxelsZ());
0190
0191 return temp;
0192 }
0193
0194
0195 void DicomPhantomZSliceHeader::DumpToFile()
0196 {
0197 G4cout << "DicomPhantomZSliceHeader::Dumping Z Slice data to " << fFilename << "..." << G4endl;
0198
0199
0200
0201
0202 if (fMateIDs.size() == 0 || fValues.size() == 0) {
0203 ReadDataFromFile();
0204 }
0205
0206 std::ofstream out;
0207 out.open(fFilename.c_str());
0208
0209 if (!out) {
0210 G4String descript = "DicomPhantomZSliceHeader::DumpToFile: could not open " + fFilename;
0211 G4Exception(descript.c_str(), "", FatalException, "");
0212 }
0213
0214 out << fMaterialNames.size() << std::endl;
0215 for (unsigned int i = 0; i < fMaterialNames.size(); ++i) {
0216 out << i << " " << fMaterialNames.at(i) << std::endl;
0217 }
0218
0219 out << fNoVoxelsX << " " << fNoVoxelsY << " " << fNoVoxelsZ << std::endl;
0220 out << fMinX << " " << fMaxX << std::endl;
0221 out << fMinY << " " << fMaxY << std::endl;
0222 out << fMinZ << " " << fMaxZ << std::endl;
0223
0224 for (unsigned int i = 0; i < fMateIDs.size(); ++i) {
0225 Print(out, fMateIDs.at(i), " ");
0226 }
0227
0228 for (unsigned int i = 0; i < fValues.size(); ++i) {
0229 Print(out, fValues.at(i), " ", 6);
0230 }
0231
0232 out.close();
0233 }
0234
0235
0236 void DicomPhantomZSliceHeader::ReadDataFromFile()
0237 {
0238 std::ifstream in;
0239 in.open(fFilename.c_str());
0240
0241 if (!in) {
0242 G4String descript = "DicomPhantomZSliceHeader::DumpToFile: could not open " + fFilename;
0243 G4Exception(descript.c_str(), "", FatalException, "");
0244 }
0245
0246 G4int nMaterials;
0247 in >> nMaterials;
0248
0249 fMaterialNames.resize(nMaterials, "");
0250 for (G4int i = 0; i < nMaterials; ++i) {
0251 G4String str1, str2;
0252 in >> str1 >> str2;
0253 if (!IsInteger(str1)) {
0254 G4String descript = "String : " + str1 + " supposed to be integer";
0255 G4Exception(
0256 "DicomPhantomZSliceHeader::ReadDataFromFile - error in \
0257 formatting: missing material index",
0258 "", FatalException, descript.c_str());
0259 }
0260 G4int index = G4s2n<G4int>(str1);
0261 if (index > nMaterials || index < 0) {
0262 G4String descript = "Index : " + str1;
0263 G4Exception(
0264 "DicomPhantomZSliceHeader::ReadDataFromFile - error:\
0265 bad material index",
0266 "", FatalException, descript.c_str());
0267 }
0268 fMaterialNames[index] = str2;
0269 }
0270
0271 in >> fNoVoxelsX >> fNoVoxelsY >> fNoVoxelsZ;
0272
0273 G4double tmpMinX, tmpMinY, tmpMinZ;
0274 G4double tmpMaxX, tmpMaxY, tmpMaxZ;
0275
0276 in >> tmpMinX >> tmpMaxX;
0277 in >> tmpMinY >> tmpMaxY;
0278 in >> tmpMinZ >> tmpMaxZ;
0279
0280 fMinX =
0281 (CheckConsistency(tmpMinX, fMinX, "Min X value")) ? fMinX : ((fMinX == 0) ? tmpMinX : fMinX);
0282 fMaxX =
0283 (CheckConsistency(tmpMaxX, fMaxX, "Max X value")) ? fMaxX : ((fMaxX == 0) ? tmpMaxX : fMaxX);
0284
0285 fMinY =
0286 (CheckConsistency(tmpMinY, fMinY, "Min Y value")) ? fMinY : ((fMinY == 0) ? tmpMinY : fMinY);
0287 fMaxY =
0288 (CheckConsistency(tmpMaxY, fMaxY, "Max Y value")) ? fMaxY : ((fMaxY == 0) ? tmpMaxY : fMaxY);
0289
0290 fMinZ =
0291 (CheckConsistency(tmpMinZ, fMinZ, "Min Z value")) ? fMinZ : ((fMinZ == 0) ? tmpMinZ : fMinZ);
0292 fMaxZ =
0293 (CheckConsistency(tmpMaxZ, fMaxZ, "Max Z value")) ? fMaxZ : ((fMaxZ == 0) ? tmpMaxZ : fMaxZ);
0294
0295 fMateIDs.clear();
0296 fValues.clear();
0297 fMateIDs.resize(fNoVoxelsY * fNoVoxelsZ, std::vector<G4int>(fNoVoxelsX, 0));
0298 fValues.resize(fNoVoxelsY * fNoVoxelsZ, std::vector<G4double>(fNoVoxelsX, 0.));
0299 for (G4int k = 0; k < fNoVoxelsZ; ++k) {
0300 for (G4int j = 0; j < fNoVoxelsY; ++j) {
0301 for (G4int i = 0; i < fNoVoxelsX; ++i) {
0302 G4int tmpMateID;
0303 in >> tmpMateID;
0304 G4int row = j * (k + 1);
0305 fMateIDs[row][i] = tmpMateID;
0306 }
0307 }
0308 }
0309
0310 for (G4int k = 0; k < fNoVoxelsZ; ++k) {
0311 for (G4int j = 0; j < fNoVoxelsY; ++j) {
0312 for (G4int i = 0; i < fNoVoxelsX; ++i) {
0313 G4double tmpValue;
0314 in >> tmpValue;
0315 G4int row = j * (k + 1);
0316 fValues[row][i] = tmpValue;
0317 }
0318 }
0319 }
0320
0321 in.close();
0322 }
0323