LCOV - code coverage report
Current view: top level - HLT/TPCLib/HWCFemulator - AliHLTTPCHWCFSupport.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 18 357 5.0 %
Date: 2016-06-14 17:26:59 Functions: 5 15 33.3 %

          Line data    Source code
       1             : // $Id$
       2             : //****************************************************************************
       3             : //* This file is property of and copyright by the ALICE HLT Project          * 
       4             : //* ALICE Experiment at CERN, All rights reserved.                           *
       5             : //*                                                                          *
       6             : //* Primary Authors: Sergey Gorbunov, Torsten Alt                            *
       7             : //* Developers:      Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> *
       8             : //*                  Torsten Alt <talt@cern.ch>                              *
       9             : //*                  for The ALICE HLT Project.                              *
      10             : //*                                                                          *
      11             : //* Permission to use, copy, modify and distribute this software and its     *
      12             : //* documentation strictly for non-commercial purposes is hereby granted     *
      13             : //* without fee, provided that the above copyright notice appears in all     *
      14             : //* copies and that both the copyright notice and this permission notice     *
      15             : //* appear in the supporting documentation. The authors make no claims       *
      16             : //* about the suitability of this software for any purpose. It is            *
      17             : //* provided "as is" without express or implied warranty.                    *
      18             : //****************************************************************************
      19             : 
      20             : //  @file   AliHLTTPCHWCFSupport.cxx
      21             : //  @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
      22             : //  @author Torsten Alt <talt@cern.ch> 
      23             : //  @brief  Input interfaces for FPGA ClusterFinder Emulator for TPC
      24             : //  @brief  ( see AliHLTTPCHWCFEmulator class )
      25             : //  @note
      26             : 
      27             : 
      28             : #include "AliHLTTPCHWCFSupport.h"
      29             : #include "AliHLTDataTypes.h"
      30             : #include "AliHLTTPCMapping.h"
      31             : #include "AliHLTTPCDigitReaderUnpacked.h"
      32             : #include "AliHLTTPCGeometry.h"
      33             : #include "AliHLTTPCDefinitions.h"
      34             : #include "AliHLTCDHWrapper.h"
      35             : #include "AliHLTTPCHWCFEmulator.h"
      36             : #include "AliTPCcalibDB.h"
      37             : #include "AliTPCCalPad.h"
      38             : #include "AliTPCCalROC.h"
      39             : #include "TMath.h"
      40             : 
      41             : #include <cstdlib>
      42             : #include <algorithm>
      43             : #include <cerrno>
      44             : #include <sys/time.h>
      45             : 
      46             : using namespace std;
      47             : 
      48             : AliHLTTPCHWCFSupport::AliHLTTPCHWCFSupport()
      49             :   : 
      50           3 :   AliHLTLogging(),
      51           3 :   fProcessingRCU2Data(0),
      52           3 :   fEventMemory(0),
      53           3 :   fEventMCMemory(0)
      54          15 : {
      55             :   // see header file for class documentation
      56         222 :   for( int i=0; i<fgkNSlices; i++ )
      57        1512 :     for( int j=0; j<fgkNPatches; j++ ) fMapping[i][j] = 0;
      58           6 : }
      59             : 
      60             : 
      61             : AliHLTTPCHWCFSupport::~AliHLTTPCHWCFSupport()
      62          12 : {
      63             :   // see header file for class documentation
      64         222 :   for( int i=0; i<fgkNSlices; i++ )
      65        2160 :     for( int j=0; j<fgkNPatches; j++ ) delete[] fMapping[i][j];
      66           3 :   ReleaseEventMemory(); 
      67           6 : }
      68             : 
      69             : AliHLTTPCHWCFSupport::AliHLTTPCHWCFSupport(const AliHLTTPCHWCFSupport&)
      70             :   : 
      71           0 :   AliHLTLogging(),
      72           0 :   fProcessingRCU2Data(0),
      73           0 :   fEventMemory(0),
      74           0 :   fEventMCMemory(0)
      75           0 : {
      76             :   // dummy
      77           0 : }
      78             : 
      79             : AliHLTTPCHWCFSupport& AliHLTTPCHWCFSupport::operator=(const AliHLTTPCHWCFSupport&){
      80             :   // dummy
      81           0 :   return *this;
      82             : }
      83             : 
      84             : 
      85             : void AliHLTTPCHWCFSupport::ReleaseEventMemory()
      86             : {
      87             :   // clean up 
      88           6 :   if( fEventMemory ) delete[] fEventMemory;
      89           3 :   if( fEventMCMemory )delete[] fEventMCMemory;
      90           3 :   fEventMemory = 0;
      91           3 :   fEventMCMemory = 0;
      92           3 : }
      93             : 
      94             : void AliHLTTPCHWCFSupport::UnloadMapping()
      95             : {
      96             :   // unload mapping
      97           0 :   for( int i=0; i<fgkNSlices; i++ ){
      98           0 :     for( int j=0; j<fgkNPatches; j++ ){
      99           0 :       delete[] fMapping[i][j];
     100           0 :       fMapping[i][j] = NULL;
     101             :     }
     102             :   }
     103           0 : }
     104             : 
     105             : const AliHLTUInt32_t *AliHLTTPCHWCFSupport::GetMapping( int slice, int patch )
     106             : { 
     107             :   // see header file for class documentation
     108           0 :   if( slice<0 || slice>=fgkNSlices ){
     109           0 :     HLTFatal("Wrong slice number %d, no mapping is provided.", slice);
     110           0 :     return 0;
     111             :   }
     112           0 :   if( patch<0 || patch>= fgkNPatches ){
     113           0 :     HLTFatal("Wrong patch number %d, no mapping is provided.", patch);
     114           0 :     return 0;
     115             :   }
     116           0 :   if( !fMapping[slice][patch] ) fMapping[slice][patch] = ReadMapping(slice,patch);
     117           0 : return fMapping[slice][patch];
     118           0 : }
     119             : 
     120             : 
     121             : AliHLTUInt32_t *AliHLTTPCHWCFSupport::ReadMapping( int slice, int patch, const char *mappingFileName ) const
     122             : {
     123             :   // Create mapping array for one patch 
     124             :   // If no mapping file provided, reads from default file
     125             :   // Output: mapping [] array of type AliHLTUInt32_t, where :
     126             :   //
     127             :   // mapping[0] == N hardware adresses in the array (mapping size is maping[0] + 1 )
     128             :   // mapping[hwAddress] == configWord
     129             :   //
     130             :   // configWord consist of:
     131             :   //
     132             :   // bits 0-7: pad number
     133             :   // bits 8-13: row number
     134             :   // bit  14 : flag for border pad
     135             :   // bit  15 : is the pad active
     136             :   // bits 16->28 : gain calibration as 13 bit fixed point,
     137             :   //               with 1 bit position before decimal point
     138             : 
     139             :   const AliHLTUInt32_t  kBorderFlag = (1 << 14); 
     140             :   const AliHLTUInt32_t  kActiveFlag = (1 << 15); 
     141             :   
     142           0 :   if( slice<0 || slice>=fgkNSlices ){
     143           0 :      HLTFatal("Wrong slice number %d, no mapping is provided.", slice);
     144           0 :      return 0;
     145             :   }
     146             : 
     147           0 :   if( patch<0 || patch>5 ){
     148           0 :      HLTFatal("Wrong patch number %d, no mapping is provided.", patch);
     149           0 :      return 0;
     150             :   }
     151             : 
     152             :   // AliHLTTPCGeometry::GetFirstRow returns first row in scheme A.
     153             :   // We have to transform to scheme B by AliHLTTPCGeometry::Slice2Sector.
     154             : 
     155             :   UInt_t offsetSchemeB=0;
     156           0 :   Int_t sector = 0;
     157             :   {
     158           0 :     Int_t tmp=0;
     159           0 :     AliHLTTPCGeometry::Slice2Sector(slice, AliHLTTPCGeometry::GetFirstRow(patch),
     160             :                                      sector, tmp);
     161           0 :     offsetSchemeB = (UInt_t) tmp;
     162           0 :   }
     163             :   
     164             : 
     165           0 :   AliTPCcalibDB *calib = AliTPCcalibDB::Instance();  
     166             :   AliTPCCalPad * gainTPC = 0;
     167             :   AliTPCCalROC * gainROC = 0;
     168           0 :   if( calib ) gainTPC = calib->GetPadGainFactor();
     169           0 :   if( gainTPC ) gainROC = gainTPC->GetCalROC(sector);  // pad gains per given sector
     170             :   else{      
     171           0 :     HLTWarning("No TPC gain calibration found");  
     172             :   }
     173             : 
     174           0 :   TString filename;
     175             :   
     176           0 :   if( mappingFileName ){
     177           0 :     filename = mappingFileName;
     178             :   } else {
     179           0 :     const char* basePath=getenv("ALICE_ROOT");
     180           0 :     if (basePath) filename.Form("%s/TPC/mapping/Patch%d.data", basePath,patch);    
     181             :   } 
     182             :   
     183           0 :   ifstream inFile;
     184           0 :   inFile.open(filename.Data());
     185           0 :   if (!inFile) {
     186           0 :     HLTFatal("Unable to open mapping file: %s   This means no mapping is provided.", filename.Data());
     187           0 :     return 0;
     188             :   }
     189             : 
     190             : 
     191             :   AliHLTUInt32_t *mapping = 0; 
     192             :   AliHLTUInt32_t *rowBranchPadHw = 0;
     193             :   bool err = 1;
     194             :   do{
     195             : 
     196           0 :     UInt_t nHWAdd=0;
     197           0 :     UInt_t maxHWAdd=0;
     198             : 
     199           0 :     if( !(inFile >> nHWAdd ) || !(inFile >> maxHWAdd)  ){
     200           0 :       HLTError("Mapping file for patch %d corrupted &s", patch,filename.Data());
     201           0 :       break;
     202             :     }
     203             : 
     204           0 :     if( maxHWAdd > 0xFFF ){
     205           0 :       HLTError("Max hardware address exceeded for patch %d, max number is %d, number from mapping file is %d.",patch, 0xFFF, maxHWAdd+1);     
     206           0 :       break;
     207             :     }
     208             : 
     209           0 :     if(nHWAdd > maxHWAdd ){
     210           0 :       HLTError("Too large number of hardware addresses for patch %d: max number is %d, number from mapping file is %d.",patch, maxHWAdd, nHWAdd );
     211           0 :       break;
     212             :     }
     213             :       
     214           0 :     mapping = new AliHLTUInt32_t[maxHWAdd+2];
     215           0 :     rowBranchPadHw = new AliHLTUInt32_t[nHWAdd];
     216           0 :     if( !mapping || !rowBranchPadHw ){
     217           0 :       HLTError("Can not allocate &d bytes of memory", (maxHWAdd+1+nHWAdd)*sizeof(AliHLTUInt32_t));
     218           0 :       break;
     219             :     }
     220             : 
     221           0 :     for( unsigned int i=0; i<maxHWAdd+2; i++ ) mapping[i] = 0;
     222           0 :     for( unsigned int i=0; i<nHWAdd; i++ ) rowBranchPadHw[i] = 0;    
     223           0 :     mapping[0] = maxHWAdd+1;
     224             :     UInt_t nRead = 0;
     225             :     err = 0;
     226           0 :     while(!err ){
     227           0 :       UInt_t hwAdd=0;
     228           0 :       UInt_t row=0;
     229           0 :       UInt_t pad=0;
     230           0 :       if( !(inFile>>hwAdd) || !(inFile>>row) || !(inFile>>pad) ) break;      
     231             : 
     232             :       err = 1;
     233             : 
     234           0 :       if ( nRead >= nHWAdd ){
     235           0 :         HLTError("Too many hardware addresses: %d, expected %d, mapping file %s corrupted?", nRead+1,  nHWAdd, filename.Data());
     236           0 :         break;
     237             :       }
     238           0 :       if (hwAdd>maxHWAdd) {
     239           0 :         HLTError("hardware address exceeds max hwAddress %d, mapping file %s corrupted?", maxHWAdd, filename.Data()); 
     240           0 :         break;
     241             :       }
     242             : 
     243           0 :       if( row < offsetSchemeB ){
     244           0 :         HLTError("row number %d below minimum %d for patch %d, mapping file %s corrupted?", row, offsetSchemeB, patch, filename.Data());      
     245           0 :         break;    
     246             :       } 
     247             : 
     248           0 :       row -= offsetSchemeB;
     249             :         
     250           0 :       if( row > 0x3F ){
     251           0 :         HLTError("row number %d withing patch exceed the maximum %d for patch %d, mapping file %s corrupted?", row, 0x3F, patch, filename.Data());    
     252           0 :         break;    
     253             :       }
     254             : 
     255           0 :       if( pad > 0xFF ){
     256           0 :         HLTError("pad number %d exceed the maximum %d for patch %d, mapping file %s corrupted?", pad, 0xFF, patch, filename.Data());  
     257           0 :         break;    
     258             :       }
     259             : 
     260             :       bool active = true; // Currently all channels are always active   
     261             :       //
     262             : 
     263             :       AliHLTFloat64_t gain = 1.;
     264           0 :       if( gainROC ){
     265           0 :         gain = gainROC->GetValue(offsetSchemeB+row,pad);
     266           0 :         if( gain>1.e-4 ) gain = 1./gain;
     267             :         else gain = 0;
     268             :       }
     269           0 :       gain*= (1<<12);
     270           0 :       AliHLTUInt32_t  gainCalib = TMath::Nint(gain); 
     271           0 :       if( gainCalib > 0x1FFF ) gainCalib = 0x1FFF;
     272             : 
     273           0 :       AliHLTUInt32_t configWord = ( (row & 0x3F) << 8 ) | (pad & 0xFF);
     274           0 :       if ( active ) configWord |= kActiveFlag;
     275           0 :       configWord |= (gainCalib & 0x1FFF) << 16;       
     276             : 
     277           0 :       mapping[1+hwAdd] = configWord;
     278             :         
     279           0 :       AliHLTUInt32_t branch = (hwAdd >> 11) & 0x1;    
     280           0 :       if( fProcessingRCU2Data ) branch = 0;
     281           0 :       rowBranchPadHw[nRead] = (row<<25) | (branch<<24) | (pad<<16) | hwAdd;
     282             : 
     283           0 :       nRead++;
     284             :       err = 0;
     285           0 :     }
     286             :     
     287           0 :     if( err ) break;
     288             :     
     289           0 :     if ( nRead!= nHWAdd ){
     290           0 :       HLTError("Too less hardware addresses: %d, expected %d, mapping file %s corrupted?", nRead,  nHWAdd, filename.Data());
     291             :       err = 1;
     292           0 :       break;
     293             :     }
     294             :     
     295             :     // mark pads at borders of A/B branches 
     296             :       
     297           0 :     std::sort(rowBranchPadHw, rowBranchPadHw + nHWAdd);
     298             :     int rowBranchPadLast = -10;
     299           0 :     for( unsigned int i=0; i<nHWAdd; i++ ){
     300           0 :       int rowBranchPad = rowBranchPadHw[i]>>16;
     301           0 :       if( rowBranchPad != rowBranchPadLast+1 ){
     302           0 :         mapping[1+(rowBranchPadHw[i] & 0xFFF)] |= kBorderFlag;
     303           0 :         if( i>0 ) mapping[1+(rowBranchPadHw[i-1] & 0xFFF)] |= kBorderFlag;         
     304             :       }
     305             :       rowBranchPadLast = rowBranchPad;
     306             :     }
     307           0 :     mapping[1+(rowBranchPadHw[nRead-1] & 0xFFF)] |= kBorderFlag;
     308             :     
     309           0 :   } while(0);
     310             :   
     311           0 :   inFile.close();
     312             : 
     313           0 :   delete[] rowBranchPadHw;
     314             : 
     315           0 :   if( err ){
     316           0 :     delete[] mapping; 
     317           0 :     return 0;
     318             :   }
     319           0 :   return mapping;
     320           0 : }
     321             : 
     322             : 
     323             : int AliHLTTPCHWCFSupport::CreateRawEvent
     324             : ( const AliHLTComponentBlockData* block, 
     325             :   const AliHLTUInt32_t *&rawEvent, AliHLTUInt32_t &rawEventSize32, 
     326             :   const AliHLTTPCClusterMCLabel *&mcLabels,  AliHLTUInt32_t &nMCLabels 
     327             : )
     328             : {
     329             :   // the method creates TPC raw data out of the input block
     330             :   // MC labels are provided if possible  
     331             :   //
     332             : 
     333           0 :   ReleaseEventMemory();
     334             :   
     335           0 :   rawEvent = 0;
     336           0 :   rawEventSize32 = 0;
     337           0 :   mcLabels = 0;
     338           0 :   nMCLabels = 0;
     339             :       
     340           0 :   if( block->fPtr==NULL ){
     341           0 :     HLTWarning("NULL pointer to the data block");
     342           0 :     return 0;
     343             :   }
     344             : 
     345           0 :   Int_t slice = AliHLTTPCDefinitions::GetMinSliceNr( *block );
     346           0 :   Int_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *block );
     347           0 :   AliHLTTPCMapping mapping(patch);
     348             : 
     349           0 :   const char *str=Form("slice %d patch %d:", slice, patch);
     350             : 
     351           0 :   if ( block->fDataType == (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) )
     352             :     {    
     353             :       // already raw format -> only set the pointers and estimate the size
     354             : 
     355             :       // read CDH header, estimate size of the data 
     356           0 :       AliHLTCDHWrapper cdhHeader(block->fPtr);
     357             : 
     358           0 :       AliHLTUInt64_t headerSize = cdhHeader.GetHeaderSize();
     359             :  
     360           0 :       AliHLTUInt64_t blockSize = block->fSize; // size of the raw data in bytes      
     361             : 
     362           0 :       if( cdhHeader.GetDataSize()!=0xFFFFFFFF ){ // use size information from the header
     363           0 :         blockSize = cdhHeader.GetDataSize();
     364           0 :         if( blockSize > block->fSize ){
     365           0 :           HLTWarning("%s Could not find a valid DDL header!",str);
     366           0 :           return 0;
     367             :         }
     368             :       }
     369             :       
     370           0 :       if( blockSize < headerSize ){
     371           0 :         HLTWarning("%s Buffer size is smaller than CDH header size", str);
     372           0 :         return 0;
     373             :       }
     374             :       
     375           0 :       rawEvent = reinterpret_cast<AliHLTUInt32_t*> (reinterpret_cast<UChar_t*>(block->fPtr)+headerSize);
     376           0 :       rawEventSize32 = ( blockSize - headerSize )/sizeof(AliHLTUInt32_t);
     377             : 
     378           0 :     }
     379           0 :   else if ( block->fDataType == AliHLTTPCDefinitions::fgkUnpackedRawDataType )
     380             :     {
     381             : 
     382           0 :       AliHLTTPCDigitReaderUnpacked digitReader;          
     383           0 :       digitReader.SetUnsorted(kTRUE);      
     384             :       
     385           0 :       if( digitReader.InitBlock(block->fPtr,block->fSize,patch,slice)<0 ) {
     386           0 :         HLTWarning("failed setting up digit reader (InitBlock)");
     387           0 :         return 0;
     388             :       }
     389             : 
     390             :       int nDigitsTotal = 0;
     391             :       int nBunchesTotal = 0;
     392             :      
     393           0 :       while( digitReader.NextChannel() ){
     394           0 :         while(digitReader.NextBunch()){
     395           0 :           nBunchesTotal++;
     396           0 :           nDigitsTotal+=digitReader.GetBunchSize();
     397             :         }
     398             :       }
     399             :       
     400           0 :       digitReader.Reset();
     401             : 
     402           0 :       if( digitReader.InitBlock(block->fPtr,block->fSize,patch,slice)<0) {
     403           0 :         HLTWarning("failed setting up digit reader (InitBlock)");
     404           0 :         return 0;
     405             :       }
     406             :       
     407             :       Int_t nPadsTotal = 0;
     408           0 :       Int_t firstRow = AliHLTTPCGeometry::GetFirstRow(patch);
     409           0 :       Int_t nRows = AliHLTTPCGeometry::GetNRows(patch);
     410             : 
     411           0 :       for( int i=0; i<nRows; i++ ){
     412           0 :         nPadsTotal += AliHLTTPCGeometry::GetNPads(firstRow+i);  
     413             :       }
     414             : 
     415           0 :       AliHLTUInt32_t totalSize32 = (nDigitsTotal + nBunchesTotal*2)/3+2*nPadsTotal + 10;
     416           0 :       AliHLTUInt32_t totalNMC = nDigitsTotal + 10;
     417             :       
     418           0 :       fEventMemory = new AliHLTUInt32_t[totalSize32];
     419           0 :       if( !fEventMemory ){
     420           0 :         HLTWarning("Not enougth memory: can not allocate %d bytes",totalSize32*8);
     421           0 :         return 0;
     422             :       }
     423             : 
     424           0 :       fEventMCMemory = new AliHLTTPCClusterMCLabel[totalNMC];
     425           0 :       if( !fEventMCMemory ){
     426           0 :         HLTWarning("Not enougth memory: can not allocate %d bytes",totalNMC*sizeof(AliHLTTPCClusterMCLabel));
     427           0 :         delete[] fEventMemory;
     428           0 :         fEventMemory = 0;
     429           0 :         return 0;
     430             :       }
     431             : 
     432           0 :       AliHLTUInt32_t nWords32 = 0;
     433             :       AliHLTUInt32_t mcIndex = 0;
     434             :       int err=0;
     435             : 
     436           0 :       AliHLTTPCDigitData tmpDigit;
     437           0 :       tmpDigit.fTrackID[0] = -1;
     438           0 :       tmpDigit.fTrackID[1] = -1;
     439           0 :       tmpDigit.fTrackID[2] = -1;
     440             : 
     441           0 :       while( !err && digitReader.NextChannel() ){
     442             :         
     443           0 :         Int_t row=digitReader.GetRow();
     444           0 :         Int_t pad=digitReader.GetPad();
     445             : 
     446           0 :         AliHLTUInt32_t hwAddr = mapping.GetHwAddress(row, pad);
     447             : 
     448             :         // create header
     449             : 
     450           0 :         if( nWords32 >= totalSize32){ err = 1; break; }      
     451             :         
     452           0 :         AliHLTUInt32_t *header = fEventMemory + nWords32;
     453           0 :         nWords32++;
     454             : 
     455           0 :         int seek10 = 2;
     456             :         int prevTime = 10000000;
     457             :         int nWords10 = 0;
     458           0 :         while(digitReader.NextBunch()){
     459             : 
     460           0 :           if( hwAddr > 0xFFF ) continue;
     461             : 
     462           0 :           Int_t nSignals = digitReader.GetBunchSize();
     463           0 :           if( nSignals <=0 ){
     464           0 :             HLTWarning("Empty bunch received");
     465           0 :             continue;
     466             :           }
     467             : 
     468           0 :           Int_t time = digitReader.GetTime() + nSignals-1;
     469             :           
     470           0 :           if( time-nSignals+1<0 || time>=AliHLTTPCGeometry::GetNTimeBins() ){
     471           0 :             HLTWarning("Wrong time bins received: %d-%d for row %d pad %d", time-nSignals+1, time, row, pad);
     472           0 :             break;
     473             :           }
     474             : 
     475           0 :           if( time >= prevTime ){
     476           0 :             HLTWarning("Unexpected order of TPC bunches in row %d, pad %d", row, pad);            
     477           0 :             break;
     478             :           }
     479             : 
     480             :           prevTime = time-nSignals+1;
     481             :           
     482           0 :           if( nWords32+( 2+nSignals)/3+1 >= totalSize32 ){ err = 1; break; }
     483           0 :           if( mcIndex + nSignals   >= totalNMC ){ err = 1; break; }
     484             : 
     485           0 :           if( nWords10 + 2 + nSignals > 0x3FF ){
     486           0 :             HLTWarning("Too much data in row %d, pad %d", row, pad);      
     487           0 :             break;
     488             :           }
     489             : 
     490           0 :           nWords10 += 2 + nSignals;
     491             : 
     492           0 :           Add10Word( nWords32, seek10, nSignals + 2 );
     493           0 :           Add10Word( nWords32, seek10, time );
     494             :           
     495           0 :           const UInt_t *bunchData = digitReader.GetSignals();
     496           0 :           const AliHLTTPCDigitData *mcDigits = digitReader.GetBunchDigits();
     497           0 :           if( !mcDigits ){
     498           0 :             HLTWarning("No MC labels found for a bunch of digits");
     499             :           }
     500             : 
     501           0 :           for(Int_t is=nSignals-1; is>=0; is--){
     502           0 :             Add10Word( nWords32, seek10, bunchData[is] );           
     503           0 :             const AliHLTTPCDigitData &digit = mcDigits ?mcDigits[is] :tmpDigit;
     504             :             int nmc = 0;
     505           0 :             for( int i=0; i<3; i++ ) if( digit.fTrackID[i] >=0 ) nmc++;      
     506           0 :             for( int i=0; i<3; i++ ){
     507           0 :               fEventMCMemory[mcIndex].fClusterID[i].fMCID = digit.fTrackID[i];
     508           0 :               fEventMCMemory[mcIndex].fClusterID[i].fWeight = 0;
     509           0 :               if( digit.fTrackID[i] >=0 ){                   
     510           0 :                 fEventMCMemory[mcIndex].fClusterID[i].fWeight  = ((float)bunchData[is])/nmc;
     511           0 :               }
     512             :             }     
     513           0 :             mcIndex++;
     514             :           }       
     515             : 
     516           0 :         } // bunches
     517             :         
     518           0 :       *header = (1<<30) | ((nWords10&0x3FF)<<16) | (hwAddr & 0xFFF);
     519             : 
     520           0 :       }// channels (pads)
     521             : 
     522           0 :       if( err ){
     523           0 :         HLTError("Internal error: too less memory allocated");        
     524             :       } else {
     525           0 :         for( AliHLTUInt32_t i=0; i<nWords32; i++ ) fEventMemory[i] = AliHLTTPCHWCFEmulator::WriteBigEndian(fEventMemory[i]);
     526           0 :         rawEvent = fEventMemory;
     527           0 :         rawEventSize32 = nWords32;
     528           0 :         mcLabels = fEventMCMemory;
     529           0 :         nMCLabels = mcIndex;
     530             :       }
     531             : 
     532           0 :     } // unpacked data type
     533             : 
     534           0 :   return 0;
     535           0 : }
     536             : 
     537             : 
     538             : void AliHLTTPCHWCFSupport::Add10Word( AliHLTUInt32_t &nWords32, int &seek10, UInt_t data )
     539             : {
     540             :   // add 10-bit data to the 32-bit word
     541             :   // fEventMemory [nWords32] --- current 32-bit word
     542             :   // *seek10 --- 10-bit position withing the word
     543             :   // pointers are increased, a new word is first initialised to 0
     544             : 
     545           0 :   data = data & 0x3FF; // truncate to 10 bits
     546             : 
     547           0 :   if( seek10 == 2 ){
     548           0 :     nWords32++;
     549           0 :     fEventMemory[nWords32-1] = data<<20;
     550           0 :     seek10 = 1;
     551           0 :   } else if( seek10 == 1 ){
     552           0 :     fEventMemory[nWords32-1] &= 0xFFF003FF;
     553           0 :     fEventMemory[nWords32-1] |= (data<<10);
     554           0 :     seek10 = 0;
     555           0 :   } else if( seek10 == 0 ){
     556           0 :     fEventMemory[nWords32-1] &= 0xFFFFFC00;
     557           0 :     fEventMemory[nWords32-1] |= data;
     558           0 :     seek10 = 2;
     559           0 :   } 
     560           0 : }
     561             : 
     562             : 
     563             : 
     564             : int AliHLTTPCHWCFSupport::CheckRawData( const AliHLTUInt32_t *buffer,
     565             :                                                    unsigned long bufferSize32, int patch, int slice )
     566             : {
     567             :   //
     568             :   // The procedure checks consistency of the data
     569             :   //
     570             : 
     571             : 
     572           0 :   if (!buffer) return 0;
     573             : 
     574           0 :   AliHLTCDHWrapper cdh((void*)buffer);
     575           0 :   const unsigned int headerSize32 = cdh.GetHeaderSize()/4;
     576             : 
     577           0 :   const char *str=Form("slice %d patch %d:", slice, patch);
     578             :   
     579           0 :   if( bufferSize32 < headerSize32 ){
     580           0 :     HLTWarning("%s Buffer size is smaller than CDH header size", str);
     581           0 :     return kFALSE;
     582             :   }    
     583             :   
     584             :   // read data header 
     585             :  
     586           0 :   AliHLTUInt32_t blockSize32 = bufferSize32; // size of the raw data in words
     587             : 
     588           0 :   if( buffer[0]!=0xFFFFFFFF ) blockSize32 = buffer[0]/4; // use size information from the header  
     589           0 :   if( blockSize32 > bufferSize32 ){  
     590           0 :     HLTWarning(Form("%s Could not find a valid DDL header!",str));
     591           0 :     return 0;
     592             :   }
     593             :   
     594           0 :   UChar_t rcuVer = (UChar_t)( (buffer[1] >> 24) & 0xFF ); 
     595             : 
     596           0 :   if (rcuVer < 2) {
     597           0 :     HLTWarning("%s Old data format, RCU version %d", str,rcuVer);
     598           0 :     return 0;
     599             :   }
     600             : 
     601             :   // is the block valid
     602             :   //AliHLTUInt32_t blockAttributes = buffer[3]; // block attributes (bits 24-31) and participating sub detectors 
     603             :   //cout<<blockAttributes<<" "<<(blockAttributes >> 24)<<endl;
     604             :   //if ( !( (blockAttributes >> 24) & 1) ) return 0; 
     605             :      
     606             : 
     607           0 :   const AliHLTUInt32_t* fData = buffer + headerSize32;
     608           0 :   unsigned long  dataSize32 = blockSize32 - headerSize32;       
     609             :   
     610             :   // Read the RCU trailer according to the RCU formware version specified in CDH
     611             :   // Cross-check with version found in the trailer
     612             :   // The two major bit should be 11 (identifies the end of the trailer)    
     613             :   
     614           0 :   AliHLTUInt32_t word = fData[dataSize32 - 1];
     615             :   
     616           0 :   if ((word >> 30) != 3) {
     617           0 :     HLTWarning("%s Last RCU trailer word not found!", str);
     618           0 :     return 0;
     619             :   }
     620             :   
     621           0 :   UChar_t ver = (word >> 16) & 0xFF;
     622             :   //AliHLTUInt32_t rcuId = (Int_t)((word >> 7) & 0x1FF);
     623           0 :   AliHLTUInt32_t rcuTrailerSize32 = (word & 0x7F); // size of RCU trailer data in words
     624             :   
     625           0 :   if (ver != rcuVer) {
     626           0 :     HLTWarning("%s Wrong RCU firmware version detected: %d != %d",
     627             :                str,ver,rcuVer);
     628           0 :     return 0;
     629             :   }  
     630             : 
     631           0 :   if (rcuTrailerSize32 < 2) {
     632           0 :     HLTWarning(Form("Invalid trailer size found (%d bytes) !",
     633             :                     rcuTrailerSize32*4));
     634           0 :     return 0;
     635             :   }
     636             :   
     637           0 :   if( rcuTrailerSize32 > dataSize32 ){
     638           0 :     HLTWarning(Form("%s Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%ld bytes)!",
     639             :                     str, rcuTrailerSize32*4,dataSize32*4));
     640           0 :     return 0;    
     641             :   }
     642             : 
     643             :   // check the trailer
     644             : 
     645           0 :   Int_t trailerIndex = dataSize32 - rcuTrailerSize32;
     646             : 
     647           0 :   for( unsigned int i=trailerIndex; i<dataSize32-1; i++){
     648           0 :     if ((fData[i] >> 30) != 2) {
     649           0 :       HLTWarning("%s Missing RCU trailer identifier pattern!",str);
     650             :       continue;
     651             :     }
     652             :   }
     653             : 
     654             :   // Read the payload size  
     655             :  
     656           0 :   Int_t  rcuPayloadSize32 = fData[trailerIndex] & 0x3FFFFFF;
     657             : 
     658           0 :   if ( rcuPayloadSize32 + rcuTrailerSize32  != dataSize32) {
     659           0 :     HLTWarning(Form("%s Inconsistent raw data size ! Raw data size - %ld bytes (from CDH), RCU trailer - %d bytes, raw data size (from RCU trailer) - %d bytes !",
     660             :                     str, dataSize32*4,
     661             :                     (rcuTrailerSize32)*4,
     662             :                     rcuPayloadSize32*4));
     663           0 :     return 0;
     664             :   }
     665             :     
     666             :   
     667             :   //AliHLTTPCMapping *mapping = new AliHLTTPCMapping(patch);
     668             :   const int kMaxNTimeBins = 2000;
     669             : 
     670           0 :   UShort_t  *channelData10 = new UShort_t[kMaxNTimeBins];    // cache for the decoded altro payload
     671             : 
     672             :   Int_t position = 0; // current position (32-bit words) in fData
     673             :  
     674           0 :   while(1){
     675             : 
     676             :     // Search for the next Altro channel
     677             : 
     678             :     word = 0;
     679           0 :     while( position < rcuPayloadSize32 ){
     680           0 :       word = fData[position++];
     681           0 :       if( (word >> 30) == 1) break;
     682             :     }
     683           0 :     if (position >= rcuPayloadSize32 ) break; // no next channel found
     684             :     
     685             :     // extract channel payload and hw address
     686             : 
     687           0 :     Int_t channelPayloadSize10 = (word >> 16) & 0x3FF; // payload size in 10-bit words 
     688           0 :     Int_t channelPayloadSize32 = (channelPayloadSize10+2)/3;
     689           0 :     Bool_t channelIOErrors = (word >> 29) & 0x1; // check for readout errors    
     690           0 :     Short_t  channelHWAddress = word & 0xFFF;
     691             : 
     692           0 :     if( position + channelPayloadSize32-1> rcuPayloadSize32 ){
     693           0 :       HLTWarning(Form("%s Inconsistent channel payload data size: expected <= %d bytes from RCU trailer, found %d bytes in the channel header!",
     694             :                       str,(rcuPayloadSize32 - position)*4, channelPayloadSize32*4 ));
     695           0 :       continue;
     696             :     }
     697             : 
     698             :     //bool channelBranchAB = ((channelHWAddress >> 11) & 0x1);
     699             :     // int channelFEC       = ((channelHWAddress >> 7) & 0xF); // front-end card index
     700             :     //int channelAltro = ((channelHWAddress >> 4) & 0x7); // altro chip index
     701             :     //int channelIndex = (channelHWAddress & 0xF); // channel index
     702             :     //int channelRow = mapping->GetRow(channelHWAddress);
     703             :     //int channelPad = mapping->GetPad(channelHWAddress);
     704             : 
     705             :     // Now unpack the Altro data: 10-bit words to 16 bit-words    
     706             :     
     707             :     Int_t channelData10Index = 0;// current position in the payload
     708             : 
     709           0 :     for (Int_t iword = 0; iword < channelPayloadSize32; iword++) {
     710           0 :       word = fData[position++];
     711           0 :       if ((word >> 30) != 0) {
     712           0 :         HLTWarning(Form("%s Unexpected end of payload in altro channel payload! Address=0x%x, word=0x%x",
     713             :                         str, channelHWAddress,word));
     714             :         channelIOErrors = 1;
     715             :         position--;
     716           0 :         break;
     717             :       }
     718           0 :       channelData10[channelData10Index++] = (word >> 20) & 0x3FF;
     719           0 :       channelData10[channelData10Index++] = (word >> 10) & 0x3FF;
     720           0 :       channelData10[channelData10Index++] = word & 0x3FF;
     721             :     }
     722             :   
     723           0 :     if ( channelIOErrors ) continue;    
     724             : 
     725             :     // read bunches
     726             : 
     727             :     Int_t prevTimeBin =  1024;
     728             :     channelData10Index = 0;
     729             : 
     730           0 :     while(1){
     731             :       
     732             :       // Read next Altro bunch 
     733             :   
     734           0 :       if ((channelData10Index+1 >= channelPayloadSize10) ) break;
     735             :     
     736           0 :       Int_t bunchLength = channelData10[channelData10Index++];
     737           0 :       Int_t bunchStartTimeBin = channelData10[channelData10Index++];
     738             : 
     739           0 :       if (bunchLength <= 2) {
     740             :         // Invalid bunch size
     741           0 :         HLTWarning(Form("%s Too short bunch length (%d) in Address=0x%x!",
     742             :                         str, bunchLength,channelHWAddress));    
     743           0 :         break;
     744             :       }
     745           0 :       if( channelData10Index + bunchLength - 2 > channelPayloadSize10 ){
     746             :         // Too long bunch detected
     747           0 :         HLTWarning(Form("%s Too long bunch detected in Address=0x%x! Expected <= %d 10-bit words, found %d !",
     748             :                         str,channelHWAddress,channelPayloadSize10-channelData10Index,bunchLength));
     749           0 :         break;
     750             :       }
     751             :             
     752           0 :       if( bunchStartTimeBin-bunchLength+1 < 0) {
     753           0 :         HLTWarning(Form("%s Invalid start time-bin in Address=0x%x ! (%d-%d+1) < 0",
     754             :                         str,channelHWAddress,bunchStartTimeBin,bunchLength));
     755           0 :         break;
     756             :       }
     757           0 :       if (bunchStartTimeBin >= prevTimeBin) {
     758           0 :         HLTWarning(Form("%s Invalid start time-bin in Address=0x%x! (%d>=%d)",
     759             :                         str,channelHWAddress,bunchStartTimeBin,prevTimeBin));
     760           0 :         break;
     761             :       }
     762             : 
     763             :       prevTimeBin = bunchStartTimeBin-bunchLength+1;
     764             :   
     765           0 :       bunchLength -= 2;
     766             :         
     767             :       //UShort_t* bunchData = &channelData10[channelData10Index];   // pointer to the current bunch samples
     768           0 :       channelData10Index += bunchLength;            
     769           0 :     }
     770           0 :   }
     771             :   
     772           0 :   delete[] channelData10;
     773             :   //delete mapping;
     774             : 
     775             :   return 1;
     776           0 : }
     777             : 

Generated by: LCOV version 1.11