]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONRawWriter.cxx
Correct procedure for padding word (Christian)
[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
a19e2543 18////////////////////////////////////
19//
ced309a5 20// MUON Raw Data generaton in ALICE-MUON
a19e2543 21// This class version 3 (further details could be found in Alice-note)
22//
23// Implemented non-constant buspatch numbers for tracking
24// with correct DDL id (first guess)
25// (Ch. Finck, dec 2005)
26//
27// Digits2Raw:
28// Generates raw data for MUON tracker and finally for trigger
29// Using real mapping (inverse) for tracker
30// For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
2cf44ef3 31// Ch. Finck, July 04
ced309a5 32// Use memcpy instead of assignment elt by elt
33// Introducing variable DSP numbers, real manu numbers per buspatch for st12
34// Implemented scaler event for Trigger
2cf44ef3 35// Ch. Finck, Jan. 06
a19e2543 36//
37////////////////////////////////////
38
2cbb173f 39#include "AliMUONRawWriter.h"
a19e2543 40
a19e2543 41#include "AliBitPacking.h"
2cf44ef3 42#include "AliRawReader.h"
a19e2543 43#include "AliLog.h"
a19e2543 44#include "AliMUON.h"
a19e2543 45#include "AliMUONConstants.h"
2cf44ef3 46
47#include "AliMUONDarcHeader.h"
48#include "AliMUONRegHeader.h"
49#include "AliMUONLocalStruct.h"
50#include "AliMUONDspHeader.h"
51#include "AliMUONBlockHeader.h"
52
2cbb173f 53#include "AliMUONData.h"
54#include "AliMUONDigit.h"
2cbb173f 55#include "AliMUONGlobalTrigger.h"
56#include "AliMUONLocalTrigger.h"
2cf44ef3 57
2cbb173f 58#include "AliMpBusPatch.h"
59#include "AliMpDEManager.h"
60#include "AliMpPad.h"
a19e2543 61#include "AliMpPlaneType.h"
2cbb173f 62#include "AliMpSegFactory.h"
63#include "AliMpStationType.h"
a19e2543 64#include "AliMpVSegmentation.h"
2cf44ef3 65
2cbb173f 66#include "TClonesArray.h"
2cf44ef3 67
a19e2543 68ClassImp(AliMUONRawWriter) // Class implementation in ROOT context
ced309a5 69
70Int_t AliMUONRawWriter::fgManuPerBusSwp1B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 224, 232};
71Int_t AliMUONRawWriter::fgManuPerBusSwp1NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 225, 233};
72
73Int_t AliMUONRawWriter::fgManuPerBusSwp2B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 226, 246};
74Int_t AliMUONRawWriter::fgManuPerBusSwp2NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 227, 245};
75
76
a19e2543 77//__________________________________________________________________________
2cbb173f 78AliMUONRawWriter::AliMUONRawWriter(AliMUONData* data)
79: TObject(),
80 fScalerEvent(kFALSE)
a19e2543 81{
2cf44ef3 82 //
a19e2543 83 // Standard Constructor
2cf44ef3 84 //
2cbb173f 85 AliDebug(1,"Standard ctor");
86
a19e2543 87 // initialize container
a19e2543 88 fMUONData = data;
89
90 // initialize array
2cf44ef3 91 fBusArray = new TClonesArray("AliMUONBusStruct",1000);
92 fBusArray->SetOwner(kTRUE);
a19e2543 93
84ceeb06 94 // ddl tracker pointers
2cf44ef3 95 fBlockHeader = new AliMUONBlockHeader();
96 fDspHeader = new AliMUONDspHeader();
97 fBusStruct = new AliMUONBusStruct();
98
84ceeb06 99 // setting data key to default value (only for writting)
100 fBlockHeader->SetDataKey(fBlockHeader->GetDefaultDataKey());
101 fDspHeader->SetDataKey(fDspHeader->GetDefaultDataKey());
102 fBusStruct->SetDataKey(fBusStruct->GetDefaultDataKey());
103
84ceeb06 104 // ddl trigger pointers
2cf44ef3 105 fDarcHeader = new AliMUONDarcHeader();
106 fRegHeader = new AliMUONRegHeader();
107 fLocalStruct = new AliMUONLocalStruct();
a19e2543 108
84ceeb06 109 // bus patch & Seg managers
a19e2543 110 fBusPatchManager = new AliMpBusPatch();
111 fBusPatchManager->ReadBusPatchFile();
2cbb173f 112
113 fSegFactory = new AliMpSegFactory();
114
84ceeb06 115 // timers
2cbb173f 116 fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
117 fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
118 fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
119
a19e2543 120}
121
122//__________________________________________________________________________
123AliMUONRawWriter::AliMUONRawWriter()
124 : TObject(),
125 fMUONData(0),
2cf44ef3 126 fBlockHeader(0),
127 fDspHeader(0),
128 fBusStruct(0),
129 fDarcHeader(0),
130 fRegHeader(0),
131 fLocalStruct(0),
ced309a5 132 fBusPatchManager(0),
2cbb173f 133 fScalerEvent(kFALSE),
134 fSegFactory(0x0)
a19e2543 135{
2cf44ef3 136 //
a19e2543 137 // Default Constructor
2cf44ef3 138 //
2cbb173f 139 AliDebug(1,"Default ctor");
140 fFile[0] = fFile[1] = 0x0;
141 fTrackerTimer.Start(kTRUE); fTrackerTimer.Stop();
142 fTriggerTimer.Start(kTRUE); fTriggerTimer.Stop();
143 fMappingTimer.Start(kTRUE); fMappingTimer.Stop();
a19e2543 144}
145
146//_______________________________________________________________________
147AliMUONRawWriter::AliMUONRawWriter (const AliMUONRawWriter& rhs)
148 : TObject(rhs)
149{
2cf44ef3 150 //
151 // Protected copy constructor
152 //
a19e2543 153 AliFatal("Not implemented.");
154}
155
156//_______________________________________________________________________
157AliMUONRawWriter &
158AliMUONRawWriter::operator=(const AliMUONRawWriter& rhs)
159{
2cf44ef3 160 //
161 // Protected assignement operator
162 //
a19e2543 163 if (this == &rhs) return *this;
164
165 AliFatal("Not implemented.");
166
167 return *this;
168}
169
170//__________________________________________________________________________
171AliMUONRawWriter::~AliMUONRawWriter(void)
172{
2cf44ef3 173 //
174 // Destructor
175 //
2cbb173f 176 AliDebug(1,"dtor");
177
2cf44ef3 178 delete fBusArray;
2cbb173f 179
2cf44ef3 180 delete fBlockHeader;
181 delete fDspHeader;
182 delete fBusStruct;
183 delete fDarcHeader;
184 delete fRegHeader;
185 delete fLocalStruct;
a19e2543 186
2cbb173f 187 delete fBusPatchManager;
188
189 delete fSegFactory;
190
191 AliInfo(Form("Execution time for MUON tracker : R:%.2fs C:%.2fs",
192 fTrackerTimer.RealTime(),fTrackerTimer.CpuTime()));
193 AliInfo(Form(" Execution time for MUON tracker (mapping calls part) "
194 ": R:%.2fs C:%.2fs",
195 fMappingTimer.RealTime(),fMappingTimer.CpuTime()));
196 AliInfo(Form("Execution time for MUON trigger : R:%.2fs C:%.2fs",
197 fTriggerTimer.RealTime(),fTriggerTimer.CpuTime()));
a19e2543 198}
2cbb173f 199
a19e2543 200//____________________________________________________________________
201Int_t AliMUONRawWriter::Digits2Raw()
202{
2cf44ef3 203 //
204 // convert digits of the current event to raw data
205 //
a19e2543 206 Int_t idDDL;
207 Char_t name[20];
208
2cbb173f 209 fMUONData->GetLoader()->LoadDigits("READ");
a19e2543 210
211 fMUONData->SetTreeAddress("D,GLT");
212
2cbb173f 213 fMUONData->ResetDigits();
214 fMUONData->ResetTrigger();
215
216 // This will get both tracker and trigger digits.
217 fMUONData->GetDigits();
218
a19e2543 219 // tracking chambers
220
2cbb173f 221 for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++)
222 {
a19e2543 223 // open files
224 idDDL = ich * 2 + 0x900; // official number for MUON
225 sprintf(name, "MUON_%d.ddl",idDDL);
226 fFile[0] = fopen(name,"w");
227
228 idDDL = (ich * 2) + 1 + 0x900;
229 sprintf(name, "MUON_%d.ddl",idDDL);
230 fFile[1] = fopen(name,"w");
2cbb173f 231
a19e2543 232 WriteTrackerDDL(ich);
233
234 // reset and close
235 fclose(fFile[0]);
236 fclose(fFile[1]);
a19e2543 237 }
238
239 // trigger chambers
240
241 // open files
242 idDDL = 0xA00;// official number for MUTR
243 sprintf(name, "MUTR_%d.ddl",idDDL);
244 fFile[0] = fopen(name,"w");
245
246 idDDL = 0xA00 + 1;
247 sprintf(name, "MUTR_%d.ddl",idDDL);
248 fFile[1] = fopen(name,"w");
249
250 WriteTriggerDDL();
251
252 // reset and close
253 fclose(fFile[0]);
254 fclose(fFile[1]);
2cbb173f 255
256 fMUONData->ResetDigits();
257 fMUONData->ResetTrigger();
258 fMUONData->GetLoader()->UnloadDigits();
a19e2543 259
260 return kTRUE;
261}
2cbb173f 262
a19e2543 263//____________________________________________________________________
264Int_t AliMUONRawWriter::WriteTrackerDDL(Int_t iCh)
265{
266 // writing DDL for tracker
267 // used inverse mapping
2cf44ef3 268 //
2cbb173f 269 fTrackerTimer.Start(kFALSE);
270
2cf44ef3 271
84aac932 272 static const Int_t kMAXADC = (1<<12)-1; // We code the charge on a 12 bits ADC.
2cf44ef3 273
a19e2543 274 // resets
275 TClonesArray* muonDigits = 0;
2cf44ef3 276
277 fBusArray->Delete();
278
a19e2543 279
280 //
2cf44ef3 281 TArrayI nbInBus;
282
283 nbInBus.Set(5000);
284
a19e2543 285 nbInBus.Reset();
286
287 // DDL header
2cf44ef3 288 Int_t headerSize = sizeof(fHeader)/4;
289
290 // DDL event one per half chamber
a19e2543 291
2cf44ef3 292 // raw data
a19e2543 293 Char_t parity = 0x4;
294 UShort_t manuId = 0;
295 UChar_t channelId = 0;
296 UShort_t charge = 0;
297 Int_t busPatchId = 0;
a19e2543 298 UInt_t word;
2cf44ef3 299
84ceeb06 300
301 // Dsp length
302 Int_t totalDspLength;
303 Int_t dspLength;
304
2cf44ef3 305 // block length
306 Int_t totalBlkLength;
307 Int_t blkLength;
308
309 // total DDL length
310 Int_t totalDDLLength;
311
312 // indexes
a19e2543 313 Int_t index;
314 Int_t indexDsp;
315 Int_t indexBlk;
2cf44ef3 316
317 // digits
318 Int_t nEntries = 0;
319 Int_t* buffer = 0;
a19e2543 320 Int_t padX;
321 Int_t padY;
322 Int_t cathode = 0;
323 Int_t detElemId;
324 Int_t nDigits;
325
326 const AliMUONDigit* digit;
327
328 AliDebug(3, Form("WriteDDL chamber %d\n", iCh+1));
329
a19e2543 330 muonDigits = fMUONData->Digits(iCh);
331
332 nDigits = muonDigits->GetEntriesFast();
333 AliDebug(3,Form("ndigits = %d\n",nDigits));
334
335 // loop over digit
336 for (Int_t idig = 0; idig < nDigits; idig++) {
337
338 digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
339
340 padX = digit->PadX();
341 padY = digit->PadY();
ce13d60d 342 charge = digit->ADC();
84aac932 343 if ( charge > kMAXADC )
2cbb173f 344 {
345 // This is most probably an error in the digitizer (which should insure
84aac932 346 // the adc is below kMAXADC), so make it a (non-fatal) error indeed.
2cbb173f 347 AliError(Form("adc value %d above %x. Setting to %x",
84aac932 348 charge,kMAXADC,kMAXADC));
349 charge = kMAXADC;
2cbb173f 350 }
a19e2543 351 cathode = digit->Cathode();
352 detElemId = digit->DetElemId();
353
354 // inverse mapping
2cbb173f 355 busPatchId = GetBusPatch(*digit);
356 if (busPatchId<0) continue;
357
358 if ( digit->ManuId() > 0x7FF || digit->ManuId() < 0 ||
359 digit->ManuChannel() > 0x3F || digit->ManuChannel() < 0 )
360 {
361 StdoutToAliError(digit->Print(););
362 AliFatal("ManuId,ManuChannel are invalid for the digit above.");
363 }
364
365 manuId = ( digit->ManuId() & 0x7FF ); // 11 bits
366 channelId = ( digit->ManuChannel() & 0x3F ); // 6 bits
2cf44ef3 367
368 AliDebug(3,Form("input IdDE %d busPatchId %d PadX %d PadY %d iCath %d \n",
a19e2543 369 detElemId, busPatchId, padX, padY, cathode));
2cf44ef3 370
a19e2543 371 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n", busPatchId, manuId, channelId ));
2cf44ef3 372
a19e2543 373 //packing word
374 AliBitPacking::PackWord((UInt_t)parity,word,29,31);
375 AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
376 AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
377 AliBitPacking::PackWord((UInt_t)charge,word,0,11);
378
379 // set sub Event
2cf44ef3 380 fBusStruct->SetLength(0);
381 fBusStruct->AddData(word);
382 fBusStruct->SetBusPatchId(busPatchId);
a19e2543 383
384 // storing the number of identical buspatches
385 nbInBus[busPatchId]++;
2cf44ef3 386 AddData(*fBusStruct);
387
a19e2543 388 }
389
390 // sorting by buspatch
2cf44ef3 391 fBusArray->Sort();
a19e2543 392
393 // gather datas from same bus patch
2cf44ef3 394 nEntries = fBusArray->GetEntriesFast();
a19e2543 395
2cf44ef3 396 for (Int_t i = 0; i < nEntries; i++) {
397 AliMUONBusStruct* temp = (AliMUONBusStruct*)fBusArray->At(i);
a19e2543 398 busPatchId = temp->GetBusPatchId();
399
400 // add bus patch header, length and total length managed by subevent class
2cf44ef3 401 for (Int_t j = 0; j < nbInBus[busPatchId]-1; j++) {
402 AliMUONBusStruct* temp1 = (AliMUONBusStruct*)fBusArray->At(++i);
a19e2543 403 temp->AddData(temp1->GetData(0));
2cf44ef3 404 fBusArray->RemoveAt(i) ;
a19e2543 405 }
406 }
2cf44ef3 407 fBusArray->Compress();
a19e2543 408
2cf44ef3 409 if (AliLog::GetGlobalDebugLevel() == 3) {
410 nEntries = fBusArray->GetEntriesFast();
411 for (Int_t i = 0; i < nEntries; i++) {
412 AliMUONBusStruct* temp = (AliMUONBusStruct*)fBusArray->At(i);
a19e2543 413 printf("busPatchid back %d\n",temp->GetBusPatchId());
2cf44ef3 414 for (Int_t j = 0; j < temp->GetLength(); j++) {
415 printf("manuId back %d, ",temp->GetManuId(j));
416 printf("channelId back %d, ",temp->GetChannelId(j));
417 printf("charge back %d\n",temp->GetCharge(j));
a19e2543 418 }
419 }
420 printf("\n");
421 }
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;
429 fBusPatchManager->GetDspInfo(iCh, iDspMax, iBusPerDSP);
430
431 TArrayI* vec = fBusPatchManager->GetBusfromDE((iCh+1)*100);
432
433 Int_t iBus0AtCh = vec->At(0); //get first bus patch id for a given ich
434
435 AliDebug(3,Form("iBus0AtCh %d", iBus0AtCh));
436
437 iBusPatch = iBus0AtCh - 1; // starting point for each chamber
438
2cf44ef3 439 // nEntries = fBusArray->GetEntriesFast();
84ceeb06 440
441 AliMUONBusStruct* busStructPtr = 0x0;
2cf44ef3 442
a19e2543 443 // open DDL file, on per 1/2 chamber
2cf44ef3 444 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
445
446 totalDDLLength = 0;
447
a19e2543 448 // filling buffer
84ceeb06 449 buffer = new Int_t [(2048+24)*50]; // 24 words at most for one buspatch and 2048 manu info at most
2cf44ef3 450
a19e2543 451 indexBlk = 0;
452 indexDsp = 0;
453 index = 0;
2cf44ef3 454
a19e2543 455 // two blocks A and B per DDL
2cf44ef3 456 for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
457
a19e2543 458 // block header
2cf44ef3 459 length = fBlockHeader->GetHeaderLength();
460 memcpy(&buffer[index],fBlockHeader->GetHeader(),length*4);
a19e2543 461 indexBlk = index;
462 index += length;
2cf44ef3 463
a19e2543 464 // 5 DSP's max per block
2cf44ef3 465 for (Int_t iDsp = 0; iDsp < iDspMax; iDsp++) {
466
467 // DSP header
468 length = fDspHeader->GetHeaderLength();
469 memcpy(&buffer[index],fDspHeader->GetHeader(),length*4);
470 indexDsp = index;
471 index += length;
472
473 // 5 buspatches max per DSP
474 for (Int_t i = 0; i < iBusPerDSP[iDsp]; i++) {
475
476 iBusPatch++;
477 if ((fBusPatchManager->GetDDLfromBus(iBusPatch) % 2) == 0) // comparing to DDL file
478 iFile = 1;
479 else
480 iFile = 0;
481
482 AliDebug(3,Form("iCh %d iDDL %d iBlock %d iDsp %d busPatchId %d", iCh, iDDL, iBlock, iDsp, iBusPatch));
483
484 nEntries = fBusArray->GetEntriesFast();
cd640dc7 485 busPatchId = -1;
84ceeb06 486
2cf44ef3 487 for (Int_t iEntries = 0; iEntries < nEntries; iEntries++) { // method "bourrique"...
84ceeb06 488 busStructPtr = (AliMUONBusStruct*)fBusArray->At(iEntries);
489 busPatchId = busStructPtr->GetBusPatchId();
2cf44ef3 490 if (busPatchId == iBusPatch) break;
491 busPatchId = -1;
84ceeb06 492 AliDebug(3,Form("busPatchId %d", busStructPtr->GetBusPatchId()));
2cf44ef3 493 }
494
495 // check if buspatchid has digit
496 if (busPatchId != -1) {
84ceeb06 497 // add bus patch structure header
498 length = busStructPtr->GetHeaderLength();
499 memcpy(&buffer[index],busStructPtr->GetHeader(),length*4);
2cf44ef3 500 index += length;
84ceeb06 501
502 // add bus patch data
503 for (Int_t j = 0; j < busStructPtr->GetLength(); j++) {
504 buffer[index++] = busStructPtr->GetData(j);
505 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n",
506 busStructPtr->GetBusPatchId(),
507 busStructPtr->GetManuId(j), busStructPtr->GetChannelId(j) ));
2cf44ef3 508 }
509 // fBusArray->RemoveAt(iEntries);
510 // fBusArray->Compress();
511 } else {
512 // writting anyhow buspatch structure (empty ones)
84ceeb06 513 buffer[index++] = busStructPtr->GetDefaultDataKey(); // fill it also for empty data size
514 buffer[index++] = busStructPtr->GetHeaderLength(); // header length
2cf44ef3 515 buffer[index++] = 0; // raw data length
516 buffer[index++] = iBusPatch; // bus patch
2cf44ef3 517 }
518 } // bus patch
519
86400e61 520 // check if totalLength even
521 // set padding word in case
522 // Add one word 0xBEEFFACE at the end of DSP structure
523 totalDspLength = index - indexDsp;
524 if ((totalDspLength % 2) == 1) {
525 buffer[indexDsp + fDspHeader->GetHeaderLength() - 2] = 1;
526 buffer[index++] = fDspHeader->GetDefaultPaddingWord();
527 totalDspLength++;
528 }
529
84ceeb06 530 dspLength = totalDspLength - fDspHeader->GetHeaderLength();
531
532 buffer[indexDsp+1] = totalDspLength; // dsp total length
533 buffer[indexDsp+2] = dspLength; // data length
84ceeb06 534
a19e2543 535 } // dsp
2cf44ef3 536
537 totalBlkLength = index - indexBlk;
538 blkLength = totalBlkLength - fBlockHeader->GetHeaderLength();
539 totalDDLLength += totalBlkLength;
540
84ceeb06 541 buffer[indexBlk+1] = totalBlkLength; // total block length
542 buffer[indexBlk+2] = blkLength;
2cf44ef3 543
544 } // block
a19e2543 545
546 //writting onto disk
547 // write DDL 1 & 2
2cf44ef3 548 fHeader.fSize = (totalDDLLength + headerSize) * 4;// total length in bytes
549 fwrite((char*)(&fHeader),headerSize*4,1,fFile[iFile]);
a19e2543 550 fwrite(buffer,sizeof(int),index,fFile[iFile]);
2cf44ef3 551
a19e2543 552 delete[] buffer;
553 }
554
2cbb173f 555 fTrackerTimer.Stop();
a19e2543 556 return kTRUE;
557}
ced309a5 558
559//____________________________________________________________________
2cbb173f 560Int_t AliMUONRawWriter::GetBusPatch(const AliMUONDigit& digit)
ced309a5 561{
2cf44ef3 562 //
2cbb173f 563 // Determine the BusPatch this digit belongs to.
2cf44ef3 564 //
2cbb173f 565 fMappingTimer.Start(kFALSE);
566
ced309a5 567 Int_t* ptr = 0;
568
569 // information from digits
2cbb173f 570 Int_t detElemId = digit.DetElemId();
571
572 AliMpVSegmentation* seg =
573 fSegFactory->CreateMpSegmentationByElectronics(detElemId, digit.ManuId());
574
575 AliMpPlaneType plane = seg->PlaneType();
ced309a5 576
2cbb173f 577 AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
ced309a5 578
2cbb173f 579 if ( stationType == kStation1 || stationType == kStation2 )
580 {
581 if (plane == kBendingPlane)
582 {
583 ptr = &fgManuPerBusSwp1B[0];
584 }
585 else
586 {
587 ptr = &fgManuPerBusSwp1NB[0];
ced309a5 588 }
589 }
2cbb173f 590 else
591 {
592 if (plane == kBendingPlane)
593 {
594 ptr = &fgManuPerBusSwp2B[0];
595 }
596 else
597 {
598 ptr = &fgManuPerBusSwp2NB[0];
599 }
ced309a5 600 }
601
ced309a5 602 // Getting buspatch id
2cbb173f 603 TArrayI* vec = fBusPatchManager->GetBusfromDE(detElemId);
ced309a5 604 Int_t pos = 0;
605
2cbb173f 606 Int_t m = ( digit.ManuId() & 0x3FF ); // remove bit 10
607 //FIXME : how can we remove that condition
608 // on the 10-th bit ? All the rest need not any knowledge about it,
609 // can't we find a way to get manu<->buspatch transparent to this too ?
610
611 if ( stationType == kStation1 || stationType == kStation2 )
612 {
ced309a5 613 for (Int_t i = 0; i < 12; i++)
2cbb173f 614 {
615 if (m >= *(ptr + pos++)) break;
616 }
617 }
618 else
619 {
ced309a5 620 // offset of 100 in manuId for following bus patch
2cbb173f 621 pos = m/100;
ced309a5 622 }
623
624 if (pos >(Int_t) vec->GetSize())
2cbb173f 625 {
626 AliError(Form("pos greater %d than size %d manuId %d detElemId %d \n",
627 pos, (Int_t)vec->GetSize(), digit.ManuId(), detElemId));
628 AliError(Form("Chamber %s Plane %s manuId %d m %d",
629 StationTypeName(stationType).Data(),
630 PlaneTypeName(plane).Data(),
631 digit.ManuId(),
632 m));
633 return -1;
634 }
ced309a5 635
2cbb173f 636 Int_t busPatchId = vec->At(pos);
ced309a5 637
2cbb173f 638 fMappingTimer.Stop();
639
640 return busPatchId;
ced309a5 641}
642
a19e2543 643//____________________________________________________________________
644Int_t AliMUONRawWriter::WriteTriggerDDL()
645{
2cf44ef3 646 //
647 // Write trigger DDL
648 //
2cbb173f 649 fTriggerTimer.Start(kFALSE);
650
a19e2543 651 // DDL event one per half chamber
a19e2543 652
a19e2543 653 // stored local id number
654 TArrayI isFired(256);
655 isFired.Reset();
656
657
2cf44ef3 658 // DDL header size
659 Int_t headerSize = sizeof(AliRawDataHeader)/4;
ced309a5 660
a19e2543 661 TClonesArray* localTrigger;
662 TClonesArray* globalTrigger;
663 AliMUONGlobalTrigger* gloTrg;
664 AliMUONLocalTrigger* locTrg = 0x0;
665
a19e2543 666 // global trigger for trigger pattern
667 globalTrigger = fMUONData->GlobalTrigger();
668 gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
2cf44ef3 669 Int_t gloTrigPat = gloTrg->GetGlobalPattern();
a19e2543 670
671 // local trigger
672 localTrigger = fMUONData->LocalTrigger();
673
674 UInt_t word;
675 Int_t* buffer = 0;
676 Int_t index;
677 Int_t iEntries = 0;
678 Int_t iLocCard, locCard;
679 Char_t locDec, trigY, posY, posX,regOut;
680 Int_t devX;
681 Int_t version = 1; // software version
682 Int_t eventType = 1; // trigger type: 1 for physics ?
683 Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
684 Int_t globalFlag = 1; // set to 2 if global info present in DDL else set to 1
685
ced309a5 686 if(fScalerEvent)
687 eventType = 2; //set to generate scaler events
688
a19e2543 689 Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
690 // stored the local card id that's fired
691 for (Int_t i = 0; i < nEntries; i++) {
692 locTrg = (AliMUONLocalTrigger*)localTrigger->At(i);
693 isFired[locTrg->LoCircuit()] = 1; // storing local boards with informations
694 }
695
696 if (!nEntries)
62c04fc3 697 AliInfo("No Trigger information available");
a19e2543 698
ced309a5 699 if(fScalerEvent)
00f56161 700 // [16(local)*51 words + 16 words]*8(reg) + 6 + 12 + 6 words scaler event 6672 words
701 buffer = new Int_t [6680];
ced309a5 702 else
00f56161 703 // [16(local)*6 words + 5 words]*8(reg) + 10 words = 818
704 buffer = new Int_t [818];
ced309a5 705
a19e2543 706
707 // open DDL file, on per 1/2 chamber
708 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
709
710 index = 0;
711
a19e2543 712 word = 0;
00f56161 713 // set darc status word
a19e2543 714 AliBitPacking::PackWord((UInt_t)iDDL+1,word,28,31); //see AliMUONDDLTrigger.h for details
715 AliBitPacking::PackWord((UInt_t)serialNb,word,24,27);
716 AliBitPacking::PackWord((UInt_t)version,word,16,23);
717 AliBitPacking::PackWord((UInt_t)eventType,word,12,15);
718
719 if (iDDL == 0) // suppose global info in DDL one
720 globalFlag = 2;
721 else
722 globalFlag = 1;
ced309a5 723
a19e2543 724 AliBitPacking::PackWord((UInt_t)globalFlag,word,8,11);
2cf44ef3 725 fDarcHeader->SetWord(word);
18d3ded7 726
727 memcpy(&buffer[index], fDarcHeader->GetHeader(), (fDarcHeader->GetDarcHeaderLength())*4);
728 index += fDarcHeader->GetDarcHeaderLength();
a19e2543 729
730 if (iDDL == 0)
2cf44ef3 731 fDarcHeader->SetGlobalOutput(gloTrigPat);// no global input for the moment....
a19e2543 732 else
2cf44ef3 733 fDarcHeader->SetGlobalOutput(0);
ced309a5 734
735 if (fScalerEvent) {
736 // 6 DARC scaler words
2cf44ef3 737 memcpy(&buffer[index], fDarcHeader->GetDarcScalers(),fDarcHeader->GetDarcScalerLength()*4);
738 index += fDarcHeader->GetDarcScalerLength();
ced309a5 739 }
2cf44ef3 740 // end of darc word
741 buffer[index++] = fDarcHeader->GetEndOfDarc();
ced309a5 742
743 // 4 words of global board input + Global board output
18d3ded7 744 memcpy(&buffer[index], fDarcHeader->GetGlobalInput(), (fDarcHeader->GetGlobalHeaderLength())*4);
745 index += fDarcHeader->GetGlobalHeaderLength();
ced309a5 746
747 if (fScalerEvent) {
748 // 10 Global scaler words
2cf44ef3 749 memcpy(fDarcHeader->GetGlobalScalers(), &buffer[index], fDarcHeader->GetGlobalScalerLength()*4);
750 index += fDarcHeader->GetGlobalScalerLength();
ced309a5 751 }
a19e2543 752
2cf44ef3 753 // end of global word
754 buffer[index++] = fDarcHeader->GetEndOfGlobal();
755
a19e2543 756 // 8 regional cards per DDL
757 for (Int_t iReg = 0; iReg < 8; iReg++) {
758
a19e2543 759 // Regional card header
760 word = 0;
00f56161 761
762 // set darc status word
763 fRegHeader->SetDarcWord(word);
764
a19e2543 765 regOut = 0;
2cf44ef3 766 AliBitPacking::PackWord((UInt_t)serialNb,word,24,28); //see AliMUONLocalStruct.h for details
a19e2543 767 AliBitPacking::PackWord((UInt_t)version,word,16,23);
768 AliBitPacking::PackWord((UInt_t)iReg,word,12,15);
769 AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // whenever regional output will be implemented
770
2cf44ef3 771 fRegHeader->SetWord(word);
772 memcpy(&buffer[index],fRegHeader->GetHeader(),fRegHeader->GetHeaderLength()*4);
773 index += fRegHeader->GetHeaderLength();
a19e2543 774
ced309a5 775 // 11 regional scaler word
776 if (fScalerEvent) {
2cf44ef3 777 memcpy(&buffer[index], fRegHeader->GetScalers(), fRegHeader->GetScalerLength()*4);
778 index += fRegHeader->GetScalerLength();
ced309a5 779 }
a19e2543 780
2cf44ef3 781 // end of regional word
782 buffer[index++] = fRegHeader->GetEndOfReg();
783
a19e2543 784 // 16 local card per regional board
785 for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
786
787 iLocCard = iLoc + iReg*16 + iDDL*128;
788
789 if (isFired[iLocCard]) {
790 locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries);
791 locCard = locTrg->LoCircuit();
792 locDec = locTrg->GetLoDecision();
793 trigY = 0;
794 posY = locTrg->LoStripY();
795 posX = locTrg->LoStripX();
796 devX = locTrg->LoDev();
797 AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n",
798 locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
799 } else { //no trigger (see PRR chpt 3.4)
2cf44ef3 800 locCard = -1; // not possible on 4 bits
a19e2543 801 locDec = 0;
802 trigY = 1;
803 posY = 15;
804 posX = 0;
805 devX = 0x8;
806 }
807
808 //packing word
809 word = 0;
810 AliBitPacking::PackWord((UInt_t)(iLocCard % 16),word,19,22); //card id number in crate
811 AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
812 AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
813 AliBitPacking::PackWord((UInt_t)posY,word,10,13);
814 AliBitPacking::PackWord((UInt_t)devX,word,5,9);
815 AliBitPacking::PackWord((UInt_t)posX,word,0,4);
816
817 if (locCard == iLocCard) {
818 // add local cards structure
819 buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
820 buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
821 buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
822 buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
823 buffer[index++] = (Int_t)word; // data word
824 if (iEntries < nEntries-1)
825 iEntries++;
826 } else {
827 buffer[index++] = 0; // 4 words for x1, x2, y1, y2
828 buffer[index++] = 0;
829 buffer[index++] = 0;
830 buffer[index++] = 0;
831 buffer[index++] = (Int_t)word; // data word
832
833 }
ced309a5 834 // 45 regional scaler word
835 if (fScalerEvent) {
2cf44ef3 836 memcpy(&buffer[index], fLocalStruct->GetScalers(), fLocalStruct->GetScalerLength()*4);
837 index += fLocalStruct->GetScalerLength();
ced309a5 838 }
839
2cf44ef3 840 // end of local structure words
841 buffer[index++] = fLocalStruct->GetEndOfLocal();
a19e2543 842
2cf44ef3 843 } // local card
a19e2543 844
845 } // Regional card
846
a19e2543 847
848 // writting onto disk
849 // write DDL 1
2cf44ef3 850 fHeader.fSize = (index + headerSize) * 4;// total length in bytes
851 fwrite((char*)(&fHeader),headerSize*4,1,fFile[iDDL]);
a19e2543 852 fwrite(buffer,sizeof(int),index,fFile[iDDL]);
853
854 }
855 delete[] buffer;
856
2cbb173f 857 fTriggerTimer.Stop();
858
ced309a5 859 return kTRUE;
a19e2543 860}
84ceeb06 861//____________________________________________________________________
862void AliMUONRawWriter::SetScalersNumbers()
863{
864 // set numbers for scaler events for trigger headers
865 // since this is provided by the experiment
866 // put dummy numbers to check the monitoring
867
868 fDarcHeader->SetScalersNumbers();
869 fRegHeader->SetScalersNumbers();
870 fLocalStruct->SetScalersNumbers();
871
872 fScalerEvent = kTRUE;
873}