X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONRawWriter.cxx;h=d783d441343da0765c2f3ef031dfe37f96ec0cbe;hb=fc2b2eaf3404264191cbb9a99df7ec14c3d7a8d9;hp=8d4b9620d1a37fa6d6c42025ef3fae6a7a8fc9ec;hpb=5cab551d37e064277494543a9980c60ffb59b461;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONRawWriter.cxx b/MUON/AliMUONRawWriter.cxx index 8d4b9620d1a..d783d441343 100644 --- a/MUON/AliMUONRawWriter.cxx +++ b/MUON/AliMUONRawWriter.cxx @@ -15,6 +15,7 @@ /* $Id$ */ +//----------------------------------------------------------------------------- /// \class AliMUONRawWriter /// MUON Raw Data generaton in ALICE-MUON /// Raw data structure could be found in Alice-note. @@ -38,7 +39,9 @@ /// empty slots and non-notified cards in trigger crates. /// Ch. Finck, August 06. /// Using AliMpDDLStore::GetBusPatchId. -/// Ch. Finck, Feb. 07. +/// +/// \author Ch. Finck, Feb. 07. +//----------------------------------------------------------------------------- #include "AliMUONRawWriter.h" @@ -47,8 +50,8 @@ #include "AliMUONBusStruct.h" #include "AliMUONConstants.h" #include "AliMUONDarcHeader.h" -#include "AliMUONData.h" -#include "AliMUONDigit.h" +#include "AliMUONVDigit.h" +#include "AliMUONVDigitStore.h" #include "AliMUONDspHeader.h" #include "AliMUONGlobalTrigger.h" #include "AliMUONLocalStruct.h" @@ -56,11 +59,16 @@ #include "AliMUONLocalTriggerBoard.h" #include "AliMUONRegionalTrigger.h" #include "AliMUONRegHeader.h" -#include "AliMUONTriggerCrate.h" -#include "AliMUONTriggerCrateStore.h" +#include "AliMUONVTriggerStore.h" +#include "AliCodeTimer.h" + +#include "AliMpCDB.h" #include "AliMpDDLStore.h" #include "AliMpDDL.h" +#include "AliMpRegionalTrigger.h" +#include "AliMpTriggerCrate.h" +#include "AliMpLocalBoard.h" #include "AliMpDetElement.h" #include "AliMpDEManager.h" #include "AliMpExMap.h" @@ -71,82 +79,48 @@ #include "AliMpVSegmentation.h" #include "AliRawReader.h" +#include "AliRawDataHeaderSim.h" #include "AliBitPacking.h" #include "AliDAQ.h" #include "AliLog.h" -#include "TList.h" #include "TObjArray.h" #include "TStopwatch.h" +#include /// \cond CLASSIMP ClassImp(AliMUONRawWriter) // Class implementation in ROOT context /// \endcond -namespace -{ - enum ETimer { kWriteTracker, kWriteTrigger, kDigitLoop, kGetBusPatch, kTest, kLast }; -} - //__________________________________________________________________________ -AliMUONRawWriter::AliMUONRawWriter(AliMUONData* data) +AliMUONRawWriter::AliMUONRawWriter() : TObject(), - fMUONData(data), fBlockHeader(new AliMUONBlockHeader()), fDspHeader(new AliMUONDspHeader()), fDarcHeader(new AliMUONDarcHeader()), fRegHeader(new AliMUONRegHeader()), fLocalStruct(new AliMUONLocalStruct()), fDDLStore(AliMpDDLStore::Instance()), - fCrateManager(new AliMUONTriggerCrateStore()), fScalerEvent(kFALSE), - fHeader(), - fTimers(new TStopwatch[kLast]) - + fHeader(0x0), + fBufferSize((((43*AliMpConstants::ManuNofChannels() + 4)*5 + 10)*5 + 8)*2), + fBuffer(new Int_t [fBufferSize]) { /// Standard Constructor AliDebug(1,"Standard ctor"); - fFile[0] = fFile[1] = 0x0; - fFile[2] = fFile[3] = 0x0; // setting data key to default value (only for writting) fBlockHeader->SetDataKey(fBlockHeader->GetDefaultDataKey()); fDspHeader->SetDataKey(fDspHeader->GetDefaultDataKey()); - // Crate manager - fCrateManager->ReadFromFile(); - - // timers - for ( Int_t i = 0; i < kLast; ++i ) - { - fTimers[i].Start(kTRUE); - fTimers[i].Stop(); - } - -} - -//__________________________________________________________________________ -AliMUONRawWriter::AliMUONRawWriter() - : TObject(), - fMUONData(0), - fBlockHeader(0), - fDspHeader(0), - fDarcHeader(0), - fRegHeader(0), - fLocalStruct(0), - fDDLStore(0), - fCrateManager(0x0), - fScalerEvent(kFALSE), - fHeader(), - fTimers(0) -{ - /// Default Constructor - - AliDebug(1,"Default ctor"); - fFile[0] = fFile[1] = 0x0; - fFile[2] = fFile[3] = 0x0; - + // Load mapping + if ( ! fDDLStore ) { + if ( ! AliMpCDB::LoadDDLStore() ) { + AliFatal("Could not access mapping from OCDB !"); + } + fDDLStore = AliMpDDLStore::Instance(); + } } //__________________________________________________________________________ @@ -161,448 +135,358 @@ AliMUONRawWriter::~AliMUONRawWriter(void) delete fDarcHeader; delete fRegHeader; delete fLocalStruct; - - delete fCrateManager; - - for ( Int_t i = 0; i < kLast; ++i ) - { - AliDebug(1, Form("Execution time (timer %d) : R:%7.2fs C:%7.2fs",i, - fTimers[i].RealTime(),fTimers[i].CpuTime())); - } - - delete[] fTimers; + delete[] fBuffer; } -//______________________________________________________________________________ -//void -//AliMUONRawWriter::CheckDigits() -//{ -// std::map > m; -// -// for (Int_t iSt = 0; iSt < AliMUONConstants::NTrackingCh()/2; ++iSt) -// { -// for (Int_t iCh = iSt*2; iCh <= iSt*2 + 1; ++iCh) -// { -// TClonesArray* muonDigits = fMUONData->Digits(iCh); -// for (Int_t idig = 0; idig < muonDigits->GetEntriesFast(); idig++) -// { -// AliMUONDigit* digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig); -// Int_t busPatchId = GetBusPatch(*digit); -// m[busPatchId][digit->ManuId()]++; -// } -// } -// } -// -// std::map >::const_iterator it; -// -// Int_t nManuMax(0); -// -// for ( it = m.begin(); it != m.end(); ++it ) -// { -// AliDebug(1,Form("BusPatch %3d has %3d manus",it->first,it->second.size())); -// nManuMax = std::max((Int_t)it->second.size(),nManuMax); -// std::map::const_iterator it2; -// for ( it2 = it->second.begin(); it2 != it->second.end(); ++it2 ) -// { -// AliDebug(1,Form(" BusPatch %3d Manu %4d Nch %3d",it->first,it2->first,it2->second)); -// } -// } -// AliDebug(1,Form("Max manus per busPatch : %3d",nManuMax)); -//} - //____________________________________________________________________ -Int_t AliMUONRawWriter::Digits2Raw() +void AliMUONRawWriter::LocalWordPacking(UInt_t& word, UInt_t locId, UInt_t locDec, + UInt_t trigY, UInt_t posY, UInt_t posX, + UInt_t sdevX, UInt_t devX) { - /// convert digits of the current event to raw data +/// pack local trigger word - Int_t idDDL; - Char_t name[255]; + AliBitPacking::PackWord(locId,word,19,22); //card id number in crate + AliBitPacking::PackWord(locDec,word,15,18); + AliBitPacking::PackWord(trigY,word,14,14); + AliBitPacking::PackWord(posY,word,10,13); + AliBitPacking::PackWord(sdevX,word,9,9); + AliBitPacking::PackWord(devX,word,5,8); + AliBitPacking::PackWord(posX,word,0,4); - fMUONData->GetLoader()->LoadDigits("READ"); +} - fMUONData->SetTreeAddress("D,GLT"); +//____________________________________________________________________ +Int_t AliMUONRawWriter::Digits2Raw(const AliMUONVDigitStore* digitStore, + const AliMUONVTriggerStore* triggerStore) +{ + /// convert digits of the current event to raw data - fMUONData->ResetDigits(); - fMUONData->ResetTrigger(); - - // This will get both tracker and trigger digits. - fMUONData->GetDigits(); + AliCodeTimerAuto("",0) -// CheckDigits(); + Int_t idDDL; // tracking chambers - for (Int_t iSt = 0; iSt < AliMUONConstants::NTrackingCh()/2; ++iSt) { - - // open files for one station - // cos station 3, 1/4 of DE's from 2 chambers has same DDL number - idDDL = iSt * 4; - strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL)); - fFile[0] = fopen(name,"w"); - - idDDL = (iSt * 4) + 1; - strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL)); - fFile[1] = fopen(name,"w"); + if ( digitStore ) + { + AliCodeTimerAuto("for Tracker",1) - idDDL = (iSt * 4) + 2;; - strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL)); - fFile[2] = fopen(name,"w"); + AliMpExMap busPatchMap; - idDDL = (iSt * 4) + 3; - strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL)); - fFile[3] = fopen(name,"w"); + Int_t nDDLs = AliDAQ::NumberOfDdls("MUONTRK"); + + Int_t nofBusPatches(0); + + for (Int_t iDDL = 0; iDDL < nDDLs; ++iDDL ) + { + AliMpDDL* ddl = fDDLStore->GetDDL(iDDL); + nofBusPatches += ddl->GetNofBusPatches(); + } + + busPatchMap.SetSize(nofBusPatches); + + Digits2BusPatchMap(*digitStore,busPatchMap); - WriteTrackerDDL(iSt); - - // reset and close when station has been processed - fclose(fFile[0]); - fclose(fFile[1]); - fclose(fFile[2]); - fclose(fFile[3]); - + for (Int_t iDDL = 0; iDDL < nDDLs; ++iDDL ) + { + WriteTrackerDDL(busPatchMap,iDDL); + } + AliDebug(1,"Tracker written"); } - AliDebug(1,"Tracker written"); - - // trigger chambers - - // open files - idDDL = 0;// MUTR - strcpy(name,AliDAQ::DdlFileName("MUONTRG",idDDL)); - fFile[0] = fopen(name,"w"); - - idDDL = 1;// MUTR - strcpy(name,AliDAQ::DdlFileName("MUONTRG",idDDL)); - fFile[1] = fopen(name,"w"); - - WriteTriggerDDL(); - - // reset and close - fclose(fFile[0]); - fclose(fFile[1]); - - AliDebug(1,"Trigger written"); - - fMUONData->ResetDigits(); - fMUONData->ResetTrigger(); - fMUONData->GetLoader()->UnloadDigits(); + if ( triggerStore ) + { + AliCodeTimerAuto("for Trigger",1) - AliDebug(1,"muondata reset"); + // trigger chambers + + AliFstream* file[2]; + + // open files + idDDL = 0;// MUTR + file[0] = new AliFstream(AliDAQ::DdlFileName("MUONTRG",idDDL)); + + idDDL = 1;// MUTR + file[1] = new AliFstream(AliDAQ::DdlFileName("MUONTRG",idDDL)); + + WriteTriggerDDL(*triggerStore,file); + + // reset and close + delete file[0]; + delete file[1]; + + AliDebug(1,"Trigger written"); + } return kTRUE; } -//____________________________________________________________________ -Int_t AliMUONRawWriter::WriteTrackerDDL(Int_t iSt) +//______________________________________________________________________________ +void +AliMUONRawWriter::Digits2BusPatchMap(const AliMUONVDigitStore& digitStore, + AliMpExMap& busPatchMap) { - /// writing DDL for tracker - /// used inverse mapping - - fTimers[kWriteTracker].Start(kFALSE); + /// Create bus patch structures corresponding to digits in the store + + AliCodeTimerAuto("",0) static const Int_t kMAXADC = (1<<12)-1; // We code the charge on a 12 bits ADC. - - // resets - TClonesArray* muonDigits = 0; - - // DDL header - Int_t headerSize = sizeof(fHeader)/4; - + // DDL event one per half chamber - + // raw data Char_t parity = 0x4; UShort_t manuId = 0; UChar_t channelId = 0; UShort_t charge = 0; Int_t busPatchId = 0; + Int_t currentBusPatchId = -1; UInt_t word; + + AliMUONBusStruct* busStruct(0x0); + + TIter next(digitStore.CreateTrackerIterator()); + AliMUONVDigit* digit; + + while ( ( digit = static_cast(next()) ) ) + { + charge = digit->ADC(); + if ( charge > kMAXADC ) + { + // This is most probably an error in the digitizer (which should insure + // the adc is below kMAXADC), so make it a (non-fatal) error indeed. + AliError(Form("adc value %d above 0x%x for DE %d . Setting to 0x%x. Digit is:", + charge,kMAXADC,digit->DetElemId(),kMAXADC)); + StdoutToAliError(digit->Print()); + charge = kMAXADC; + } + + // inverse mapping + busPatchId = GetBusPatch(*digit); + if (busPatchId<0) continue; + + if ( digit->ManuId() > 0x7FF || + digit->ManuChannel() > 0x3F ) + { + StdoutToAliError(digit->Print();); + AliFatal("ManuId,ManuChannel are invalid for the digit above."); + } + + manuId = ( digit->ManuId() & 0x7FF ); // 11 bits + channelId = ( digit->ManuChannel() & 0x3F ); // 6 bits + + //packing word + word = 0; + AliBitPacking::PackWord((UInt_t)manuId,word,18,28); + AliBitPacking::PackWord((UInt_t)channelId,word,12,17); + AliBitPacking::PackWord((UInt_t)charge,word,0,11); + + // parity word + parity = word & 0x1; + for (Int_t i = 1; i <= 30; ++i) + { + parity ^= ((word >> i) & 0x1); + } + AliBitPacking::PackWord((UInt_t)parity,word,31,31); - // Dsp length - Int_t totalDspLength; - Int_t dspLength; + if ( currentBusPatchId != busPatchId ) + { + busStruct = + static_cast(busPatchMap.GetValue(busPatchId)); + currentBusPatchId = busPatchId; + } + + if (!busStruct) + { + busStruct = new AliMUONBusStruct; + busStruct->SetDataKey(busStruct->GetDefaultDataKey()); + busStruct->SetBusPatchId(busPatchId); + busStruct->SetLength(0); + busPatchMap.Add(busPatchId,busStruct); + } + + // set sub Event + busStruct->AddData(word); + } +} - // block length - Int_t totalBlkLength; - Int_t blkLength; +//______________________________________________________________________________ +void +AliMUONRawWriter::WriteTrackerDDL(AliMpExMap& busPatchMap, Int_t iDDL) +{ + /// Write DDL file for one tracker DDL - // total DDL length - Int_t totalDDLLength; - - // indexes - Int_t index; - Int_t indexDsp; - Int_t indexBlk; - // buffer size (max'ed out) // (((43 manus max per bus patch *64 channels + 4 bus patch words) * 5 bus patch // + 10 dsp words)*5 dsps + 8 block words)*2 blocks - static const Int_t kBufferSize = (((43*64 + 4)*5 + 10)*5 + 8)*2; - - Int_t nDigits; + + AliCodeTimerAuto("",0) - AliMpExMap busPatchMap(kTRUE); + if (fHeader == 0x0) { + AliError("Raw data header must be set"); + return; + } + memset(fBuffer,0,fBufferSize*sizeof(Int_t)); - fTimers[kDigitLoop].Start(kFALSE); + AliMpDDL* ddl = fDDLStore->GetDDL(iDDL); + Int_t iDspMax = ddl->GetMaxDsp(); + Int_t iBusPerDSP[5]; //number of bus patches per DSP + ddl->GetBusPerDsp(iBusPerDSP); + Int_t busIter = 0; - for (Int_t iCh = iSt*2; iCh <= iSt*2 + 1; ++iCh) { - - muonDigits = fMUONData->Digits(iCh); - - nDigits = muonDigits->GetEntriesFast(); - - // loop over digit - for (Int_t idig = 0; idig < nDigits; ++idig) { - - AliMUONDigit* digit = static_cast(muonDigits->UncheckedAt(idig)); - - charge = digit->ADC(); - if ( charge > kMAXADC ) - { - // This is most probably an error in the digitizer (which should insure - // the adc is below kMAXADC), so make it a (non-fatal) error indeed. - AliError(Form("adc value %d above %x for ch %d . Setting to %x. Digit is:",iCh, - charge,kMAXADC,kMAXADC)); - StdoutToAliError(digit->Print()); - charge = kMAXADC; - } - - // inverse mapping - fTimers[kGetBusPatch].Start(kFALSE); - busPatchId = GetBusPatch(*digit); - fTimers[kGetBusPatch].Stop(); - if (busPatchId<0) continue; - - if ( digit->ManuId() > 0x7FF || digit->ManuId() < 0 || - digit->ManuChannel() > 0x3F || digit->ManuChannel() < 0 ) - { - StdoutToAliError(digit->Print();); - AliFatal("ManuId,ManuChannel are invalid for the digit above."); - } - - manuId = ( digit->ManuId() & 0x7FF ); // 11 bits - channelId = ( digit->ManuChannel() & 0x3F ); // 6 bits - - //packing word - word = 0; - AliBitPacking::PackWord((UInt_t)manuId,word,18,28); - AliBitPacking::PackWord((UInt_t)channelId,word,12,17); - AliBitPacking::PackWord((UInt_t)charge,word,0,11); - - // parity word - parity = word & 0x1; - for (Int_t i = 1; i <= 30; ++i) - parity ^= ((word >> i) & 0x1); - AliBitPacking::PackWord((UInt_t)parity,word,31,31); - - AliMUONBusStruct* busStruct = - static_cast(busPatchMap.GetValue(busPatchId)); - - if (!busStruct) - { - busStruct = new AliMUONBusStruct; - busStruct->SetDataKey(busStruct->GetDefaultDataKey()); - busStruct->SetBusPatchId(busPatchId); - busStruct->SetLength(0); - busPatchMap.Add(busPatchId,busStruct); - } - - // set sub Event - busStruct->AddData(word); - - } // idig - } // loop over chamber in station - - fTimers[kDigitLoop].Stop(); + Int_t totalDDLLength = 0; - // getting info for the number of buspatches - Int_t iBusPatch; - Int_t length; - Int_t iBusPerDSP[5];//number of bus patches per DSP - Int_t iDspMax; //number max of DSP per block - Int_t iFile = 0; - - AliMUONBusStruct* busStructPtr(0x0); - - // open DDL files, 4 per station - for (Int_t iDDL = iSt*4; iDDL < 4 + iSt*4; ++iDDL) { - - AliMpDDL* ddl = fDDLStore->GetDDL(iDDL); - iDspMax = ddl->GetMaxDsp(); - ddl->GetBusPerDsp(iBusPerDSP); - Int_t busIter = 0; - - Int_t buffer[kBufferSize]; + Int_t index = 0; + + // two blocks A and B per DDL + for (Int_t iBlock = 0; iBlock < 2; ++iBlock) + { + // block header + Int_t length = fBlockHeader->GetHeaderLength(); + memcpy(&fBuffer[index],fBlockHeader->GetHeader(),length*4); + Int_t indexBlk = index; + index += length; - totalDDLLength = 0; - - indexBlk = 0; - indexDsp = 0; - index = 0; - - // two blocks A and B per DDL - for (Int_t iBlock = 0; iBlock < 2; ++iBlock) { - - // block header - length = fBlockHeader->GetHeaderLength(); - memcpy(&buffer[index],fBlockHeader->GetHeader(),length*4); - indexBlk = index; - index += length; + // 5 DSP's max per block + for (Int_t iDsp = 0; iDsp < iDspMax; ++iDsp) + { + // DSP header + Int_t dspHeaderLength = fDspHeader->GetHeaderLength(); + memcpy(&fBuffer[index],fDspHeader->GetHeader(),dspHeaderLength*4); + Int_t indexDsp = index; + index += dspHeaderLength; - // 5 DSP's max per block - for (Int_t iDsp = 0; iDsp < iDspMax; ++iDsp) { - - // DSP header - length = fDspHeader->GetHeaderLength(); - memcpy(&buffer[index],fDspHeader->GetHeader(),length*4); - indexDsp = index; - index += length; - - // 5 buspatches max per DSP - for (Int_t i = 0; i < iBusPerDSP[iDsp]; i++) { - - iBusPatch = ddl->GetBusPatchId(busIter++); - - // iteration over bus patch in DDL - if (iBusPatch == -1) { - AliWarning(Form("Error in bus itr in DDL %d\n", iDDL)); - continue; - } - - // 4 DDL's per station, condition needed for station 3 - iFile = iDDL - iSt*4; // works only if DDL begins at zero (as it should be) !!! - - busStructPtr = static_cast(busPatchMap.GetValue(iBusPatch)); - - // check if buspatchid has digit - if (busStructPtr) { - // add bus patch structure header - length = busStructPtr->GetHeaderLength(); - memcpy(&buffer[index],busStructPtr->GetHeader(),length*4); - index += length; - - // add bus patch data - length = busStructPtr->GetLength(); - memcpy(&buffer[index],busStructPtr->GetData(),length*4); - index += length; - - if (AliLog::GetGlobalDebugLevel() == 3) { - for (Int_t j = 0; j < busStructPtr->GetLength(); j++) { - printf("busPatchId %d, manuId %d channelId %d\n", busStructPtr->GetBusPatchId(), - busStructPtr->GetManuId(j), busStructPtr->GetChannelId(j)); - } - } - } else { - // writting anyhow buspatch structure (empty ones) - buffer[index++] = busStructPtr->GetDefaultDataKey(); // fill it also for empty data size - buffer[index++] = busStructPtr->GetHeaderLength(); // header length - buffer[index++] = 0; // raw data length - buffer[index++] = iBusPatch; // bus patch - } - } // bus patch + // 5 buspatches max per DSP + for (Int_t i = 0; i < iBusPerDSP[iDsp]; ++i) + { + Int_t iBusPatch = ddl->GetBusPatchId(busIter++); - // check if totalLength even - // set padding word in case - // Add one word 0xBEEFFACE at the end of DSP structure - totalDspLength = index - indexDsp; - if ((totalDspLength % 2) == 1) { - buffer[indexDsp + fDspHeader->GetHeaderLength() - 2] = 1; - buffer[index++] = fDspHeader->GetDefaultPaddingWord(); - totalDspLength++; + // iteration over bus patch in DDL + if (iBusPatch == -1) + { + AliWarning(Form("Error in bus itr in DDL %d\n", iDDL)); + continue; } - dspLength = totalDspLength - fDspHeader->GetHeaderLength(); + AliMUONBusStruct* busStructPtr = static_cast(busPatchMap.GetValue(iBusPatch)); - buffer[indexDsp+1] = totalDspLength; // dsp total length - buffer[indexDsp+2] = dspLength; // data length - - } // dsp + // check if buspatchid has digit + if (busStructPtr) + { + // add bus patch structure header + Int_t busHeaderLength = busStructPtr->GetHeaderLength(); + memcpy(&fBuffer[index],busStructPtr->GetHeader(),busHeaderLength*4); + index += busHeaderLength; + + // add bus patch data + Int_t busLength = busStructPtr->GetLength(); + memcpy(&fBuffer[index],busStructPtr->GetData(),busLength*4); + index += busLength; + } + else + { + // writting anyhow buspatch structure (empty ones) + fBuffer[index++] = busStructPtr->GetDefaultDataKey(); // fill it also for empty data size + fBuffer[index++] = busStructPtr->GetHeaderLength(); // header length + fBuffer[index++] = 0; // raw data length + fBuffer[index++] = iBusPatch; // bus patch + } + } // bus patch - totalBlkLength = index - indexBlk; - blkLength = totalBlkLength - fBlockHeader->GetHeaderLength(); - totalDDLLength += totalBlkLength; + // check if totalLength even + // set padding word in case + // Add one word 0xBEEFFACE at the end of DSP structure + Int_t totalDspLength = index - indexDsp; + if ((totalDspLength % 2) == 1) + { + fBuffer[indexDsp + fDspHeader->GetHeaderLength() - 2] = 1; + fBuffer[index++] = fDspHeader->GetDefaultPaddingWord(); + totalDspLength++; + } - buffer[indexBlk+1] = totalBlkLength; // total block length - buffer[indexBlk+2] = blkLength; + Int_t dspLength = totalDspLength - fDspHeader->GetHeaderLength(); - } // block - - //writting onto disk - // write DDL 1 - 4 - // total length in bytes - fHeader.fSize = (totalDDLLength + headerSize) * 4; + fBuffer[indexDsp+1] = totalDspLength; // dsp total length + fBuffer[indexDsp+2] = dspLength; // data length - fwrite((char*)(&fHeader),headerSize*4,1,fFile[iFile]); - fwrite(buffer,sizeof(int),index,fFile[iFile]); - } + } // dsp + + Int_t totalBlkLength = index - indexBlk; + Int_t blkLength = totalBlkLength - fBlockHeader->GetHeaderLength(); + totalDDLLength += totalBlkLength; + + fBuffer[indexBlk+1] = totalBlkLength; // total block length + fBuffer[indexBlk+2] = blkLength; + + } // block - fTimers[kWriteTracker].Stop(); - return kTRUE; + // add twice the end of CRT structure data key + // hope it's good placed (ChF) + fBuffer[index++] = fBlockHeader->GetDdlDataKey(); + fBuffer[index++] = fBlockHeader->GetDdlDataKey(); + totalDDLLength += 2; + + // writting onto disk + // total length in bytes + // DDL header + + Int_t headerSize = sizeof(AliRawDataHeader)/4; + + fHeader->fSize = (totalDDLLength + headerSize) * 4; + + AliFstream* file = new AliFstream(AliDAQ::DdlFileName("MUONTRK",iDDL)); + + file->WriteBuffer((char*)fHeader,headerSize*4); + file->WriteBuffer((char*)fBuffer,sizeof(int)*index); + delete file; } -//____________________________________________________________________ -Int_t AliMUONRawWriter::GetBusPatch(const AliMUONDigit& digit) const +//______________________________________________________________________________ +Int_t AliMUONRawWriter::GetBusPatch(const AliMUONVDigit& digit) const { /// Determine the BusPatch this digit belongs to. return fDDLStore->GetBusPatchId(digit.DetElemId(),digit.ManuId()); } -//____________________________________________________________________ -Int_t AliMUONRawWriter::WriteTriggerDDL() +//______________________________________________________________________________ +Int_t AliMUONRawWriter::WriteTriggerDDL(const AliMUONVTriggerStore& triggerStore, AliFstream* file[2]) { /// Write trigger DDL - - fTimers[kWriteTrigger].Start(kFALSE); - // DDL event one per half chamber + AliCodeTimerAuto("",0) - // stored local id number - TArrayI isFired(256); - isFired.Reset(); + if (fHeader == 0x0) { + AliError("Raw data header must be set"); + return 0; + } + // DDL event one per half chamber // DDL header size Int_t headerSize = sizeof(AliRawDataHeader)/4; - TClonesArray* localTrigger; - TClonesArray* globalTrigger; - TClonesArray* regionalTrigger; - - AliMUONGlobalTrigger* gloTrg; - AliMUONLocalTrigger* locTrg = 0x0; - AliMUONRegionalTrigger* regTrg = 0x0; - // global trigger for trigger pattern - globalTrigger = fMUONData->GlobalTrigger(); - gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0); + AliMUONGlobalTrigger* gloTrg = triggerStore.Global(); if (!gloTrg) { - fTimers[kWriteTrigger].Stop(); return 0; } Int_t gloTrigResp = gloTrg->GetGlobalResponse(); - - // local trigger - localTrigger = fMUONData->LocalTrigger(); - - - // regional trigger - regionalTrigger = fMUONData->RegionalTrigger(); - + UInt_t *gloTrigInput = gloTrg->GetGlobalInput(); UInt_t word; Int_t* buffer = 0; Int_t index; - Int_t iEntries = 0; - Int_t iLocCard, locCard; + Int_t locCard; UChar_t locDec, trigY, posY, posX, regOut; UInt_t regInpLpt; UInt_t regInpHpt; UInt_t devX; + UChar_t sdevX; UInt_t version = 1; // software version UInt_t eventPhys = 1; // trigger type: 1 for physics, 0 for software UInt_t serialNb = 0xF; // serial nb of card: all bits on for the moment @@ -627,19 +511,10 @@ Int_t AliMUONRawWriter::WriteTriggerDDL() (kRegHeaderLength + kRegScalerLength +1))* 8 + (kDarcHeaderLength + kDarcScalerLength + kGlobalHeaderLength + kGlobalScalerLength + 2); - if(fScalerEvent) + if(fScalerEvent) { eventPhys = 0; //set to generate scaler events - - Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards - // stored the local card id that's fired - for (Int_t i = 0; i < nEntries; i++) { - locTrg = (AliMUONLocalTrigger*)localTrigger->At(i); - isFired[locTrg->LoCircuit()] = 1; // storing local boards with informations + fHeader->fWord2 |= (0x1 << 14); // set L1SwC bit on } - - if (!nEntries) - AliDebug(1, "No Trigger information available"); - if(fScalerEvent) buffer = new Int_t [kScalerBufferSize]; else @@ -648,8 +523,8 @@ Int_t AliMUONRawWriter::WriteTriggerDDL() // reset crate // open DDL file, on per 1/2 chamber - for (Int_t iDDL = 0; iDDL < 2; iDDL++) { - + for ( Int_t iDDL = 0; iDDL < 2; ++iDDL ) + { index = 0; if (iDDL == 0) // suppose global info in DDL one @@ -670,10 +545,14 @@ Int_t AliMUONRawWriter::WriteTriggerDDL() index += kDarcHeaderLength; // no global input for the moment.... - if (iDDL == 0) - fDarcHeader->SetGlobalOutput(gloTrigResp); - else - fDarcHeader->SetGlobalOutput(0); + if (iDDL == 0) { + fDarcHeader->SetGlobalOutput(gloTrigResp); + for (Int_t ii = 0; ii < 4; ii++) { + fDarcHeader->SetGlobalInput(gloTrigInput[ii],ii); + } + } else { + fDarcHeader->SetGlobalOutput(0); + } if (fScalerEvent) { // 6 DARC scaler words @@ -689,29 +568,33 @@ Int_t AliMUONRawWriter::WriteTriggerDDL() if (fScalerEvent) { // 10 Global scaler words - memcpy(fDarcHeader->GetGlobalScalers(), &buffer[index], kGlobalScalerLength*4); + memcpy(&buffer[index], fDarcHeader->GetGlobalScalers(), kGlobalScalerLength*4); index += kGlobalScalerLength; } // end of global word buffer[index++] = fDarcHeader->GetEndOfGlobal(); + const AliMpRegionalTrigger* reg = AliMpDDLStore::Instance()->GetRegionalTrigger(); + Int_t nCrate = reg->GetNofTriggerCrates()/2; // 8 regional cards per DDL - for (Int_t iReg = 0; iReg < 8; iReg++) { + for (Int_t iReg = 0; iReg < nCrate; ++iReg) { - // crate info - AliMUONTriggerCrate* crate = fCrateManager->Crate(iDDL, iReg); + // crate info + AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->GetTriggerCrate(iDDL, iReg); - if (!crate) - AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, iDDL)); + if (!crate) { + AliError(Form("Missing crate number %d in DDL %d\n", iReg, iDDL)); + continue; + } // regional info tree, make sure that no reg card missing - for (Int_t i = 0; i < 16; ++i) { - regTrg = (AliMUONRegionalTrigger*)regionalTrigger->At(i); - if (regTrg) - if (regTrg->GetId() == (iReg + iDDL*8)) break; - } - + AliMUONRegionalTrigger* regTrg = triggerStore.FindRegional(crate->GetId()); + if (!regTrg) { + AliError(Form("Missing regional board %d in trigger Store\n", crate->GetId())); + continue; + } + // Regional card header word = 0; @@ -719,15 +602,15 @@ Int_t AliMUONRawWriter::WriteTriggerDDL() fRegHeader->SetDarcWord(word); regOut = regTrg->GetOutput(); - regInpHpt = regTrg->GetLocalOutput(0); - regInpLpt = regTrg->GetLocalOutput(1); + regInpLpt = regTrg->GetLocalOutput(0); + regInpHpt = regTrg->GetLocalOutput(1); // fill darc word, not darc status for the moment (empty) //see AliMUONRegHeader.h for details AliBitPacking::PackWord((UInt_t)eventPhys,word,31,31); - AliBitPacking::PackWord((UInt_t)serialNb,word,19,24); - AliBitPacking::PackWord((UInt_t)version,word,16,23); - AliBitPacking::PackWord((UInt_t)iReg,word,15,18); + AliBitPacking::PackWord((UInt_t)serialNb,word,20,25); + AliBitPacking::PackWord((UInt_t)version,word,8,15); + AliBitPacking::PackWord((UInt_t)crate->GetId(),word,16,19); AliBitPacking::PackWord((UInt_t)regOut,word,0,7); fRegHeader->SetWord(word); @@ -745,109 +628,104 @@ Int_t AliMUONRawWriter::WriteTriggerDDL() // end of regional word buffer[index++] = fRegHeader->GetEndOfReg(); - TObjArray *boards = crate->Boards(); - - // 16 local card per regional board // UShort_t localMask = 0x0; + + Int_t nLocalBoard = AliMpConstants::LocalBoardNofChannels(); - for (Int_t iLoc = 0; iLoc < 16; iLoc++) { - + for (Int_t iLoc = 0; iLoc < nLocalBoard; iLoc++) { + // slot zero for Regional card - AliMUONLocalTriggerBoard* localBoard = (AliMUONLocalTriggerBoard*)boards->At(iLoc+1); - - if (localBoard) { // if not empty slot - - if ((iLocCard = localBoard->GetNumber()) != 0) {// if notified board - - if (isFired[iLocCard]) { // if card has triggered - locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries++); - locCard = locTrg->LoCircuit(); - locDec = locTrg->GetLoDecision(); - trigY = 0; - posY = locTrg->LoStripY(); - posX = locTrg->LoStripX(); - devX = locTrg->LoDev(); - - AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n", - locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev())); - } else { //no trigger (see PRR chpt 3.4) - locDec = 0; - trigY = 1; - posY = 15; - posX = 0; - devX = 0x8; - // set local card id to -1 - locCard = -1; - } - - //packing word - word = 0; - AliBitPacking::PackWord((UInt_t)iLoc,word,19,22); //card id number in crate - AliBitPacking::PackWord((UInt_t)locDec,word,15,18); - AliBitPacking::PackWord((UInt_t)trigY,word,14,14); - AliBitPacking::PackWord((UInt_t)posY,word,10,13); - AliBitPacking::PackWord((UInt_t)devX,word,5,9); - AliBitPacking::PackWord((UInt_t)posX,word,0,4); - - if (locCard == iLocCard) { - // add local cards structure - buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16)); - buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16)); - buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16)); - buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16)); - buffer[index++] = (Int_t)word; // data word - - } else { - buffer[index++] = 0; // 4 words for x1, x2, y1, y2 - buffer[index++] = 0; - buffer[index++] = 0; - buffer[index++] = 0; - buffer[index++] = (Int_t)word; // data word - - } - } else {// number!=0 - // fill with 10CDEAD word for 'non-notified' slots - for (Int_t i = 0; i < fLocalStruct->GetLength(); i++) - buffer[index++] = fLocalStruct->GetDisableWord(); + Int_t localBoardId = crate->GetLocalBoardId(iLoc); + + if (localBoardId) { // if not empty slot + AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(localBoardId); + + if (localBoard->IsNotified()) {// if notified board + AliMUONLocalTrigger* locTrg = triggerStore.FindLocal(localBoardId); + + if (locTrg) + { + locCard = locTrg->LoCircuit(); + locDec = locTrg->GetLoDecision(); + trigY = locTrg->LoTrigY(); + posY = locTrg->LoStripY(); + posX = locTrg->LoStripX(); + devX = locTrg->LoDev(); + sdevX = locTrg->LoSdev(); + + AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n", + locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev())); + //packing word + word = 0; + LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, + (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX); + + buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16)); + buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16)); + buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16)); + buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16)); + buffer[index++] = (Int_t)word; // data word + } + } + // fill copy card X-Y inputs from the notified cards + if (localBoard->GetInputXfrom() && localBoard->GetInputYfrom()) + { + // not triggered + locDec = 0; trigY = 1; posY = 15; + posX = 0; devX = 0; sdevX = 1; + LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, + (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX); + + Int_t localFromId = localBoard->GetInputXfrom(); + AliMUONLocalTrigger* locTrgfrom = triggerStore.FindLocal(localFromId); + + if ( locTrgfrom ) + { + buffer[index++] = 0; // copy only X3-4 & Y1-4 + buffer[index++] = (locTrgfrom->GetX3Pattern() | (locTrgfrom->GetX4Pattern() << 16)); + buffer[index++] = (locTrgfrom->GetY1Pattern() | (locTrgfrom->GetY2Pattern() << 16)); + buffer[index++] = (locTrgfrom->GetY3Pattern() | (locTrgfrom->GetY4Pattern() << 16)); + buffer[index++] = word; + } } + } else { // fill with 10CDEAD word for empty slots for (Int_t i = 0; i < fLocalStruct->GetLength(); i++) - buffer[index++] = fLocalStruct->GetDisableWord(); + buffer[index++] = fLocalStruct->GetDisableWord(); }// condition localBoard - + // 45 regional scaler word if (fScalerEvent) { memcpy(&buffer[index], fLocalStruct->GetScalers(), kLocScalerLength*4); index += kLocScalerLength; } - + // end of local structure words - buffer[index++] = fLocalStruct->GetEndOfLocal(); - + buffer[index++] = fLocalStruct->GetEndOfLocal(); + } // local card // fill regional header with local output - fRegHeader->SetInput(regInpHpt, 0); + fRegHeader->SetInput(regInpLpt, 0); fRegHeader->SetInput(regInpHpt, 1); memcpy(&buffer[indexReg],fRegHeader->GetHeader(),kRegHeaderLength*4); - + } // Regional card // writting onto disk // write DDL's - fHeader.fSize = (index + headerSize) * 4;// total length in bytes - fwrite((char*)(&fHeader),headerSize*4,1,fFile[iDDL]); - fwrite(buffer,sizeof(int),index,fFile[iDDL]); + fHeader->fSize = (index + headerSize) * 4;// total length in bytes + file[iDDL]->WriteBuffer((char*)fHeader,headerSize*4); + file[iDDL]->WriteBuffer((char*)buffer,sizeof(int)*index); } delete[] buffer; - fTimers[kWriteTrigger].Stop(); - return kTRUE; } + //____________________________________________________________________ void AliMUONRawWriter::SetScalersNumbers() {