LCOV - code coverage report
Current view: top level - MUON/MUONbase - AliMUONRawWriter.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 266 306 86.9 %
Date: 2016-06-14 17:26:59 Functions: 12 13 92.3 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : /* $Id$ */
      17             : 
      18             : //-----------------------------------------------------------------------------
      19             : /// \class AliMUONRawWriter
      20             : /// MUON Raw Data generaton in ALICE-MUON
      21             : /// Raw data structure could be found in Alice-note.
      22             : ///
      23             : /// Implemented non-constant buspatch numbers for tracking
      24             : /// with correct DDL id (first guess)
      25             : /// (Ch. Finck, dec 2005)
      26             : ///
      27             : /// Digits2Raw:
      28             : /// Generates raw data for MUON tracker and finally for trigger
      29             : /// Using real mapping (inverse) for tracker
      30             : /// For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
      31             : /// Ch. Finck, July 04
      32             : /// Use memcpy instead of assignment elt by elt
      33             : /// Introducing variable DSP numbers, real manu numbers per buspatch for st12
      34             : /// Implemented scaler event for Trigger
      35             : /// Ch. Finck, Jan. 06
      36             : /// Using bus itr in DDL instead of simple incrementation
      37             : /// treat correctly the DDL & buspatch for station 3.
      38             : /// Using informations from AliMUONTriggerCrateStore for 
      39             : /// empty slots and non-notified cards in trigger crates.
      40             : /// Ch. Finck, August 06.
      41             : /// Using AliMpDDLStore::GetBusPatchId.
      42             : ///
      43             : /// \author Ch. Finck, Feb. 07.
      44             : //-----------------------------------------------------------------------------
      45             : 
      46             : 
      47             : #include "AliMUONRawWriter.h"
      48             : 
      49             : #include "AliMUONBlockHeader.h"
      50             : #include "AliMUONBusStruct.h"
      51             : #include "AliMUONConstants.h"
      52             : #include "AliMUONDarcHeader.h"
      53             : #include "AliMUONVDigit.h"
      54             : #include "AliMUONVDigitStore.h"
      55             : #include "AliMUONDspHeader.h"
      56             : #include "AliMUONGlobalTrigger.h"
      57             : #include "AliMUONLocalStruct.h"
      58             : #include "AliMUONLocalTrigger.h"
      59             : #include "AliMUONLocalTriggerBoard.h"
      60             : #include "AliMUONRegionalTrigger.h"
      61             : #include "AliMUONRegHeader.h"
      62             : 
      63             : #include "AliMUONVTriggerStore.h"
      64             : #include "AliCodeTimer.h"
      65             : 
      66             : #include "AliMpCDB.h"
      67             : #include "AliMpDDLStore.h"
      68             : #include "AliMpDDL.h"
      69             : #include "AliMpRegionalTrigger.h"
      70             : #include "AliMpTriggerCrate.h"
      71             : #include "AliMpLocalBoard.h"
      72             : #include "AliMpDetElement.h"
      73             : #include "AliMpDEManager.h"
      74             : #include "AliMpExMap.h"
      75             : #include "AliMpConstants.h"
      76             : #include "AliMpPlaneType.h"
      77             : #include "AliMpSegmentation.h"
      78             : #include "AliMpStationType.h"
      79             : #include "AliMpVSegmentation.h"
      80             : 
      81             : #include "AliRawReader.h"
      82             : #include "AliRawDataHeaderSim.h"
      83             : #include "AliBitPacking.h" 
      84             : #include "AliDAQ.h"
      85             : #include "AliLog.h"
      86             : 
      87             : #include "TObjArray.h"
      88             : #include "TStopwatch.h"
      89             : #include <Riostream.h>
      90             : 
      91             : /// \cond CLASSIMP
      92          18 : ClassImp(AliMUONRawWriter) // Class implementation in ROOT context
      93             : /// \endcond
      94             : 
      95             : //__________________________________________________________________________
      96             : AliMUONRawWriter::AliMUONRawWriter()
      97           1 :   : TObject(),
      98           3 :     fBlockHeader(new AliMUONBlockHeader()),
      99           3 :     fDspHeader(new AliMUONDspHeader()),
     100           3 :     fDarcHeader(new AliMUONDarcHeader()),
     101           3 :     fRegHeader(new AliMUONRegHeader()),
     102           3 :     fLocalStruct(new AliMUONLocalStruct()),
     103           2 :     fDDLStore(AliMpDDLStore::Instance()),
     104           1 :     fScalerEvent(kFALSE),
     105           1 :     fHeader(0x0),
     106           1 :     fBufferSize((((43*AliMpConstants::ManuNofChannels() + 4)*5 + 10)*5 + 8)*2),
     107           2 :     fBuffer(new Int_t [fBufferSize])
     108           5 : {
     109             :   /// Standard Constructor
     110             : 
     111           5 :   AliDebug(1,"Standard ctor");
     112             : 
     113             :   // setting data key to default value (only for writting)
     114           1 :   fBlockHeader->SetDataKey(fBlockHeader->GetDefaultDataKey());
     115           1 :   fDspHeader->SetDataKey(fDspHeader->GetDefaultDataKey());
     116             : 
     117             :   // Load mapping
     118           1 :   if ( ! fDDLStore ) {
     119           0 :     if ( ! AliMpCDB::LoadDDLStore() ) {
     120           0 :       AliFatal("Could not access mapping from OCDB !");
     121             :     }
     122           0 :     fDDLStore = AliMpDDLStore::Instance();
     123           0 :   }  
     124           2 : }
     125             : 
     126             : //__________________________________________________________________________
     127             : AliMUONRawWriter::~AliMUONRawWriter(void)
     128           6 : {
     129             :   /// Destructor
     130             : 
     131           5 :   AliDebug(1,"dtor");
     132             :   
     133           2 :   delete fBlockHeader;
     134           2 :   delete fDspHeader;
     135           2 :   delete fDarcHeader;
     136           2 :   delete fRegHeader;
     137           2 :   delete fLocalStruct;
     138           2 :   delete[] fBuffer;
     139           3 : }
     140             : 
     141             : //____________________________________________________________________
     142             : void  AliMUONRawWriter::LocalWordPacking(UInt_t& word, UInt_t locId, UInt_t locDec, 
     143             :                                          UInt_t trigY, UInt_t posY, UInt_t posX, 
     144             :                                          UInt_t sdevX, UInt_t devX)
     145             : {
     146             : /// pack local trigger word
     147             : 
     148        1936 :     AliBitPacking::PackWord(locId,word,19,22); //card id number in crate
     149         968 :     AliBitPacking::PackWord(locDec,word,15,18);
     150         968 :     AliBitPacking::PackWord(trigY,word,14,14);
     151         968 :     AliBitPacking::PackWord(posY,word,10,13);
     152         968 :     AliBitPacking::PackWord(sdevX,word,9,9);
     153         968 :     AliBitPacking::PackWord(devX,word,5,8);
     154         968 :     AliBitPacking::PackWord(posX,word,0,4);
     155             : 
     156         968 : }
     157             : 
     158             : //____________________________________________________________________
     159             : Int_t AliMUONRawWriter::Digits2Raw(const AliMUONVDigitStore* digitStore,
     160             :                                    const AliMUONVTriggerStore* triggerStore)
     161             : {
     162             :   /// convert digits of the current event to raw data
     163             : 
     164           8 :   AliCodeTimerAuto("",0)
     165             :   
     166             :   Int_t idDDL;
     167             : 
     168             :   // tracking chambers
     169             :   
     170           4 :   if ( digitStore ) 
     171             :   {
     172           8 :     AliCodeTimerAuto("for Tracker",1)
     173             : 
     174           4 :     AliMpExMap busPatchMap;
     175             : 
     176           4 :     Int_t nDDLs = AliDAQ::NumberOfDdls("MUONTRK");
     177             :     
     178             :     Int_t nofBusPatches(0);
     179             :     
     180         168 :     for (Int_t iDDL = 0; iDDL < nDDLs; ++iDDL ) 
     181             :     {
     182          80 :       AliMpDDL* ddl = fDDLStore->GetDDL(iDDL);
     183         160 :       nofBusPatches += ddl->GetNofBusPatches();
     184             :     }
     185             :     
     186           4 :     busPatchMap.SetSize(nofBusPatches);
     187             :     
     188           4 :     Digits2BusPatchMap(*digitStore,busPatchMap);
     189             : 
     190         168 :     for (Int_t iDDL = 0; iDDL < nDDLs; ++iDDL ) 
     191             :     {
     192          80 :       WriteTrackerDDL(busPatchMap,iDDL);
     193             :     }
     194          20 :     AliDebug(1,"Tracker written");
     195           4 :   }
     196             :  
     197           4 :   if ( triggerStore )
     198             :   {
     199           8 :     AliCodeTimerAuto("for Trigger",1)
     200             : 
     201             :     // trigger chambers
     202             :     
     203           4 :     AliFstream* file[2];
     204             :     
     205             :     // open files
     206             :     idDDL = 0;// MUTR
     207          16 :     file[0] = new AliFstream(AliDAQ::DdlFileName("MUONTRG",idDDL));
     208             :     
     209             :     idDDL = 1;// MUTR
     210          16 :     file[1] = new AliFstream(AliDAQ::DdlFileName("MUONTRG",idDDL));
     211             :       
     212           4 :     WriteTriggerDDL(*triggerStore,file);
     213             :       
     214             :     // reset and close
     215           8 :     delete file[0];
     216           8 :     delete file[1];
     217             :       
     218          20 :     AliDebug(1,"Trigger written");
     219           4 :   }
     220             :   
     221             :   return kTRUE;
     222           4 : }
     223             : 
     224             : //______________________________________________________________________________
     225             : void 
     226             : AliMUONRawWriter::Digits2BusPatchMap(const AliMUONVDigitStore& digitStore,
     227             :                                      AliMpExMap& busPatchMap)
     228             : {
     229             :   /// Create bus patch structures corresponding to digits in the store
     230             :   
     231           8 :   AliCodeTimerAuto("",0)
     232             :   
     233             :   static const Int_t kMAXADC = (1<<12)-1; // We code the charge on a 12 bits ADC.
     234             :     
     235             :   // DDL event one per half chamber
     236             :   
     237             :   // raw data
     238             :   Char_t parity = 0x4;
     239             :   UShort_t manuId = 0;
     240             :   UChar_t channelId = 0;
     241             :   UShort_t charge = 0;
     242             :   Int_t busPatchId = 0;
     243             :   Int_t currentBusPatchId = -1;
     244           4 :   UInt_t word;
     245             :   
     246             :   AliMUONBusStruct* busStruct(0x0);
     247             :   
     248           8 :   TIter next(digitStore.CreateTrackerIterator());
     249             :   AliMUONVDigit* digit;
     250             :   
     251        1428 :   while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
     252             :   {
     253        1416 :     charge = digit->ADC();
     254         708 :     if ( charge > kMAXADC )
     255             :     {
     256             :       // This is most probably an error in the digitizer (which should insure
     257             :       // the adc is below kMAXADC), so make it a (non-fatal) error indeed.
     258           0 :       AliError(Form("adc value %d above 0x%x for DE %d . Setting to 0x%x. Digit is:",
     259             :                     charge,kMAXADC,digit->DetElemId(),kMAXADC));
     260           0 :       StdoutToAliError(digit->Print());
     261             :       charge = kMAXADC;
     262           0 :     }
     263             :     
     264             :     // inverse mapping
     265         708 :     busPatchId = GetBusPatch(*digit);
     266             : 
     267         708 :     if (busPatchId<0) continue;
     268             :     
     269        2124 :     if ( digit->ManuId() > 0x7FF ||
     270        1416 :          digit->ManuChannel() > 0x3F )
     271             :     {
     272           0 :       StdoutToAliError(digit->Print(););
     273           0 :       AliFatal("ManuId,ManuChannel are invalid for the digit above.");
     274             :     }
     275             :     
     276        1416 :     manuId = ( digit->ManuId() & 0x7FF ); // 11 bits
     277        1416 :     channelId = ( digit->ManuChannel() & 0x3F ); // 6 bits
     278             :     
     279             :     //packing word
     280         708 :     word = 0;
     281         708 :     AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
     282         708 :     AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
     283         708 :     AliBitPacking::PackWord((UInt_t)charge,word,0,11);
     284             :     
     285             :     // parity word
     286         708 :     parity = word & 0x1;
     287       43896 :     for (Int_t i = 1; i <= 30; ++i) 
     288             :     {
     289       21240 :       parity ^=  ((word >> i) & 0x1);
     290             :     }
     291         708 :     AliBitPacking::PackWord((UInt_t)parity,word,31,31);
     292             : 
     293         708 :     if ( currentBusPatchId != busPatchId ) 
     294             :     {
     295             :       busStruct = 
     296         274 :         static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(busPatchId));
     297             :       currentBusPatchId = busPatchId;
     298         137 :     }
     299             :     
     300         708 :     if (!busStruct)
     301             :     {
     302         256 :       busStruct = new AliMUONBusStruct;
     303         128 :       busStruct->SetDataKey(busStruct->GetDefaultDataKey());
     304         128 :       busStruct->SetBusPatchId(busPatchId);
     305         128 :       busStruct->SetLength(0);
     306         128 :       busPatchMap.Add(busPatchId,busStruct);
     307             :     }
     308             :     
     309             :     // set sub Event
     310         708 :     busStruct->AddData(word);
     311             :   }
     312           4 : }
     313             : 
     314             : //______________________________________________________________________________
     315             : void
     316             : AliMUONRawWriter::WriteTrackerDDL(AliMpExMap& busPatchMap, Int_t iDDL)
     317             : {
     318             :   /// Write DDL file for one tracker DDL
     319             :   
     320             :   // buffer size (max'ed out)
     321             :   // (((43 manus max per bus patch *64 channels + 4 bus patch words) * 5 bus patch 
     322             :   //   + 10 dsp words)*5 dsps + 8 block words)*2 blocks 
     323             :  
     324         160 :   AliCodeTimerAuto("",0)
     325             : 
     326          80 :   if (fHeader == 0x0) {
     327           0 :     AliError("Raw data header must be set");
     328           0 :     return;
     329             :   }
     330          80 :   memset(fBuffer,0,fBufferSize*sizeof(Int_t));
     331             :   
     332          80 :   AliMpDDL* ddl = fDDLStore->GetDDL(iDDL);
     333          80 :   Int_t iDspMax = ddl->GetMaxDsp();
     334          80 :   Int_t iBusPerDSP[5]; //number of bus patches per DSP
     335          80 :   ddl->GetBusPerDsp(iBusPerDSP);
     336             :   Int_t busIter = 0;
     337             :   
     338             :   Int_t totalDDLLength = 0;
     339             :   
     340             :   Int_t index = 0;
     341             :   
     342             :   // two blocks A and B per DDL
     343         480 :   for (Int_t iBlock = 0; iBlock < 2; ++iBlock) 
     344             :   {
     345             :     // block header
     346         160 :     Int_t length = fBlockHeader->GetHeaderLength();
     347         160 :     memcpy(&fBuffer[index],fBlockHeader->GetHeader(),length*4);
     348             :     Int_t indexBlk = index;
     349         160 :     index += length; 
     350             :     
     351             :     // 5 DSP's max per block
     352        1792 :     for (Int_t iDsp = 0; iDsp < iDspMax; ++iDsp) 
     353             :     {
     354             :       // DSP header
     355         736 :       Int_t dspHeaderLength = fDspHeader->GetHeaderLength();
     356         736 :       memcpy(&fBuffer[index],fDspHeader->GetHeader(),dspHeaderLength*4);
     357             :       Int_t indexDsp = index;
     358         736 :       index += dspHeaderLength; 
     359             :       
     360             :       // 5 buspatches max per DSP
     361        8576 :       for (Int_t i = 0; i < iBusPerDSP[iDsp]; ++i) 
     362             :       {
     363        3552 :         Int_t iBusPatch = ddl->GetBusPatchId(busIter++);
     364             :         
     365             :         // iteration over bus patch in DDL
     366        3552 :         if (iBusPatch == -1) 
     367             :         {
     368           0 :           AliWarning(Form("Error in bus itr in DDL %d\n", iDDL));
     369           0 :           continue;
     370             :         }
     371             :         
     372        7104 :         AliMUONBusStruct* busStructPtr = static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(iBusPatch));
     373             :         
     374             :         // check if buspatchid has digit
     375        3552 :         if (busStructPtr) 
     376             :         {
     377             :           // add bus patch structure header
     378         128 :           Int_t busHeaderLength = busStructPtr->GetHeaderLength();
     379         128 :           memcpy(&fBuffer[index],busStructPtr->GetHeader(),busHeaderLength*4);
     380         128 :           index += busHeaderLength;
     381             :           
     382             :           // add bus patch data
     383         128 :           Int_t busLength = busStructPtr->GetLength();
     384         128 :           memcpy(&fBuffer[index],busStructPtr->GetData(),busLength*4);
     385         128 :           index += busLength;
     386         128 :         } 
     387             :         else 
     388             :         {
     389             :           // writting anyhow buspatch structure (empty ones)
     390        3424 :           fBuffer[index++] = busStructPtr->GetDefaultDataKey(); // fill it also for empty data size
     391        3424 :           fBuffer[index++] = busStructPtr->GetHeaderLength(); // header length
     392        3424 :           fBuffer[index++] = 0; // raw data length
     393        3424 :           fBuffer[index++] = iBusPatch; // bus patch
     394             :         }
     395        3552 :       } // bus patch
     396             :       
     397             :       // check if totalLength even
     398             :       // set padding word in case
     399             :       // Add one word 0xBEEFFACE at the end of DSP structure
     400         736 :       Int_t totalDspLength  = index - indexDsp;
     401         736 :       if ((totalDspLength % 2) == 1) 
     402             :       { 
     403          50 :         fBuffer[indexDsp + fDspHeader->GetHeaderLength() - 2] = 1;
     404          50 :         fBuffer[index++] = fDspHeader->GetDefaultPaddingWord();
     405          50 :         totalDspLength++;
     406          50 :       }
     407             :       
     408         736 :       Int_t dspLength     = totalDspLength - fDspHeader->GetHeaderLength();
     409             :       
     410         736 :       fBuffer[indexDsp+1] = totalDspLength; // dsp total length
     411         736 :       fBuffer[indexDsp+2] = dspLength; // data length  
     412             :       
     413             :     } // dsp
     414             :     
     415         160 :     Int_t totalBlkLength  = index - indexBlk;
     416         160 :     Int_t blkLength       = totalBlkLength - fBlockHeader->GetHeaderLength();
     417         160 :     totalDDLLength       += totalBlkLength;
     418             :     
     419         160 :     fBuffer[indexBlk+1] = totalBlkLength; // total block length
     420         160 :     fBuffer[indexBlk+2] = blkLength;
     421             :         
     422             :   } // block
     423             :   
     424             :     // add twice the end of CRT structure data key
     425             :     // hope it's good placed (ChF)
     426          80 :     fBuffer[index++] = fBlockHeader->GetDdlDataKey();
     427          80 :     fBuffer[index++] = fBlockHeader->GetDdlDataKey();
     428          80 :     totalDDLLength  += 2;
     429             :   
     430             :   // writting onto disk
     431             :   // total length in bytes
     432             :   // DDL header
     433             : 
     434             :   Int_t headerSize = sizeof(AliRawDataHeaderV3)/4;
     435             :   
     436          80 :   fHeader->fSize = (totalDDLLength + headerSize) * 4;
     437             :   
     438         240 :   AliFstream* file = new AliFstream(AliDAQ::DdlFileName("MUONTRK",iDDL));
     439             :   
     440          80 :   file->WriteBuffer((char*)fHeader,headerSize*4);
     441          80 :   file->WriteBuffer((char*)fBuffer,sizeof(int)*index);
     442         160 :   delete file;
     443         160 : }
     444             : 
     445             : //______________________________________________________________________________
     446             : Int_t AliMUONRawWriter::GetBusPatch(const AliMUONVDigit& digit) const
     447             : {
     448             :   /// Determine the BusPatch this digit belongs to.
     449             : 
     450        1416 :     return fDDLStore->GetBusPatchId(digit.DetElemId(),digit.ManuId());
     451             : }
     452             : 
     453             : //______________________________________________________________________________
     454             : Int_t AliMUONRawWriter::WriteTriggerDDL(const AliMUONVTriggerStore& triggerStore, AliFstream* file[2])
     455             : {
     456             :   /// Write trigger DDL
     457             :   
     458           8 :   AliCodeTimerAuto("",0)
     459             : 
     460           4 :   if (fHeader == 0x0) {
     461           0 :     AliError("Raw data header must be set");
     462           0 :     return 0;
     463             :   }
     464             : 
     465             :  // DDL event one per half chamber
     466             : 
     467             :  // DDL header size
     468             :   Int_t headerSize = sizeof(AliRawDataHeaderV3)/4;
     469             : 
     470             :   // global trigger for trigger pattern
     471           4 :   AliMUONGlobalTrigger* gloTrg = triggerStore.Global();
     472           4 :   if (!gloTrg) 
     473             :   {
     474           0 :     return 0;
     475             :   }
     476             :   
     477           8 :   Int_t gloTrigResp = gloTrg->GetGlobalResponse();
     478           4 :   UInt_t *gloTrigInput = gloTrg->GetGlobalInput();
     479             : 
     480           4 :   UInt_t word;
     481             :   Int_t* buffer = 0;
     482             :   Int_t index;
     483             :   UChar_t locDec, trigY, posY, posX, regOut;
     484             :   UInt_t regInpLpt;
     485             :   UInt_t regInpHpt;
     486             : 
     487             :   UInt_t devX;
     488             :   UChar_t sdevX;
     489             :   UInt_t version = 1; // software version
     490             :   UInt_t eventPhys = 1; // trigger type: 1 for physics, 0 for software
     491             :   UInt_t serialNb = 0xF; // serial nb of card: all bits on for the moment
     492             :   Int_t globalFlag = 0; // set to 1 if global info present in DDL else set to 0
     493             : 
     494             :   // size of headers
     495           6 :   static const Int_t kDarcHeaderLength   = fDarcHeader->GetDarcHeaderLength();
     496           6 :   static const Int_t kGlobalHeaderLength = fDarcHeader->GetGlobalHeaderLength();
     497           6 :   static const Int_t kDarcScalerLength   = fDarcHeader->GetDarcScalerLength();
     498           6 :   static const Int_t kGlobalScalerLength = fDarcHeader->GetGlobalScalerLength();
     499           6 :   static const Int_t kRegHeaderLength    = fRegHeader->GetHeaderLength();
     500           6 :   static const Int_t kRegScalerLength    = fRegHeader->GetScalerLength();
     501           6 :   static const Int_t kLocHeaderLength    = fLocalStruct->GetLength();
     502           6 :   static const Int_t kLocScalerLength    = fLocalStruct->GetScalerLength();
     503             : 
     504             :   // [16(local)*6 words + 6 words]*8(reg) + 8 words = 824 
     505           7 :   static const Int_t kBufferSize = (16 * (kLocHeaderLength+1) +  (kRegHeaderLength+1))* 8 
     506           1 :       +  kDarcHeaderLength + kGlobalHeaderLength + 2;
     507             : 
     508             :   // [16(local)*51 words + 16 words]*8(reg) + 8 + 10 + 8 words scaler event 6682 words
     509           8 :   static const Int_t kScalerBufferSize = (16 * (kLocHeaderLength +  kLocScalerLength +1) +  
     510           3 :                                          (kRegHeaderLength + kRegScalerLength +1))* 8 +
     511           2 :                                          (kDarcHeaderLength + kDarcScalerLength + 
     512           2 :                                           kGlobalHeaderLength + kGlobalScalerLength + 2);
     513           4 :   if(fScalerEvent) {
     514             :     eventPhys = 0; //set to generate scaler events
     515           0 :     fHeader->fWord2 |= (0x1 << 14); // set L1SwC bit on
     516           0 :   }
     517           4 :   if(fScalerEvent)
     518           0 :     buffer = new Int_t [kScalerBufferSize];
     519             :   else
     520           8 :     buffer = new Int_t [kBufferSize];
     521             : 
     522             :   // reset crate
     523             : 
     524             :   // open DDL file, on per 1/2 chamber
     525          24 :   for ( Int_t iDDL = 0; iDDL < 2; ++iDDL ) 
     526             :   {
     527             :     index = 0; 
     528             : 
     529           8 :     if (iDDL == 0) // suppose global info in DDL one
     530           4 :       globalFlag = 1;
     531             :     else 
     532             :       globalFlag = 0;
     533             : 
     534           8 :     word = 0;
     535             :     // set darc status word
     536             :     // see AliMUONDarcHeader.h for details
     537           8 :     AliBitPacking::PackWord((UInt_t)eventPhys,word,30,30);
     538           8 :     AliBitPacking::PackWord((UInt_t)serialNb,word,20,23);
     539           8 :     AliBitPacking::PackWord((UInt_t)globalFlag,word,10,10);
     540           8 :     AliBitPacking::PackWord((UInt_t)version,word,12,19);
     541           8 :     fDarcHeader->SetWord(word);
     542             : 
     543           8 :     memcpy(&buffer[index], fDarcHeader->GetHeader(), (kDarcHeaderLength)*4); 
     544           8 :     index += kDarcHeaderLength;
     545             : 
     546             :     // no global input for the moment....
     547           8 :     if (iDDL == 0) {
     548          12 :       fDarcHeader->SetGlobalOutput(gloTrigResp);
     549          40 :       for (Int_t ii = 0; ii < 4; ii++) {
     550          16 :         fDarcHeader->SetGlobalInput(gloTrigInput[ii],ii);
     551             :       }
     552           4 :     } else {
     553           4 :       fDarcHeader->SetGlobalOutput(0);
     554             :     }
     555             : 
     556           8 :     if (fScalerEvent) {
     557             :       // 6 DARC scaler words
     558           0 :       memcpy(&buffer[index], fDarcHeader->GetDarcScalers(),kDarcScalerLength*4);
     559           0 :       index += kDarcScalerLength;
     560           0 :     }
     561             :     // end of darc word
     562           8 :     buffer[index++] = fDarcHeader->GetEndOfDarc();
     563             : 
     564             :     // 4 words of global board input + Global board output
     565           8 :     memcpy(&buffer[index], fDarcHeader->GetGlobalInput(), (kGlobalHeaderLength)*4); 
     566           8 :     index += kGlobalHeaderLength; 
     567             : 
     568           8 :     if (fScalerEvent) {
     569             :       // 10 Global scaler words
     570           0 :       memcpy(&buffer[index], fDarcHeader->GetGlobalScalers(), kGlobalScalerLength*4);
     571           0 :       index += kGlobalScalerLength;
     572           0 :     }
     573             : 
     574             :     // end of global word
     575           8 :     buffer[index++] = fDarcHeader->GetEndOfGlobal();
     576          16 :     const AliMpRegionalTrigger* reg = AliMpDDLStore::Instance()->GetRegionalTrigger(); 
     577             : 
     578          16 :     Int_t nCrate = reg->GetNofTriggerCrates()/2;
     579             :     // 8 regional cards per DDL
     580         144 :     for (Int_t iReg = 0; iReg < nCrate; ++iReg) {
     581             : 
     582             :         // crate info
     583         128 :       AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->GetTriggerCrate(iDDL, iReg);
     584             : 
     585          64 :       if (!crate) {
     586           0 :         AliError(Form("Missing crate number %d in DDL %d\n", iReg, iDDL));
     587           0 :         continue;
     588             :       }  
     589             : 
     590             :       // regional info tree, make sure that no reg card missing
     591          64 :       AliMUONRegionalTrigger* regTrg  = triggerStore.FindRegional(crate->GetId());
     592          64 :       if (!regTrg) {
     593           0 :         AliError(Form("Missing regional board %d in trigger Store\n", crate->GetId()));
     594           0 :         continue;
     595             :       }  
     596             :     
     597             :       // Regional card header
     598          64 :       word = 0;
     599             : 
     600             :       // set darc status word
     601          64 :       fRegHeader->SetDarcWord(word);
     602             : 
     603          64 :       regOut    = regTrg->GetOutput();
     604          64 :       regInpLpt = regTrg->GetLocalOutput(0);
     605          64 :       regInpHpt = regTrg->GetLocalOutput(1);
     606             : 
     607             :       // fill darc word, not darc status for the moment (empty)
     608             :       //see  AliMUONRegHeader.h for details
     609          64 :       AliBitPacking::PackWord((UInt_t)eventPhys,word,31,31); 
     610          64 :       AliBitPacking::PackWord((UInt_t)serialNb,word,20,25); 
     611          64 :       AliBitPacking::PackWord((UInt_t)version,word,8,15);
     612          64 :       AliBitPacking::PackWord((UInt_t)crate->GetId(),word,16,19);
     613          64 :       AliBitPacking::PackWord((UInt_t)regOut,word,0,7); 
     614          64 :       fRegHeader->SetWord(word);
     615             : 
     616             : 
     617             :       // fill header later, need local response
     618             :       Int_t indexReg = index;
     619          64 :       index += kRegHeaderLength;
     620             : 
     621             :       // 11 regional scaler word
     622          64 :       if (fScalerEvent) {
     623           0 :         memcpy(&buffer[index], fRegHeader->GetScalers(), kRegScalerLength*4);
     624           0 :         index += kRegScalerLength;
     625           0 :       }
     626             : 
     627             :       // end of regional word
     628          64 :       buffer[index++] = fRegHeader->GetEndOfReg();
     629             :       
     630             :       // 16 local card per regional board
     631             :       //      UShort_t localMask = 0x0;
     632             :       
     633          64 :       Int_t nLocalBoard = AliMpConstants::LocalBoardNofChannels();
     634             : 
     635        2176 :       for (Int_t iLoc = 0; iLoc < nLocalBoard; iLoc++) {
     636             :           
     637             :         // slot zero for Regional card
     638        1024 :         Int_t localBoardId = crate->GetLocalBoardId(iLoc);
     639             : 
     640        1024 :         if (localBoardId) { // if not empty slot
     641        1936 :           AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(localBoardId);
     642             : 
     643         968 :           if (localBoard->IsNotified()) {// if notified board 
     644         936 :             AliMUONLocalTrigger* locTrg = triggerStore.FindLocal(localBoardId);
     645             : 
     646         936 :       if (locTrg)
     647             :       {
     648         936 :         locDec  = locTrg->GetLoDecision();
     649         936 :         trigY   = locTrg->LoTrigY();
     650         936 :         posY    = locTrg->LoStripY();
     651         936 :         posX    = locTrg->LoStripX();
     652         936 :         devX    = locTrg->LoDev();
     653         936 :         sdevX   = locTrg->LoSdev();
     654             :         
     655        4680 :         AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n", 
     656             :                         locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));  
     657             :         //packing word
     658         936 :         word = 0;
     659        1872 :         LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, 
     660         936 :                          (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX);
     661             :         
     662         936 :         buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
     663         936 :         buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
     664         936 :         buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
     665         936 :         buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
     666         936 :         buffer[index++] = (Int_t)word; // data word
     667         936 :       }
     668         936 :           }
     669             :           // fill copy card X-Y inputs from the notified cards 
     670        1000 :           if (localBoard->GetInputXfrom() && localBoard->GetInputYfrom()) 
     671             :           {
     672             :             // not triggered
     673             :             locDec = 0; trigY = 1; posY = 15;    
     674             :             posX   = 0; devX  = 0; sdevX = 1;
     675          32 :             LocalWordPacking(word, (UInt_t)iLoc, (UInt_t)locDec, (UInt_t)trigY, (UInt_t)posY, 
     676             :                              (UInt_t)posX, (UInt_t)sdevX, (UInt_t)devX);
     677             : 
     678          32 :             Int_t localFromId = localBoard->GetInputXfrom();
     679          32 :             AliMUONLocalTrigger* locTrgfrom  = triggerStore.FindLocal(localFromId);
     680             : 
     681          32 :       if ( locTrgfrom ) 
     682             :       {
     683          32 :         buffer[index++] = 0; // copy only X3-4 & Y1-4
     684          32 :         buffer[index++] = (locTrgfrom->GetX3Pattern() | (locTrgfrom->GetX4Pattern() << 16));
     685          32 :         buffer[index++] = (locTrgfrom->GetY1Pattern() | (locTrgfrom->GetY2Pattern() << 16));
     686          32 :         buffer[index++] = (locTrgfrom->GetY3Pattern() | (locTrgfrom->GetY4Pattern() << 16));
     687          32 :         buffer[index++] = word;
     688          32 :       }
     689          32 :           }
     690             : 
     691         968 :         } else { 
     692             :           // fill with 10CDEAD word for empty slots
     693         672 :           for (Int_t i = 0; i < fLocalStruct->GetLength(); i++)
     694         280 :               buffer[index++] = fLocalStruct->GetDisableWord(); 
     695             :         }// condition localBoard
     696             :           
     697             :         // 45 regional scaler word
     698        1024 :         if (fScalerEvent) {
     699           0 :           memcpy(&buffer[index], fLocalStruct->GetScalers(), kLocScalerLength*4);
     700           0 :           index += kLocScalerLength;
     701           0 :         }
     702             :           
     703             :         // end of local structure words
     704        1024 :         buffer[index++] = fLocalStruct->GetEndOfLocal();
     705             :           
     706             :       } // local card 
     707             :       // fill regional header with local output
     708          64 :       fRegHeader->SetInput(regInpLpt, 0);
     709          64 :       fRegHeader->SetInput(regInpHpt, 1);
     710          64 :       memcpy(&buffer[indexReg],fRegHeader->GetHeader(),kRegHeaderLength*4);
     711             :       
     712          64 :     } // Regional card
     713             :     
     714             : 
     715             :     // writting onto disk
     716             :     // write DDL's
     717           8 :     fHeader->fSize = (index + headerSize) * 4;// total length in bytes
     718           8 :     file[iDDL]->WriteBuffer((char*)fHeader,headerSize*4);
     719           8 :     file[iDDL]->WriteBuffer((char*)buffer,sizeof(int)*index);
     720             :   
     721             :   }
     722           8 :   delete[] buffer;
     723             : 
     724             :   return kTRUE;
     725           8 : }
     726             : 
     727             : //____________________________________________________________________
     728             : void AliMUONRawWriter::SetScalersNumbers()
     729             : {
     730             :   /// set numbers for scaler events for trigger headers
     731             :   /// since this is provided by the experiment
     732             :   /// put dummy numbers to check the monitoring
     733             : 
     734           0 :   fDarcHeader->SetScalersNumbers();
     735           0 :   fRegHeader->SetScalersNumbers();
     736           0 :   fLocalStruct->SetScalersNumbers();
     737             :  
     738           0 :   fScalerEvent = kTRUE;
     739           0 : }
     740             : 

Generated by: LCOV version 1.11