CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/SimCalorimetry/EcalElectronicsEmulation/bin/GenABIO.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 8; -*-
00002 
00010 #include <iostream>
00011 #include <fstream>
00012 #include <sstream>
00013 #include <vector>
00014 #include <cassert>
00015 #include <cstdlib>
00016 #include <cstring>
00017 
00018 #include "ecalDccMap.h"
00019 
00020 #if !defined(__linux__) && !(defined(__APPLE__) && __DARWIN_C_LEVEL >= 200809L)
00021 #include <errno.h>
00022 /* getline implementation is copied from glibc. */
00023 
00024 #ifndef SIZE_MAX
00025 # define SIZE_MAX ((size_t) -1)
00026 #endif
00027 #ifndef SSIZE_MAX
00028 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
00029 #endif
00030 namespace {
00031 ssize_t getline (char **lineptr, size_t *n, FILE *fp)
00032 {
00033     ssize_t result;
00034     size_t cur_len = 0;
00035 
00036     if (lineptr == NULL || n == NULL || fp == NULL)
00037     {
00038         errno = EINVAL;
00039         return -1;
00040    }
00041 
00042     if (*lineptr == NULL || *n == 0)
00043     {
00044         *n = 120;
00045         *lineptr = (char *) malloc (*n);
00046         if (*lineptr == NULL)
00047         {
00048             result = -1;
00049             goto end;
00050         }
00051     }
00052 
00053     for (;;)
00054     {
00055         int i;
00056 
00057         i = getc (fp);
00058         if (i == EOF)
00059         {
00060             result = -1;
00061             break;
00062         }
00063 
00064         /* Make enough space for len+1 (for final NUL) bytes.  */
00065         if (cur_len + 1 >= *n)
00066         {
00067             size_t needed_max =
00068                 SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
00069             size_t needed = 2 * *n + 1;   /* Be generous. */
00070             char *new_lineptr;
00071 
00072             if (needed_max < needed)
00073                 needed = needed_max;
00074             if (cur_len + 1 >= needed)
00075             {
00076                 result = -1;
00077                 goto end;
00078             }
00079 
00080             new_lineptr = (char *) realloc (*lineptr, needed);
00081             if (new_lineptr == NULL)
00082             {
00083                 result = -1;
00084                 goto end;
00085             }
00086 
00087             *lineptr = new_lineptr;
00088             *n = needed;
00089         }
00090 
00091         (*lineptr)[cur_len] = i;
00092         cur_len++;
00093 
00094         if (i == '\n')
00095             break;
00096     }
00097     (*lineptr)[cur_len] = '\0';
00098     result = cur_len ? (ssize_t) cur_len : result;
00099 
00100 end:
00101     return result;
00102 }
00103 }
00104 #endif
00105 
00106 
00107 using namespace std;
00108 
00111 const static int nBarrelEtaBins = 170;
00114 const static int nBarrelPhiBins = 360;
00117 const static int nEndcapXBins = 100;
00120 const static int nEndcapYBins = 100;
00123 const static int supercrystalEdge = 5;
00126 const static int nSupercrystalXBins = nEndcapXBins/supercrystalEdge;
00129 const static int nSupercrystalYBins = nEndcapYBins/supercrystalEdge;
00132 const static int nBarrelTowerEtaBins = nBarrelEtaBins/5;
00135 const static int nBarrelTowerPhiBins = nBarrelPhiBins/5;
00138 const static int nEndcaps = 2;
00141 const static int nEndcapTTInEta = 11;
00144 const static int nBarrelTTInEta = 34;
00147 const static int nTTInEta =
00148 2*nEndcapTTInEta+nBarrelTTInEta;
00151 const static int nTTInPhi = 72;
00154 const int nABInEta=4;
00157 const int nABInPhi=3;
00160 const int nDCCEE = 9;
00161 const int nABABCh = 8;//nbr of AB input/output ch. on an AB
00162 const int nABTCCCh = 12;//nbr of TCC inputs on an AB
00163 const int nDCCCh = 12;//nbr of DCC outputs on an AB
00164 const int nTCCInEta = 6; //nbr of TCC bins along eta
00165 const int nAB = nABInPhi*nABInEta;
00166 const int nTTInABAlongEta=nTTInEta/nABInEta;
00167 const int nTTInABAlongPhi=nTTInPhi/nABInPhi;
00168 const int iTTEtaMin[nABInEta] = {0,11,28,45};
00169 const int iTTEtaMax[nABInEta] = {10,27,44,55};
00170 const int iTTEtaSign[nABInEta] = {-1,-1,1,1};
00171 
00172 //Eta bounds for TCC partionning
00173 //a TCC covers from iTCCEtaBounds[iTCCEta] included to
00174 //iTCCEtaBounds[iTCCEta+1] excluded.
00175 const int iTCCEtaBounds[nTCCInEta+1] = {0,7,11,28,45,49,56};
00176 
00177 const char* abTTFFilePrefix = "TTF_AB";
00178 const char* abTTFFilePostfix = ".txt";
00179 const char* abSRFFilePrefix = "AF_AB";
00180 const char* abSRFFilePostfix = ".txt";
00181 const char* abIOFilePrefix = "IO_AB";
00182 const char* abIOFilePostfix = ".txt";
00183 
00184 const char* srfFilename = "SRF.txt";
00185 const char* ttfFilename = "TTF.txt";
00186 const char* xconnectFilename = "xconnect_universal.txt";
00187 
00188 const char srpFlagMarker[] = {'.', 'S', 'N', 'C', '4','5','6','7'};
00189 const char tccFlagMarker[] = {'.', 'S', '?', 'C', '4', '5', '6', '7'};
00190 
00191 char srp2roFlags[128];
00192 
00193 typedef enum {suppress=0, sr2, sr1, full, fsuppress, fsr2, fsr1, ffull} roAction_t;
00194 char roFlagMarker[] = {/*suppress*/'.', /*sr1*/'z', /*sr1*/'Z', /*full*/'F',
00195                        /*fsuppress*/'4', /*fsr2*/'5', /*fsr1*/'6', /*ffull*/'7'
00196 };
00197 
00198 const int nactions = 8;
00199 //can be overwritten according by cmd line arguments
00200 roAction_t actions[nactions] = {/*LI->*/sr2,/*S->*/full,/*N->*/ full,/*C->*/full,
00201                                 /*fLI->*/sr2,/*fS->*/sr2,/*fN->*/sr2,/*fC->*/sr2}; 
00202 
00203 //list of SC deserves by an endcap DCC [0(EE-)|1(EE+)][iDCCPhi]
00204 vector<pair<int, int> > ecalDccSC[nEndcaps][nDCCEE];
00205 
00206 void fillABTTFFiles(const char ttFlags[nTTInEta][nTTInPhi],
00207                     ofstream files[]);
00208 void fillABSRPFiles(const char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00209                     const char endcapSrFlags[nEndcaps][nSupercrystalXBins]
00210                     [nSupercrystalYBins],
00211                     ofstream files[]);
00212 void fillABIOFiles(const char ttFlags[nTTInEta][nTTInPhi],
00213                    const char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00214                    const char endcapSrFlags[nEndcaps][nSupercrystalXBins]
00215                    [nSupercrystalYBins],
00216                    ofstream files[]);
00217 inline int abNum(int iABEta, int iABPhi){return 3*iABEta+iABPhi;}
00218 
00219 bool readTTF(FILE* file, char ttFlags[nTTInEta][nTTInPhi]);
00220 bool readSRF(FILE* file,
00221              char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00222              char endcapSrFlags[nEndcaps][nSupercrystalXBins]
00223              [nSupercrystalYBins]);
00224 
00225 void writeABTTFFileHeader(ofstream& f, int abNum);
00226 void writeABSRFFileHeader(ofstream& f, int abNum);
00227 void writeABIOFileHeader(ofstream& f, int abNum);
00228 string getFlagStream(char flags[nTTInEta][nTTInPhi], int iEtaMin, int iEtaMax,
00229                      int iPhiMin, int iPhiMax);
00230 string getABTCCInputStream(const char tccFlags[nTTInEta][nTTInPhi],
00231                            int iABEta, int iABPhi, int iTCCCh);
00232 void getABTTPhiBounds(int iABPhi, int& iTTPhiMin, int& iTTPhiMax);
00233 string getABABOutputStream(const char tccFlags[nTTInEta][nTTInPhi],
00234                            int iABEta, int iABPhi, int iABCh);
00235 string getABABInputStream(const char tccFlags[nTTInEta][nTTInPhi], int iABEta, 
00236                           int iABPhi, int iABCh);
00237 string getABDCCOutputStream(const char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00238                             const char endcapSrFlags[nEndcaps][nSupercrystalXBins]
00239                             [nSupercrystalYBins],
00240                             int iABEta, int iABPhi, int DCCCh);
00241 void abConnect(int iAB,int iABCh,int& iOtherAB,int& iOtherABCh);
00242 
00243 int iEvent = 0;
00244 
00245 int theAB = -1;
00246 
00247 int main(int argc, char* argv[]){
00248   char barrelSrFlags[nBarrelTTInEta][nTTInPhi];
00249   char endcapSrFlags[nEndcaps][nEndcapXBins/5][nEndcapYBins/5];
00250   char ttFlags[nTTInEta][nTTInPhi];
00251   ofstream abTTFFiles[nAB];
00252   ofstream abSRFFiles[nAB];
00253   ofstream abIOFiles[nAB];
00254 
00255   int iarg = 0;
00256   while(++iarg<argc){
00257     if(strcmp(argv[iarg],"-h")==0||strcmp(argv[iarg],"--help")==0){
00258       cout << "Usage: GenABIO [OPTIONS]\n\n"
00259         "Produces TT and SR flag files for each SRP board from TTF.txt and "
00260         "SRF.txt global flag files. Requires the SRP cross-connect description"
00261         " description file (xconnect_universal.txt). TTF.txt, SRF.txt and "
00262         "xconnect_universal.txt must be in the directory the command is "
00263         "launched.\n\n"
00264         "OPTIONS:\n"
00265         "  -A, --actions IJKLMNOP. IJKLMNOP I..P integers from 0 to 7.\n"
00266         "                I: action flag for low interest RUs\n"
00267         "                J: action flag for single RUs\n"
00268         "                K: action flag for neighbour RUs\n"
00269         "                L: action flag for centers RUs\n"
00270         "                M: action flag for forced low interest RUs\n"
00271         "                N: action flag for forced single RUs\n"
00272         "                O: action flag for forced neighbour RUs\n"
00273         "                P: action flag for forced centers RUs\n\n"
00274         " -h, --help display this help\n"
00275         " -a n, --ab n specifies indices of the AB whose file must be "
00276         "produced. The ab number runs from 1 to 12. Use -1 to produce files "
00277         "for every AB\n\n"
00278         ;
00279       
00280       return 0;
00281     }
00282     
00283     if(!strcmp(argv[iarg],"-A") || !strcmp(argv[iarg],"-A")){//actions
00284       if(++iarg>=argc){ cout << "Option error. Try -h\n"; return 1; }
00285       for(int i=0; i<8; ++i){
00286         int act = argv[iarg][i]-'0';
00287         if(act<0 || act>=nactions){
00288           cout << "Error. Action argument is invalid.\n";
00289           return 1;
00290         } else{
00291           actions[i] = (roAction_t)act;
00292         }
00293       }
00294       continue;
00295     }
00296     if(!strcmp(argv[iarg],"-a")||!strcmp(argv[iarg],"--ab")){
00297       if(++iarg>=argc){ cout << "Option error. Try -h\n"; return 1; }
00298       theAB = strtoul(argv[iarg], 0, 0);
00299       if(theAB>=0) --theAB;
00300       if(theAB<-1 || theAB>11){
00301         cout << "AB number is incorrect. Try -h option to get help.\n";
00302       }
00303       continue;
00304     }
00305   }
00306 
00307   for(size_t i=0; i<sizeof(srp2roFlags)/sizeof(srp2roFlags[0]); srp2roFlags[i++]='?');
00308   for(size_t i=0; i<sizeof(actions)/sizeof(actions[0]); ++i){
00309     srp2roFlags[(int)srpFlagMarker[i]] = roFlagMarker[actions[i]];
00310   }
00311 
00312   for(int iEE=0; iEE < nEndcaps; ++iEE){
00313     for(int iY = 0; iY < nSupercrystalXBins; ++iY){
00314       for(int iX = 0; iX < nSupercrystalYBins; ++iX){
00315         int iDCCPhi = dccPhiIndexOfRU(iEE==0?0:2,iX,iY);
00316         if(iDCCPhi>=0){//SC exists
00317           ecalDccSC[iEE][iDCCPhi].push_back(pair<int,int>(iX,iY));
00318         }
00319       }
00320     }
00321   }
00322   
00323   stringstream s;
00324   for(int iAB=0; iAB< nAB; ++iAB){
00325     if(theAB!=-1 && theAB!=iAB) continue;
00326     s.str("");
00327     s << abTTFFilePrefix << (iAB<9?"0":"") << iAB+1 << abTTFFilePostfix;
00328     abTTFFiles[iAB].open(s.str().c_str(), ios::out);
00329     writeABTTFFileHeader(abTTFFiles[iAB], iAB);
00330     s.str("");
00331     s << abSRFFilePrefix << (iAB<9?"0":"") << iAB+1 << abSRFFilePostfix;
00332     abSRFFiles[iAB].open(s.str().c_str(), ios::out);
00333     writeABSRFFileHeader(abSRFFiles[iAB], iAB);
00334     s.str("");
00335     s << abIOFilePrefix << (iAB<9?"0":"") << iAB+1 << abIOFilePostfix;
00336     abIOFiles[iAB].open(s.str().c_str(), ios::out);
00337     writeABIOFileHeader(abIOFiles[iAB], iAB);
00338   }
00339 
00340   FILE* srfFile = fopen(srfFilename, "r");
00341   if(srfFile==NULL){
00342     cerr << "Failed to open SRF file, " << srfFilename << endl;
00343     exit(EXIT_FAILURE);
00344   }
00345 
00346   FILE* ttfFile = fopen(ttfFilename, "r");
00347   if(ttfFile==NULL){
00348     cerr << "Failed to open TTF file, " << ttfFilename << endl;
00349     exit(EXIT_FAILURE);
00350   }
00351   
00352   iEvent = 0;
00353   while(readSRF(srfFile,barrelSrFlags,endcapSrFlags)
00354         && readTTF(ttfFile,ttFlags)){
00355     if(iEvent%100==0){
00356       cout << "Event " << iEvent << endl;
00357     }
00358     fillABTTFFiles(ttFlags,abTTFFiles);
00359     fillABSRPFiles(barrelSrFlags, endcapSrFlags, abSRFFiles);
00360     fillABIOFiles(ttFlags,barrelSrFlags,endcapSrFlags,abIOFiles);
00361     ++iEvent;
00362   }
00363   
00364   return 0;
00365 }
00366 
00370 void  fillABTTFFiles(const char ttFlags[nTTInEta][nTTInPhi],
00371                      ofstream files[]){
00372   for(int iABEta=0; iABEta<nABInEta; ++iABEta){
00373     for(int iABPhi=0; iABPhi<nABInPhi; ++iABPhi){
00374       int iAB = abNum(iABEta,iABPhi);
00375       int iTTPhiMin;
00376       int iTTPhiMax;
00377       getABTTPhiBounds(iABPhi, iTTPhiMin, iTTPhiMax);
00378       //      writeEventHeader(files[iAB], iEvent, nTTInABAlongPhi);
00379       files[iAB] << "# Event " << iEvent << "\n";
00380       
00381       for(int i = 0 ; i <= iTTEtaMax[iABEta]-iTTEtaMin[iABEta];
00382           ++i){
00383         int iTTEta;
00384         if(iTTEtaSign[iABEta]>0){
00385           iTTEta = iTTEtaMin[iABEta] + i;
00386         } else{
00387           iTTEta = iTTEtaMax[iABEta] - i;
00388         }
00389         for(int iTTPhi = iTTPhiMin;
00390             mod(iTTPhiMax-iTTPhi,nTTInPhi) < nTTInABAlongPhi;
00391             iTTPhi = mod(++iTTPhi, nTTInPhi)){
00392           files[iAB] << ttFlags[iTTEta][iTTPhi];
00393         }
00394         files[iAB] << "\n";
00395       }
00396       files[iAB] << "#\n";
00397       //writeEventTrailer(files[iAB], nTTInABAlongPhi);
00398     }
00399   }  
00400 }
00401 
00402 void  fillABSRPFiles(const char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00403                      const char endcapSrFlags[nEndcaps][nSupercrystalXBins]
00404                      [nSupercrystalYBins],
00405                      ofstream files[nAB]){
00406   //event headers:
00407   for(int iAB=0; iAB < nAB; ++iAB){
00408     files[iAB] << "# Event " << iEvent << "\n";
00409   }
00410   
00411   bool lineAppended[nAB];
00412   for(int i=0; i< nAB; lineAppended[i++]=false)/*empty*/;
00413   
00414   //EE:
00415   for(int iEE = 0; iEE < nEndcaps; ++iEE){
00416     for(int iX = 0; iX < nSupercrystalXBins; ++iX){
00417       for(int iY=0; iY < nSupercrystalYBins; ++iY){
00418         //        int iDCC = dccIndex(iEE==0?0:2,iX*5,iY*5);
00419         int iDCC = dccIndexOfRU(iEE==0?0:2,iX,iY);
00420         if(iDCC>=0){
00421           int iAB = abOfDcc(iDCC);
00422           if(!lineAppended[iAB]){
00423             for(int i=0; i< iY; ++i) files[iAB] << ' ';
00424           }
00425           files[iAB] << srp2roFlags[(int)endcapSrFlags[iEE][iX][iY]];
00426           lineAppended[iAB] = true;
00427         }
00428       }//next iY
00429       for(int iFile=0; iFile< nAB; ++iFile){
00430         if(lineAppended[iFile]){
00431           files[iFile] << "\n";
00432           lineAppended[iFile] = false;
00433         }
00434       }
00435     }//next iX
00436   }
00437   
00438   //EB:
00439   for(int iABEta=1; iABEta<3; ++iABEta){
00440     for(int iABPhi=0; iABPhi<nABInPhi; ++iABPhi){
00441       int iAB = abNum(iABEta,iABPhi);
00442       int iTTPhiMin;
00443       int iTTPhiMax;
00444       getABTTPhiBounds(iABPhi, iTTPhiMin, iTTPhiMax);
00445       //writeEventHeader(files[iAB], iEvent, nTTInABAlongPhi);
00446       for(int i = 0 ; i <= iTTEtaMax[iABEta]-iTTEtaMin[iABEta];
00447           ++i){
00448         int iTTEta;
00449         if(iTTEtaSign[iABEta]>0){
00450           iTTEta = iTTEtaMin[iABEta] + i;
00451         } else{
00452           iTTEta = iTTEtaMax[iABEta] - i;
00453         }
00454         for(int iTTPhi = iTTPhiMin;
00455             mod(iTTPhiMax-iTTPhi,nTTInPhi) < nTTInABAlongPhi;
00456             iTTPhi = mod(++iTTPhi, nTTInPhi)){
00457           files[iAB] << srp2roFlags[(int)barrelSrFlags[iTTEta-nEndcapTTInEta][iTTPhi]];
00458         }
00459         files[iAB] << "\n";
00460       }
00461       //      writeEventTrailer(files[iAB], nTTInABAlongPhi);
00462       files[iAB] << "#\n";
00463     }
00464   }
00465 
00466   //file trailers
00467   for(int iAB=0; iAB < nAB; ++iAB){
00468     files[iAB] << "#\n";
00469   }
00470 }
00471 
00472 void  fillABIOFiles(const char ttFlags[nTTInEta][nTTInPhi],
00473                     const char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00474                     const char endcapSrFlags[nEndcaps][nSupercrystalXBins][nSupercrystalYBins],
00475                     ofstream files[]){
00476   for(int iABEta=0; iABEta < nABInEta; ++iABEta){
00477     for(int iABPhi=0; iABPhi < nABInPhi; ++iABPhi){
00478       int iAB = abNum(iABEta, iABPhi);
00479       //      writeABIOFileHeader(files[iAB], iAB);
00480       files[iAB] << "# Event " << iEvent << "\n"; 
00481       //TCC inputs:
00482       for(int iTCC=0; iTCC< nABTCCCh; ++iTCC){
00483         files[iAB] << "ITCC" << iTCC+1 << ":"
00484                    << getABTCCInputStream(ttFlags, iABEta, iABPhi, iTCC)
00485                    << "\n";
00486       }
00487       //AB inputs:
00488       for(int iABCh=0; iABCh<nABABCh; ++iABCh){
00489         files[iAB] << "IAB" <<  iABCh+1 << ":"
00490                    << getABABInputStream(ttFlags, iABEta, iABPhi, iABCh)
00491                    << "\n";
00492       }
00493       //AB outputs:
00494       for(int iABCh=0; iABCh<nABABCh; ++iABCh){
00495         files[iAB] << "OAB" <<  iABCh+1 << ":"
00496                    << getABABOutputStream(ttFlags, iABEta, iABPhi, iABCh)
00497                    << "\n";
00498       }
00499       //DCC output:
00500       for(int iDCCCh=0; iDCCCh<nDCCCh; ++iDCCCh){
00501         files[iAB] << "ODCC";
00502         files[iAB]<< (iDCCCh<=8?"0":"") << iDCCCh+1 << ":"
00503                   << getABDCCOutputStream(barrelSrFlags, endcapSrFlags, iABEta, iABPhi,iDCCCh)
00504                   << "\n";
00505       }
00506       files[iAB] << "#\n";
00507     }
00508   }
00509 }
00510 
00511 /*
00512   stringstream filename;
00513   filename.str("");
00514   filename << abTTFFilePrefix << abNum(iABEta, iABPhi) <<abTTFFilePostfix;
00515   ofstream file(filename.str(), ios::ate);
00516 
00517 */
00518 
00519 bool readTTF(FILE* f, char ttFlags[nTTInEta][nTTInPhi]){
00520   char* buffer = NULL;
00521   size_t bufferSize = 0;
00522   int read;
00523   if(f==NULL) exit(EXIT_FAILURE);
00524   int line=0;
00525   int iEta = 0;
00526   while(iEta<nTTInEta && (read=getline(&buffer, &bufferSize,f))!=-1){
00527     ++line;
00528     char* pos = buffer;
00529     while(*pos==' ' || *pos=='\t') ++pos; //skip spaces
00530     if(*pos!='#' && *pos!='\n'){//not a comment line nor an empty line
00531       if(read-1!=nTTInPhi){
00532         cerr << "Error: line " << line
00533              << " of file "<< ttfFilename << " has incorrect length"
00534           //             << " (" << read-1 << " instead of " << nTTInPhi << ")"
00535              << endl;
00536         exit(EXIT_FAILURE);
00537       }
00538       for(int iPhi=0; iPhi<nTTInPhi; ++iPhi){
00539         ttFlags[iEta][iPhi] = buffer[iPhi];
00540         //         if(ttFlags[iEta][iPhi]!='.'){
00541         //           cout << __FILE__ << ":" << __LINE__ << ": "
00542         //                << iEta << "," << iPhi
00543         //                << " " << ttFlags[iEta][iPhi] << "\n";
00544         //         }
00545       }
00546       ++iEta;
00547     }
00548   }
00549   //returns true if all TT were read (not at end of file)
00550   return (iEta==nTTInEta)?true:false;
00551 }
00552 
00553 bool readSRF(FILE* f,
00554              char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00555              char endcapSrFlags[nEndcaps][nSupercrystalXBins]
00556              [nSupercrystalYBins]){
00557   char* buffer = NULL;
00558   size_t bufferSize = 0;
00559   int read;
00560   if(f==NULL) exit(EXIT_FAILURE);
00561   int line=0;
00562   int iEta = 0;
00563   int iXm = 0;
00564   int iXp = 0;
00565   int iReadLine = 0;//number of read line, comment lines excluded
00566   //number of non-comment lines to read:
00567   const int nReadLine = nBarrelTTInEta + nEndcaps*nSupercrystalXBins; 
00568   while(iReadLine<nReadLine && (read=getline(&buffer, &bufferSize,f))!=-1){
00569     ++line;
00570     char* pos = buffer;
00571     while(*pos==' ' || *pos=='\t') ++pos; //skip spaces
00572     if(*pos!='#' && *pos!='\n'){//not a comment line nor an empty line
00573       //go back to beginning of line:
00574       pos = buffer;
00575       if(iReadLine<nSupercrystalXBins){//EE- reading
00576         if(read-1!=nSupercrystalYBins){
00577           cerr << "Error: line " << line
00578                << " of file "<< srfFilename << " has incorrect length"
00579                << " (" << read-1 << " instead of " << nSupercrystalYBins << ")"
00580                << endl;
00581           exit(EXIT_FAILURE);
00582         }
00583         for(int iY=0; iY<nSupercrystalYBins; ++iY){
00584           endcapSrFlags[0][iXm][iY] = buffer[iY];
00585         }
00586         ++iXm;
00587       } else if(iReadLine<nSupercrystalYBins+nBarrelTTInEta){//EB reading
00588         if(read-1!=nTTInPhi){
00589           cerr << "Error: line " << line
00590                << " of file "<< srfFilename << " has incorrect length"
00591                << " (" << read-1 << " instead of " << nTTInPhi << ")"
00592                << endl;
00593           exit(EXIT_FAILURE);
00594         }
00595         for(int iPhi=0; iPhi<nTTInPhi; ++iPhi){
00596           barrelSrFlags[iEta][iPhi] = buffer[iPhi];
00597         }
00598         ++iEta;
00599       } else if(iReadLine<2*nSupercrystalXBins+nBarrelTTInEta){ //EE+ reading
00600         if(read-1!=nSupercrystalYBins){
00601           cerr << "Error: line " << line
00602                << " of file "<< srfFilename << " has incorrect length"
00603                << " (" << read-1 << " instead of " << nSupercrystalYBins << ")"
00604                << endl;
00605           exit(EXIT_FAILURE);
00606         }
00607         for(int iY=0; iY<nSupercrystalYBins; ++iY){
00608           endcapSrFlags[1][iXp][iY] = buffer[iY];
00609         }
00610         ++iXp;
00611       }
00612       ++iReadLine;      
00613     }//not a comment or empty line
00614   }
00615   //returns 0 if all TT were read:
00616   return (iReadLine==nReadLine)?true:false;
00617 }
00618 
00619 
00620 // void writeEventHeader(ofstream& f, int iEvent, int nPhi){
00621 //   //event header:
00622 //   stringstream header;
00623 //   header.str("");
00624 //   header << " event " << iEvent << " ";
00625 //   f << "+";
00626 //   for(int iPhi = 0; iPhi < nPhi; ++iPhi){
00627 //     if(iPhi == (int)(nPhi-header.str().size())/2){
00628 //       f << header.str();
00629 //       iPhi += header.str().size()-1;
00630 //     } else{
00631 //       f << "-";
00632 //     }
00633 //   }
00634 //   f << "+\n";
00635 // }
00636 
00637 // void writeEventTrailer(ofstream& f, int nPhi){
00638 //   f << "+";
00639 //   for(int iPhi = 0; iPhi < nPhi; ++iPhi) f << "-";
00640 //   f << "+\n";
00641 // }
00642 
00643 void writeABTTFFileHeader(ofstream& f, int abNum){
00644   time_t t;
00645   time(&t);
00646   const char* date = ctime(&t);
00647   f << "# TTF flag map covered by AB " << abNum+1 <<"\n#\n"
00648     "# Generated on : " << date << "#\n"
00649     "# +---> Phi          " << srpFlagMarker[0] << ": 000 (low interest)\n"
00650     "# |                  " << srpFlagMarker[1] << ": 001 (single)\n"     
00651     "# |                  " << srpFlagMarker[2] << ": 010 (neighbour)\n"    
00652     "# V |Eta|            " << srpFlagMarker[3] << ": 011 (center)\n"     
00653     "#\n";
00654 }
00655 
00656 void writeABSRFFileHeader(ofstream& f, int abNum){
00657   time_t t;
00658   time(&t);
00659   const char* date = ctime(&t);
00660   const char* xLabel;
00661   const char* yLabel;
00662   if(abNum<3 || abNum>8){//endcap
00663     xLabel = "Y  ";
00664     yLabel = "X    ";
00665   } else{//barrel
00666     xLabel = "Phi";
00667     yLabel = "|Eta|";
00668   }
00669   f << "# SRF flag map covered by AB " << abNum+1 <<"\n#\n"
00670     "# Generated on : " << date << "#\n"
00671     "# +---> " << xLabel << "          " << roFlagMarker[0] << ": 000 (suppress)\n"          
00672     "# |                  "              << roFlagMarker[1] << ": 010 (SR Threshold 2)\n"     
00673     "# |                  "              << roFlagMarker[2] << ": 001 (SR Threshold 1)\n"     
00674     "# V " << yLabel << "            "   << roFlagMarker[3] << ": 011 (Full readout)\n"     
00675     "#\n"
00676     "# action table (when forced):\n"
00677     "# LI-> " << roFlagMarker[actions[0]] << " (" << roFlagMarker[actions[4]]<< ")" << "\n"
00678     "# S -> " << roFlagMarker[actions[1]] << " (" << roFlagMarker[actions[5]]<< ")" << "\n"
00679     "# N -> " << roFlagMarker[actions[2]] << " (" << roFlagMarker[actions[6]]<< ")" << "\n"
00680     "# C -> " << roFlagMarker[actions[3]] << " (" << roFlagMarker[actions[7]]<< ")" << "\n";
00681 }
00682 
00683 void writeABIOFileHeader(ofstream& f, int abNum){
00684   time_t t;
00685   time(&t);
00686   const char* date = ctime(&t);
00687   f << "# AB " << abNum+1 <<" I/O \n#\n"
00688     "# Generated on : " << date << "#\n"
00689     "# " << srpFlagMarker[0] << ": 000 (low interest)   " << tccFlagMarker[0] << ": 000 (low interest)   " << roFlagMarker[0] << ": 000 (suppress)\n"
00690     "# " << srpFlagMarker[1] << ": 001 (single)         " << tccFlagMarker[1] << ": 001 (mid interest)   " << roFlagMarker[1] << ": 010 (SR Threshold 2)\n"
00691     "# " << srpFlagMarker[2] << ": 010 (neighbour)      " << tccFlagMarker[2] << ": 010 (not valid)      " << roFlagMarker[2] << ": 001 (SR Threshold 1)\n"   
00692     "# " << srpFlagMarker[3] << ": 011 (center)         " << tccFlagMarker[3] << ": 011 (high interest)  " <<   roFlagMarker[3] << ": 011 (Full readout)\n"
00693     "#\n"
00694     "# action table (when forced):\n"
00695     "# LI-> " << roFlagMarker[actions[0]] << " (" << roFlagMarker[actions[4]]<< ")" << "\n"
00696     "# S -> " << roFlagMarker[actions[1]] << " (" << roFlagMarker[actions[5]]<< ")" << "\n"
00697     "# N -> " << roFlagMarker[actions[2]] << " (" << roFlagMarker[actions[6]]<< ")" << "\n"
00698     "# C -> " << roFlagMarker[actions[3]] << " (" << roFlagMarker[actions[7]]<< ")" << "\n"
00699     "#\n"; 
00700 }
00701 
00702 string getFlagStream(const char flags[nTTInEta][nTTInPhi], int iEtaMin,
00703                      int iEtaMax, int iPhiMin, int iPhiMax){
00704   assert(0<=iEtaMin && iEtaMin<=iEtaMax && iEtaMax<nTTInEta);
00705   if(iEtaMin<=nTTInEta/2 && iEtaMax>nTTInEta){
00706     cerr << "Implementation Errror:"
00707          << __FILE__ << ":" << __LINE__ 
00708          << ": A flag stream cannot covers parts of both half-ECAL!"
00709          << endl;
00710     exit(EXIT_FAILURE);
00711   }
00712 
00713   bool zPos = (iEtaMin>=nTTInEta/2);
00714 
00715   stringstream buffer;
00716   buffer.str("");
00717   for(int jEta = 0; jEta <= iEtaMax-iEtaMin; ++jEta){
00718     //loops on iEta in |eta| increasing order:
00719     int iEta;
00720     if(zPos){
00721       iEta = iEtaMin + jEta;
00722     } else{
00723       iEta = iEtaMax - jEta;
00724     }
00725 
00726     for(int iPhi = mod(iPhiMin,nTTInPhi);
00727         mod(iPhiMax+1-iPhi,nTTInPhi) != 0;
00728         iPhi = mod(++iPhi, nTTInPhi)){
00729       buffer << flags[iEta][iPhi];
00730     }
00731   }
00732   
00733   return buffer.str();
00734 }
00735 
00736 string getABTCCInputStream(const char tccFlags[nTTInEta][nTTInPhi],
00737                            int iABEta, int iABPhi, int iTCCCh){
00738   //gets eta bounds for this tcc channel:
00739   int iTCCEta;
00740   if(iABEta==1 || iABEta==2){//barrel
00741     if(iTCCCh>5) return ""; //only 6 TCCs per AB for barrel
00742     iTCCEta =  1 + iABEta;
00743   } else{//endcap
00744     if(iABEta==0){//EE-
00745       iTCCEta = (iTCCCh<6)?1:0;
00746     } else{//EE+
00747       iTCCEta = (iTCCCh<6)?4:5;
00748     }
00749   }      
00750   int iEtaMin = iTCCEtaBounds[iTCCEta];
00751   int iEtaMax = iTCCEtaBounds[iTCCEta+1]-1;
00752 
00753   //gets phi bounds:
00754   int iPhiMin;
00755   int iPhiMax;
00756   getABTTPhiBounds(iABPhi, iPhiMin, iPhiMax);
00757   //phi is increasing with TTC channel number
00758   //a TTC covers a 4TT-wide phi-sector
00759   //=>iPhiMin(iTTCCh) = iPhiMin(AB) + 4*iTTCCh for iTCCCh<6 
00760   iPhiMin += 4*(iTCCCh%6);
00761   iPhiMax = iPhiMin + 4 - 1;
00762   
00763   return getFlagStream(tccFlags, iEtaMin, iEtaMax, iPhiMin, iPhiMax);
00764 }
00765 
00766 string getABABOutputStream(const char tccFlags[nTTInEta][nTTInPhi],
00767                            int iABEta, int iABPhi, int iABCh){
00768   stringstream buffer;
00769   buffer.str("");
00770   bool barrel = (iABEta==1 || iABEta==2); //true for barrel, false for endcap
00771   switch(iABCh){
00772   case 0:
00773     //to AB ch #0 are sent the 16 1st TCC flags received on TCC input Ch. 0
00774     buffer << getABTCCInputStream(tccFlags, iABEta, iABPhi, 0).substr(0,16);
00775     break;
00776   case 1:
00777     //to AB ch #1 are sent the 16 1st TCC flags received on TCC input Ch. 0 to 5:
00778     for(int iTCCCh=0; iTCCCh<6; ++iTCCCh){
00779       buffer <<
00780         getABTCCInputStream(tccFlags, iABEta, iABPhi, iTCCCh).substr(0,16);
00781     }
00782     break;
00783   case 2:
00784     //to AB ch #2 are sent the 16 1st TCC flags received on TCC input Ch. 5:
00785     buffer << getABTCCInputStream(tccFlags, iABEta, iABPhi, 5).substr(0,16);
00786     break;
00787   case 3:
00788     //to AB ch #3 are sent TCC flags received on TCC input Ch. 0 and 6:
00789     buffer << getABTCCInputStream(tccFlags, iABEta, iABPhi, 0);
00790     buffer << getABTCCInputStream(tccFlags, iABEta, iABPhi, 6);
00791     break;
00792   case 4:
00793     //to AB ch #4 are sent TCC flags received on TCC input Ch 5 and 11:
00794     buffer << getABTCCInputStream(tccFlags, iABEta, iABPhi, 5);
00795     buffer << getABTCCInputStream(tccFlags, iABEta, iABPhi, 11);
00796     break;
00797   case 5:
00798     //for endcaps AB output ch 5 is not used.
00799     //for barrel, to AB ch #5 are sent the 16 last TCC flags received on TCC
00800     //input Ch. 0:
00801     if(barrel){//in barrel
00802       string s = getABTCCInputStream(tccFlags, iABEta, iABPhi, 0);
00803       assert(s.size()>=16);
00804       buffer << s.substr(s.size()-16,16);
00805     }
00806     break;
00807   case 6:
00808     //for endcaps AB output ch 6 is not used.
00809     //for barrel, to AB ch #6 are sent the 16 last TCC flags received on TCC
00810     //input Ch. 0 to 5:
00811     if(barrel){//in barrel
00812       for(int iTCCCh=0; iTCCCh<6; ++iTCCCh){
00813         string s = getABTCCInputStream(tccFlags, iABEta, iABPhi, iTCCCh); 
00814         buffer << s.substr(s.size()-16,16);
00815       }
00816     }
00817     break;
00818   case 7:
00819     //for endcaps AB output ch 7 is not used.
00820     //for barrel, to AB ch #7 are sent the 16 last TCC flags received on TCC
00821     //input Ch. 5:
00822     if(barrel){//in barrel
00823       string s = getABTCCInputStream(tccFlags, iABEta, iABPhi, 5);
00824       assert(s.size()>=16);
00825       buffer << s.substr(s.size()-16,16);
00826     }
00827     break;
00828   default:
00829     assert(false);
00830   }
00831   return buffer.str();
00832 }
00833 
00834 string getABABInputStream(const char tccFlags[nTTInEta][nTTInPhi], int iABEta, 
00835                           int iABPhi, int iABCh){
00836   int iAB = abNum(iABEta, iABPhi);
00837   int iOtherAB; //AB which this channel is connected to
00838   int iOtherABCh; //ch # on the other side of the AB-AB link
00839   abConnect(iAB,iABCh,iOtherAB,iOtherABCh);
00840   int iOtherABEta = iOtherAB/3;
00841   int iOtherABPhi = iOtherAB%3;
00842   return getABABOutputStream(tccFlags, iOtherABEta, iOtherABPhi, iOtherABCh);
00843 }
00844 
00845 
00846 void getABTTPhiBounds(int iABPhi, int& iTTPhiMin, int& iTTPhiMax){
00847   iTTPhiMin = mod(-6+iABPhi*nTTInABAlongPhi,nTTInPhi);
00848   iTTPhiMax = mod(iTTPhiMin+nTTInABAlongPhi-1, nTTInPhi);
00849 }
00850 
00851 void abConnect(int iAB,int iABCh,int& iOtherAB,int& iOtherABCh){
00852   static bool firstCall = true;
00853   static int xconnectMap[nAB][nABABCh][2];
00854   if(firstCall){
00855     FILE* f = fopen(xconnectFilename, "r");
00856     if(f==NULL){
00857       cerr << "Error. Failed to open xconnect definition file,"
00858            << xconnectFilename << endl;
00859       exit(EXIT_FAILURE);
00860     }
00861     //skips two first lines:
00862     for(int i=0; i<2; ++i){
00863       int c;
00864       while((c=getc(f))!='\n' && c >=0);
00865     }
00866     int ilink = 0 ;
00867     while(!feof(f)){
00868       int abIn;
00869       int pinIn;
00870       int abOut;
00871       int pinOut;
00872       if(4==fscanf(f, "%d\t%d\t%d\t%d", &abIn, &pinIn, &abOut, &pinOut)){
00873         xconnectMap[abIn][pinIn][0] = abOut;
00874         xconnectMap[abIn][pinIn][1] = pinOut;
00875         ++ilink;
00876       }
00877     }
00878     if(ilink!=nAB*nABABCh){
00879       cerr << "Error cross-connect definition file " << xconnectFilename
00880            << " contains an unexpected number of link definition."
00881            << endl;
00882       exit(EXIT_FAILURE);
00883     }
00884     firstCall = false;
00885   }
00886 
00887   iOtherAB = xconnectMap[iAB][iABCh][0];
00888   iOtherABCh = xconnectMap[iAB][iABCh][1];
00889 }
00890 
00891 string getABDCCOutputStream(const char barrelSrFlags[nBarrelTTInEta][nTTInPhi],
00892                             const char endcapSrFlags[nEndcaps][nSupercrystalXBins]
00893                             [nSupercrystalYBins],
00894                             int iABEta, int iABPhi, int iDCCCh){
00895   bool barrel = (iABEta==1||iABEta==2);
00896   if(barrel){
00897     //same as TCC with same ch number but with TCC flags replaced by SRP flags:
00898     string stream = getABTCCInputStream(barrelSrFlags-nEndcapTTInEta, iABEta, iABPhi, iDCCCh);
00899     //converts srp flags to readout flags:
00900     for(size_t i=0; i< stream.size(); ++i){
00901       stream[i] = srp2roFlags[(int)stream[i]];
00902     }
00903     return stream;
00904   } else{//endcap
00905     if(iDCCCh<3){//used DCC output channel
00906       //endcap index:
00907       int iEE=(iABEta==0)?0:1;
00908       stringstream buffer("");
00909       //3 DCC per AB and AB DCC output channel in
00910       //increasing DCC phi position:
00911       int iDCCPhi = iABPhi*3+iDCCCh;
00912       for(size_t iSC=0; iSC < ecalDccSC[iEE][iDCCPhi].size(); ++iSC){
00913         pair<int,int> sc = ecalDccSC[iEE][iDCCPhi][iSC];
00914         buffer << srp2roFlags[(int)endcapSrFlags[iEE][sc.first][sc.second]];
00915       }
00916       return buffer.str();
00917     } else{//unused output channel
00918       return "";
00919     }
00920   }
00921 }