#include "AliFMDDebug.h"
#include "AliFMDParameters.h"
#include "AliFMDDigit.h"
#include "AliFMDSDigit.h"
#include "AliRawReader.h"
#include "AliFMDRawReader.h"
#include "AliFMDDebug.h"
#include "AliFMDCalibSampleRate.h"
#include "AliFMDCalibStripRange.h"
#include "AliFMDAltroMapping.h"
#include "AliFMDUShortMap.h"
#include "AliAltroRawStreamV3.h"
#include <TArrayS.h> // ROOT_TArrayS
#include <TTree.h> // ROOT_TTree
#include <TClonesArray.h> // ROOT_TClonesArray
#include <TString.h>
#include <iostream>
#include <climits>
ClassImp(AliFMDRawReader)
#if 0
;
#endif
AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree)
: TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"),
fTree(tree),
fReader(reader),
fData(0),
fNbytes(0),
fMinStrip(0),
fMaxStrip(127),
fPreSamp(14+5),
fSeen(0),
fVerbose(false),
fErrors("TObject"),
fNErrChanLen(0),
fNErrAddress(0)
{
for (Int_t i = 0; i < 3; i++) {
fSampleRate[i] = 0;
fZeroSuppress[i] = kFALSE;
fNoiseFactor[i] = 1;
fL1Phase[i] = 0;
fNErrors[i] = 0;
}
}
void
AliFMDRawReader::Exec(Option_t*)
{
TClonesArray* array = new TClonesArray("AliFMDDigit");
if (!fTree) {
AliError("No tree");
return;
}
fTree->Branch("FMD", &array);
ReadAdcs(array);
Int_t nWrite = fTree->Fill();
AliDebugF(1,"Got a grand total of %d digits, wrote %d bytes to tree",
array->GetEntriesFast(), nWrite);
delete array;
}
void
AliFMDRawReader::AddError(Int_t ddl, Int_t hwaddr)
{
Int_t nErr = fErrors.GetEntries();
TObject* o = new (fErrors[nErr]) TObject;
o->SetUniqueID((ddl & 0xFF) << 12 | (hwaddr & 0xFFF));
}
void
AliFMDRawReader::ReadbackError(const AliAltroRawStreamV3& input,
const char* format, ...)
{
static char buf[512];
va_list ap;
va_start(ap, format);
vsnprintf(buf, 511, format, ap);
buf[511] = '\0';
va_end(ap);
if (AliDebugLevel() > 10) {
AliLog::Flush();
AliWarning(buf);
input.HexDumpChannel();
}
Int_t ddl = input.GetDDLNumber();
Int_t hwaddr = input.GetHWAddress();
fReader->AddMinorErrorLog(AliAltroRawStreamV3::kAltroPayloadErr,buf);
AddError(ddl, hwaddr);
fNErrors[ddl]++;
}
Int_t
AliFMDRawReader::NewDDL(AliAltroRawStreamV3& input, UShort_t& det)
{
UInt_t ddl = input.GetDDLNumber();
AliDebugF(2,"DDL number %d", ddl);
UInt_t cfg1 = input.GetAltroCFG1();
if (((cfg1 >> 10) & 0x8) == 0x8) {
UInt_t cfg2 = input.GetAltroCFG2();
AliDebugF(3,"We have data from older MiniConf 0x%x cfg2=0x%08x",
((cfg1 >> 10) & 0x8), cfg2);
fZeroSuppress[ddl] = (cfg1 >> 0) & 0x1;
fNoiseFactor[ddl] = (cfg1 >> 6) & 0xF;
fSampleRate[ddl] = (cfg2 >> 20) & 0xF;
}
else {
AliDebugF(3,"We have data from newer MiniConf 0x%x",
((cfg1 >> 10) & 0x8));
fZeroSuppress[ddl] = input.GetZeroSupp();
fNoiseFactor[ddl] = input.GetNNonZSPostsamples();
fSampleRate[ddl] = input.GetNPretriggerSamples();
}
AliDebugF(10,"Phase of DDL=%d is %g (%d)", ddl, input.GetL1Phase(),
input.GetAltroCFG2() & 0x1F);
fL1Phase[ddl] = input.GetAltroCFG2() & 0x1F;
AliDebugF(3,"RCU @ DDL %d zero suppression: %s",
ddl, (fZeroSuppress[ddl] ? "yes" : "no"));
AliDebugF(3,"RCU @ DDL %d noise factor: %d", ddl,fNoiseFactor[ddl]);
AliDebugF(3,"RCU @ DDL %d sample rate: %d", ddl,fSampleRate[ddl]);
Int_t nChAddrMismatch = input.GetNChAddrMismatch();
Int_t nChLenMismatch = input.GetNChLengthMismatch();
if (nChAddrMismatch != 0) {
ReadbackError(input,
"Got %d channels with address mis-matches for 0x%03x",
nChAddrMismatch, ddl);
fNErrAddress += nChAddrMismatch;
}
if (nChLenMismatch != 0) {
ReadbackError(input,
"Got %d channels with length mis-matches for 0x%03x",
nChLenMismatch, ddl);
fNErrChanLen += nChLenMismatch;
}
AliFMDParameters* pars = AliFMDParameters::Instance();
AliFMDAltroMapping* map = pars->GetAltroMap();
if (map->DDL2Detector(ddl) < 0) return -1;
det = map->DDL2Detector(ddl);
if (AliLog::GetDebugLevel("FMD", 0) > 5)
input.PrintRCUTrailer();
return ddl;
}
Int_t
AliFMDRawReader::NewChannel(const AliAltroRawStreamV3& input, UShort_t det,
Char_t& ring, UShort_t& sec, Short_t& strbase)
{
UShort_t board, chip, channel;
Int_t ddl = input.GetDDLNumber();
Int_t hwaddr = input.GetHWAddress();
if (input.IsChannelBad()) {
ReadbackError(input, "Ignoring channel %03d/0x%03x with errors",
ddl, hwaddr);
return 0xFFFF;
}
AliFMDParameters* pars = AliFMDParameters::Instance();
AliFMDAltroMapping* map = pars->GetAltroMap();
map->ChannelAddress(hwaddr, board, chip, channel);
if (!map->Channel2StripBase(board, chip, channel, ring, sec, strbase)) {
AliErrorF("Failed to get detector id from DDL %d, "
"hardware address 0x%03x", ddl, hwaddr);
return -1;
}
AliDebugF(7,"Board: 0x%02x, Altro: 0x%x, Channel: 0x%x",
board, chip, channel);
fMinStrip = pars->GetMinStrip(det, ring, sec, strbase);
fMaxStrip = pars->GetMaxStrip(det, ring, sec, strbase);
fPreSamp = pars->GetPreSamples(det, ring, sec, strbase);
if (fSampleRate[ddl] == 0) {
AliDebugF(7,"Get sample rate for RCU @ DDL %d from OCDB", ddl);
fSampleRate[ddl] = pars->GetSampleRate(det, ring, sec, strbase);
}
AliDebugF(7,"RCU @ DDL %d sample rate: %d", ddl,fSampleRate[ddl]);
return hwaddr;
}
Bool_t
AliFMDRawReader::NewBunch(const AliAltroRawStreamV3& input,
UShort_t& start, UShort_t& length)
{
Int_t ddl = input.GetDDLNumber();
Int_t hwaddr = input.GetHWAddress();
UShort_t nSamples = input.GetNSamplesPerCh() + fPreSamp;
UShort_t tstart = input.GetStartTimeBin();
length = input.GetBunchLength();
if (tstart >= nSamples) {
ReadbackError(input,
"Bunch in %03d/0x%03x has an start time greater "
"than number of samples: 0x%x >= 0x%x",
ddl, hwaddr, tstart, nSamples);
return false;
}
if ((int(tstart) - length + 1) < 0) {
ReadbackError(input,
"Bunch in %03d/0x%03x has an invalid length and "
"start time: 0x%x,0x%x (%d-%d+1=%d<0)",
ddl, hwaddr, length, tstart, tstart, length,
int(tstart)-length+1);
return false;
}
if (tstart >= start) {
ReadbackError(input,
"Bunch in %03d/0x%03x has early start time: "
"0x%x >= 0x%x", ddl, hwaddr, tstart, start);
return false;
}
start = tstart;
return true;
}
Int_t
AliFMDRawReader::NewSample(const AliAltroRawStreamV3& input,
Int_t i, UShort_t t, UShort_t sec,
UShort_t strbase, Short_t& str, UShort_t& samp)
{
if (t < fPreSamp) return -1;
Int_t ddl = input.GetDDLNumber();
Int_t hwa = input.GetHWAddress();
const UShort_t* data = input.GetSignals();
Short_t adc = data[i];
AliDebugF(10,"0x%04x/0x%03x/%04d %4d", ddl, hwa, t, adc);
AliFMDParameters* pars = AliFMDParameters::Instance();
AliFMDAltroMapping* map = pars->GetAltroMap();
samp = 0;
Short_t stroff = 0;
map->Timebin2Strip(sec, t, fPreSamp, fSampleRate[ddl], stroff, samp);
str = strbase + stroff;
AliDebugF(20,"0x%04x/0x%03x/%04d=%4d maps to strip %3d sample %d "
"(pre: %d, min: %d, max: %d, rate: %d)",
ddl, hwa, t, adc, str, samp, fPreSamp,
fMinStrip, fMaxStrip, fSampleRate[ddl]);
if (str < 0) {
AliDebugF(10,"Got presamples at timebin %d", i);
return -1;
}
Short_t lstrip = (t - fPreSamp) / fSampleRate[ddl] + fMinStrip;
AliDebugF(15,"Checking if strip %d (%d) in range [%d,%d]",
lstrip, str, fMinStrip, fMaxStrip);
if (lstrip < fMinStrip || lstrip > fMaxStrip) {
AliDebugF(10,"Strip %03d-%d (%d,%d) from t=%d out of range (%3d->%3d)",
str, samp, lstrip, stroff, t, fMinStrip, fMaxStrip);
adc = -1;
}
if (adc > 1023)
AliWarningF("ADC value out of range: %4d", adc);
return adc;
}
Int_t
AliFMDRawReader::NextSample(UShort_t& det, Char_t& rng, UShort_t& sec,
UShort_t& str, UShort_t& sam, UShort_t& rat,
Short_t& adc, Bool_t& zs, UShort_t& fac)
{
static AliAltroRawStreamV3 stream(fReader);
static Int_t ddl = -1;
static UShort_t tdet = 0;
static Char_t trng = '\0';
static UShort_t tsec = 0;
static Short_t tstr = 0;
static Short_t bstr = -1;
static UShort_t tsam = 0;
static Int_t hwaddr = -1;
static UShort_t start = 0;
static UShort_t length = 0;
static Short_t t = -1;
static Int_t i = 0;
if (stream.GetDDLNumber() < 0) {
fReader->Reset();
fReader->Select("FMD");
stream.Reset();
stream.SelectRawData("FMD");
stream.SetCheckAltroPayload(false);
for (Int_t j = 0; j < kNDDL; j++) fNErrors[j] = 0;
ddl = -1;
tdet = 0;
trng = '\0';
tsec = 0;
tstr = 0;
tsam = -1;
hwaddr = -1;
}
UShort_t ret = 0;
do {
AliDebugF(15, "t=%4d, start=%4d, length=%4d", t, start, length);
if (t < start - length + 1) {
AliDebugF(10,"Time t=%d < start-length+1=%d-%d+1 (%3d/0x%03x)",
t, start, length, ddl, hwaddr);
if (hwaddr > 0xFFF ||
hwaddr < 0 ||
!stream.NextBunch()) {
if (AliDebugLevel() >= 10 && hwaddr > 0xFFF) {
AliDebug(10,"Last channel read was marked bad");
}
if (AliDebugLevel() >= 10 && hwaddr < 0) {
AliDebug(10,"No more channels");
}
AliDebug(10,"No next bunch, or first entry");
if (ddl < 0 || !stream.NextChannel()) {
if (AliDebugLevel() >= 10 && ddl < 0) {
AliDebug(10,"No DDL");
}
AliDebug(10,"No next channel, or first entry");
if (!stream.NextDDL()) {
AliDebug(10,"No more DDLs");
stream.Reset();
return 0;
}
ddl = NewDDL(stream, tdet);
AliDebugF(5,"New DDL: %d (%d)", ddl, tdet);
ret |= 0x1;
continue;
}
hwaddr = NewChannel(stream, tdet, trng, tsec, bstr);
if (hwaddr > 0xFFF) fNErrors[ddl] += 1;
AliDebugF(5,"New Channel: %3d/0x%03x", ddl, hwaddr);
start = 1024;
ret |= 0x2;
continue;
}
if (!NewBunch(stream, start, length)) {
hwaddr = 0xFFFF;
return -1;
}
AliDebugF(5, "New bunch in %3d/0x%03x: start=0x%03x, length=%4d",
ddl, hwaddr, start, length);
ret |= 0x4;
t = start;
i = 0;
AliDebugF(10,"Got new bunch FMD%d%c[%2d], bunch @ %d, length=%d",
tdet, trng, tsec, start, length);
}
Int_t tadc = NewSample(stream, i, t, tsec, bstr, tstr, tsam);
AliDebugF(10,"New sample FMD%d%c[%2d,%3d]-%d = 0x%03x",
tdet, trng, tsec, tstr, tsam, tadc);
ret |= 0x8;
if (tadc >= 0) {
det = tdet;
rng = trng;
sec = tsec;
str = tstr;
sam = tsam;
adc = tadc;
rat = fSampleRate[ddl];
zs = fZeroSuppress[ddl];
fac = fNoiseFactor[ddl];
t--;
i++;
AliDebugF(10,"Returning FMD%d%c[%2d,%3d]-%d = 0x%03x (%d,%d,%d)",
det, rng, sec, str, sam, adc, rat, zs, fac);
break;
}
t--;
i++;
} while (true);
AliDebugF(5,"Returning 0x%02x", ret);
return ret;
}
Int_t
AliFMDRawReader::NextSignal(UShort_t& det, Char_t& rng,
UShort_t& sec, UShort_t& str,
Short_t& adc, Bool_t& zs,
UShort_t& fac)
{
Int_t ret = 0;
do {
UShort_t samp, rate;
if ((ret = NextSample(det, rng, sec, str, samp, rate, adc, zs, fac)) <= 0)
return ret;
Bool_t take = SelectSample(samp, rate);
if (!take) continue;
break;
} while (true);
return ret;
}
Bool_t
AliFMDRawReader::SelectSample(UShort_t samp, UShort_t rate)
{
Bool_t take = kFALSE;
switch (rate) {
case 1: take = kTRUE; break;
case 2: if (samp == 1) take = kTRUE; break;
case 3: if (samp == 1) take = kTRUE; break;
case 4: if (samp == 2) take = kTRUE; break;
default: if (samp == rate-2) take = kTRUE; break;
}
return take;
}
Bool_t
AliFMDRawReader::ReadAdcs(TClonesArray* array)
{
AliDebug(3,"Reading ADC values into a TClonesArray");
if (!array) {
AliError("No TClonesArray passed");
return kFALSE;
}
const UShort_t kUShortMax = (1 << 16) - 1;
fSeen.Reset(kUShortMax);
fErrors.Clear();
fNErrChanLen = 0;
fNErrAddress = 0;
for (Int_t ddl = 0; ddl < kNDDL; ddl++) fNErrors[ddl] = 0;
AliAltroRawStreamV3 input(fReader);
input.Reset();
input.SetCheckAltroPayload(false);
input.SelectRawData("FMD");
while (input.NextDDL()) {
UShort_t det = 0;
Int_t ddl = NewDDL(input, det);
if (ddl < 0) break;
fNErrors[ddl] = 0;
while (input.NextChannel()) {
Char_t ring;
UShort_t sec;
Short_t strbase;
Int_t hwaddr = NewChannel(input, det, ring, sec, strbase);
if (hwaddr < 0) break;
if (hwaddr > 0xFFF) continue;
UShort_t start = 0x3FF;
Bool_t errors = false;
Int_t first = -1;
Int_t last = -1;
while (input.NextBunch()) {
const UShort_t* data = input.GetSignals();
UShort_t length;
if (!NewBunch(input, start, length)) {
errors = true;
break;
}
for (Int_t i = 0; i < length; i++) {
Short_t str;
UShort_t samp;
Int_t t = start - i;
Int_t adc = NewSample(input, i, t, sec, strbase, str, samp);
if (adc <= 0) continue;
UShort_t counts = adc;
AliDebugF(10,"FMD%d%c[%02d,%03d]-%d: %4d",
det, ring, sec, str, samp, counts);
Int_t idx = fSeen(det, ring, sec, str);
AliFMDDigit* digit = 0;
if (idx == kUShortMax) {
fSeen(det, ring, sec, str) = idx = array->GetEntriesFast();
AliDebugF(7, "making digit @ %5d for FMD%d%c[%2d,%3d]-%d "
"from %3d/0x%03x/%4d (def: %d)",
idx, det, ring, sec, str, samp, ddl, hwaddr, t,
fSampleRate[ddl]);
digit = new ((*array)[idx]) AliFMDDigit(det, ring, sec, str);
digit->SetDefaultCounts(fSampleRate[ddl]);
}
else {
digit = static_cast<AliFMDDigit*>(array->At(idx));
}
if (first < 0) first = idx;
last = idx;
AliDebugF(5,"Setting FMD%d%c[%2d,%3d]-%d from timebin "
"%4d=%4d (%4d)", det, ring, sec, str, samp, t,
counts, data[i]);
digit->SetCount(samp, counts);
if (AliLog::GetDebugLevel("FMD","") >= 5) digit->Print();
}
}
if (errors) {
AliDebugF(2,"Channel %3d/0x%03x contain errors, "
"resetting index %d to %d", ddl, hwaddr, first, last);
if (first >= 0) {
for (Int_t i = first; i <= last; i++) {
AliFMDDigit* digit = static_cast<AliFMDDigit*>(array->At(i));
for (Int_t j = 0; j < fSampleRate[ddl]; j++) {
AliDebugF(10,"Resetting strip %s=%d",
digit->GetName(),digit->Counts());
digit->SetCount(j, kBadSignal);
}
}
}
}
}
}
if (fNErrors[0] > 0 || fNErrors[1] > 0 || fNErrors[2] > 0 ||
fNErrChanLen > 0 || fNErrAddress > 0) {
AliLog::SetPrintRepetitions(false);
AliWarningF("R/O errors: FMD1=%d, FMD2=%d, FMD3=%d, "
"Channel Length=%d, address=%d",
fNErrors[0], fNErrors[1], fNErrors[2],
fNErrChanLen, fNErrAddress);
AliLog::SetPrintRepetitions(true);
}
if (fVerbose && fErrors.GetEntries() > 0) {
TString msg;
Int_t nErr = fErrors.GetEntries();
for (Int_t i = 0; i < nErr; i++) {
UInt_t where = fErrors.At(i)->GetUniqueID();
if (i % 6 == 0) msg.Append("\n");
msg.Append(Form(" %3d/0x%03x", (where >> 12) & 0xFF, (where & 0xFFF)));
}
AliLog::SetPrintRepetitions(false);
AliWarningF("Got %d errors in channels %s", nErr, msg.Data());
AliLog::SetPrintRepetitions(true);
}
return kTRUE;
}
Bool_t
AliFMDRawReader::ReadAdcs(AliFMDUShortMap& map)
{
AliDebug(3,"Reading ADC values into a map");
for (Int_t ddl = 0; ddl < kNDDL; ddl++) fNErrors[ddl] = 0;
AliAltroRawStreamV3 input(fReader);
input.Reset();
input.SetCheckAltroPayload(false);
input.SelectRawData("FMD");
while (input.NextDDL()) {
UShort_t det = 0;
Int_t ddl = NewDDL(input, det);
if (ddl < 0) break;
fNErrors[ddl] = 0;
while (input.NextChannel()) {
Char_t ring;
UShort_t sec;
Short_t strbase;
Int_t hwaddr = NewChannel(input, det, ring, sec, strbase);
if (hwaddr < 0) break;
if (hwaddr > 0xFFF) continue;
UShort_t start = 0x3FF;
Bool_t errors = false;
Int_t first = -1;
Int_t last = -1;
while (input.NextBunch()) {
UShort_t length;
if (!NewBunch(input, start, length)) {
errors = true;
break;
}
for (Int_t i = 0; i < length; i++) {
Short_t str;
UShort_t samp;
Int_t t = start - i;
Int_t adc = NewSample(input, i, t, sec, strbase, str, samp);
if (adc < 0) continue;
UShort_t counts = adc;
AliDebugF(10, "FMD%d%c[%02d,%03d]-%d: %4d",
det, ring, sec, str, samp, counts);
if (SelectSample(samp, fSampleRate[ddl]))
map(det,ring,sec,str) = counts;
if (first < 0) first = str;
last = str;
}
}
if (errors) {
AliDebugF(2, "Channel %3d/0x%03x contain errors, "
"resetting strips %d to %d", ddl, hwaddr, first, last);
if (first >= 0) {
Int_t ds = first <= last ? 1 : -1;
for (Int_t i = first; i != last+ds; i += ds) {
AliDebugF(10, "Resetting strip FMD%d%c[%02d,%03d]=%d",
det,ring,sec,i,map(det,ring,sec,i));
map(det,ring,sec,i) = kBadSignal;
}
}
}
}
}
return kTRUE;
}
Bool_t AliFMDRawReader::ReadSODevent(AliFMDCalibSampleRate* sampleRate,
AliFMDCalibStripRange* stripRange,
TArrayS &pulseSize,
TArrayS &pulseLength,
Bool_t* detectors)
{
AliDebug(0,"Start of SOD/EOD");
UInt_t shift_clk[18];
UInt_t sample_clk[18];
UInt_t strip_low[18];
UInt_t strip_high[18];
UInt_t pulse_size[18];
UInt_t pulse_length[18];
for (size_t i = 0; i < 18; i++) {
shift_clk[i] = 0;
sample_clk[i] = 0;
strip_low[i] = 0;
strip_high[i] = 0;
pulse_size[i] = 0;
pulse_length[i] = 0;
}
AliFMDParameters* param = AliFMDParameters::Instance();
AliFMDAltroMapping* map = param->GetAltroMap();
AliAltroRawStreamV3 streamer(fReader);
streamer.Reset();
streamer.SelectRawData("FMD");
while (streamer.NextDDL()) {
Int_t ddl = streamer.GetDDLNumber();
Int_t detID = fReader->GetDetectorID();
if (detectors) detectors[map->DDL2Detector(ddl)-1] = kTRUE;
AliDebugF(0," From reader: DDL number is %d , det ID is %d",ddl,detID);
ULong_t nPayloadWords = streamer.GetRCUPayloadSizeInSOD();
UChar_t* payloadData = streamer.GetRCUPayloadInSOD();
UInt_t* payloadWords = reinterpret_cast<UInt_t*>(payloadData);
for (ULong_t i = 1; i <= nPayloadWords ; i++, payloadWords++) {
UInt_t payloadWord = *payloadWords;
UInt_t address = (0xffffff & payloadWord);
UInt_t type = ((address >> 21) & 0xf);
UInt_t error = ((address >> 20) & 0x1);
UInt_t bcast = ((address >> 18) & 0x1);
UInt_t bc_not_altro = ((address >> 17) & 0x1);
UInt_t board = ((address >> 12) & 0x1f);
UInt_t instruction = 0;
UInt_t chip = 0;
UInt_t channel = 0;
if(bc_not_altro)
instruction = address & 0xfff;
else {
chip = ((address >> 9) & 0x7);
channel = ((address >> 5) & 0x5);
instruction = (address & 0x1f);
}
Bool_t readDataWord = kFALSE;
switch(type) {
case 0x0:
readDataWord = kTRUE;
case 0x1:
case 0x2:
i++;
payloadWords++;
break;
case 0x4:
case 0x5:
break;
case 0x6:
case 0x7:
i = nPayloadWords + 1;
break;
default:
break;
}
if(!readDataWord) continue;
UInt_t dataWord = *payloadWords;
UInt_t data = (0xFFFFF & dataWord) ;
if(error) {
AliWarningF("error bit detected at Word 0x%06x; "
"error % d, type %d, bc_not_altro %d, "
"bcast %d, board 0x%02x, chip 0x%x, "
"channel 0x%02x, instruction 0x%03x",
address, error, type, bc_not_altro,
bcast,board,chip,channel,instruction);
continue;
}
switch(instruction) {
case 0x01: break;
case 0x02: break;
case 0x03: break;
case 0x04: break;
case 0x05: break;
case 0x06: break;
case 0x07: break;
case 0x08: break;
case 0x09: break;
case 0x0A: break;
case 0x2D: break;
case 0x2E: break;
case 0x2F: break;
case 0x30: break;
case 0x31: break;
case 0x32: break;
case 0x33: break;
case 0x34: break;
case 0x35: break;
case 0x36: break;
case 0x37: break;
case 0x38: break;
case 0x39: break;
case 0x3A: break;
case 0x3B: break;
case 0x3C: break;
case 0x3D: break;
case 0x3E: break;
case 0x3F: break;
case 0x40: break;
case 0x41: break;
case 0x42: break;
case 0x43: break;
case 0x44: break;
case 0x45: break;
case 0x46: break;
case 0x47: break;
case 0x48: break;
case 0x49: break;
case 0x4A: break;
case 0x0B: break;
case 0x0C: break;
case 0x0D: break;
case 0x0E: break;
case 0x0F: break;
case 0x10: break;
case 0x11: break;
case 0x12: break;
case 0x13: break;
case 0x14: break;
case 0x15: break;
case 0x16: break;
case 0x17: break;
case 0x18: break;
case 0x19: break;
case 0x1A: break;
case 0x1B: break;
case 0x1C: break;
case 0x1D: break;
case 0x1E: break;
case 0x1F: break;
case 0x20: break;
case 0x21: break;
case 0x22: break;
case 0x23: break;
case 0x24: break;
case 0x25:
shift_clk[board] = ((data >> 8 ) & 0xFF);
AliDebugF(30, "Read shift_clk=%d for board 0x%02x",
shift_clk[board], board);
break;
case 0x26:
strip_low[board] = ((data >> 0 ) & 0xFF);
strip_high[board] = ((data >> 8 ) & 0xFF);
break;
case 0x27:
pulse_size[board] = ((data >> 8 ) & 0xFF);
break;
case 0x28: break;
case 0x29: break;
case 0x2A: break;
case 0x2B:
sample_clk[board] = ((data >> 8 ) & 0xFF);
AliDebugF(30,"Read sample_clk=%d for board 0x%02x",
sample_clk[board], board);
break;
case 0x2C: break;
case 0x4B:
pulse_length[board] = ((data >> 0 ) & 0xFF);
break;
default: break;
}
AliDebugF(50,"instruction 0x%x, dataword 0x%x",
instruction,dataWord);
}
UShort_t det = 0;
UShort_t sector = 0;
Short_t strip = -1;
Char_t ring = '\0';
const UInt_t boards[4] = {0,1,16,17};
for(Int_t i=0;i<4;i++) {
if(ddl==0 && (i==1 || i==3)) continue;
UInt_t chip =0, channel=0;
det = map->DDL2Detector(ddl);
map->Channel2StripBase(boards[i], chip, channel, ring, sector, strip);
UInt_t samplerate = 0;
#if USE_VOTE
if(sample_clk[boards[i]] == 0) {
if(ddl == 0) {
Int_t sample1 = sample_clk[boards[0]];
Int_t sample2 = sample_clk[boards[2]];
if(sample1) sample_clk[boards[i]] = sample1;
else sample_clk[boards[i]] = sample2;
}
else {
Int_t sample1 = sample_clk[boards[0]];
Int_t sample2 = sample_clk[boards[1]];
Int_t sample3 = sample_clk[boards[2]];
Int_t sample4 = sample_clk[boards[3]];
Int_t agreement = 0;
if(sample1 == sample2) agreement++;
if(sample1 == sample3) agreement++;
if(sample1 == sample4) agreement++;
if(sample2 == sample3) agreement++;
if(sample2 == sample4) agreement++;
if(sample3 == sample4) agreement++;
Int_t idx = 0;
if(i<3) idx = i+1;
else idx = i-1;
if(agreement == 3) {
sample_clk[boards[i]] = sample_clk[boards[idx]];
shift_clk[boards[i]] = shift_clk[boards[idx]];
strip_low[boards[i]] = strip_low[boards[idx]];
strip_high[boards[i]] = strip_high[boards[idx]];
pulse_length[boards[i]] = pulse_length[boards[idx]];
pulse_size[boards[i]] = pulse_size[boards[idx]];
AliDebugF(3,"Vote taken for ddl %d, board 0x%x",
ddl,boards[i]);
}
}
}
#endif
if(sample_clk[boards[i]])
samplerate = shift_clk[boards[i]]/sample_clk[boards[i]];
AliDebugF(10,"Sample rate for board 0x%02x is %d",
boards[i], samplerate);
sampleRate->Set(det,ring,sector,0,samplerate);
stripRange->Set(det,ring,sector,0,
strip_low[boards[i]],strip_high[boards[i]]);
AliDebugF(20,"det %d, ring %c, ",det,ring);
pulseLength.AddAt(pulse_length[boards[i]],
GetHalfringIndex(det,ring,boards[i]/16));
pulseSize.AddAt(pulse_size[boards[i]],
GetHalfringIndex(det,ring,boards[i]/16));
AliDebugF(20,": Board: 0x%02x\n"
"\tstrip_low %3d, strip_high %3d\n"
"\tshift_clk %3d, sample_clk %3d\n"
"\tpulse_size %3d, pulse_length %3d",
boards[i],
strip_low[boards[i]], strip_high[boards[i]],
shift_clk[boards[i]], sample_clk[boards[i]],
pulse_size[boards[i]],pulse_length[boards[i]]);
}
}
AliFMDParameters::Instance()->SetSampleRate(sampleRate);
AliFMDParameters::Instance()->SetStripRange(stripRange);
AliDebug(0,"End of SOD/EOD");
return kTRUE;
}
UInt_t AliFMDRawReader::Get32bitWord(Int_t idx)
{
if (!fData) {
AliFatal("Raw data paylod buffer is not yet initialized !");
}
Int_t index = 4*idx;
if (index < 4) {
AliWarningF("Invalid raw data payload position (%d) !",index);
}
UInt_t word = 0;
word = fData[--index] << 24;
word |= fData[--index] << 16;
word |= fData[--index] << 8;
word |= fData[--index] << 0 ;
return word;
}
Int_t AliFMDRawReader::GetHalfringIndex(UShort_t det, Char_t ring,
UShort_t board) const
{
UShort_t iring = (ring == 'I' ? 1 : 0);
Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0));
return index-2;
}