ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Interface to the Altro format
// to read and write digits
// To be used in Alice Data Challenges 
// and in the compression of the RAW data

#include "AliAltroBuffer.h"
#include "AliAltroMapping.h"
#include "AliRawDataHeaderSim.h"
#include "AliLog.h"
#include "AliFstream.h"
//#include <stdlib.h>


ClassImp(AliAltroBuffer)

//_____________________________________________________________________________
AliAltroBuffer::AliAltroBuffer(const char* fileName, AliAltroMapping *mapping):
  fShift(0),
  fCurrentCell(0),
  fFreeCellBuffer(16),
  fVerbose(0),
  fFile(NULL),
  fDataHeaderPos(0),
  fMapping(mapping)
{
  //the buffer is cleaned 
  for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0;

  //open the output file
  fFile = new AliFstream(fileName);

}

//_____________________________________________________________________________
AliAltroBuffer::~AliAltroBuffer()
{
// destructor

  //Flush out the Buffer content at the end only if Buffer wasn't completely filled
  Flush();
  if (fVerbose) Info("~AliAltroBuffer", "File Created");

  delete fFile;

}

//_____________________________________________________________________________
AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
  TObject(source),
  fShift(source.fShift),
  fCurrentCell(source.fCurrentCell),
  fFreeCellBuffer(source.fFreeCellBuffer),
  fVerbose(source.fVerbose),
  fFile(NULL),
  fDataHeaderPos(source.fDataHeaderPos),
  fMapping(source.fMapping)
{
// Copy Constructor

  Fatal("AliAltroBuffer", "copy constructor not implemented");
}

//_____________________________________________________________________________
AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
{
//Assigment operator

  Fatal("operator =", "assignment operator not implemented");
  return *this;
}

//_____________________________________________________________________________
void AliAltroBuffer::Flush()
{
// Flushes the Buffer content 
  if (fFreeCellBuffer != 16) {
    Int_t temp = fFreeCellBuffer;
    for (Int_t i = 0; i < temp; i++){
      FillBuffer(0x2AA);
    }//end for
  }//end if
}

//_____________________________________________________________________________
void AliAltroBuffer::FillBuffer(Int_t val)
{
//Fills the Buffer with 16 ten bits words and write into a file 

  if ((val > 0x3FF) || (val < 0)) {
    Error("FillBuffer", "Value out of range (10 bits): %d", val);
    val = 0x3FF;
  }
  fFreeCellBuffer--;

  fBuffer[fCurrentCell] |= (val << fShift);
  fShift += 10;

  if (fShift > 32) {
    fCurrentCell++;
    fShift -= 32;
    fBuffer[fCurrentCell] |= (val >> (10 - fShift));
  }

  if (fShift == 32) {
    //Buffer is written into a file
    fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5);
    //Buffer is empty
    for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
    fShift = 0;
    fCurrentCell = 0;
    fFreeCellBuffer = 16;
  }
}

//_____________________________________________________________________________
void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
				  Int_t rowNumber, Int_t secNumber)
{
//Writes a trailer of 40 bits

  if (!fMapping) {
    AliFatal("No ALTRO mapping information is loaded!");
  }

  Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber);
  if (hwAddress == -1)
    AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber));
  WriteTrailer(wordsNumber,hwAddress);
}

//_____________________________________________________________________________
void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress)
{
//Writes a trailer of 40 bits using
//a given hardware adress
  Int_t num = fFreeCellBuffer % 4;
  for(Int_t i = 0; i < num; i++) {
    FillBuffer(0x2AA);
  }//end for
  Int_t temp;
  temp = hwAddress & 0x3FF;
  FillBuffer(temp);

  temp = (wordsNumber << 6) & 0x3FF;
  temp |= (0xA << 2);
  temp |= ((hwAddress >> 10) & 0x3);
  FillBuffer(temp);

  temp = 0xA << 6;
  temp |= ((wordsNumber & 0x3FF) >> 4);
  FillBuffer(temp);

  temp = 0x2AA;
  FillBuffer(temp);
}

