#include "AliFMDDebug.h" // Better debug macros
#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
#include "AliFMDDigit.h" // ALIFMDDIGIT_H
+#include "AliFMDSDigit.h" // ALIFMDSDIGIT_H
#include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H
#include "AliRawReader.h" // ALIRAWREADER_H
#include "AliFMDRawReader.h" // ALIFMDRAWREADER_H
#include "AliFMDDebug.h"
#include "AliFMDCalibSampleRate.h"
#include "AliFMDCalibStripRange.h"
+#include "AliFMDAltroMapping.h"
// #include "AliFMDAltroIO.h" // ALIFMDALTROIO_H
#include <TArrayS.h> // ROOT_TArrayS
#include <TTree.h> // ROOT_TTree
#include <TClonesArray.h> // ROOT_TClonesArray
#include <TString.h>
- #include <iostream>
+#include <iostream>
+#include <climits>
// #include <iomanip>
//____________________________________________________________________
: TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"),
fTree(tree),
fReader(reader),
- fSampleRate(1),
+ // fSampleRate(1),
fData(0),
fNbytes(0),
fSeen()
{
// Default CTOR
+ for (Int_t i = 0; i < 3; i++) {
+ fSampleRate[i] = 0;
+ fZeroSuppress[i] = kFALSE;
+ fNoiseFactor[i] = 1;
+ }
}
//____________________________________________________________________
array->GetEntriesFast(), nWrite));
}
+//____________________________________________________________________
+Bool_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)
+{
+ // Scan current event for next signal. It returns kFALSE when
+ // there's no more data in the event.
+ static AliAltroRawStream stream(fReader); // = 0;
+ static AliFMDParameters* pars = 0;
+ static AliFMDAltroMapping* map = 0;
+ static Int_t ddl = -1;
+ // static UInt_t rate = 0;
+ 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 Short_t tsam = -1;
+ static UInt_t trate = 0;
+ static Int_t hwaddr = -1;
+ static UShort_t stripMin = 0;
+ static UShort_t stripMax = 0; // 127;
+ static UShort_t preSamp = 0; // 14+5;
+ if (stream.GetDDLNumber() < 0) {
+ fReader->Select("FMD");
+
+ // Reset "seen" array
+ // const UShort_t kUShortMax = (1 << 16) - 1;
+ // fSeen.Reset(kUShortMax);
+
+ pars = AliFMDParameters::Instance();
+ map = pars->GetAltroMap();
+ // stream = new AliAltroRawStream(fReader);
+
+ AliFMDDebug(5, ("Setting %d word headers",
+ pars->HasCompleteHeader() ? 8 : 7));
+ stream.SetShortDataHeader(!pars->HasCompleteHeader());
+
+ // Reset variables
+ ddl = -1;
+ trate = 0;
+ tdet = 0;
+ trng = '\0';
+ tsec = 0;
+ tstr = 0;
+ tsam = -1;
+ hwaddr = -1;
+ }
+ do {
+ Bool_t next = stream.Next();
+ if (!next) {
+ // if (stream) delete stream;
+ // stream = 0;
+ return kFALSE;
+ }
+ Int_t thisDDL = stream.GetDDLNumber();
+ AliFMDDebug(10, ("RCU @ DDL %d", thisDDL));
+ if (thisDDL != ddl) {
+ ddl = thisDDL;
+ fZeroSuppress[ddl] = zs = stream.GetZeroSupp();
+ fNoiseFactor[ddl] = fac = stream.GetNPostsamples();
+ fSampleRate[ddl] = trate = 0; // stream.GetNPresamples();
+ tdet = map->DDL2Detector(ddl);
+ AliFMDDebug(10, ("RCU @ DDL %d zero suppression: %s",ddl, zs?"yes":"no"));
+ AliFMDDebug(10, ("RCU @ DDL %d noise factor: %d", ddl,fac));
+ AliFMDDebug(10, ("RCU @ DDL %d sample rate: %d", ddl, trate));
+ }
+ Int_t thisAddr = stream.GetHWAddress();
+ AliFMDDebug(10, ("RCU @ DDL %d, Address 0x%03x", ddl, thisAddr));
+ if (thisAddr != hwaddr) {
+ hwaddr = thisAddr;
+ UShort_t board, chip, channel;
+ map->ChannelAddress(hwaddr, board, chip, channel);
+ map->Channel2StripBase(board, chip, channel, trng, tsec, bstr);
+ AliFMDDebug(10, ("0x%04x/0x%03x maps to FMD%d%c[%2d]-%3d",
+ ddl, hwaddr, tdet, trng, tsec, bstr));
+
+ stripMin = pars->GetMinStrip(tdet, trng, tsec, bstr);
+ stripMax = pars->GetMaxStrip(tdet, trng, tsec, bstr);
+ preSamp = pars->GetPreSamples(tdet, trng, tsec, bstr);
+ if (trate == 0)
+ fSampleRate[ddl] = trate = pars->GetSampleRate(tdet, trng, tsec, bstr);
+ AliFMDDebug(10, ("RCU @ DDL %d, Address 0x%03x sample rate: %d",
+ ddl, hwaddr, trate));
+
+ Int_t nChAddrMismatch = stream.GetNChAddrMismatch();
+ Int_t nChLenMismatch = stream.GetNChLengthMismatch();
+ if (nChAddrMismatch != 0)
+ AliWarning(Form("Got %d channels with address mis-matches for 0x%03x",
+ nChAddrMismatch, hwaddr));
+ if (nChLenMismatch != 0)
+ AliWarning(Form("Got %d channels with length mis-matches for 0x%03x",
+ nChLenMismatch, hwaddr));
+ }
+ // Get the signal
+ adc = stream.GetSignal();
+
+ // Sanity check - if the total bunch length is less than 1, then
+ // read until we get the next bunch.
+ Int_t b = stream.GetTimeLength();
+ if (b < 1) {
+ AliWarning(Form("Bunch length %0d is less than 0 for "
+ "DDL %4d address 0x%03x", b, ddl, hwaddr));
+ continue;
+ }
+ // Sanity check - if the current time is less than 0, then read
+ // until we get a new bunch.
+ Int_t t = stream.GetTime();
+ if (t < 0) {
+ AliWarning(Form("Time %0d is less than 0 for DDL %4d address 0x%03x",
+ t, ddl, hwaddr));
+ continue;
+ }
+
+ Short_t strOff = 0;
+ UShort_t samp = 0;
+ map->Timebin2Strip(tsec, t, preSamp, trate, strOff, samp);
+ tstr = bstr + strOff;
+ tsam = samp;
+ AliFMDDebug(20, ("0x%04x/0x%03x/%04d maps to FMD%d%c[%2d,%3d]-%d",
+ ddl, hwaddr, t, tdet, trng, tsec, tstr, samp));
+
+ // Local strip number to channel
+ Short_t l = (tstr > bstr ? tstr - bstr : bstr - tstr);
+ AliFMDDebug(10, ("Checking if strip %d in range [%d,%d]",
+ l, stripMin, stripMax));
+ if (l < stripMin || l > stripMax) {
+ AliFMDDebug(5, ("VA channel %3d (t: %4d) of DDL %4d address 0x%03x "
+ "is out of range (%3d->%3d)",
+ l, t, ddl, hwaddr, stripMin, stripMax));
+ continue;
+ }
+
+
+ det = tdet;
+ rng = trng;
+ sec = tsec;
+ str = tstr;
+ sam = tsam;
+ rat = trate;
+ // adc = stream.GetSignal();
+
+ break;
+ } while (true);
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDRawReader::NextSignal(UShort_t& det, Char_t& rng,
+ UShort_t& sec, UShort_t& str,
+ Short_t& adc, Bool_t& zs,
+ UShort_t& fac)
+{
+
+ do {
+ UShort_t samp, rate;
+ if (!NextSample(det, rng, sec, str, samp, rate, adc, zs, fac))
+ return kFALSE;
+
+ 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;
+ }
+ if (!take) continue;
+ break;
+ } while (true);
+ return kTRUE;
+}
+//____________________________________________________________________
+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;
+}
+
#if 1
//____________________________________________________________________
Bool_t
// return kFALSE;
// }
// Get sample rate
- AliFMDParameters* pars = AliFMDParameters::Instance();
- AliFMDRawStream input(fReader);
+ AliFMDParameters* pars = AliFMDParameters::Instance();
+ AliFMDAltroMapping* map = pars->GetAltroMap();
+ AliFMDRawStream input(fReader);
AliFMDDebug(5, ("Setting 7 word headers"));
input.SetShortDataHeader(!pars->HasCompleteHeader());
UShort_t stripMin = 0;
UShort_t stripMax = 0; // 127;
UShort_t preSamp = 0; // 14+5;
-
+
+ Int_t oldddl = -1;
UInt_t ddl = 0;
- UInt_t rate = 0;
+ // UInt_t rate = 0;
UInt_t last = 0;
UInt_t hwaddr = 0;
// Data array is approx twice the size needed.
UShort_t data[2048];
+ for (size_t i = 0; i < 2048; i++) data[i] = 0; // kUShortMax;
Bool_t isGood = kTRUE;
while (isGood) {
isGood = input.ReadChannel(ddl, hwaddr, last, data);
// if (!isGood) break;
- if (ddl >= UInt_t(-1)) {
+ if (ddl >= UINT_MAX /* UInt_t(-1) */) {
AliFMDDebug(5, ("At end of event with %d digits",
array->GetEntriesFast()));
break;
}
+ if (UInt_t(oldddl) != ddl) {
+ fZeroSuppress[ddl] = input.GetZeroSupp();
+ AliFMDDebug(20, ("RCU @ DDL %d zero suppression: %s",
+ ddl, (fZeroSuppress[ddl] ? "yes" : "no")));
- AliFMDDebug(5, ("Read channel 0x%x of size %d", hwaddr, last));
+ // WARNING: We store the noise factor in the 2nd baseline
+ // filters excluded post samples, since we'll never use that
+ // mode.
+ fNoiseFactor[ddl] = input.GetNPostsamples();
+ AliFMDDebug(20, ("RCU @ DDL %d noise factor: %d", ddl,fNoiseFactor[ddl]));
+ // WARNING: We store the noise factor in the 2nd baseline
+ // filters excluded post samples, since we'll never use that
+ // mode.
+ fSampleRate[ddl] = input.GetNPretriggerSamples();
+ AliFMDDebug(20, ("RCU @ DDL %d Sample rate: %d", ddl,fNoiseFactor[ddl]));
+
+ Int_t nChAddrMismatch = input.GetNChAddrMismatch();
+ Int_t nChLenMismatch = input.GetNChLengthMismatch();
+ if (nChAddrMismatch != 0)
+ AliWarning(Form("Got %d channels with address mis-matches for 0x%03x",
+ nChAddrMismatch, hwaddr));
+ if (nChLenMismatch != 0)
+ AliWarning(Form("Got %d channels with length mis-matches for 0x%03x",
+ nChLenMismatch, hwaddr));
+ oldddl = ddl;
+ }
+ // AliFMDDebug(5, ("Read channel 0x%x of size %d", hwaddr, last));
+
+ UShort_t det, sec, samp, board, chip, channel;
+ Short_t strbase;
+ Char_t ring;
+
+ if (map->DDL2Detector(ddl) < 0) break;
+ det = map->DDL2Detector(ddl);
+ map->ChannelAddress(hwaddr, board, chip, channel);
+ if (!map->Channel2StripBase(board, chip, channel, ring, sec, strbase)) {
+ AliError(Form("Failed to get detector id from DDL %d, "
+ "hardware address 0x%03x", ddl, hwaddr));
+ continue;
+ }
+ AliFMDDebug(5, ("Board: 0x%02x, Altro: 0x%x, Channel: 0x%x, Length: %4d",
+ board, chip, channel, last));
+
+ stripMin = pars->GetMinStrip(det, ring, sec, strbase);
+ stripMax = pars->GetMaxStrip(det, ring, sec, strbase);
+ preSamp = pars->GetPreSamples(det, ring, sec, strbase);
+ if (fSampleRate[ddl] == 0)
+ fSampleRate[ddl] = pars->GetSampleRate(det, ring, sec, strbase);
// Loop over the `timebins', and make the digits
for (size_t i = 0; i < last; i++) {
// if (i < preSamp) continue;
+ AliFMDDebug(15, ("0x%04x/0x%03x/%04d %4d", ddl, hwaddr, i, data[i]));
- UShort_t det, sec, samp;
- Short_t str;
- Char_t ring;
- if (!pars->Hardware2Detector(ddl, hwaddr, i, det, ring, sec, str, samp)) {
- AliError(Form("Failed to get detector id from DDL %d, "
- "hardware address 0x%03x, timebin %d", ddl, hwaddr, i));
- continue;
- }
+ Short_t stroff = 0;
+ map->Timebin2Strip(sec, i, preSamp, fSampleRate[ddl], stroff, samp);
+ Short_t str = strbase + stroff;
+
AliFMDDebug(10, ("0x%04x/0x%03x/%04d maps to FMD%d%c[%2d,%3d]-%d",
ddl, hwaddr, i, det, ring, sec, str, samp));
if (str < 0) {
AliFMDDebug(8, ("Got presamples at timebin %d", i));
+ data[i] = 0; // Reset cache
continue;
}
- stripMin = pars->GetMinStrip(det, ring, sec, str);
- stripMax = pars->GetMaxStrip(det, ring, sec, str);
- preSamp = pars->GetPreSamples(det, ring, sec, str);
- rate = pars->GetSampleRate(det, ring, sec, str);
- Short_t lstrip = (i - preSamp) / rate + stripMin;
+ Short_t lstrip = (i - preSamp) / fSampleRate[ddl] + stripMin;
AliFMDDebug(15, ("Checking if strip %d (%d) in range [%d,%d]",
lstrip, str, stripMin, stripMax));
if (lstrip < stripMin || lstrip > stripMax) {
AliFMDDebug(5, ("FMD%d%c[%02d,%03d]-%d out of range (%3d->%3d)",
det, ring, sec, samp, str, stripMin, stripMax));
+ data[i] = 0; // Reset cache
continue;
}
+ // Possibly do pedestal subtraction of signal
+ Int_t counts = data[i];
+
// Check the cache of indicies
Int_t idx = fSeen(det, ring, sec, str);
det, ring, sec, str, samp, i));
new ((*array)[idx]) AliFMDDigit(det, ring, sec, str);
}
- AliFMDDigit* digit = static_cast<AliFMDDigit*>(array->At(idx));
+ AliFMDBaseDigit* digit = static_cast<AliFMDBaseDigit*>(array->At(idx));
AliFMDDebug(10,
- ("Setting from FMD%d%c[%2d,%3d]-%d from timebin %4d = %4d",
- det, ring, sec, str, samp, i, data[i]));
- digit->SetCount(samp, data[i]);
+ ("Setting FMD%d%c[%2d,%3d]-%d from timebin %4d=%4d (%4d)",
+ det, ring, sec, str, samp, i, counts, data[i]));
+ digit->SetCount(samp, counts);
+ data[i] = 0; // Reset cache
}
}
return kTRUE;
UInt_t strip_high[18];
UInt_t pulse_size[18];
UInt_t pulse_length[18];
- AliFMDParameters* param = AliFMDParameters::Instance();
+ AliFMDParameters* param = AliFMDParameters::Instance();
+ AliFMDAltroMapping* map = param->GetAltroMap();
while(fReader->ReadNextData(fData)) {
if(ddl==0 && (i==1 || i==3)) continue;
UInt_t chip =0, channel=0;
- param->Hardware2Detector(ddl,boards[i],chip,channel,
- det,ring,sector,strip);
+ det = map->DDL2Detector(ddl);
+ map->Channel2StripBase(boards[i], chip, channel, ring, sector, strip);
UInt_t samplerate = 1;
if(sample_clk[boards[i]] == 0) {
AliFMDDebug(0, ("End of SOD/EOD"));
-
+ return kTRUE;
}
//____________________________________________________________________