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