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