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