mEmcRawToLong.c

Go to the documentation of this file.
00001 #include "mEmcRawToLong.h"
00002 #include "packetConstants.h"
00003 #include "emlLib.h"
00004 
00008 long mEmcRawToLong_(
00009   TABLE_HEAD_ST    *dEmcRawData_h,    DEMCRAWDATA_ST      *dEmcRawData ,
00010   TABLE_HEAD_ST    *dEmcDCMLongData_h,    DEMCDCMLONGDATA_ST *dEmcDCMLongData )
00011 {
00012 /*:>--------------------------------------------------------------------
00013 **: ROUTINE:    mEmcRawToDCMLongData_
00014 **: DESCRIPTION: Physics Analysis Module ANSI C template.
00015 **:             This is an ANSI C Physics Analysis Module template
00016 **:             automatically generated by stic from mEmcRawToLong.idl.
00017 **:             Please edit comments and code.
00018 **: AUTHOR:     hpl - H.P. Lovecraft, hplovecraft@cthulhu.void
00019 **: ARGUMENTS:
00020 **:       IN:
00021 **:        dEmcRawData    - PLEASE FILL IN DESCRIPTION HERE
00022 **:       dEmcRawData_h   - header Structure for dEmcRawData
00023 **:    INOUT:
00024 **:      OUT:
00025 **:        dEmcDCMLongData    - PLEASE FILL IN DESCRIPTION HERE
00026 **:       dEmcDCMLongData_h   - header Structure for dEmcDCMLongData
00027 **: RETURNS:    STAF Condition Value
00028 **:>------------------------------------------------------------------*/
00029 
00030   short sector;
00031   short i,j,k;
00032   long rawdata[5][4608][4][2];   /* Max value for PbGl, PbSc is 2592 only */
00033   long activemodule[32][4][2];   /* One for each FEM module */
00034   int ll;
00035   long iarm,isector,iz,iy,itower,imod,ichan,imody,imodz,ichany,ichanz;
00036   long swkey;
00037   long FEMmodule;
00038   int  icount;
00039   int  pkts_per_sector;
00040  
00041   static unsigned short header = 0xFFFF;
00042   static unsigned int trailer = 0x70001;
00043  
00044   short timecell = 1;
00045   short precell = 2;
00046   short postcell = 3;
00047   short iflag,ievno,iclock,idetid;
00048   short ioffset;
00049   int channel;
00050   int  fem_channel;
00051  
00052   /* this is the map of software tower channel to fem channel
00053      (software map to hardware map) */
00054   const int fem_map[144] = {
00055     21,  20,  45,  44,  69,  68,  93,  92, 117, 116, 141, 140,
00056     23,  22,  47,  46,  71,  70,  95,  94, 119, 118, 143, 142,
00057     17,  16,  41,  40,  65,  64,  89,  88, 113, 112, 137, 136,
00058     19,  18,  43,  42,  67,  66,  91,  90, 115, 114, 139, 138,
00059     13,  12,  37,  36,  61,  60,  85,  84, 109, 108, 133, 132,
00060     15,  14,  39,  38,  63,  62,  87,  86, 111, 110, 135, 134,
00061      9,   8,  33,  32,  57,  56,  81,  80, 105, 104, 129, 128,
00062     11,  10,  35,  34,  59,  58,  83,  82, 107, 106, 131, 130,
00063      5,   4,  29,  28,  53,  52,  77,  76, 101, 100, 125, 124,
00064      7,   6,  31,  30,  55,  54,  79,  78, 103, 102, 127, 126,
00065      1,   0,  25,  24,  49,  48,  73,  72,  97,  96, 121, 120,
00066      3,   2,  27,  26,  51,  50,  75,  74,  99,  98, 123, 122
00067   };
00068 
00069   short i_FEMData;   /* Counter of output rows */
00070 
00071   long userword[8];
00072   
00073   int tempsize;
00074 
00075   /* ----------  Executable  -------------------------------*/
00076 
00077   if(dEmcRawData_h->nok <= 0)
00078     {
00079       printf("Error in mEmcRawToFEM: raw data table empty \n");
00080       return ( STAFCV_BAD);
00081     }
00082   /*
00083     Read raw data.  Using hwkey restore sector and serial number
00084     of channel within the sector.  Compute FEM module number that goes
00085     with the channel.  Indicate in a table that this FEM has at least
00086     one hit, and store raw data until read-in is finished
00087     We assume that one specific channel has only one raw data entry
00088     in dEmcRawData table
00089   */    
00090 
00091   for (ll = 0; ll < sizeof(rawdata)/sizeof(rawdata[0][0][0][0]); ll++)
00092     {
00093       *((long *)rawdata + ll) = 0;
00094     }
00095   for (ll = 0; ll < sizeof(activemodule)/sizeof(activemodule[0][0][0]); ll++)
00096     {
00097       *((long *)activemodule + ll) = 0;
00098     }
00099   for (ll = 0; ll < sizeof(userword)/sizeof(userword[0]); ll++)
00100     {
00101       *(userword + ll) = 0;
00102     }
00103   /* Take care of proper filling later ! */
00104   
00105   /* Set userwords to 5900 */
00106   for (i=0;i<8;i++) userword[i] = 0x00005900;
00107 
00108   ievno = dEmcRawData[0].evno & 0xffff;   /* Word only, not longword */
00109   iclock = ievno - 1;                     /* Dummy, take care of it ! */
00110   iflag = 0;                              /* Dummy for now */
00111   idetid = 4;
00112   
00113   i_FEMData = 0;
00114   
00115   
00116   for ( i = 0; i < dEmcRawData_h->nok ; i++)
00117     {
00118       /* Replace this section: derive everything from swkey,
00119          to get more transparent to "Indexer"
00120          Jan. 3, 2000, G. David */
00121 
00122       swkey = dEmcRawData[i].swkey;
00123       iarm = swkey / 100000; swkey = swkey - 100000 * iarm;
00124       isector = swkey / 10000; swkey = swkey - 10000 * isector;
00125       iy = swkey / 100; 
00126       iz = swkey - 100 * iy;
00127 
00128       /* Get supermodule and channel within supermodule */
00129       if(iarm == 0 || isector > 1)
00130         /* This is PbSc */
00131         {
00132           /* Supermodule numbering goes like 6 * y + z */
00133           imody = iy / 12;
00134           imodz = iz / 12;
00135           imod = 6 * imody + imodz;
00136           /* Channel within supermodule goes like 12 * y + z */
00137           ichany = iy % 12;
00138           ichanz = iz % 12;
00139           ichan = 12 * ichany + ichanz;
00140           itower = 144 * imod + ichan;
00141           fem_channel = 144 * imod + fem_map[ichan];
00142         }
00143       else      
00144         /* This is PbGl */
00145         {
00146           /* Super-duper-module numbering goes like 8 * y + z */
00147           imody = iy / 12;
00148           imodz = iz / 12;
00149           imod = 8 * imody + imodz;
00150           /* Channel within supermodule goes like 12 * y + z */
00151           ichany = iy % 12;
00152           ichanz = iz % 12;
00153           ichan = 12 * ichany + ichanz;
00154           itower = 144 * imod + ichan;
00155           fem_channel = 144 * imod + fem_map[ichan];
00156         }
00157       activemodule[imod][isector][iarm] = 1;
00158       
00159       
00160       /* Fake values to time, pre and post AMU cell numbers */
00161       /* we might want to make these random from 0-63, */
00162       /* since that would better correspond to reality */
00163 
00164       timecell = 1;
00165       precell = 2;
00166       postcell = 3;
00167       
00168       /*
00169          put in raw data channels.  note that adclopost is
00170          for high gain data
00171       */
00172       rawdata[0][fem_channel][isector][iarm] = dEmcRawData[i].adclopost;
00173       rawdata[1][fem_channel][isector][iarm] = dEmcRawData[i].adclopre;
00174       rawdata[2][fem_channel][isector][iarm] = dEmcRawData[i].adchipost;
00175       rawdata[3][fem_channel][isector][iarm] = dEmcRawData[i].adchipre;
00176       rawdata[4][fem_channel][isector][iarm] = dEmcRawData[i].tdc;
00177       
00178     }   /* End for i = 0, loop over RawData rows */
00179 
00180   /*
00181     OK, now let's write out one dEmcFEMData structure for each FEM
00182     that has at least one non-zero channel
00183    */
00184 
00185   for ( isector = 0; isector < 4; isector++)
00186     {
00187       for (iarm = 0; iarm < 2; iarm++)
00188         {
00189           if(iarm == 0 || isector > 1)
00190             {
00191               pkts_per_sector = 18;
00192             }
00193           else
00194             {
00195               pkts_per_sector = 32;
00196             }
00197           for ( imod = 0; imod < pkts_per_sector; imod++)
00198             {
00199 
00200               // write out only the modules that have data
00201               if( activemodule[imod][isector][iarm] > 0 )
00202                 {
00203                   dEmcDCMLongData[i_FEMData].scheme = 1108;
00204 
00205                   /* 
00206                      Eventually check how module is encoded!
00207                      Right now it is similar to "hwkey"
00208                   */
00209 
00210                   /* Encode serially */
00211                   if(iarm == 0)
00212                     {
00213                       FEMmodule = 18 * isector + imod;
00214                     }
00215                   else
00216                     {
00217                       if(isector > 1)
00218                         {
00219                           FEMmodule = 72 + 18 * (isector - 2) + imod;
00220                         }
00221                       else
00222                         {
00223                           FEMmodule = 108 + 32 * isector + imod;
00224                         }
00225                     }
00226 
00227                   dEmcDCMLongData[i_FEMData].packetID = 8001 + FEMmodule;
00228 
00229                   icount = 0;   // keeps track of where we are in the packet
00230                   dEmcDCMLongData[i_FEMData].DCM[icount++] = iflag;
00231                   dEmcDCMLongData[i_FEMData].DCM[icount++] = FEMmodule + 1;
00232                   dEmcDCMLongData[i_FEMData].DCM[icount++] = ievno;
00233                   dEmcDCMLongData[i_FEMData].DCM[icount++] = iclock;
00234                   dEmcDCMLongData[i_FEMData].DCM[icount++] = idetid;
00235 
00236                   dEmcDCMLongData[i_FEMData].DCM[icount++] = postcell;
00237                   dEmcDCMLongData[i_FEMData].DCM[icount++] = precell;
00238                   dEmcDCMLongData[i_FEMData].DCM[icount++] = timecell;
00239 
00240                   ioffset = imod * 144;
00241 
00242                   /* the real data channels are scrambled */
00243                   for ( fem_channel = ioffset; fem_channel < ioffset + 144; fem_channel++)
00244                     {
00245                       channel = (fem_channel - ioffset) << 20;
00246 
00247                       /* in simulated data, there is a hit if the channel data
00248                          are non-zero */
00249                       if ( rawdata[0][fem_channel][isector][iarm] != 0 )
00250                           { 
00251                             dEmcDCMLongData[i_FEMData].DCM[icount++] = channel |
00252                                    (rawdata[0][fem_channel][isector][iarm] ^ 0xfff) | 0x92000;
00253                             dEmcDCMLongData[i_FEMData].DCM[icount++] = channel |
00254                                    (rawdata[1][fem_channel][isector][iarm] ^ 0xfff) | 0xa4000;
00255                             dEmcDCMLongData[i_FEMData].DCM[icount++] = channel |
00256                                    (rawdata[2][fem_channel][isector][iarm] ^ 0xfff) | 0xb3000;
00257                             dEmcDCMLongData[i_FEMData].DCM[icount++] = channel |
00258                                    (rawdata[3][fem_channel][isector][iarm] ^ 0xfff) | 0xc5000;
00259                             dEmcDCMLongData[i_FEMData].DCM[icount++] = channel |
00260                                    (rawdata[4][fem_channel][isector][iarm] ^ 0xfff) | 0xd1000;
00261                           }
00262 
00263                     }  /* End loop over itower from ioffset to ioffset + 144 */
00264 
00265                   dEmcDCMLongData[i_FEMData].DCM[icount++] = 0x10080000; /* long. parity */
00266                   dEmcDCMLongData[i_FEMData].DCM[icount++] = 0x10072220; /* summary word */
00267 
00268                   dEmcDCMLongData[i_FEMData].nWords = icount;   /* now put in length */
00269 
00270                   /* Increment table row count */
00271                   
00272                   i_FEMData = i_FEMData + 1;
00273                 }  /* End if (activemodule[imod][isector] > 0) */
00274               
00275             }   /* End loop over imod, max. number of FEM modules in sector */
00276         }    /* End loop over iarm */
00277       
00278     }    /* End loop over isector, all sectors */
00279   
00280   dEmcDCMLongData_h->nok = i_FEMData;
00281   
00282 
00283   return STAFCV_OK;
00284 }
00285