From 1e8f773ec10afa84ca5d4a654a27b44759f36097 Mon Sep 17 00:00:00 2001 From: cholm Date: Tue, 21 Mar 2006 12:58:10 +0000 Subject: [PATCH] New RAW I/O. I rolled my own, because I wasn't happy with the old implementation, and things were missing. The new implementation can actually be used in any setting, and is much more flexible. Some other fixes for various small things, and new macros to make fake alignment data, etc. --- FMD/AliFMDAlignFaker.cxx | 42 ++-- FMD/AliFMDAlignFaker.h | 2 +- FMD/AliFMDAltroIO.cxx | 454 +++++++++++++++++++++++++++++++++++ FMD/AliFMDAltroIO.h | 233 ++++++++++++++++++ FMD/AliFMDAltroMapping.cxx | 15 +- FMD/AliFMDAltroMapping.h | 2 +- FMD/AliFMDCalibFaker.cxx | 1 + FMD/AliFMDDigitizer.cxx | 1 + FMD/AliFMDDisplay.cxx | 20 +- FMD/AliFMDDisplay.h | 4 +- FMD/AliFMDInput.cxx | 22 ++ FMD/AliFMDParameters.cxx | 157 +++++++++--- FMD/AliFMDParameters.h | 6 + FMD/AliFMDRawReader.cxx | 94 +++++++- FMD/AliFMDRawStream.cxx | 173 ++++++++++++- FMD/AliFMDRawStream.h | 21 +- FMD/AliFMDRawWriter.cxx | 330 ++++++++++++++++--------- FMD/AliFMDRawWriter.h | 3 +- FMD/AliFMDReconstructor.cxx | 4 +- FMD/FMDbaseLinkDef.h | 3 + FMD/Reconstruct.C | 6 +- FMD/Simulate.C | 29 ++- FMD/libFMDbase.pkg | 1 + FMD/scripts/ApplyAlignment.C | 41 ++++ FMD/scripts/Convert2Raw.C | 26 ++ FMD/scripts/DisplayHits.C | 2 + FMD/scripts/MakeAlignment.C | 25 ++ FMD/scripts/RawTest.C | 2 +- FMD/scripts/ShowRaw.C | 9 +- FMD/scripts/TestHWMap.C | 17 +- FMD/scripts/TestRawIO.C | 33 +++ 31 files changed, 1542 insertions(+), 236 deletions(-) create mode 100644 FMD/AliFMDAltroIO.cxx create mode 100644 FMD/AliFMDAltroIO.h create mode 100644 FMD/scripts/ApplyAlignment.C create mode 100644 FMD/scripts/Convert2Raw.C create mode 100644 FMD/scripts/MakeAlignment.C create mode 100644 FMD/scripts/TestRawIO.C diff --git a/FMD/AliFMDAlignFaker.cxx b/FMD/AliFMDAlignFaker.cxx index 97931d79ec9..ec63bfcb29b 100644 --- a/FMD/AliFMDAlignFaker.cxx +++ b/FMD/AliFMDAlignFaker.cxx @@ -42,6 +42,7 @@ #include #include #include +#include //==================================================================== ClassImp(AliFMDAlignFaker) @@ -141,24 +142,26 @@ AliFMDAlignFaker::Exec(Option_t*) // Loop over all entries in geometry to find our nodes. while ((node = static_cast(next()))) { const char* name = node->GetName(); - if (IS_NODE_HALF(name) && TESTBIT(fMask, kHalves) || - IS_NODE_SENSOR(name) && TESTBIT(fMask, kSensors)) { - // Get the path - TString path(Form("/%s", gGeoManager->GetNode(0)->GetName())); - Int_t nLevel = next.GetLevel(); - for (Int_t lvl = 0; lvl <= nLevel; lvl++) { - TGeoNode* p = next.GetNode(lvl); - if (!p && lvl != 0) { - AliWarning(Form("No node at level %d in path %s", lvl, path.Data())); - continue; - } - if (!path.IsNull()) path.Append("/"); - path.Append(p->GetName()); + if (!(IS_NODE_HALF(name) && TESTBIT(fMask, kHalves)) && + !(IS_NODE_SENSOR(name) && TESTBIT(fMask, kSensors))) + continue; + + // Get the path + TString path(Form("/%s", gGeoManager->GetNode(0)->GetName())); + Int_t nLevel = next.GetLevel(); + for (Int_t lvl = 0; lvl <= nLevel; lvl++) { + TGeoNode* p = next.GetNode(lvl); + if (!p) { + if (lvl != 0) + AliWarning(Form("No node at level %d in path %s",lvl,path.Data())); + continue; } - Int_t id = node->GetVolume()->GetNumber(); - if (IS_NODE_HALF(name)) MakeAlignHalf(path, id); - if (IS_NODE_SENSOR(name)) MakeAlignSensor(path, id); + if (!path.IsNull()) path.Append("/"); + path.Append(p->GetName()); } + Int_t id = node->GetVolume()->GetNumber(); + if (IS_NODE_HALF(name)) MakeAlignHalf(path, id); + if (IS_NODE_SENSOR(name)) MakeAlignSensor(path, id); } TString t(GetTitle()); @@ -174,7 +177,8 @@ AliFMDAlignFaker::MakeAlign(const TString& path, Int_t id, Double_t transX, Double_t transY, Double_t transZ, Double_t rotX, Double_t rotY, Double_t rotZ) { - AliDebug(1, Form("Make alignment for %s (volume %d)", path.Data(), id)); + AliDebug(1, Form("Make alignment for %s (volume %d): (%f,%f,%f) (%f,%f,%f)", + path.Data(), id, transX, transY, transZ, rotX, rotY, rotZ)); Int_t nAlign = fArray->GetEntries(); AliAlignObjAngles* obj = new ((*fArray)[nAlign]) AliAlignObjAngles(path.Data(), id,0,0,0,0,0,0); @@ -193,7 +197,7 @@ AliFMDAlignFaker::MakeAlign(const TString& path, Int_t id, Bool_t AliFMDAlignFaker::MakeAlignHalf(const TString& path, Int_t id) { - AliDebug(1, Form("Make alignment for half-ring/cone %s", path.Data())); + AliDebug(15, Form("Make alignment for half-ring/cone %s", path.Data())); Double_t transX = gRandom->Uniform(fHalfTransMin.X(), fHalfTransMax.X()); Double_t transY = gRandom->Uniform(fHalfTransMin.Y(), fHalfTransMax.Y()); Double_t transZ = gRandom->Uniform(fHalfTransMin.Z(), fHalfTransMax.Z()); @@ -208,7 +212,7 @@ AliFMDAlignFaker::MakeAlignHalf(const TString& path, Int_t id) Bool_t AliFMDAlignFaker::MakeAlignSensor(const TString& path, Int_t id) { - AliDebug(1, Form("Make alignment for sensor %s", path.Data())); + AliDebug(15, Form("Make alignment for sensor %s", path.Data())); Double_t transX = gRandom->Uniform(fSensorTransMin.X(), fSensorTransMax.X()); Double_t transY = gRandom->Uniform(fSensorTransMin.Y(), fSensorTransMax.Y()); Double_t transZ = gRandom->Uniform(fSensorTransMin.Z(), fSensorTransMax.Z()); diff --git a/FMD/AliFMDAlignFaker.h b/FMD/AliFMDAlignFaker.h index 13e09d5c915..dfd1ea00ba3 100644 --- a/FMD/AliFMDAlignFaker.h +++ b/FMD/AliFMDAlignFaker.h @@ -36,7 +36,7 @@ public: const char* loc="local://cdb"); virtual ~AliFMDAlignFaker() {} void AddAlign(EWhat w) { SETBIT(fMask, w); } - void RemoveAlign(EWhat w) { SETBIT(fMask, w); } + void RemoveAlign(EWhat w) { CLRBIT(fMask, w); } void SetAlign(Int_t mask) { fMask = mask; } void SetSensorDisplacement(Double_t x1=0, Double_t y1=0, Double_t z1=0, Double_t x2=.01, Double_t y2=.01, Double_t z2=0); diff --git a/FMD/AliFMDAltroIO.cxx b/FMD/AliFMDAltroIO.cxx new file mode 100644 index 00000000000..3d7b68a3fe5 --- /dev/null +++ b/FMD/AliFMDAltroIO.cxx @@ -0,0 +1,454 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* $Id$ */ + +//____________________________________________________________________ +// +// Mapping of ALTRO hardware channel to detector coordinates +// +#include "AliFMDAltroIO.h" +#include +#include +#include "AliLog.h" +#include +#include +#define PRETTY_HEX(N,X) \ + " 0x" << std::setfill('0') << std::setw(N) << std::hex << X \ + << std::setfill(' ') << std::dec + +//==================================================================== +ClassImp(AliFMDAltroIO) +#if 0 + ; // This is here to keep Emacs for indenting the next line +#endif + +//____________________________________________________________________ +const AliFMDAltroIO::W40_t AliFMDAltroIO::fgkTrailerMask = +((AliFMDAltroIO::W40_t(0x2aaa) << 26) + (AliFMDAltroIO::W40_t(0xa) << 12)); + +//____________________________________________________________________ +AliFMDAltroIO::AliFMDAltroIO() + : fBuffer(0), fIBuffer(0) +{} + +//____________________________________________________________________ +const char* +AliFMDAltroIO::ErrorString(Int_t err) const +{ + switch (err) { + case kNoError: return "No error"; break; + case kBadFile: return "Bad state after open/close file"; break; + case kBadBits: return "Bad bit offset specified"; break; + case kBadRead: return "Bad state after reading from file"; break; + case kBadWrite: return "Bad state after writing to file"; break; + case kBadSeek: return "Bad state after seeking in file"; break; + case kBadTell: return "Could not tell position in file"; break; + case kBadTrailer: return "Bad trailer 40 bit word in file"; break; + case kBadFill: return "Bad fill word in file"; break; + } + return "Unknown"; +} + + +//____________________________________________________________________ +AliFMDAltroIO::W40_t +AliFMDAltroIO::ConcatW40(size_t n, const W10_t& w) const +{ + if (n > 3) return -kBadBits; + return W40_t(w & 0x3ff) << (10 * n); +} + +//____________________________________________________________________ +AliFMDAltroIO::W10_t +AliFMDAltroIO::ExtractW10(size_t n, const W40_t w) const +{ + if (n > 3) return -kBadBits; + return (w >> (10 * n)) & 0x3ff; +} + +//==================================================================== +ClassImp(AliFMDAltroReader) +#if 0 + ; // This is here to keep Emacs for indenting the next line +#endif + +//____________________________________________________________________ +AliFMDAltroReader::AliFMDAltroReader(std::istream& stream) + : fInput(stream) + // : fBuffer(buffer), fCurrent(n / 10 * sizeof(char)) +{ + // fInput.open(filename); + if (!fInput) throw -kBadFile; + fBegin = fInput.tellg(); + if (fInput.bad()) throw -kBadTell; + fInput.seekg(0, std::ios_base::end); + if (fInput.bad()) throw -kBadSeek; + fCurrent = fInput.tellg(); + if (fInput.bad()) throw -kBadTell; +#if 0 + fInput.seekg(fBegin); + size_t i = 0; + do { + W40_t w = 0; + fInput.read((char*)&w, 5); + std::cout << std::setw(6) << i << ": " << PRETTY_HEX(10, w) << std::endl; + i++; + } while (!fInput.eof()); + fInput.seekg(fCurrent); +#endif +} + +//____________________________________________________________________ +Int_t +AliFMDAltroReader::ReadChannel(UShort_t& board, UShort_t& chip, + UShort_t& channel, UShort_t& last, + UShort_t* data) +{ + UShort_t hwaddr; + Int_t ret = ReadChannel(hwaddr, last, data); + board = (hwaddr >> 7) & 0x1f; + chip = (hwaddr >> 4) & 0x3; + channel = hwaddr & 0xf; + return ret; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroReader::ReadChannel(UShort_t& hwaddr, UShort_t& last, + UShort_t* data) +{ + Int_t ret, tmp; + AliDebug(15, Form("Reading a channel")); + if ((ret = ExtractTrailer(hwaddr, last)) < 0) { + AliError(Form("Failed to read trailer: %s", ErrorString(-ret))); + return ret; + } + AliDebug(15, Form("Now extracting bunches from %d 10 bit words", last)); + tmp = ExtractBunches(last, data); + if (tmp < 0) { + AliError(Form("Failed to read bunches: %s", ErrorString(-tmp))); + return tmp; + } + ret += tmp; + last = (last == 0 ? 0 : last - 2); + return ret; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroReader::ExtractTrailer(UShort_t& hwaddr, UShort_t& last) +{ + AliDebug(15, "Extracting trailer"); + W40_t trailer = GetNextW40(); + if (trailer < 0) { + AliError(Form("Trailer 0x%x is bad: %s", trailer, ErrorString(-trailer))); + return trailer; + } + if (!IsTrailer(trailer)) { + AliError(Form("Bad trailer: 0x%08x", trailer)); + return -kBadTrailer; + } + last = (trailer >> 16) & 0x3ff; + hwaddr = (trailer & 0xfff); + return 4; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroReader::ExtractBunches(UShort_t last, UShort_t* data) +{ + Int_t ret; + if ((ret = ExtractFillWords(last)) < 0) { + AliError(Form("Failed to read fill words: %s", ErrorString(-ret))); + return ret; + } + while (last > 0) { + Int_t tmp = ExtractBunch(data); + if (tmp <= 0) { + AliError(Form("Failed to extract bunch at %d: %s", + last, ErrorString(-tmp))); + return tmp; + } + ret += tmp; + last -= tmp; + } + return ret; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroReader::ExtractFillWords(UShort_t last) +{ + // Number of fill words + size_t nFill = (last % 4 == 0 ? 0 : 4 - last % 4); + // Read the fill words + for (size_t i = 3; i >= 4 - nFill; i--) { + W10_t f = GetNextW10(); + if (f != 0x2aa) return -kBadFill; + } + return nFill; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroReader::ExtractBunch(UShort_t* data) +{ + Int_t ret = 0; + W10_t l = GetNextW10(); + if (l < 0) { + AliError(Form("Failed to read bunch length: %s", ErrorString(-l))); + return l; + } + W10_t t = GetNextW10(); + if (t < 0) { + AliError(Form("Failed to read bunch time: %s", ErrorString(-t))); + return t; + } + ret += 2; + for (Int_t i = 2; i < l; i++) { + W10_t s = GetNextW10(); + if (s < 0) { + AliError(Form("Failed to read bunch data: %s", ErrorString(-s))); + return 2; + } + AliDebug(50,Form("Assigning to data[%d - (%d - 1)] = 0x%X", t, i, s)); + data[t - (i-1)] = s; + ret++; + } + return ret; +} + +//____________________________________________________________________ +Bool_t +AliFMDAltroReader::IsTrailer(W40_t x) +{ + return ((x & fgkTrailerMask) == fgkTrailerMask); +} + +//____________________________________________________________________ +Bool_t +AliFMDAltroReader::IsBof() +{ + return fCurrent == fBegin; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroReader::ReadW40() +{ + fInput.seekg(fCurrent-std::istream::pos_type(5)); + if (fInput.bad()) return -kBadSeek; + fCurrent = fInput.tellg(); + if (fInput.bad()) return -kBadTell; + fInput.read((char*)&fBuffer, 5 * sizeof(char)); + if (fInput.bad()) return -kBadRead; + fIBuffer = 4; + AliDebug(15, Form(" 0x%03x 0x%03x 0x%03x 0x%03x 0x%010x %6d", + ExtractW10(3, fBuffer), ExtractW10(2, fBuffer), + ExtractW10(1, fBuffer), ExtractW10(0, fBuffer), + fBuffer, fCurrent)); + return fCurrent; +} + +//____________________________________________________________________ +AliFMDAltroIO::W10_t +AliFMDAltroReader::GetNextW10() +{ + if (fIBuffer <= 0) { + Int_t ret; + if ((ret = ReadW40()) < 0) return ret; + } + fIBuffer--; + W10_t w10 = ExtractW10(fIBuffer, fBuffer); + return w10; +} + +//____________________________________________________________________ +AliFMDAltroIO::W40_t +AliFMDAltroReader::GetNextW40() +{ + W40_t w40 = 0; + for (Int_t i = 3; i >= 0; i--) { + W10_t tmp = GetNextW10(); + W40_t bits = ConcatW40(i, tmp); + if (bits < 0) return bits; + w40 += bits; + } + return w40; +} + +//==================================================================== +ClassImp(AliFMDAltroWriter) +#if 0 + ; // This is here to keep Emacs for indenting the next line +#endif + +//____________________________________________________________________ +AliFMDAltroWriter::AliFMDAltroWriter(std::ostream& stream) + : fThreshold(0), fTotal(0), fOutput(stream) +{ + AliDebug(15, "New AliFMDAltroWriter object"); + fTime = 0; + fLength = 0; + fLast = 0; + // Write a dummy header + fHeader = fOutput.tellp(); + if (fOutput.bad()) throw -kBadTell; + AliRawDataHeader header; + fOutput.write((char*)(&header), sizeof(header)); + if (fOutput.bad()) throw -kBadWrite; + fBegin = fOutput.tellp(); + if (fOutput.bad()) throw -kBadTell; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::Flush() +{ + if (fIBuffer == 0) return 0; + fOutput.write((char*)&fBuffer, 5 * sizeof(char)); + if (fOutput.bad()) return -kBadWrite; + // for (size_t i = 0; i < 4; i++) + // std::cout << "\t" << PRETTY_HEX(3, ExtractW10(i, fBuffer)); + // std::cout << "\t" << PRETTY_HEX(10, fBuffer) << std::endl; + fTotal += 5; + fIBuffer = 0; + fBuffer = 0; + return 5; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::Close() +{ + Flush(); + std::ostream::pos_type end = fOutput.tellp(); + if (fOutput.bad()) return -kBadTell; + fOutput.seekp(fHeader, std::ios_base::beg); + if (fOutput.bad()) return -kBadSeek; + AliRawDataHeader header; + header.fSize = (size_t(end) - fHeader); + AliDebug(15, Form("Size set to %d (%d)", header.fSize, fTotal)); + header.SetAttribute(0); + fOutput.write((char*)(&header), sizeof(header)); + if (fOutput.bad()) return -kBadWrite; + fOutput.seekp(end); + if (fOutput.bad()) return -kBadSeek; + return sizeof(header); +} + + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::AddSignal(UShort_t adc) +{ + Int_t ret = 0; + if (adc < fThreshold) + ret = AddBunchTrailer(); + else { + ret = AddToBuffer(adc); + fLength++; + } + fTime++; + if (ret < 0) AliError(Form("Failed to add signal %x: %s", ErrorString(ret))); + return ret; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::AddChannelTrailer(UShort_t board, UShort_t chip, + UShort_t channel) +{ + UInt_t hwaddr = (channel & 0xf)+((chip & 0x3) << 4)+((board & 0x1f) << 7); + return AddChannelTrailer(hwaddr); +} + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::AddChannelTrailer(UInt_t hwaddr) +{ + Int_t ret =0, tmp; + if ((tmp = AddBunchTrailer()) < 0) { + AliError(Form("Failed to bad bunch trailer: %s", ErrorString(tmp))); + return tmp; + } + ret += tmp; + if ((tmp = AddFillWords()) < 0) { + AliError(Form("Failed to bad fill words: %s", ErrorString(tmp))); + return tmp; + } + ret += tmp; + W40_t trailer = (fgkTrailerMask + hwaddr + ((fLast & 0x3ff) << 16)); + fBuffer = trailer; + fIBuffer = 3; + ret += 4; + if ((tmp = Flush()) < 0) { + AliError(Form("Failed to flush: %s", ErrorString(tmp))); + return tmp; + } + ret += tmp; + fTime = 0; + fLast = 0; + return ret; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::AddToBuffer(UShort_t x) +{ + W40_t tmp = ConcatW40(fIBuffer, x); + if (tmp < 0) return tmp; + fBuffer += tmp; + fIBuffer++; + fLast++; + Int_t ret = 0; + if (fIBuffer > 3 && (ret = Flush() < 0)) return ret; + return 1; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::AddBunchTrailer() +{ + if (fLength <= 0) return 0; + Int_t ret = 0, tmp; + if ((tmp = AddToBuffer(fTime)) < 0) return tmp; + ret += tmp; + if ((tmp = AddToBuffer(fLength+2)) < 0) return tmp; + ret += tmp; + fLength = 0; + return ret; +} + +//____________________________________________________________________ +Int_t +AliFMDAltroWriter::AddFillWords() +{ + Int_t ret = 0, tmp; + if (fIBuffer == 0) return ret; + for (Int_t i = fIBuffer; i < 4; i++) { + if ((tmp = AddToBuffer(0x2aa)) < 0) return tmp; + ret += tmp; + fLast--; + } + if ((tmp = Flush() < 0)) return tmp; + return ret; +} + +//_____________________________________________________________________________ +// +// EOF +// diff --git a/FMD/AliFMDAltroIO.h b/FMD/AliFMDAltroIO.h new file mode 100644 index 00000000000..bd579283b88 --- /dev/null +++ b/FMD/AliFMDAltroIO.h @@ -0,0 +1,233 @@ +#ifndef ALIFMDALTROIO_H +#define ALIFMDALTROIO_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights + * reserved. + * + * Latest changes by Christian Holm Christensen + * + * See cxx source for full Copyright notice + */ +#include +#include + +//____________________________________________________________________ +class AliFMDAltroIO : public TObject +{ + public: + /** Type of 40 bit words (signed) */ + typedef long long W40_t; + /** Type of 10 bit words (signed) */ + typedef Int_t W10_t; + /** Constructor */ + AliFMDAltroIO(); + /** Destructor */ + virtual ~AliFMDAltroIO() {} + /** Error states */ + enum { + /** No error */ + kNoError, + /** Bad state after open/close file */ + kBadFile, + /** Bad bit offset specified */ + kBadBits, + /** Bad state after reading from file */ + kBadRead, + /** Bad state after writing to file */ + kBadWrite, + /** Bad state after seeking in file */ + kBadSeek, + /** Could not tell position in file */ + kBadTell, + /** Bad trailer 40 bit word in file */ + kBadTrailer, + /** Bad fill word in file */ + kBadFill + }; + /** Trailer mask */ + static const W40_t fgkTrailerMask; + /** Get error string */ + const char* ErrorString(Int_t err) const; +protected: + /** I/O Buffer */ + W40_t fBuffer; + /** Pointer into buffer */ + Int_t fIBuffer; + + /** Concatenate a 10 bit word into a 40 bit word. + @param n Offset (0-3) + @param w 10 bit word + @return @a w at offset @a n in a 40 bit word on success, a + negative error code on failure. */ + virtual W40_t ConcatW40(size_t n, const W10_t& w) const; + /** Extract a 10 bit word from a 40 bit word + @param n The number 10bit word to extract (0-3) + @param w 40 bit word to extract from. + @return The 10 bit word at @a n of @a w on success, or a + negative error code otherwise. */ + virtual W10_t ExtractW10(size_t n, const W40_t w) const; + + ClassDef(AliFMDAltroIO,0); +}; + +//____________________________________________________________________ +class AliFMDAltroReader : public AliFMDAltroIO +{ +public: + /** Constructor + @param filename File to read from + @exception Int_t A negative error code in case of failure */ + AliFMDAltroReader(std::istream& stream); + virtual ~AliFMDAltroReader() {} + /** Read one channel from the input file. Note, that channels are + read from the back of the file. + @param board On return, the FEC board number + @param chip On return, the ALTRO chip number + @param channel On return, the ALTRO channel number + @param last On return, the size of the data + @param data An array to fill with the data. note, this + should be large enough to hold all the data (1024 is the maximum + number of timebins that can be read, so that's a safe size). + @return negative error code on failure, 0 if nothing is read, or + the number of 10 bit words read. */ + Int_t ReadChannel(UShort_t& board, UShort_t& chip, UShort_t& channel, + UShort_t& last, UShort_t* data); + /** Read one channel from the input file. Note, that channels are + read from the back of the file. + @param hwaddr On return, the hardware address + @param last On return, the size of the data + @param data An array to fill with the data. note, this + should be large enough to hold all the data (1024 is the maximum + number of timebins that can be read, so that's a safe size). + @return negative error code on failure, 0 if nothing is read, or + the number of 10 bit words read. */ + Int_t ReadChannel(UShort_t& hwaddr, UShort_t& last, UShort_t* data); + /** Extract the channel trailer. + @param hwaddr On return, the hardware address + @param last On return, the size of the data + @return negative error code on failure, 0 if nothing is read, or + the number of 10 bit words read. */ + Int_t ExtractTrailer(UShort_t& hwaddr, UShort_t& last); + /** Extract bunches from data section of a channel. + @param last Pointer to last meaning full data entry. + @param data An array to fill with the read data. + @return negative error code on failure, otherwise number of 10 + bit words read. */ + Int_t ExtractBunches(UShort_t last, UShort_t* data); + /** Extract possible fill words. + @param last Pointer to last meaning full data entry. + @return Negative error code on failure, otherwise number of fill + words read. */ + Int_t ExtractFillWords(UShort_t last); + /** Extract bunch information from data. + @param data An array to fill with the read data. + @return negative error code on failure, otherwise number of 10 + bit words read. */ + Int_t ExtractBunch(UShort_t* data); + /** Check if @a x is a valid trailer + @param x 40 bit word to check. + @return @c true if @a x is a valid trailer */ + Bool_t IsTrailer(W40_t x); + /** @return @c true if we're at the beginning of the file */ + Bool_t IsBof(); +protected: + /** Input stream */ + std::istream& fInput; + /** Current position in file */ + // std::istream::pos_type + size_t fCurrent; + /** High water mark */ + size_t fBegin; + + /** Read a 40 bit word from the input. + @return negative error code on failure, current position otherwise. */ + virtual Int_t ReadW40(); + /** Get a 10 bit word from the (buffered) input. + @return 10 bit word on success, negative error code on failure. */ + virtual W10_t GetNextW10(); + /** Get the next 40 bit word from the (buffered) input. + @return The 40 bit word, or negative error code on failure */ + virtual W40_t GetNextW40(); + + ClassDef(AliFMDAltroReader,0); +}; + +//____________________________________________________________________ +class AliFMDAltroWriter : public AliFMDAltroIO +{ +public: + /** Constructor. + @param filename File to read from + @exception Int_t A negative error code in case of failure */ + AliFMDAltroWriter(std::ostream& stream); + virtual ~AliFMDAltroWriter() {} + /** @param threshold Zero-suppresion threshold */ + void SetThreshold(UShort_t threshold) { fThreshold = threshold; } + /** Close the output, by writing the appropriate header. The actual + stream should be called by the user. + @return number of bytes written, or negative error code on failure */ + Int_t Close(); + /** Flush buffered output to file (if there is any). + @return 0, or negative error code on failure */ + Int_t Flush(); + /** Add a signal to output. If the signal @a adc is less then the + current threshold, a new bunch trailer is written. + @param adc Signal + @return 0 on success, or negative error code on failure */ + Int_t AddSignal(UShort_t adc); + /** Write a channel trailer to output. + @param board The FEC board number (0-31) + @param chip The ALTRO chip number (0-7) + @param channel The ALTRO channel number (0-16) + @return Number of 10 bit words written, or negative error code + on failure */ + Int_t AddChannelTrailer(UShort_t board, UShort_t chip, UShort_t channel); + /** Write a channel trailer to output. + @param hwaddr Hardware address (channel address) + @return Number of 10 bit words written, or negative error code + on failure */ + Int_t AddChannelTrailer(UInt_t hwaddr); +protected: + /** Add a value to output buffer. + @param x Value to add. + @return number of 10 bit words written to disk, or negative + error code on failure */ + Int_t AddToBuffer(UShort_t x); + /** Add a bunch trailer to output. + @return number of 10 bit words written to disk, or negative + error code on failure */ + Int_t AddBunchTrailer(); + /** Add fill words as needed to output + @return number of 10 bit words written to disk, or negative + error code on failure */ + Int_t AddFillWords(); + /** Zero suppression threshold */ + UShort_t fThreshold; + /** Current time */ + UShort_t fTime; + /** Current bunch length */ + UShort_t fLength; + /** Last meaning-full data */ + UShort_t fLast; + /** High-water mark (begining of file) */ + size_t fBegin; + /** High-water mark (begining of file) */ + size_t fHeader; + /** Total number of bytes written */ + Long_t fTotal; + /** output stream */ + std::ostream& fOutput; + + ClassDef(AliFMDAltroWriter,0); +}; + + + +#endif +//____________________________________________________________________ +// +// Local Variables: +// mode: C++ +// End: +// +// EOF +// diff --git a/FMD/AliFMDAltroMapping.cxx b/FMD/AliFMDAltroMapping.cxx index d948d5ee863..cbdf971e65a 100644 --- a/FMD/AliFMDAltroMapping.cxx +++ b/FMD/AliFMDAltroMapping.cxx @@ -31,7 +31,6 @@ ClassImp(AliFMDAltroMapping) //_____________________________________________________________________________ AliFMDAltroMapping::AliFMDAltroMapping() - : AliAltroMapping(0) {} @@ -239,16 +238,16 @@ AliFMDAltroMapping::Detector2Hardware(UShort_t det, Char_t ring, UInt_t ncs = (ring == 'I' ? 8 : 4); // Channels per sensor UInt_t bbase = (ring == 'I' ? 0 : 2); UInt_t board = bbase + sec / nsen; - UInt_t lsen = (sec - (board - bbase) * nsen); - UInt_t altro = (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 1 : 2)); - UInt_t sbase = (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 2*nsa : 3*nsa)); - UInt_t chan = (sec % 2) + (lsen-sbase) / 2 * ncs + 2 * str / 128; + UInt_t lsec = (sec - (board - bbase) * nsen); // Local sec in half-ring + UInt_t altro = (lsec < 2 * nsa ? 0 : (lsec < 3 * nsa ? 1 : 2)); + UInt_t sbase = (altro == 0 ? 0 : altro == 1 ? 2 * nsa : 3 * nsa); + UInt_t chan = (sec % 2) + (lsec-sbase) / 2 * ncs + 2 * (str / 128); AliDebug(40, Form("\n" " chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n" " = %d + %d + %d = %d", - sec, lsen, sbase, 2, ncs, str, - (sec % 2), (lsen - sbase) / 2 * ncs, - 2 * str / 128, chan)); + sec, lsec, sbase, 2, ncs, str, + (sec % 2), (lsec - sbase) / 2 * ncs, + 2 * (str / 128), chan)); addr = chan + (altro << 4) + (board << 7); return kTRUE; diff --git a/FMD/AliFMDAltroMapping.h b/FMD/AliFMDAltroMapping.h index 769efd11dd8..0ad1ddf0d29 100644 --- a/FMD/AliFMDAltroMapping.h +++ b/FMD/AliFMDAltroMapping.h @@ -29,7 +29,7 @@ public: UInt_t& ddl, UInt_t& hwaddr) const; Int_t GetHWAdress(Int_t sector, Int_t str, Int_t ring) const { - return GetHWAdress(sector, str, ring); + return GetHWAddress(sector, str, ring); } Int_t GetHWAddress(Int_t sector, Int_t str, Int_t ring) const; Int_t GetPadRow(Int_t hwaddr) const; diff --git a/FMD/AliFMDCalibFaker.cxx b/FMD/AliFMDCalibFaker.cxx index 9c87aef9b81..3296e5b5711 100644 --- a/FMD/AliFMDCalibFaker.cxx +++ b/FMD/AliFMDCalibFaker.cxx @@ -37,6 +37,7 @@ #include #include #include +#include #include //==================================================================== diff --git a/FMD/AliFMDDigitizer.cxx b/FMD/AliFMDDigitizer.cxx index f175c2d7cd4..64f491855ea 100644 --- a/FMD/AliFMDDigitizer.cxx +++ b/FMD/AliFMDDigitizer.cxx @@ -261,6 +261,7 @@ Bool_t AliFMDBaseDigitizer::Init() { // Initialization + AliFMDParameters::Instance()->Init(); return kTRUE; } diff --git a/FMD/AliFMDDisplay.cxx b/FMD/AliFMDDisplay.cxx index 68953c5f00a..9a804a0e904 100644 --- a/FMD/AliFMDDisplay.cxx +++ b/FMD/AliFMDDisplay.cxx @@ -82,10 +82,10 @@ AliFMDDisplay::AliFMDDisplay(const char* gAliceFile) } //____________________________________________________________________ -void +void AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py) { - AliInfo(Form("Event %d, at (%d,%d)", px, py)); + // AliInfo(Form("Event %d, at (%d,%d)", px, py)); if (px == 0 && py == 0) return; if (!fZoomMode && fPad->GetView()) { fPad->GetView()->ExecuteRotateView(event, px, py); @@ -125,10 +125,10 @@ AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py) } //____________________________________________________________________ -Int_t -AliFMDDisplay::DistanceToPrimitive(Int_t px, Int_t py) +Int_t +AliFMDDisplay::DistancetoPrimitive(Int_t px, Int_t) { - AliInfo(Form("@ (%d,%d)", px, py)); + // AliInfo(Form("@ (%d,%d)", px, py)); fPad->SetCursor(kCross); Float_t xmin = fPad->GetX1(); Float_t xmax = fPad->GetX2(); @@ -200,12 +200,14 @@ AliFMDDisplay::End() { fPad->cd(); fMarkers->Draw(); + fPad->cd(); AppendPad(); - fPad->Update(); + // fPad->Update(); fPad->cd(); - fCanvas->Modified(kTRUE); - fCanvas->Update(); - fCanvas->cd(); + // fCanvas->Modified(kTRUE); + //fCanvas->Update(); + // fCanvas->cd(); + // fPad->cd(); fWait = kTRUE; while (fWait) { gApplication->StartIdleing(); diff --git a/FMD/AliFMDDisplay.h b/FMD/AliFMDDisplay.h index 04ff8e142dc..1d2af934bc5 100644 --- a/FMD/AliFMDDisplay.h +++ b/FMD/AliFMDDisplay.h @@ -31,8 +31,8 @@ public: void Zoom() { fZoomMode = kTRUE; } void Pick() { fZoomMode = kFALSE; } void ExecuteEvent(Int_t event, Int_t px, Int_t py); - Int_t DistanceToPrimitive(Int_t px, Int_t py); - + Int_t DistancetoPrimitive(Int_t px, Int_t py); + void Paint(Option_t* option="") { (void)option; } virtual Bool_t Init(); virtual Bool_t Begin(Int_t event); diff --git a/FMD/AliFMDInput.cxx b/FMD/AliFMDInput.cxx index c22fb594838..ce675161993 100644 --- a/FMD/AliFMDInput.cxx +++ b/FMD/AliFMDInput.cxx @@ -37,6 +37,9 @@ #include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H #include #include +#include +#include +#include #include // ROOT_TTree #include // ROOT_TChain #include // ROOT_TParticle @@ -195,6 +198,25 @@ AliFMDInput::Init() Fatal("Init", "No geometry manager found"); return kFALSE; } + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBEntry* align = cdb->Get("FMD/Align/Data"); + if (align) { + AliInfo("Got alignment data from CDB"); + TClonesArray* array = dynamic_cast(align->GetObject()); + if (!array) { + AliWarning("Invalid align data from CDB"); + } + else { + Int_t nAlign = array->GetEntries(); + for (Int_t i = 0; i < nAlign; i++) { + AliAlignObjAngles* a = static_cast(array->At(i)); + if (!a->ApplyToGeometry()) { + AliWarning(Form("Failed to apply alignment to %s", + a->GetVolPath())); + } + } + } + } } diff --git a/FMD/AliFMDParameters.cxx b/FMD/AliFMDParameters.cxx index e90e295032e..d7bff74ef9e 100644 --- a/FMD/AliFMDParameters.cxx +++ b/FMD/AliFMDParameters.cxx @@ -95,58 +95,117 @@ AliFMDParameters::Init() // Initialize the parameters manager. We need to get stuff from the // CDB here. if (fIsInit) return; + InitPulseGain(); + InitPedestal(); + InitDeadMap(); + InitSampleRate(); + InitZeroSuppression(); + InitAltroMap(); + fIsInit = kTRUE; +} +//__________________________________________________________________ +void +AliFMDParameters::InitPulseGain() +{ AliCDBManager* cdb = AliCDBManager::Instance(); AliCDBEntry* gain = cdb->Get(fgkPulseGain); - AliCDBEntry* pedestal = cdb->Get(fgkPedestal); - AliCDBEntry* deadMap = cdb->Get(fgkDead); - AliCDBEntry* zeroSup = cdb->Get(fgkZeroSuppression); - AliCDBEntry* sampRat = cdb->Get(fgkSampleRate); - AliCDBEntry* hwMap = cdb->Get(fgkAltroMap); + if (!gain) { + AliWarning(Form("No %s found in CDB, perhaps you need to " + "use AliFMDCalibFaker?", fgkPulseGain)); + return; + } - if (gain) { - AliDebug(1, Form("Got gain from CDB")); - fPulseGain = dynamic_cast(gain->GetObject()); - if (!fPulseGain) - AliWarning("Invalid pulser gain object from CDB"); + AliDebug(1, Form("Got gain from CDB")); + fPulseGain = dynamic_cast(gain->GetObject()); + if (!fPulseGain) AliWarning("Invalid pulser gain object from CDB"); +} +//__________________________________________________________________ +void +AliFMDParameters::InitPedestal() +{ + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBEntry* pedestal = cdb->Get(fgkPedestal); + if (!pedestal) { + AliWarning(Form("No %s found in CDB, perhaps you need to " + "use AliFMDCalibFaker?", fgkPedestal)); + return; } - if (pedestal) { - AliDebug(1, Form("Got pedestal from CDB")); - fPedestal = dynamic_cast(pedestal->GetObject()); - if (!fPedestal) - AliWarning("Invalid pedestal object from CDB"); + AliDebug(1, Form("Got pedestal from CDB")); + fPedestal = dynamic_cast(pedestal->GetObject()); + if (!fPedestal) AliWarning("Invalid pedestal object from CDB"); +} + +//__________________________________________________________________ +void +AliFMDParameters::InitDeadMap() +{ + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBEntry* deadMap = cdb->Get(fgkDead); + if (!deadMap) { + AliWarning(Form("No %s found in CDB, perhaps you need to " + "use AliFMDCalibFaker?", fgkDead)); + return; } - if (deadMap) { - AliDebug(1, Form("Got dead map from CDB")); - fDeadMap = dynamic_cast(deadMap->GetObject()); - if (!fDeadMap) - AliWarning("Invalid dead map object from CDB"); + AliDebug(1, Form("Got dead map from CDB")); + fDeadMap = dynamic_cast(deadMap->GetObject()); + if (!fDeadMap) AliWarning("Invalid dead map object from CDB"); +} + +//__________________________________________________________________ +void +AliFMDParameters::InitZeroSuppression() +{ + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBEntry* zeroSup = cdb->Get(fgkZeroSuppression); + if (!zeroSup) { + AliWarning(Form("No %s found in CDB, perhaps you need to " + "use AliFMDCalibFaker?", fgkZeroSuppression)); + return; } - if (zeroSup) { - AliDebug(1, Form("Got zero suppression from CDB")); - fZeroSuppression = - dynamic_cast(zeroSup->GetObject()); - if (!fZeroSuppression) - AliWarning("Invalid zero suppression object from CDB"); + AliDebug(1, Form("Got zero suppression from CDB")); + fZeroSuppression = + dynamic_cast(zeroSup->GetObject()); + if (!fZeroSuppression)AliWarning("Invalid zero suppression object from CDB"); +} + +//__________________________________________________________________ +void +AliFMDParameters::InitSampleRate() +{ + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBEntry* sampRat = cdb->Get(fgkSampleRate); + if (!sampRat) { + AliWarning(Form("No %s found in CDB, perhaps you need to " + "use AliFMDCalibFaker?", fgkSampleRate)); + return; } - if (sampRat) { - AliDebug(1, Form("Got zero suppression from CDB")); - fSampleRate = - dynamic_cast(sampRat->GetObject()); - if (!fSampleRate) - AliWarning("Invalid zero suppression object from CDB"); + AliDebug(1, Form("Got zero suppression from CDB")); + fSampleRate = dynamic_cast(sampRat->GetObject()); + if (!fSampleRate) AliWarning("Invalid zero suppression object from CDB"); +} + +//__________________________________________________________________ +void +AliFMDParameters::InitAltroMap() +{ + AliCDBManager* cdb = AliCDBManager::Instance(); + AliCDBEntry* hwMap = cdb->Get(fgkAltroMap); + if (!hwMap) { + AliWarning(Form("No %s found in CDB, perhaps you need to " + "use AliFMDCalibFaker?", fgkAltroMap)); + fAltroMap = new AliFMDAltroMapping; + return; } - if (hwMap) { - AliDebug(1, Form("Got ALTRO map from CDB")); - fAltroMap = dynamic_cast(hwMap->GetObject()); - if (!fAltroMap) - AliWarning("Invalid ALTRO map object from CDB"); + AliDebug(1, Form("Got ALTRO map from CDB")); + fAltroMap = dynamic_cast(hwMap->GetObject()); + if (!fAltroMap) { + AliWarning("Invalid ALTRO map object from CDB"); + fAltroMap = new AliFMDAltroMapping; } - if (!fAltroMap) fAltroMap = new AliFMDAltroMapping; - - fIsInit = kTRUE; } + //__________________________________________________________________ Float_t AliFMDParameters::GetThreshold() const @@ -174,6 +233,9 @@ AliFMDParameters::GetPulseGain(UShort_t detector, Char_t ring, fFixedPulseGain = fVA1MipRange * GetEdepMip() / fAltroChannelSize; return fFixedPulseGain; } + AliDebug(50, Form("pulse gain for FMD%d%c[%2d,%3d]=%f", + detector, ring, sector, strip, + fPulseGain->Value(detector, ring, sector, strip))); return fPulseGain->Value(detector, ring, sector, strip); } @@ -183,6 +245,10 @@ AliFMDParameters::IsDead(UShort_t detector, Char_t ring, UShort_t sector, UShort_t strip) const { if (!fDeadMap) return kFALSE; + AliDebug(50, Form("Dead for FMD%d%c[%2d,%3d]=%s", + detector, ring, sector, strip, + fDeadMap->operator()(detector, ring, sector, strip) ? + "no" : "yes")); return fDeadMap->operator()(detector, ring, sector, strip); } @@ -193,6 +259,10 @@ AliFMDParameters::GetZeroSuppression(UShort_t detector, Char_t ring, { if (!fZeroSuppression) return fFixedZeroSuppression; // Need to map strip to ALTRO chip. + AliDebug(50, Form("zero sup. for FMD%d%c[%2d,%3d]=%f", + detector, ring, sector, strip, + fZeroSuppression->operator()(detector, ring, + sector, strip))); return fZeroSuppression->operator()(detector, ring, sector, strip/128); } @@ -202,6 +272,7 @@ AliFMDParameters::GetSampleRate(UShort_t ddl) const { if (!fSampleRate) return fFixedSampleRate; // Need to map sector to digitizier card. + AliDebug(50, Form("Sample rate for %d=%d", ddl, fSampleRate->Rate(ddl))); return fSampleRate->Rate(ddl); } @@ -211,6 +282,9 @@ AliFMDParameters::GetPedestal(UShort_t detector, Char_t ring, UShort_t sector, UShort_t strip) const { if (!fPedestal) return fFixedPedestal; + AliDebug(50, Form("pedestal for FMD%d%c[%2d,%3d]=%f", + detector, ring, sector, strip, + fPedestal->Value(detector, ring, sector, strip))); return fPedestal->Value(detector, ring, sector, strip); } @@ -220,6 +294,9 @@ AliFMDParameters::GetPedestalWidth(UShort_t detector, Char_t ring, UShort_t sector, UShort_t strip) const { if (!fPedestal) return fFixedPedestalWidth; + AliDebug(50, Form("pedetal width for FMD%d%c[%2d,%3d]=%f", + detector, ring, sector, strip, + fPedestal->Width(detector, ring, sector, strip))); return fPedestal->Width(detector, ring, sector, strip); } diff --git a/FMD/AliFMDParameters.h b/FMD/AliFMDParameters.h index a809842d193..94ee0dd2bf7 100644 --- a/FMD/AliFMDParameters.h +++ b/FMD/AliFMDParameters.h @@ -102,6 +102,12 @@ protected: AliFMDParameters(); virtual ~AliFMDParameters() {} static AliFMDParameters* fgInstance; // Static singleton instance + void InitPulseGain(); + void InitPedestal(); + void InitDeadMap(); + void InitSampleRate(); + void InitZeroSuppression(); + void InitAltroMap(); Bool_t fIsInit; // Whether we've been initialised diff --git a/FMD/AliFMDRawReader.cxx b/FMD/AliFMDRawReader.cxx index 043f74db138..96fee2fb4c9 100644 --- a/FMD/AliFMDRawReader.cxx +++ b/FMD/AliFMDRawReader.cxx @@ -48,9 +48,16 @@ #include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H #include "AliRawReader.h" // ALIRAWREADER_H #include "AliFMDRawReader.h" // ALIFMDRAWREADER_H +#include "AliFMDAltroIO.h" // ALIFMDALTROIO_H #include // ROOT_TArrayI #include // ROOT_TTree #include // ROOT_TClonesArray +#include +#include +#include +#define PRETTY_HEX(N,X) \ + " 0x" << std::setfill('0') << std::setw(N) << std::hex << X \ + << std::setfill(' ') << std::dec //____________________________________________________________________ ClassImp(AliFMDRawReader) @@ -69,6 +76,82 @@ AliFMDRawReader::AliFMDRawReader(AliRawReader* reader, TTree* tree) } +//____________________________________________________________________ +void +AliFMDRawReader::Exec(Option_t*) +{ + // Read raw data into the digits array, using AliFMDAltroReader. + if (!fReader->ReadHeader()) { + Error("ReadAdcs", "Couldn't read header"); + return; + } + + TClonesArray* array = new TClonesArray("AliFMDDigit"); + fTree->Branch("FMD", &array); + + // Get sample rate + AliFMDParameters* pars = AliFMDParameters::Instance(); + + // Select FMD DDL's + fReader->Select(AliFMDParameters::kBaseDDL>>8); + + UShort_t stripMin = 0; + UShort_t stripMax = 127; + UShort_t preSamp = 0; + + do { + UChar_t* cdata; + if (!fReader->ReadNextData(cdata)) break; + size_t nchar = fReader->GetDataSize(); + UShort_t ddl = AliFMDParameters::kBaseDDL + fReader->GetDDLID(); + UShort_t rate = pars->GetSampleRate(ddl); + AliDebug(1, Form("Reading %d bytes (%d 10bit words) from %d", + nchar, nchar * 8 / 10, ddl)); + // Make a stream to read from + std::string str((char*)(cdata), nchar); + std::istringstream s(str); + // Prep the reader class. + AliFMDAltroReader r(s); + // Data array is approx twice the size needed. + UShort_t data[2048], hwaddr, last; + while (r.ReadChannel(hwaddr, last, data) > 0) { + AliDebug(5, Form("Read channel 0x%x of size %d", hwaddr, last)); + UShort_t det, sec, str; + Char_t ring; + if (!pars->Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) { + AliError(Form("Failed to detector id from DDL %d " + "and hardware address 0x%x", ddl, hwaddr)); + continue; + } + AliDebug(5, Form("DDL 0x%04x, address 0x%03x maps to FMD%d%c[%2d,%3d]", + ddl, hwaddr, det, ring, sec, str)); + + // Loop over the `timebins', and make the digits + for (size_t i = 0; i < last; i++) { + if (i < preSamp) continue; + Int_t n = array->GetEntries(); + UShort_t curStr = str + stripMin + i / rate; + if ((curStr-str) > stripMax) { + AliError(Form("Current strip is %d but DB says max is %d", + curStr, stripMax)); + } + AliDebug(5, Form("making digit for FMD%d%c[%2d,%3d] from sample %4d", + det, ring, sec, curStr, i)); + new ((*array)[n]) AliFMDDigit(det, ring, sec, curStr, data[i], + (rate >= 2 ? data[i+1] : 0), + (rate >= 3 ? data[i+2] : 0)); + if (rate >= 2) i++; + if (rate >= 3) i++; + } + if (r.IsBof()) break; + } + } while (true); + AliDebug(1, Form("Got a grand total of %d digits", array->GetEntries())); +} + +#if 0 +// This is the old method, for comparison. It's really ugly, and far +// too convoluted. //____________________________________________________________________ void AliFMDRawReader::Exec(Option_t*) @@ -109,6 +192,7 @@ AliFMDRawReader::Exec(Option_t*) count++; Int_t ddl = fReader->GetDDLID(); + AliDebug(10, Form("Current DDL is %d", ddl)); if (ddl != oldDDL || input.IsNewStrip() || !next) { // Make a new digit, if we have some data (oldDetector == 0, // means that we haven't really read anything yet - that is, @@ -144,16 +228,15 @@ AliFMDRawReader::Exec(Option_t*) // If we got a new DDL, it means we have a new detector. if (ddl != oldDDL) { if (detector != 0) - AliDebug(10, Form("Read %d channels for FMD%d", - count + 1, detector)); + AliDebug(10, Form("Read %d channels for FMD%d", count + 1, detector)); // Reset counts, and update the DDL cache count = 0; oldDDL = ddl; // Check that we're processing a FMD detector Int_t detId = fReader->GetDetectorID(); if (detId != (AliFMDParameters::kBaseDDL >> 8)) { - Error("ReadAdcs", "Detector ID %d != %d", - detId, (AliFMDParameters::kBaseDDL >> 8)); + AliError(Form("Detector ID %d != %d", + detId, (AliFMDParameters::kBaseDDL >> 8))); break; } // Figure out what detector we're deling with @@ -163,7 +246,7 @@ AliFMDRawReader::Exec(Option_t*) case 1: detector = 2; break; case 2: detector = 3; break; default: - Error("ReadAdcs", "Unknown DDL 0x%x for FMD", ddl); + AliError(Form("Unknown DDL 0x%x for FMD", ddl)); return; } AliDebug(10, Form("Reading ADCs for 0x%x - That is FMD%d", @@ -183,6 +266,7 @@ AliFMDRawReader::Exec(Option_t*) return; } +#endif //____________________________________________________________________ // diff --git a/FMD/AliFMDRawStream.cxx b/FMD/AliFMDRawStream.cxx index 8cfcbfd225a..c33ad39286c 100644 --- a/FMD/AliFMDRawStream.cxx +++ b/FMD/AliFMDRawStream.cxx @@ -27,6 +27,9 @@ // #include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H #include // ALIRAWREADER_H +#include +#include +#include //____________________________________________________________________ ClassImp(AliFMDRawStream) @@ -39,11 +42,179 @@ AliFMDRawStream::AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate) : AliAltroRawStream(reader), fSampleRate(sampleRate), fPrevTime(-1), - fExplicitSampleRate(kFALSE) + fExplicitSampleRate(kFALSE), + fPos(0), + fCur(0), + fRead(0) { if (fSampleRate > 0) fExplicitSampleRate = kTRUE; } +//_____________________________________________________________________________ +Int_t +AliFMDRawStream::ReadTrailer(UInt_t& addr, UInt_t& len) +{ + if (fPos <= 0) return 0; + if (fPos < 4) { + AliError("could not read trailer"); + return -1; + } + AliDebug(1, Form("Reading a trailer at %d", fPos)); + Int_t temp = Get10BitWord(); + if (temp != 0x2AA) { + AliError(Form("Incorrect trailer! Expected 0x2AA but got %x!",temp)); + return -1; + } + temp = Get10BitWord(); + if ((temp >> 6) != 0xA) { + AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6)); + return -1; + } + + len = (temp << 4) & 0x3FF; + temp = Get10BitWord(); + len |= (temp >> 6); + if (((temp >> 2) & 0xF) != 0xA) { + AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6)); + return -1; + } + addr = (temp & 0x3) << 10; + temp = Get10BitWord(); + addr |= temp; + + return 4; +} + +//_____________________________________________________________________________ +Int_t +AliFMDRawStream::ReadFillWords(UInt_t len) +{ + if (len % 4 == 0) return 0; + Int_t nFill = (4 - (len % 4)) % 4; + AliDebug(1, Form("Reading %d fill words", nFill)); + for (Int_t i = 0; i < nFill; i++) { + UInt_t fill = Get10BitWord(); + if (fill != 0x2AA) { + AliError(Form("Invalid fill! Expected 0x2AA, but got %X!", fill)); + return -1; + } + } + return nFill; +} + +//_____________________________________________________________________________ +Int_t +AliFMDRawStream::ReadBunch(UShort_t* data) +{ + AliDebug(1, "Reading a bunch"); + if (fPos <= 0) { + AliError("could not read bunch length"); + return -1; + } + UShort_t len = Get10BitWord(); + if (fPos <= 0) { + AliError("could not read bunch length"); + return -1; + } + UShort_t time = Get10BitWord(); + + AliDebug(1, Form("Bunch is %d long and ends at t=%d", len, time)); + for (UInt_t i = 2; i < len; i++) { + Int_t amp = Get10BitWord(); + if (amp < 0) { + AliError(Form("Bad adc value (%X) !", amp)); + return -1; + } + data[time - (i-2)] = amp; + } + return len; +} + +//_____________________________________________________________________________ +Int_t +AliFMDRawStream::ReadIntoBuffer() +{ + if (fPos > 0) return kTRUE; + do { + AliDebug(1, Form("Reading into the buffer")); + if (!fRawReader->ReadNextData(fRead)) return -1; + } while (fRawReader->GetDataSize() == 0); + fPos = (fRawReader->GetDataSize() * 8) / 10; + // Skip trailing `0x2AA's - is this needed? Won't it break the + // trailer? +#if 0 + UShort_t skip; + while ((skip = Get10BitWord()) != 0x2AA) + AliDebug(1,Form("Skipping one %x", skip)); +#endif + fPos++; + return fPos; +} + +//_____________________________________________________________________________ +Bool_t +AliFMDRawStream::ReadChannel(UInt_t& addr, UInt_t& len, UShort_t* data) +{ + Int_t ret = 0; + AliDebug(1, "Reading a channel"); + if ((ret = ReadIntoBuffer()) < 0) return kFALSE; + if ((ret = ReadTrailer(addr, len)) < 0) return kFALSE; + if ((ret = ReadFillWords(len)) < 0) return kFALSE; + Int_t toRead = len; + while (toRead > 0) { + if ((ret = ReadBunch(data)) < 0) return kFALSE; + toRead -= ret; + } + len -= 2; + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t +AliFMDRawStream::DumpData() +{ + Int_t ret; + if ((ret = ReadIntoBuffer()) < 0) return kFALSE; + UShort_t data; + Int_t i = 0; + while ((data = Get10BitWord()) != 0xffff) { + if (i % 4 == 0) { + if (i != 0) std::cout << "\n"; + std::cout << std::setw(6) << i << ":"; + } + std::cout << " 0x" << std::setfill('0') << std::setw(3) + << std::hex << data << std::dec << std::setfill(' ') + << std::flush; + i++; + } + return kTRUE; +} + +//_____________________________________________________________________________ +UShort_t +AliFMDRawStream::Get10BitWord() +{ + // return a word in a 10 bit array as an UShort_t + --fPos; + if (fPos < 0) { + AliWarning("At high water mark"); + return 0xFFFF; + } + Int_t iBit = fPos * 10; + Int_t iByte = iBit / 8; + Int_t shift = iBit % 8; + // return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF; + + // recalculate the byte numbers and the shift because + // the raw data is written as integers where the high bits are filled first + // -> little endian is assumed here ! + Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4); + iByte++; + Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4); + shift = 6 - shift; + return ((fRead[iByteHigh] * 256 + fRead[iByteLow]) >> shift) & 0x03FF; +} + //_____________________________________________________________________________ Bool_t AliFMDRawStream::Next() diff --git a/FMD/AliFMDRawStream.h b/FMD/AliFMDRawStream.h index 1fd692f4d16..413874702cb 100644 --- a/FMD/AliFMDRawStream.h +++ b/FMD/AliFMDRawStream.h @@ -41,13 +41,22 @@ public: Short_t Count() const { return fSignal; } Short_t SampleRate() const { return fSampleRate; } - virtual Bool_t Next(); - -private: - UShort_t fSampleRate; // # of ALTRO samples per VA1_ALICE clock - Int_t fPrevTime; // Last time bin - Bool_t fExplicitSampleRate; // True if the sample rate was set externally + virtual Bool_t Next(); + virtual Bool_t ReadChannel(UInt_t& addr, UInt_t& len, UShort_t* data); + virtual Bool_t DumpData(); +protected: + virtual Int_t ReadIntoBuffer(); + virtual Int_t ReadTrailer(UInt_t& head, UInt_t& len); + virtual Int_t ReadFillWords(UInt_t len); + virtual Int_t ReadBunch(UShort_t* data); + virtual UShort_t Get10BitWord(); + UShort_t fSampleRate; // # of ALTRO samples per VA1_ALICE clock + Int_t fPrevTime; // Last time bin + Bool_t fExplicitSampleRate; // True if the sample rate was set externally + Int_t fPos; + Int_t fCur; + UChar_t* fRead; ClassDef(AliFMDRawStream, 0) // Read raw FMD Altro data }; diff --git a/FMD/AliFMDRawWriter.cxx b/FMD/AliFMDRawWriter.cxx index 649a17f99ad..fcb7d441e0e 100644 --- a/FMD/AliFMDRawWriter.cxx +++ b/FMD/AliFMDRawWriter.cxx @@ -40,8 +40,11 @@ #include "AliFMDParameters.h" // ALIFMDPARAMETERS_H #include "AliFMDDigit.h" // ALIFMDDIGIT_H #include "AliFMDRawWriter.h" // ALIFMDRAWREADER_H +#include "AliFMDAltroMapping.h" // ALIFMDALTROMAPPING_H +#include "AliFMDAltroIO.h" // ALIFMDALTROWRITER_H #include // ROOT_TArrayI #include // ROOT_TClonesArray +#include //____________________________________________________________________ ClassImp(AliFMDRawWriter) @@ -136,145 +139,238 @@ AliFMDRawWriter::Exec(Option_t*) } digitBranch->SetAddress(&digits); - AliFMDParameters* pars = AliFMDParameters::Instance(); Int_t nEvents = Int_t(digitTree->GetEntries()); for (Int_t event = 0; event < nEvents; event++) { fFMD->ResetDigits(); digitTree->GetEvent(event); - Int_t nDigits = digits->GetEntries(); - if (nDigits < 1) continue; + // Write out the digits + WriteDigits(digits); + } + loader->UnloadDigits(); +} +//____________________________________________________________________ +void +AliFMDRawWriter::WriteDigits(TClonesArray* digits) +{ + Int_t nDigits = digits->GetEntries(); + if (nDigits < 1) return; - UShort_t prevDetector = 0; - Char_t prevRing = '\0'; - UShort_t prevSector = 0; - // UShort_t prevStrip = 0; + AliFMDParameters* pars = AliFMDParameters::Instance(); + AliFMDAltroWriter* writer = 0; + Int_t sampleRate = -1; + UShort_t hwaddr = 0; + UShort_t ddl = 0; + std::ofstream* file = 0; + Int_t ret = 0; + for (Int_t i = 0; i < nDigits; i++) { + // Get the digit + AliFMDDigit* digit = static_cast(digits->At(i)); + UInt_t thisDDL, thisHwaddr; + UShort_t det = digit->Detector(); + Char_t ring = digit->Ring(); + UShort_t sector = digit->Sector(); + UShort_t strip = digit->Strip(); + if (!pars->Detector2Hardware(det,ring,sector,strip,thisDDL,thisHwaddr)) { + AliError(Form("Failed to get hardware address for FMD%d%c[%2d,%3d]", + det, ring, sector, strip)); + continue; + } + AliDebug(40, Form("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] " + "(board 0x%x, chip 0x%x, channel 0x%x)", + thisHwaddr, det, ring, sector, strip, + (thisHwaddr >> 7), (thisHwaddr >> 4) & 0x7, + thisHwaddr & 0xf)); + if (writer) writer->AddChannelTrailer(hwaddr); + hwaddr = thisHwaddr; + } + // Check if we're still in the same detector (DDL) + if (ddl != thisDDL) { + if (writer) { + AliDebug(1, Form("Closing altro writer %p", writer)); + if ((ret = writer->Close()) < 0) { + AliError(Form("Error: %s", writer->ErrorString(ret))); + return; + } + delete writer; + writer = 0; + file->close(); + delete file; + file = 0; + } + ddl = thisDDL; + } + // 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)); + if (!file || !*file) { + AliFatal(Form("Failed to open file FMD_%d.ddl", ddl)); + return; + } + writer = new AliFMDAltroWriter(*file); + writer->SetThreshold(pars->GetZeroSuppression(det, ring, sector, strip)); + sampleRate = pars->GetSampleRate(ddl); + } + // Write out our signal + writer->AddSignal(digit->Count1()); + if (sampleRate >= 2) writer->AddSignal(digit->Count2()); + if (sampleRate >= 3) writer->AddSignal(digit->Count3()); + } + if (writer) { + writer->AddChannelTrailer(hwaddr); + writer->Close(); + delete writer; + file->close(); + delete file; + } +} - // The first seen strip number for a channel - UShort_t startStrip = 0; + - // Which channel number in the ALTRO channel we're at - UShort_t offset = 0; +#if 0 +//____________________________________________________________________ +void +AliFMDRawWriter::WriteDigits(TClonesArray* digits) +{ + Int_t nDigits = digits->GetEntries(); + if (nDigits < 1) return; - // How many times the ALTRO Samples one VA1_ALICE channel - Int_t sampleRate = 1; + AliFMDParameters* pars = AliFMDParameters::Instance(); + UShort_t prevDetector = 0; + Char_t prevRing = '\0'; + UShort_t prevSector = 0; + // UShort_t prevStrip = 0; + + // The first seen strip number for a channel + UShort_t startStrip = 0; + + // Which channel number in the ALTRO channel we're at + UShort_t offset = 0; + + // How many times the ALTRO Samples one VA1_ALICE channel + Int_t sampleRate = 1; + + // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel + // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' + TArrayI channel(fChannelsPerAltro * sampleRate); - // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel - // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' - TArrayI channel(fChannelsPerAltro * sampleRate); - - // The Altro buffer - AliAltroBuffer* altro = 0; + // The Altro buffer + AliAltroBuffer* altro = 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. - 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(); - fThreshold = pars->GetZeroSuppression(det, ring, sector, strip); - if (det != prevDetector) { - AliDebug(15, Form("FMD: New DDL, was %d, now %d", - AliFMDParameters::kBaseDDL + prevDetector - 1, - AliFMDParameters::kBaseDDL + det - 1)); - // 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("New altro: Write channel at %d Strip: %d " - "Sector: %d Ring: %d", - i, startStrip, prevSector, prevRing)); - // TPC to FMD translations - // - // TPC FMD - // ----------+----------- - // pad | strip - // row | sector - // sector | ring - // - WriteChannel(altro, startStrip, prevSector, prevRing, channel); - altro->Flush(); - altro->WriteDataHeader(kFALSE, kFALSE); - delete altro; - altro = 0; - } - - prevDetector = det; - // Need to open a new DDL! - Int_t ddlId = AliFMDParameters::kBaseDDL + det - 1; - TString filename(Form("%s_%d.ddl", fFMD->GetName(), ddlId)); + // 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. + for (Int_t i = 0; i < nDigits; i++) { + // Get the digit + AliFMDDigit* digit = static_cast(digits->At(i)); - AliDebug(15, Form("New altro buffer with DDL file %s", - filename.Data())); - AliDebug(15, Form("New altro at %d", i)); - // Create a new altro buffer - a `1' as the second argument - // means `write mode' - altro = new AliAltroBuffer(filename.Data(), 1); - - // 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); - - // Figure out the sample rate - if (fSampleRate > 0) sampleRate = fSampleRate; - else { - if (digit->Count2() >= 0) sampleRate = 2; - if (digit->Count3() >= 0) sampleRate = 3; - } - - channel.Set(fChannelsPerAltro * sampleRate); - offset = 0; - prevRing = ring; - prevSector = sector; - startStrip = strip; - } - else if (offset == fChannelsPerAltro - || digit->Ring() != prevRing - || digit->Sector() != prevSector) { - // Force a new Altro channel - AliDebug(15, Form("Flushing channel to disk because %s", - (offset == fChannelsPerAltro ? "channel is full" : - (ring != prevRing ? "new ring up" : - "new sector up")))); - AliDebug(15, Form("New Channel: Write channel at %d Strip: %d " + UShort_t det = digit->Detector(); + Char_t ring = digit->Ring(); + UShort_t sector = digit->Sector(); + UShort_t strip = digit->Strip(); + fThreshold = pars->GetZeroSuppression(det, ring, sector, strip); + if (det != prevDetector) { + AliDebug(15, Form("FMD: New DDL, was %d, now %d", + AliFMDParameters::kBaseDDL + prevDetector - 1, + AliFMDParameters::kBaseDDL + det - 1)); + // 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("New altro: Write channel at %d Strip: %d " "Sector: %d Ring: %d", i, startStrip, prevSector, prevRing)); + // TPC to FMD translations + // + // TPC FMD + // ----------+----------- + // pad | strip + // row | sector + // sector | ring + // WriteChannel(altro, startStrip, prevSector, prevRing, channel); - // Reset and update channel variables - channel.Reset(0); - offset = 0; - startStrip = strip; - prevRing = ring; - prevSector = sector; + altro->Flush(); + altro->WriteDataHeader(kFALSE, kFALSE); + delete altro; + altro = 0; + } + prevDetector = det; + // Need to open a new DDL! + Int_t ddlId = AliFMDParameters::kBaseDDL + det - 1; + TString filename(Form("%s_%d.ddl", fFMD->GetName(), ddlId)); + + AliDebug(15, Form("New altro buffer with DDL file %s", + filename.Data())); + AliDebug(15, Form("New altro at %d", i)); + // 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); + + // Figure out the sample rate + if (fSampleRate > 0) sampleRate = fSampleRate; + else { + if (digit->Count2() >= 0) sampleRate = 2; + if (digit->Count3() >= 0) sampleRate = 3; } - // Store the counts of the ADC in the channel buffer - channel[offset * sampleRate] = digit->Count1(); - if (sampleRate > 1) - channel[offset * sampleRate + 1] = digit->Count2(); - if (sampleRate > 2) - channel[offset * sampleRate + 2] = digit->Count3(); - offset++; + channel.Set(fChannelsPerAltro * sampleRate); + offset = 0; + prevRing = ring; + prevSector = sector; + startStrip = strip; } - // Finally, we need to close the final ALTRO buffer if it wasn't - // already - if (altro) { - altro->Flush(); - altro->WriteDataHeader(kFALSE, kFALSE); - delete altro; + else if (offset == fChannelsPerAltro + || digit->Ring() != prevRing + || digit->Sector() != prevSector) { + // Force a new Altro channel + AliDebug(15, Form("Flushing channel to disk because %s", + (offset == fChannelsPerAltro ? "channel is full" : + (ring != prevRing ? "new ring up" : + "new sector up")))); + AliDebug(15, Form("New Channel: Write channel at %d Strip: %d " + "Sector: %d Ring: %d", + i, startStrip, prevSector, prevRing)); + WriteChannel(altro, startStrip, prevSector, prevRing, channel); + // Reset and update channel variables + channel.Reset(0); + offset = 0; + startStrip = strip; + prevRing = ring; + prevSector = sector; } + + // Store the counts of the ADC in the channel buffer + channel[offset * sampleRate] = digit->Count1(); + if (sampleRate > 1) + channel[offset * sampleRate + 1] = digit->Count2(); + if (sampleRate > 2) + channel[offset * sampleRate + 2] = digit->Count3(); + offset++; + } + // Finally, we need to close the final ALTRO buffer if it wasn't + // already + if (altro) { + altro->Flush(); + altro->WriteDataHeader(kFALSE, kFALSE); + delete altro; } - loader->UnloadDigits(); } +#endif //____________________________________________________________________ void diff --git a/FMD/AliFMDRawWriter.h b/FMD/AliFMDRawWriter.h index 0d142a93f44..8191456d707 100644 --- a/FMD/AliFMDRawWriter.h +++ b/FMD/AliFMDRawWriter.h @@ -22,7 +22,7 @@ class AliFMD; class AliAltroBuffer; class TArrayI; - +class TClonesArray; //____________________________________________________________________ class AliFMDRawWriter : public TTask @@ -33,6 +33,7 @@ public: virtual void Exec(Option_t* option=""); protected: + virtual void WriteDigits(TClonesArray* digits); virtual void WriteChannel(AliAltroBuffer* altro, UShort_t strip, UShort_t sector, Char_t ring, const TArrayI& data); diff --git a/FMD/AliFMDReconstructor.cxx b/FMD/AliFMDReconstructor.cxx index b78398b4274..c30a7c85864 100644 --- a/FMD/AliFMDReconstructor.cxx +++ b/FMD/AliFMDReconstructor.cxx @@ -198,8 +198,6 @@ AliFMDReconstructor::Init(AliRunLoader* runLoader) Warning("Init", "No generator event header - " "perhaps we get the vertex from ESD?"); } - // Get the ESD tree - SetESD(new AliESD); } //____________________________________________________________________ @@ -224,7 +222,7 @@ AliFMDReconstructor::Reconstruct(TTree* digitsTree, // FIXME: The vertex may not be known yet, so we may have to move // some of this to FillESD. AliDebug(1, "Reconstructing from digits in a tree"); -#if 0 +#if 1 if (fESD) { const AliESDVertex* vertex = fESD->GetVertex(); if (vertex) { diff --git a/FMD/FMDbaseLinkDef.h b/FMD/FMDbaseLinkDef.h index 0c8efec9374..a8c16c20875 100644 --- a/FMD/FMDbaseLinkDef.h +++ b/FMD/FMDbaseLinkDef.h @@ -25,6 +25,9 @@ #pragma link C++ class AliFMDCalibGain+; #pragma link C++ class AliFMDCalibSampleRate+; #pragma link C++ class AliFMDAltroMapping+; +#pragma link C++ class AliFMDAltroIO+; +#pragma link C++ class AliFMDAltroReader+; +#pragma link C++ class AliFMDAltroWriter+; #else # error Not for compilation diff --git a/FMD/Reconstruct.C b/FMD/Reconstruct.C index d52a6933833..efc5aa89f78 100644 --- a/FMD/Reconstruct.C +++ b/FMD/Reconstruct.C @@ -20,13 +20,15 @@ void Reconstruct() { - AliLog::SetModuleDebugLevel("FMD", 1); + AliCDBManager* cdb = AliCDBManager::Instance(); + cdb->SetDefaultStorage("local://cdb"); + AliLog::SetModuleDebugLevel("FMD", 2); AliReconstruction rec; rec.SetRunLocalReconstruction("FMD"); rec.SetRunVertexFinder(kFALSE); rec.SetRunTracking(""); rec.SetFillESD("FMD"); - // rec.SetInput("./"); + rec.SetInput("./"); rec.Run(); } diff --git a/FMD/Simulate.C b/FMD/Simulate.C index bb66d05fc85..970442bc7f1 100644 --- a/FMD/Simulate.C +++ b/FMD/Simulate.C @@ -19,17 +19,24 @@ void Simulate() { - AliSimulation sim; - sim.SetConfigFile("$(ALICE_ROOT)/FMD/Config.C"); - // sim.SetMakeSDigits("FMD"); - sim.SetMakeDigits("FMD"); - sim.SetWriteRawData("FMD"); - // sim.SetMakeDigitsFromHits("FMD"); - TStopwatch w; - w.Start(); - sim.Run(1); - w.Stop(); - w.Print(); + AliCDBManager* cdb = AliCDBManager::Instance(); + cdb->SetDefaultStorage("local://cdb"); + AliSimulation sim; + AliCDBEntry* align = cdb->Get("FMD/Align/Data"); + if (align) { + TClonesArray* array = dynamic_cast(align->GetObject()); + if (array) sim.SetAlignObjArray(array); + } + sim.SetConfigFile("$(ALICE_ROOT)/FMD/Config.C"); + // sim.SetMakeSDigits("FMD"); + sim.SetMakeDigits("FMD"); + sim.SetWriteRawData("FMD"); + // sim.SetMakeDigitsFromHits("FMD"); + TStopwatch w; + w.Start(); + sim.Run(1); + w.Stop(); + w.Print(); } // diff --git a/FMD/libFMDbase.pkg b/FMD/libFMDbase.pkg index 9cb54e18a8b..0db92fabcb4 100644 --- a/FMD/libFMDbase.pkg +++ b/FMD/libFMDbase.pkg @@ -9,6 +9,7 @@ SRCS = AliFMDDigit.cxx \ AliFMDCalibGain.cxx \ AliFMDCalibSampleRate.cxx \ AliFMDAltroMapping.cxx \ + AliFMDAltroIO.cxx \ AliFMDParameters.cxx \ AliFMDGeometry.cxx \ AliFMDRing.cxx \ diff --git a/FMD/scripts/ApplyAlignment.C b/FMD/scripts/ApplyAlignment.C new file mode 100644 index 00000000000..9b7212690dd --- /dev/null +++ b/FMD/scripts/ApplyAlignment.C @@ -0,0 +1,41 @@ +//____________________________________________________________________ +// +// $Id$ +// +// Read in the geometry, and get alignment data from CDB, and apply +// that to the geometry. +// +void +ApplyAlignment() +{ + gSystem->Load("libFMDutil.so"); + TGeoManager::Import("geometry.root"); + + AliCDBManager* cdb = AliCDBManager::Instance(); + cdb->SetDefaultStorage("local://cdb"); + AliCDBEntry* align = cdb->Get("FMD/Align/Data"); + if (align) { + Info("ApplyAlignment","Got alignment data from CDB"); + TClonesArray* array = dynamic_cast(align->GetObject()); + if (!array) { + Warning("ApplyAlignement", "Invalid align data from CDB"); + } + else { + Int_t nAlign = array->GetEntries(); + for (Int_t i = 0; i < nAlign; i++) { + AliAlignObjAngles* a = static_cast(array->At(i)); + if (!a->ApplyToGeometry()) { + Warning("ApplyAlignement", "Failed to apply alignment to %s", + a->GetVolPath()); + } + } + } + } + TCanvas* c = new TCanvas("Geometry", "Geometry"); + c->SetFillColor(1); + gGeoManager->GetTopVolume()->Draw(); +} +//____________________________________________________________________ +// +// EOF +// diff --git a/FMD/scripts/Convert2Raw.C b/FMD/scripts/Convert2Raw.C new file mode 100644 index 00000000000..8d5c36d6146 --- /dev/null +++ b/FMD/scripts/Convert2Raw.C @@ -0,0 +1,26 @@ +//____________________________________________________________________ +// +// $Id$ +// +// Read in digits, and convert them to raw data files. This is mainly +// for testing. +// +void +Convert2Raw() +{ + AliRunLoader* runLoader = + AliRunLoader::Open("galice.root", "Alice", "read"); + runLoader->LoadgAlice(); + AliRun* run = runLoader->GetAliRun(); + AliLoader* fmdLoader = runLoader->GetLoader("FMDLoader"); + AliFMD* fmd = static_cast(run->GetDetector("FMD")); + AliLog::SetModuleDebugLevel("FMD", 1); + + AliFMDParameters::Instance()->Init(); + AliFMDRawWriter rw(fmd); + rw.Exec(); +} +//____________________________________________________________________ +// +// EOF +// diff --git a/FMD/scripts/DisplayHits.C b/FMD/scripts/DisplayHits.C index a0c38dc5ae1..0d0c3555693 100644 --- a/FMD/scripts/DisplayHits.C +++ b/FMD/scripts/DisplayHits.C @@ -7,6 +7,8 @@ void DisplayHits() { + AliCDBManager* cdb = AliCDBManager::Instance(); + cdb->SetDefaultStorage("local://cdb"); gSystem->Load("libFMDutil.so"); AliFMDDisplay* d = new AliFMDDisplay; d->AddLoad(AliFMDInput::kHits); diff --git a/FMD/scripts/MakeAlignment.C b/FMD/scripts/MakeAlignment.C new file mode 100644 index 00000000000..69f669c168d --- /dev/null +++ b/FMD/scripts/MakeAlignment.C @@ -0,0 +1,25 @@ +//____________________________________________________________________ +// +// $Id$ +// +// Make fake alignment data. +// +void +MakeAlignment() +{ + if (!TGeoManager::Import("geometry.root")) + gAlice->Init("$ALICE_ROOT/FMD/Config.C"); + AliCDBManager* cdb = AliCDBManager::Instance(); + cdb->SetDefaultStorage("local://cdb"); + + gSystem->Load("libFMDutil.so"); + AliFMDAlignFaker f; + f.RemoveAlign(AliFMDAlignFaker::kHalves); + f.SetSensorDisplacement(0,0,0,0,0,0); + f.SetSensorRotation(0,0,0,0,0,0); + f.Exec(); +} +//____________________________________________________________________ +// +// EOF +// diff --git a/FMD/scripts/RawTest.C b/FMD/scripts/RawTest.C index 63fb470fdb4..94ec56f2362 100644 --- a/FMD/scripts/RawTest.C +++ b/FMD/scripts/RawTest.C @@ -47,7 +47,7 @@ RawTest() return 0; } AliFMDRawStream input(reader, sampleRate); - reader->Select(AliFMD::kBaseDDL >> 8); + reader->Select(AliFMDParameters::kBaseDDL >> 8); Int_t oldDDL = -1; Int_t count = 0; diff --git a/FMD/scripts/ShowRaw.C b/FMD/scripts/ShowRaw.C index d610cb0c26c..2a55719a63b 100644 --- a/FMD/scripts/ShowRaw.C +++ b/FMD/scripts/ShowRaw.C @@ -8,7 +8,8 @@ void ShowRaw(Int_t det=2, bool verbose=false, Int_t event=0) { - TString file(Form("raw%d/FMD_%d.ddl", event, AliFMD::kBaseDDL + det - 1)); + TString file(Form("raw%d/FMD_%d.ddl", event, + AliFMDParameters::kBaseDDL + det - 1)); std::cout << "Reading raw data file " << file << std::endl; @@ -26,9 +27,9 @@ ShowRaw(Int_t det=2, bool verbose=false, Int_t event=0) Int_t numWords,padNum,rowNum,secNum=0; Int_t value = 0; Int_t zero = 0; - // if (!buff.ReadDataHeader()) { - // std::cout<< file << " isn't a valid data file!" << std::endl; - // } + if (!buff.ReadDataHeader()) { + std::cout<< file << " isn't a valid data file!" << std::endl; + } while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum)){ if (verbose) diff --git a/FMD/scripts/TestHWMap.C b/FMD/scripts/TestHWMap.C index 3b7efed1856..2fe855ebae9 100644 --- a/FMD/scripts/TestHWMap.C +++ b/FMD/scripts/TestHWMap.C @@ -50,8 +50,8 @@ CheckTrans(UShort_t det, Char_t ring, UShort_t sec, UShort_t str, Waring("TestHWMap", "Ring Id differ %c != %c", ring, oring); if (sec != osec) Warning("TestHWMap", "Sector # differ %d != %d", sec, osec); - if (str != ostr) - Warning("TestHWMap", "Strip # differ %d != %d", str, ostr); + if ((str / 128) * 128 != ostr) + Warning("TestHWMap", "Strip # differ %d != %d", (str / 128) * 128, ostr); } //____________________________________________________________________ @@ -59,14 +59,17 @@ void TestHWMap() { AliFMDParameters* param = AliFMDParameters::Instance(); + param->Init(); + AliLog::SetModuleDebugLevel("FMD", 1); - for (UShort_t det = 2; det <= 2; det++) { + UInt_t oldddl = 0, oldhwaddr = 0xFFFFFFFF; + for (UShort_t det = 1; det <= 3; det++) { for (UShort_t rng = 0; rng < 2; rng++) { Char_t ring = (rng == 0 ? 'I' : 'O'); Int_t nsec = (ring == 'I' ? 20 : 40); Int_t nstr = (ring == 'I' ? 512 : 256); for (UShort_t sec = 0; sec < nsec; sec++) { - for (UShort_t str = 0; str < nstr; str += 128) { + for (UShort_t str = 0; str < nstr; str ++) { UInt_t ddl, hwaddr; if (!param->Detector2Hardware(det, ring, sec, str, ddl, hwaddr)) { Warning("TestHWMap", "detector to hardware failed on %s", @@ -80,7 +83,11 @@ TestHWMap() Addr2Str(ddl, hwaddr)); continue; } - PrintTrans(det,ring,sec,str,ddl,hwaddr,odet,oring,osec,ostr); + if (oldddl != ddl || oldhwaddr != hwaddr) { + PrintTrans(det,ring,sec,str,ddl,hwaddr,odet,oring,osec,ostr); + oldddl = ddl; + oldhwaddr = hwaddr; + } CheckTrans(det,ring,sec,str,odet,oring,osec,ostr); }// Loop over strips } // Loop over sectors diff --git a/FMD/scripts/TestRawIO.C b/FMD/scripts/TestRawIO.C new file mode 100644 index 00000000000..cb517cf6f0f --- /dev/null +++ b/FMD/scripts/TestRawIO.C @@ -0,0 +1,33 @@ +//____________________________________________________________________ +// +// $Id$ +// +// Test of AliFMDAltro{Reader,Writer} +// +void +TestRawIO() +{ + std::ofstream ofile("foo.dat"); + AliFMDAltroWriter w(ofile); + for (size_t i = 0; i < 16; i++) + w.AddSignal((i << 4) + i); + w.AddChannelTrailer(0xabe); + w.Close(); + ofile.close(); + + std::ifstream ifile("foo.dat"); + AliRawDataHeader h; + ifile.read((char*)&h, sizeof(h)); + AliFMDAltroReader r(ifile); + UShort_t hwaddr, last; + UShort_t data[1024]; + int ret = r.ReadChannel(hwaddr, last, data); + printf("Read returned %d, w/addr=0x%x, last=%d\n", ret, hwaddr, last); + if (ret < 0) return; + for (size_t i = 0; i < last; i++) + std::cout << i << "\t0x" << std::hex << data[i] << std::endl; +} +//____________________________________________________________________ +// +// EOF +// -- 2.43.0