Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-11-09 23:35:32

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