#include "AliLoader.h"
#include "AliTRDfeeParam.h"
+#include "AliTRDcalibDB.h"
#include "AliTRDtrapConfig.h"
#include "AliTRDdigitsManager.h"
#include "AliTRDarrayADC.h"
#include "AliTRDarrayDictionary.h"
#include "AliTRDtrackletMCM.h"
#include "AliTRDmcmSim.h"
+#include "TTreeStream.h"
ClassImp(AliTRDmcmSim)
Bool_t AliTRDmcmSim::fgApplyCut = kTRUE;
Int_t AliTRDmcmSim::fgAddBaseline = 0;
+Bool_t AliTRDmcmSim::fgStoreClusters = kFALSE;
const Int_t AliTRDmcmSim::fgkFormatIndex = std::ios_base::xalloc();
-const Int_t AliTRDmcmSim::fgkNADC = AliTRDfeeParam::GetNadcMcm();
const UShort_t AliTRDmcmSim::fgkFPshifts[4] = {11, 14, 17, 21};
fTailAmplLong(NULL),
fTailAmplShort(NULL),
fNHits(0),
- fFitReg(NULL)
+ fFitReg(NULL),
+ fDebugStream(0x0)
{
//
// AliTRDmcmSim default constructor
//
if(fInitialized) {
- for( Int_t iAdc = 0 ; iAdc < fgkNADC; iAdc++ ) {
+ for( Int_t iAdc = 0 ; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++ ) {
delete [] fADCR[iAdc];
delete [] fADCF[iAdc];
}
if (!fInitialized) {
fFeeParam = AliTRDfeeParam::Instance();
- fTrapConfig = AliTRDtrapConfig::Instance();
+ fTrapConfig = AliTRDcalibDB::Instance()->GetTrapConfig();
}
fDetector = det;
fRow = fFeeParam->GetPadRowFromMCM( fRobPos, fMcmPos );
if (!fInitialized) {
- fADCR = new Int_t *[fgkNADC];
- fADCF = new Int_t *[fgkNADC];
- fZSMap = new Int_t [fgkNADC];
- fGainCounterA = new UInt_t[fgkNADC];
- fGainCounterB = new UInt_t[fgkNADC];
+ fADCR = new Int_t *[AliTRDfeeParam::GetNadcMcm()];
+ fADCF = new Int_t *[AliTRDfeeParam::GetNadcMcm()];
+ fZSMap = new Int_t [AliTRDfeeParam::GetNadcMcm()];
+ fGainCounterA = new UInt_t[AliTRDfeeParam::GetNadcMcm()];
+ fGainCounterB = new UInt_t[AliTRDfeeParam::GetNadcMcm()];
fNTimeBin = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kC13CPUA, fDetector, fRobPos, fMcmPos);
- for( Int_t iAdc = 0 ; iAdc < fgkNADC; iAdc++ ) {
+ for( Int_t iAdc = 0 ; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++ ) {
fADCR[iAdc] = new Int_t[fNTimeBin];
fADCF[iAdc] = new Int_t[fNTimeBin];
}
// filter registers
- fPedAcc = new UInt_t[fgkNADC]; // accumulator for pedestal filter
- fTailAmplLong = new UShort_t[fgkNADC];
- fTailAmplShort = new UShort_t[fgkNADC];
+ fPedAcc = new UInt_t[AliTRDfeeParam::GetNadcMcm()]; // accumulator for pedestal filter
+ fTailAmplLong = new UShort_t[AliTRDfeeParam::GetNadcMcm()];
+ fTailAmplShort = new UShort_t[AliTRDfeeParam::GetNadcMcm()];
// tracklet calculation
- fFitReg = new FitReg_t[fgkNADC];
+ fFitReg = new FitReg_t[AliTRDfeeParam::GetNadcMcm()];
fTrackletArray = new TClonesArray("AliTRDtrackletMCM", fgkMaxTracklets);
fMCMT = new UInt_t[fgkMaxTracklets];
if( !CheckInitialized() )
return;
- for( Int_t iAdc = 0 ; iAdc < fgkNADC; iAdc++ ) {
+ for( Int_t iAdc = 0 ; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++ ) {
for( Int_t it = 0 ; it < fNTimeBin ; it++ ) {
fADCR[iAdc][it] = 0;
fADCF[iAdc][it] = 0;
return;
fNTimeBin = ntimebins;
- for( Int_t iAdc = 0 ; iAdc < fgkNADC; iAdc++ ) {
+ for( Int_t iAdc = 0 ; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++ ) {
delete [] fADCR[iAdc];
delete [] fADCF[iAdc];
fADCR[iAdc] = new Int_t[fNTimeBin];
TH2F *hist = new TH2F("mcmdata", Form("Data of MCM %i on ROB %i in detector %i", \
fMcmPos, fRobPos, fDetector), \
- fgkNADC, -0.5, fgkNADC-.5, fNTimeBin, -.5, fNTimeBin-.5);
+ AliTRDfeeParam::GetNadcMcm(), -0.5, AliTRDfeeParam::GetNadcMcm()-.5, fNTimeBin, -.5, fNTimeBin-.5);
hist->GetXaxis()->SetTitle("ADC Channel");
hist->GetYaxis()->SetTitle("Timebin");
hist->SetStats(kFALSE);
if (opt.Contains("R")) {
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
hist->SetBinContent(iAdc+1, iTimeBin+1, fADCR[iAdc][iTimeBin] >> fgkAddDigits);
}
}
}
else {
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
hist->SetBinContent(iAdc+1, iTimeBin+1, fADCF[iAdc][iTimeBin] >> fgkAddDigits);
}
}
AliTRDtrackletMCM *trkl = (AliTRDtrackletMCM*) (*fTrackletArray)[iTrkl];
Float_t padWidth = 0.635 + 0.03 * (fDetector % 6);
Float_t offset = padWidth/256. * ((((((fRobPos & 0x1) << 2) + (fMcmPos & 0x3)) * 18) << 8) - ((18*4*2 - 18*2 - 3) << 7)); // revert adding offset in FitTracklet
- Int_t ndrift = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos) >> 5;
- Float_t slope = trkl->GetdY() * 140e-4 / ndrift;
+ Int_t ndrift = fTrapConfig->GetDmemUnsigned(fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos) >> 5;
+ Float_t slope = 0;
+ if (ndrift)
+ slope = trkl->GetdY() * 140e-4 / ndrift;
Int_t t0 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPFS, fDetector, fRobPos, fMcmPos);
Int_t t1 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPFE, fDetector, fRobPos, fMcmPos);
}
}
-void AliTRDmcmSim::SetData( Int_t adc, Int_t* const data )
+void AliTRDmcmSim::SetData( Int_t adc, const Int_t* const data )
{
//
// Store ADC data into array of raw data
if( !CheckInitialized() ) return;
- if( adc < 0 || adc >= fgkNADC ) {
- AliError(Form ("Error: ADC %i is out of range (0 .. %d).", adc, fgkNADC-1));
+ if( adc < 0 || adc >= AliTRDfeeParam::GetNadcMcm() ) {
+ AliError(Form ("Error: ADC %i is out of range (0 .. %d).", adc, AliTRDfeeParam::GetNadcMcm()-1));
return;
}
if( !CheckInitialized() ) return;
- if( adc < 0 || adc >= fgkNADC ) {
- AliError(Form ("Error: ADC %i is out of range (0 .. %d).", adc, fgkNADC-1));
+ if( adc < 0 || adc >= AliTRDfeeParam::GetNadcMcm() ) {
+ AliError(Form ("Error: ADC %i is out of range (0 .. %d).", adc, AliTRDfeeParam::GetNadcMcm()-1));
return;
}
continue;
fDict[iDict] = newDict;
- fDict[iDict]->Expand();
+ if(fDict[iDict]->GetDim() != 0)
+ fDict[iDict]->Expand();
}
else {
fDict[iDict] = newDict;
- if (fDict[iDict])
+ if (fDict[iDict] && (fDict[iDict]->GetDim() != 0) )
fDict[iDict]->Expand();
- }
+ }
// If there is no data, set dictionary to zero to avoid crashes
if (fDict[iDict]->GetDim() == 0) {
- AliError(Form("Dictionary %i of det. %i has dim. 0", iDict, fDetector));
+ // AliError(Form("Dictionary %i of det. %i has dim. 0", iDict, fDetector));
fDict[iDict] = 0x0;
}
}
Int_t offset = (fMcmPos % 4 + 1) * 21 + (fRobPos % 2) * 84 - 1;
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
Int_t value = adcArray->GetDataByAdcCol(GetRow(), offset - iAdc, iTimeBin);
// treat 0 as suppressed,
// this is not correct but reported like that from arrayADC
}
}
-void AliTRDmcmSim::SetDataByPad(AliTRDarrayADC* const adcArray, AliTRDdigitsManager * const digitsManager)
+void AliTRDmcmSim::SetDataByPad(const AliTRDarrayADC* const adcArray, AliTRDdigitsManager * const digitsManager)
{
// Set the ADC data from an AliTRDarrayADC
// (by pad, to be used during initial reading in simulation)
Int_t offset = (fMcmPos % 4 + 1) * 18 + (fRobPos % 2) * 72 + 1;
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
Int_t value = -1;
Int_t pad = offset - iAdc;
if (pad > -1 && pad < 144)
if( !CheckInitialized() )
return;
- if( adc < 0 || adc >= fgkNADC ) {
+ if( adc < 0 || adc >= AliTRDfeeParam::GetNadcMcm() ) {
return;
}
// n : unused , c : ADC count, m : selected ADCs
if( rawVer >= 3 &&
(fTrapConfig->GetTrapReg(AliTRDtrapConfig::kC15CPUA, fDetector, fRobPos, fMcmPos) & (1 << 13))) { // check for zs flag in TRAP configuration
- for( Int_t iAdc = 0 ; iAdc < fgkNADC ; iAdc++ ) {
+ for( Int_t iAdc = 0 ; iAdc < AliTRDfeeParam::GetNadcMcm() ; iAdc++ ) {
if( ~fZSMap[iAdc] != 0 ) { // 0 means not suppressed
adcMask |= (1 << (iAdc+4) ); // last 4 digit reserved for 1100=0xc
nActiveADC++; // number of 1 in mmm....m
UShort_t fptc = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kFPTC, fDetector, fRobPos, fMcmPos); // 0..3, 0 - fastest, 3 - slowest
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++)
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++)
fPedAcc[iAdc] = (baseline << 2) * (1 << fgkFPshifts[fptc]);
}
// the input has been stable for a sufficiently long time.
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
fADCF[iAdc][iTimeBin] = FilterPedestalNextSample(iAdc, iTimeBin, fADCR[iAdc][iTimeBin]);
}
}
// Initializes the gain filter. In this case, only threshold
// counters are reset.
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
// these are counters which in hardware continue
// until maximum or reset
fGainCounterA[iAdc] = 0;
UShort_t fgta = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kFGTA, fDetector, fRobPos, fMcmPos); // 20;
UShort_t fgtb = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kFGTB, fDetector, fRobPos, fMcmPos); // 2060;
+ UInt_t fgfExtended = 0x700 + fgf; // The corr factor which is finally applied has to be extended by 0x700 (hex) or 0.875 (dec)
+ // because fgf=0 correspons to 0.875 and fgf=511 correspons to 1.125 - 2^(-11)
+ // (see TRAP User Manual for details)
+
UInt_t corr; // corrected value
value &= 0xFFF;
- corr = (value * fgf) >> 11;
+ corr = (value * fgfExtended) >> 11;
corr = corr > 0xfff ? 0xfff : corr;
corr = AddUintClipping(corr, fga, 12);
{
// Read data from fADCF and apply gain filter.
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
fADCF[iAdc][iTimeBin] = FilterGainNextSample(iAdc, fADCF[iAdc][iTimeBin]);
}
ql = lambdaL * (1 - lambdaS) * alphaL;
qs = lambdaS * (1 - lambdaL) * (1 - alphaL);
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
Int_t value = baseline & 0xFFF;
Int_t corr = (value * fTrapConfig->GetTrapReg(AliTRDtrapConfig::TrapReg_t(AliTRDtrapConfig::kFGF0 + iAdc), fDetector, fRobPos, fMcmPos)) >> 11;
corr = corr > 0xfff ? 0xfff : corr;
// Apply tail cancellation filter to all data.
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
fADCF[iAdc][iTimeBin] = FilterTailNextSample(iAdc, fADCF[iAdc][iTimeBin]);
}
}
Int_t **adc = fADCF;
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++)
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++)
fZSMap[iAdc] = -1;
for( Int_t it = 0 ; it < fNTimeBin ; it++ ) {
}
// ----- last channel -----
- iAdc = fgkNADC - 1;
+ iAdc = AliTRDfeeParam::GetNadcMcm() - 1;
ap = adc[iAdc-1][it]; // previous
ac = adc[iAdc ][it]; // current
}
// ----- middle channels -----
- for( iAdc = 1 ; iAdc < fgkNADC-1; iAdc++ ) {
+ for( iAdc = 1 ; iAdc < AliTRDfeeParam::GetNadcMcm()-1; iAdc++ ) {
ap = adc[iAdc-1][it]; // previous
ac = adc[iAdc ][it]; // current
an = adc[iAdc+1][it]; // next
//??? to be clarified:
UInt_t adcMask = 0xffffffff;
- UShort_t timebin, adcch, adcLeft, adcCentral, adcRight, hitQual, timebin1, timebin2, qtotTemp;
+ Bool_t hitQual;
+ Int_t adcLeft, adcCentral, adcRight;
+ UShort_t timebin, adcch, timebin1, timebin2, qtotTemp;
Short_t ypos, fromLeft, fromRight, found;
UShort_t qTotal[19+1]; // the last is dummy
UShort_t marked[6], qMarked[6], worse1, worse2;
- timebin1 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPFS, fDetector, fRobPos, fMcmPos);
- if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS0, fDetector, fRobPos, fMcmPos)
- < timebin1)
- timebin1 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS0, fDetector, fRobPos, fMcmPos);
- timebin2 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPFE, fDetector, fRobPos, fMcmPos);
- if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE1, fDetector, fRobPos, fMcmPos)
- > timebin2)
- timebin2 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE1, fDetector, fRobPos, fMcmPos);
+ if (fgStoreClusters) {
+ timebin1 = 0;
+ timebin2 = fNTimeBin;
+ }
+ else {
+ // find first timebin to be looked at
+ timebin1 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPFS, fDetector, fRobPos, fMcmPos);
+ if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS0, fDetector, fRobPos, fMcmPos)
+ < timebin1)
+ timebin1 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS0, fDetector, fRobPos, fMcmPos);
+ if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS1, fDetector, fRobPos, fMcmPos)
+ < timebin1)
+ timebin1 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS1, fDetector, fRobPos, fMcmPos);
+
+ // find last timebin to be looked at
+ timebin2 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPFE, fDetector, fRobPos, fMcmPos);
+ if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE0, fDetector, fRobPos, fMcmPos)
+ > timebin2)
+ timebin2 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE0, fDetector, fRobPos, fMcmPos);
+ if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE1, fDetector, fRobPos, fMcmPos)
+ > timebin2)
+ timebin2 = fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE1, fDetector, fRobPos, fMcmPos);
+ }
// reset the fit registers
fNHits = 0;
- for (adcch = 0; adcch < fgkNADC-2; adcch++) // due to border channels
+ for (adcch = 0; adcch < AliTRDfeeParam::GetNadcMcm()-2; adcch++) // due to border channels
{
fFitReg[adcch].fNhits = 0;
fFitReg[adcch].fQ0 = 0;
{
// first find the hit candidates and store the total cluster charge in qTotal array
// in case of not hit store 0 there.
- for (adcch = 0; adcch < fgkNADC-2; adcch++) {
+ for (adcch = 0; adcch < AliTRDfeeParam::GetNadcMcm()-2; adcch++) {
if ( ( (adcMask >> adcch) & 7) == 7) //??? all 3 channels are present in case of ZS
{
adcLeft = fADCF[adcch ][timebin];
adcCentral = fADCF[adcch+1][timebin];
adcRight = fADCF[adcch+2][timebin];
- if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVBY, fDetector, fRobPos, fMcmPos) == 1)
+
+ if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVBY, fDetector, fRobPos, fMcmPos) == 0) {
+ // bypass the cluster verification
+ hitQual = kTRUE;
+ }
+ else {
hitQual = ( (adcLeft * adcRight) <
- (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos) * adcCentral) );
- else
- hitQual = 1;
+ ((fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos) * adcCentral*adcCentral) >> 10) );
+ if (hitQual)
+ AliDebug(5, Form("cluster quality cut passed with %3i, %3i, %3i - threshold %3i -> %i",
+ adcLeft, adcCentral, adcRight,
+ fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos),
+ fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos) * adcCentral*adcCentral));
+ }
+
// The accumulated charge is with the pedestal!!!
qtotTemp = adcLeft + adcCentral + adcRight;
+ if ((fDebugStream) && (qtotTemp > 130)) {
+ (*fDebugStream) << "testtree"
+ << "qtot=" << qtotTemp
+ << "qleft=" << adcLeft
+ << "qcent=" << adcCentral
+ << "qright=" << adcRight
+ << "\n";
+ }
if ( (hitQual) &&
(qtotTemp >= fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPHT, fDetector, fRobPos, fMcmPos)) &&
(adcLeft <= adcCentral) &&
}
}
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
if (fFitReg[iAdc].fNhits != 0) {
AliDebug(2, Form("fitreg[%i]: nHits = %i, sumX = %i, sumY = %i, sumX2 = %i, sumY2 = %i, sumXY = %i", iAdc,
fFitReg[iAdc].fNhits,
UInt_t scaleY = (UInt_t) ((0.635 + 0.03 * layer)/(256.0 * 160.0e-4) * shift);
UInt_t scaleD = (UInt_t) ((0.635 + 0.03 * layer)/(256.0 * 140.0e-4) * shift);
- Int_t deflCorr = (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCorr, fDetector, fRobPos, fMcmPos);
- Int_t ndrift = (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos);
+ Int_t deflCorr = (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCorr, fDetector, fRobPos, fMcmPos);
+ Int_t ndrift = (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos);
// local variables for calculation
Long64_t mult, temp, denom; //???
AliDebug(5, Form("Det: %3i, ROB: %i, MCM: %2i: deflection: %i, min: %i, max: %i",
fDetector, fRobPos, fMcmPos, slope,
- (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos),
- (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos)));
+ (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos),
+ (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos)));
- AliDebug(5, Form("Fit sums: x = %i, X = %i, y = %i, Y = %i, Z = %i",
- sumX, sumX2, sumY, sumY2, sumXY));
+ AliDebug(5, Form("Fit sums: x = %i, X = %i, y = %i, Y = %i, Z = %i, q0 = %i, q1 = %i",
+ sumX, sumX2, sumY, sumY2, sumXY, q0, q1));
fitSlope = (Float_t) (nHits * sumXY - sumX * sumY) / (nHits * sumX2 - sumX*sumX);
Bool_t rejected = kFALSE;
// deflection range table from DMEM
- if ((slope < ((Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))) ||
- (slope > ((Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))))
+ if ((slope < ((Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))) ||
+ (slope > ((Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))))
rejected = kTRUE;
if (rejected && GetApplyCut())
// assemble and store the tracklet word
fMCMT[cpu] = (pid << 24) | (padrow << 20) | (slope << 13) | offset;
- // calculate MC label
+ // calculate number of hits and MC label
Int_t mcLabel[] = { -1, -1, -1};
Int_t nHits0 = 0;
Int_t nHits1 = 0;
- if (fDigitsManager) {
- const Int_t maxLabels = 30;
- Int_t label[maxLabels] = {0}; // up to 30 different labels possible
- Int_t count[maxLabels] = {0};
- Int_t nLabels = 0;
- for (Int_t iHit = 0; iHit < fNHits; iHit++) {
- if ((fHits[iHit].fChannel - fFitPtr[cpu] < 0) ||
- (fHits[iHit].fChannel - fFitPtr[cpu] > 1))
- continue;
-
- // counting contributing hits
- if (fHits[iHit].fTimebin >= fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS0, fDetector, fRobPos, fMcmPos) &&
- fHits[iHit].fTimebin < fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE0, fDetector, fRobPos, fMcmPos))
- nHits0++;
- if (fHits[iHit].fTimebin >= fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS1, fDetector, fRobPos, fMcmPos) &&
- fHits[iHit].fTimebin < fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE1, fDetector, fRobPos, fMcmPos))
- nHits1++;
+ const Int_t maxLabels = 30;
+ Int_t label[maxLabels] = {0}; // up to 30 different labels possible
+ Int_t count[maxLabels] = {0};
+ Int_t nLabels = 0;
+
+ for (Int_t iHit = 0; iHit < fNHits; iHit++) {
+ if ((fHits[iHit].fChannel - fFitPtr[cpu] < 0) ||
+ (fHits[iHit].fChannel - fFitPtr[cpu] > 1))
+ continue;
+
+ // counting contributing hits
+ if (fHits[iHit].fTimebin >= fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS0, fDetector, fRobPos, fMcmPos) &&
+ fHits[iHit].fTimebin < fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE0, fDetector, fRobPos, fMcmPos))
+ nHits0++;
+ if (fHits[iHit].fTimebin >= fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQS1, fDetector, fRobPos, fMcmPos) &&
+ fHits[iHit].fTimebin < fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPQE1, fDetector, fRobPos, fMcmPos))
+ nHits1++;
+
+ // label calculation only if there is a digitsmanager to get the labels from
+ if (fDigitsManager) {
for (Int_t i = 0; i < 3; i++) {
Int_t currLabel = fHits[iHit].fLabel[i];
for (Int_t iLabel = 0; iLabel < nLabels; iLabel++) {
}
}
}
- Int_t index[2*maxLabels];
- TMath::Sort(maxLabels, count, index);
- for (Int_t i = 0; i < 3; i++) {
- if (count[index[i]] <= 0)
- break;
- mcLabel[i] = label[index[i]];
+
+ if (fDigitsManager) {
+ Int_t index[2*maxLabels];
+ TMath::Sort(maxLabels, count, index);
+ for (Int_t i = 0; i < 3; i++) {
+ if (count[index[i]] <= 0)
+ break;
+ mcLabel[i] = label[index[i]];
+ }
}
}
new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletMCM((UInt_t) fMCMT[cpu], fDetector*2 + fRobPos%2, fRobPos, fMcmPos);
((AliTRDtrackletMCM*) (*fTrackletArray)[fTrackletArray->GetEntriesFast()-1])->SetOffset(fitOffset);
((AliTRDtrackletMCM*) (*fTrackletArray)[fTrackletArray->GetEntriesFast()-1])->SetError(TMath::Sqrt(TMath::Abs(fitError)/nHits));
-// // cluster information
-// Float_t *res = new Float_t[nHits];
-// Float_t *qtot = new Float_t[nHits];
-// Int_t nCls = 0;
-// for (Int_t iHit = 0; iHit < fNHits; iHit++) {
-// // check if hit contributes
-// if (fHits[iHit].fChannel == fFitPtr[cpu]) {
-// res[nCls] = fHits[iHit].fYpos - (fitSlope * fHits[iHit].fTimebin + fitOffset);
-// qtot[nCls] = fHits[iHit].fQtot;
-// nCls++;
-// }
-// else if (fHits[iHit].fChannel == fFitPtr[cpu] + 1) {
-// res[nCls] = fHits[iHit].fYpos + 256 - (fitSlope * fHits[iHit].fTimebin + fitOffset);
-// qtot[nCls] = fHits[iHit].fQtot;
-// nCls++;
-// }
-// }
-// ((AliTRDtrackletMCM*) (*fTrackletArray)[fTrackletArray->GetEntriesFast()-1])->SetClusters(res, qtot, nCls);
-// delete [] res;
-// delete [] qtot;
+ // store cluster information (if requested)
+ if (fgStoreClusters) {
+ Float_t *res = new Float_t[fNTimeBin];
+ Float_t *qtot = new Float_t[fNTimeBin];
+ for (Int_t iTimebin = 0; iTimebin < fNTimeBin; ++iTimebin) {
+ res[iTimebin] = 0;
+ qtot[iTimebin] = 0;
+ }
+ for (Int_t iHit = 0; iHit < fNHits; iHit++) {
+ Int_t timebin = fHits[iHit].fTimebin;
+
+ // check if hit contributes
+ if (fHits[iHit].fChannel == fFitPtr[cpu]) {
+ res[timebin] = fHits[iHit].fYpos - (fitSlope * timebin + fitOffset);
+ qtot[timebin] = fHits[iHit].fQtot;
+ }
+ else if (fHits[iHit].fChannel == fFitPtr[cpu] + 1) {
+ res[timebin] = fHits[iHit].fYpos + 256 - (fitSlope * timebin + fitOffset);
+ qtot[timebin] = fHits[iHit].fQtot;
+ }
+ }
+ ((AliTRDtrackletMCM*) (*fTrackletArray)[fTrackletArray->GetEntriesFast()-1])->SetClusters(res, qtot, fNTimeBin);
+ delete [] res;
+ delete [] qtot;
+ }
if (fitError < 0)
AliError(Form("Strange fit error: %f from Sx: %i, Sy: %i, Sxy: %i, Sx2: %i, Sy2: %i, nHits: %i",
if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kEBSF, fDetector, fRobPos, fMcmPos) != 0) // store unfiltered data
{
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
if (~fZSMap[iAdc] == 0) {
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
digits->SetDataByAdcCol(GetRow(), offset - iAdc, iTimeBin, -1);
}
}
else {
- for (Int_t iAdc = 0; iAdc < fgkNADC; iAdc++) {
+ for (Int_t iAdc = 0; iAdc < AliTRDfeeParam::GetNadcMcm(); iAdc++) {
if (~fZSMap[iAdc] != 0) {
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
digits->SetDataByAdcCol(GetRow(), offset - iAdc, iTimeBin, (fADCF[iAdc][iTimeBin] >> fgkAddDigits) - fgAddBaseline);
ULong64_t addrQ0;
ULong64_t addr;
- UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTnbins); // number of bins in q0 / 4 !!
- UInt_t pidTotalSize = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTLength);
+ UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTnbins, fDetector, fRobPos, fMcmPos); // number of bins in q0 / 4 !!
+ UInt_t pidTotalSize = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTLength, fDetector, fRobPos, fMcmPos);
if(nBinsQ0==0 || pidTotalSize==0) // make sure we don't run into trouble if the value for Q0 is not configured
return 0; // Q1 not configured is ok for 1D LUT
- ULong_t corrQ0 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTcor0, fDetector, fRobPos, fMcmPos);
- ULong_t corrQ1 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTcor1, fDetector, fRobPos, fMcmPos);
+ ULong_t corrQ0 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTcor0, fDetector, fRobPos, fMcmPos);
+ ULong_t corrQ1 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTcor1, fDetector, fRobPos, fMcmPos);
if(corrQ0==0) // make sure we don't run into trouble if one of the values is not configured
return 0;
// For a LUT with 11 input and 8 output bits, the first memory address is set to LUT[0] | (LUT[1] << 8) | (LUT[2] << 16) | (LUT[3] << 24)
// and so on
- UInt_t result = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTStart+(addr/4));
+ UInt_t result = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTStart+(addr/4), fDetector, fRobPos, fMcmPos);
return (result>>((addr%4)*8)) & 0xFF;
}
os << "----- Unfiltered ADC data (10 bit) -----" << std::endl;
os << "ch ";
- for (Int_t iChannel = 0; iChannel < mcm.fgkNADC; iChannel++)
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++)
os << std::setw(5) << iChannel;
os << std::endl;
for (Int_t iTimeBin = 0; iTimeBin < mcm.fNTimeBin; iTimeBin++) {
os << "tb " << std::setw(2) << iTimeBin << ":";
- for (Int_t iChannel = 0; iChannel < mcm.fgkNADC; iChannel++) {
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++) {
os << std::setw(5) << (mcm.fADCR[iChannel][iTimeBin] >> mcm.fgkAddDigits);
}
os << std::endl;
os << "----- Filtered ADC data (10+2 bit) -----" << std::endl;
os << "ch ";
- for (Int_t iChannel = 0; iChannel < mcm.fgkNADC; iChannel++)
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++)
os << std::setw(4) << iChannel
<< ((~mcm.fZSMap[iChannel] != 0) ? "!" : " ");
os << std::endl;
for (Int_t iTimeBin = 0; iTimeBin < mcm.fNTimeBin; iTimeBin++) {
os << "tb " << std::setw(2) << iTimeBin << ":";
- for (Int_t iChannel = 0; iChannel < mcm.fgkNADC; iChannel++) {
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++) {
os << std::setw(4) << (mcm.fADCF[iChannel][iTimeBin])
<< (((mcm.fZSMap[iChannel] & (1 << iTimeBin)) == 0) ? "!" : " ");
}
Int_t addrStep = 0x80;
for (Int_t iTimeBin = 0; iTimeBin < mcm.fNTimeBin; iTimeBin++) {
- for (Int_t iChannel = 0; iChannel < mcm.fgkNADC; iChannel++) {
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++) {
os << std::setw(5) << 10
<< std::setw(5) << addrOffset + iChannel * addrStep + iTimeBin
<< std::setw(5) << (mcm.fADCF[iChannel][iTimeBin])
for(int adcch=fFitPtr[cpu]; adcch<fFitPtr[cpu]+2; adcch++) {
os << " <ch chnr=\"" << adcch << "\">"<< std::endl;
os << " <hits>" << fFitReg[adcch].fNhits << "</hits>"<< std::endl;
- os << " <q0>" << fFitReg[adcch].fQ0/4 << "</q0>"<< std::endl; // divided by 4 because in simulation we have 2 additional decimal places
- os << " <q1>" << fFitReg[adcch].fQ1/4 << "</q1>"<< std::endl; // in the output
+ os << " <q0>" << fFitReg[adcch].fQ0 << "</q0>"<< std::endl;
+ os << " <q1>" << fFitReg[adcch].fQ1 << "</q1>"<< std::endl;
os << " <sumx>" << fFitReg[adcch].fSumX << "</sumx>"<< std::endl;
os << " <sumxsq>" << fFitReg[adcch].fSumX2 << "</sumxsq>"<< std::endl;
os << " <sumy>" << fFitReg[adcch].fSumY << "</sumy>"<< std::endl;
}
+void AliTRDmcmSim::PrintAdcDatTxt(ostream& os) const
+{
+ // print ADC data in text format (suitable as Modelsim stimuli)
+
+ os << "# MCM " << fMcmPos << " on ROB " << fRobPos <<
+ " in detector " << fDetector << std::endl;
+
+ for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); ++iChannel) {
+ os << std::setw(5) << (fADCR[iChannel][iTimeBin] >> fgkAddDigits);
+ }
+ os << std::endl;
+ }
+}
+
+
void AliTRDmcmSim::PrintAdcDatHuman(ostream& os) const
{
// print ADC data in human-readable format
os << "----- Unfiltered ADC data (10 bit) -----" << std::endl;
os << "ch ";
- for (Int_t iChannel = 0; iChannel < fgkNADC; iChannel++)
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++)
os << std::setw(5) << iChannel;
os << std::endl;
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
os << "tb " << std::setw(2) << iTimeBin << ":";
- for (Int_t iChannel = 0; iChannel < fgkNADC; iChannel++) {
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++) {
os << std::setw(5) << (fADCR[iChannel][iTimeBin] >> fgkAddDigits);
}
os << std::endl;
os << "----- Filtered ADC data (10+2 bit) -----" << std::endl;
os << "ch ";
- for (Int_t iChannel = 0; iChannel < fgkNADC; iChannel++)
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++)
os << std::setw(4) << iChannel
<< ((~fZSMap[iChannel] != 0) ? "!" : " ");
os << std::endl;
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
os << "tb " << std::setw(2) << iTimeBin << ":";
- for (Int_t iChannel = 0; iChannel < fgkNADC; iChannel++) {
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++) {
os << std::setw(4) << (fADCF[iChannel][iTimeBin])
<< (((fZSMap[iChannel] & (1 << iTimeBin)) == 0) ? "!" : " ");
}
os << " <ro-board rob=\"" << fRobPos << "\">" << std::endl;
os << " <m mcm=\"" << fMcmPos << "\">" << std::endl;
- for(Int_t iChannel = 0; iChannel < fgkNADC; iChannel++) {
+ for(Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++) {
os << " <ch chnr=\"" << iChannel << "\">" << std::endl;
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
os << "<tb>" << fADCF[iChannel][iTimeBin]/4 << "</tb>";
Int_t addrOffsetEBSIA = 0x20;
for (Int_t iTimeBin = 0; iTimeBin < fNTimeBin; iTimeBin++) {
- for (Int_t iChannel = 0; iChannel < fgkNADC; iChannel++) {
+ for (Int_t iChannel = 0; iChannel < AliTRDfeeParam::GetNadcMcm(); iChannel++) {
if ((iTimeBin < timeBinOffset) || (iTimeBin >= fNTimeBin+timeBinOffset)) {
if(broadcast==kFALSE)
fTrapConfig->PrintDatx(os, addrOffset+iChannel*addrStep+addrOffsetEBSIA+iTimeBin, 10, GetRobPos(), GetMcmPos());
UInt_t result;
- UInt_t addrEnd = AliTRDtrapConfig::fgkDmemAddrLUTStart + fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTLength)/4; // /4 because each addr contains 4 values
- UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTnbins);
+ UInt_t addrEnd = fgkDmemAddrLUTStart + fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTLength, fDetector, fRobPos, fMcmPos)/4; // /4 because each addr contains 4 values
+ UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTnbins, fDetector, fRobPos, fMcmPos);
std::cout << "nBinsQ0: " << nBinsQ0 << std::endl;
- std::cout << "LUT table length: " << fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTLength) << std::endl;
-
- for(UInt_t addr=AliTRDtrapConfig::fgkDmemAddrLUTStart; addr< addrEnd; addr++) {
- result = fTrapConfig->GetDmemUnsigned(addr);
- std::cout << addr << " # x: " << ((addr-AliTRDtrapConfig::fgkDmemAddrLUTStart)%((nBinsQ0)/4))*4 << ", y: " <<(addr-AliTRDtrapConfig::fgkDmemAddrLUTStart)/(nBinsQ0/4)
- << " # " <<((result>>0)&0xFF)
- << " | " << ((result>>8)&0xFF)
- << " | " << ((result>>16)&0xFF)
- << " | " << ((result>>24)&0xFF) << std::endl;
+ std::cout << "LUT table length: " << fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTLength, fDetector, fRobPos, fMcmPos) << std::endl;
+
+ if (nBinsQ0>0) {
+ for(UInt_t addr=fgkDmemAddrLUTStart; addr< addrEnd; addr++) {
+ result = fTrapConfig->GetDmemUnsigned(addr, fDetector, fRobPos, fMcmPos);
+ std::cout << addr << " # x: " << ((addr-fgkDmemAddrLUTStart)%((nBinsQ0)/4))*4 << ", y: " <<(addr-fgkDmemAddrLUTStart)/(nBinsQ0/4)
+ << " # " <<((result>>0)&0xFF)
+ << " | " << ((result>>8)&0xFF)
+ << " | " << ((result>>16)&0xFF)
+ << " | " << ((result>>24)&0xFF) << std::endl;
+ }
}
}
+
+
+Bool_t AliTRDmcmSim::ReadPackedConfig(AliTRDtrapConfig *cfg, Int_t hc, UInt_t *data, Int_t size)
+{
+ // Read the packed configuration from the passed memory block
+ //
+ // To be used to retrieve the TRAP configuration from the
+ // configuration as sent in the raw data.
+
+ AliDebugClass(1, "Reading packed configuration");
+
+ Int_t det = hc/2;
+
+ Int_t idx = 0;
+ Int_t err = 0;
+ Int_t step, bwidth, nwords, exitFlag, bitcnt;
+
+ UShort_t caddr;
+ UInt_t dat, msk, header, dataHi;
+
+ while (idx < size && *data != 0x00000000) {
+
+ Int_t rob = (*data >> 28) & 0x7;
+ Int_t mcm = (*data >> 24) & 0xf;
+
+ AliDebugClass(1, Form("Config of det. %3i MCM %i:%02i (0x%08x)", det, rob, mcm, *data));
+ data++;
+
+ while (idx < size && *data != 0x00000000) {
+
+ header = *data;
+ data++;
+ idx++;
+
+ AliDebugClass(5, Form("read: 0x%08x", header));
+
+ if (header & 0x01) // single data
+ {
+ dat = (header >> 2) & 0xFFFF; // 16 bit data
+ caddr = (header >> 18) & 0x3FFF; // 14 bit address
+
+ if (caddr != 0x1FFF) // temp!!! because the end marker was wrong
+ {
+ if (header & 0x02) // check if > 16 bits
+ {
+ dataHi = *data;
+ AliDebugClass(5, Form("read: 0x%08x", dataHi));
+ data++;
+ idx++;
+ err += ((dataHi ^ (dat | 1)) & 0xFFFF) != 0;
+ dat = (dataHi & 0xFFFF0000) | dat;
+ }
+ AliDebugClass(5, Form("addr=0x%04x (%s) data=0x%08x\n", caddr, cfg->GetRegName(cfg->GetRegByAddress(caddr)), dat));
+ if ( ! cfg->Poke(caddr, dat, det, rob, mcm) )
+ AliDebugClass(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+ if (idx > size)
+ {
+ AliDebugClass(5, Form("(single-write): no more data, missing end marker\n"));
+ return -err;
+ }
+ }
+ else
+ {
+ AliDebugClass(5, Form("(single-write): address 0x%04x => old endmarker?\n", caddr));
+ return err;
+ }
+ }
+
+ else // block of data
+ {
+ step = (header >> 1) & 0x0003;
+ bwidth = ((header >> 3) & 0x001F) + 1;
+ nwords = (header >> 8) & 0x00FF;
+ caddr = (header >> 16) & 0xFFFF;
+ exitFlag = (step == 0) || (step == 3) || (nwords == 0);
+
+ if (exitFlag)
+ break;
+
+ switch (bwidth)
+ {
+ case 15:
+ case 10:
+ case 7:
+ case 6:
+ case 5:
+ {
+ msk = (1 << bwidth) - 1;
+ bitcnt = 0;
+ while (nwords > 0)
+ {
+ nwords--;
+ bitcnt -= bwidth;
+ if (bitcnt < 0)
+ {
+ header = *data;
+ AliDebugClass(5, Form("read 0x%08x", header));
+ data++;
+ idx++;
+ err += (header & 1);
+ header = header >> 1;
+ bitcnt = 31 - bwidth;
+ }
+ AliDebugClass(5, Form("addr=0x%04x (%s) data=0x%08x\n", caddr, cfg->GetRegName(cfg->GetRegByAddress(caddr)), header & msk));
+ if ( ! cfg->Poke(caddr, header & msk, det, rob, mcm) )
+ AliDebugClass(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+
+ caddr += step;
+ header = header >> bwidth;
+ if (idx >= size)
+ {
+ AliDebugClass(5, Form("(block-write): no end marker! %d words read\n", idx));
+ return -err;
+ }
+ }
+ break;
+ } // end case 5-15
+ case 31:
+ {
+ while (nwords > 0)
+ {
+ header = *data;
+ AliDebugClass(5, Form("read 0x%08x", header));
+ data++;
+ idx++;
+ nwords--;
+ err += (header & 1);
+
+ AliDebugClass(5, Form("addr=0x%04x (%s) data=0x%08x", caddr, cfg->GetRegName(cfg->GetRegByAddress(caddr)), header >> 1));
+ if ( ! cfg->Poke(caddr, header >> 1, det, rob, mcm) )
+ AliDebugClass(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+
+ caddr += step;
+ if (idx >= size)
+ {
+ AliDebugClass(5, Form("no end marker! %d words read", idx));
+ return -err;
+ }
+ }
+ break;
+ }
+ default: return err;
+ } // end switch
+ } // end block case
+ }
+ } // end while
+ AliDebugClass(5, Form("no end marker! %d words read", idx));
+ return -err; // only if the max length of the block reached!
+}