]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRawData.cxx
8831c835f1aa72eb002d3e5e08c7d23c73a6118f
[u/mrichter/AliRoot.git] / MUON / AliMUONRawData.cxx
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)
23 // * the bus patch id is calculated with an absolute number 0 - 999
24 // one DDL per 1/2 chamber is created for both cathode.
25 //
26 ////////////////////////////////////
27 #include <TClonesArray.h>
28 #include "AliMUONRawData.h"
29 #include "AliMUONDigit.h"
30 #include "AliMUONTriggerDecision.h"
31 #include "AliMUONConstants.h"
32 #include "AliMUONData.h"
33 #include "AliRun.h" 
34 #include "AliRunLoader.h"
35 #include "AliLoader.h"
36 #include "AliBitPacking.h" 
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"
44
45 const Int_t AliMUONRawData::fgkDefaultPrintLevel = 0;
46
47 ClassImp(AliMUONRawData) // Class implementation in ROOT context
48
49 //__________________________________________________________________________
50 AliMUONRawData::AliMUONRawData(AliLoader* loader)
51   : TObject(),
52     fDebug(0)
53 {
54   // Standard Constructor
55  
56   fPrintLevel = fgkDefaultPrintLevel;
57
58   // initialize loader's
59   fLoader = loader;
60
61   // initialize container
62   fMUONData  = new AliMUONData(fLoader,"MUON","MUON");
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();
79 }
80
81 //__________________________________________________________________________
82 AliMUONRawData::AliMUONRawData()
83   : TObject(),
84     fMUONData(0),
85     fPrintLevel(fgkDefaultPrintLevel),
86     fDebug(0),
87     fLoader(0)
88 {
89   // Default Constructor
90 }
91
92 //_______________________________________________________________________
93 AliMUONRawData::AliMUONRawData (const AliMUONRawData& rhs)
94   : TObject(rhs)
95 {
96 // Protected copy constructor
97
98   Fatal("AliMUONRawData", "Not implemented.");
99 }
100
101 //_______________________________________________________________________
102 AliMUONRawData & 
103 AliMUONRawData::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 //__________________________________________________________________________
115 AliMUONRawData::~AliMUONRawData(void)
116 {
117   if (fMUONData)
118     delete fMUONData;
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;
136   return;
137 }
138 //____________________________________________________________________
139 Int_t AliMUONRawData::WriteRawData()
140 {
141  // convert digits of the current event to raw data
142
143   Int_t DDLId;
144   Char_t name[20];
145
146   fLoader->LoadDigits("READ");
147
148   fMUONData->SetTreeAddress("D");
149
150   for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
151   //  for (Int_t ich = 0; ich < 2; ich++) {
152
153     // open files
154     DDLId = ich * 2  + 0x900;
155     sprintf(name, "MUON_%d.ddl",DDLId);
156     fFile1 = fopen(name,"w");
157
158     DDLId = (ich * 2) + 1 + 0x900;
159     sprintf(name, "MUON_%d.ddl",DDLId);
160     fFile2 = fopen(name,"w");
161
162     WriteTrackerDDL(ich);
163   
164     // reset and close
165     fclose(fFile1);
166     fclose(fFile2);
167     fMUONData->ResetDigits();
168   }
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();
183   
184 //   // reset and close
185 //   fclose(fFile1);
186 //   fclose(fFile2);
187    fLoader->UnloadDigits();
188
189   return kTRUE;
190 }
191 //____________________________________________________________________
192 Int_t AliMUONRawData::WriteTrackerDDL(Int_t iCh)
193 {
194   // resets
195   TClonesArray* muonDigits = 0;
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();
211
212   // DDL event one per half chamber
213   AliMUONSubEventTracker* subEvent;
214
215   // data format
216   Char_t parity = 0x4;
217   UShort_t manuId = 0;
218   UChar_t channelId = 0;
219   UShort_t charge = 0;
220   Int_t busPatchId = 0;
221
222   UInt_t word;
223   Int_t nEntries = 0;
224   Int_t* buffer = 0;
225   Int_t index;
226   Int_t indexDsp;
227   Int_t indexBlk;
228
229   Int_t nDigits;
230   const AliMUONDigit* digit;
231
232    if (fPrintLevel > 0)
233       printf("WriteDDL chamber %d\n", iCh+1);
234
235   for (Int_t iCath = 0; iCath < 2; iCath++) {
236
237     fMUONData->ResetDigits();
238     fMUONData->GetCathode(iCath);
239     muonDigits = fMUONData->Digits(iCh);
240
241     nDigits = muonDigits->GetEntriesFast();
242     if (fPrintLevel == 2)
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
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 //____________________________________________________________________
396 Int_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 //____________________________________________________________________
458 void 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;
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
492
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);
501       // 64 manu cards for one buspatch
502       manuId = (id % chPerBus)/64; //start at zero 
503       manuId &= 0x7FF; // 11 bits 
504
505       // channel id
506       channelId = (id % chPerBus) % 64; //start at zero 
507       channelId &= 0x3F; // 6 bits
508
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);
527       // charge
528       charge = digit->Signal();
529       charge &= 0xFFF;
530
531       if (fPrintLevel == 2)
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());
534
535 }