//_____________________________________________________________________________
void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, 
				  Int_t secNumber,
				  Int_t nTimeBins, const Int_t* adcValues,
				  Int_t threshold)
{
  //Write all ADC values and the trailer of a channel
  Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
  // write the trailer
  if (nWords) WriteTrailer(nWords, padNumber, rowNumber, secNumber);
}

//_____________________________________________________________________________
void AliAltroBuffer::WriteChannel(Short_t hwAddress,
				  Int_t nTimeBins, const Int_t* adcValues,
				  Int_t threshold)
{
  //Write all ADC values and the trailer of a channel
  Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
  // write the trailer
  if (nWords) WriteTrailer(nWords, hwAddress);
}

//_____________________________________________________________________________
Int_t AliAltroBuffer::WriteBunch(Int_t nTimeBins, const Int_t* adcValues,
				 Int_t threshold)
{
  //Write all ADC values
  //Return number of words written

  Int_t nWords = 0;
  Int_t timeBin = -1;
  Int_t bunchLength = 0;

  // loop over time bins
  for (Int_t iTime = 0; iTime < nTimeBins; iTime++) {
    if (adcValues[iTime] >= threshold) { // ADC value above threshold
      FillBuffer(adcValues[iTime]);
      nWords++;
      timeBin = iTime;
      bunchLength++;

    } else if (timeBin >= 0) {  // end of bunch
      FillBuffer(timeBin);
      FillBuffer(bunchLength + 2);
      nWords += 2;
      timeBin = -1;
      bunchLength = 0;
    }
  }

  if (timeBin >= 0) {  // end of bunch
    FillBuffer(timeBin);
    FillBuffer(bunchLength + 2);
    nWords += 2;
  }

  return nWords;
}

//_____________________________________________________________________________
void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t /*compressed*/)
{
//Write a (dummy or real) DDL data header, 
//set the attributes according to the RCU version

  AliRawDataHeaderSim header;
  if (dummy) {
    //if size=0 it means that this data header is a dummy data header
    fDataHeaderPos = fFile->Tellp();
    fFile->WriteBuffer((char*)(&header), sizeof(header));
  } else {
    UChar_t rcuVer = WriteRCUTrailer(0);
    UInt_t currentFilePos = fFile->Tellp();
    fFile->Seekp(fDataHeaderPos);
    header.fSize = 0xFFFFFFFF; // RCU can't write raw-data size so we always get an 'invalid' size field
    header.fAttributesSubDetectors |= (rcuVer << 24);
    fFile->WriteBuffer((char*)(&header), sizeof(header));
    fFile->Seekp(currentFilePos);
  }
}

