EmcDynamicData.C

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------
00002 | This file describes EmcDynamicData class members. Constructor of this
00003 | class parses EMCal electronic configuration file and creates arrays for data
00004 | storage, map of channels that correspond to data arrays elements, array 
00005 | of Reference structures that describe monitoring references and array of
00006 | SuperModule structures that is used by class EMCalFEE to determine what 
00007 | channels should be read out. See example of it usage in EmcParseTest.cc file.
00008 | Created by Sergei Belikov 04/20/99.
00009 -------------------------------------------------------------------------*/
00010 /*==============================================================================
00011 | The purpose of EmcDynamicData class is:                                       |
00012 | 1. to Parse script file describing EMCalchannels and references connections   |
00013 |    to FEMs;                                                                   |
00014 | 2. to create storage arrays for only active channels and references data;     |
00015 | 3. to create routers that explain Event Iterating routines/classes what       |
00016 |    channels should be read out and where these data should be stored.         |
00017 |    Actually router creates "connections" between electronics channels and     |
00018 |    elements of data arrays.                                                   |
00019 |                                                                               |
00020 |  To make your own EmcDynamicData object, just do:                             |
00021 |_____________________________________________________________________________  |
00022 | int status;                                                                   |
00023 | EmcDynamicData myobject(status,ConfigFileName,false,true,true);//constructor  |
00024 |                                                          // does all          |
00025 | if(status) exit(1); //non-zero status means there were script errors          |
00026 | const int* dataMap=myobject.getEmcMap(); // get list of detector cells        |
00027 | int nchannel=myobject.getEmcSize(); // get size of data arrays                |
00028 | float* myHighGain=myobject.getEmcHG();//access to EMCal HighGain pre-post     |
00029 |// the same for getEmcLG, getEmcTAC. You can also use                          |
00030 | EmcData* allEMCdata=myobject.getEmcData();//to get structure for all EMC data |
00031 | EmCData* allREFdata=myobject.getRefData();//to get all reference data         |
00032 |_____________________________________________________________________________  |
00033 | Boolean 3-nd parameter to constructor defines if raw data arrays should be    |
00034 | created too. By default it is false. Boolean 4-th parameter defines if 24 or  |
00035 | 32 channels from each ASIC board will be read. Default value is true that     |
00036 | means that only 24 channles connected to towers will be readout.              |
00037 | Boolean as a 5-th parameter to constructor defines channel mapping style.     |
00038 | Default value is true that means that we use EMCal mapping style. False means |
00039 | that in smMap array  electronics channel numbers are stored instead of tower  |
00040 | numbers.                                                                      |
00041 |_____________________________________________________________________________  |
00042 | Slang in this program:                                                        |
00043 | abs position-means position in the EMCal detector. For towers it is 0-24767,  |
00044 |         for FEM or reference - this is a position of the supermodule (12x12   |
00045 | towers) in EMCal : 0-171. EMCal is treated as 8 sectors, PbSc1, ...,PbSc6,    |
00046 | PgGl1,PbGl2. In this program names of corresponding sectors are: W0,W1,W2,    |
00047 | W3,E2,E3,E0,E1. Reason - Edouard asked to push PbGl as far as possible :)     |
00048 ===============================================================================*/
00049 
00050 #include <iostream>
00051 #include <cstdlib>
00052 #include "EmcDynamicData.h"
00053 #include "emcGlobals.h"
00054 #include "EmcIndexer.h"
00055 #include <cstring>
00056 #include <cassert>
00057 
00058 using std::cout;
00059 using std::cerr;
00060 using std::endl;
00061 
00062 int EmcDynamicData::ScriptErrors=0;
00063 bool EmcDynamicData::FEMchErr=false;
00064 
00065 #define EMCcode 8001        //lowest packet identifier for EMCal
00066 #define FEMChannels 192     // as it is stated now FEM will send data for 32x6=192 channels
00067 #define ASICs   6           // number of ASIC boards in FEM
00068 #define FEM     0
00069 #define CHAN    1
00070 #define REF     2
00071 #define DELAY   3
00072 #define MAP     4
00073 #define DATA    5
00074 #define EMC_UNKNOWN -1      
00075 
00076 
00077 const char* dev[]=
00078 {
00079   "FEM:",
00080   "CHAN:",
00081   "REF:",
00082   "DELAY:",
00083   "MAP:",
00084   "DATA:"
00085 };
00086 //Starting address of each sector in calibration array.
00087 unsigned long SectorBases[]=
00088 {
00089   0,
00090   3456,
00091   6912,
00092   10368,
00093   13824,
00094   17280,
00095   20736,
00096   26880,
00097   33024
00098 
00099 };
00100 //Sector names
00101 const char* sectors[]=
00102 {
00103   "W0",
00104   "W1",
00105   "W2",
00106   "W3",
00107   "E2",
00108   "E3",
00109   "E0",
00110   "E1",
00111   "NO"
00112 };
00113 //FEM keywords
00114 const char *FEMkeywords[]=
00115 {
00116   "PIN=",
00117   "POS=",
00118   "SECTOR="
00119 };
00120 const char *DELAYkeywords[]=
00121 {
00122   "TAC=",
00123   "POST="
00124 };
00125 
00126 long SectorFEM[]=
00127 {
00128   0,
00129   18,
00130   36,
00131   54,
00132   72,
00133   90,
00134   108,
00135   140,
00136   172
00137 };
00138 
00139 const char* REFkeywords[]=
00140 {
00141   "TYPE=",              //type of reference
00142   "POS=",       //position of reference in sector
00143   "SECTOR=",            //      in what sector
00144   "CHAN="               // FEM channel
00145 };
00146 
00147 const char* DATAkeywords[]=
00148 {
00149   "TOW",
00150   "ALL"
00151 };
00152 
00153 const char* MAPkeywords[]=
00154 {
00155   "EMC",
00156   "FEM"
00157 };
00158 
00159 int  EmcDynamicData::cmpSM(const void *a, const void *b)
00160 {
00161   SuperModule* sa=(SuperModule*)a;
00162   SuperModule* sb=(SuperModule*)b;
00163   if(sa->absPosition<sb->absPosition)return -1;
00164   else if(sa->absPosition>sb->absPosition)return 1;
00165   cout<<"FEM with pin="<<sa->femPin<<" and FEM with pin="<<sb->femPin;
00166   cout<<" have the same absolute position="<<sa->absPosition<<endl;
00167   ScriptErrors++;
00168   return 0;
00169 }
00170 
00171 int EmcDynamicData::cmpRef(const void *a, const void *b)
00172 {
00173   Reference* sa=(Reference*)a;
00174   Reference* sb=(Reference*)b;
00175   if(sa->type<sb->type)      return -1;
00176   else if(sa->type>sb->type) return 1;
00177   if(sa->absPosition<sb->absPosition) return -1;
00178   if(sa->absPosition>sb->absPosition) return  1;
00179 
00180 
00181 
00182 //    if(sa->absFEM<sb->absFEM)return -1;
00183 //    else if(sa->absFEM>sb->absFEM)return 1;
00184 //    if(sa->chan<sb->chan)return -1;
00185 //    if(sa->chan>sb->chan)return 1;
00186 
00187   cout<<"ERROR!!! Two reference are servicing same supermodule "<<sa->absPosition<<endl;
00188   ScriptErrors++;
00189   return 0;
00190 }
00191 
00192 int EmcDynamicData::cmpCh(const void *c1, const void *c2)
00193 {
00194   FEMchErr=false;
00195   int sa=*(int*)c1;
00196   int sb=*(int*)c2;
00197   if(sa<sb)return -1;
00198   if(sa>sb)return 1;
00199   cout<<"ERROR!!! Two channels have the same number: "<<sa<<"-"<<sb<<endl;
00200   FEMchErr=true;
00201   ScriptErrors++;
00202   return 0;
00203 }
00204 
00205 //*************************************************************************
00206 
00207 char* EmcDynamicData::strupr(char* s)
00208 {
00209   for(int i=0;i<=(int)strlen(s);i++)
00210     if(s[i]>='a' && s[i]<='z')s[i]^=0x20;
00211   return s;
00212 }
00213 
00214 
00215 //*************************************************************************
00216 
00217 
00218 
00219 void EmcDynamicData::MBCleanStr(char *String)
00220 {
00221   strupr(String); // convert string in upper case
00222   char* str=String;
00223   if((str=strchr(str,'#')))*str='\0'; //cut off coments.
00224   str=String;
00225   while((str=strchr(str,',')))*str=' '; // replace all ',' with ' '
00226   while(strlen(String))
00227     {
00228       if ((String[0] == ' ') || (String[0] == '\t') || (String[0] == '\n'))
00229         strcpy(String,String+1); // remove blank spaces before keyword
00230       else break;
00231     }
00232 }
00233 
00234 //*************************************************************************
00235 int EmcDynamicData::MBControl(char *String, char*& RestString)
00236 {
00237   int size=0;
00238   for(int i=0;i<int(sizeof(dev)/sizeof(*dev));i++)
00239     {
00240       size=strlen(dev[i]);
00241       if(!strncmp(String,dev[i],size))
00242         {
00243           RestString=String+size;
00244           return i;
00245         }
00246     }
00247   RestString=NULL;
00248   return EMC_UNKNOWN;
00249 }
00250 //*************************************************************************
00251 int EmcDynamicData::MBControl(char *String, char*& RestString, const char ** names, int n)
00252 {
00253   int size=0;
00254   //  cout<<sizeof(names)<<" "<<sizeof(*names)<<" "<<sizeof(**names)<<endl;
00255   for(int i=0;i<n;i++)
00256     {
00257       //      cout<<"NAMES "<<i<<" "<<names[i]<<endl;
00258       size=strlen(names[i]);
00259       if(!strncmp(String,names[i],size))
00260         {
00261           RestString=String+size;
00262           return i;
00263         }
00264     }
00265   RestString=NULL;
00266   return EMC_UNKNOWN;
00267 }
00268 //*************************************************************************
00269 int EmcDynamicData::FindSector(char *String)
00270 {
00271   for(int i=0;i<int(sizeof(sectors)/sizeof(*sectors));i++)
00272     {
00273       if(!strncmp(String,sectors[i],strlen(sectors[i])))
00274         return i;
00275     }
00276   return -1;
00277 }
00278 //*************************************************************************
00279 int EmcDynamicData::ParseDELAY(char* String)
00280 {
00281   char* point;
00282   if(!(point=strstr(String,DELAYkeywords[0]))) //Find TAC delay
00283     {
00284       cout<<"DALAY: ERROR!!! LINE "<<line<<": "<<DELAYkeywords[0];
00285       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00286       ScriptErrors++;
00287     }
00288   else if(sscanf(point+strlen(DELAYkeywords[0]),"%d",&tacDelay)!=1)
00289     {
00290       cout<<"DELAY: ERROR!!! LINE "<<line<<": "<<DELAYkeywords[0];
00291       cout<<" has wrong value:"<<endl<<"-->"<<fLine<<endl;
00292       ScriptErrors++;
00293     }
00294   else
00295     {
00296       if(curSM>=0)smMap[curSM].tac_pre=tacDelay;
00297     }
00298 
00299   if(!(point=strstr(String,DELAYkeywords[1]))) //Find POST delay
00300     {
00301       cout<<"DALAY: ERROR!!! LINE "<<line<<": "<<DELAYkeywords[1];
00302       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00303       ScriptErrors++;
00304     }
00305   else if(sscanf(point+strlen(DELAYkeywords[1]),"%d",&postDelay)!=1)
00306     {
00307       cout<<"DELAY: ERROR!!! LINE "<<line<<": "<<DELAYkeywords[1];
00308       cout<<"wrong value:"<<endl<<"-->"<<fLine<<endl;
00309       ScriptErrors++;
00310     }
00311   else
00312     {
00313       if(curSM>=0)smMap[curSM].post_pre=postDelay;
00314     }
00315   return ScriptErrors;
00316 }
00317 
00318 int EmcDynamicData::ParseMAP(char* String)
00319 {
00320   char* point;
00321   if((point=strstr(String,MAPkeywords[0])))  channelMap=true; //If MAP: EMCAL was set in configuration file
00322   else if((point=strstr(String,MAPkeywords[1]))) channelMap=false;//If MAP: FEM was set in configuration file
00323   else
00324     {
00325       cout<<"MAP: ERROR!!! LINE "<<line<<": ";
00326       cout<<" wrong mapping style - should be EMCAL or FEM:"<<endl<<"-->"<<fLine<<endl;
00327       ScriptErrors++;           
00328     }
00329   return ScriptErrors;
00330 }
00331 int EmcDynamicData::ParseDATA(char* String)
00332 {
00333   char* point;
00334   if((point=strstr(String,DATAkeywords[0])))  Style=true; //If DATA: TOWERS was set in configuration file
00335   else if((point=strstr(String,DATAkeywords[1]))) Style=false;//If DATA: ALL was set in configuration file
00336   else
00337     {
00338       cout<<"MAP: ERROR!!! LINE "<<line<<": ";
00339       cout<<" wrong data style - should be TOWERS or ALL:"<<endl<<"-->"<<fLine<<endl;
00340       ScriptErrors++;           
00341     }
00342   return ScriptErrors;
00343 }
00344 int EmcDynamicData::ParseFEM(char* String)
00345 {
00346   char* point;
00347   int FEMpin=0;
00348 
00349   if(!(point=strstr(String,FEMkeywords[0]))) //Find PID
00350     {
00351       cout<<"FEM: ERROR!!! LINE "<<line<<": "<<FEMkeywords[0];
00352       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00353       ScriptErrors++;
00354     }
00355   else if(sscanf(point+strlen(FEMkeywords[0]),"%d",&FEMpin)!=1)
00356     {
00357       cout<<"FEM: ERROR!!! LINE "<<line<<": "<<FEMkeywords[0];
00358       cout<<"wrong value:"<<endl<<"-->"<<fLine<<endl;
00359       ScriptErrors++;
00360     }
00361 
00362   if(!(point=strstr(String,FEMkeywords[1]))) //Find Position
00363     {
00364       cout<<"FEM: ERROR!!! LINE "<<line<<": "<<FEMkeywords[1];
00365       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00366       ScriptErrors++;
00367     }
00368   else if(sscanf(point+strlen(FEMkeywords[1]),"%d",&Position)!=1)
00369     {
00370       cout<<"FEM: ERROR!!! LINE "<<line<<": "<<FEMkeywords[1];
00371       cout<<"wrong value:"<<endl<<"-->"<<fLine<<endl;
00372       ScriptErrors++;
00373     }
00374 
00375   if(!(point=strstr(String,FEMkeywords[2]))) //Find Sector
00376     {
00377       cout<<"FEM: ERROR!!! LINE "<<line<<": "<<FEMkeywords[2];
00378       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00379       ScriptErrors++;
00380     }
00381   else 
00382     {
00383       Sector=FindSector(point+strlen(FEMkeywords[2]));
00384       if(Sector<0)
00385         {
00386           cout<<"FEM: ERROR!!! LINE "<<line<<": Wrong sector name: ";
00387           cout<<point<<endl<<"-->"<<fLine<<endl;
00388           ScriptErrors++;
00389         }
00390     }
00391   if((Position<0 || Position>17) && Sector<6)
00392     {
00393       cout<<"FEM: ERROR!!! LINE "<<line<<": wrong position for PbSc FEM"<<endl;
00394       cout<<"-->"<<fLine<<endl;
00395       ScriptErrors++;
00396     }
00397   if((Position<0 || Position>31) && (Sector==6 || Sector==7))
00398     {
00399       cout<<"FEM: ERROR!!! LINE "<<line<<": wrong position for PbGl FEM"<<endl;
00400       cout<<"-->"<<fLine<<endl;
00401       ScriptErrors++;
00402     }
00403                         
00404   if(!ScriptErrors)
00405     {
00406       curSM=nSM;
00407       smMap=(SuperModule* )realloc(smMap,(++nSM)*sizeof(SuperModule));
00408       if(!smMap)
00409         {
00410           cout<<"Can't allocate memory for FEM addresses!"<<endl;
00411           ScriptErrors++;
00412           return -1;
00413         }
00414       smMap[curSM].absPosition=SectorFEM[Sector]+Position;
00415       smMap[curSM].femPin=FEMpin;
00416       smMap[curSM].packet=SectorFEM[Sector]+Position+EMCcode;
00417       smMap[curSM].nch=0;
00418       smMap[curSM].startTad=0;
00419       smMap[curSM].startRad=0;
00420       smMap[curSM].femCh=NULL; 
00421       smMap[curSM].nref=0;  
00422       smMap[curSM].adRef=NULL;
00423       smMap[curSM].nrefCh=0;
00424       smMap[curSM].refCh=NULL;
00425       smMap[curSM].tac_pre=tacDelay;
00426       smMap[curSM].post_pre=postDelay;
00427       for(int si=0;si<curSM;si++)
00428         {
00429           if(smMap[si].femPin==FEMpin)
00430             {
00431               cout<<"ERROR!!! LINE "<<line<<": FEM "<<si;
00432               cout<<" has the same PIN as a current FEM"<<endl;
00433               cout<<"-->"<<fLine<<endl;
00434               ScriptErrors++;
00435             }
00436         }
00437     }
00438   return ScriptErrors;
00439 }
00440 int EmcDynamicData::ParseCHAN(char* str)
00441 {
00442   int chn;
00443   int start=-1;
00444   int series=0;
00445   int number=-1;
00446   int number2=-1;
00447   for(int i=0;i<(int)(strlen(str)+1);i++)
00448     {
00449       if(str[i]>='0' && str[i]<='9')
00450         {
00451           if(start<0)start=i;
00452         }
00453       else if(str[i]=='-')
00454         {
00455           if(start<0)
00456             {
00457               cout<<"ERROR!!! LINE "<<line<<": no number before '-'"<<endl;
00458               cout<<"-->"<<fLine<<endl;
00459               ScriptErrors++;
00460               return ScriptErrors;
00461             }
00462           if(sscanf(str+start,"%d",&number)!=1)
00463             {
00464               cout<<"ERROR!!! LINE "<<line<<": wrong value before '-'"<<endl;
00465               cout<<"-->"<<fLine<<endl;
00466               ScriptErrors++;
00467               return ScriptErrors;
00468             }
00469           if(Style && number>=FEMChannels-ASICs*8)
00470             {
00471               cout<<"ERROR!!! LINE "<<line<<": "<<number;
00472               cout<<" If you use 24 channel mode channel number must be <"<<FEMChannels-ASICs*8<<endl;
00473               cout<<"-->"<<fLine<<endl;
00474               ScriptErrors++;
00475               return ScriptErrors;
00476             }
00477           if(!Style && number>=FEMChannels)
00478             {
00479               cout<<"ERROR!!! LINE "<<line<<": "<<number;
00480               cout<<" If you use 32 channel mode channel number must be <"<<FEMChannels<<endl;
00481               cout<<"-->"<<fLine<<endl;
00482               ScriptErrors++;
00483               return ScriptErrors;
00484             }
00485 
00486           series=1;
00487           start=-1;
00488         }
00489       else if(str[i]==' ' || str[i]=='\t' || str[i]=='\n' || str[i]=='\0')
00490         {
00491           if(start>=0)
00492             {
00493               if(series)
00494                 {
00495                   if(sscanf(str+start,"%d",&number2)!=1)
00496                     {
00497                       cout<<"ERROR!!! LINE "<<line<<": wrong value after '-'"<<endl;
00498                       cout<<"-->"<<fLine<<endl;
00499                       ScriptErrors++;
00500                       return ScriptErrors;
00501                     }
00502                   if(Style && number2>=FEMChannels-ASICs*8)
00503                     {
00504                       cout<<"ERROR!!! LINE "<<line<<": "<<number<<"-"<<number2;
00505                       cout<<" If you use 24 channel mode channel number must be <"<<FEMChannels-ASICs*8<<endl;
00506                       cout<<"-->"<<fLine<<endl;
00507                       ScriptErrors++;
00508                       return ScriptErrors;
00509                     }
00510                   if(!Style && number2>=FEMChannels)
00511                     {
00512                       cout<<"ERROR!!! LINE "<<line<<": "<<number<<"-"<<number2;
00513                       cout<<" If you use 32 channel mode channel number must be <"<<FEMChannels<<endl;
00514                       cout<<"-->"<<fLine<<endl;
00515                       ScriptErrors++;
00516                       return ScriptErrors;
00517                     }
00518 
00519                   if(number2<number)
00520                     {
00521                       cout<<"ERROR!!! LINE "<<line<<": "<<number<<"-"<<number2;
00522                       cout<<" : second value should be greater then first"<<endl;
00523                       cout<<"-->"<<fLine<<endl;
00524                       ScriptErrors++;
00525                       return ScriptErrors;
00526                     }
00527                   if(!ScriptErrors)
00528                     {
00529                       smMap[curSM].femCh=(int* )realloc(smMap[curSM].femCh, (smMap[curSM].nch+number2-number+1)*sizeof(unsigned long));
00530                       if(!smMap[curSM].femCh)
00531                         {
00532                           cout<<"Can't allocate memory for FEM addresses!"<<endl;
00533                           ScriptErrors++;
00534                           return ScriptErrors;
00535                         }
00536                       DataMap=(int* )realloc(DataMap, (Data.size+number2-number+1)*sizeof(int));
00537                       if(!DataMap)
00538                         {
00539                           cout<<"Can't allocate memory for data addresses!"<<endl;
00540                           ScriptErrors++;
00541                           return ScriptErrors;
00542                         }
00543                       for(int j=number;j<=number2;j++)
00544                         {
00545                           if(Style)
00546                             chn=j+j/12*4;
00547                           else chn=j;
00548 
00549                           DataMap[Data.size++]=SectorBases[Sector]+Position*FEMChannels+chn;
00550                           smMap[curSM].femCh[smMap[curSM].nch++]=chn;
00551                         }
00552                       start=-1;
00553                       series=0;
00554                     }
00555                 }
00556               else
00557                 {
00558                   if(sscanf(str+start,"%d",&number)!=1)
00559                     {
00560                       cout<<"ERROR!!! LINE "<<line<<": wrong channel number"<<endl;
00561                       cout<<"-->"<<fLine<<endl;
00562                       ScriptErrors++;
00563                       return ScriptErrors;
00564                     }
00565 
00566                   start=-1;
00567                   if(!ScriptErrors)
00568                     {
00569                       smMap[curSM].femCh=(int* )realloc(smMap[curSM].femCh, (smMap[curSM].nch+1)*sizeof(unsigned long));
00570                       if(!smMap[curSM].femCh)
00571                         {
00572                           cout<<"Can't allocate memory for FEM addresses!"<<endl;
00573                           return ScriptErrors;
00574                         }
00575                       DataMap=(int* )realloc(DataMap, (Data.size+1)*sizeof(int));
00576                       if(!DataMap)
00577                         {
00578                           cout<<"Can't allocate memory for data addresses!"<<endl;
00579                           return ScriptErrors;
00580                         }
00581                       if(Style)
00582                         chn=number+number/12*4;
00583                       else chn=number;
00584 
00585                       DataMap[Data.size++]=SectorBases[Sector]+Position*FEMChannels+chn;
00586                       smMap[curSM].femCh[smMap[curSM].nch++]=chn;
00587                     }
00588                 }
00589             }
00590         }
00591       else
00592         {
00593           cout<<"ERROR!!! Line "<<line;
00594           cout<<": Wrong character in string: '"<<char(str[i])<<"'"<<endl;
00595           cout<<"-->"<<fLine<<endl;
00596           ScriptErrors++;
00597           return ScriptErrors;
00598         }
00599     }
00600   return ScriptErrors;
00601 }
00602 int EmcDynamicData::ParseREF(char* String)
00603 {
00604   int type;
00605   int rPosition;
00606   int rSector=-1;
00607   int rCh;
00608   char* point;
00609   if(!(point=strstr(String,REFkeywords[0]))) //Find type
00610     {
00611       cout<<"REF: ERROR!!! LINE "<<line<<": "<<REFkeywords[0];
00612       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00613       ScriptErrors++;
00614     }
00615   else if(sscanf(point+strlen(REFkeywords[0]),"%d",&type)!=1)
00616     {
00617       cout<<"REF: ERROR!!! LINE "<<line<<": "<<REFkeywords[0];
00618       cout<<"wrong value:"<<endl<<"-->"<<fLine<<endl;
00619       ScriptErrors++;
00620     }
00621 
00622   if(!(point=strstr(String,REFkeywords[1]))) //Find Position
00623     {
00624       cout<<"REF: ERROR!!! LINE "<<line<<": "<<REFkeywords[1];
00625       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00626       ScriptErrors++;
00627     }
00628   else if( sscanf(point+strlen(REFkeywords[1]),"%d",&rPosition)!=1)
00629     {
00630       cout<<"REF: ERROR!!! LINE "<<line<<": "<<REFkeywords[1];
00631       cout<<"wrong value:"<<endl<<"-->"<<fLine<<endl;
00632       ScriptErrors++;
00633     }
00634 
00635   if(!(point=strstr(String,REFkeywords[2]))) //Find Sector
00636     {
00637       cout<<"REF: ERROR!!! LINE "<<line<<": "<<REFkeywords[2];
00638       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00639       ScriptErrors++;
00640     }
00641   else
00642     {
00643       rSector=FindSector(point+strlen(REFkeywords[2]));
00644       if(rSector<0)
00645         {
00646           cout<<"REF: ERROR!!! LINE "<<line<<": Wrong sector name: ";
00647           cout<<point<<endl<<"-->"<<fLine<<endl;
00648           ScriptErrors++;
00649         }
00650     }
00651   if(!(point=strstr(String,REFkeywords[3]))) //Find channel
00652     {
00653       cout<<"REF: ERROR!!! LINE "<<line<<": "<<REFkeywords[3];
00654       cout<<" is not specified:"<<endl<<"-->"<<fLine<<endl;
00655       ScriptErrors++;
00656     }
00657   else if(sscanf(point+strlen(REFkeywords[3]),"%d",&rCh)!=1)
00658     {
00659       cout<<"REF: ERROR!!! LINE "<<line<<": "<<REFkeywords[3];
00660       cout<<"wrong value:"<<endl<<"-->"<<fLine<<endl;
00661       ScriptErrors++;
00662     }
00663   if(!ScriptErrors)
00664     {
00665       refMap=(Reference *)realloc(refMap,(Refs.size+1)*sizeof(Reference));
00666       if(!refMap)
00667         {
00668           cout<<"Can't allocate memory for reference!"<<endl;
00669           return ScriptErrors;
00670         }
00671       assert(rSector>=0) ;
00672       refMap[Refs.size].absPosition=SectorFEM[rSector]+rPosition;
00673       refMap[Refs.size].type=type;
00674       refMap[Refs.size].absFEM=smMap[curSM].absPosition;
00675       if(Style)rCh=rCh+rCh/12*4;
00676       refMap[Refs.size].chan=rCh;
00677       refMap[Refs.size].nSMch=0;
00678       refMap[Refs.size].startSMad=0;
00679       smMap[curSM].refCh=(int*)realloc(smMap[curSM].refCh,sizeof(int)*(smMap[curSM].nrefCh+1));
00680       if(!smMap[curSM].refCh)
00681         {
00682           cout<<"Can't allocate memory for new reflist!!!"<<endl;
00683           ScriptErrors++;
00684           return ScriptErrors;
00685         }
00686       smMap[curSM].refCh[smMap[curSM].nrefCh]=rCh;
00687       smMap[curSM].nrefCh++;
00688 
00689       Refs.size++;
00690     }
00691   return ScriptErrors;
00692 }
00693 
00694 EmcDynamicData::EmcDynamicData(int& status, char* filename, bool GetRaw, 
00695                                bool fem24ch, bool EmcalMapStyle)
00696 { 
00697   emcConfigurationFile configFile(filename) ;
00698 
00699   if (!configFile.IsValid()) {
00700     cerr << "<E> EmcDynamicData::EmcDynamicData(...) : Error opening file " << filename << endl ;
00701     status = 1 ;
00702   }
00703   else {
00704     ParseConfigurationFile(status,configFile,GetRaw,fem24ch,EmcalMapStyle) ;
00705   }
00706 }
00707 
00708 EmcDynamicData::EmcDynamicData(int& status, emcConfigurationFile& configFile, 
00709                                bool GetRaw, bool fem24ch, 
00710                                bool EmcalMapStyle)
00711 { 
00712   if (configFile.IsValid()) {
00713     ParseConfigurationFile(status,configFile,GetRaw,fem24ch,EmcalMapStyle) ;
00714   }
00715   else {
00716     cerr << "<E> EmcDynamicData::EmcDynamicData(...) : Config. File invalid." << endl ;
00717     status = 1 ;
00718   }
00719 }
00720 
00721 void 
00722 EmcDynamicData::ParseConfigurationFile(int& status, 
00723                                        emcConfigurationFile& configFile, 
00724                                        bool GetRaw, bool fem24ch, 
00725                                        bool EmcalMapStyle)
00726 {
00727   char String[300];
00728   char *restString=NULL;
00729   line=0;
00730   fLine=NULL;
00731   status=0;
00732   Style=fem24ch;
00733   outputRaw=GetRaw;
00734   channelMap=EmcalMapStyle;
00735   Data.hg=NULL;
00736   Data.lg=NULL;
00737   Data.tac=NULL;
00738   Data.rawdata=NULL;
00739   DataMap=NULL;
00740   Data.size=0;
00741 
00742   Refs.hg=NULL;
00743   Refs.lg=NULL;
00744   Refs.tac=NULL;
00745   Refs.rawdata=NULL;
00746   refMap=NULL;
00747   Refs.size=0;
00748 
00749   smMap=NULL;
00750   nSM=0;
00751   curSM=-1;
00752 
00753   FEMchErr=false;
00754 
00755   ScriptErrors=0;
00756   int MBControlVal;
00757 
00758         
00759   // Start read configuration.
00760  
00761   //  while(fgets(String,sizeof(String),fdin) != NULL)
00762 
00763   configFile.Rewind() ;
00764 
00765   while ( configFile.GetLine(String,sizeof(String)) )
00766     {
00767       line++;
00768       fLine=new char[strlen(String)+1];
00769       strcpy(fLine,String);
00770       MBCleanStr(String);
00771       if(strlen(String))
00772         {
00773           MBControlVal = MBControl(String,restString);
00774           switch(MBControlVal)
00775             {
00776             case FEM:
00777               if(ParseFEM(restString)<0)
00778                 {
00779                   delete [] fLine;
00780                   status=-1;
00781                   return;
00782                 }
00783               break;
00784 
00785             case MAP:
00786               if(nSM)
00787                 {
00788                   cout<<"ERROR!!! LINE "<<line;
00789                   cout<<": MAP must be specified before any FEM description"<<endl;
00790                   cout<<"-->"<<fLine;
00791                   ScriptErrors++;
00792                 }
00793               ParseMAP(restString);
00794               break;
00795 
00796             case DATA:
00797               if(nSM)
00798                 {
00799                   cout<<"ERROR!!! LINE "<<line;
00800                   cout<<": DATA must be specified before any FEM description"<<endl;
00801                   cout<<"-->"<<fLine;
00802                   ScriptErrors++;
00803                 }
00804               ParseDATA(restString);
00805               break;
00806 
00807             case CHAN:
00808               if(!nSM)
00809                 {
00810                   cout<<"ERROR!!! LINE "<<line;
00811                   cout<<": FEM is not specified for these channels"<<endl;
00812                   cout<<"-->"<<fLine;
00813                   ScriptErrors++;
00814                 }
00815               ParseCHAN(restString);
00816               break;
00817 
00818             case REF:
00819               if(!nSM)
00820                 {
00821                   cout<<"ERROR!!! LINE "<<line;
00822                   cout<<": FEM is not specified for these references"<<endl;
00823                   cout<<"-->"<<fLine;
00824                   ScriptErrors++;
00825                 }
00826               ParseREF(restString);  
00827               break;
00828 
00829             case DELAY:
00830               ParseDELAY(restString);  
00831               break;
00832 
00833             default:
00834               cout<<"ERROR!!! LINE "<<line;
00835               cout<<": no keyword(like FEM:, CHAN:, REF:) or unknown keyword"<<endl;
00836               cout<<"-->"<<fLine<<endl;
00837               ScriptErrors++;
00838               break;
00839             } // end switch
00840         }// end if string is not empty
00841       delete [] fLine;
00842     } // end while not EOF
00843   //  fclose(fdin);
00844   cout<<"Total errors in script: "<<ScriptErrors<<endl;
00845   status=ScriptErrors;
00846   if(!nSM)
00847     {
00848       cout<<"Empty or non ASCII configuration file! Number of FEM=0."<<endl;
00849       status=3;
00850       return;
00851     }
00852   if(status)return;
00853   // Sorting FEM, REF, channels.
00854   //  ::qsort(smMap,nSM,sizeof(SuperModule),cmpSM);
00855   if(nSM > 0) ::qsort(smMap,nSM,sizeof(SuperModule),cmpSM);
00856   for(int ns=0;ns<nSM;ns++)
00857     {
00858       //      ::qsort(smMap[ns].femCh,smMap[ns].nch,sizeof(int),cmpCh);
00859       if(smMap[ns].nch > 0) ::qsort(smMap[ns].femCh,smMap[ns].nch,sizeof(int),cmpCh);
00860       if(ScriptErrors) cout<<"FEM PIN="<<smMap[ns].femPin<<endl<<endl;
00861       //      ::qsort(smMap[ns].refCh,smMap[ns].nrefCh,sizeof(int),cmpCh);
00862       if(smMap[ns].nrefCh > 0) ::qsort(smMap[ns].refCh,smMap[ns].nrefCh,sizeof(int),cmpCh);
00863       if(ScriptErrors) cout<<"FEM PIN="<<smMap[ns].femPin<<endl;
00864     }
00865   //  //  ::qsort(refMap,Refs.size,sizeof(Reference),cmpRef);
00866   //  ::qsort(DataMap,Data.size,sizeof(int),cmpCh);
00867   if(Refs.size > 0) ::qsort(refMap,Refs.size,sizeof(Reference),cmpRef);
00868   if(Data.size > 0) ::qsort(DataMap,Data.size,sizeof(int),cmpCh);
00869   status=ScriptErrors;
00870   if(status)return;
00871   Data.hg=(float *)calloc(Data.size,sizeof(float));
00872   if(!Data.hg)
00873     {
00874       cout<<"Can't allocate memory for HighGain!!!"<<endl;
00875       status=1000;
00876       return;
00877     }
00878   Data.lg=(float *)calloc(Data.size,sizeof(float));
00879   if(!Data.lg)
00880     {
00881       cout<<"Can't allocate memory for LowGain!!!"<<endl;
00882       status=1001;
00883       return;
00884     }
00885   Data.tac=(float *)calloc(Data.size,sizeof(float));
00886   if(!Data.tac)
00887     {
00888       cout<<"Can't allocate memory for TAC!!!"<<endl;
00889       status=1002;
00890       return;
00891     }
00892   if(outputRaw)
00893     {
00894       Data.rawdata=(float **)calloc(5,sizeof(float*));
00895       for(int rc=0;rc<5;rc++)
00896         {
00897           Data.rawdata[rc]=(float *)calloc(Data.size,sizeof(float));
00898           if(!Data.rawdata[rc])
00899             {
00900               cout<<"Can't allocate memory for raw data!!!"<<endl;
00901               status=1012;
00902               return;
00903             }
00904         }
00905     }
00906   Refs.hg=(float *)calloc(Refs.size,sizeof(float));
00907   if(!Refs.hg)
00908     {
00909       cout<<"Can't allocate memory for references HighGain!!!"<<endl;
00910       status=1003;
00911       return;
00912     }
00913   Refs.lg=(float *)calloc(Refs.size,sizeof(float));
00914   if(!Refs.lg)
00915     {
00916       cout<<"Can't allocate memory for references LowGain!!!"<<endl;
00917       status=1004;
00918       return;
00919     }
00920   Refs.tac=(float *)calloc(Refs.size,sizeof(float));
00921   if(!Refs.tac)
00922     {
00923       cout<<"Can't allocate memory for references TAC!!!"<<endl;
00924       status=1005;
00925       return;
00926     }
00927   if(outputRaw)
00928     {
00929       Refs.rawdata=(float **)calloc(5,sizeof(float*));
00930       for(int rf=0;rf<5;rf++)
00931         {
00932           Refs.rawdata[rf]=(float *)calloc(Refs.size,sizeof(float));
00933           //      if(Refs.size > 0) Refs.rawdata[rf]=(float *)calloc(Refs.size,sizeof(float));
00934           if(!Refs.rawdata[rf])
00935             {
00936               cout<<"Can't allocate memory for references raw data!!!"<<endl;
00937               status=1022;
00938               return;
00939             }
00940         }
00941     }
00942   setSMad();
00943   // Find Supermodule that correponds to reference
00944   setREFtoSM();
00945   if(channelMap)
00946     {
00947       for(int im=0;im<Data.size;im++)
00948         DataMap[im] = EmcIndexer::absFEMCHiPX(DataMap[im]);
00949     }
00950   return;
00951 }
00952 void EmcDynamicData::setSMad()
00953 {
00954   int ctotal=0;
00955   int rtotal=0;
00956   for(int i=0;i<nSM;i++)
00957     {
00958       smMap[i].startTad=ctotal;
00959       ctotal+=smMap[i].nch;
00960       smMap[i].startRad=rtotal;
00961       rtotal+=smMap[i].nrefCh;
00962     }
00963 }
00964 void EmcDynamicData::setREFtoSM() //makes crossreferences between SuperModule and Reference objects
00965 {
00966   for(int r=0;r<Refs.size;r++)
00967     {
00968       for(int s=0;s<nSM;s++)
00969         {
00970           //                    if(refMap[r].absPosition<smMap[s].absPosition)break;
00971           if(refMap[r].absPosition==smMap[s].absPosition)
00972             {
00973               refMap[r].nSMch=smMap[s].nch; //set number of SM channels in reference structure
00974               refMap[r].startSMad=smMap[s].startTad; // set starting address of SM data in data array
00975               smMap[s].adRef=(int*)realloc(smMap[s].adRef,(smMap[s].nref+1)*sizeof(int));
00976               if(!smMap[s].adRef)
00977                 {
00978                   cout<<"Can't reallocate memory for SM reference list!!!"<<endl;
00979                   ScriptErrors++;
00980                   return;
00981                 }
00982               smMap[s].adRef[smMap[s].nref]=r;  //add reference to SM reference list
00983               smMap[s].nref++;           //increment nnumber of references
00984                                 //                              break;
00985             }
00986           if(refMap[r].absFEM==smMap[s].absPosition)
00987             {
00988               int absRefAd=refMap[r].chan+refMap[r].absFEM*FEMChannels;
00989               int i;
00990               for(i=smMap[s].startTad;i<(smMap[s].startTad+smMap[s].nch);i++)
00991                 {
00992                   if(absRefAd==DataMap[i])
00993                     {
00994                       refMap[r].chan=i;
00995                       break;
00996                     }
00997                 }
00998               if(i==(smMap[s].startTad+smMap[s].nch))
00999                 {
01000                   refMap[r].chan=-1;
01001                 }
01002             }
01003         }
01004     }
01005 }
01006 
01007 
01008 EmcDynamicData::~EmcDynamicData()
01009 {
01010   free(Data.hg);
01011   free(Data.lg);
01012   free(Data.tac);
01013   free(Refs.hg);
01014   free(Refs.lg);
01015   free(Refs.tac);
01016   free(DataMap);
01017   for(int i=0;i<nSM;i++)
01018     {
01019       free(smMap[i].femCh);
01020       free(smMap[i].refCh);
01021       free(smMap[i].adRef);
01022     }
01023   free(smMap);
01024   free(refMap);
01025   if(Data.rawdata)
01026     {
01027       for(int rc=0;rc<5;rc++)
01028         free(Data.rawdata[rc]);
01029       free(Data.rawdata);
01030     }
01031   if(Refs.rawdata)
01032     {
01033       for(int rf=0;rf<5;rf++)
01034         free(Refs.rawdata[rf]);
01035       free(Refs.rawdata);
01036     }
01037 }
01038 
01039         
01040