Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:30:31

0001 ////////////////////////////////////////////////////////////////////////////////
0002 //
0003 //    Compares output files from PrintGeomInfo created using DDD and DD4hep
0004 //    inputs. Usage:
0005 //
0006 //    SimFileCompare infile1 infile2 type files debug
0007 //    infile1  (const char*)   First file name
0008 //    infile2  (const char*)   Second file name
0009 //    type     (int)           Type of file: material (0), solid (1),
0010 //                             LogicalVolume (2), PhysicalVolume (3);
0011 //                             Region (4)
0012 //    files    (int)           Double digits each inidicating the file source
0013 //                             (0 for DDD, 1 for DD4hep). So if first file is
0014 //                             DDD and second is DD4hep, it will be 10
0015 //    debug    (int)           Single digit number (0 minimum printout)
0016 //
0017 ////////////////////////////////////////////////////////////////////////////////
0018 
0019 #include <algorithm>
0020 #include <cstdlib>
0021 #include <fstream>
0022 #include <iomanip>
0023 #include <iostream>
0024 #include <map>
0025 #include <string>
0026 #include <vector>
0027 #include <cstdint>
0028 #include "SimG4Core/Geometry/interface/DD4hep2DDDName.h"
0029 
0030 struct materials {
0031   int occ;
0032   double radl, intl;
0033   materials(int oc = 1, double rd = 0, double in = 0) : occ(oc), radl(rd), intl(in) {}
0034 };
0035 
0036 struct solids {
0037   int occ;
0038   double volume;
0039   solids(int oc = 1, double vol = 0) : occ(oc), volume(vol) {}
0040 };
0041 
0042 struct lvs {
0043   int occ;
0044   double mass;
0045   lvs(int oc = 1, double m = 0) : occ(oc), mass(m) {}
0046 };
0047 
0048 struct pvs {
0049   int occ;
0050   double xx, yy, zz;
0051   pvs(int oc = 1, double x = 0, double y = 0, double z = 0) : occ(oc), xx(x), yy(y), zz(z) {}
0052 };
0053 
0054 struct regions {
0055   int occ;
0056   double nmat, nvol;
0057   regions(int oc = 1, double mat = 0, double vol = 0) : occ(oc), nmat(mat), nvol(vol) {}
0058 };
0059 
0060 std::string removeExtraName(const std::string& name, int debug) {
0061   std::string nam(name);
0062   std::string nam1 = name.substr(0, 2);
0063   if (((nam1 == "GE") || (nam1 == "GH") || (nam1 == "MB") || (nam1 == "ME") || (nam1 == "RE") || (nam1 == "RR") ||
0064        (nam1 == "RT")) &&
0065       (name.size() > 5)) {
0066     uint32_t loc = name.size() - 5;
0067     if ((name.substr(0, 15) != "MBCables_Wheels") && (name.substr(loc, 1) == "_")) {
0068       std::string nam2 = (name.substr(loc + 3, 1) == "0") ? name.substr(loc + 4, 1) : name.substr(loc + 3, 2);
0069       nam = name.substr(0, loc + 1) + nam2;
0070     }
0071   }
0072   if (debug)
0073     std::cout << name << " : " << nam1 << " " << nam << std::endl;
0074   return nam;
0075 }
0076 
0077 std::string reducedName(const std::string& name, int debug) {
0078   std::string nam(name);
0079   uint32_t first = ((name.find(":") == std::string::npos) ? 0 : (name.find(":") + 1));
0080   uint32_t last(name.size() + 1);
0081   uint32_t loc(first);
0082   while (1) {
0083     if (name.find("_", loc) == std::string::npos)
0084       break;
0085     if (((loc + 5) < name.size()) && (name.substr(loc, 5) == "shape")) {
0086       last = loc;
0087       break;
0088     }
0089     loc = name.find("_", loc) + 1;
0090     if (loc > name.size())
0091       break;
0092   }
0093   nam = name.substr(first, last - first - 1);
0094   if ((last < name.size()) && (name.substr(name.size() - 5, 5) == "_refl"))
0095     nam += "_refl";
0096   if (debug > 0)
0097     std::cout << name << " col " << first << ":" << last << " " << nam << std::endl;
0098   return nam;
0099 }
0100 
0101 std::vector<std::string> splitString(const std::string& fLine) {
0102   std::vector<std::string> result;
0103   int start = 0;
0104   bool empty = true;
0105   for (unsigned i = 0; i <= fLine.size(); i++) {
0106     if (fLine[i] == ' ' || i == fLine.size()) {
0107       if (!empty) {
0108         std::string item(fLine, start, i - start);
0109         result.push_back(item);
0110         empty = true;
0111       }
0112       start = i + 1;
0113     } else {
0114       if (empty)
0115         empty = false;
0116     }
0117   }
0118   return result;
0119 }
0120 
0121 template <typename T>
0122 void myPrint1(std::map<std::string, T> const& obj) {
0123   for (auto it : obj) {
0124     if (it.second.occ > 1)
0125       std::cout << it.first << " : " << it.second.occ << std::endl;
0126   }
0127 }
0128 
0129 template <typename T>
0130 void myPrint2(std::map<std::string, T> const& obj1, std::map<std::string, T> const& obj2) {
0131   for (auto it : obj1) {
0132     if (obj2.find(it.first) == obj2.end())
0133       std::cout << it.first << " appearing " << it.second.occ << " times" << std::endl;
0134   }
0135 }
0136 
0137 void CompareFiles(const char* fileFile1, const char* fileFile2, int type, int files, int debug) {
0138   std::map<std::string, materials> matFile1, matFile2;
0139   std::map<std::string, solids> solidFile1, solidFile2;
0140   std::map<std::string, lvs> lvFile1, lvFile2;
0141   std::map<std::string, pvs> pvFile1, pvFile2;
0142   std::map<std::string, regions> regFile1, regFile2;
0143   bool typeFile1 = ((files % 10) == 0);
0144   bool typeFile2 = (((files / 10) % 10) == 0);
0145   char buffer[100];
0146   std::string name;
0147   std::ifstream fInput1(fileFile1);
0148   unsigned int sizeFile1(0), sizeFile2(0);
0149   if (!fInput1.good()) {
0150     std::cout << "Cannot open file " << fileFile1 << std::endl;
0151   } else {
0152     while (fInput1.getline(buffer, 100)) {
0153       std::vector<std::string> items = splitString(std::string(buffer));
0154       if ((type == 0) || (type == 2))
0155         name = DD4hep2DDDName::nameMatterLV(items[0], !typeFile1);
0156       else if (type == 1)
0157         name = DD4hep2DDDName::nameSolid(items[0], !typeFile1);
0158       else if (type == 3)
0159         name = DD4hep2DDDName::namePV(items[0], !typeFile1);
0160       else
0161         name = items[0];
0162       double r1 = (items.size() > 1) ? atof(items[1].c_str()) : 0;
0163       double r2 = (items.size() > 2) ? atof(items[2].c_str()) : 0;
0164       double r3 = (items.size() > 3) ? atof(items[3].c_str()) : 0;
0165       if (type == 0) {
0166         auto it = matFile1.find(name);
0167         if (it == matFile1.end())
0168           matFile1[name] = materials(1, r1, r2);
0169         else
0170           ++((it->second).occ);
0171       } else if (type == 1) {
0172         auto it = solidFile1.find(name);
0173         if (it == solidFile1.end())
0174           solidFile1[name] = solids(1, r1);
0175         else
0176           ++((it->second).occ);
0177       } else if (type == 2) {
0178         auto it = lvFile1.find(name);
0179         if (it == lvFile1.end())
0180           lvFile1[name] = lvs(1, r1);
0181         else
0182           ++((it->second).occ);
0183       } else if (type == 3) {
0184         auto it = pvFile1.find(name);
0185         if (it == pvFile1.end())
0186           pvFile1[name] = pvs(1, r1, r2, r3);
0187         else
0188           ++((it->second).occ);
0189       } else {
0190         auto it = regFile1.find(name);
0191         if (it == regFile1.end())
0192           regFile1[name] = regions(1, r1, r2);
0193         else
0194           ++((it->second).occ);
0195       }
0196     }
0197     fInput1.close();
0198     sizeFile1 = ((type == 0) ? matFile1.size()
0199                              : ((type == 1) ? solidFile1.size() : ((type == 2) ? lvFile1.size() : pvFile1.size())));
0200   }
0201   std::ifstream fInput2(fileFile2);
0202   if (!fInput2.good()) {
0203     std::cout << "Cannot open file " << fileFile2 << std::endl;
0204   } else {
0205     while (fInput2.getline(buffer, 100)) {
0206       std::vector<std::string> items = splitString(std::string(buffer));
0207       if ((type == 0) || (type == 2))
0208         name = DD4hep2DDDName::nameMatterLV(items[0], !typeFile2);
0209       else if (type == 1)
0210         name = DD4hep2DDDName::nameSolid(items[0], !typeFile2);
0211       else if (type == 3)
0212         name = DD4hep2DDDName::namePV(items[0], !typeFile2);
0213       else
0214         name = items[0];
0215       double r1 = (items.size() > 1) ? atof(items[1].c_str()) : 0;
0216       double r2 = (items.size() > 2) ? atof(items[2].c_str()) : 0;
0217       double r3 = (items.size() > 3) ? atof(items[3].c_str()) : 0;
0218       if (type == 0) {
0219         auto it = matFile2.find(name);
0220         if (it == matFile2.end())
0221           matFile2[name] = materials(1, r1, r2);
0222         else
0223           ++((it->second).occ);
0224       } else if (type == 1) {
0225         auto it = solidFile2.find(name);
0226         if (it == solidFile2.end())
0227           solidFile2[name] = solids(1, r1);
0228         else
0229           ++((it->second).occ);
0230       } else if (type == 2) {
0231         auto it = lvFile2.find(name);
0232         if (it == lvFile2.end())
0233           lvFile2[name] = lvs(1, r1);
0234         else
0235           ++((it->second).occ);
0236       } else if (type == 3) {
0237         auto it = pvFile2.find(name);
0238         if (it == pvFile2.end())
0239           pvFile2[name] = pvs(1, r1, r2, r3);
0240         else
0241           ++((it->second).occ);
0242       } else {
0243         auto it = regFile2.find(name);
0244         if (it == regFile2.end())
0245           regFile2[name] = regions(1, r1, r2);
0246         else
0247           ++((it->second).occ);
0248       }
0249     }
0250     fInput2.close();
0251     sizeFile2 = ((type == 0) ? matFile2.size()
0252                              : ((type == 1) ? solidFile2.size() : ((type == 2) ? lvFile2.size() : pvFile2.size())));
0253   }
0254   std::cout << "Reads " << sizeFile1 << " names from " << fileFile1 << " and " << sizeFile2 << " names from "
0255             << fileFile2 << std::endl;
0256 
0257   std::cout << "\nMore than one entry for a given name in " << fileFile1 << std::endl;
0258   if (type == 0) {
0259     myPrint1(matFile1);
0260   } else if (type == 1) {
0261     myPrint1(solidFile1);
0262   } else if (type == 2) {
0263     myPrint1(lvFile1);
0264   } else if (type == 3) {
0265     myPrint1(pvFile1);
0266   } else {
0267     myPrint1(regFile1);
0268   }
0269 
0270   std::cout << "\nMore than one entry for a given name in " << fileFile2 << std::endl;
0271   if (type == 0) {
0272     myPrint1(matFile2);
0273   } else if (type == 1) {
0274     myPrint1(solidFile2);
0275   } else if (type == 2) {
0276     myPrint1(lvFile2);
0277   } else if (type == 3) {
0278     myPrint1(pvFile2);
0279   } else {
0280     myPrint1(regFile2);
0281   }
0282 
0283   std::cout << "\nEntry in " << fileFile1 << " not in " << fileFile2 << std::endl;
0284   if (type == 0) {
0285     myPrint2(matFile1, matFile2);
0286   } else if (type == 1) {
0287     myPrint2(solidFile1, solidFile2);
0288   } else if (type == 2) {
0289     myPrint2(lvFile1, lvFile2);
0290   } else if (type == 3) {
0291     myPrint2(pvFile1, pvFile2);
0292   } else {
0293     myPrint2(regFile1, regFile2);
0294   }
0295 
0296   std::cout << "\nEntry in " << fileFile2 << " not in " << fileFile1 << std::endl;
0297   if (type == 0) {
0298     myPrint2(matFile2, matFile1);
0299   } else if (type == 1) {
0300     myPrint2(solidFile2, solidFile1);
0301   } else if (type == 2) {
0302     myPrint2(lvFile2, lvFile1);
0303   } else if (type == 2) {
0304     myPrint2(pvFile2, pvFile1);
0305   } else {
0306     myPrint2(regFile2, regFile1);
0307   }
0308 
0309   //Now type specific changes
0310   std::cout << "\nEntries in " << fileFile1 << " and " << fileFile2 << " do not match in the content\n";
0311   const double denmin = 0.0001;
0312   int kount1(0), kount2(0);
0313   double difmax1(0), difmax2(0);
0314   std::string nameMax("");
0315   if (type == 0) {
0316     const double tol1 = 0.00001;
0317     for (auto it1 : matFile1) {
0318       auto it2 = matFile2.find(it1.first);
0319       if (it2 != matFile2.end()) {
0320         ++kount1;
0321         double rdif =
0322             0.5 * (it1.second.radl - it2->second.radl) / std::max(denmin, (it1.second.radl + it2->second.radl));
0323         double idif =
0324             0.5 * (it1.second.intl - it2->second.intl) / std::max(denmin, (it1.second.intl + it2->second.intl));
0325         if (std::abs(rdif) > difmax1) {
0326           difmax1 = std::abs(rdif);
0327           difmax2 = std::abs(idif);
0328           nameMax = it1.first;
0329         }
0330         if ((std::abs(rdif) > tol1) || (std::abs(idif) > tol1)) {
0331           ++kount2;
0332           std::cout << it1.first << " X0 " << it1.second.radl << ":" << it2->second.radl << ":" << rdif << " #L "
0333                     << it1.second.intl << ":" << it2->second.intl << ":" << idif << std::endl;
0334         }
0335       }
0336     }
0337     std::cout << "\n " << kount2 << " out of " << kount1 << " entries having discrpancies at the level of " << tol1
0338               << " or more; the maximum happens for " << nameMax << " with " << difmax1 << ":" << difmax2 << "\n";
0339   } else if (type == 1) {
0340     const double tol2 = 0.0001;
0341     for (auto it1 : solidFile1) {
0342       auto it2 = solidFile2.find(it1.first);
0343       if (it2 != solidFile2.end()) {
0344         ++kount1;
0345         double vdif =
0346             0.5 * (it1.second.volume - it2->second.volume) / std::max(denmin, (it1.second.volume + it2->second.volume));
0347         if (std::abs(vdif) > difmax1) {
0348           difmax1 = std::abs(vdif);
0349           nameMax = it1.first;
0350         }
0351         if (std::abs(vdif) > tol2) {
0352           ++kount2;
0353           std::cout << it1.first << " Volume " << it1.second.volume << ":" << it2->second.volume << ":" << vdif
0354                     << std::endl;
0355         }
0356       }
0357     }
0358     std::cout << "\n " << kount2 << " out of " << kount1 << " entries having discrpancies at the level of " << tol2
0359               << " or more; the maximum happens for " << nameMax << " with " << difmax1 << "\n";
0360   } else if (type == 2) {
0361     const double tol3 = 0.0001;
0362     for (auto it1 : lvFile1) {
0363       auto it2 = lvFile2.find(it1.first);
0364       if (it2 != lvFile2.end()) {
0365         ++kount1;
0366         double vdif =
0367             0.5 * (it1.second.mass - it2->second.mass) / std::max(denmin, (it1.second.mass + it2->second.mass));
0368         if (std::abs(vdif) > difmax1) {
0369           difmax1 = std::abs(vdif);
0370           nameMax = it1.first;
0371         }
0372         if (std::abs(vdif) > tol3) {
0373           ++kount2;
0374           std::cout << it1.first << " Mass " << it1.second.mass << ":" << it2->second.mass << ":" << vdif << std::endl;
0375         }
0376       }
0377     }
0378     std::cout << "\n " << kount2 << " out of " << kount1 << " entries having discrpancies at the level of " << tol3
0379               << " or more; the maximum happens for " << nameMax << " with " << difmax1 << "\n";
0380   } else if (type == 3) {
0381     const double tol4 = 0.0001;
0382     for (auto it1 : pvFile1) {
0383       auto it2 = pvFile2.find(it1.first);
0384       if (it2 != pvFile2.end()) {
0385         ++kount1;
0386         double xdif = (it1.second.xx - it2->second.xx);
0387         double ydif = (it1.second.yy - it2->second.yy);
0388         double zdif = (it1.second.zz - it2->second.zz);
0389         double vdif = std::max(std::abs(xdif), std::abs(ydif));
0390         vdif = std::max(vdif, std::abs(zdif));
0391         if (vdif > difmax1) {
0392           difmax1 = vdif;
0393           nameMax = it1.first;
0394         }
0395         if ((std::abs(xdif) > tol4) || (std::abs(ydif) > tol4) || (std::abs(zdif) > tol4)) {
0396           ++kount2;
0397           std::cout << it1.first << " x " << it1.second.xx << ":" << it2->second.xx << ":" << xdif << " y "
0398                     << it1.second.yy << ":" << it2->second.yy << ":" << ydif << " z " << it1.second.zz << ":"
0399                     << it2->second.zz << ":" << zdif << std::endl;
0400         }
0401       }
0402     }
0403     std::cout << "\n " << kount2 << " out of " << kount1 << " entries having discrpancies at the level of " << tol4
0404               << " or more; the maximum happens for " << nameMax << " with " << difmax1 << "\n";
0405   } else {
0406     const double tol5 = 0.0001;
0407     for (auto it1 : regFile1) {
0408       auto it2 = regFile2.find(it1.first);
0409       if (it2 != regFile2.end()) {
0410         ++kount1;
0411         double matdif = (it1.second.nmat - it2->second.nmat);
0412         double voldif = (it1.second.nvol - it2->second.nvol);
0413         if (std::abs(matdif) > difmax1) {
0414           difmax1 = std::abs(matdif);
0415           nameMax = it1.first;
0416         }
0417         if (std::abs(voldif) > difmax2) {
0418           difmax2 = std::abs(voldif);
0419           nameMax = it1.first;
0420         }
0421         if ((std::abs(matdif) > tol5) || (std::abs(voldif) > tol5)) {
0422           ++kount2;
0423           std::cout << it1.first << " Material " << it1.second.nmat << ":" << it2->second.nmat << ":" << matdif
0424                     << " Volume " << it1.second.nvol << ":" << it2->second.nvol << ":" << voldif << std::endl;
0425         }
0426       }
0427     }
0428     std::cout << "\n " << kount2 << " out of " << kount1 << " entries having discrpancies at the level of " << tol5
0429               << " or more; the maximum happens for " << nameMax << " with " << difmax1 << ":" << difmax2 << "\n";
0430   }
0431 }
0432 
0433 int main(int argc, char* argv[]) {
0434   if (argc <= 5) {
0435     std::cout << "Please give a minimum of 2 arguments \n"
0436               << "name of the first input file\n"
0437               << "name of the second input file\n"
0438               << "type (Material:0, Solid:1, LV:2, PV:3, Region:4)\n"
0439               << "files (10 if first file from DDD and second from DD4hep)\n"
0440               << "debug flag (0 for minimum printout)\n"
0441               << std::endl;
0442     return 0;
0443   }
0444 
0445   const char* infile1 = argv[1];
0446   const char* infile2 = argv[2];
0447   int type = ((argc > 3) ? atoi(argv[3]) : 0);
0448   if (type < 0 || type > 3)
0449     type = 0;
0450   int files = ((argc > 4) ? atoi(argv[4]) : 10);
0451   int debug = ((argc > 6) ? atoi(argv[6]) : 0);
0452   CompareFiles(infile1, infile2, type, files, debug);
0453   return 0;
0454 }