//_____________________________________________________________________________
UChar_t AliAltroBuffer::WriteRCUTrailer(Int_t rcuId)
{
  // Writes the RCU trailer
  // rcuId the is serial number of the corresponding
  // RCU. The basic format of the trailer can be
  // found in the RCU manual.
  // This method should be called at the end of
  // raw data writing.

  UInt_t currentFilePos = fFile->Tellp();
  UInt_t size = currentFilePos-fDataHeaderPos;
  size -= sizeof(AliRawDataHeaderV3);
  
  if ((size % 5) != 0) {
    AliFatal(Form("The current raw data payload is not a mutiple of 5 (%d) ! Can not write the RCU trailer !",size));
    return 0;
  }

  // Now put the size in unit of number of 40bit words
  size /= 5;
  fFile->WriteBuffer((char *)(&size),sizeof(UInt_t));

  // Now several not yet full defined fields
  // In principle they are supposed to contain
  // information about the sampling frequency,
  // L1 phase, list of 'dead' FECs, etc.
  //  UInt_t buffer[n];
  //  fFile->WriteBuffer((char *)(buffer),sizeof(UInt_t)*n);
  
  //  Now the RCU identifier and size of the trailer
  //  FOr the moment the triler size is 2 32-bit words
  UInt_t buffer = (2 & 0x7F);
  buffer |= ((rcuId & 0x1FF) << 7);
  buffer |= 0xAAAAU << 16;
  fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t));

  return 0;
}
 AliAltroBuffer.cxx:1
 AliAltroBuffer.cxx:2
 AliAltroBuffer.cxx:3
 AliAltroBuffer.cxx:4
 AliAltroBuffer.cxx:5
 AliAltroBuffer.cxx:6
 AliAltroBuffer.cxx:7
 AliAltroBuffer.cxx:8
 AliAltroBuffer.cxx:9
 AliAltroBuffer.cxx:10
 AliAltroBuffer.cxx:11
 AliAltroBuffer.cxx:12
 AliAltroBuffer.cxx:13
 AliAltroBuffer.cxx:14
 AliAltroBuffer.cxx:15
 AliAltroBuffer.cxx:16
 AliAltroBuffer.cxx:17
 AliAltroBuffer.cxx:18
 AliAltroBuffer.cxx:19
 AliAltroBuffer.cxx:20
 AliAltroBuffer.cxx:21
 AliAltroBuffer.cxx:22
 AliAltroBuffer.cxx:23
 AliAltroBuffer.cxx:24
 AliAltroBuffer.cxx:25
 AliAltroBuffer.cxx:26
 AliAltroBuffer.cxx:27
 AliAltroBuffer.cxx:28
 AliAltroBuffer.cxx:29
 AliAltroBuffer.cxx:30
 AliAltroBuffer.cxx:31
 AliAltroBuffer.cxx:32
 AliAltroBuffer.cxx:33
 AliAltroBuffer.cxx:34
 AliAltroBuffer.cxx:35
 AliAltroBuffer.cxx:36
 AliAltroBuffer.cxx:37
 AliAltroBuffer.cxx:38
 AliAltroBuffer.cxx:39
 AliAltroBuffer.cxx:40
 AliAltroBuffer.cxx:41
 AliAltroBuffer.cxx:42
 AliAltroBuffer.cxx:43
 AliAltroBuffer.cxx:44
 AliAltroBuffer.cxx:45
 AliAltroBuffer.cxx:46
 AliAltroBuffer.cxx:47
 AliAltroBuffer.cxx:48
 AliAltroBuffer.cxx:49
 AliAltroBuffer.cxx:50
 AliAltroBuffer.cxx:51
 AliAltroBuffer.cxx:52
 AliAltroBuffer.cxx:53
 AliAltroBuffer.cxx:54
 AliAltroBuffer.cxx:55
 AliAltroBuffer.cxx:56
 AliAltroBuffer.cxx:57
 AliAltroBuffer.cxx:58
 AliAltroBuffer.cxx:59
 AliAltroBuffer.cxx:60
 AliAltroBuffer.cxx:61
 AliAltroBuffer.cxx:62
 AliAltroBuffer.cxx:63
 AliAltroBuffer.cxx:64
 AliAltroBuffer.cxx:65
 AliAltroBuffer.cxx:66
 AliAltroBuffer.cxx:67
 AliAltroBuffer.cxx:68
 AliAltroBuffer.cxx:69
 AliAltroBuffer.cxx:70
 AliAltroBuffer.cxx:71
 AliAltroBuffer.cxx:72
 AliAltroBuffer.cxx:73
 AliAltroBuffer.cxx:74
 AliAltroBuffer.cxx:75
 AliAltroBuffer.cxx:76
 AliAltroBuffer.cxx:77
 AliAltroBuffer.cxx:78
 AliAltroBuffer.cxx:79
 AliAltroBuffer.cxx:80
 AliAltroBuffer.cxx:81
 AliAltroBuffer.cxx:82
 AliAltroBuffer.cxx:83
 AliAltroBuffer.cxx:84
 AliAltroBuffer.cxx:85
 AliAltroBuffer.cxx:86
 AliAltroBuffer.cxx:87
 AliAltroBuffer.cxx:88
 AliAltroBuffer.cxx:89
 AliAltroBuffer.cxx:90
 AliAltroBuffer.cxx:91
 AliAltroBuffer.cxx:92
 AliAltroBuffer.cxx:93
 AliAltroBuffer.cxx:94
 AliAltroBuffer.cxx:95
 AliAltroBuffer.cxx:96
 AliAltroBuffer.cxx:97
 AliAltroBuffer.cxx:98
 AliAltroBuffer.cxx:99
 AliAltroBuffer.cxx:100
 AliAltroBuffer.cxx:101
 AliAltroBuffer.cxx:102
 AliAltroBuffer.cxx:103
 AliAltroBuffer.cxx:104
 AliAltroBuffer.cxx:105
 AliAltroBuffer.cxx:106
 AliAltroBuffer.cxx:107
 AliAltroBuffer.cxx:108
 AliAltroBuffer.cxx:109
 AliAltroBuffer.cxx:110
 AliAltroBuffer.cxx:111
 AliAltroBuffer.cxx:112
 AliAltroBuffer.cxx:113
 AliAltroBuffer.cxx:114
 AliAltroBuffer.cxx:115
 AliAltroBuffer.cxx:116
 AliAltroBuffer.cxx:117
 AliAltroBuffer.cxx:118
 AliAltroBuffer.cxx:119
 AliAltroBuffer.cxx:120
 AliAltroBuffer.cxx:121
 AliAltroBuffer.cxx:122
 AliAltroBuffer.cxx:123
 AliAltroBuffer.cxx:124
 AliAltroBuffer.cxx:125
 AliAltroBuffer.cxx:126
 AliAltroBuffer.cxx:127
 AliAltroBuffer.cxx:128
 AliAltroBuffer.cxx:129
 AliAltroBuffer.cxx:130
 AliAltroBuffer.cxx:131
 AliAltroBuffer.cxx:132
 AliAltroBuffer.cxx:133
 AliAltroBuffer.cxx:134
 AliAltroBuffer.cxx:135
 AliAltroBuffer.cxx:136
 AliAltroBuffer.cxx:137
 AliAltroBuffer.cxx:138
 AliAltroBuffer.cxx:139
 AliAltroBuffer.cxx:140
 AliAltroBuffer.cxx:141
 AliAltroBuffer.cxx:142
 AliAltroBuffer.cxx:143
 AliAltroBuffer.cxx:144
 AliAltroBuffer.cxx:145
 AliAltroBuffer.cxx:146
 AliAltroBuffer.cxx:147
 AliAltroBuffer.cxx:148
 AliAltroBuffer.cxx:149
 AliAltroBuffer.cxx:150
 AliAltroBuffer.cxx:151
 AliAltroBuffer.cxx:152
 AliAltroBuffer.cxx:153
 AliAltroBuffer.cxx:154
 AliAltroBuffer.cxx:155
 AliAltroBuffer.cxx:156
 AliAltroBuffer.cxx:157
 AliAltroBuffer.cxx:158
 AliAltroBuffer.cxx:159
 AliAltroBuffer.cxx:160
 AliAltroBuffer.cxx:161
 AliAltroBuffer.cxx:162
 AliAltroBuffer.cxx:163
 AliAltroBuffer.cxx:164
 AliAltroBuffer.cxx:165
 AliAltroBuffer.cxx:166
 AliAltroBuffer.cxx:167
 AliAltroBuffer.cxx:168
 AliAltroBuffer.cxx:169
 AliAltroBuffer.cxx:170
 AliAltroBuffer.cxx:171
 AliAltroBuffer.cxx:172
 AliAltroBuffer.cxx:173
 AliAltroBuffer.cxx:174
 AliAltroBuffer.cxx:175
 AliAltroBuffer.cxx:176
 AliAltroBuffer.cxx:177
 AliAltroBuffer.cxx:178
 AliAltroBuffer.cxx:179
 AliAltroBuffer.cxx:180
 AliAltroBuffer.cxx:181
 AliAltroBuffer.cxx:182
 AliAltroBuffer.cxx:183
 AliAltroBuffer.cxx:184
 AliAltroBuffer.cxx:185
 AliAltroBuffer.cxx:186
 AliAltroBuffer.cxx:187
 AliAltroBuffer.cxx:188
 AliAltroBuffer.cxx:189
 AliAltroBuffer.cxx:190
 AliAltroBuffer.cxx:191
 AliAltroBuffer.cxx:192
 AliAltroBuffer.cxx:193
 AliAltroBuffer.cxx:194
 AliAltroBuffer.cxx:195
 AliAltroBuffer.cxx:196
 AliAltroBuffer.cxx:197
 AliAltroBuffer.cxx:198
 AliAltroBuffer.cxx:199
 AliAltroBuffer.cxx:200
 AliAltroBuffer.cxx:201
 AliAltroBuffer.cxx:202
 AliAltroBuffer.cxx:203
 AliAltroBuffer.cxx:204
 AliAltroBuffer.cxx:205
 AliAltroBuffer.cxx:206
 AliAltroBuffer.cxx:207
 AliAltroBuffer.cxx:208
 AliAltroBuffer.cxx:209
 AliAltroBuffer.cxx:210
 AliAltroBuffer.cxx:211
 AliAltroBuffer.cxx:212
 AliAltroBuffer.cxx:213
 AliAltroBuffer.cxx:214
 AliAltroBuffer.cxx:215
 AliAltroBuffer.cxx:216
 AliAltroBuffer.cxx:217
 AliAltroBuffer.cxx:218
 AliAltroBuffer.cxx:219
 AliAltroBuffer.cxx:220
 AliAltroBuffer.cxx:221
 AliAltroBuffer.cxx:222
 AliAltroBuffer.cxx:223
 AliAltroBuffer.cxx:224
 AliAltroBuffer.cxx:225
 AliAltroBuffer.cxx:226
 AliAltroBuffer.cxx:227
 AliAltroBuffer.cxx:228
 AliAltroBuffer.cxx:229
 AliAltroBuffer.cxx:230
 AliAltroBuffer.cxx:231
 AliAltroBuffer.cxx:232
 AliAltroBuffer.cxx:233
 AliAltroBuffer.cxx:234
 AliAltroBuffer.cxx:235
 AliAltroBuffer.cxx:236
 AliAltroBuffer.cxx:237
 AliAltroBuffer.cxx:238
 AliAltroBuffer.cxx:239
 AliAltroBuffer.cxx:240
 AliAltroBuffer.cxx:241
 AliAltroBuffer.cxx:242
 AliAltroBuffer.cxx:243
 AliAltroBuffer.cxx:244
 AliAltroBuffer.cxx:245
 AliAltroBuffer.cxx:246
 AliAltroBuffer.cxx:247
 AliAltroBuffer.cxx:248
 AliAltroBuffer.cxx:249
 AliAltroBuffer.cxx:250
 AliAltroBuffer.cxx:251
 AliAltroBuffer.cxx:252
 AliAltroBuffer.cxx:253
 AliAltroBuffer.cxx:254
 AliAltroBuffer.cxx:255
 AliAltroBuffer.cxx:256
 AliAltroBuffer.cxx:257
 AliAltroBuffer.cxx:258
 AliAltroBuffer.cxx:259
 AliAltroBuffer.cxx:260
 AliAltroBuffer.cxx:261
 AliAltroBuffer.cxx:262
 AliAltroBuffer.cxx:263
 AliAltroBuffer.cxx:264
 AliAltroBuffer.cxx:265
 AliAltroBuffer.cxx:266
 AliAltroBuffer.cxx:267
 AliAltroBuffer.cxx:268
 AliAltroBuffer.cxx:269
 AliAltroBuffer.cxx:270
 AliAltroBuffer.cxx:271
 AliAltroBuffer.cxx:272
 AliAltroBuffer.cxx:273
 AliAltroBuffer.cxx:274
 AliAltroBuffer.cxx:275
 AliAltroBuffer.cxx:276
 AliAltroBuffer.cxx:277
 AliAltroBuffer.cxx:278
 AliAltroBuffer.cxx:279
 AliAltroBuffer.cxx:280
 AliAltroBuffer.cxx:281
 AliAltroBuffer.cxx:282
 AliAltroBuffer.cxx:283
 AliAltroBuffer.cxx:284
 AliAltroBuffer.cxx:285
 AliAltroBuffer.cxx:286
 AliAltroBuffer.cxx:287
 AliAltroBuffer.cxx:288
 AliAltroBuffer.cxx:289
 AliAltroBuffer.cxx:290
 AliAltroBuffer.cxx:291
 AliAltroBuffer.cxx:292
 AliAltroBuffer.cxx:293
 AliAltroBuffer.cxx:294