1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ////////////////////////////////////
18 // MUON Raw Data generator and reader in ALICE-MUON
19 // This class version 3 (further details could be found in Alice-note)
21 // Implemented non-constant buspatch numbers for tracking
22 // with correct DDL id (first guess)
23 // (Ch. Finck, dec 2005)
26 // Generates raw data for MUON tracker and finally for trigger
27 // Using real mapping (inverse) for tracker
28 // For trigger there is no mapping (mapping could be found in AliMUONTriggerCircuit)
32 // Using real mapping for tracker
33 // Indranil Das (Adapted for runloader: Ch. Finck) july 05
35 ////////////////////////////////////
40 #include <TClonesArray.h>
42 #include "AliLoader.h"
43 #include "AliBitPacking.h"
44 #include "AliRawReader.h"
49 #include "AliMUONRawData.h"
50 #include "AliMUONDigit.h"
52 #include "AliMUONConstants.h"
53 #include "AliMUONData.h"
55 #include "AliMUONSubEventTrigger.h"
56 #include "AliMUONDDLTracker.h"
57 #include "AliMUONDDLTrigger.h"
59 #include "AliMUONLocalTrigger.h"
60 #include "AliMUONGlobalTrigger.h"
62 #include "AliMUONGeometrySegmentation.h"
63 #include "AliMUONGeometryModule.h"
64 #include "AliMUONGeometryStore.h"
65 #include "AliMUONSegmentationManager.h"
66 #include "AliMpPlaneType.h"
67 #include "AliMpVSegmentation.h"
68 #include "AliMpHelper.h"
72 ClassImp(AliMUONRawData) // Class implementation in ROOT context
73 //__________________________________________________________________________
74 AliMUONRawData::AliMUONRawData(AliLoader* loader)
77 // Standard Constructor
79 // initialize loader's
82 // initialize container
83 fMUONData = new AliMUONData(fLoader,"MUON","MUON");
86 fSubEventArray = new TClonesArray("AliMUONSubEventTracker",1000);
90 fDDLTracker = new AliMUONDDLTracker();
91 fDDLTrigger = new AliMUONDDLTrigger();
97 //__________________________________________________________________________
98 AliMUONRawData::AliMUONRawData()
105 // Default Constructor
106 fFile[0] = fFile[1] = 0x0;
110 //_______________________________________________________________________
111 AliMUONRawData::AliMUONRawData (const AliMUONRawData& rhs)
114 // Protected copy constructor
116 AliFatal("Not implemented.");
119 //_______________________________________________________________________
121 AliMUONRawData::operator=(const AliMUONRawData& rhs)
123 // Protected assignement operator
125 if (this == &rhs) return *this;
127 AliFatal("Not implemented.");
132 //__________________________________________________________________________
133 AliMUONRawData::~AliMUONRawData(void)
138 fSubEventArray->Delete(); //using delete cos allocating memory in copy ctor.
145 fDetElemIdToBusPatch.Delete();
146 fBusPatchToDetElem.Delete();
147 fBusPatchToDDL.Delete();
151 //____________________________________________________________________
152 Int_t AliMUONRawData::Digits2Raw()
154 // convert digits of the current event to raw data
159 fLoader->LoadDigits("READ");
161 fMUONData->SetTreeAddress("D,GLT");
166 for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
169 idDDL = ich * 2 + 0x900; // official number for MUON
170 sprintf(name, "MUON_%d.ddl",idDDL);
171 fFile[0] = fopen(name,"w");
173 idDDL = (ich * 2) + 1 + 0x900;
174 sprintf(name, "MUON_%d.ddl",idDDL);
175 fFile[1] = fopen(name,"w");
177 WriteTrackerDDL(ich);
182 fMUONData->ResetDigits();
188 idDDL = 0xA00;// official number for MUTR
189 sprintf(name, "MUTR_%d.ddl",idDDL);
190 fFile[0] = fopen(name,"w");
193 sprintf(name, "MUTR_%d.ddl",idDDL);
194 fFile[1] = fopen(name,"w");
201 fMUONData->ResetTrigger();
203 fLoader->UnloadDigits();
207 //____________________________________________________________________
208 Int_t AliMUONRawData::WriteTrackerDDL(Int_t iCh)
210 // writing DDL for tracker
211 // used inverse mapping
214 TClonesArray* muonDigits = 0;
215 fSubEventArray->Clear();
225 AliRawDataHeader header = fDDLTracker->GetHeader();
226 Int_t headerSize = fDDLTracker->GetHeaderSize();
228 // DDL event one per half chamber
229 AliMUONSubEventTracker* subEvent;
234 UChar_t channelId = 0;
236 Int_t busPatchId = 0;
250 const AliMUONDigit* digit;
252 AliDebug(3, Form("WriteDDL chamber %d\n", iCh+1));
255 fMUONData->ResetDigits();
256 fMUONData->GetDigits();
257 muonDigits = fMUONData->Digits(iCh);
259 nDigits = muonDigits->GetEntriesFast();
260 AliDebug(3,Form("ndigits = %d\n",nDigits));
263 for (Int_t idig = 0; idig < nDigits; idig++) {
265 digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
267 padX = digit->PadX();
268 padY = digit->PadY();
269 charge = digit->Signal();
271 cathode = digit->Cathode();
272 detElemId = digit->DetElemId();
275 Int_t error = GetInvMapping(digit, busPatchId, manuId, channelId);
278 AliDebug(3,Form("input IdDE %d busPatchId %d PadX %d PadY %d iCath %d \n",
279 detElemId, busPatchId, padX, padY, cathode));
281 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n", busPatchId, manuId, channelId ));
284 AliBitPacking::PackWord((UInt_t)parity,word,29,31);
285 AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
286 AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
287 AliBitPacking::PackWord((UInt_t)charge,word,0,11);
290 subEvent = new AliMUONSubEventTracker();
291 subEvent->AddData(word);
292 subEvent->SetBusPatchId(busPatchId);
294 // storing the number of identical buspatches
295 nbInBus[busPatchId]++;
301 // sorting by buspatch
302 fSubEventArray->Sort();
304 // gather datas from same bus patch
305 nEntries = fSubEventArray->GetEntriesFast();
307 for (Int_t i = 0; i < nEntries; i++) {
308 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray->At(i);
309 busPatchId = temp->GetBusPatchId();
311 // add bus patch header, length and total length managed by subevent class
312 temp->SetTriggerWord(0xdeadbeef);
313 for (Int_t j = 0; j < nbInBus[busPatchId]-1; j++) {
314 AliMUONSubEventTracker* temp1 = (AliMUONSubEventTracker*)fSubEventArray->At(++i);
315 temp->AddData(temp1->GetData(0));
316 fSubEventArray->RemoveAt(i) ;
319 fSubEventArray->Compress();
321 if (AliLog::GetGlobalDebugLevel() == 3) {
322 nEntries = fSubEventArray->GetEntriesFast();
323 for (Int_t i = 0; i < nEntries; i++) {
324 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray->At(i);
325 printf("busPatchid back %d\n",temp->GetBusPatchId());
326 for (Int_t j = 0; j < temp->GetLength(); j++) {
327 printf("manuId back %d, ",temp->GetManuId(j));
328 printf("channelId back %d, ",temp->GetChannelId(j));
329 printf("charge back %d\n",temp->GetCharge(j));
335 // getting info for the number of buspatches
338 Int_t iBusPerDSP[5];//number of bus patches per DSP
339 Int_t iDspMax; //number max of DSP per block
342 GetDspInfo(iCh, iDspMax, iBusPerDSP);
344 TArrayI* vec = GetBusfromDE((iCh+1)*100);
346 Int_t iBus0AtCh = vec->At(0); //get first bus patch id for a given ich
348 AliDebug(3,Form("iBus0AtCh %d", iBus0AtCh));
350 iBusPatch = iBus0AtCh - 1; // starting point for each chamber
352 // nEntries = fSubEventArray->GetEntriesFast();
353 AliMUONSubEventTracker* temp = 0x0;
355 // open DDL file, on per 1/2 chamber
356 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
360 buffer = new Int_t [(2048+24)*50]; // 24 words in average for one buspatch and 2048 manu info at most
366 // two blocks A and B per DDL
367 for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
370 length = fDDLTracker->GetBlkHeaderLength();
371 memcpy(&buffer[index],fDDLTracker->GetBlkHeader(),length*4);
375 // 5 DSP's max per block
376 for (Int_t iDsp = 0; iDsp < iDspMax; iDsp++) {
379 length = fDDLTracker->GetDspHeaderLength();
380 memcpy(&buffer[index],fDDLTracker->GetDspHeader(),length*4);
384 //Â 5 buspatches max per DSP
385 for (Int_t i = 0; i < iBusPerDSP[iDsp]; i++) {
388 if ((fBusPatchToDDL(iBusPatch) % 2) == 1) // comparing to DDL file
393 AliDebug(3,Form("iCh %d iDDL %d iBlock %d iDsp %d busPatchId %d", iCh, iDDL, iBlock, iDsp, iBusPatch));
395 nEntries = fSubEventArray->GetEntriesFast();
397 for (Int_t iEntries = 0; iEntries < nEntries; iEntries++) { // method "bourrique"...
398 temp = (AliMUONSubEventTracker*)fSubEventArray->At(iEntries);
399 busPatchId = temp->GetBusPatchId();
400 if (busPatchId == iBusPatch) break;
402 AliDebug(3,Form("busPatchId %d", temp->GetBusPatchId()));
405 // check if buspatchid has digit
406 if (busPatchId != -1) {
407 // add bus patch structure
408 length = temp->GetHeaderLength();
409 memcpy(&buffer[index],temp->GetAddress(),length*4);
411 for (Int_t j = 0; j < temp->GetLength(); j++) {
412 buffer[index++] = temp->GetData(j);
413 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n", temp->GetBusPatchId(),
414 temp->GetManuId(j), temp->GetChannelId(j) ));
416 // fSubEventArray->RemoveAt(iEntries);
417 // fSubEventArray->Compress();
419 // writting anyhow buspatch structure (empty ones)
420 buffer[index++] = 4; // total length
421 buffer[index++] = 0; // raw data length
422 buffer[index++] = iBusPatch; // bus patch
423 buffer[index++] = 0xdeadbeef; // trigger word
426 buffer[indexDsp] = index - indexDsp; // dsp length
427 buffer[indexDsp+1] = index - indexDsp - fDDLTracker->GetDspHeaderLength();
428 if ((index - indexDsp) % 2 == 0)
429 buffer[indexDsp+7] = 0;
431 buffer[indexDsp+7] = 1;
433 buffer[indexBlk] = index - indexBlk; // block length
434 buffer[indexBlk+1] = index - indexBlk - fDDLTracker->GetBlkHeaderLength();
439 header.fSize = (index + headerSize) * 4;// total length in bytes
440 fwrite((char*)(&header),headerSize*4,1,fFile[iFile]);
441 fwrite(buffer,sizeof(int),index,fFile[iFile]);
448 //____________________________________________________________________
449 Int_t AliMUONRawData::WriteTriggerDDL()
452 // DDL event one per half chamber
453 AliMUONSubEventTrigger* subEvent = 0x0;
456 // stored local id number
457 TArrayI isFired(256);
462 AliRawDataHeader header = fDDLTrigger->GetHeader();
463 Int_t headerSize = fDDLTrigger->GetHeaderSize();
465 TClonesArray* localTrigger;
466 TClonesArray* globalTrigger;
467 AliMUONGlobalTrigger* gloTrg;
468 AliMUONLocalTrigger* locTrg = 0x0;
470 // getting information from trigger
471 fMUONData->GetTriggerD();
473 // global trigger for trigger pattern
474 globalTrigger = fMUONData->GlobalTrigger();
475 gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
476 Int_t gloTrigPat = GetGlobalTriggerPattern(gloTrg);
479 localTrigger = fMUONData->LocalTrigger();
485 Int_t iLocCard, locCard;
486 Char_t locDec, trigY, posY, posX,regOut;
488 Int_t version = 1; // software version
489 Int_t eventType = 1; // trigger type: 1 for physics ?
490 Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
491 Int_t globalFlag = 1; // set to 2 if global info present in DDL else set to 1
493 Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
494 // stored the local card id that's fired
495 for (Int_t i = 0; i < nEntries; i++) {
496 locTrg = (AliMUONLocalTrigger*)localTrigger->At(i);
497 isFired[locTrg->LoCircuit()] = 1; // storing local boards with informations
501 AliError("No Trigger information available");
503 buffer = new Int_t [672]; // [16(local)*5 words + 3 words]*8(reg) + 8 words = 672
505 // open DDL file, on per 1/2 chamber
506 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
510 // DDL enhanced header
512 AliBitPacking::PackWord((UInt_t)iDDL+1,word,28,31); //see AliMUONDDLTrigger.h for details
513 AliBitPacking::PackWord((UInt_t)serialNb,word,24,27);
514 AliBitPacking::PackWord((UInt_t)version,word,16,23);
515 AliBitPacking::PackWord((UInt_t)eventType,word,12,15);
517 if (iDDL == 0) // suppose global info in DDL one
521 AliBitPacking::PackWord((UInt_t)globalFlag,word,8,11);
522 fDDLTrigger->SetDDLWord(word);
525 fDDLTrigger->SetGlobalOutput(gloTrigPat);// no global input for the moment....
527 fDDLTrigger->SetGlobalOutput(0);
528 length = fDDLTrigger->GetHeaderLength();
529 memcpy(&buffer[index],fDDLTrigger->GetEnhancedHeader(),length*4);
532 // 8 regional cards per DDL
533 for (Int_t iReg = 0; iReg < 8; iReg++) {
535 subEvent = new AliMUONSubEventTrigger();
537 // Regional card header
540 AliBitPacking::PackWord((UInt_t)serialNb,word,24,28); //see AliMUONSubEventTrigger.h for details
541 AliBitPacking::PackWord((UInt_t)version,word,16,23);
542 AliBitPacking::PackWord((UInt_t)iReg,word,12,15);
543 AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // whenever regional output will be implemented
545 subEvent->SetRegWord(word);
546 memcpy(&buffer[index++],subEvent->GetAddress(),4);
548 buffer[index++] = 0;// 2 words of regional input
551 // 16 local card per regional board
552 for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
554 iLocCard = iLoc + iReg*16 + iDDL*128;
556 if (isFired[iLocCard]) {
557 locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries);
558 locCard = locTrg->LoCircuit();
559 locDec = locTrg->GetLoDecision();
561 posY = locTrg->LoStripY();
562 posX = locTrg->LoStripX();
563 devX = locTrg->LoDev();
564 AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n",
565 locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
566 } else { //no trigger (see PRR chpt 3.4)
577 AliBitPacking::PackWord((UInt_t)(iLocCard % 16),word,19,22); //card id number in crate
578 AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
579 AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
580 AliBitPacking::PackWord((UInt_t)posY,word,10,13);
581 AliBitPacking::PackWord((UInt_t)devX,word,5,9);
582 AliBitPacking::PackWord((UInt_t)posX,word,0,4);
584 if (locCard == iLocCard) {
585 // add local cards structure
586 buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
587 buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
588 buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
589 buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
590 buffer[index++] = (Int_t)word; // data word
591 if (iEntries < nEntries-1)
594 buffer[index++] = 0; // 4 words for x1, x2, y1, y2
598 buffer[index++] = (Int_t)word; // data word
607 buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word
608 buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word for 64 bits transfer purpose
610 // writting onto disk
612 header.fSize = (index + headerSize) * 4;// total length in bytes
613 fwrite((char*)(&header),headerSize*4,1,fFile[iDDL]);
614 fwrite(buffer,sizeof(int),index,fFile[iDDL]);
622 //____________________________________________________________________
623 Int_t AliMUONRawData::GetInvMapping(const AliMUONDigit* digit,
624 Int_t &busPatchId, UShort_t &manuId, UChar_t &channelId)
627 // Inverse mapping for tracker
629 // information from digits
630 Int_t iCath = digit->Cathode();
631 Int_t idDE = digit->DetElemId();
632 Int_t padX = digit->PadX();
633 Int_t padY = digit->PadY();
635 if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0)
636 padX--; // while in AliMUONSt345Seg. they begin at (1,1)
641 AliMpPlaneType plane;
642 AliMpPlaneType plane1 = kBendingPlane;
643 AliMpPlaneType plane2 = kNonBendingPlane;
645 if (idDE < 500) { // should use GetDirection somehow (ChF)
646 if ( ((idDE % 100) % 2) != 0 ) {
647 plane1 = kNonBendingPlane;
648 plane2 = kBendingPlane;
651 // station 345 bending == cath0 for the moment
652 plane = (iCath == 0) ? plane1 : plane2;
654 AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
655 AliMpPad pad = seg->PadByIndices(AliMpIntPair(padX,padY),kTRUE);
658 AliWarning(Form("No elec. for idDE: %d, padx: %d pady %d, charge: %d\n",
659 idDE, digit->PadX(), digit->PadY(), digit->Signal()));
664 manuId = pad.GetLocation().GetFirst();
665 manuId &= 0x7FF; // 11 bits
667 // Getting channel id
668 channelId = pad.GetLocation().GetSecond();
669 channelId &= 0x3F; // 6 bits
671 // Getting buspatch id
672 TArrayI* vec = GetBusfromDE(idDE);
675 if (idDE < 500) { // station 1 & 2
676 // set 32 manus for one bus patch ? (ChF)
679 // offset of 100 in manuId for following bus patch
683 // if (pos >(int_t) vec.size())
684 // AliWarning("pos greater than size\n");
685 busPatchId = vec->At(pos);
687 if (plane == kNonBendingPlane) // for Non-Bending manuid+= 1000;
688 manuId += 1000; // tmp solution til one finds something better (ChF)
690 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId:%d\n",
691 idDE, busPatchId, manuId, channelId));
693 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady: %d, charge: %d\n",
694 idDE, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal()));
696 return kFALSE; // no error
699 //____________________________________________________________________
700 Int_t AliMUONRawData::GetGlobalTriggerPattern(const AliMUONGlobalTrigger* gloTrg) const
702 // global trigger pattern calculation
704 Int_t gloTrigPat = 0;
706 if (gloTrg->SinglePlusLpt()) gloTrigPat|= 0x1;
707 if (gloTrg->SinglePlusHpt()) gloTrigPat|= 0x2;
708 if (gloTrg->SinglePlusApt()) gloTrigPat|= 0x4;
710 if (gloTrg->SingleMinusLpt()) gloTrigPat|= 0x8;
711 if (gloTrg->SingleMinusHpt()) gloTrigPat|= 0x10;
712 if (gloTrg->SingleMinusApt()) gloTrigPat|= 0x20;
714 if (gloTrg->SingleUndefLpt()) gloTrigPat|= 0x40;
715 if (gloTrg->SingleUndefHpt()) gloTrigPat|= 0x80;
716 if (gloTrg->SingleUndefApt()) gloTrigPat|= 0x100;
718 if (gloTrg->PairUnlikeLpt()) gloTrigPat|= 0x200;
719 if (gloTrg->PairUnlikeHpt()) gloTrigPat|= 0x400;
720 if (gloTrg->PairUnlikeApt()) gloTrigPat|= 0x800;
722 if (gloTrg->PairLikeLpt()) gloTrigPat|= 0x1000;
723 if (gloTrg->PairLikeHpt()) gloTrigPat|= 0x2000;
724 if (gloTrg->PairLikeApt()) gloTrigPat|= 0x4000;
729 //____________________________________________________________________
730 Int_t AliMUONRawData::Raw2Digits(AliRawReader* rawReader)
734 ReadTrackerDDL(rawReader);
737 ReadTriggerDDL(rawReader);
743 //____________________________________________________________________
744 Int_t AliMUONRawData::ReadTrackerDDL(AliRawReader* rawReader)
746 // reading tracker DDL
747 // filling the TClonesArray in MUONData
750 AliMUONSubEventTracker* subEventTracker = new AliMUONSubEventTracker();
751 AliMUONDigit* digit = new AliMUONDigit();
754 //Read Header Size of DDL,Block,DSP and BusPatch.
756 Int_t ddlHeaderSize = fDDLTracker->GetHeaderSize();
757 Int_t blockHeaderSize = fDDLTracker->GetBlkHeaderLength();
758 Int_t dspHeaderSize = fDDLTracker->GetDspHeaderLength();
759 Int_t buspatchHeaderSize = subEventTracker->GetHeaderLength();
761 Int_t totalDDLSize, totalBlockSize, totalDspSize , totalBusPatchSize, dataSize;
764 Int_t iBusPerDSP[5];//number of bus patches per DSP
765 Int_t iDspMax; //number max of DSP per block
767 // minimum data size (only header's)
769 Int_t blankBlockSize;
772 for(Int_t iDDL = 0; iDDL < 20; iDDL++) { // DDL loop
774 AliDebug(3, Form("Chamber %d\n", iDDL/2 +1 ));
777 GetDspInfo(iDDL/2, iDspMax, iBusPerDSP);
779 // Each DDL is made with 2 Blocks each of which consists of 5 DSP's at most and each of DSP has at most 5 buspatches.
780 // This information is used to calculate the size of headers (DDL,Block and DSP) which has no interesting data.
781 blankDDLSize = ddlHeaderSize + 2*blockHeaderSize + 2*iDspMax*dspHeaderSize;
782 blankBlockSize = blockHeaderSize + iDspMax*dspHeaderSize;
784 for (Int_t i = 0; i < iDspMax; i++) {
785 blankDDLSize += 2*iBusPerDSP[i]*buspatchHeaderSize;
786 blankBlockSize += iBusPerDSP[i]*buspatchHeaderSize;
789 rawReader->Select(0X9, iDDL, iDDL); //Select the DDL file to be read
791 rawReader->ReadHeader();
793 totalDDLSize = (rawReader->GetDataSize() + sizeof(AliRawDataHeader))/4; // 4 is multiplied to convert byte 2 words
795 if(totalDDLSize > blankDDLSize) { // Compare the DDL header with an empty DDL header size to read the file
797 Int_t totalDataWord = rawReader->GetDataSize()/4 ;
798 UInt_t *buffer = new UInt_t[totalDataWord];
799 for(Int_t i = 0; i < totalDataWord; i++) {
800 UInt_t& temp = buffer[i];
801 rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
816 for(Int_t iBlock = 0; iBlock < 2 ;iBlock++){ // loop over 2 blocks
817 totalBlockSize = buffer[index];
819 if(totalBlockSize > blankBlockSize) { // compare block header
820 index += blockHeaderSize;
822 for(Int_t iDsp = 0; iDsp < iDspMax ;iDsp++){ //DSP loop
824 totalDspSize = buffer[index];
827 blankDspSize = dspHeaderSize + iBusPerDSP[iDsp]*buspatchHeaderSize; // no data just header
829 if(totalDspSize > blankDspSize) { // Compare DSP Header
830 index += dspHeaderSize;
832 for(Int_t iBusPatch = 0; iBusPatch < iBusPerDSP[iDsp]; iBusPatch++) {
834 totalBusPatchSize = buffer[index];
835 buspatchId = buffer[index+2];
836 indexBusPatch = index;
838 if(totalBusPatchSize > buspatchHeaderSize) { //Check Buspatch header
840 index += buspatchHeaderSize;
841 dataSize = totalBusPatchSize - buspatchHeaderSize;
843 if(dataSize>0) { // check data present
845 for(Int_t iData = 0; iData < dataSize; iData++) {
847 subEventTracker->SetData(buffer[index++],iData); //Set to extract data
849 parity = subEventTracker->GetParity(iData); // test later for parity
850 manuId = subEventTracker->GetManuId(iData);
851 channelId = subEventTracker->GetChannelId(iData);
852 charge = subEventTracker->GetCharge(iData);
854 digit->SetSignal(charge);
856 Int_t error = GetMapping(buspatchId,manuId,channelId,digit); // Get Back the hits at pads
860 if (AliLog::GetGlobalDebugLevel() == 3) {
861 Int_t padX = digit->PadX();
862 Int_t padY = digit->PadY();
863 Int_t iCath = digit->Cathode();
864 Int_t idDE = digit->DetElemId();
866 AliDebug(1,Form("output IdDE %d busPatchid %d PadX %d PadY %d iCath %d \n",
867 idDE, buspatchId, padX, padY, iCath));
869 AliDebug(3,Form("idDE %d Padx %d Pady %d, Cath %d, charge %d",idDE, padX, padY, iCath, charge));
873 fMUONData->AddDigit(iDDL/2, *digit);
877 } // testing buspatch
879 index = indexBusPatch + totalBusPatchSize;
885 index = indexDsp + totalDspSize;
891 index = totalBlockSize;
896 } //loop checking the header size of DDL
902 delete subEventTracker;
908 //____________________________________________________________________
909 Int_t AliMUONRawData::GetMapping(Int_t busPatchId, UShort_t manuId,
910 UChar_t channelId, AliMUONDigit* digit )
913 // mapping for tracker
915 // getting DE from buspatch
916 Int_t idDE = GetDEfromBus(busPatchId);
917 AliDebug(3,Form("idDE: %d busPatchId %d\n", idDE, busPatchId));
924 AliMpPlaneType plane;
926 if (manuId > 1000) { // again tmp solution (ChF) (+1000 for Non-Bending plane
927 plane = kNonBendingPlane;
929 plane = kBendingPlane;
932 if (idDE < 500) { // should use GetDirection somehow (ChF)
933 if ( ((idDE % 100) % 2) != 0 ) {
939 iCath = (manuId > 1000) ? iCath2 : iCath1;
941 if (manuId > 1000) manuId -= 1000; // back to normal manuId
943 AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
944 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,(Int_t)channelId),kTRUE);
947 AliWarning(Form("No pad for idDE: %d, busPatchId %d, manuId: %d, channelId: %d\n",
948 idDE, busPatchId, manuId, channelId));
953 Int_t padX = pad.GetIndices().GetFirst();
956 Int_t padY = pad.GetIndices().GetSecond();
958 if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0)
959 padX++; // while in AliMUONSt345Seg. they begin at (1,1)
962 // storing into digits
963 digit->SetPadX(padX);
964 digit->SetPadY(padY);
965 digit->SetCathode(iCath);
966 digit->SetDetElemId(idDE);
968 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady %d\n",
969 idDE, busPatchId, manuId, channelId, padX, padY));
973 //____________________________________________________________________
974 Int_t AliMUONRawData::ReadTriggerDDL(AliRawReader* rawReader)
977 // reading DDL for trigger
979 AliMUONSubEventTrigger* subEventTrigger = new AliMUONSubEventTrigger();
980 AliMUONGlobalTrigger* globalTrigger = 0x0;
981 AliMUONLocalTrigger* localTrigger = new AliMUONLocalTrigger();
984 //Int_t ddlHeaderSize = fDDLTrigger->GetHeaderSize();
985 // we dont need this, as size of ddl data is same for triger and no trigger
987 Int_t ddlEnhanceHeaderSize = fDDLTrigger->GetHeaderLength();
988 Int_t regHeaderLength = subEventTrigger->GetRegHeaderLength() ;
990 Int_t loCircuit, loStripX, loDev, loStripY, loLpt, loHpt;
993 UShort_t x1Pattern, x2Pattern, x3Pattern, x4Pattern;
994 UShort_t y1Pattern, y2Pattern, y3Pattern, y4Pattern;
997 // loop over the two ddl's
998 for(Int_t iDDL = 0; iDDL < 2; iDDL++) { //DDL loop
1000 rawReader->Select(0XA,iDDL,iDDL); //Select the DDL file to be read
1002 rawReader->ReadHeader();
1004 Int_t totalDataWord = rawReader->GetDataSize()/4 ;
1005 UInt_t *buffer = new UInt_t[totalDataWord];
1006 for(Int_t i=0;i<totalDataWord;i++){
1007 UInt_t& temp = buffer[i];
1008 rawReader->ReadNextInt(temp); // takes the whole result into buffer variable for future analysis
1011 // rawReader->ReadNext((UChar_t*)buffer, totalDataWord); // method is protected ????
1015 // fill DDL header informations
1016 memcpy(fDDLTrigger->GetEnhancedHeader(), &buffer[index], ddlEnhanceHeaderSize*4);
1018 // fill global trigger information
1019 globalTrigger = GetGlobalTriggerPattern(fDDLTrigger->GetGlobalOuput());
1020 fMUONData->AddGlobalTrigger(*globalTrigger);
1022 index += ddlEnhanceHeaderSize;
1024 // 8 regional boards
1025 for (Int_t iReg = 0; iReg < 8; iReg++) { //loop over regeonal card
1028 subEventTrigger->SetRegWord(buffer[index]); //read regional data
1030 index += regHeaderLength;
1032 // 16 local cards per regional board
1033 for (Int_t iLoc = 0; iLoc < 16; iLoc++) { //loop over local card
1035 Int_t iLocIndex = index;
1037 // 5 word trigger information
1038 for(Int_t iData = 0; iData < 5 ;iData++ ){
1039 subEventTrigger->SetLocalData(buffer[index++],5*iLoc+iData); //read local data
1042 if(buffer[iLocIndex] > 0) {
1044 loCircuit = (Int_t)subEventTrigger->GetLocalId(iLoc)+ 16*iReg + 128*iDDL;
1045 loStripX = (Int_t)subEventTrigger->GetXPos(iLoc);
1046 loStripY = (Int_t)subEventTrigger->GetYPos(iLoc);
1047 loDev = (Int_t)subEventTrigger->GetXDev(iLoc);
1049 // fill local trigger
1050 localTrigger->SetLoCircuit(loCircuit);
1051 localTrigger->SetLoStripX(loStripX );
1052 localTrigger->SetLoStripY(loStripY);
1053 localTrigger->SetLoDev(loDev);
1055 loDecision = subEventTrigger->GetLocalDec(iLoc);
1056 loLpt = loDecision & 0x3;
1057 loHpt = (loDecision >> 2) & 0x3;
1059 // fill local trigger
1060 localTrigger->SetLoLpt(loLpt);
1061 localTrigger->SetLoHpt(loHpt);
1063 //getting pattern from subvent
1064 x1Pattern = subEventTrigger->GetX1(iLoc);
1065 x2Pattern = subEventTrigger->GetX2(iLoc);
1066 x3Pattern = subEventTrigger->GetX3(iLoc);
1067 x4Pattern = subEventTrigger->GetX4(iLoc);
1069 y1Pattern = subEventTrigger->GetY1(iLoc);
1070 y2Pattern = subEventTrigger->GetY2(iLoc);
1071 y3Pattern = subEventTrigger->GetY3(iLoc);
1072 y4Pattern = subEventTrigger->GetY4(iLoc);
1074 // fill local trigger
1075 localTrigger->SetX1Pattern(x1Pattern);
1076 localTrigger->SetX2Pattern(x2Pattern);
1077 localTrigger->SetX3Pattern(x3Pattern);
1078 localTrigger->SetX4Pattern(x4Pattern);
1080 localTrigger->SetY1Pattern(y1Pattern);
1081 localTrigger->SetY2Pattern(y2Pattern);
1082 localTrigger->SetY3Pattern(y3Pattern);
1083 localTrigger->SetY4Pattern(y4Pattern);
1084 fMUONData->AddLocalTrigger(*localTrigger);
1088 } // local card loop
1090 } // regional card loop
1095 delete subEventTrigger;
1096 delete globalTrigger;
1097 delete localTrigger;
1102 //____________________________________________________________________
1103 AliMUONGlobalTrigger* AliMUONRawData::GetGlobalTriggerPattern(Int_t gloTrigPat) const
1105 // global trigger pattern calculation
1107 Int_t globalSinglePlus[3]; // tot num of single plus
1108 Int_t globalSingleMinus[3]; // tot num of single minus
1109 Int_t globalSingleUndef[3]; // tot num of single undefined
1110 Int_t globalPairUnlike[3]; // tot num of unlike-sign pairs
1111 Int_t globalPairLike[3]; // tot num of like-sign pairs
1114 for (Int_t i = 0; i < 3; i++) {
1115 globalSinglePlus[i] = gloTrigPat & (0x1 << i);
1116 globalSingleMinus[i] = gloTrigPat & (0x1 << i+3);
1117 globalSingleUndef[i] = gloTrigPat & (0x1 << i+6);
1118 globalPairUnlike[i] = gloTrigPat & (0x1 << i+9);
1119 globalPairLike[i] = gloTrigPat & (0x1 << i+12);
1122 return (new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
1123 globalSingleUndef, globalPairUnlike,
1127 //____________________________________________________________________
1128 Int_t AliMUONRawData::GetDEfromBus(Int_t busPatchId)
1130 // getting DE id from bus patch
1131 Long_t it = fBusPatchToDetElem.GetValue(busPatchId);
1139 //____________________________________________________________________
1140 TArrayI* AliMUONRawData::GetBusfromDE(Int_t idDE)
1142 // getting bus patch from DE id
1144 return (TArrayI*)fDetElemIdToBusPatch.GetValue(idDE);
1146 //____________________________________________________________________
1147 Int_t AliMUONRawData::GetDDLfromBus(Int_t busPatchId)
1149 // getting DE id from bus patch
1150 Long_t it = fBusPatchToDDL.GetValue(busPatchId);
1158 //____________________________________________________________________
1159 void AliMUONRawData::GetDspInfo(Int_t iCh, Int_t& iDspMax, Int_t* iBusPerDSP)
1161 // calculates the number of DSP & buspatch per block
1163 Int_t iBusPerBlk = fMaxBusPerCh[iCh]/4; //per half chamber; per block
1165 iDspMax = iBusPerBlk/5; //number max of DSP per block
1166 if (iBusPerBlk % 5 != 0)
1169 for (Int_t i = 0; i < iDspMax; i++) {
1170 if ((iBusPerBlk -= 5) > 0)
1173 iBusPerDSP[i] = iBusPerBlk + 5;
1177 //____________________________________________________________________
1178 void AliMUONRawData::ReadBusPatchFile()
1181 // idDE <> buspatch map
1184 TString dirPath = gSystem->Getenv("ALICE_ROOT");
1185 dirPath += "/MUON/mapping/data/";
1187 TString infile = dirPath + "DetElemIdToBusPatch.dat";
1189 ifstream in(infile, ios::in);
1190 if (!in) AliError("DetElemIdToBusPatch.dat not found.");
1195 Int_t maxBusPatch = 0;
1197 while ( in.getline(line,80) ) {
1199 if ( line[0] == '#' ) continue;
1201 TString tmp(AliMpHelper::Normalize(line));
1203 Int_t blankPos = tmp.First(' ');
1204 Int_t blankPos1 = tmp.Last(' ');
1206 TString sDE(tmp(0, blankPos));
1208 Int_t idDE = atoi(sDE.Data());
1210 if (idDE/100 != iChprev) {
1211 fMaxBusPerCh[iChprev-1] = maxBusPatch-iChprev*100+1;
1215 TString sDDL(tmp(blankPos1 + 1, tmp.Length()-blankPos1));
1217 Int_t iDDL = atoi(sDDL.Data());
1219 TString busPatch(tmp(blankPos + 1,blankPos1-blankPos-1));
1220 AliDebug(3,Form("idDE %d buspatch %s iDDL %d\n", idDE, busPatch.Data(), iDDL));
1222 TArrayI busPatchList;
1223 // decoding range of buspatch
1224 AliMpHelper::DecodeName(busPatch,';',busPatchList);
1226 // filling buspatch -> idDE
1227 for (Int_t i = 0; i < busPatchList.GetSize(); i++) {
1228 fBusPatchToDetElem.Add((Long_t)busPatchList[i],(Long_t)idDE);
1229 fBusPatchToDDL.Add((Long_t)busPatchList[i],(Long_t)iDDL);
1230 maxBusPatch = busPatchList[i];
1233 // filling idDE -> buspatch list (vector)
1234 fDetElemIdToBusPatch.Add((Long_t)idDE, (Long_t)(new TArrayI(busPatchList)));
1238 fMaxBusPerCh[iChprev-1] = maxBusPatch-iChprev*100+1;