X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=FMD%2FAliFMDRawWriter.cxx;h=623e872ee24b08cee293049289fac104a1c21261;hb=2d2b680b3ff2b6c96d861f8b60b75ab10cace8e0;hp=9b3cbadfca011a059f316a1b06fadce219c38788;hpb=c2fc12580f7bb903a1f061ae3d60882098e8a988;p=u%2Fmrichter%2FAliRoot.git diff --git a/FMD/AliFMDRawWriter.cxx b/FMD/AliFMDRawWriter.cxx index 9b3cbadfca0..623e872ee24 100644 --- a/FMD/AliFMDRawWriter.cxx +++ b/FMD/AliFMDRawWriter.cxx @@ -36,9 +36,10 @@ // ALTRO format. See the Exec member function for more information on // that format. // -#include // ALILOG_H +// #include // ALILOG_H +#include "AliFMDDebug.h" // Better debug macros #include // ALILOADER_H -#include // ALIALTROBUFFER_H +#include // ALIALTROBUFFER_H #include "AliFMD.h" // ALIFMD_H #include "AliFMDParameters.h" // ALIFMDPARAMETERS_H #include "AliFMDDigit.h" // ALIFMDDIGIT_H @@ -46,8 +47,11 @@ #include "AliFMDAltroMapping.h" // ALIFMDALTROMAPPING_H // #include "AliFMDAltroIO.h" // ALIFMDALTROWRITER_H #include // ROOT_TArrayI +#include // ROOT_TArrayI +#include // ROOT_TArrayI #include // ROOT_TClonesArray -#include +// #include +#include "AliDAQ.h" //____________________________________________________________________ ClassImp(AliFMDRawWriter) @@ -58,8 +62,15 @@ ClassImp(AliFMDRawWriter) //____________________________________________________________________ AliFMDRawWriter::AliFMDRawWriter(AliFMD* fmd) : TTask("FMDRawWriter", "Writer of Raw ADC values from the FMD"), - fFMD(fmd) -{} + fFMD(fmd), + fSampleRate(0), + fChannelsPerAltro(0), + fThreshold(0) +{ + // CTOR + AliFMDDebug(5, ("Created AliFMDRawWriter object")); +} + //____________________________________________________________________ @@ -122,23 +133,25 @@ AliFMDRawWriter::Exec(Option_t*) // Note, that this method assumes that the digits are ordered. // AliLoader* loader = fFMD->GetLoader(); - loader->LoadDigits(); + loader->LoadDigits("READ"); TTree* digitTree = loader->TreeD(); if (!digitTree) { - Error("Digits2Raw", "no digit tree"); + AliError("no digit tree"); return; } - TClonesArray* digits = new TClonesArray("AliFMDDigit", 1000); fFMD->SetTreeAddress(); - TBranch* digitBranch = digitTree->GetBranch(fFMD->GetName()); - if (!digitBranch) { - Error("Digits2Raw", "no branch for %s", fFMD->GetName()); - return; - } - digitBranch->SetAddress(&digits); + TClonesArray* digits = fFMD->Digits(); + // new TClonesArray("AliFMDDigit", 1000); + // TBranch* digitBranch = digitTree->GetBranch(fFMD->GetName()); + // if (!digitBranch) { + // AliError(Form("no branch for %s", fFMD->GetName())); + // return; + // } + // digitBranch->SetAddress(&digits); Int_t nEvents = Int_t(digitTree->GetEntries()); + AliFMDDebug(5, ("Got a total of %5d events from tree", nEvents)); for (Int_t event = 0; event < nEvents; event++) { fFMD->ResetDigits(); digitTree->GetEvent(event); @@ -147,112 +160,222 @@ AliFMDRawWriter::Exec(Option_t*) WriteDigits(digits); } loader->UnloadDigits(); + //delete digits; } #if 1 //____________________________________________________________________ -void +Long_t AliFMDRawWriter::WriteDigits(TClonesArray* digits) { + // WRite an array of digits to disk file Int_t nDigits = digits->GetEntries(); - if (nDigits < 1) return; + if (nDigits < 1) return 0; + AliFMDDebug(5, ("Got a total of %5d digits from tree", nDigits)); AliFMDParameters* pars = AliFMDParameters::Instance(); UShort_t threshold = 0; - UInt_t prevddl = 0; + UInt_t prevddl = 0xFFFF; UInt_t prevaddr = 0xFFF; // UShort_t prevStrip = 0; // Which channel number in the ALTRO channel we're at UShort_t nWords = 0; UShort_t preSamples = 0; - - // How many times the ALTRO Samples one VA1_ALICE channel - Int_t sampleRate = 1; + UShort_t sampleRate = 0; // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' TArrayI data(pars->GetChannelsPerAltro() * 8); + TArrayF peds(pars->GetChannelsPerAltro() * 8); + TArrayF noise(pars->GetChannelsPerAltro() * 8); // The Altro buffer - AliAltroBuffer* altro = 0; - + AliAltroBufferV3* altro = 0; + + Int_t totalWords = 0; + Int_t nCounts = 0; + Long_t nBits = 0; + // Loop over the digits in the event. Note, that we assume the // the digits are in order in the branch. If they were not, we'd // have to cache all channels before we could write the data to // the ALTRO buffer, or we'd have to set up a map of the digits. + UShort_t oldDet = 1000; for (Int_t i = 0; i < nDigits; i++) { // Get the digit AliFMDDigit* digit = static_cast(digits->At(i)); - UShort_t det = digit->Detector(); Char_t ring = digit->Ring(); UShort_t sector = digit->Sector(); UShort_t strip = digit->Strip(); - UInt_t ddl; - UInt_t addr; - threshold = pars->GetZeroSuppression(det, ring, sector, strip); - if (!pars->Detector2Hardware(det, ring, sector, strip, ddl, addr)) { - AliError(Form("Failed to get hardware address for FMD%d%c[%2d,%3d]", - det, ring, sector, strip)); - continue; - } - if (addr != prevaddr) { - // Flush a channel to output - AliDebug(15, Form("Now hardware address 0x%x from FMD%d%c[%2d,%3d] " - "(board 0x%x, chip 0x%x, channel 0x%x), flushing old " - "channel at 0x%x with %d words", - addr, det, ring, sector, strip, - (addr >> 7), (addr >> 4) & 0x7, addr & 0xf, - prevaddr, nWords)); - if (altro) altro->WriteChannel(prevaddr,nWords,data.fArray,threshold); - nWords = preSamples; - prevaddr = addr; - for (size_t i = 0; i < nWords; i++) data[i] = digit->Count(0); + UShort_t ddl, addr, time; + + AliFMDDebug(15, ("Processing digit # %5d FMD%d%c[%2d,%3d]", + i, det, ring, sector, strip)); + threshold = pars->GetZeroSuppression(det, ring, sector, strip); + sampleRate = pars->GetSampleRate(det, ring, sector, strip); + preSamples = pars->GetPreSamples(det, ring, sector, strip); + + if (det != oldDet) { + AliFMDDebug(5, ("Got new detector: %d (was %d)", det, oldDet)); + oldDet = det; } - if (ddl != prevddl) { - AliDebug(15, Form("FMD: New DDL, was %d, now %d", prevddl, ddl)); - // If an altro exists, delete the object, flushing the data to - // disk, and closing the file. - if (altro) { - // When the first argument is false, we write the real - // header. - AliDebug(15, Form("Closing output")); - altro->Flush(); - altro->WriteDataHeader(kFALSE, kFALSE); - delete altro; - altro = 0; + AliFMDDebug(15, ("Sample rate is %d", sampleRate)); + + for (UShort_t j = 0; j < sampleRate; j++) { + if (!pars->Detector2Hardware(det,ring,sector,strip,j,ddl,addr,time)){ + AliError(Form("Failed to get hardware address for FMD%d%c[%2d,%3d]-%d", + det, ring, sector, strip, j)); + continue; } - prevddl = ddl; - // Need to open a new DDL! - TString filename(Form("%s_%d.ddl", fFMD->GetName(), ddl)); - AliDebug(15, Form("New altro buffer with DDL file %s", filename.Data())); - // Create a new altro buffer - a `1' as the second argument - // means `write mode' - altro = new AliAltroBuffer(filename.Data(), 1); - altro->SetMapping(pars->GetAltroMap()); - // Write a dummy (first argument is true) header to the DDL - // file - later on, when we close the file, we write the real - // header - altro->WriteDataHeader(kTRUE, kFALSE); - } - // Store the counts of the ADC in the channel buffer - sampleRate = pars->GetSampleRate(det, ring, sector, strip); - for (int s = 0; s < sampleRate; s++) { - data[nWords] = digit->Count(s); + AliFMDDebug(10, ("FMD%d%c[%2d,%3d]-%d-> 0x%x/0x%x/%04d", + det, ring, sector, strip, j, ddl, addr, time)); + if (addr != prevaddr) { + // Flush a channel to output + AliFMDDebug(5, ("Now hardware address 0x%x from FMD%d%c[%2d,%3d]-%d" + "(b: 0x%02x, a: 0x%01x, c: 0x%02x, t: %04d), " + "flushing old channel at 0x%x with %d words", + addr, det, ring, sector, strip, j, + (addr >> 7), (addr >> 4) & 0x7, addr & 0xf, + time, prevaddr, nWords)); + totalWords += nWords; + ZeroSuppress(data.fArray, nWords, peds.fArray, noise.fArray, threshold); + if (altro) + /*nBits+=*/altro->WriteChannel(prevaddr,nWords,data.fArray,threshold); + data.Reset(-1); + peds.Reset(0); + noise.Reset(0); + nWords = 0; + prevaddr = addr; + } + if (ddl != prevddl) { + AliFMDDebug(10, ("FMD: New DDL, was %d, now %d", prevddl, ddl)); + // If an altro exists, delete the object, flushing the data to + // disk, and closing the file. + if (altro) { + // When the first argument is false, we write the real + // header. + AliFMDDebug(15, ("Closing output")); + /* nBits += */ altro->Flush(); + /* nBits += */ altro->WriteDataHeader(kFALSE, kFALSE); + delete altro; + altro = 0; + } + prevddl = ddl; + // Need to open a new DDL! + TString filename(AliDAQ::DdlFileName(fFMD ? fFMD->GetName() : "FMD", ddl)); + AliFMDDebug(5, ("New altro buffer with DDL file %s", filename.Data())); + // Create a new altro buffer - a `1' as the second argument + // means `write mode' + altro = new AliAltroBufferV3(filename.Data()); + altro->SetMapping(pars->GetAltroMap()); + // Write a dummy (first argument is true) header to the DDL + // file - later on, when we close the file, we write the real + // header + altro->WriteDataHeader(kTRUE, kFALSE); + } + + // Get the pedestal value + peds[time] = pars->GetPedestal(det, ring, sector, strip); + noise[time] = pars->GetPedestalWidth(det, ring, sector, strip); + + // Store the counts of the ADC in the channel buffer + AliFMDDebug(15, ("Storing FMD%d%c[%02d,%03d]-%d in timebin %d (%d)", + det, ring, sector, strip, j, time, preSamples)); + data[time] = digit->Count(j); nWords++; + nCounts++; + if (time == preSamples) { + AliFMDDebug(15, ("Filling in %4d for %d presamples", + data[time], preSamples)); + for (int k = 0; k < preSamples; k++) { + peds[k] = peds[time]; + noise[k] = noise[time]; + data[k] = data[time]; + } + nWords += preSamples; + } } } // Finally, we need to close the final ALTRO buffer if it wasn't // already if (altro) { - if (nWords > 0) altro->WriteChannel(prevaddr,nWords,data.fArray,threshold); - altro->Flush(); - altro->WriteDataHeader(kFALSE, kFALSE); + ZeroSuppress(data.fArray, nWords, peds.fArray, noise.fArray, threshold); + if (nWords > 0) + /* nBits += */ altro->WriteChannel(prevaddr,nWords,data.fArray,threshold); + /* nBits += */ altro->Flush(); + /* nBits += */ altro->WriteDataHeader(kFALSE, kFALSE); delete altro; } + AliFMDDebug(5, ("Wrote a total of %d words in %ld bytes for %d counts", + nWords, nBits / 8, nCounts)); + return nBits; +} +//____________________________________________________________________ +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; + } } + #else //____________________________________________________________________ void @@ -281,11 +404,11 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) det, ring, sector, strip)); continue; } - AliDebug(40, Form("Got DDL=%d and address=%d from FMD%d%c[%2d,%3d]", + AliFMDDebug(40, ("Got DDL=%d and address=%d from FMD%d%c[%2d,%3d]", thisDDL, thisHwaddr, det, ring, sector, strip)); // Check if we're still in the same channel if (thisHwaddr != hwaddr) { - AliDebug(30, Form("Now hardware address 0x%x from FMD%d%c[%2d,%3d] " + AliFMDDebug(30, ("Now hardware address 0x%x from FMD%d%c[%2d,%3d] " "(board 0x%x, chip 0x%x, channel 0x%x)", thisHwaddr, det, ring, sector, strip, (thisHwaddr >> 7), (thisHwaddr >> 4) & 0x7, @@ -296,7 +419,7 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) // Check if we're still in the same detector (DDL) if (ddl != thisDDL) { if (writer) { - AliDebug(1, Form("Closing altro writer %p", writer)); + AliFMDDebug(1, ("Closing altro writer %p", writer)); if ((ret = writer->Close()) < 0) { AliError(Form("Error: %s", writer->ErrorString(ret))); return; @@ -312,10 +435,12 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) // If we haven't got a writer (either because none were made so // far, or because we've switch DDL), make one. if (!writer) { - AliDebug(1, Form("Opening new ALTRO writer w/file FMD_%d.ddl", ddl)); - file = new std::ofstream(Form("FMD_%d.ddl", ddl)); + AliFMDDebug(1, ("Opening new ALTRO writer w/file %s", + AliDAQ::DdlFileName("FMD",ddl))); + file = new std::ofstream(AliDAQ::DdlFileName("FMD",ddl)); if (!file || !*file) { - AliFatal(Form("Failed to open file FMD_%d.ddl", ddl)); + AliFatal(Form("Failed to open file %s", + AliDAQ::DdlFileName("FMD",ddl))); return; } writer = new AliFMDAltroWriter(*file); @@ -344,3 +469,4 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) // // EOF // +