+//____________________________________________________________________
+void
+AliFMDRawWriter::WriteRCUTrailer(AliAltroBufferV3* altro,
+ UInt_t ddl,
+ Bool_t zs,
+ UShort_t factor,
+ UShort_t rate) const
+{
+ // Flush and write the data header
+ altro->Flush();
+ altro->WriteDataHeader(kFALSE, kFALSE);
+
+ // Set parameters in RCU trailer.
+ // Zero-suppression flag
+ altro->SetZeroSupp(zs); // bool
+ // WARNING: We store the noise factor in the 2nd baseline
+ // filters excluded post samples, since we'll never use that
+ // mode.
+ altro->SetNPostsamples(factor); //
+ // WARNING: We store the sample rate in the number of pre-trigger
+ // samples, since we'll never use that mode.
+ altro->SetNPretriggerSamples(rate); // fSampleRate[ddl]
+ // Active front-end cars
+ altro->SetActiveFECsA((ddl == 0 ? 0x1 : 0x3));
+ altro->SetActiveFECsB((ddl == 0 ? 0x1 : 0x3));
+
+ // Calculate number of samples
+ altro->SetNSamplesPerCh(rate * 128);
+ AliDebug(5,Form("Writing RCU trailer @ DDL %d w/zs=%d, factor=%d, rate=%d",
+ ddl, zs > 0, factor, rate));
+ altro->WriteRCUTrailer(ddl);
+}
+
+//____________________________________________________________________
+void
+AliFMDRawWriter::ZeroSuppress(Int_t*& data, Int_t nWords,
+ const Float_t* peds,
+ const Float_t* noise, UShort_t threshold) const
+{
+ // Simulate the ALTRO zero-suppression filter. The data passed in
+ // the first array is modified, such that all suppressed channels
+ // are set to some value below threshold.
+ //
+ // If threshold == 0 zero suppression is considered disabled, and no
+ // action is taken.
+ if (threshold <= 0) return;
+
+ // const Short_t width = 3;
+ // If fPedSubtract is false, compare data-(ped+f*noise), if true
+ // always modify data by -(ped+f*noise), and force negative values
+ // to zero.
+ Bool_t pedSubtract = AliFMDParameters::Instance()->IsZSPedSubtract();
+ UShort_t pre = AliFMDParameters::Instance()->GetZSPreSamples();
+ UShort_t post = AliFMDParameters::Instance()->GetZSPostSamples();
+ Float_t factor = AliFMDParameters::Instance()->GetPedestalFactor();
+
+ TArrayC mask(nWords+1);
+ for (Short_t i = 0; i < nWords; i++) {
+ Float_t val = data[i] - peds[i] - factor * noise[i];
+ if (val < 0.5) val = 0;
+ if (pedSubtract) data[i] = Int_t(val) & 0x3FF;
+
+ mask[i] = (val > threshold ? 1 : 0);
+ AliFMDDebug(10, ("Comparing sample %d %d-%f-%f*%f=%f to %d -> %s",
+ i, data[i], peds[i], factor, noise[i], val, threshold,
+ (mask[i] ? "above" : "below")));
+ }
+
+ for (Short_t i = 0; i < nWords; i++) {
+ if (mask[i]) { // Signal above, so do nothing
+ AliFMDDebug(10, ("Sample %d, above", i));
+ if (i < nWords-1 && !mask[i+1]) {
+ // After a valid sample. Increase the pointer to the next
+ // possible data, thereby skipping over the post-samples
+ AliFMDDebug(10, ("At sample %d, next is below, skipping %d to %d",
+ i, post, i+post));
+ i += post;
+ }
+ continue;
+ }
+
+ Short_t lookahead = TMath::Min(Short_t(nWords), Short_t(i+pre));
+ AliFMDDebug(10, ("Sample %d, below, look to %d", i, lookahead));
+ if (mask[lookahead] && pre > 0) {
+ AliFMDDebug(10, ("Sample %d is a pre-sample to %d", i, lookahead));
+ // We're in a presample, so don't modify the data, and increase
+ // counter by the number of pre-samples
+ i += pre-1;
+ continue;
+ }
+
+ // This sample must be surpressed
+ data[i] = threshold - 1;
+ }
+}
+