LCOV - code coverage report
Current view: top level - RAW/RAWDatasim - AliAltroBuffer.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 104 124 83.9 %
Date: 2016-06-14 17:26:59 Functions: 15 18 83.3 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : /* $Id$ */
      17             : 
      18             : // Interface to the Altro format
      19             : // to read and write digits
      20             : // To be used in Alice Data Challenges 
      21             : // and in the compression of the RAW data
      22             : 
      23             : #include "AliAltroBuffer.h"
      24             : #include "AliAltroMapping.h"
      25             : #include "AliRawDataHeaderSim.h"
      26             : #include "AliLog.h"
      27             : #include "AliFstream.h"
      28             : //#include <stdlib.h>
      29             : 
      30             : 
      31         122 : ClassImp(AliAltroBuffer)
      32             : 
      33             : //_____________________________________________________________________________
      34         841 : AliAltroBuffer::AliAltroBuffer(const char* fileName, AliAltroMapping *mapping):
      35         841 :   fShift(0),
      36         841 :   fCurrentCell(0),
      37         841 :   fFreeCellBuffer(16),
      38         841 :   fVerbose(0),
      39         841 :   fFile(NULL),
      40         841 :   fDataHeaderPos(0),
      41         841 :   fMapping(mapping)
      42        2617 : {
      43             :   //the buffer is cleaned 
      44       10092 :   for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0;
      45             : 
      46             :   //open the output file
      47        2523 :   fFile = new AliFstream(fileName);
      48             : 
      49         888 : }
      50             : 
      51             : //_____________________________________________________________________________
      52             : AliAltroBuffer::~AliAltroBuffer()
      53        1870 : {
      54             : // destructor
      55             : 
      56             :   //Flush out the Buffer content at the end only if Buffer wasn't completely filled
      57         841 :   Flush();
      58         841 :   if (fVerbose) Info("~AliAltroBuffer", "File Created");
      59             : 
      60        1682 :   delete fFile;
      61             : 
      62         935 : }
      63             : 
      64             : //_____________________________________________________________________________
      65             : AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
      66           0 :   TObject(source),
      67           0 :   fShift(source.fShift),
      68           0 :   fCurrentCell(source.fCurrentCell),
      69           0 :   fFreeCellBuffer(source.fFreeCellBuffer),
      70           0 :   fVerbose(source.fVerbose),
      71           0 :   fFile(NULL),
      72           0 :   fDataHeaderPos(source.fDataHeaderPos),
      73           0 :   fMapping(source.fMapping)
      74           0 : {
      75             : // Copy Constructor
      76             : 
      77           0 :   Fatal("AliAltroBuffer", "copy constructor not implemented");
      78           0 : }
      79             : 
      80             : //_____________________________________________________________________________
      81             : AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
      82             : {
      83             : //Assigment operator
      84             : 
      85           0 :   Fatal("operator =", "assignment operator not implemented");
      86           0 :   return *this;
      87             : }
      88             : 
      89             : //_____________________________________________________________________________
      90             : void AliAltroBuffer::Flush()
      91             : {
      92             : // Flushes the Buffer content 
      93        3364 :   if (fFreeCellBuffer != 16) {
      94             :     Int_t temp = fFreeCellBuffer;
      95         600 :     for (Int_t i = 0; i < temp; i++){
      96         268 :       FillBuffer(0x2AA);
      97             :     }//end for
      98          32 :   }//end if
      99        1682 : }
     100             : 
     101             : //_____________________________________________________________________________
     102             : void AliAltroBuffer::FillBuffer(Int_t val)
     103             : {
     104             : //Fills the Buffer with 16 ten bits words and write into a file 
     105             : 
     106       21824 :   if ((val > 0x3FF) || (val < 0)) {
     107           0 :     Error("FillBuffer", "Value out of range (10 bits): %d", val);
     108             :     val = 0x3FF;
     109           0 :   }
     110       10912 :   fFreeCellBuffer--;
     111             : 
     112       10912 :   fBuffer[fCurrentCell] |= (val << fShift);
     113       10912 :   fShift += 10;
     114             : 
     115       10912 :   if (fShift > 32) {
     116        2728 :     fCurrentCell++;
     117        2728 :     fShift -= 32;
     118        2728 :     fBuffer[fCurrentCell] |= (val >> (10 - fShift));
     119        2728 :   }
     120             : 
     121       10912 :   if (fShift == 32) {
     122             :     //Buffer is written into a file
     123         682 :     fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5);
     124             :     //Buffer is empty
     125        8184 :     for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
     126         682 :     fShift = 0;
     127         682 :     fCurrentCell = 0;
     128         682 :     fFreeCellBuffer = 16;
     129         682 :   }
     130       10912 : }
     131             : 
     132             : //_____________________________________________________________________________
     133             : void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
     134             :                                   Int_t rowNumber, Int_t secNumber)
     135             : {
     136             : //Writes a trailer of 40 bits
     137             : 
     138       95126 :   if (!fMapping) {
     139           0 :     AliFatal("No ALTRO mapping information is loaded!");
     140           0 :   }
     141             : 
     142       47563 :   Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber);
     143       47563 :   if (hwAddress == -1)
     144           0 :     AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber));
     145       47563 :   WriteTrailer(wordsNumber,hwAddress);
     146       47563 : }
     147             : 
     148             : //_____________________________________________________________________________
     149             : void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress)
     150             : {
     151             : //Writes a trailer of 40 bits using
     152             : //a given hardware adress
     153         424 :   Int_t num = fFreeCellBuffer % 4;
     154        1058 :   for(Int_t i = 0; i < num; i++) {
     155         317 :     FillBuffer(0x2AA);
     156             :   }//end for
     157             :   Int_t temp;
     158         212 :   temp = hwAddress & 0x3FF;
     159         212 :   FillBuffer(temp);
     160             : 
     161         212 :   temp = (wordsNumber << 6) & 0x3FF;
     162         212 :   temp |= (0xA << 2);
     163         212 :   temp |= ((hwAddress >> 10) & 0x3);
     164         212 :   FillBuffer(temp);
     165             : 
     166             :   temp = 0xA << 6;
     167         212 :   temp |= ((wordsNumber & 0x3FF) >> 4);
     168         212 :   FillBuffer(temp);
     169             : 
     170             :   temp = 0x2AA;
     171         212 :   FillBuffer(temp);
     172         212 : }
     173             : 
     174             : //_____________________________________________________________________________
     175             : void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, 
     176             :                                   Int_t secNumber,
     177             :                                   Int_t nTimeBins, const Int_t* adcValues,
     178             :                                   Int_t threshold)
     179             : {
     180             :   //Write all ADC values and the trailer of a channel
     181         548 :   Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
     182             :   // write the trailer
     183         470 :   if (nWords) WriteTrailer(nWords, padNumber, rowNumber, secNumber);
     184         274 : }
     185             : 
     186             : //_____________________________________________________________________________
     187             : void AliAltroBuffer::WriteChannel(Short_t hwAddress,
     188             :                                   Int_t nTimeBins, const Int_t* adcValues,
     189             :                                   Int_t threshold)
     190             : {
     191             :   //Write all ADC values and the trailer of a channel
     192        3200 :   Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
     193             :   // write the trailer
     194        3200 :   if (nWords) WriteTrailer(nWords, hwAddress);
     195        1600 : }
     196             : 
     197             : //_____________________________________________________________________________
     198             : Int_t AliAltroBuffer::WriteBunch(Int_t nTimeBins, const Int_t* adcValues,
     199             :                                  Int_t threshold)
     200             : {
     201             :   //Write all ADC values
     202             :   //Return number of words written
     203             : 
     204             :   Int_t nWords = 0;
     205             :   Int_t timeBin = -1;
     206             :   Int_t bunchLength = 0;
     207             : 
     208             :   // loop over time bins
     209     1777718 :   for (Int_t iTime = 0; iTime < nTimeBins; iTime++) {
     210      886048 :     if (adcValues[iTime] >= threshold) { // ADC value above threshold
     211      858639 :       FillBuffer(adcValues[iTime]);
     212      858639 :       nWords++;
     213             :       timeBin = iTime;
     214      858639 :       bunchLength++;
     215             : 
     216      886048 :     } else if (timeBin >= 0) {  // end of bunch
     217         181 :       FillBuffer(timeBin);
     218         181 :       FillBuffer(bunchLength + 2);
     219         181 :       nWords += 2;
     220             :       timeBin = -1;
     221             :       bunchLength = 0;
     222         181 :     }
     223             :   }
     224             : 
     225        1874 :   if (timeBin >= 0) {  // end of bunch
     226        1615 :     FillBuffer(timeBin);
     227        1615 :     FillBuffer(bunchLength + 2);
     228        1615 :     nWords += 2;
     229        1615 :   }
     230             : 
     231        1874 :   return nWords;
     232             : }
     233             : 
     234             : //_____________________________________________________________________________
     235             : void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t /*compressed*/)
     236             : {
     237             : //Write a (dummy or real) DDL data header, 
     238             : //set the attributes according to the RCU version
     239             : 
     240        1682 :   AliRawDataHeaderSim header;
     241        1682 :   if (dummy) {
     242             :     //if size=0 it means that this data header is a dummy data header
     243         841 :     fDataHeaderPos = fFile->Tellp();
     244         841 :     fFile->WriteBuffer((char*)(&header), sizeof(header));
     245         841 :   } else {
     246         841 :     UChar_t rcuVer = WriteRCUTrailer(0);
     247         841 :     UInt_t currentFilePos = fFile->Tellp();
     248         841 :     fFile->Seekp(fDataHeaderPos);
     249         841 :     header.fSize = 0xFFFFFFFF; // RCU can't write raw-data size so we always get an 'invalid' size field
     250         841 :     header.fAttributesSubDetectors |= (rcuVer << 24);
     251         841 :     fFile->WriteBuffer((char*)(&header), sizeof(header));
     252         841 :     fFile->Seekp(currentFilePos);
     253             :   }
     254        1682 : }
     255             : 
     256             : //_____________________________________________________________________________
     257             : UChar_t AliAltroBuffer::WriteRCUTrailer(Int_t rcuId)
     258             : {
     259             :   // Writes the RCU trailer
     260             :   // rcuId the is serial number of the corresponding
     261             :   // RCU. The basic format of the trailer can be
     262             :   // found in the RCU manual.
     263             :   // This method should be called at the end of
     264             :   // raw data writing.
     265             : 
     266          94 :   UInt_t currentFilePos = fFile->Tellp();
     267          47 :   UInt_t size = currentFilePos-fDataHeaderPos;
     268          47 :   size -= sizeof(AliRawDataHeaderV3);
     269             :   
     270          47 :   if ((size % 5) != 0) {
     271           0 :     AliFatal(Form("The current raw data payload is not a mutiple of 5 (%d) ! Can not write the RCU trailer !",size));
     272           0 :     return 0;
     273             :   }
     274             : 
     275             :   // Now put the size in unit of number of 40bit words
     276          47 :   size /= 5;
     277          47 :   fFile->WriteBuffer((char *)(&size),sizeof(UInt_t));
     278             : 
     279             :   // Now several not yet full defined fields
     280             :   // In principle they are supposed to contain
     281             :   // information about the sampling frequency,
     282             :   // L1 phase, list of 'dead' FECs, etc.
     283             :   //  UInt_t buffer[n];
     284             :   //  fFile->WriteBuffer((char *)(buffer),sizeof(UInt_t)*n);
     285             :   
     286             :   //  Now the RCU identifier and size of the trailer
     287             :   //  FOr the moment the triler size is 2 32-bit words
     288          47 :   UInt_t buffer = (2 & 0x7F);
     289          47 :   buffer |= ((rcuId & 0x1FF) << 7);
     290          47 :   buffer |= 0xAAAAU << 16;
     291          47 :   fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t));
     292             : 
     293             :   return 0;
     294          94 : }

Generated by: LCOV version 1.11