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