Add local cards pattern & local decision words (Christian)
[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//
18// MUON Raw Data generator in ALICE-MUON
19//
20// This class v-1:
21// * generates raw data for MUON tracker only (for the moment)
22// * a simple mapping is used (see below)
69be760c 23// * the bus patch id is calculated with an absolute number 0 - 999
f6762c71 24// one DDL per 1/2 chamber is created for both cathode.
25//
26////////////////////////////////////
69be760c 27#include <TClonesArray.h>
f6762c71 28#include "AliMUONRawData.h"
29#include "AliMUONDigit.h"
69be760c 30#include "AliMUONTriggerDecision.h"
f6762c71 31#include "AliMUONConstants.h"
32#include "AliMUONData.h"
f6762c71 33#include "AliRun.h"
34#include "AliRunLoader.h"
35#include "AliLoader.h"
36#include "AliBitPacking.h"
69be760c 37#include "AliMUONDDLTracker.h"
38#include "AliMUONDDLTrigger.h"
39
40// #include "AliMUON.h"
41// #include "AliMUONLocalTrigger.h"
42// #include "AliMUONGlobalTrigger.h"
43// #include "AliMUONTriggerCircuit.h"
f6762c71 44
45const Int_t AliMUONRawData::fgkDefaultPrintLevel = 0;
46
47ClassImp(AliMUONRawData) // Class implementation in ROOT context
48
49//__________________________________________________________________________
50AliMUONRawData::AliMUONRawData(AliLoader* loader)
69be760c 51 : TObject(),
52 fDebug(0)
f6762c71 53{
54 // Standard Constructor
55
f6762c71 56 fPrintLevel = fgkDefaultPrintLevel;
57
58 // initialize loader's
59 fLoader = loader;
60
61 // initialize container
62 fMUONData = new AliMUONData(fLoader,"MUON","MUON");
69be760c 63
64 // trigger decision, temp solution, local & global has to move to Digits Tree
65// fTrigDec = new AliMUONTriggerDecision(fLoader);
66// fTrigData = fTrigDec->GetMUONData();
67
68 // initialize array
69 fSubEventArray[0] = new TClonesArray("AliMUONSubEventTracker",1000);
70 fSubEventArray[1] = new TClonesArray("AliMUONSubEventTracker",1000);
71
72 // initialize array
73 fSubEventTrigArray[0] = new TClonesArray("AliMUONSubEventTrigger",1000);
74 fSubEventTrigArray[1] = new TClonesArray("AliMUONSubEventTrigger",1000);
75
76 // ddl pointer
77 fDDLTracker = new AliMUONDDLTracker();
78 fDDLTrigger= new AliMUONDDLTrigger();
f6762c71 79}
80
81//__________________________________________________________________________
82AliMUONRawData::AliMUONRawData()
83 : TObject(),
f6762c71 84 fMUONData(0),
85 fPrintLevel(fgkDefaultPrintLevel),
86 fDebug(0),
87 fLoader(0)
88{
89 // Default Constructor
90}
91
92//_______________________________________________________________________
93AliMUONRawData::AliMUONRawData (const AliMUONRawData& rhs)
94 : TObject(rhs)
95{
96// Protected copy constructor
97
98 Fatal("AliMUONRawData", "Not implemented.");
99}
100
101//_______________________________________________________________________
102AliMUONRawData &
103AliMUONRawData::operator=(const AliMUONRawData& rhs)
104{
105// Protected assignement operator
106
107 if (this == &rhs) return *this;
108
109 Fatal("operator=", "Not implemented.");
110
111 return *this;
112}
113
114//__________________________________________________________________________
115AliMUONRawData::~AliMUONRawData(void)
116{
117 if (fMUONData)
118 delete fMUONData;
69be760c 119 if (fSubEventArray[0])
120 fSubEventArray[0]->Delete(); //using delete cos allocating memory in copy ctor.
121 if (fSubEventArray[1])
122 fSubEventArray[1]->Delete();
123
124 if (fSubEventTrigArray[0])
125 fSubEventTrigArray[0]->Delete();
126 if (fSubEventTrigArray[1])
127 fSubEventTrigArray[1]->Delete();
128
129 if (fDDLTracker)
130 delete fDDLTracker;
131 if (fDDLTrigger)
132 delete fDDLTrigger;
133
134// if (fTrigDec)
135// delete fTrigDec;
f6762c71 136 return;
137}
138//____________________________________________________________________
139Int_t AliMUONRawData::WriteRawData()
140{
141 // convert digits of the current event to raw data
142
f6762c71 143 Int_t DDLId;
144 Char_t name[20];
145
146 fLoader->LoadDigits("READ");
69be760c 147
f6762c71 148 fMUONData->SetTreeAddress("D");
f6762c71 149
150 for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
69be760c 151 // for (Int_t ich = 0; ich < 2; ich++) {
f6762c71 152
153 // open files
98724670 154 DDLId = ich * 2 + 0x900;
f6762c71 155 sprintf(name, "MUON_%d.ddl",DDLId);
156 fFile1 = fopen(name,"w");
157
69be760c 158 DDLId = (ich * 2) + 1 + 0x900;
f6762c71 159 sprintf(name, "MUON_%d.ddl",DDLId);
160 fFile2 = fopen(name,"w");
161
69be760c 162 WriteTrackerDDL(ich);
f6762c71 163
164 // reset and close
165 fclose(fFile1);
166 fclose(fFile2);
167 fMUONData->ResetDigits();
168 }
69be760c 169
170 // trigger chambers
171
172
173 // open files
174// DDLId = 0xA00;
175// sprintf(name, "MUTR_%d.ddl",DDLId);
176// fFile1 = fopen(name,"w");
177
178// DDLId = 0xA00 + 1;
179// sprintf(name, "MUTR_%d.ddl",DDLId);
180// fFile2 = fopen(name,"w");
181
182// WriteTriggerDDL();
f6762c71 183
69be760c 184// // reset and close
185// fclose(fFile1);
186// fclose(fFile2);
187 fLoader->UnloadDigits();
188
f6762c71 189 return kTRUE;
190}
191//____________________________________________________________________
69be760c 192Int_t AliMUONRawData::WriteTrackerDDL(Int_t iCh)
f6762c71 193{
69be760c 194 // resets
f6762c71 195 TClonesArray* muonDigits = 0;
69be760c 196 fSubEventArray[0]->Clear();
197 fSubEventArray[1]->Clear();
198
199 //
200 TArrayI nbInBus[2];
201
202 nbInBus[0].Set(5000);
203 nbInBus[1].Set(5000);
204
205 nbInBus[0].Reset();
206 nbInBus[1].Reset();
207
208 // DDL header
209 AliRawDataHeader header = fDDLTracker->GetHeader();
210 Int_t headerSize = fDDLTracker->GetHeaderSize();
f6762c71 211
212 // DDL event one per half chamber
69be760c 213 AliMUONSubEventTracker* subEvent;
f6762c71 214
215 // data format
216 Char_t parity = 0x4;
69be760c 217 UShort_t manuId = 0;
218 UChar_t channelId = 0;
219 UShort_t charge = 0;
220 Int_t busPatchId = 0;
f6762c71 221
222 UInt_t word;
69be760c 223 Int_t nEntries = 0;
224 Int_t* buffer = 0;
225 Int_t index;
226 Int_t indexDsp;
227 Int_t indexBlk;
f6762c71 228
229 Int_t nDigits;
69be760c 230 const AliMUONDigit* digit;
f6762c71 231
69be760c 232 if (fPrintLevel > 0)
233 printf("WriteDDL chamber %d\n", iCh+1);
f6762c71 234
235 for (Int_t iCath = 0; iCath < 2; iCath++) {
236
f6762c71 237 fMUONData->ResetDigits();
238 fMUONData->GetCathode(iCath);
239 muonDigits = fMUONData->Digits(iCh);
240
241 nDigits = muonDigits->GetEntriesFast();
69be760c 242 if (fPrintLevel == 2)
f6762c71 243 printf("ndigits = %d\n",nDigits);
244
245 // open DDL file, on per 1/2 chamber
246
247 for (Int_t idig = 0; idig < nDigits; idig++) {
248
249 digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
250
69be760c 251 // mapping
252 GetDummyMapping(iCh, iCath, digit, busPatchId, manuId, channelId, charge);
253
254 //packing word
255 AliBitPacking::PackWord((UInt_t)parity,word,29,31);
256 AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
257 AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
258 AliBitPacking::PackWord((UInt_t)charge,word,0,11);
259
260 // set sub Event
261 subEvent = new AliMUONSubEventTracker();
262 subEvent->AddData(word);
263 subEvent->SetBusPatchId(busPatchId);
264 if (digit->PadX() > 0) {
265 nbInBus[0][busPatchId]++;
266 AddData1(subEvent);
267 } else {
268 nbInBus[1][busPatchId]++;
269 AddData2(subEvent);
270 }
271 delete subEvent;
272 }
273 }
274 fSubEventArray[0]->Sort();
275 fSubEventArray[1]->Sort();
276
277 // gather datas from same bus patch
278 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
279 nEntries = fSubEventArray[iDDL]->GetEntriesFast();
280
281 for (Int_t i = 0; i < nEntries; i++) {
282 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
283 busPatchId = temp->GetBusPatchId();
284
285 // add bus patch header, length and total length managed by subevent class
286 temp->SetTriggerWord(0xdeadbeef);
287 for (Int_t j = 0; j < nbInBus[iDDL][busPatchId]-1; j++) {
288 AliMUONSubEventTracker* temp1 = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(++i);
289 temp->AddData(temp1->GetData(0));
290 fSubEventArray[iDDL]->RemoveAt(i) ;
291 }
292 }
293 fSubEventArray[iDDL]->Compress();
294
295 if (fPrintLevel == 3) {
296 nEntries = fSubEventArray[iDDL]->GetEntriesFast();
297 for (Int_t i = 0; i < nEntries; i++) {
298 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(i);
299 printf("busPatchid back %d\n",temp->GetBusPatchId());
300 for (Int_t j = 0; j < temp->GetLength(); j++) {
301 printf("manuId back %d, ",temp->GetManuId(j));
302 printf("channelId back %d, ",temp->GetChannelId(j));
303 printf("charge back %d\n",temp->GetCharge(j));
304 }
305 }
306 printf("\n");
307 }
308
309 }
310
311 Int_t iBusPatch;
312 Int_t iEntries;
313
314 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
315
316
317 // filling buffer
318 nEntries = fSubEventArray[iDDL]->GetEntriesFast();
319 buffer = new Int_t [(2048+24)*50]; // 24 words in average for one buspatch and 2048 manu info at most
320
321 indexBlk = 0;
322 indexDsp = 0;
323 index = 0;
324 iBusPatch = 0;
325 iEntries = 0;
326
327 for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
328
329 // block header
330 fDDLTracker->SetTotalBlkLength(0xFFFFFFFF);
331 memcpy(&buffer[index],fDDLTracker->GetBlkHeader(),32);
332 indexBlk = index;
333 index += 8;
334
335 for (Int_t iDsp = 0; iDsp < 5; iDsp++) {
336
337 // DSP header
338 fDDLTracker->SetTotalDspLength(0xEEEEEEEE);
339 memcpy(&buffer[index],fDDLTracker->GetDspHeader(),32);
340 indexDsp = index;
341 index += 8;
342
343 for (Int_t i = 0; i < 5; i++) {
344
345 iBusPatch = i + iBlock*25 + iDsp*5 + 50*(2*iCh + iDDL);
346
347 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray[iDDL]->At(iEntries);
348 if (nEntries > 0)
349 busPatchId = temp->GetBusPatchId();
350 else
351 busPatchId = -1;
352
353 if (busPatchId == iBusPatch) {
354 // add bus patch structure
355 memcpy(&buffer[index],temp->GetAddress(),16);
356 index+= 4;
357 for (Int_t j = 0; j < temp->GetLength(); j++)
358 buffer[index++] = temp->GetData(j);
359 if (iEntries < nEntries-1)
360 iEntries++;
361 } else {
362 buffer[index++] = 4; // total length
363 buffer[index++] = 0; // raw data length
364 buffer[index++] = iBusPatch; // bus patch
365 buffer[index++] = 0xdeadbeef; // trigger word
366 }
367 } // bus patch
368 buffer[indexDsp] = index - indexDsp;
369 buffer[indexDsp+1] = index - indexDsp -8;
370 if ((index - indexDsp) % 2 == 0)
371 buffer[indexDsp+7] = 0;
372 else
373 buffer[indexDsp+7] = 1;
374 } // dsp
375 buffer[indexBlk] = index - indexBlk;
376 buffer[indexBlk+1] = index - indexBlk -8;
377 }
378 if (iDDL == 0) {
379 // write DDL 1
380 header.fSize = index + headerSize;// total length in word
381 fwrite((char*)(&header),headerSize*4,1,fFile1);
382 fwrite(buffer,sizeof(int),index,fFile1);
383 }
384 if (iDDL == 1) {
385 // write DDL 2
386 header.fSize = index + headerSize;// total length in word
387 fwrite((char*)(&header),headerSize*4,1,fFile2);
388 fwrite(buffer,sizeof(int),index,fFile2);
389 }
390 delete[] buffer;
391 }
392
393 return kTRUE;
394}
395//____________________________________________________________________
396Int_t AliMUONRawData::WriteTriggerDDL()
397{
398
399// Long_t gloTrigPat;
400// TClonesArray *localTrigger;
401// TClonesArray *globalTrigger;
402// AliMUONLocalTrigger *locTrg;
403// AliMUONGlobalTrigger *gloTrg;
404// AliMUONTriggerCircuit *circuit;
405
406// fTrigData->SetTreeAddress("D,GLT");
407// fTrigDec->Digits2Trigger();
408
409
410// AliMUON * pMUON = (AliMUON *) gAlice->GetDetector("MUON");
411
412// // global trigger for trigger pattern
413// gloTrigPat = 0;
414
415// globalTrigger = fMUONData->GlobalTrigger();
416
417// gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
418// if (gloTrg->SinglePlusLpt()) gloTrigPat|= 0x1;
419// if (gloTrg->SinglePlusHpt()) gloTrigPat|= 0x2;
420// if (gloTrg->SinglePlusApt()) gloTrigPat|= 0x4;
421
422// if (gloTrg->SingleMinusLpt()) gloTrigPat|= 0x8;
423// if (gloTrg->SingleMinusHpt()) gloTrigPat|= 0x10;
424// if (gloTrg->SingleMinusApt()) gloTrigPat|= 0x20;
425
426// if (gloTrg->SingleUndefLpt()) gloTrigPat|= 0x40;
427// if (gloTrg->SingleUndefHpt()) gloTrigPat|= 0x80;
428// if (gloTrg->SingleUndefApt()) gloTrigPat|= 0x100;
429
430// if (gloTrg->PairUnlikeLpt()) gloTrigPat|= 0x200;
431// if (gloTrg->PairUnlikeHpt()) gloTrigPat|= 0x400;
432// if (gloTrg->PairUnlikeApt()) gloTrigPat|= 0x800;
433
434// if (gloTrg->PairLikeLpt()) gloTrigPat|= 0x1000;
435// if (gloTrg->PairLikeHpt()) gloTrigPat|= 0x2000;
436// if (gloTrg->PairLikeApt()) gloTrigPat|= 0x4000;
437
438// // local trigger
439// localTrigger = fMUONData->LocalTrigger();
440// Int_t nlocals = (Int_t) (localTrigger->GetEntries());// 234 local cards
441
442// for (Int_t i=0; i<nlocals; i++) { // loop on Local Trigger
443// locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(i);
444// circuit = &(pMUON->TriggerCircuit(locTrg->LoCircuit()));
445// Float_t y11 = circuit->GetY11Pos(locTrg->LoStripX());
446// Int_t stripX21 = locTrg->LoStripX()+locTrg->LoDev()+1;
447// Float_t y21 = circuit->GetY21Pos(stripX21);
448// Float_t x11 = circuit->GetX11Pos(locTrg->LoStripY());
449// y11 = y21 = x11 = 0.;
450// }
451
452// fTrigData->ResetTrigger();
453// fTrigData->ResetDigits();
454
455 return kTRUE;
456}
457//____________________________________________________________________
458void AliMUONRawData::GetDummyMapping(Int_t iCh, Int_t iCath, const AliMUONDigit* digit,
459 Int_t &busPatchId, UShort_t &manuId, UChar_t &channelId, UShort_t &charge)
460{
461
462 Int_t offsetX = 0; // offet row
463 Int_t offsetY = 0; // offset columns
464 Int_t offsetCath = 0; //offset from one cathod to the other
465 Int_t maxChannel = 0; // maximum nb of channel in 1/2 chamber
466 Int_t id;
f6762c71 467 switch (iCh+1) {
468 case 1:
469 case 2:
470 case 3:
471 case 4:
472 offsetX = 512;
473 offsetY = 256;
474 offsetCath = 65536;
475 maxChannel = (offsetY * offsetX + 2* offsetY + offsetCath);
476 break;
477 case 5:
478 case 6:
479 case 7:
480 case 8:
481 case 9:
482 case 10:
483 offsetX = 1024;
484 offsetY = 0;
485 offsetCath = 65536;
486 maxChannel = (256 * offsetX + offsetX + offsetCath);
487 break;
488 }
489 // dummy mapping
490 // manu Id directly from a matrix 8*8, same segmentation for B and NB
491 // 50 buspatches for 1/2 chamber
f6762c71 492
69be760c 493 id = (TMath::Abs(digit->PadX()) * offsetX + digit->PadY() + offsetY +
494 offsetCath * iCath);
495 Int_t chPerBus = maxChannel/50;
496 busPatchId = id/chPerBus; // start at zero
497 if (digit->PadX() > 0)
498 busPatchId += 50*iCh*2;
499 else
500 busPatchId += 50*(2*iCh+1);
f6762c71 501 // 64 manu cards for one buspatch
69be760c 502 manuId = (id % chPerBus)/64; //start at zero
f6762c71 503 manuId &= 0x7FF; // 11 bits
504
505 // channel id
69be760c 506 channelId = (id % chPerBus) % 64; //start at zero
f6762c71 507 channelId &= 0x3F; // 6 bits
508
69be760c 509// id = (TMath::Abs(digit->PadX()) * offsetX + digit->PadY() + offsetY +
510// offsetCath * iCath);
511// busPatchId = id/50;
512
513// Int_t inBusId = id - (maxChannel/50 * busPatchId);// id channel in buspatch
514// Int_t manuPerBus = (maxChannel/(50*64)); // number of manus per buspatch
515
516// // 64 manu cards for one buspatch
517// manuId = inBusId/manuPerBus;
518// manuId &= 0x7FF; // 11 bits
519
520// // channel id
521// channelId = (inBusId % manuPerBus);
522// channelId &= 0x3F; // 6 bits
523
524 if (fPrintLevel == 2)
525 printf("id: %d, busPatchId %d, manuId: %d, channelId: %d, maxchannel: %d, chPerBus %d\n",
526 id, busPatchId, manuId, channelId, maxChannel, chPerBus);
f6762c71 527 // charge
528 charge = digit->Signal();
529 charge &= 0xFFF;
530
69be760c 531 if (fPrintLevel == 2)
f6762c71 532 printf("id: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d, charge %d\n",
533 id, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal());
f6762c71 534
f6762c71 535}