]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONRawData.cxx
disable global transformation for trigger & transform.dat files in new ALICE coordina...
[u/mrichter/AliRoot.git] / MUON / AliMUONRawData.cxx
CommitLineData
f6762c71 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
16////////////////////////////////////
17//
ce6a659c 18// MUON Raw Data generator and reader in ALICE-MUON
19// This class version 1 (further details could be found in Alice-note)
20// Digits2Raw:
c8b4255f 21// Generates raw data for MUON tracker and finally for trigger
f6762c71 22// * a simple mapping is used (see below)
69be760c 23// * the bus patch id is calculated with an absolute number 0 - 999
c8b4255f 24// * one DDL per 1/2 chamber is created for both cathode.
25// For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
ce6a659c 26// Ch. Finck july 04
27// Raw2Digits:
28// Using still dummy mapping (inverse) for tracker
29// Indranil Das (Adapted for runloader: Ch. Finck) july 05
f6762c71 30////////////////////////////////////
c8b4255f 31
a2da7817 32#include <fstream>
33#include <string>
34
69be760c 35#include <TClonesArray.h>
f6762c71 36#include "AliMUONRawData.h"
37#include "AliMUONDigit.h"
1195fa7b 38
f1501d74 39#include "AliMUON.h"
40#include "AliMUONChamber.h"
f6762c71 41#include "AliMUONConstants.h"
42#include "AliMUONData.h"
f6762c71 43#include "AliLoader.h"
44#include "AliBitPacking.h"
1197ff51 45#include "AliRawReader.h"
1195fa7b 46
47#include "AliMUONSubEventTrigger.h"
69be760c 48#include "AliMUONDDLTracker.h"
49#include "AliMUONDDLTrigger.h"
50
c8b4255f 51#include "AliMUONLocalTrigger.h"
52#include "AliMUONGlobalTrigger.h"
f1501d74 53
54#include "AliMUONGeometrySegmentation.h"
a2da7817 55#include "AliMUONGeometryModule.h"
56#include "AliMUONGeometryStore.h"
57#include "AliMUONSegmentationManager.h"
58#include "AliMpPlaneType.h"
59#include "AliMpVSegmentation.h"
60#include "AliMpHelper.h"
61#include "AliMpPad.h"
8c343c7c 62#include "AliLog.h"
f1501d74 63#include "AliRun.h"
f6762c71 64
f6762c71 65
f6762c71 66
ce6a659c 67ClassImp(AliMUONRawData) // Class implementation in ROOT context
f6762c71 68//__________________________________________________________________________
a2da7817 69AliMUONRawData::AliMUONRawData(AliLoader* loader)
1197ff51 70 : TObject()
f6762c71 71{
72 // Standard Constructor
73
f6762c71 74 // initialize loader's
75 fLoader = loader;
76
77 // initialize container
78 fMUONData = new AliMUONData(fLoader,"MUON","MUON");
69be760c 79
69be760c 80 // initialize array
a2da7817 81 fSubEventArray = new TClonesArray("AliMUONSubEventTracker",1000);
69be760c 82
69be760c 83
84 // ddl pointer
85 fDDLTracker = new AliMUONDDLTracker();
ce6a659c 86 fDDLTrigger = new AliMUONDDLTrigger();
a2da7817 87
88 ReadBusPatchFile();
89
f6762c71 90}
91
92//__________________________________________________________________________
93AliMUONRawData::AliMUONRawData()
94 : TObject(),
f6762c71 95 fMUONData(0),
ce6a659c 96 fLoader(0),
ce6a659c 97 fDDLTracker(0),
98 fDDLTrigger(0)
f6762c71 99{
100 // Default Constructor
a2da7817 101 fFile[0] = fFile[1] = 0x0;
102
f6762c71 103}
104
105//_______________________________________________________________________
106AliMUONRawData::AliMUONRawData (const AliMUONRawData& rhs)
107 : TObject(rhs)
108{
109// Protected copy constructor
110
8c343c7c 111 AliFatal("Not implemented.");
f6762c71 112}
113
114//_______________________________________________________________________
115AliMUONRawData &
116AliMUONRawData::operator=(const AliMUONRawData& rhs)
117{
118// Protected assignement operator
119
120 if (this == &rhs) return *this;
121
8c343c7c 122 AliFatal("Not implemented.");
f6762c71 123
124 return *this;
125}
126
127//__________________________________________________________________________
128AliMUONRawData::~AliMUONRawData(void)
129{
130 if (fMUONData)
131 delete fMUONData;
a2da7817 132 if (fSubEventArray)
133 fSubEventArray->Delete(); //using delete cos allocating memory in copy ctor.
69be760c 134
69be760c 135 if (fDDLTracker)
136 delete fDDLTracker;
137 if (fDDLTrigger)
138 delete fDDLTrigger;
139
a2da7817 140 fDetElemIdToBusPatch.Delete();
141 fBusPatchToDetElem.Delete();
142
f6762c71 143 return;
144}
145//____________________________________________________________________
1197ff51 146Int_t AliMUONRawData::Digits2Raw()
f6762c71 147{
148 // convert digits of the current event to raw data
149
1195fa7b 150 Int_t idDDL;
f6762c71 151 Char_t name[20];
152
153 fLoader->LoadDigits("READ");
69be760c 154
c8b4255f 155 fMUONData->SetTreeAddress("D,GLT");
f6762c71 156
f6762c71 157
c8b4255f 158 // tracking chambers
159
160 for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
161
f6762c71 162 // open files
a2da7817 163 idDDL = ich * 2 + 0x900; // official number for MUON
1195fa7b 164 sprintf(name, "MUON_%d.ddl",idDDL);
a2da7817 165 fFile[0] = fopen(name,"w");
f6762c71 166
1195fa7b 167 idDDL = (ich * 2) + 1 + 0x900;
168 sprintf(name, "MUON_%d.ddl",idDDL);
a2da7817 169 fFile[1] = fopen(name,"w");
f6762c71 170
69be760c 171 WriteTrackerDDL(ich);
f6762c71 172
173 // reset and close
a2da7817 174 fclose(fFile[0]);
175 fclose(fFile[1]);
f6762c71 176 fMUONData->ResetDigits();
177 }
69be760c 178
179 // trigger chambers
c8b4255f 180
69be760c 181 // open files
a2da7817 182 idDDL = 0xA00;// official number for MUTR
1195fa7b 183 sprintf(name, "MUTR_%d.ddl",idDDL);
a2da7817 184 fFile[0] = fopen(name,"w");
69be760c 185
1195fa7b 186 idDDL = 0xA00 + 1;
187 sprintf(name, "MUTR_%d.ddl",idDDL);
a2da7817 188 fFile[1] = fopen(name,"w");
69be760c 189
c8b4255f 190 WriteTriggerDDL();
191
192 // reset and close
a2da7817 193 fclose(fFile[0]);
194 fclose(fFile[1]);
c8b4255f 195 fMUONData->ResetTrigger();
f6762c71 196
c8b4255f 197 fLoader->UnloadDigits();
69be760c 198
f6762c71 199 return kTRUE;
200}
201//____________________________________________________________________
69be760c 202Int_t AliMUONRawData::WriteTrackerDDL(Int_t iCh)
f6762c71 203{
a2da7817 204 // writing DDL for tracker
205 // used inverse mapping
206
69be760c 207 // resets
f6762c71 208 TClonesArray* muonDigits = 0;
a2da7817 209 fSubEventArray->Clear();
69be760c 210
211 //
a2da7817 212 TArrayI nbInBus;
69be760c 213
a2da7817 214 nbInBus.Set(5000);
69be760c 215
a2da7817 216 nbInBus.Reset();
69be760c 217
218 // DDL header
219 AliRawDataHeader header = fDDLTracker->GetHeader();
220 Int_t headerSize = fDDLTracker->GetHeaderSize();
f6762c71 221
222 // DDL event one per half chamber
69be760c 223 AliMUONSubEventTracker* subEvent;
f6762c71 224
225 // data format
226 Char_t parity = 0x4;
69be760c 227 UShort_t manuId = 0;
228 UChar_t channelId = 0;
229 UShort_t charge = 0;
230 Int_t busPatchId = 0;
f6762c71 231
232 UInt_t word;
69be760c 233 Int_t nEntries = 0;
234 Int_t* buffer = 0;
235 Int_t index;
236 Int_t indexDsp;
237 Int_t indexBlk;
f1501d74 238 Int_t padX;
239 Int_t padY;
240 Int_t cathode = 0;
241 Int_t detElemId;
f6762c71 242 Int_t nDigits;
f6762c71 243
a2da7817 244 const AliMUONDigit* digit;
f6762c71 245
a2da7817 246 AliDebug(3, Form("WriteDDL chamber %d\n", iCh+1));
f6762c71 247
a2da7817 248 // getting digits
249 fMUONData->ResetDigits();
250 fMUONData->GetDigits();
251 muonDigits = fMUONData->Digits(iCh);
f6762c71 252
a2da7817 253 nDigits = muonDigits->GetEntriesFast();
254 AliDebug(3,Form("ndigits = %d\n",nDigits));
f6762c71 255
a2da7817 256 // loop over digit
257 for (Int_t idig = 0; idig < nDigits; idig++) {
258
259 digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
260
261 padX = digit->PadX();
262 padY = digit->PadY();
263 charge = digit->Signal();
264 charge &= 0xFFF;
265 cathode = digit->Cathode();
266 detElemId = digit->DetElemId();
267
268 // inverse mapping
269 Int_t error = GetInvMapping(digit, busPatchId, manuId, channelId);
270 if (error) continue;
271
272 AliDebug(1,Form("input IdDE %d busPatchId %d PadX %d PadY %d iCath %d \n",
273 detElemId, busPatchId, padX, padY, cathode));
274
275 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n", busPatchId, manuId, channelId ));
276
277 //packing word
278 AliBitPacking::PackWord((UInt_t)parity,word,29,31);
279 AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
280 AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
281 AliBitPacking::PackWord((UInt_t)charge,word,0,11);
282
283 // set sub Event
284 subEvent = new AliMUONSubEventTracker();
285 subEvent->AddData(word);
286 subEvent->SetBusPatchId(busPatchId);
287
288 // storing the number of identical buspatches
289 nbInBus[busPatchId]++;
290 AddData(subEvent);
291
292 delete subEvent;
293 }
294
295 // sorting by buspatch
296 fSubEventArray->Sort();
69be760c 297
298 // gather datas from same bus patch
a2da7817 299 nEntries = fSubEventArray->GetEntriesFast();
300
301 for (Int_t i = 0; i < nEntries; i++) {
302 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray->At(i);
303 busPatchId = temp->GetBusPatchId();
304
305 // add bus patch header, length and total length managed by subevent class
306 temp->SetTriggerWord(0xdeadbeef);
307 for (Int_t j = 0; j < nbInBus[busPatchId]-1; j++) {
308 AliMUONSubEventTracker* temp1 = (AliMUONSubEventTracker*)fSubEventArray->At(++i);
309 temp->AddData(temp1->GetData(0));
310 fSubEventArray->RemoveAt(i) ;
311 }
312 }
313 fSubEventArray->Compress();
69be760c 314
a2da7817 315 if (AliLog::GetGlobalDebugLevel() == 3) {
316 nEntries = fSubEventArray->GetEntriesFast();
69be760c 317 for (Int_t i = 0; i < nEntries; i++) {
a2da7817 318 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray->At(i);
319 printf("busPatchid back %d\n",temp->GetBusPatchId());
320 for (Int_t j = 0; j < temp->GetLength(); j++) {
321 printf("manuId back %d, ",temp->GetManuId(j));
322 printf("channelId back %d, ",temp->GetChannelId(j));
323 printf("charge back %d\n",temp->GetCharge(j));
69be760c 324 }
325 }
a2da7817 326 printf("\n");
327 }
69be760c 328
329 Int_t iBusPatch;
a2da7817 330 Int_t iEntries = 0;
c8f4be1a 331 Int_t length;
69be760c 332
a2da7817 333 // open DDL file, on per 1/2 chamber
69be760c 334 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
335
69be760c 336 // filling buffer
a2da7817 337 nEntries = fSubEventArray->GetEntriesFast();
69be760c 338 buffer = new Int_t [(2048+24)*50]; // 24 words in average for one buspatch and 2048 manu info at most
339
340 indexBlk = 0;
341 indexDsp = 0;
342 index = 0;
343 iBusPatch = 0;
69be760c 344
a2da7817 345 // two blocks A and B per DDL
69be760c 346 for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
347
348 // block header
c8f4be1a 349 length = fDDLTracker->GetBlkHeaderLength();
350 memcpy(&buffer[index],fDDLTracker->GetBlkHeader(),length*4);
69be760c 351 indexBlk = index;
c8f4be1a 352 index += length;
69be760c 353
a2da7817 354 // 5 DSP's per block
69be760c 355 for (Int_t iDsp = 0; iDsp < 5; iDsp++) {
356
357 // DSP header
c8f4be1a 358 length = fDDLTracker->GetDspHeaderLength();
359 memcpy(&buffer[index],fDDLTracker->GetDspHeader(),length*4);
69be760c 360 indexDsp = index;
c8f4be1a 361 index += length;
69be760c 362
a2da7817 363 // 5 buspatches per DSP
69be760c 364 for (Int_t i = 0; i < 5; i++) {
365
a2da7817 366 // assuming busPatchId begins at 100 (to be discussed ChF)
367 iBusPatch = i + iBlock*25 + iDsp*5 + 50*(2*(iCh+1) + iDDL);
368 AliDebug(3,Form("busPatchId %d", iBusPatch));
69be760c 369
a2da7817 370 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray->At(iEntries);
371 if (nEntries > 0) {
69be760c 372 busPatchId = temp->GetBusPatchId();
a2da7817 373 AliDebug(3,Form("busPatchId %d", temp->GetBusPatchId()));
374 } else
375 busPatchId = -1;
376
377 // check if buspatchid has digit
69be760c 378 if (busPatchId == iBusPatch) {
379 // add bus patch structure
c8f4be1a 380 length = temp->GetHeaderLength();
381 memcpy(&buffer[index],temp->GetAddress(),length*4);
382 index += length;
a2da7817 383 for (Int_t j = 0; j < temp->GetLength(); j++) {
69be760c 384 buffer[index++] = temp->GetData(j);
a2da7817 385 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n", temp->GetBusPatchId(),
386 temp->GetManuId(j), temp->GetChannelId(j) ));
387 }
69be760c 388 if (iEntries < nEntries-1)
a2da7817 389 iEntries++;
69be760c 390 } else {
a2da7817 391 // writting anyhow buspatch structure (empty ones)
69be760c 392 buffer[index++] = 4; // total length
393 buffer[index++] = 0; // raw data length
394 buffer[index++] = iBusPatch; // bus patch
395 buffer[index++] = 0xdeadbeef; // trigger word
396 }
397 } // bus patch
c8f4be1a 398 buffer[indexDsp] = index - indexDsp; // dsp length
399 buffer[indexDsp+1] = index - indexDsp - fDDLTracker->GetDspHeaderLength();
69be760c 400 if ((index - indexDsp) % 2 == 0)
401 buffer[indexDsp+7] = 0;
402 else
403 buffer[indexDsp+7] = 1;
404 } // dsp
c8f4be1a 405 buffer[indexBlk] = index - indexBlk; // block length
406 buffer[indexBlk+1] = index - indexBlk - fDDLTracker->GetBlkHeaderLength();
69be760c 407 }
a2da7817 408
409 //writting onto disk
410 // write DDL 1 & 2
411 header.fSize = (index + headerSize) * 4;// total length in bytes
412 fwrite((char*)(&header),headerSize*4,1,fFile[iDDL]);
413 fwrite(buffer,sizeof(int),index,fFile[iDDL]);
414
69be760c 415 delete[] buffer;
416 }
417
418 return kTRUE;
419}
420//____________________________________________________________________
421Int_t AliMUONRawData::WriteTriggerDDL()
422{
423
c8b4255f 424 // DDL event one per half chamber
425 AliMUONSubEventTrigger* subEvent = 0x0;
69be760c 426
69be760c 427
c8b4255f 428 // stored local id number
429 TArrayI isFired(256);
430 isFired.Reset();
69be760c 431
69be760c 432
c8b4255f 433 // DDL header
434 AliRawDataHeader header = fDDLTrigger->GetHeader();
435 Int_t headerSize = fDDLTrigger->GetHeaderSize();
c8f4be1a 436 Int_t length;
c8b4255f 437 TClonesArray* localTrigger;
438 TClonesArray* globalTrigger;
439 AliMUONGlobalTrigger* gloTrg;
440 AliMUONLocalTrigger* locTrg = 0x0;
441
a2da7817 442 // getting information from trigger
c8b4255f 443 fMUONData->GetTriggerD();
444
445 // global trigger for trigger pattern
446 globalTrigger = fMUONData->GlobalTrigger();
447 gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
448 Int_t gloTrigPat = GetGlobalTriggerPattern(gloTrg);
449
450 // local trigger
451 localTrigger = fMUONData->LocalTrigger();
452
453 UInt_t word;
454 Int_t* buffer = 0;
455 Int_t index;
456 Int_t iEntries = 0;
457 Int_t iLocCard, locCard;
e516b01d 458 Char_t locDec, trigY, posY, devX, posX,regOut;
c8b4255f 459 Int_t version = 1; // software version
c8f4be1a 460 Int_t eventType = 1; // trigger type: 1 for physics ?
c8b4255f 461 Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
c8f4be1a 462 Int_t globalFlag = 1; // set to 2 if global info present in DDL else set to 1
c8b4255f 463
464 Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
465 // stored the local card id that's fired
466 for (Int_t i = 0; i < nEntries; i++) {
467 locTrg = (AliMUONLocalTrigger*)localTrigger->At(i);
a2da7817 468 isFired[locTrg->LoCircuit()] = 1; // storing local boards with informations
c8b4255f 469 }
470
471 if (!nEntries)
8c343c7c 472 AliError("No Trigger information available");
c8b4255f 473
c8f4be1a 474 buffer = new Int_t [672]; // [16(local)*5 words + 3 words]*8(reg) + 8 words = 672
c8b4255f 475
a2da7817 476 // open DDL file, on per 1/2 chamber
c8b4255f 477 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
478
479 index = 0;
480
481 // DDL enhanced header
c8f4be1a 482 word = 0;
483 AliBitPacking::PackWord((UInt_t)iDDL+1,word,28,31); //see AliMUONDDLTrigger.h for details
484 AliBitPacking::PackWord((UInt_t)serialNb,word,24,27);
485 AliBitPacking::PackWord((UInt_t)version,word,16,23);
486 AliBitPacking::PackWord((UInt_t)eventType,word,12,15);
487
488 if (iDDL == 0) // suppose global info in DDL one
489 globalFlag = 2;
490 else
491 globalFlag = 1;
492 AliBitPacking::PackWord((UInt_t)globalFlag,word,8,11);
c8b4255f 493 fDDLTrigger->SetDDLWord(word);
c8f4be1a 494
495 if (iDDL == 0)
496 fDDLTrigger->SetGlobalOutput(gloTrigPat);// no global input for the moment....
497 else
498 fDDLTrigger->SetGlobalOutput(0);
499 length = fDDLTrigger->GetHeaderLength();
500 memcpy(&buffer[index],fDDLTrigger->GetEnhancedHeader(),length*4);
501 index += length;
c8b4255f 502
a2da7817 503 // 8 regional cards per DDL
c8b4255f 504 for (Int_t iReg = 0; iReg < 8; iReg++) {
505
506 subEvent = new AliMUONSubEventTrigger();
507
508 // Regional card header
509 word = 0;
e516b01d 510 regOut = 0;
511 AliBitPacking::PackWord((UInt_t)serialNb,word,24,28); //see AliMUONSubEventTrigger.h for details
512 AliBitPacking::PackWord((UInt_t)version,word,16,23);
513 AliBitPacking::PackWord((UInt_t)iReg,word,12,15);
514 AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // whenever regional output will be implemented
515
c8b4255f 516 subEvent->SetRegWord(word);
517 memcpy(&buffer[index++],subEvent->GetAddress(),4);
518
e516b01d 519 buffer[index++] = 0;// 2 words of regional input
520 buffer[index++] = 0;
521
a2da7817 522 // 16 local card per regional board
c8b4255f 523 for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
524
525 iLocCard = iLoc + iReg*16 + iDDL*128;
526
527 if (isFired[iLocCard]) {
528 locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries);
529 locCard = locTrg->LoCircuit();
530 locDec = locTrg->GetLoDecision();
531 trigY = 0;
532 posY = locTrg->LoStripY();
533 posX = locTrg->LoStripX();
534 devX = locTrg->LoDev();
1197ff51 535 AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n",
ce6a659c 536 locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
c8b4255f 537 } else { //no trigger (see PRR chpt 3.4)
538 locCard = -1;
539 locDec = 0;
540 trigY = 1;
541 posY = 15;
542 posX = 0;
543 devX = 0x8000;
544 }
545
546 //packing word
547 word = 0;
548 AliBitPacking::PackWord((UInt_t)(iLocCard % 16),word,19,22); //card id number in crate
549 AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
550 AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
551 AliBitPacking::PackWord((UInt_t)posY,word,10,13);
552 AliBitPacking::PackWord((UInt_t)devX,word,5,9);
553 AliBitPacking::PackWord((UInt_t)posX,word,0,4);
554
555 if (locCard == iLocCard) {
556 // add local cards structure
557 buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
558 buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
559 buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
560 buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
561 buffer[index++] = (Int_t)word; // data word
562 if (iEntries < nEntries-1)
563 iEntries++;
564 } else {
565 buffer[index++] = 0; // 4 words for x1, x2, y1, y2
566 buffer[index++] = 0;
567 buffer[index++] = 0;
568 buffer[index++] = 0;
569 buffer[index++] = (Int_t)word; // data word
570
571 }
572 } // local card
c8b4255f 573
574 delete subEvent;
575
576 } // Regional card
577
578 buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word
a0b2ac9a 579 buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word for 64 bits transfer purpose
c8b4255f 580
a2da7817 581 // writting onto disk
582 // write DDL 1
583 header.fSize = (index + headerSize) * 4;// total length in bytes
584 fwrite((char*)(&header),headerSize*4,1,fFile[iDDL]);
585 fwrite(buffer,sizeof(int),index,fFile[iDDL]);
586
c8b4255f 587 }
588 delete[] buffer;
69be760c 589
590 return kTRUE;
591}
a2da7817 592
69be760c 593//____________________________________________________________________
a2da7817 594Int_t AliMUONRawData::GetInvMapping(const AliMUONDigit* digit,
f1501d74 595 Int_t &busPatchId, UShort_t &manuId, UChar_t &channelId)
69be760c 596{
f6762c71 597
a2da7817 598 // Inverse mapping for tracker
599
600 // information from digits
601 Int_t iCath = digit->Cathode();
602 Int_t idDE = digit->DetElemId();
603 Int_t padX = digit->PadX();
604 Int_t padY = digit->PadY();
605
606 if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0)
607 padX--; // while in AliMUONSt345Seg. they begin at (1,1)
608 padY--;
609 }
610
611 // segmentation
612 AliMpPlaneType plane;
613 AliMpPlaneType plane1 = kBendingPlane;
614 AliMpPlaneType plane2 = kNonBendingPlane;
615
616 if (idDE < 500) { // should use GetDirection somehow (ChF)
617 if ( ((idDE % 100) % 2) != 0 ) {
618 plane1 = kNonBendingPlane;
619 plane2 = kBendingPlane;
620 }
621 }
622 // station 345 bending == cath0 for the moment
623 plane = (iCath == 0) ? plane1 : plane2;
624
625 AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
626 AliMpPad pad = seg->PadByIndices(AliMpIntPair(padX,padY),kTRUE);
627
628 if(!pad.IsValid()) {
629 AliWarning(Form("No elec. for idDE: %d, padx: %d pady %d, charge: %d\n",
630 idDE, digit->PadX(), digit->PadY(), digit->Signal()));
631 return kTRUE;
632 }
633
634 // Getting Manu id
635 manuId = pad.GetLocation().GetFirst();
636 manuId &= 0x7FF; // 11 bits
f6762c71 637
a2da7817 638 // Getting channel id
639 channelId = pad.GetLocation().GetSecond();
640 channelId &= 0x3F; // 6 bits
f6762c71 641
a2da7817 642 // Getting buspatch id
643 TArrayI* vec = GetBusfromDE(idDE);
644 Int_t pos;
645
646 if (idDE < 500) { // station 1 & 2
647 // set 32 manus for one bus patch ? (ChF)
648 pos = manuId/32;
649 } else {
650 // offset of 100 in manuId for following bus patch
651 pos = manuId/100;
652 }
653
654 // if (pos >(int_t) vec.size())
655// AliWarning("pos greater than size\n");
656 busPatchId = vec->At(pos);
657
658 if (plane == kNonBendingPlane) // for Non-Bending manuid+= 1000;
659 manuId += 1000; // tmp solution til one finds something better (ChF)
660
661 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId:%d\n",
662 idDE, busPatchId, manuId, channelId));
663
664 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady: %d, charge: %d\n",
665 idDE, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal()));
666
667 return kFALSE; // no error
f6762c71 668}
c8b4255f 669
670//____________________________________________________________________
1195fa7b 671Int_t AliMUONRawData::GetGlobalTriggerPattern(const AliMUONGlobalTrigger* gloTrg)
c8b4255f 672{
1195fa7b 673 // global trigger pattern calculation
674
c8b4255f 675 Int_t gloTrigPat = 0;
676
677 if (gloTrg->SinglePlusLpt()) gloTrigPat|= 0x1;
678 if (gloTrg->SinglePlusHpt()) gloTrigPat|= 0x2;
679 if (gloTrg->SinglePlusApt()) gloTrigPat|= 0x4;
680
681 if (gloTrg->SingleMinusLpt()) gloTrigPat|= 0x8;
682 if (gloTrg->SingleMinusHpt()) gloTrigPat|= 0x10;
683 if (gloTrg->SingleMinusApt()) gloTrigPat|= 0x20;
684
685 if (gloTrg->SingleUndefLpt()) gloTrigPat|= 0x40;
686 if (gloTrg->SingleUndefHpt()) gloTrigPat|= 0x80;
687 if (gloTrg->SingleUndefApt()) gloTrigPat|= 0x100;
688
689 if (gloTrg->PairUnlikeLpt()) gloTrigPat|= 0x200;
690 if (gloTrg->PairUnlikeHpt()) gloTrigPat|= 0x400;
691 if (gloTrg->PairUnlikeApt()) gloTrigPat|= 0x800;
692
693 if (gloTrg->PairLikeLpt()) gloTrigPat|= 0x1000;
694 if (gloTrg->PairLikeHpt()) gloTrigPat|= 0x2000;
695 if (gloTrg->PairLikeApt()) gloTrigPat|= 0x4000;
696
697 return gloTrigPat;
698}
1197ff51 699
700//____________________________________________________________________
ce6a659c 701Int_t AliMUONRawData::Raw2Digits(AliRawReader* rawReader)
1197ff51 702{
ce6a659c 703
704 // generate digits
705 ReadTrackerDDL(rawReader);
706
707 // generate trigger
708 ReadTriggerDDL(rawReader);
709
710 return kTRUE;
1197ff51 711
712}
713
714//____________________________________________________________________
ce6a659c 715Int_t AliMUONRawData::ReadTrackerDDL(AliRawReader* rawReader)
1197ff51 716{
a2da7817 717 // reading tracker DDL
718 // filling the TClonesArray in MUONData
719 //
1197ff51 720
ce6a659c 721 AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
722 AliMUONDigit* digit = new AliMUONDigit();
723
724
725 //Read Header Size of DDL,Block,DSP and BusPatch.
726
727 Int_t ddlHeaderSize = fDDLTracker->GetHeaderSize();
728 Int_t blockHeaderSize = fDDLTracker->GetBlkHeaderLength();
729 Int_t dspHeaderSize = fDDLTracker->GetDspHeaderLength();
730 Int_t buspatchHeaderSize = subEventTracker->GetHeaderLength();
731
732// Each DDL is made with 2 Blocks each of which consists of 5 DSP and each of DSP has at most 5 buspatches.
733// This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data.
734
735 const Int_t blankDDLSize = ddlHeaderSize + 2*blockHeaderSize + 2*5*dspHeaderSize + 2*5*5*buspatchHeaderSize;
736 const Int_t blankBlockSize = blockHeaderSize + 5*dspHeaderSize + 5*5*buspatchHeaderSize;
737 const Int_t blankDspSize = dspHeaderSize + 5*buspatchHeaderSize;
738
739 Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize;
740
a2da7817 741 UShort_t charge;
742 Int_t padX, padY,iCath;
ce6a659c 743
a2da7817 744 for(Int_t iDDL = 0; iDDL < 20; iDDL++) { // DDL loop
745 AliDebug(3, Form("Chamber %d\n", iDDL/2 +1 ));
ce6a659c 746
a2da7817 747 rawReader->Select(0X9, iDDL, iDDL); //Select the DDL file to be read
ce6a659c 748
a2da7817 749 rawReader->ReadHeader();
ce6a659c 750
a2da7817 751 totalDDLSize = (rawReader->GetDataSize()+sizeof(AliRawDataHeader))/4; // 4 is multiplied to convert byte 2 word
ce6a659c 752
a2da7817 753 if(totalDDLSize>blankDDLSize){ // Compare the DDL header with an empty DDL header size to read the file
ce6a659c 754
a2da7817 755 Int_t totalDataWord = rawReader->GetDataSize()/4 ;
756 UInt_t *buffer = new UInt_t[totalDataWord];
757 for(Int_t i = 0; i < totalDataWord; i++) {
758 UInt_t& temp = buffer[i];
759 rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
760 }
ce6a659c 761
a2da7817 762 Char_t parity;
763 Int_t buspatchId;
764 UChar_t channelId;
765 UShort_t manuId;//,charge;
766 Int_t idDE;//,padX, padY,iCath;
767 Int_t indexDsp, indexBusPatch, index = 0;
ce6a659c 768
769
a2da7817 770 for(Int_t iBlock = 0; iBlock < 2 ;iBlock++){ // loop over 2 blocks
771 totalBlockSize = buffer[index];
772
773 if(totalBlockSize > blankBlockSize){ // compare block header
774 index += blockHeaderSize;
ce6a659c 775
a2da7817 776 for(Int_t iDsp = 0; iDsp < 5 ;iDsp++){ //DSP loop
777 totalDspSize = buffer[index];
778 indexDsp = index;
ce6a659c 779
a2da7817 780 if(totalDspSize > blankDspSize){ // Compare DSP Header
781 index += dspHeaderSize;
782
783 for(Int_t iBusPatch = 0; iBusPatch < 5 ; iBusPatch++){
784 totalBusPatchSize = buffer[index];
785 indexBusPatch = index;
786 buspatchId = buffer[index+2];
ce6a659c 787
a2da7817 788 if(totalBusPatchSize > buspatchHeaderSize){ //Check Buspatch header
789 index += buspatchHeaderSize;
790 dataSize = totalBusPatchSize - buspatchHeaderSize;
ce6a659c 791
a2da7817 792 if(dataSize>0) {
ce6a659c 793
a2da7817 794 for(Int_t iData = 0; iData < dataSize ;iData++) {
ce6a659c 795
a2da7817 796 subEventTracker->SetData(buffer[index++],iData); //Set to extract data
797 parity = subEventTracker->GetParity(iData);
798 manuId = subEventTracker->GetManuId(iData);
799 channelId = subEventTracker->GetChannelId(iData);
800 charge = subEventTracker->GetCharge(iData);
801 digit->SetSignal(charge); // set charge
ce6a659c 802
a2da7817 803 Int_t error = GetMapping(buspatchId,manuId,channelId,digit); // Get Back the hits at pads
804 if (error) continue;
ce6a659c 805
a2da7817 806 padX = digit->PadX();
807 padY = digit->PadY();
808 iCath = digit->Cathode();
809 idDE = digit->DetElemId();
ce6a659c 810
a2da7817 811 AliDebug(1,Form("output IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n",
812 idDE, buspatchId, padX, padY, iCath));
813
ce6a659c 814
a2da7817 815 AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",idDE, padX, padY, iCath, charge));
816 // fill digits
817 // fMUONData->AddDigit(iCh, *digit);
818 fMUONData->AddDigit(iDDL/2, *digit);
ce6a659c 819
ce6a659c 820
a2da7817 821 } // data loop
822 } // dataSize test
823 } // testing buspatch
ce6a659c 824
a2da7817 825 index = indexBusPatch + totalBusPatchSize;
ce6a659c 826
a2da7817 827 } //buspatch loop
ce6a659c 828
829
a2da7817 830 } // dsp test
ce6a659c 831
a2da7817 832 index = indexDsp + totalDspSize;
ce6a659c 833
a2da7817 834 } // dsp loop
ce6a659c 835
a2da7817 836 } //block test
ce6a659c 837
a2da7817 838 index = totalBlockSize;
ce6a659c 839
a2da7817 840 } //block loop
ce6a659c 841
a2da7817 842 delete[] buffer;
843 } //loop checking the header size of DDL
ce6a659c 844
a2da7817 845 //delete rawReader;
846 } // DDL loop
ce6a659c 847
ce6a659c 848
849 delete subEventTracker;
850 delete digit;
851
852 return kTRUE;
1197ff51 853}
854
855//____________________________________________________________________
a2da7817 856Int_t AliMUONRawData::GetMapping(Int_t busPatchId, UShort_t manuId,
ce6a659c 857 UChar_t channelId, AliMUONDigit* digit )
1197ff51 858{
a2da7817 859
860 // mapping for tracker
861
862 // getting DE from buspatch
863 Int_t idDE = GetDEfromBus(busPatchId);
864 AliDebug(3,Form("idDE: %d busPatchId %d\n", idDE, busPatchId));
865
866 // segmentation
867 Int_t iCath;
868 Int_t iCath1 = 0;
869 Int_t iCath2 = 1;
870
871 AliMpPlaneType plane;
872
873 if (manuId > 1000) { // again tmp solution (ChF) (+1000 for Non-Bending plane
874 plane = kNonBendingPlane;
875 } else {
876 plane = kBendingPlane;
ce6a659c 877 }
a2da7817 878
879 if (idDE < 500) { // should use GetDirection somehow (ChF)
880 if ( ((idDE % 100) % 2) != 0 ) {
881 iCath1 = 1;
882 iCath2 = 0;
883 }
ce6a659c 884 }
a2da7817 885
886 iCath = (manuId > 1000) ? iCath2 : iCath1;
887
888 if (manuId > 1000) manuId -= 1000; // back to normal manuId
889
890 AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
891 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,(Int_t)channelId),kTRUE);
892
893 if(!pad.IsValid()){
894 AliWarning(Form("No pad for idDE: %d, busPatchId %d, manuId: %d, channelId: %d\n",
895 idDE, busPatchId, manuId, channelId));
896 return kTRUE;
897 } // return error
898
899 // Getting padX
900 Int_t padX = pad.GetIndices().GetFirst();
901
902 // Getting padY
903 Int_t padY = pad.GetIndices().GetSecond();
904
905 if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0)
906 padX++; // while in AliMUONSt345Seg. they begin at (1,1)
907 padY++;
ce6a659c 908 }
a2da7817 909 // storing into digits
ce6a659c 910 digit->SetPadX(padX);
911 digit->SetPadY(padY);
912 digit->SetCathode(iCath);
a2da7817 913 digit->SetDetElemId(idDE);
ce6a659c 914
a2da7817 915 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
916 idDE, busPatchId, manuId, channelId, padX, padY));
917 return kFALSE;
1197ff51 918}
919
920//____________________________________________________________________
ce6a659c 921Int_t AliMUONRawData::ReadTriggerDDL(AliRawReader* rawReader)
922{
a2da7817 923
924 // reading DDL for trigger
925
ce6a659c 926 AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
927 AliMUONGlobalTrigger* globalTrigger = 0x0;
928 AliMUONLocalTrigger* localTrigger = new AliMUONLocalTrigger();
929
930
a2da7817 931 //Int_t ddlHeaderSize = fDDLTrigger->GetHeaderSize();
932 // we dont need this, as size of ddl data is same for triger and no trigger
ce6a659c 933
934 Int_t ddlEnhanceHeaderSize = fDDLTrigger->GetHeaderLength();
935 Int_t regHeaderLength = subEventTrigger->GetRegHeaderLength() ;
936
937 Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
938 Char_t loDecision;
939
940 UShort_t X1Pattern, X2Pattern, X3Pattern, X4Pattern;
941 UShort_t Y1Pattern, Y2Pattern, Y3Pattern, Y4Pattern;
942
943
a2da7817 944 // loop over the two ddl's
945 for(Int_t iDDL = 0; iDDL < 2; iDDL++) { //DDL loop
ce6a659c 946
947 rawReader->Select(0XA,iDDL,iDDL); //Select the DDL file to be read
948
949 rawReader->ReadHeader();
950
951 Int_t totalDataWord = rawReader->GetDataSize()/4 ;
952 UInt_t *buffer = new UInt_t[totalDataWord];
953 for(Int_t i=0;i<totalDataWord;i++){
954 UInt_t& temp = buffer[i];
955 rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
956 }
957
958 // rawReader->ReadNext((UChar_t*)buffer, totalDataWord); // method is protected ????
959
960 Int_t index = 0;
961
962 // fill DDL header informations
963 memcpy(fDDLTrigger->GetEnhancedHeader(), &buffer[index], ddlEnhanceHeaderSize*4);
964
965 // fill global trigger information
966 globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
967 fMUONData->AddGlobalTrigger(*globalTrigger);
968
969 index += ddlEnhanceHeaderSize;
970
a2da7817 971 // 8 regional boards
ce6a659c 972 for (Int_t iReg = 0; iReg < 8; iReg++) { //loop over regeonal card
973
974
975 subEventTrigger->SetRegWord(buffer[index]); //read regional data
976
977 index += regHeaderLength;
978
a2da7817 979 // 16 local cards per regional board
ce6a659c 980 for (Int_t iLoc = 0; iLoc < 16; iLoc++) { //loop over local card
981
982 Int_t iLocIndex = index;
983
a2da7817 984 // 5 word trigger information
ce6a659c 985 for(Int_t iData = 0; iData < 5 ;iData++ ){
986 subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData); //read local data
987 }
988
989 if(buffer[iLocIndex] > 0) {
990
991 loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL;
992 loStripX = (Int_t)subEventTrigger->GetXPos(iLoc);
993 loStripY = (Int_t)subEventTrigger->GetYPos(iLoc);
994 loDev = (Int_t)subEventTrigger->GetXDev(iLoc);
995
996 // fill local trigger
997 localTrigger->SetLoCircuit(loCircuit);
998 localTrigger->SetLoStripX(loStripX );
999 localTrigger->SetLoStripY(loStripY);
1000 localTrigger->SetLoDev(loDev);
1001
1002 loDecision = subEventTrigger->GetLocalDec(iLoc);
1003 loLpt = loDecision & 0x3;
1004 loHpt = (loDecision >> 2) & 0x3;
1005
1006 // fill local trigger
1007 localTrigger->SetLoLpt(loLpt);
1008 localTrigger->SetLoHpt(loHpt);
1009
a2da7817 1010 //getting pattern from subvent
ce6a659c 1011 X1Pattern = subEventTrigger->GetX1(iLoc);
1012 X2Pattern = subEventTrigger->GetX2(iLoc);
1013 X3Pattern = subEventTrigger->GetX3(iLoc);
1014 X4Pattern = subEventTrigger->GetX4(iLoc);
1015
1016 Y1Pattern = subEventTrigger->GetY1(iLoc);
1017 Y2Pattern = subEventTrigger->GetY2(iLoc);
1018 Y3Pattern = subEventTrigger->GetY3(iLoc);
1019 Y4Pattern = subEventTrigger->GetY4(iLoc);
1020
1021 // fill local trigger
1022 localTrigger->SetX1Pattern(X1Pattern);
1023 localTrigger->SetX2Pattern(X2Pattern);
1024 localTrigger->SetX3Pattern(X3Pattern);
1025 localTrigger->SetX4Pattern(X4Pattern);
1026
1027 localTrigger->SetY1Pattern(Y1Pattern);
1028 localTrigger->SetY2Pattern(Y2Pattern);
1029 localTrigger->SetY3Pattern(Y3Pattern);
1030 localTrigger->SetY4Pattern(Y4Pattern);
1031 fMUONData->AddLocalTrigger(*localTrigger);
1032
1033 }
1034
1035 } // local card loop
1036
a2da7817 1037 } // regional card loop
ce6a659c 1038
1039 delete [] buffer;
ce6a659c 1040 } // DDL loop
1041
ce6a659c 1042 delete subEventTrigger;
1043 delete globalTrigger;
1044 delete localTrigger;
1045
1046 return kTRUE;
1047
1048}
1049//____________________________________________________________________
1050AliMUONGlobalTrigger* AliMUONRawData::GetGlobalTriggerPattern(Int_t gloTrigPat)
1197ff51 1051{
ce6a659c 1052 // global trigger pattern calculation
1053
1054 Int_t globalSinglePlus[3]; // tot num of single plus
1055 Int_t globalSingleMinus[3]; // tot num of single minus
1056 Int_t globalSingleUndef[3]; // tot num of single undefined
1057 Int_t globalPairUnlike[3]; // tot num of unlike-sign pairs
1058 Int_t globalPairLike[3]; // tot num of like-sign pairs
1059
1060
1061 for (Int_t i = 0; i < 3; i++) {
1062 globalSinglePlus[i] = gloTrigPat & (0x1 << i);
1063 globalSingleMinus[i] = gloTrigPat & (0x1 << i+3);
1064 globalSingleUndef[i] = gloTrigPat & (0x1 << i+6);
1065 globalPairUnlike[i] = gloTrigPat & (0x1 << i+9);
1066 globalPairLike[i] = gloTrigPat & (0x1 << i+12);
1067 }
1068
1069 return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
a2da7817 1070 globalSingleUndef, globalPairUnlike,
1071 globalPairLike));
1072
1073}
1074//____________________________________________________________________
1075Int_t AliMUONRawData::GetDEfromBus(Int_t busPatchId)
1076{
1077 // getting DE id from bus patch
1078 Long_t it = fBusPatchToDetElem.GetValue(busPatchId);
1079
1080 if ( it )
1081 return (Int_t)it;
1082 else
1083 return -1;
1084}
1085
1086//____________________________________________________________________
1087TArrayI* AliMUONRawData::GetBusfromDE(Int_t idDE)
1088{
1089 // getting bus patch from DE id
1090
1091 return (TArrayI*)fDetElemIdToBusPatch.GetValue(idDE);
1092}
1093//____________________________________________________________________
1094void AliMUONRawData::ReadBusPatchFile()
1095{
1096
1097 // idDE <> buspatch map
1098
1099 // reading file
1100 TString dirPath = gSystem->Getenv("ALICE_ROOT");
1101 dirPath += "/MUON/mapping/data/";
1102
1103 TString infile = dirPath + "DetElemIdToBusPatch.dat";
1104
1105 ifstream in(infile, ios::in);
1106 if (!in) AliError("DetElemIdToBusPatch.dat not found.");
1107
1108 char line[80];
1109
1110 while ( in.getline(line,80) ) {
1111
1112 if ( line[0] == '#' ) continue;
1113
1114 TString tmp(AliMpHelper::Normalize(line));
1115
1116 Int_t blankPos = tmp.First(' ');
1117
1118 TString sDE(tmp(0, blankPos));
1119
1120 Int_t idDE = atoi(sDE.Data());
1121
1122 TString busPatch(tmp(blankPos + 1, tmp.Length()-blankPos));
1123
1124 TArrayI busPatchList;
1125 // decoding range of buspatch
1126 AliMpHelper::DecodeName(busPatch,';',busPatchList);
1127
1128 // filling buspatch -> idDE
1129 for (Int_t i = 0; i < busPatchList.GetSize(); i++)
1130 fBusPatchToDetElem.Add((Long_t)busPatchList[i],(Long_t)idDE);
1131
1132
1133 // filling idDE -> buspatch list (vector)
1134 fDetElemIdToBusPatch.Add((Long_t)idDE, (Long_t)(new TArrayI(busPatchList)));
1135
1136 }
1137
1138 in.close();
1197ff51 1139
1140}