Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-26 02:43:47

0001 #include <vector>
0002 #include <utility>
0003 #include <set>
0004 #include <cmath>
0005 #include <iostream>
0006 #include <fstream>
0007 #include <cstdlib>
0008 #include <cassert>
0009 
0010 #include "L1Trigger/TrackFindingTracklet/interface/TrackletConfigBuilder.h"
0011 #include "L1Trigger/TrackFindingTracklet/interface/Settings.h"
0012 
0013 using namespace std;
0014 using namespace trklet;
0015 
0016 TrackletConfigBuilder::TrackletConfigBuilder(const Settings& settings) : settings_(settings) {
0017   NSector_ = N_SECTOR;
0018   rcrit_ = settings.rcrit();
0019 
0020   combinedmodules_ = settings.combined();
0021 
0022   extended_ = settings.extended();
0023 
0024   rinvmax_ = settings.rinvmax();
0025 
0026   rmaxdisk_ = settings.rmaxdisk();
0027   zlength_ = settings.zlength();
0028 
0029   for (int i = 0; i < N_LAYER; i++) {
0030     rmean_[i] = settings.rmean(i);
0031   }
0032 
0033   for (int i = 0; i < N_DISK; i++) {
0034     zmean_[i] = settings.zmean(i);
0035   }
0036 
0037   dphisectorHG_ = settings.dphisectorHG();
0038 
0039   for (int layerdisk = 0; layerdisk < N_LAYER + N_DISK; layerdisk++) {
0040     NRegions_[layerdisk] = settings.nallstubs(layerdisk);
0041     NVMME_[layerdisk] = settings.nvmme(layerdisk);
0042   }
0043 
0044   for (unsigned int iseed = 0; iseed < N_SEED_PROMPT; iseed++) {
0045     NVMTE_[iseed] = std::pair<unsigned int, unsigned int>(settings.nvmte(0, iseed), settings.nvmte(1, iseed));
0046     NTC_[iseed] = settings.NTC(iseed);
0047   }
0048 
0049   initGeom();
0050 
0051   buildTE();
0052 
0053   buildTC();
0054 
0055   buildProjections();
0056 }
0057 
0058 std::pair<unsigned int, unsigned int> TrackletConfigBuilder::seedLayers(unsigned int iSeed) {
0059   return std::pair<unsigned int, unsigned int>(settings_.seedlayers(0, iSeed), settings_.seedlayers(1, iSeed));
0060 }
0061 
0062 void TrackletConfigBuilder::initGeom() {
0063   for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0064     double dphi = dphisectorHG_ / NRegions_[ilayer];
0065     for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0066       std::vector<std::pair<unsigned int, unsigned int> > emptyVec;
0067       projections_[ilayer].push_back(emptyVec);
0068       double phimin = dphi * iReg;
0069       double phimax = phimin + dphi;
0070       std::pair<double, double> tmp(phimin, phimax);
0071       allStubs_[ilayer].push_back(tmp);
0072       double dphiVM = dphi / NVMME_[ilayer];
0073       for (unsigned int iVM = 0; iVM < NVMME_[ilayer]; iVM++) {
0074         double phivmmin = phimin + iVM * dphiVM;
0075         double phivmmax = phivmmin + dphiVM;
0076         std::pair<double, double> tmp(phivmmin, phivmmax);
0077         VMStubsME_[ilayer].push_back(tmp);
0078       }
0079     }
0080   }
0081   for (unsigned int iseed = 0; iseed < N_SEED_PROMPT; iseed++) {
0082     unsigned int l1 = seedLayers(iseed).first;
0083     unsigned int l2 = seedLayers(iseed).second;
0084     unsigned int nVM1 = NVMTE_[iseed].first;
0085     unsigned int nVM2 = NVMTE_[iseed].second;
0086     double dphiVM = dphisectorHG_ / (nVM1 * NRegions_[l1]);
0087     for (unsigned int iVM = 0; iVM < nVM1 * NRegions_[l1]; iVM++) {
0088       double phivmmin = iVM * dphiVM;
0089       double phivmmax = phivmmin + dphiVM;
0090       std::pair<double, double> tmp(phivmmin, phivmmax);
0091       VMStubsTE_[iseed].first.push_back(tmp);
0092     }
0093     dphiVM = dphisectorHG_ / (nVM2 * NRegions_[l2]);
0094     for (unsigned int iVM = 0; iVM < nVM2 * NRegions_[l2]; iVM++) {
0095       double phivmmin = iVM * dphiVM;
0096       double phivmmax = phivmmin + dphiVM;
0097       std::pair<double, double> tmp(phivmmin, phivmmax);
0098       VMStubsTE_[iseed].second.push_back(tmp);
0099     }
0100   }
0101 }
0102 
0103 std::pair<double, double> TrackletConfigBuilder::seedRadii(unsigned int iseed) {
0104   std::pair<unsigned int, unsigned int> seedlayers = seedLayers(iseed);
0105 
0106   unsigned int l1 = seedlayers.first;
0107   unsigned int l2 = seedlayers.second;
0108 
0109   double r1, r2;
0110 
0111   if (iseed < 4) {  //barrel seeding
0112     r1 = rmean_[l1];
0113     r2 = rmean_[l2];
0114   } else if (iseed < 6) {   //disk seeding
0115     r1 = rmean_[0] + 40.0;  //Somwwhat of a hack - but allows finding all the regions
0116     //when projecting to L1
0117     r2 = r1 * zmean_[l2 - 6] / zmean_[l1 - 6];
0118   } else {  //overlap seeding
0119     r1 = rmean_[l1];
0120     r2 = r1 * zmean_[l2 - 6] / zlength_;
0121   }
0122 
0123   return std::pair<double, double>(r1, r2);
0124 }
0125 
0126 bool TrackletConfigBuilder::validTEPair(unsigned int iseed, unsigned int iTE1, unsigned int iTE2) {
0127   double rinvmin = 999.9;
0128   double rinvmax = -999.9;
0129 
0130   double phi1[2] = {VMStubsTE_[iseed].first[iTE1].first, VMStubsTE_[iseed].first[iTE1].second};
0131   double phi2[2] = {VMStubsTE_[iseed].second[iTE2].first, VMStubsTE_[iseed].second[iTE2].second};
0132 
0133   std::pair<double, double> seedradii = seedRadii(iseed);
0134 
0135   for (unsigned int i1 = 0; i1 < 2; i1++) {
0136     for (unsigned int i2 = 0; i2 < 2; i2++) {
0137       double arinv = rinv(seedradii.first, phi1[i1], seedradii.second, phi2[i2]);
0138       if (arinv < rinvmin)
0139         rinvmin = arinv;
0140       if (arinv > rinvmax)
0141         rinvmax = arinv;
0142     }
0143   }
0144 
0145   if (rinvmin > rinvmax_)
0146     return false;
0147   if (rinvmax < -rinvmax_)
0148     return false;
0149 
0150   return true;
0151 }
0152 
0153 void TrackletConfigBuilder::buildTE() {
0154   for (unsigned int iseed = 0; iseed < N_SEED_PROMPT; iseed++) {
0155     for (unsigned int i1 = 0; i1 < VMStubsTE_[iseed].first.size(); i1++) {
0156       for (unsigned int i2 = 0; i2 < VMStubsTE_[iseed].second.size(); i2++) {
0157         if (validTEPair(iseed, i1, i2)) {
0158           std::pair<unsigned int, unsigned int> tmp(i1, i2);
0159           TE_[iseed].push_back(tmp);
0160         }
0161       }
0162     }
0163   }
0164 }
0165 
0166 void TrackletConfigBuilder::buildTC() {
0167   for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0168     unsigned int nTC = NTC_[iSeed];
0169     std::vector<std::pair<unsigned int, unsigned int> >& TEs = TE_[iSeed];
0170     std::vector<std::vector<unsigned int> >& TCs = TC_[iSeed];
0171 
0172     //Very naive method to group TEs in TC
0173 
0174     double invnTC = nTC * (1.0 / TEs.size());
0175 
0176     for (unsigned int iTE = 0; iTE < TEs.size(); iTE++) {
0177       int iTC = invnTC * iTE;
0178       assert(iTC < (int)nTC);
0179       if (iTC >= (int)TCs.size()) {
0180         std::vector<unsigned int> tmp;
0181         tmp.push_back(iTE);
0182         TCs.push_back(tmp);
0183       } else {
0184         TCs[iTC].push_back(iTE);
0185       }
0186     }
0187   }
0188 }
0189 
0190 std::pair<double, double> TrackletConfigBuilder::seedPhiRange(double rproj, unsigned int iSeed, unsigned int iTC) {
0191   std::vector<std::vector<unsigned int> >& TCs = TC_[iSeed];
0192 
0193   std::pair<double, double> seedradii = seedRadii(iSeed);
0194 
0195   double phimin = 999.0;
0196   double phimax = -999.0;
0197   for (unsigned int iTE = 0; iTE < TCs[iTC].size(); iTE++) {
0198     unsigned int theTE = TCs[iTC][iTE];
0199     unsigned int l1TE = TE_[iSeed][theTE].first;
0200     unsigned int l2TE = TE_[iSeed][theTE].second;
0201     double phi1[2] = {VMStubsTE_[iSeed].first[l1TE].first, VMStubsTE_[iSeed].first[l1TE].second};
0202     double phi2[2] = {VMStubsTE_[iSeed].second[l2TE].first, VMStubsTE_[iSeed].second[l2TE].second};
0203     for (unsigned int i1 = 0; i1 < 2; i1++) {
0204       for (unsigned int i2 = 0; i2 < 2; i2++) {
0205         double aphi = phi(seedradii.first, phi1[i1], seedradii.second, phi2[i2], rproj);
0206         if (aphi < phimin)
0207           phimin = aphi;
0208         if (aphi > phimax)
0209           phimax = aphi;
0210       }
0211     }
0212   }
0213   return std::pair<double, double>(phimin, phimax);
0214 }
0215 
0216 void TrackletConfigBuilder::buildProjections() {
0217   for (unsigned int iseed = 0; iseed < N_SEED_PROMPT; iseed++) {
0218     std::vector<std::vector<unsigned int> >& TCs = TC_[iseed];
0219 
0220     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0221       if (matchport_[iseed][ilayer] == -1)
0222         continue;
0223       for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0224         for (unsigned int iTC = 0; iTC < TCs.size(); iTC++) {
0225           double rproj = rmaxdisk_;
0226           if (ilayer < 6)
0227             rproj = rmean_[ilayer];
0228           std::pair<double, double> phiRange = seedPhiRange(rproj, iseed, iTC);
0229           if (phiRange.first < allStubs_[ilayer][iReg].second && phiRange.second > allStubs_[ilayer][iReg].first) {
0230             std::pair<unsigned int, unsigned int> tmp(iseed, iTC);  //seedindex and TC
0231             projections_[ilayer][iReg].push_back(tmp);
0232           }
0233         }
0234       }
0235     }
0236   }
0237 }
0238 
0239 double TrackletConfigBuilder::phi(double r1, double phi1, double r2, double phi2, double r) {
0240   double rhoinv = rinv(r1, phi1, r2, phi2);
0241   if (std::abs(rhoinv) > rinvmax_) {
0242     rhoinv = rinvmax_ * rhoinv / std::abs(rhoinv);
0243   }
0244   return phi1 + asin(0.5 * r * rhoinv) - asin(0.5 * r1 * rhoinv);
0245 }
0246 
0247 double TrackletConfigBuilder::rinv(double r1, double phi1, double r2, double phi2) {
0248   double deltaphi = phi1 - phi2;
0249   return 2 * sin(deltaphi) / sqrt(r2 * r2 + r1 * r1 - 2 * r1 * r2 * cos(deltaphi));
0250 }
0251 
0252 std::string TrackletConfigBuilder::iSeedStr(unsigned int iSeed) {
0253   static std::string name[8] = {"L1L2", "L2L3", "L3L4", "L5L6", "D1D2", "D3D4", "L1D1", "L2D1"};
0254 
0255   assert(iSeed < 8);
0256   return name[iSeed];
0257 }
0258 
0259 std::string TrackletConfigBuilder::numStr(unsigned int i) {
0260   static std::string num[32] = {"1",  "2",  "3",  "4",  "5",  "6",  "7",  "8",  "9",  "10", "11",
0261                                 "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22",
0262                                 "23", "24", "25", "26", "27", "28", "29", "30", "31", "32"};
0263   assert(i < 32);
0264   return num[i];
0265 }
0266 
0267 std::string TrackletConfigBuilder::iTCStr(unsigned int iTC) {
0268   static std::string name[12] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"};
0269 
0270   assert(iTC < 12);
0271   return name[iTC];
0272 }
0273 
0274 std::string TrackletConfigBuilder::iRegStr(unsigned int iReg, unsigned int iSeed) {
0275   static std::string name[8] = {"A", "B", "C", "D", "E", "F", "G", "H"};
0276 
0277   static std::string nameOverlap[8] = {"X", "Y", "Z", "W", "Q", "R", "S", "T"};
0278 
0279   static std::string nameL2L3[4] = {"I", "J", "K", "L"};
0280 
0281   if (iSeed == Seed::L2L3) {
0282     assert(iReg < 4);
0283     return nameL2L3[iReg];
0284   }
0285   if (iSeed == Seed::L1D1 || iSeed == Seed::L2D1) {
0286     assert(iReg < 8);
0287     return nameOverlap[iReg];
0288   }
0289   assert(iReg < 8);
0290   return name[iReg];
0291 }
0292 
0293 std::string TrackletConfigBuilder::TCName(unsigned int iSeed, unsigned int iTC) {
0294   if (combinedmodules_) {
0295     return "TP_" + iSeedStr(iSeed) + iTCStr(iTC);
0296   } else {
0297     return "TC_" + iSeedStr(iSeed) + iTCStr(iTC);
0298   }
0299 }
0300 
0301 std::string TrackletConfigBuilder::LayerName(unsigned int ilayer) {
0302   return ilayer < 6 ? ("L" + numStr(ilayer)) : ("D" + numStr(ilayer - 6));
0303 }
0304 
0305 std::string TrackletConfigBuilder::TPROJName(unsigned int iSeed,
0306                                              unsigned int iTC,
0307                                              unsigned int ilayer,
0308                                              unsigned int ireg) {
0309   return "TPROJ_" + iSeedStr(iSeed) + iTCStr(iTC) + "_" + LayerName(ilayer) + "PHI" + iTCStr(ireg);
0310 }
0311 
0312 std::string TrackletConfigBuilder::PRName(unsigned int ilayer, unsigned int ireg) {
0313   if (combinedmodules_) {
0314     return "MP_" + LayerName(ilayer) + "PHI" + iTCStr(ireg);
0315   } else {
0316     return "PR_" + LayerName(ilayer) + "PHI" + iTCStr(ireg);
0317   }
0318 }
0319 
0320 void TrackletConfigBuilder::writeProjectionMemories(std::ostream& os, std::ostream& memories, std::ostream&) {
0321   for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0322     for (unsigned int ireg = 0; ireg < projections_[ilayer].size(); ireg++) {
0323       for (unsigned int imem = 0; imem < projections_[ilayer][ireg].size(); imem++) {
0324         unsigned int iSeed = projections_[ilayer][ireg][imem].first;
0325         unsigned int iTC = projections_[ilayer][ireg][imem].second;
0326 
0327         memories << "TrackletProjections: " + TPROJName(iSeed, iTC, ilayer, ireg) + " [54]" << std::endl;
0328 
0329         os << TPROJName(iSeed, iTC, ilayer, ireg) << " input=> " << TCName(iSeed, iTC) << ".projout"
0330            << LayerName(ilayer) << "PHI" << iTCStr(ireg) << " output=> " << PRName(ilayer, ireg) << ".projin"
0331            << std::endl;
0332       }
0333     }
0334   }
0335 }
0336 
0337 std::string TrackletConfigBuilder::SPName(unsigned int l1,
0338                                           unsigned int ireg1,
0339                                           unsigned int ivm1,
0340                                           unsigned int l2,
0341                                           unsigned int ireg2,
0342                                           unsigned int ivm2,
0343                                           unsigned int iseed) {
0344   return "SP_" + LayerName(l1) + "PHI" + iRegStr(ireg1, iseed) + numStr(ivm1) + "_" + LayerName(l2) + "PHI" +
0345          iRegStr(ireg2, iseed) + numStr(ivm2);
0346 }
0347 
0348 std::string TrackletConfigBuilder::SPDName(unsigned int l1,
0349                                            unsigned int ireg1,
0350                                            unsigned int ivm1,
0351                                            unsigned int l2,
0352                                            unsigned int ireg2,
0353                                            unsigned int ivm2,
0354                                            unsigned int l3,
0355                                            unsigned int ireg3,
0356                                            unsigned int ivm3,
0357                                            unsigned int iseed) {
0358   return "SPD_" + LayerName(l1) + "PHI" + iRegStr(ireg1, iseed) + numStr(ivm1) + "_" + LayerName(l2) + "PHI" +
0359          iRegStr(ireg2, iseed) + numStr(ivm2) + "_" + LayerName(l3) + "PHI" + iRegStr(ireg3, iseed) + numStr(ivm3);
0360 }
0361 
0362 std::string TrackletConfigBuilder::TEName(unsigned int l1,
0363                                           unsigned int ireg1,
0364                                           unsigned int ivm1,
0365                                           unsigned int l2,
0366                                           unsigned int ireg2,
0367                                           unsigned int ivm2,
0368                                           unsigned int iseed) {
0369   return "TE_" + LayerName(l1) + "PHI" + iRegStr(ireg1, iseed) + numStr(ivm1) + "_" + LayerName(l2) + "PHI" +
0370          iRegStr(ireg2, iseed) + numStr(ivm2);
0371 }
0372 
0373 std::string TrackletConfigBuilder::TEDName(unsigned int l1,
0374                                            unsigned int ireg1,
0375                                            unsigned int ivm1,
0376                                            unsigned int l2,
0377                                            unsigned int ireg2,
0378                                            unsigned int ivm2,
0379                                            unsigned int iseed) {
0380   return "TED_" + LayerName(l1) + "PHI" + iRegStr(ireg1, iseed) + numStr(ivm1) + "_" + LayerName(l2) + "PHI" +
0381          iRegStr(ireg2, iseed) + numStr(ivm2);
0382 }
0383 
0384 std::string TrackletConfigBuilder::TParName(unsigned int l1, unsigned int l2, unsigned int l3, unsigned int itc) {
0385   return "TPAR_" + LayerName(l1) + LayerName(l2) + LayerName(l3) + iTCStr(itc);
0386 }
0387 
0388 std::string TrackletConfigBuilder::TCDName(unsigned int l1, unsigned int l2, unsigned int l3, unsigned int itc) {
0389   return "TCD_" + LayerName(l1) + LayerName(l2) + LayerName(l3) + iTCStr(itc);
0390 }
0391 
0392 std::string TrackletConfigBuilder::TPROJName(
0393     unsigned int l1, unsigned int l2, unsigned int l3, unsigned int itc, unsigned int projlayer, unsigned int projreg) {
0394   return "TPROJ_" + LayerName(l1) + LayerName(l2) + LayerName(l3) + iTCStr(itc) + "_" + LayerName(projlayer) + "PHI" +
0395          iTCStr(projreg);
0396 }
0397 
0398 std::string TrackletConfigBuilder::FTName(unsigned int l1, unsigned int l2, unsigned int l3) {
0399   return "FT_" + LayerName(l1) + LayerName(l2) + LayerName(l3);
0400 }
0401 
0402 std::string TrackletConfigBuilder::TREName(
0403     unsigned int l1, unsigned int ireg1, unsigned int l2, unsigned int ireg2, unsigned int iseed, unsigned int count) {
0404   return "TRE_" + LayerName(l1) + iRegStr(ireg1, iseed) + LayerName(l2) + iRegStr(ireg2, iseed) + "_" + numStr(count);
0405 }
0406 
0407 std::string TrackletConfigBuilder::STName(unsigned int l1,
0408                                           unsigned int ireg1,
0409                                           unsigned int l2,
0410                                           unsigned int ireg2,
0411                                           unsigned int l3,
0412                                           unsigned int ireg3,
0413                                           unsigned int iseed,
0414                                           unsigned int count) {
0415   return "ST_" + LayerName(l1) + iRegStr(ireg1, iseed) + LayerName(l2) + iRegStr(ireg2, iseed) + "_" + LayerName(l3) +
0416          iRegStr(ireg3, iseed) + "_" + numStr(count);
0417 }
0418 
0419 std::string TrackletConfigBuilder::TCNAme(unsigned int iseed, unsigned int iTC) {
0420   return "TC_" + iSeedStr(iseed) + iTCStr(iTC);
0421 }
0422 
0423 void TrackletConfigBuilder::writeSPMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
0424   if (combinedmodules_)
0425     return;
0426 
0427   for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0428     for (unsigned int iTC = 0; iTC < TC_[iSeed].size(); iTC++) {
0429       for (unsigned int iTE = 0; iTE < TC_[iSeed][iTC].size(); iTE++) {
0430         unsigned int theTE = TC_[iSeed][iTC][iTE];
0431 
0432         unsigned int TE1 = TE_[iSeed][theTE].first;
0433         unsigned int TE2 = TE_[iSeed][theTE].second;
0434 
0435         unsigned int l1 = seedLayers(iSeed).first;
0436         unsigned int l2 = seedLayers(iSeed).second;
0437 
0438         memories << "StubPairs: "
0439                  << SPName(l1, TE1 / NVMTE_[iSeed].first, TE1, l2, TE2 / NVMTE_[iSeed].second, TE2, iSeed) << " [12]"
0440                  << std::endl;
0441         modules << "TrackletEngine: "
0442                 << TEName(l1, TE1 / NVMTE_[iSeed].first, TE1, l2, TE2 / NVMTE_[iSeed].second, TE2, iSeed) << std::endl;
0443 
0444         os << SPName(l1, TE1 / NVMTE_[iSeed].first, TE1, l2, TE2 / NVMTE_[iSeed].second, TE2, iSeed) << " input=> "
0445            << TEName(l1, TE1 / NVMTE_[iSeed].first, TE1, l2, TE2 / NVMTE_[iSeed].second, TE2, iSeed)
0446            << ".stubpairout output=> " << TCNAme(iSeed, iTC) << ".stubpairin" << std::endl;
0447       }
0448     }
0449   }
0450 }
0451 
0452 void TrackletConfigBuilder::writeSPDMemories(std::ostream& wires, std::ostream& memories, std::ostream& modules) {
0453   if (!extended_)
0454     return;
0455 
0456   vector<string> stubTriplets[N_SEED];
0457 
0458   for (unsigned int iSeed = N_SEED_PROMPT; iSeed < N_SEED; iSeed++) {
0459     int layerdisk1 = settings_.seedlayers(0, iSeed);
0460     int layerdisk2 = settings_.seedlayers(1, iSeed);
0461     int layerdisk3 = settings_.seedlayers(2, iSeed);
0462 
0463     unsigned int nallstub1 = settings_.nallstubs(layerdisk1);
0464     unsigned int nallstub2 = settings_.nallstubs(layerdisk2);
0465     unsigned int nallstub3 = settings_.nallstubs(layerdisk3);
0466 
0467     unsigned int nvm1 = settings_.nvmte(0, iSeed);
0468     unsigned int nvm2 = settings_.nvmte(1, iSeed);
0469     unsigned int nvm3 = settings_.nvmte(2, iSeed);
0470 
0471     int count = 0;
0472     for (unsigned int ireg1 = 0; ireg1 < nallstub1; ireg1++) {
0473       for (unsigned int ireg2 = 0; ireg2 < nallstub2; ireg2++) {
0474         for (unsigned int ireg3 = 0; ireg3 < nallstub3; ireg3++) {
0475           count++;
0476           memories << "StubTriplets: " << STName(layerdisk1, ireg1, layerdisk2, ireg2, layerdisk3, ireg3, iSeed, count)
0477                    << " [18]" << std::endl;
0478           stubTriplets[iSeed].push_back(STName(layerdisk1, ireg1, layerdisk2, ireg2, layerdisk3, ireg3, iSeed, count));
0479         }
0480       }
0481     }
0482 
0483     for (unsigned int ireg1 = 0; ireg1 < nallstub1; ireg1++) {
0484       for (unsigned int ivm1 = 0; ivm1 < nvm1; ivm1++) {
0485         for (unsigned int ireg2 = 0; ireg2 < nallstub2; ireg2++) {
0486           for (unsigned int ivm2 = 0; ivm2 < nvm2; ivm2++) {
0487             int count = 0;
0488 
0489             modules << "TrackletEngineDisplaced: "
0490                     << TEDName(layerdisk1, ireg1, ireg1 * nvm1 + ivm1, layerdisk2, ireg2, ireg2 * nvm2 + ivm2, iSeed)
0491                     << std::endl;
0492 
0493             for (unsigned int ireg3 = 0; ireg3 < nallstub3; ireg3++) {
0494               for (unsigned int ivm3 = 0; ivm3 < nvm3; ivm3++) {
0495                 count++;
0496 
0497                 memories << "StubPairsDisplaced: "
0498                          << SPDName(layerdisk1,
0499                                     ireg1,
0500                                     ireg1 * nvm1 + ivm1,
0501                                     layerdisk2,
0502                                     ireg2,
0503                                     ireg2 * nvm2 + ivm2,
0504                                     layerdisk3,
0505                                     ireg3,
0506                                     ireg3 * nvm3 + ivm3,
0507                                     iSeed)
0508                          << " [12]" << std::endl;
0509 
0510                 modules << "TripletEngine: " << TREName(layerdisk1, ireg1, layerdisk2, ireg2, iSeed, count)
0511                         << std::endl;
0512 
0513                 wires << SPDName(layerdisk1,
0514                                  ireg1,
0515                                  ireg1 * nvm1 + ivm1,
0516                                  layerdisk2,
0517                                  ireg2,
0518                                  ireg2 * nvm2 + ivm2,
0519                                  layerdisk3,
0520                                  ireg3,
0521                                  ireg3 * nvm3 + ivm3,
0522                                  iSeed)
0523                       << " input=> "
0524                       << TEDName(layerdisk1, ireg1, ireg1 * nvm1 + ivm1, layerdisk2, ireg2, ireg2 * nvm2 + ivm2, iSeed)
0525                       << ".stubpairout output=> " << TREName(layerdisk1, ireg1, layerdisk2, ireg2, iSeed, count)
0526                       << ".stubpair"
0527                       << "1"
0528                       << "in" << std::endl;
0529               }
0530             }
0531           }
0532         }
0533       }
0534     }
0535 
0536     unsigned int nTC = 10;
0537     for (unsigned int itc = 0; itc < nTC; itc++) {
0538       for (int iproj = 0; iproj < 4; iproj++) {
0539         int ilay = settings_.projlayers(iSeed, iproj);
0540         if (ilay > 0) {
0541           unsigned int nallstub = settings_.nallstubs(ilay - 1);
0542           for (unsigned int ireg = 0; ireg < nallstub; ireg++) {
0543             memories << "TrackletProjections: " << TPROJName(layerdisk1, layerdisk2, layerdisk3, itc, ilay - 1, ireg)
0544                      << " [54]" << std::endl;
0545           }
0546         }
0547 
0548         int idisk = settings_.projdisks(iSeed, iproj);
0549         if (idisk > 0) {
0550           unsigned int nallstub = settings_.nallstubs(idisk + 5);
0551           for (unsigned int ireg = 0; ireg < nallstub; ireg++) {
0552             memories << "TrackletProjections: " << TPROJName(layerdisk1, layerdisk2, layerdisk3, itc, idisk + 5, ireg)
0553                      << " [54]" << std::endl;
0554 
0555             wires << TPROJName(layerdisk1, layerdisk2, layerdisk3, itc, idisk + 5, ireg) << " input=> "
0556                   << TCDName(layerdisk1, layerdisk2, layerdisk3, itc) << ".projout" << LayerName(idisk + 1) << "PHI"
0557                   << iTCStr(ireg) << " output=> "
0558                   << "PR_" << LayerName(idisk + 1) << "PHI" << iTCStr(ireg) << ".projin" << std::endl;
0559           }
0560         }
0561       }
0562 
0563       memories << "TrackletParameters: " << TParName(layerdisk1, layerdisk2, layerdisk3, itc) << " [56]" << std::endl;
0564 
0565       modules << "TrackletCalculatorDisplaced: " << TCDName(layerdisk1, layerdisk2, layerdisk3, itc) << std::endl;
0566     }
0567 
0568     unsigned int nST = stubTriplets[iSeed].size();
0569     for (unsigned int iST = 0; iST < nST; iST++) {
0570       unsigned int iTC = (iST * nTC) / nST;
0571       assert(iTC < nTC);
0572       string stname = stubTriplets[iSeed][iST];
0573       string trename = "TRE_" + stname.substr(3, 6) + "_";
0574       unsigned int stlen = stname.size();
0575       if (stname[stlen - 2] == '_')
0576         trename += stname.substr(stlen - 1, 1);
0577       if (stname[stlen - 3] == '_')
0578         trename += stname.substr(stlen - 2, 2);
0579       wires << stname << " input=> " << trename << ".stubtripout output=> "
0580             << TCDName(layerdisk1, layerdisk2, layerdisk3, iTC) << ".stubtriplet" << ((iST * nTC) % nST) << "in"
0581             << std::endl;
0582     }
0583 
0584     modules << "FitTrack: " << FTName(layerdisk1, layerdisk2, layerdisk3) << std::endl;
0585   }
0586 }
0587 
0588 void TrackletConfigBuilder::writeAPMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
0589   if (combinedmodules_)
0590     return;
0591 
0592   for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0593     for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0594       memories << "AllProj: AP_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << " [56]" << std::endl;
0595       modules << "ProjectionRouter: PR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << std::endl;
0596 
0597       os << "AP_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << " input=> PR_" << LayerName(ilayer) << "PHI"
0598          << iTCStr(iReg) << ".allprojout output=> MC_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".allprojin"
0599          << std::endl;
0600     }
0601   }
0602 }
0603 
0604 void TrackletConfigBuilder::writeCMMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
0605   if (combinedmodules_)
0606     return;
0607 
0608   for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0609     for (unsigned int iME = 0; iME < NVMME_[ilayer] * NRegions_[ilayer]; iME++) {
0610       memories << "CandidateMatch: CM_" << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << iME + 1
0611                << " [12]" << std::endl;
0612       modules << "MatchEngine: ME_" << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << iME + 1
0613               << std::endl;
0614 
0615       os << "CM_" << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << iME + 1 << " input=> ME_"
0616          << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << iME + 1 << ".matchout output=> MC_"
0617          << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << ".matchin" << std::endl;
0618     }
0619   }
0620 }
0621 
0622 void TrackletConfigBuilder::writeVMPROJMemories(std::ostream& os, std::ostream& memories, std::ostream&) {
0623   if (combinedmodules_)
0624     return;
0625 
0626   for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0627     for (unsigned int iME = 0; iME < NVMME_[ilayer] * NRegions_[ilayer]; iME++) {
0628       memories << "VMProjections: VMPROJ_" << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << iME + 1
0629                << " [13]" << std::endl;
0630 
0631       os << "VMPROJ_" << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << iME + 1 << " input=> PR_"
0632          << LayerName(ilayer) << "PHI" << iTCStr(iME / NVMME_[ilayer]) << ".vmprojout"
0633          << "PHI" << iTCStr(iME / NVMME_[ilayer]) << iME + 1 << " output=> ME_" << LayerName(ilayer) << "PHI"
0634          << iTCStr(iME / NVMME_[ilayer]) << iME + 1 << ".vmprojin" << std::endl;
0635     }
0636   }
0637 }
0638 
0639 void TrackletConfigBuilder::writeFMMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
0640   if (combinedmodules_) {
0641     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0642       for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0643         modules << "MatchProcessor: MP_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << std::endl;
0644         for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0645           if (matchport_[iSeed][ilayer] == -1)
0646             continue;
0647           memories << "FullMatch: FM_" << iSeedStr(iSeed) << "_" << LayerName(ilayer) << "PHI" << iTCStr(iReg)
0648                    << " [36]" << std::endl;
0649           os << "FM_" << iSeedStr(iSeed) << "_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << " input=> MP_"
0650              << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".matchout1 output=> FT_" << iSeedStr(iSeed)
0651              << ".fullmatch" << matchport_[iSeed][ilayer] << "in" << iReg + 1 << std::endl;
0652         }
0653       }
0654     }
0655   } else {
0656     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0657       for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0658         modules << "MatchCalculator: MC_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << std::endl;
0659         for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0660           if (matchport_[iSeed][ilayer] == -1)
0661             continue;
0662           memories << "FullMatch: FM_" << iSeedStr(iSeed) << "_" << LayerName(ilayer) << "PHI" << iTCStr(iReg)
0663                    << " [36]" << std::endl;
0664           os << "FM_" << iSeedStr(iSeed) << "_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << " input=> MC_"
0665              << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".matchout1 output=> FT_" << iSeedStr(iSeed)
0666              << ".fullmatch" << matchport_[iSeed][ilayer] << "in" << iReg + 1 << std::endl;
0667         }
0668       }
0669     }
0670   }
0671 }
0672 
0673 void TrackletConfigBuilder::writeASMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
0674   if (combinedmodules_) {
0675     //First write AS memories used by MatchProcessor
0676     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0677       for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0678         memories << "AllStubs: AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n1"
0679                  << " [42]" << std::endl;
0680         if (combinedmodules_) {
0681           modules << "VMRouterCM: VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << std::endl;
0682         } else {
0683           modules << "VMRouter: VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << std::endl;
0684         }
0685         os << "AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n1"
0686            << " input=> VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".allstubout output=> MP_"
0687            << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".allstubin" << std::endl;
0688       }
0689     }
0690 
0691     //Next write AS memories used by TrackletProcessor
0692     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0693       for (int iReg = 0; iReg < (int)NRegions_[ilayer]; iReg++) {
0694         unsigned int nmem = 1;
0695 
0696         for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0697           unsigned int l1 = seedLayers(iSeed).first;
0698           unsigned int l2 = seedLayers(iSeed).second;
0699 
0700           if (ilayer != l1 && ilayer != l2)
0701             continue;
0702 
0703           bool inner = ilayer == l1;
0704 
0705           for (unsigned int iTC = 0; iTC < TC_[iSeed].size(); iTC++) {
0706             int nTCReg = TC_[iSeed].size() / NRegions_[l2];
0707 
0708             int iTCReg = iTC / nTCReg;
0709 
0710             int jTCReg = iTC % nTCReg;
0711 
0712             if (ilayer == l2) {
0713               if (iTCReg != iReg)
0714                 continue;
0715             }
0716 
0717             string ext = "";
0718 
0719             if (ilayer == l1) {
0720               int ratio = NRegions_[l1] / NRegions_[l2];
0721               int min = iTCReg * ratio - 1 + jTCReg;
0722               int max = (iTCReg + 1) * ratio - (nTCReg - jTCReg - 1);
0723               if ((int)iReg < min || (int)iReg > max)
0724                 continue;
0725 
0726               if (max - min >= 2) {
0727                 ext = "M";
0728                 if (iReg == min)
0729                   ext = "R";
0730                 if (iReg == max)
0731                   ext = "L";
0732               }
0733 
0734               if (max - min == 1) {
0735                 if (nTCReg == 2) {
0736                   assert(0);
0737                   if (jTCReg == 0) {
0738                     if (iReg == min)
0739                       ext = "R";
0740                     if (iReg == max)
0741                       ext = "B";
0742                   }
0743                   if (jTCReg == 1) {
0744                     if (iReg == min)
0745                       ext = "A";
0746                     if (iReg == max)
0747                       ext = "L";
0748                   }
0749                 }
0750                 if (nTCReg == 3) {
0751                   if (jTCReg == 0) {
0752                     if (iReg == min)
0753                       ext = "A";
0754                     if (iReg == max)
0755                       ext = "F";
0756                   }
0757                   if (jTCReg == 1) {
0758                     if (iReg == min)
0759                       ext = "E";
0760                     if (iReg == max)
0761                       ext = "D";
0762                   }
0763                   if (jTCReg == 2) {
0764                     if (iReg == min)
0765                       ext = "C";
0766                     if (iReg == max)
0767                       ext = "B";
0768                   }
0769                 }
0770               }
0771               assert(!ext.empty());
0772             }
0773 
0774             if (ext.empty()) {
0775               ext = "_" + LayerName(l1) + iTCStr(iTC);
0776             }
0777 
0778             if (iSeed < 4) {  //Barrel seeding
0779               ext = "_B" + ext;
0780             } else if (iSeed > 5) {
0781               ext = "_O" + ext;
0782             } else {
0783               ext = "_D" + ext;
0784             }
0785 
0786             nmem++;
0787             if (inner) {
0788               memories << "AllInnerStubs: ";
0789             } else {
0790               memories << "AllStubs: ";
0791             }
0792             memories << "AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ext << " [42]" << std::endl;
0793             os << "AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ext << " input=> VMR_" << LayerName(ilayer)
0794                << "PHI" << iTCStr(iReg) << ".all" << (inner ? "inner" : "") << "stubout output=> TP_" << iSeedStr(iSeed)
0795                << iTCStr(iTC);
0796             if (inner) {
0797               os << ".innerallstubin" << std::endl;
0798             } else {
0799               os << ".outerallstubin" << std::endl;
0800             }
0801           }
0802         }
0803       }
0804     }
0805   } else {
0806     //First write AS memories used by MatchCalculator
0807     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0808       for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0809         memories << "AllStubs: AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n1"
0810                  << " [42]" << std::endl;
0811         if (combinedmodules_) {
0812           modules << "VMRouterCM: VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << std::endl;
0813         } else {
0814           modules << "VMRouter: VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << std::endl;
0815         }
0816         os << "AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n1"
0817            << " input=> VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".allstubout output=> MC_"
0818            << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".allstubin" << std::endl;
0819       }
0820     }
0821 
0822     //Next write AS memories used by TrackletCalculator
0823     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0824       for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0825         unsigned int nmem = 1;
0826 
0827         for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0828           unsigned int l1 = seedLayers(iSeed).first;
0829           unsigned int l2 = seedLayers(iSeed).second;
0830 
0831           if (ilayer != l1 && ilayer != l2)
0832             continue;
0833 
0834           for (unsigned int iTC = 0; iTC < TC_[iSeed].size(); iTC++) {
0835             bool used = false;
0836             for (unsigned int iTE = 0; iTE < TC_[iSeed][iTC].size(); iTE++) {
0837               unsigned int theTE = TC_[iSeed][iTC][iTE];
0838 
0839               unsigned int TE1 = TE_[iSeed][theTE].first;
0840               unsigned int TE2 = TE_[iSeed][theTE].second;
0841 
0842               if (l1 == ilayer && iReg == TE1 / NVMTE_[iSeed].first)
0843                 used = true;
0844               if (l2 == ilayer && iReg == TE2 / NVMTE_[iSeed].second)
0845                 used = true;
0846             }
0847 
0848             if (used) {
0849               nmem++;
0850               memories << "AllStubs: AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n" << nmem << " [42]"
0851                        << std::endl;
0852               os << "AS_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n" << nmem << " input=> VMR_"
0853                  << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".allstubout output=> TC_" << iSeedStr(iSeed)
0854                  << iTCStr(iTC);
0855               if (ilayer == l1) {
0856                 os << ".innerallstubin" << std::endl;
0857               } else {
0858                 os << ".outerallstubin" << std::endl;
0859               }
0860             }
0861           }
0862         }
0863       }
0864     }
0865   }
0866 }
0867 
0868 void TrackletConfigBuilder::writeVMSMemories(std::ostream& os, std::ostream& memories, std::ostream&) {
0869   if (combinedmodules_) {
0870     //First write VMS memories used by MatchProcessor
0871     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0872       for (unsigned int iReg = 0; iReg < NRegions_[ilayer]; iReg++) {
0873         memories << "VMStubsME: VMSME_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n1 [18]" << std::endl;
0874         os << "VMSME_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << "n1"
0875            << " input=> VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".vmstuboutPHI" << iTCStr(iReg)
0876            << " output=> MP_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".vmstubin" << std::endl;
0877       }
0878     }
0879 
0880     //Next write VMS memories used by TrackletProcessor
0881     for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0882       //FIXME - code could be cleaner
0883       unsigned int l1 = seedLayers(iSeed).first;
0884       unsigned int l2 = seedLayers(iSeed).second;
0885 
0886       unsigned int ilayer = seedLayers(iSeed).second;
0887 
0888       //for(unsigned int iReg=0;iReg<NRegions_[ilayer];iReg++){
0889 
0890       unsigned int nTCReg = TC_[iSeed].size() / NRegions_[l2];
0891 
0892       for (unsigned int iReg = 0; iReg < NRegions_[l2]; iReg++) {
0893         unsigned int nmem = 0;
0894         //Hack since we use same module twice
0895         if (iSeed == Seed::L2D1) {
0896           nmem = 2;
0897         }
0898 
0899         for (unsigned iTC = 0; iTC < nTCReg; iTC++) {
0900           nmem++;
0901           memories << "VMStubsTE: VMSTE_" << LayerName(ilayer) << "PHI" << iRegStr(iReg, iSeed) << "n" << nmem
0902                    << " [18]" << std::endl;
0903           os << "VMSTE_" << LayerName(ilayer) << "PHI" << iRegStr(iReg, iSeed) << "n" << nmem << " input=> VMR_"
0904              << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".vmstubout_seed_" << iSeed << " output=> TP_"
0905              << LayerName(l1) << LayerName(l2) << iTCStr(iReg * nTCReg + iTC) << ".outervmstubin" << std::endl;
0906         }
0907       }
0908     }
0909   } else {
0910     //First write VMS memories used by MatchEngine
0911     for (unsigned int ilayer = 0; ilayer < N_LAYER + N_DISK; ilayer++) {
0912       for (unsigned int iVMME = 0; iVMME < NVMME_[ilayer] * NRegions_[ilayer]; iVMME++) {
0913         unsigned int iReg = iVMME / NVMME_[ilayer];
0914         memories << "VMStubsME: VMSME_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << iVMME + 1 << "n1 [18]"
0915                  << std::endl;
0916         os << "VMSME_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << iVMME + 1 << "n1"
0917            << " input=> VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".vmstuboutMEPHI" << iTCStr(iReg)
0918            << iVMME + 1 << " output=> ME_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << iVMME + 1 << ".vmstubin"
0919            << std::endl;
0920       }
0921     }
0922 
0923     //Next write VMS memories used by TrackletEngine
0924     for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0925       for (unsigned int innerouterseed = 0; innerouterseed < 2; innerouterseed++) {
0926         //FIXME - code could be cleaner
0927         unsigned int l1 = seedLayers(iSeed).first;
0928         unsigned int l2 = seedLayers(iSeed).second;
0929 
0930         unsigned int NVMTE1 = NVMTE_[iSeed].first;
0931         unsigned int NVMTE2 = NVMTE_[iSeed].second;
0932 
0933         unsigned int ilayer = seedLayers(iSeed).first;
0934         unsigned int NVMTE = NVMTE_[iSeed].first;
0935         if (innerouterseed == 1) {
0936           ilayer = seedLayers(iSeed).second;
0937           NVMTE = NVMTE_[iSeed].second;
0938         }
0939 
0940         for (unsigned int iVMTE = 0; iVMTE < NVMTE * NRegions_[ilayer]; iVMTE++) {
0941           unsigned int iReg = iVMTE / NVMTE;
0942 
0943           unsigned int nmem = 0;
0944 
0945           if (iSeed == Seed::L2D1) {
0946             nmem = 4;
0947           }
0948 
0949           for (unsigned int iTE = 0; iTE < TE_[iSeed].size(); iTE++) {
0950             unsigned int TE1 = TE_[iSeed][iTE].first;
0951             unsigned int TE2 = TE_[iSeed][iTE].second;
0952 
0953             bool used = false;
0954 
0955             if (innerouterseed == 0 && iVMTE == TE1)
0956               used = true;
0957             if (innerouterseed == 1 && iVMTE == TE2)
0958               used = true;
0959 
0960             if (!used)
0961               continue;
0962 
0963             string inorout = "I";
0964             if (innerouterseed == 1)
0965               inorout = "O";
0966 
0967             nmem++;
0968             memories << "VMStubsTE: VMSTE_" << LayerName(ilayer) << "PHI" << iRegStr(iReg, iSeed) << iVMTE + 1 << "n"
0969                      << nmem << " [18]" << std::endl;
0970             os << "VMSTE_" << LayerName(ilayer) << "PHI" << iRegStr(iReg, iSeed) << iVMTE + 1 << "n" << nmem
0971                << " input=> VMR_" << LayerName(ilayer) << "PHI" << iTCStr(iReg) << ".vmstuboutTE" << inorout << "PHI"
0972                << iRegStr(iReg, iSeed) << iVMTE + 1 << " output=> TE_" << LayerName(l1) << "PHI"
0973                << iRegStr(TE1 / NVMTE1, iSeed) << TE1 + 1 << "_" << LayerName(l2) << "PHI"
0974                << iRegStr(TE2 / NVMTE2, iSeed) << TE2 + 1;
0975             if (innerouterseed == 0) {
0976               os << ".innervmstubin" << std::endl;
0977             } else {
0978               os << ".outervmstubin" << std::endl;
0979             }
0980           }
0981         }
0982       }
0983     }
0984   }
0985 }
0986 
0987 void TrackletConfigBuilder::writeTPARMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
0988   if (combinedmodules_) {
0989     for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0990       for (unsigned int iTP = 0; iTP < TC_[iSeed].size(); iTP++) {
0991         memories << "TrackletParameters: TPAR_" << iSeedStr(iSeed) << iTCStr(iTP) << " [56]" << std::endl;
0992         modules << "TrackletProcessor: TP_" << iSeedStr(iSeed) << iTCStr(iTP) << std::endl;
0993         os << "TPAR_" << iSeedStr(iSeed) << iTCStr(iTP) << " input=> TP_" << iSeedStr(iSeed) << iTCStr(iTP)
0994            << ".trackpar output=> FT_" << iSeedStr(iSeed) << ".tparin" << std::endl;
0995       }
0996     }
0997   } else {
0998     for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
0999       for (unsigned int iTC = 0; iTC < TC_[iSeed].size(); iTC++) {
1000         memories << "TrackletParameters: TPAR_" << iSeedStr(iSeed) << iTCStr(iTC) << " [56]" << std::endl;
1001         modules << "TrackletCalculator: TC_" << iSeedStr(iSeed) << iTCStr(iTC) << std::endl;
1002         os << "TPAR_" << iSeedStr(iSeed) << iTCStr(iTC) << " input=> TC_" << iSeedStr(iSeed) << iTCStr(iTC)
1003            << ".trackpar output=> FT_" << iSeedStr(iSeed) << ".tparin" << std::endl;
1004       }
1005     }
1006   }
1007 }
1008 
1009 void TrackletConfigBuilder::writeTFMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
1010   for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
1011     memories << "TrackFit: TF_" << iSeedStr(iSeed) << " [126]" << std::endl;
1012     modules << "FitTrack: FT_" << iSeedStr(iSeed) << std::endl;
1013     os << "TF_" << iSeedStr(iSeed) << " input=> FT_" << iSeedStr(iSeed) << ".trackout output=> PD.trackin" << std::endl;
1014   }
1015 }
1016 
1017 void TrackletConfigBuilder::writeCTMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
1018   modules << "PurgeDuplicate: PD" << std::endl;
1019 
1020   for (unsigned int iSeed = 0; iSeed < N_SEED_PROMPT; iSeed++) {
1021     memories << "CleanTrack: CT_" << iSeedStr(iSeed) << " [126]" << std::endl;
1022     os << "CT_" << iSeedStr(iSeed) << " input=> PD.trackout output=>" << std::endl;
1023   }
1024 }
1025 
1026 void TrackletConfigBuilder::writeILMemories(std::ostream& os, std::ostream& memories, std::ostream& modules) {
1027   //FIXME these should not be hardcoded - but for now wanted to avoid reading file
1028   string dtcname[52];
1029   unsigned int layerdisk[52];
1030   double phimin[52];
1031   double phimax[52];
1032 
1033   dtcname[0] = "PS10G_1";
1034   layerdisk[0] = 0;
1035   phimin[0] = 0.304273;
1036   phimax[0] = 0.742925;
1037   dtcname[1] = "PS10G_1";
1038   layerdisk[1] = 6;
1039   phimin[1] = -0.185672;
1040   phimax[1] = 0.883803;
1041   dtcname[2] = "PS10G_1";
1042   layerdisk[2] = 8;
1043   phimin[2] = -0.132414;
1044   phimax[2] = 0.830545;
1045   dtcname[3] = "PS10G_1";
1046   layerdisk[3] = 10;
1047   phimin[3] = -0.132414;
1048   phimax[3] = 0.830545;
1049   dtcname[4] = "PS10G_2";
1050   layerdisk[4] = 0;
1051   phimin[4] = -0.0133719;
1052   phimax[4] = 0.715599;
1053   dtcname[5] = "PS10G_2";
1054   layerdisk[5] = 7;
1055   phimin[5] = -0.110089;
1056   phimax[5] = 0.808221;
1057   dtcname[6] = "PS10G_2";
1058   layerdisk[6] = 9;
1059   phimin[6] = -0.132414;
1060   phimax[6] = 0.830545;
1061   dtcname[7] = "PS10G_3";
1062   layerdisk[7] = 1;
1063   phimin[7] = -0.11381;
1064   phimax[7] = 0.822812;
1065   dtcname[8] = "PS10G_3";
1066   layerdisk[8] = 7;
1067   phimin[8] = -0.185672;
1068   phimax[8] = 0.883803;
1069   dtcname[9] = "PS10G_4";
1070   layerdisk[9] = 6;
1071   phimin[9] = -0.0823971;
1072   phimax[9] = 0.780529;
1073   dtcname[10] = "PS10G_4";
1074   layerdisk[10] = 8;
1075   phimin[10] = -0.0963091;
1076   phimax[10] = 0.794441;
1077   dtcname[11] = "PS10G_4";
1078   layerdisk[11] = 10;
1079   phimin[11] = -0.0963091;
1080   phimax[11] = 0.794441;
1081   dtcname[12] = "PS_1";
1082   layerdisk[12] = 2;
1083   phimin[12] = 0.0827748;
1084   phimax[12] = 0.615357;
1085   dtcname[13] = "PS_1";
1086   layerdisk[13] = 7;
1087   phimin[13] = -0.0823971;
1088   phimax[13] = 0.780529;
1089   dtcname[14] = "PS_2";
1090   layerdisk[14] = 2;
1091   phimin[14] = -0.0917521;
1092   phimax[14] = 0.614191;
1093   dtcname[15] = "PS_2";
1094   layerdisk[15] = 9;
1095   phimin[15] = -0.0963091;
1096   phimax[15] = 0.794441;
1097   dtcname[16] = "2S_1";
1098   layerdisk[16] = 3;
1099   phimin[16] = -0.0246209;
1100   phimax[16] = 0.763311;
1101   dtcname[17] = "2S_1";
1102   layerdisk[17] = 4;
1103   phimin[17] = 0.261875;
1104   phimax[17] = 0.403311;
1105   dtcname[18] = "2S_2";
1106   layerdisk[18] = 4;
1107   phimin[18] = -0.0542445;
1108   phimax[18] = 0.715509;
1109   dtcname[19] = "2S_3";
1110   layerdisk[19] = 5;
1111   phimin[19] = 0.0410126;
1112   phimax[19] = 0.730605;
1113   dtcname[20] = "2S_4";
1114   layerdisk[20] = 5;
1115   phimin[20] = -0.0428961;
1116   phimax[20] = 0.693862;
1117   dtcname[21] = "2S_4";
1118   layerdisk[21] = 8;
1119   phimin[21] = -0.0676705;
1120   phimax[21] = 0.765802;
1121   dtcname[22] = "2S_5";
1122   layerdisk[22] = 6;
1123   phimin[22] = -0.0648206;
1124   phimax[22] = 0.762952;
1125   dtcname[23] = "2S_5";
1126   layerdisk[23] = 9;
1127   phimin[23] = -0.0676705;
1128   phimax[23] = 0.765802;
1129   dtcname[24] = "2S_6";
1130   layerdisk[24] = 7;
1131   phimin[24] = -0.0648206;
1132   phimax[24] = 0.762952;
1133   dtcname[25] = "2S_6";
1134   layerdisk[25] = 10;
1135   phimin[25] = -0.0676705;
1136   phimax[25] = 0.765802;
1137   dtcname[26] = "negPS10G_1";
1138   layerdisk[26] = 0;
1139   phimin[26] = -0.023281;
1140   phimax[26] = 0.372347;
1141   dtcname[27] = "negPS10G_1";
1142   layerdisk[27] = 6;
1143   phimin[27] = -0.185672;
1144   phimax[27] = 0.883803;
1145   dtcname[28] = "negPS10G_1";
1146   layerdisk[28] = 8;
1147   phimin[28] = -0.132414;
1148   phimax[28] = 0.830545;
1149   dtcname[29] = "negPS10G_1";
1150   layerdisk[29] = 10;
1151   phimin[29] = -0.132414;
1152   phimax[29] = 0.830545;
1153   dtcname[30] = "negPS10G_2";
1154   layerdisk[30] = 0;
1155   phimin[30] = -0.0133719;
1156   phimax[30] = 0.715599;
1157   dtcname[31] = "negPS10G_2";
1158   layerdisk[31] = 7;
1159   phimin[31] = -0.110089;
1160   phimax[31] = 0.808221;
1161   dtcname[32] = "negPS10G_2";
1162   layerdisk[32] = 9;
1163   phimin[32] = -0.132414;
1164   phimax[32] = 0.830545;
1165   dtcname[33] = "negPS10G_3";
1166   layerdisk[33] = 1;
1167   phimin[33] = -0.115834;
1168   phimax[33] = 0.813823;
1169   dtcname[34] = "negPS10G_3";
1170   layerdisk[34] = 7;
1171   phimin[34] = -0.185672;
1172   phimax[34] = 0.883803;
1173   dtcname[35] = "negPS10G_4";
1174   layerdisk[35] = 6;
1175   phimin[35] = -0.0823971;
1176   phimax[35] = 0.780529;
1177   dtcname[36] = "negPS10G_4";
1178   layerdisk[36] = 8;
1179   phimin[36] = -0.0963091;
1180   phimax[36] = 0.794441;
1181   dtcname[37] = "negPS10G_4";
1182   layerdisk[37] = 10;
1183   phimin[37] = -0.0963091;
1184   phimax[37] = 0.794441;
1185   dtcname[38] = "negPS_1";
1186   layerdisk[38] = 2;
1187   phimin[38] = -0.0961318;
1188   phimax[38] = 0.445198;
1189   dtcname[39] = "negPS_1";
1190   layerdisk[39] = 7;
1191   phimin[39] = -0.0823971;
1192   phimax[39] = 0.780529;
1193   dtcname[40] = "negPS_2";
1194   layerdisk[40] = 2;
1195   phimin[40] = -0.0917521;
1196   phimax[40] = 0.614191;
1197   dtcname[41] = "negPS_2";
1198   layerdisk[41] = 9;
1199   phimin[41] = -0.0963091;
1200   phimax[41] = 0.794441;
1201   dtcname[42] = "neg2S_1";
1202   layerdisk[42] = 3;
1203   phimin[42] = -0.0246209;
1204   phimax[42] = 0.763311;
1205   dtcname[43] = "neg2S_1";
1206   layerdisk[43] = 4;
1207   phimin[43] = 0.261875;
1208   phimax[43] = 0.403311;
1209   dtcname[44] = "neg2S_2";
1210   layerdisk[44] = 4;
1211   phimin[44] = -0.0542445;
1212   phimax[44] = 0.715509;
1213   dtcname[45] = "neg2S_3";
1214   layerdisk[45] = 5;
1215   phimin[45] = 0.0410126;
1216   phimax[45] = 0.730605;
1217   dtcname[46] = "neg2S_4";
1218   layerdisk[46] = 5;
1219   phimin[46] = -0.0428961;
1220   phimax[46] = 0.693862;
1221   dtcname[47] = "neg2S_4";
1222   layerdisk[47] = 8;
1223   phimin[47] = -0.06767;
1224   phimax[47] = 0.765802;
1225   dtcname[48] = "neg2S_5";
1226   layerdisk[48] = 6;
1227   phimin[48] = -0.0648201;
1228   phimax[48] = 0.762952;
1229   dtcname[49] = "neg2S_5";
1230   layerdisk[49] = 9;
1231   phimin[49] = -0.06767;
1232   phimax[49] = 0.765802;
1233   dtcname[50] = "neg2S_6";
1234   layerdisk[50] = 7;
1235   phimin[50] = -0.0648201;
1236   phimax[50] = 0.762952;
1237   dtcname[51] = "neg2S_6";
1238   layerdisk[51] = 10;
1239   phimin[51] = -0.06767;
1240   phimax[51] = 0.765802;
1241 
1242   double dphi = 0.5 * dphisectorHG_ - M_PI / NSector_;
1243 
1244   string olddtc = "";
1245   for (unsigned int i = 0; i < 52; i++) {
1246     if (olddtc != dtcname[i]) {
1247       modules << "InputRouter: IR_" << dtcname[i] << "_A" << std::endl;
1248       modules << "InputRouter: IR_" << dtcname[i] << "_B" << std::endl;
1249       memories << "DTCLink: DL_" << dtcname[i] << "_A [36]" << std::endl;
1250       memories << "DTCLink: DL_" << dtcname[i] << "_B [36]" << std::endl;
1251       os << "DL_" << dtcname[i] << "_A"
1252          << " input=> output=> IR_" << dtcname[i] << "_A.stubin" << std::endl;
1253       os << "DL_" << dtcname[i] << "_B"
1254          << " input=> output=> IR_" << dtcname[i] << "_B.stubin" << std::endl;
1255     }
1256     olddtc = dtcname[i];
1257   }
1258 
1259   for (unsigned int i = 0; i < 52; i++) {
1260     double phimintmp = phimin[i] + dphi;
1261     double phimaxtmp = phimax[i] + dphi;
1262 
1263     for (unsigned int iReg = 0; iReg < NRegions_[layerdisk[i]]; iReg++) {
1264       if (allStubs_[layerdisk[i]][iReg].first > phimaxtmp && allStubs_[layerdisk[i]][iReg].second < phimintmp)
1265         continue;
1266 
1267       if (allStubs_[layerdisk[i]][iReg].second < phimaxtmp) {
1268         memories << "InputLink: IL_" << LayerName(layerdisk[i]) << "PHI" << iTCStr(iReg) << "_" << dtcname[i] << "_A"
1269                  << " [36]" << std::endl;
1270         os << "IL_" << LayerName(layerdisk[i]) << "PHI" << iTCStr(iReg) << "_" << dtcname[i] << "_A"
1271            << " input=> IR_" << dtcname[i] << "_A.stubout output=> VMR_" << LayerName(layerdisk[i]) << "PHI"
1272            << iTCStr(iReg) << ".stubin" << std::endl;
1273       }
1274 
1275       if (allStubs_[layerdisk[i]][iReg].first > phimintmp) {
1276         memories << "InputLink: IL_" << LayerName(layerdisk[i]) << "PHI" << iTCStr(iReg) << "_" << dtcname[i] << "_B"
1277                  << " [36]" << std::endl;
1278         os << "IL_" << LayerName(layerdisk[i]) << "PHI" << iTCStr(iReg) << "_" << dtcname[i] << "_B"
1279            << " input=> IR_" << dtcname[i] << "_B.stubout output=> VMR_" << LayerName(layerdisk[i]) << "PHI"
1280            << iTCStr(iReg) << ".stubin" << std::endl;
1281       }
1282     }
1283   }
1284 }
1285 
1286 void TrackletConfigBuilder::writeAll(std::ostream& wires, std::ostream& memories, std::ostream& modules) {
1287   writeILMemories(wires, memories, modules);
1288   writeASMemories(wires, memories, modules);
1289   writeVMSMemories(wires, memories, modules);
1290   writeSPMemories(wires, memories, modules);
1291   writeSPDMemories(wires, memories, modules);
1292   writeProjectionMemories(wires, memories, modules);
1293   writeTPARMemories(wires, memories, modules);
1294   writeVMPROJMemories(wires, memories, modules);
1295   writeAPMemories(wires, memories, modules);
1296   writeCMMemories(wires, memories, modules);
1297   writeFMMemories(wires, memories, modules);
1298   writeTFMemories(wires, memories, modules);
1299   writeCTMemories(wires, memories, modules);
1300 }