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