]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONRawWriter.cxx
Extended include path to cover all directories needed by all
[u/mrichter/AliRoot.git] / MUON / AliMUONRawWriter.cxx
CommitLineData
a19e2543 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
da8d4b6d 16/* $Id$ */
17
9265505b 18/// \class AliMUONRawWriter
19/// MUON Raw Data generaton in ALICE-MUON
5cab551d 20/// Raw data structure could be found in Alice-note.
9265505b 21///
22/// Implemented non-constant buspatch numbers for tracking
23/// with correct DDL id (first guess)
24/// (Ch. Finck, dec 2005)
25///
26/// Digits2Raw:
27/// Generates raw data for MUON tracker and finally for trigger
28/// Using real mapping (inverse) for tracker
29/// For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
30/// Ch. Finck, July 04
31/// Use memcpy instead of assignment elt by elt
32/// Introducing variable DSP numbers, real manu numbers per buspatch for st12
33/// Implemented scaler event for Trigger
34/// Ch. Finck, Jan. 06
35/// Using bus itr in DDL instead of simple incrementation
36/// treat correctly the DDL & buspatch for station 3.
37/// Using informations from AliMUONTriggerCrateStore for
38/// empty slots and non-notified cards in trigger crates.
39/// Ch. Finck, August 06.
5cab551d 40/// Using AliMpDDLStore::GetBusPatchId.
78649106 41///
42/// \author Ch. Finck, Feb. 07.
5cab551d 43
a19e2543 44
2cbb173f 45#include "AliMUONRawWriter.h"
a19e2543 46
344ef20f 47#include "AliMUONBlockHeader.h"
48#include "AliMUONBusStruct.h"
a19e2543 49#include "AliMUONConstants.h"
2cf44ef3 50#include "AliMUONDarcHeader.h"
2cbb173f 51#include "AliMUONData.h"
52#include "AliMUONDigit.h"
344ef20f 53#include "AliMUONDspHeader.h"
2cbb173f 54#include "AliMUONGlobalTrigger.h"
344ef20f 55#include "AliMUONLocalStruct.h"
2cbb173f 56#include "AliMUONLocalTrigger.h"
a844d67f 57#include "AliMUONLocalTriggerBoard.h"
4798d385 58#include "AliMUONRegionalTrigger.h"
344ef20f 59#include "AliMUONRegHeader.h"
60#include "AliMUONTriggerCrate.h"
61#include "AliMUONTriggerCrateStore.h"
9265505b 62
e5ced899 63#include "AliMpDDLStore.h"
64#include "AliMpDDL.h"
65#include "AliMpDetElement.h"
2cbb173f 66#include "AliMpDEManager.h"
344ef20f 67#include "AliMpExMap.h"
1c80232e 68#include "AliMpConstants.h"
a19e2543 69#include "AliMpPlaneType.h"
9265505b 70#include "AliMpSegmentation.h"
2cbb173f 71#include "AliMpStationType.h"
a19e2543 72#include "AliMpVSegmentation.h"
9265505b 73
344ef20f 74#include "AliRawReader.h"
9265505b 75#include "AliBitPacking.h"
76#include "AliDAQ.h"
77#include "AliLog.h"
78
79#include "TList.h"
a844d67f 80#include "TObjArray.h"
1c80232e 81#include "TStopwatch.h"
c4860b34 82#include <Riostream.h>
2cf44ef3 83
9265505b 84/// \cond CLASSIMP
a19e2543 85ClassImp(AliMUONRawWriter) // Class implementation in ROOT context
9265505b 86/// \endcond
ced309a5 87
344ef20f 88namespace
89{
90 enum ETimer { kWriteTracker, kWriteTrigger, kDigitLoop, kGetBusPatch, kTest, kLast };
91}
ced309a5 92
a19e2543 93//__________________________________________________________________________
2cbb173f 94AliMUONRawWriter::AliMUONRawWriter(AliMUONData* data)
9f5dcca3 95 : TObject(),
96 fMUONData(data),
9f5dcca3 97 fBlockHeader(new AliMUONBlockHeader()),
98 fDspHeader(new AliMUONDspHeader()),
9f5dcca3 99 fDarcHeader(new AliMUONDarcHeader()),
100 fRegHeader(new AliMUONRegHeader()),
101 fLocalStruct(new AliMUONLocalStruct()),
5cab551d 102 fDDLStore(AliMpDDLStore::Instance()),
9f5dcca3 103 fCrateManager(new AliMUONTriggerCrateStore()),
104 fScalerEvent(kFALSE),
105 fHeader(),
9265505b 106 fTimers(new TStopwatch[kLast])
344ef20f 107
a19e2543 108{
9265505b 109 /// Standard Constructor
110
2cbb173f 111 AliDebug(1,"Standard ctor");
9f5dcca3 112 fFile[0] = fFile[1] = 0x0;
113 fFile[2] = fFile[3] = 0x0;
a19e2543 114
84ceeb06 115 // setting data key to default value (only for writting)
116 fBlockHeader->SetDataKey(fBlockHeader->GetDefaultDataKey());
117 fDspHeader->SetDataKey(fDspHeader->GetDefaultDataKey());
84ceeb06 118
a844d67f 119 // Crate manager
a844d67f 120 fCrateManager->ReadFromFile();
121
84ceeb06 122 // timers
344ef20f 123 for ( Int_t i = 0; i < kLast; ++i )
124 {
125 fTimers[i].Start(kTRUE);
126 fTimers[i].Stop();
127 }
2cbb173f 128
a19e2543 129}
130
131//__________________________________________________________________________
132AliMUONRawWriter::AliMUONRawWriter()
133 : TObject(),
134 fMUONData(0),
2cf44ef3 135 fBlockHeader(0),
136 fDspHeader(0),
2cf44ef3 137 fDarcHeader(0),
138 fRegHeader(0),
139 fLocalStruct(0),
5cab551d 140 fDDLStore(0),
a844d67f 141 fCrateManager(0x0),
2cbb173f 142 fScalerEvent(kFALSE),
9f5dcca3 143 fHeader(),
9265505b 144 fTimers(0)
a19e2543 145{
9265505b 146 /// Default Constructor
147
2cbb173f 148 AliDebug(1,"Default ctor");
149 fFile[0] = fFile[1] = 0x0;
1d81a83f 150 fFile[2] = fFile[3] = 0x0;
151
a19e2543 152}
153
a19e2543 154//__________________________________________________________________________
155AliMUONRawWriter::~AliMUONRawWriter(void)
156{
9265505b 157 /// Destructor
158
2cbb173f 159 AliDebug(1,"dtor");
160
2cf44ef3 161 delete fBlockHeader;
162 delete fDspHeader;
2cf44ef3 163 delete fDarcHeader;
164 delete fRegHeader;
165 delete fLocalStruct;
a19e2543 166
a844d67f 167 delete fCrateManager;
168
344ef20f 169 for ( Int_t i = 0; i < kLast; ++i )
170 {
a7b01aa5 171 AliDebug(1, Form("Execution time (timer %d) : R:%7.2fs C:%7.2fs",i,
344ef20f 172 fTimers[i].RealTime(),fTimers[i].CpuTime()));
173 }
174
175 delete[] fTimers;
a19e2543 176}
2cbb173f 177
a19e2543 178//____________________________________________________________________
179Int_t AliMUONRawWriter::Digits2Raw()
180{
9265505b 181 /// convert digits of the current event to raw data
182
a19e2543 183 Int_t idDDL;
1d81a83f 184 Char_t name[255];
a19e2543 185
2cbb173f 186 fMUONData->GetLoader()->LoadDigits("READ");
a19e2543 187
188 fMUONData->SetTreeAddress("D,GLT");
189
2cbb173f 190 fMUONData->ResetDigits();
191 fMUONData->ResetTrigger();
192
193 // This will get both tracker and trigger digits.
194 fMUONData->GetDigits();
195
344ef20f 196// CheckDigits();
a19e2543 197
344ef20f 198 // tracking chambers
199
200 for (Int_t iSt = 0; iSt < AliMUONConstants::NTrackingCh()/2; ++iSt) {
1d81a83f 201
202 // open files for one station
203 // cos station 3, 1/4 of DE's from 2 chambers has same DDL number
204 idDDL = iSt * 4;
362c9d61 205 strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL));
a19e2543 206 fFile[0] = fopen(name,"w");
207
1d81a83f 208 idDDL = (iSt * 4) + 1;
362c9d61 209 strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL));
a19e2543 210 fFile[1] = fopen(name,"w");
1d81a83f 211
212 idDDL = (iSt * 4) + 2;;
213 strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL));
214 fFile[2] = fopen(name,"w");
215
216 idDDL = (iSt * 4) + 3;
217 strcpy(name,AliDAQ::DdlFileName("MUONTRK",idDDL));
218 fFile[3] = fopen(name,"w");
219
220 WriteTrackerDDL(iSt);
a19e2543 221
1d81a83f 222 // reset and close when station has been processed
a19e2543 223 fclose(fFile[0]);
224 fclose(fFile[1]);
1d81a83f 225 fclose(fFile[2]);
226 fclose(fFile[3]);
227
a19e2543 228 }
229
344ef20f 230 AliDebug(1,"Tracker written");
231
a19e2543 232 // trigger chambers
233
234 // open files
362c9d61 235 idDDL = 0;// MUTR
236 strcpy(name,AliDAQ::DdlFileName("MUONTRG",idDDL));
a19e2543 237 fFile[0] = fopen(name,"w");
238
362c9d61 239 idDDL = 1;// MUTR
240 strcpy(name,AliDAQ::DdlFileName("MUONTRG",idDDL));
a19e2543 241 fFile[1] = fopen(name,"w");
242
1afc1008 243 WriteTriggerDDL();
a19e2543 244
245 // reset and close
246 fclose(fFile[0]);
247 fclose(fFile[1]);
2cbb173f 248
344ef20f 249 AliDebug(1,"Trigger written");
250
2cbb173f 251 fMUONData->ResetDigits();
252 fMUONData->ResetTrigger();
253 fMUONData->GetLoader()->UnloadDigits();
a19e2543 254
344ef20f 255 AliDebug(1,"muondata reset");
256
a19e2543 257 return kTRUE;
258}
2cbb173f 259
a19e2543 260//____________________________________________________________________
1d81a83f 261Int_t AliMUONRawWriter::WriteTrackerDDL(Int_t iSt)
a19e2543 262{
9265505b 263 /// writing DDL for tracker
264 /// used inverse mapping
265
344ef20f 266 fTimers[kWriteTracker].Start(kFALSE);
2cbb173f 267
84aac932 268 static const Int_t kMAXADC = (1<<12)-1; // We code the charge on a 12 bits ADC.
2cf44ef3 269
a19e2543 270 // resets
271 TClonesArray* muonDigits = 0;
2cf44ef3 272
a19e2543 273 // DDL header
2cf44ef3 274 Int_t headerSize = sizeof(fHeader)/4;
275
276 // DDL event one per half chamber
a19e2543 277
2cf44ef3 278 // raw data
a19e2543 279 Char_t parity = 0x4;
280 UShort_t manuId = 0;
281 UChar_t channelId = 0;
282 UShort_t charge = 0;
283 Int_t busPatchId = 0;
a19e2543 284 UInt_t word;
2cf44ef3 285
84ceeb06 286
287 // Dsp length
288 Int_t totalDspLength;
289 Int_t dspLength;
290
2cf44ef3 291 // block length
292 Int_t totalBlkLength;
293 Int_t blkLength;
294
295 // total DDL length
296 Int_t totalDDLLength;
297
298 // indexes
a19e2543 299 Int_t index;
300 Int_t indexDsp;
301 Int_t indexBlk;
2cf44ef3 302
344ef20f 303 // buffer size (max'ed out)
304 // (((43 manus max per bus patch *64 channels + 4 bus patch words) * 5 bus patch
305 // + 10 dsp words)*5 dsps + 8 block words)*2 blocks
306 static const Int_t kBufferSize = (((43*64 + 4)*5 + 10)*5 + 8)*2;
307
a19e2543 308 Int_t nDigits;
309
344ef20f 310 AliMpExMap busPatchMap(kTRUE);
311
312 fTimers[kDigitLoop].Start(kFALSE);
313
314 for (Int_t iCh = iSt*2; iCh <= iSt*2 + 1; ++iCh) {
a19e2543 315
1d81a83f 316 muonDigits = fMUONData->Digits(iCh);
344ef20f 317
1d81a83f 318 nDigits = muonDigits->GetEntriesFast();
344ef20f 319
1d81a83f 320 // loop over digit
344ef20f 321 for (Int_t idig = 0; idig < nDigits; ++idig) {
322
323 AliMUONDigit* digit = static_cast<AliMUONDigit*>(muonDigits->UncheckedAt(idig));
324
1d81a83f 325 charge = digit->ADC();
326 if ( charge > kMAXADC )
344ef20f 327 {
328 // This is most probably an error in the digitizer (which should insure
329 // the adc is below kMAXADC), so make it a (non-fatal) error indeed.
330 AliError(Form("adc value %d above %x for ch %d . Setting to %x. Digit is:",iCh,
331 charge,kMAXADC,kMAXADC));
332 StdoutToAliError(digit->Print());
333 charge = kMAXADC;
334 }
335
1d81a83f 336 // inverse mapping
344ef20f 337 fTimers[kGetBusPatch].Start(kFALSE);
1d81a83f 338 busPatchId = GetBusPatch(*digit);
344ef20f 339 fTimers[kGetBusPatch].Stop();
1d81a83f 340 if (busPatchId<0) continue;
344ef20f 341
1d81a83f 342 if ( digit->ManuId() > 0x7FF || digit->ManuId() < 0 ||
344ef20f 343 digit->ManuChannel() > 0x3F || digit->ManuChannel() < 0 )
344 {
345 StdoutToAliError(digit->Print(););
346 AliFatal("ManuId,ManuChannel are invalid for the digit above.");
347 }
348
1d81a83f 349 manuId = ( digit->ManuId() & 0x7FF ); // 11 bits
350 channelId = ( digit->ManuChannel() & 0x3F ); // 6 bits
344ef20f 351
1d81a83f 352 //packing word
353 word = 0;
354 AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
355 AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
356 AliBitPacking::PackWord((UInt_t)charge,word,0,11);
344ef20f 357
1d81a83f 358 // parity word
359 parity = word & 0x1;
344ef20f 360 for (Int_t i = 1; i <= 30; ++i)
361 parity ^= ((word >> i) & 0x1);
1d81a83f 362 AliBitPacking::PackWord((UInt_t)parity,word,31,31);
344ef20f 363
364 AliMUONBusStruct* busStruct =
365 static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(busPatchId));
366
367 if (!busStruct)
368 {
369 busStruct = new AliMUONBusStruct;
370 busStruct->SetDataKey(busStruct->GetDefaultDataKey());
371 busStruct->SetBusPatchId(busPatchId);
372 busStruct->SetLength(0);
373 busPatchMap.Add(busPatchId,busStruct);
f5439c77 374 }
a19e2543 375
344ef20f 376 // set sub Event
377 busStruct->AddData(word);
378
379 } // idig
380 } // loop over chamber in station
381
382 fTimers[kDigitLoop].Stop();
a19e2543 383
384 // getting info for the number of buspatches
385 Int_t iBusPatch;
386 Int_t length;
387 Int_t iBusPerDSP[5];//number of bus patches per DSP
388 Int_t iDspMax; //number max of DSP per block
a19e2543 389 Int_t iFile = 0;
a19e2543 390
344ef20f 391 AliMUONBusStruct* busStructPtr(0x0);
a19e2543 392
1d81a83f 393 // open DDL files, 4 per station
344ef20f 394 for (Int_t iDDL = iSt*4; iDDL < 4 + iSt*4; ++iDDL) {
a19e2543 395
5cab551d 396 AliMpDDL* ddl = fDDLStore->GetDDL(iDDL);
e5ced899 397 iDspMax = ddl->GetMaxDsp();
398 ddl->GetBusPerDsp(iBusPerDSP);
399 Int_t busIter = 0;
84ceeb06 400
344ef20f 401 Int_t buffer[kBufferSize];
402
2cf44ef3 403 totalDDLLength = 0;
404
a19e2543 405 indexBlk = 0;
406 indexDsp = 0;
407 index = 0;
2cf44ef3 408
a19e2543 409 // two blocks A and B per DDL
344ef20f 410 for (Int_t iBlock = 0; iBlock < 2; ++iBlock) {
411
a19e2543 412 // block header
2cf44ef3 413 length = fBlockHeader->GetHeaderLength();
414 memcpy(&buffer[index],fBlockHeader->GetHeader(),length*4);
a19e2543 415 indexBlk = index;
416 index += length;
344ef20f 417
a19e2543 418 // 5 DSP's max per block
344ef20f 419 for (Int_t iDsp = 0; iDsp < iDspMax; ++iDsp) {
420
421 // DSP header
422 length = fDspHeader->GetHeaderLength();
423 memcpy(&buffer[index],fDspHeader->GetHeader(),length*4);
424 indexDsp = index;
425 index += length;
426
427 // 5 buspatches max per DSP
428 for (Int_t i = 0; i < iBusPerDSP[iDsp]; i++) {
429
e5ced899 430 iBusPatch = ddl->GetBusPatchId(busIter++);
344ef20f 431
432 // iteration over bus patch in DDL
433 if (iBusPatch == -1) {
434 AliWarning(Form("Error in bus itr in DDL %d\n", iDDL));
435 continue;
436 }
437
438 // 4 DDL's per station, condition needed for station 3
439 iFile = iDDL - iSt*4; // works only if DDL begins at zero (as it should be) !!!
440
441 busStructPtr = static_cast<AliMUONBusStruct*>(busPatchMap.GetValue(iBusPatch));
442
443 // check if buspatchid has digit
444 if (busStructPtr) {
445 // add bus patch structure header
446 length = busStructPtr->GetHeaderLength();
447 memcpy(&buffer[index],busStructPtr->GetHeader(),length*4);
448 index += length;
449
450 // add bus patch data
451 length = busStructPtr->GetLength();
452 memcpy(&buffer[index],busStructPtr->GetData(),length*4);
453 index += length;
454
455 if (AliLog::GetGlobalDebugLevel() == 3) {
456 for (Int_t j = 0; j < busStructPtr->GetLength(); j++) {
457 printf("busPatchId %d, manuId %d channelId %d\n", busStructPtr->GetBusPatchId(),
458 busStructPtr->GetManuId(j), busStructPtr->GetChannelId(j));
459 }
460 }
461 } else {
462 // writting anyhow buspatch structure (empty ones)
463 buffer[index++] = busStructPtr->GetDefaultDataKey(); // fill it also for empty data size
464 buffer[index++] = busStructPtr->GetHeaderLength(); // header length
465 buffer[index++] = 0; // raw data length
466 buffer[index++] = iBusPatch; // bus patch
467 }
468 } // bus patch
469
470 // check if totalLength even
471 // set padding word in case
472 // Add one word 0xBEEFFACE at the end of DSP structure
473 totalDspLength = index - indexDsp;
474 if ((totalDspLength % 2) == 1) {
475 buffer[indexDsp + fDspHeader->GetHeaderLength() - 2] = 1;
476 buffer[index++] = fDspHeader->GetDefaultPaddingWord();
477 totalDspLength++;
478 }
479
480 dspLength = totalDspLength - fDspHeader->GetHeaderLength();
481
482 buffer[indexDsp+1] = totalDspLength; // dsp total length
483 buffer[indexDsp+2] = dspLength; // data length
484
a19e2543 485 } // dsp
344ef20f 486
2cf44ef3 487 totalBlkLength = index - indexBlk;
488 blkLength = totalBlkLength - fBlockHeader->GetHeaderLength();
489 totalDDLLength += totalBlkLength;
344ef20f 490
84ceeb06 491 buffer[indexBlk+1] = totalBlkLength; // total block length
492 buffer[indexBlk+2] = blkLength;
344ef20f 493
2cf44ef3 494 } // block
a19e2543 495
496 //writting onto disk
1d81a83f 497 // write DDL 1 - 4
344ef20f 498 // total length in bytes
499 fHeader.fSize = (totalDDLLength + headerSize) * 4;
500
2cf44ef3 501 fwrite((char*)(&fHeader),headerSize*4,1,fFile[iFile]);
a19e2543 502 fwrite(buffer,sizeof(int),index,fFile[iFile]);
a19e2543 503 }
344ef20f 504
505 fTimers[kWriteTracker].Stop();
a19e2543 506 return kTRUE;
507}
ced309a5 508
344ef20f 509//____________________________________________________________________
510Int_t AliMUONRawWriter::GetBusPatch(const AliMUONDigit& digit) const
511{
9265505b 512 /// Determine the BusPatch this digit belongs to.
513
5cab551d 514 return fDDLStore->GetBusPatchId(digit.DetElemId(),digit.ManuId());
344ef20f 515}
516
a19e2543 517//____________________________________________________________________
518Int_t AliMUONRawWriter::WriteTriggerDDL()
519{
9265505b 520 /// Write trigger DDL
521
344ef20f 522 fTimers[kWriteTrigger].Start(kFALSE);
2cbb173f 523
a19e2543 524 // DDL event one per half chamber
a19e2543 525
2cf44ef3 526 // DDL header size
527 Int_t headerSize = sizeof(AliRawDataHeader)/4;
ced309a5 528
a19e2543 529 TClonesArray* localTrigger;
530 TClonesArray* globalTrigger;
4798d385 531 TClonesArray* regionalTrigger;
532
a19e2543 533 AliMUONGlobalTrigger* gloTrg;
534 AliMUONLocalTrigger* locTrg = 0x0;
4798d385 535 AliMUONRegionalTrigger* regTrg = 0x0;
a19e2543 536
a19e2543 537 // global trigger for trigger pattern
538 globalTrigger = fMUONData->GlobalTrigger();
539 gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
344ef20f 540 if (!gloTrg)
541 {
542 fTimers[kWriteTrigger].Stop();
543 return 0;
544 }
545
073695a9 546 Int_t gloTrigResp = gloTrg->GetGlobalResponse();
a19e2543 547
548 // local trigger
4798d385 549 localTrigger = fMUONData->LocalTrigger();
550
551
552 // regional trigger
553 regionalTrigger = fMUONData->RegionalTrigger();
554
a19e2543 555
556 UInt_t word;
557 Int_t* buffer = 0;
558 Int_t index;
559 Int_t iEntries = 0;
560 Int_t iLocCard, locCard;
1afc1008 561 UChar_t locDec, trigY, posY, posX, regOut;
bebe0279 562 UInt_t regInpLpt;
563 UInt_t regInpHpt;
564
1afc1008 565 UInt_t devX;
c4860b34 566 UChar_t sdevX;
1afc1008 567 UInt_t version = 1; // software version
568 UInt_t eventPhys = 1; // trigger type: 1 for physics, 0 for software
569 UInt_t serialNb = 0xF; // serial nb of card: all bits on for the moment
d622a0ec 570 Int_t globalFlag = 0; // set to 1 if global info present in DDL else set to 0
571
572 // size of headers
573 static const Int_t kDarcHeaderLength = fDarcHeader->GetDarcHeaderLength();
574 static const Int_t kGlobalHeaderLength = fDarcHeader->GetGlobalHeaderLength();
575 static const Int_t kDarcScalerLength = fDarcHeader->GetDarcScalerLength();
576 static const Int_t kGlobalScalerLength = fDarcHeader->GetGlobalScalerLength();
577 static const Int_t kRegHeaderLength = fRegHeader->GetHeaderLength();
578 static const Int_t kRegScalerLength = fRegHeader->GetScalerLength();
579 static const Int_t kLocHeaderLength = fLocalStruct->GetLength();
580 static const Int_t kLocScalerLength = fLocalStruct->GetScalerLength();
581
582 // [16(local)*6 words + 6 words]*8(reg) + 8 words = 824
583 static const Int_t kBufferSize = (16 * (kLocHeaderLength+1) + (kRegHeaderLength+1))* 8
584 + kDarcHeaderLength + kGlobalHeaderLength + 2;
585
586 // [16(local)*51 words + 16 words]*8(reg) + 8 + 10 + 8 words scaler event 6682 words
587 static const Int_t kScalerBufferSize = (16 * (kLocHeaderLength + kLocScalerLength +1) +
588 (kRegHeaderLength + kRegScalerLength +1))* 8 +
589 (kDarcHeaderLength + kDarcScalerLength +
590 kGlobalHeaderLength + kGlobalScalerLength + 2);
ced309a5 591 if(fScalerEvent)
d622a0ec 592 eventPhys = 0; //set to generate scaler events
ced309a5 593
a19e2543 594 Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
a19e2543 595
596 if (!nEntries)
a7b01aa5 597 AliDebug(1, "No Trigger information available");
a19e2543 598
ced309a5 599 if(fScalerEvent)
d622a0ec 600 buffer = new Int_t [kScalerBufferSize];
ced309a5 601 else
d622a0ec 602 buffer = new Int_t [kBufferSize];
ced309a5 603
a844d67f 604 // reset crate
a19e2543 605
606 // open DDL file, on per 1/2 chamber
607 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
a844d67f 608
a19e2543 609 index = 0;
610
a19e2543 611 if (iDDL == 0) // suppose global info in DDL one
a19e2543 612 globalFlag = 1;
d622a0ec 613 else
614 globalFlag = 0;
ced309a5 615
d622a0ec 616 word = 0;
617 // set darc status word
618 // see AliMUONDarcHeader.h for details
619 AliBitPacking::PackWord((UInt_t)eventPhys,word,30,30);
620 AliBitPacking::PackWord((UInt_t)serialNb,word,20,23);
621 AliBitPacking::PackWord((UInt_t)globalFlag,word,10,10);
622 AliBitPacking::PackWord((UInt_t)version,word,12,19);
2cf44ef3 623 fDarcHeader->SetWord(word);
18d3ded7 624
d622a0ec 625 memcpy(&buffer[index], fDarcHeader->GetHeader(), (kDarcHeaderLength)*4);
bebe0279 626 index += kDarcHeaderLength;
a19e2543 627
073695a9 628 // no global input for the moment....
a19e2543 629 if (iDDL == 0)
073695a9 630 fDarcHeader->SetGlobalOutput(gloTrigResp);
a19e2543 631 else
2cf44ef3 632 fDarcHeader->SetGlobalOutput(0);
ced309a5 633
634 if (fScalerEvent) {
635 // 6 DARC scaler words
d622a0ec 636 memcpy(&buffer[index], fDarcHeader->GetDarcScalers(),kDarcScalerLength*4);
bebe0279 637 index += kDarcScalerLength;
ced309a5 638 }
2cf44ef3 639 // end of darc word
640 buffer[index++] = fDarcHeader->GetEndOfDarc();
ced309a5 641
642 // 4 words of global board input + Global board output
d622a0ec 643 memcpy(&buffer[index], fDarcHeader->GetGlobalInput(), (kGlobalHeaderLength)*4);
bebe0279 644 index += kGlobalHeaderLength;
ced309a5 645
646 if (fScalerEvent) {
647 // 10 Global scaler words
d622a0ec 648 memcpy(fDarcHeader->GetGlobalScalers(), &buffer[index], kGlobalScalerLength*4);
bebe0279 649 index += kGlobalScalerLength;
ced309a5 650 }
a19e2543 651
2cf44ef3 652 // end of global word
653 buffer[index++] = fDarcHeader->GetEndOfGlobal();
654
a19e2543 655 // 8 regional cards per DDL
656 for (Int_t iReg = 0; iReg < 8; iReg++) {
657
a844d67f 658 // crate info
aa6ecf89 659 AliMUONTriggerCrate* crate = fCrateManager->Crate(iDDL, iReg);
a844d67f 660
661 if (!crate)
662 AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, iDDL));
663
4798d385 664 // regional info tree, make sure that no reg card missing
665 for (Int_t i = 0; i < 16; ++i) {
666 regTrg = (AliMUONRegionalTrigger*)regionalTrigger->At(i);
667 if (regTrg)
668 if (regTrg->GetId() == (iReg + iDDL*8)) break;
669 }
670
a19e2543 671 // Regional card header
672 word = 0;
00f56161 673
674 // set darc status word
675 fRegHeader->SetDarcWord(word);
676
4798d385 677 regOut = regTrg->GetOutput();
678 regInpHpt = regTrg->GetLocalOutput(0);
679 regInpLpt = regTrg->GetLocalOutput(1);
680
d622a0ec 681 // fill darc word, not darc status for the moment (empty)
682 //see AliMUONRegHeader.h for details
683 AliBitPacking::PackWord((UInt_t)eventPhys,word,31,31);
684 AliBitPacking::PackWord((UInt_t)serialNb,word,19,24);
a19e2543 685 AliBitPacking::PackWord((UInt_t)version,word,16,23);
d622a0ec 686 AliBitPacking::PackWord((UInt_t)iReg,word,15,18);
4798d385 687 AliBitPacking::PackWord((UInt_t)regOut,word,0,7);
2cf44ef3 688 fRegHeader->SetWord(word);
d622a0ec 689
bebe0279 690
691 // fill header later, need local response
692 Int_t indexReg = index;
693 index += kRegHeaderLength;
a19e2543 694
ced309a5 695 // 11 regional scaler word
696 if (fScalerEvent) {
bebe0279 697 memcpy(&buffer[index], fRegHeader->GetScalers(), kRegScalerLength*4);
698 index += kRegScalerLength;
ced309a5 699 }
a19e2543 700
2cf44ef3 701 // end of regional word
702 buffer[index++] = fRegHeader->GetEndOfReg();
a844d67f 703
704 TObjArray *boards = crate->Boards();
705
2cf44ef3 706
a19e2543 707 // 16 local card per regional board
4798d385 708 // UShort_t localMask = 0x0;
c4860b34 709
a19e2543 710 for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
c4860b34 711
712 // slot zero for Regional card
713 AliMUONLocalTriggerBoard* localBoard = (AliMUONLocalTriggerBoard*)boards->At(iLoc+1);
714
715 if (localBoard) { // if not empty slot
716
717 if ((iLocCard = localBoard->GetNumber()) != 0) {// if notified board
718
719 locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries++);
720 locCard = locTrg->LoCircuit();
721 locDec = locTrg->GetLoDecision();
722 trigY = locTrg->LoTrigY();
723 posY = locTrg->LoStripY();
724 posX = locTrg->LoStripX();
725 devX = locTrg->LoDev();
726 sdevX = locTrg->LoSdev();
727
728 AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n",
729 locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
730 //packing word
731 word = 0;
732 AliBitPacking::PackWord((UInt_t)iLoc,word,19,22); //card id number in crate
733 AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
734 AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
735 AliBitPacking::PackWord((UInt_t)posY,word,10,13);
736 AliBitPacking::PackWord((UInt_t)sdevX,word,9,9);
737 AliBitPacking::PackWord((UInt_t)devX,word,5,8);
738 AliBitPacking::PackWord((UInt_t)posX,word,0,4);
739
740 buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
741 buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
742 buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
743 buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
744 buffer[index++] = (Int_t)word; // data word
745
746 } else {// number!=0
747 // fill with 10CDEAD word for 'non-notified' slots
748 for (Int_t i = 0; i < fLocalStruct->GetLength(); i++)
749 buffer[index++] = fLocalStruct->GetDisableWord();
750 }
751 } else {
752 // fill with 10CDEAD word for empty slots
753 for (Int_t i = 0; i < fLocalStruct->GetLength(); i++)
754 buffer[index++] = fLocalStruct->GetDisableWord();
755 }// condition localBoard
756
757 // 45 regional scaler word
758 if (fScalerEvent) {
759 memcpy(&buffer[index], fLocalStruct->GetScalers(), kLocScalerLength*4);
760 index += kLocScalerLength;
a844d67f 761 }
c4860b34 762
763 // end of local structure words
764 buffer[index++] = fLocalStruct->GetEndOfLocal();
765
2cf44ef3 766 } // local card
bebe0279 767 // fill regional header with local output
4798d385 768 fRegHeader->SetInput(regInpHpt, 0);
bebe0279 769 fRegHeader->SetInput(regInpHpt, 1);
bebe0279 770 memcpy(&buffer[indexReg],fRegHeader->GetHeader(),kRegHeaderLength*4);
c4860b34 771
a19e2543 772 } // Regional card
773
a19e2543 774
775 // writting onto disk
a844d67f 776 // write DDL's
2cf44ef3 777 fHeader.fSize = (index + headerSize) * 4;// total length in bytes
778 fwrite((char*)(&fHeader),headerSize*4,1,fFile[iDDL]);
a19e2543 779 fwrite(buffer,sizeof(int),index,fFile[iDDL]);
780
781 }
782 delete[] buffer;
783
344ef20f 784 fTimers[kWriteTrigger].Stop();
2cbb173f 785
ced309a5 786 return kTRUE;
a19e2543 787}
84ceeb06 788//____________________________________________________________________
789void AliMUONRawWriter::SetScalersNumbers()
790{
9265505b 791 /// set numbers for scaler events for trigger headers
792 /// since this is provided by the experiment
793 /// put dummy numbers to check the monitoring
84ceeb06 794
795 fDarcHeader->SetScalersNumbers();
796 fRegHeader->SetScalersNumbers();
797 fLocalStruct->SetScalersNumbers();
798
799 fScalerEvent = kTRUE;
800}
a844d67f 801