]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONRawWriter.cxx
- Updated for modifs in AliMpFiles
[u/mrichter/AliRoot.git] / MUON / AliMUONRawWriter.cxx
CommitLineData
a19e2543 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//
ced309a5 18// MUON Raw Data generaton in ALICE-MUON
a19e2543 19// This class version 3 (further details could be found in Alice-note)
20//
21// Implemented non-constant buspatch numbers for tracking
22// with correct DDL id (first guess)
23// (Ch. Finck, dec 2005)
24//
25// Digits2Raw:
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)
29// Ch. Finck july 04
ced309a5 30// Use memcpy instead of assignment elt by elt
31// Introducing variable DSP numbers, real manu numbers per buspatch for st12
32// Implemented scaler event for Trigger
33// Ch. Finck , Jan. 06
a19e2543 34//
35////////////////////////////////////
36
37#include <fstream>
38#include <string>
39
40#include <TClonesArray.h>
41
42#include "AliLoader.h"
43#include "AliBitPacking.h"
44#include "AliRawReader.h"
45#include "AliLog.h"
46#include "AliRun.h"
47
48#include "AliMUON.h"
49#include "AliMUONRawWriter.h"
50#include "AliMUONDigit.h"
51
52#include "AliMUONConstants.h"
53#include "AliMUONData.h"
54
55#include "AliMUONSubEventTrigger.h"
ced309a5 56#include "AliMUONScalerEventTrigger.h"
a19e2543 57#include "AliMUONDDLTracker.h"
58#include "AliMUONDDLTrigger.h"
59
60#include "AliMUONLocalTrigger.h"
61#include "AliMUONGlobalTrigger.h"
62
63#include "AliMUONGeometrySegmentation.h"
64#include "AliMUONGeometryModule.h"
65#include "AliMUONGeometryStore.h"
66#include "AliMpSegFactory.h"
67#include "AliMpPlaneType.h"
68#include "AliMpVSegmentation.h"
69#include "AliMpHelper.h"
70#include "AliMpPad.h"
71
a19e2543 72ClassImp(AliMUONRawWriter) // Class implementation in ROOT context
ced309a5 73
74Int_t AliMUONRawWriter::fgManuPerBusSwp1B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 224, 232};
75Int_t AliMUONRawWriter::fgManuPerBusSwp1NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 225, 233};
76
77Int_t AliMUONRawWriter::fgManuPerBusSwp2B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 226, 246};
78Int_t AliMUONRawWriter::fgManuPerBusSwp2NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 227, 245};
79
80
a19e2543 81//__________________________________________________________________________
82AliMUONRawWriter::AliMUONRawWriter(AliLoader* loader, AliMUONData* data)
ced309a5 83 : TObject(),
84 fScalerEvent(kFALSE)
a19e2543 85{
86 // Standard Constructor
87
88 // initialize loader's
89 fLoader = loader;
90
91 // initialize segmentation factory
92 fSegFactory = new AliMpSegFactory();
93
94 // initialize container
a19e2543 95 fMUONData = data;
96
97 // initialize array
98 fSubEventArray = new TClonesArray("AliMUONSubEventTracker",1000);
99
100
101 // ddl pointer
102 fDDLTracker = new AliMUONDDLTracker();
103 fDDLTrigger = new AliMUONDDLTrigger();
104
105 fBusPatchManager = new AliMpBusPatch();
106 fBusPatchManager->ReadBusPatchFile();
a19e2543 107}
108
109//__________________________________________________________________________
110AliMUONRawWriter::AliMUONRawWriter()
111 : TObject(),
112 fMUONData(0),
113 fLoader(0),
114 fSegFactory(0),
115 fDDLTracker(0),
ced309a5 116 fDDLTrigger(0),
117 fBusPatchManager(0),
118 fScalerEvent(kFALSE)
a19e2543 119{
120 // Default Constructor
121 fFile[0] = fFile[1] = 0x0;
122
123}
124
125//_______________________________________________________________________
126AliMUONRawWriter::AliMUONRawWriter (const AliMUONRawWriter& rhs)
127 : TObject(rhs)
128{
129// Protected copy constructor
130
131 AliFatal("Not implemented.");
132}
133
134//_______________________________________________________________________
135AliMUONRawWriter &
136AliMUONRawWriter::operator=(const AliMUONRawWriter& rhs)
137{
138// Protected assignement operator
139
140 if (this == &rhs) return *this;
141
142 AliFatal("Not implemented.");
143
144 return *this;
145}
146
147//__________________________________________________________________________
148AliMUONRawWriter::~AliMUONRawWriter(void)
149{
150 if (fSegFactory)
151 fSegFactory->DeleteSegmentations();
152 delete fSegFactory;
153
154 if (fSubEventArray)
155 fSubEventArray->Delete(); //using delete cos allocating memory in copy ctor.
156
157 if (fDDLTracker)
158 delete fDDLTracker;
159 if (fDDLTrigger)
160 delete fDDLTrigger;
161
162 fBusPatchManager->Delete();
163
164 return;
165}
166//____________________________________________________________________
167Int_t AliMUONRawWriter::Digits2Raw()
168{
169 // convert digits of the current event to raw data
170
171 Int_t idDDL;
172 Char_t name[20];
173
174 fLoader->LoadDigits("READ");
175
176 fMUONData->SetTreeAddress("D,GLT");
177
178
179 // tracking chambers
180
181 for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
182
183 // open files
184 idDDL = ich * 2 + 0x900; // official number for MUON
185 sprintf(name, "MUON_%d.ddl",idDDL);
186 fFile[0] = fopen(name,"w");
187
188 idDDL = (ich * 2) + 1 + 0x900;
189 sprintf(name, "MUON_%d.ddl",idDDL);
190 fFile[1] = fopen(name,"w");
191
192 WriteTrackerDDL(ich);
193
194 // reset and close
195 fclose(fFile[0]);
196 fclose(fFile[1]);
197 fMUONData->ResetDigits();
198 }
199
200 // trigger chambers
201
202 // open files
203 idDDL = 0xA00;// official number for MUTR
204 sprintf(name, "MUTR_%d.ddl",idDDL);
205 fFile[0] = fopen(name,"w");
206
207 idDDL = 0xA00 + 1;
208 sprintf(name, "MUTR_%d.ddl",idDDL);
209 fFile[1] = fopen(name,"w");
210
211 WriteTriggerDDL();
212
213 // reset and close
214 fclose(fFile[0]);
215 fclose(fFile[1]);
216 fMUONData->ResetTrigger();
217
218 fLoader->UnloadDigits();
219
220 return kTRUE;
221}
222//____________________________________________________________________
223Int_t AliMUONRawWriter::WriteTrackerDDL(Int_t iCh)
224{
225 // writing DDL for tracker
226 // used inverse mapping
227
228 // resets
229 TClonesArray* muonDigits = 0;
230 fSubEventArray->Clear();
231
232 //
233 TArrayI nbInBus;
234
235 nbInBus.Set(5000);
236
237 nbInBus.Reset();
238
239 // DDL header
240 AliRawDataHeader header = fDDLTracker->GetHeader();
241 Int_t headerSize = fDDLTracker->GetHeaderSize();
242
243 // DDL event one per half chamber
244 AliMUONSubEventTracker* subEvent;
245
246 // data format
247 Char_t parity = 0x4;
248 UShort_t manuId = 0;
249 UChar_t channelId = 0;
250 UShort_t charge = 0;
251 Int_t busPatchId = 0;
252
253 UInt_t word;
254 Int_t nEntries = 0;
255 Int_t* buffer = 0;
256 Int_t index;
257 Int_t indexDsp;
258 Int_t indexBlk;
259 Int_t padX;
260 Int_t padY;
261 Int_t cathode = 0;
262 Int_t detElemId;
263 Int_t nDigits;
264
265 const AliMUONDigit* digit;
266
267 AliDebug(3, Form("WriteDDL chamber %d\n", iCh+1));
268
269 // getting digits
270 fMUONData->ResetDigits();
271 fMUONData->GetDigits();
272 muonDigits = fMUONData->Digits(iCh);
273
274 nDigits = muonDigits->GetEntriesFast();
275 AliDebug(3,Form("ndigits = %d\n",nDigits));
276
277 // loop over digit
278 for (Int_t idig = 0; idig < nDigits; idig++) {
279
280 digit = (AliMUONDigit*) muonDigits->UncheckedAt(idig);
281
282 padX = digit->PadX();
283 padY = digit->PadY();
284 charge = digit->Signal();
285 charge &= 0xFFF;
286 cathode = digit->Cathode();
287 detElemId = digit->DetElemId();
288
289 // inverse mapping
290 Int_t error = GetInvMapping(digit, busPatchId, manuId, channelId);
291 if (error) continue;
292
293 AliDebug(3,Form("input IdDE %d busPatchId %d PadX %d PadY %d iCath %d \n",
294 detElemId, busPatchId, padX, padY, cathode));
295
296 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n", busPatchId, manuId, channelId ));
297
298 //packing word
299 AliBitPacking::PackWord((UInt_t)parity,word,29,31);
300 AliBitPacking::PackWord((UInt_t)manuId,word,18,28);
301 AliBitPacking::PackWord((UInt_t)channelId,word,12,17);
302 AliBitPacking::PackWord((UInt_t)charge,word,0,11);
303
304 // set sub Event
305 subEvent = new AliMUONSubEventTracker();
306 subEvent->AddData(word);
307 subEvent->SetBusPatchId(busPatchId);
308
309 // storing the number of identical buspatches
310 nbInBus[busPatchId]++;
311 AddData(subEvent);
312
313 delete subEvent;
314 }
315
316 // sorting by buspatch
317 fSubEventArray->Sort();
318
319 // gather datas from same bus patch
320 nEntries = fSubEventArray->GetEntriesFast();
321
322 for (Int_t i = 0; i < nEntries; i++) {
323 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray->At(i);
324 busPatchId = temp->GetBusPatchId();
325
326 // add bus patch header, length and total length managed by subevent class
327 temp->SetTriggerWord(0xdeadbeef);
328 for (Int_t j = 0; j < nbInBus[busPatchId]-1; j++) {
329 AliMUONSubEventTracker* temp1 = (AliMUONSubEventTracker*)fSubEventArray->At(++i);
330 temp->AddData(temp1->GetData(0));
331 fSubEventArray->RemoveAt(i) ;
332 }
333 }
334 fSubEventArray->Compress();
335
336 if (AliLog::GetGlobalDebugLevel() == 3) {
337 nEntries = fSubEventArray->GetEntriesFast();
338 for (Int_t i = 0; i < nEntries; i++) {
339 AliMUONSubEventTracker* temp = (AliMUONSubEventTracker*)fSubEventArray->At(i);
340 printf("busPatchid back %d\n",temp->GetBusPatchId());
341 for (Int_t j = 0; j < temp->GetLength(); j++) {
342 printf("manuId back %d, ",temp->GetManuId(j));
343 printf("channelId back %d, ",temp->GetChannelId(j));
344 printf("charge back %d\n",temp->GetCharge(j));
345 }
346 }
347 printf("\n");
348 }
349
350 // getting info for the number of buspatches
351 Int_t iBusPatch;
352 Int_t length;
353 Int_t iBusPerDSP[5];//number of bus patches per DSP
354 Int_t iDspMax; //number max of DSP per block
355
356 Int_t iFile = 0;
357 fBusPatchManager->GetDspInfo(iCh, iDspMax, iBusPerDSP);
358
359 TArrayI* vec = fBusPatchManager->GetBusfromDE((iCh+1)*100);
360
361 Int_t iBus0AtCh = vec->At(0); //get first bus patch id for a given ich
362
363 AliDebug(3,Form("iBus0AtCh %d", iBus0AtCh));
364
365 iBusPatch = iBus0AtCh - 1; // starting point for each chamber
366
367 // nEntries = fSubEventArray->GetEntriesFast();
368 AliMUONSubEventTracker* temp = 0x0;
369
370 // open DDL file, on per 1/2 chamber
371 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
372
373
374 // filling buffer
375 buffer = new Int_t [(2048+24)*50]; // 24 words in average for one buspatch and 2048 manu info at most
376
377 indexBlk = 0;
378 indexDsp = 0;
379 index = 0;
380
381 // two blocks A and B per DDL
382 for (Int_t iBlock = 0; iBlock < 2; iBlock++) {
383
384 // block header
385 length = fDDLTracker->GetBlkHeaderLength();
386 memcpy(&buffer[index],fDDLTracker->GetBlkHeader(),length*4);
387 indexBlk = index;
388 index += length;
389
390 // 5 DSP's max per block
391 for (Int_t iDsp = 0; iDsp < iDspMax; iDsp++) {
392
393 // DSP header
394 length = fDDLTracker->GetDspHeaderLength();
395 memcpy(&buffer[index],fDDLTracker->GetDspHeader(),length*4);
396 indexDsp = index;
397 index += length;
398
399 // 5 buspatches max per DSP
400 for (Int_t i = 0; i < iBusPerDSP[iDsp]; i++) {
401
402 iBusPatch ++;
403 if ((fBusPatchManager->GetDDLfromBus(iBusPatch) % 2) == 1) // comparing to DDL file
404 iFile = 0;
405 else
406 iFile = 1;
407
408 AliDebug(3,Form("iCh %d iDDL %d iBlock %d iDsp %d busPatchId %d", iCh, iDDL, iBlock, iDsp, iBusPatch));
409
410 nEntries = fSubEventArray->GetEntriesFast();
411
412 for (Int_t iEntries = 0; iEntries < nEntries; iEntries++) { // method "bourrique"...
413 temp = (AliMUONSubEventTracker*)fSubEventArray->At(iEntries);
414 busPatchId = temp->GetBusPatchId();
415 if (busPatchId == iBusPatch) break;
416 busPatchId = -1;
417 AliDebug(3,Form("busPatchId %d", temp->GetBusPatchId()));
418 }
419
420 // check if buspatchid has digit
421 if (busPatchId != -1) {
422 // add bus patch structure
423 length = temp->GetHeaderLength();
ced309a5 424 memcpy(&buffer[index],temp->GetBusPatchHeader(),length*4);
a19e2543 425 index += length;
426 for (Int_t j = 0; j < temp->GetLength(); j++) {
427 buffer[index++] = temp->GetData(j);
428 AliDebug(3,Form("busPatchId %d, manuId %d channelId %d\n", temp->GetBusPatchId(),
429 temp->GetManuId(j), temp->GetChannelId(j) ));
430 }
431 // fSubEventArray->RemoveAt(iEntries);
432 // fSubEventArray->Compress();
433 } else {
434 // writting anyhow buspatch structure (empty ones)
435 buffer[index++] = 4; // total length
436 buffer[index++] = 0; // raw data length
437 buffer[index++] = iBusPatch; // bus patch
438 buffer[index++] = 0xdeadbeef; // trigger word
439 }
440 } // bus patch
441 buffer[indexDsp] = index - indexDsp; // dsp length
442 buffer[indexDsp+1] = index - indexDsp - fDDLTracker->GetDspHeaderLength();
443 if ((index - indexDsp) % 2 == 0)
444 buffer[indexDsp+7] = 0;
445 else
446 buffer[indexDsp+7] = 1;
447 } // dsp
448 buffer[indexBlk] = index - indexBlk; // block length
449 buffer[indexBlk+1] = index - indexBlk - fDDLTracker->GetBlkHeaderLength();
450 }
451
452 //writting onto disk
453 // write DDL 1 & 2
454 header.fSize = (index + headerSize) * 4;// total length in bytes
455 fwrite((char*)(&header),headerSize*4,1,fFile[iFile]);
456 fwrite(buffer,sizeof(int),index,fFile[iFile]);
457
458 delete[] buffer;
459 }
460
461 return kTRUE;
462}
ced309a5 463
464//____________________________________________________________________
465Int_t AliMUONRawWriter::GetInvMapping(const AliMUONDigit* digit,
466 Int_t &busPatchId, UShort_t &manuId, UChar_t &channelId)
467{
468
469 // Inverse mapping for tracker
470
471 Int_t* ptr = 0;
472
473 // information from digits
474 Int_t iCath = digit->Cathode();
475 Int_t idDE = digit->DetElemId();
476 Int_t padX = digit->PadX();
477 Int_t padY = digit->PadY();
478 Int_t iCh = idDE/100;
479
480 if (idDE >= 500) { // Since in AliMpSlat pads begin at (0,0)
481 padX--; // while in AliMUONSt345Seg. they begin at (1,1)
482 padY--;
483 }
484
485 // segmentation
486 AliMpPlaneType plane;
487 AliMpPlaneType plane1 = kBendingPlane;
488 AliMpPlaneType plane2 = kNonBendingPlane;
489
490 if (idDE < 500) { // should use GetDirection somehow (ChF)
491 if ( ((idDE % 100) % 2) != 0 ) {
492 plane1 = kNonBendingPlane;
493 plane2 = kBendingPlane;
494 }
495 }
496 // station 345 bending == cath0 for the moment
497 plane = (iCath == 0) ? plane1 : plane2;
498
499 if (idDE < 500) {
500 if (iCh == 1 || iCh == 2)
501 if (plane == kBendingPlane)
502 ptr = &fgManuPerBusSwp1B[0];
503 else
504 ptr = &fgManuPerBusSwp1NB[0];
505 else
506 if (plane == kBendingPlane)
507 ptr = &fgManuPerBusSwp2B[0];
508 else
509 ptr = &fgManuPerBusSwp2NB[0];
510 }
511
512 //AliMpVSegmentation* seg = AliMUONSegmentationManager::Segmentation(idDE, plane);
513 AliMpVSegmentation* seg = fSegFactory->CreateMpSegmentation(idDE, iCath);
514 AliMpPad pad = seg->PadByIndices(AliMpIntPair(padX,padY),kTRUE);
515
516 if (!pad.IsValid()) {
517 AliWarning(Form("No elec. for idDE: %d, padx: %d pady %d, charge: %d\n",
518 idDE, digit->PadX(), digit->PadY(), digit->Signal()));
519 return kTRUE;
520 }
521
522 // Getting Manu id
523 manuId = pad.GetLocation().GetFirst();
524 manuId &= 0x7FF; // 11 bits
525
526 // Getting channel id
527 channelId = pad.GetLocation().GetSecond();
528 channelId &= 0x3F; // 6 bits
529
530 // Getting buspatch id
531 TArrayI* vec = fBusPatchManager->GetBusfromDE(idDE);
532 Int_t pos = 0;
533
534 if (idDE < 500) { // station 1 & 2
535 for (Int_t i = 0; i < 12; i++)
536 if (manuId >= *(ptr + pos++))
537 break;
538 // while(*(ptr + pos) <= manuId)
539// pos++;
540// pos--;
541 } else {
542 // offset of 100 in manuId for following bus patch
543 pos = manuId/100;
544 }
545
546 if (pos >(Int_t) vec->GetSize())
547 AliWarning(Form("pos greater %d than size %d manuId %d idDE %d \n",
548 pos, (Int_t)vec->GetSize(), manuId, idDE));
549 busPatchId = vec->At(pos);
550
551 if (plane == kNonBendingPlane) // for Non-Bending manuid+= 1000;
552 manuId += 1000; // tmp solution til one finds something better (ChF)
553
554 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId:%d\n",
555 idDE, busPatchId, manuId, channelId));
556
557 AliDebug(3,Form("idDE: %d, busPatchId %d, manuId: %d, channelId: %d, padx: %d pady: %d, charge: %d\n",
558 idDE, busPatchId, manuId, channelId, digit->PadX(), digit->PadY(), digit->Signal()));
559
560 return kFALSE; // no error
561}
562
a19e2543 563//____________________________________________________________________
564Int_t AliMUONRawWriter::WriteTriggerDDL()
565{
566
567 // DDL event one per half chamber
ced309a5 568 AliMUONSubEventTrigger* subEvent = 0x0;
569 AliMUONScalerEventTrigger* scalerEvent = 0x0;
a19e2543 570
571
572 // stored local id number
573 TArrayI isFired(256);
574 isFired.Reset();
575
576
577 // DDL header
578 AliRawDataHeader header = fDDLTrigger->GetHeader();
579 Int_t headerSize = fDDLTrigger->GetHeaderSize();
ced309a5 580
a19e2543 581 TClonesArray* localTrigger;
582 TClonesArray* globalTrigger;
583 AliMUONGlobalTrigger* gloTrg;
584 AliMUONLocalTrigger* locTrg = 0x0;
585
586 // getting information from trigger
587 fMUONData->GetTriggerD();
588
589 // global trigger for trigger pattern
590 globalTrigger = fMUONData->GlobalTrigger();
591 gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(0);
592 Int_t gloTrigPat = GetGlobalTriggerPattern(gloTrg);
593
594 // local trigger
595 localTrigger = fMUONData->LocalTrigger();
596
597 UInt_t word;
598 Int_t* buffer = 0;
599 Int_t index;
600 Int_t iEntries = 0;
601 Int_t iLocCard, locCard;
602 Char_t locDec, trigY, posY, posX,regOut;
603 Int_t devX;
604 Int_t version = 1; // software version
605 Int_t eventType = 1; // trigger type: 1 for physics ?
606 Int_t serialNb = 0xF; // serial nb of card: all bits on for the moment
607 Int_t globalFlag = 1; // set to 2 if global info present in DDL else set to 1
608
ced309a5 609 if(fScalerEvent)
610 eventType = 2; //set to generate scaler events
611
a19e2543 612 Int_t nEntries = (Int_t) (localTrigger->GetEntries());// 234 local cards
613 // stored the local card id that's fired
614 for (Int_t i = 0; i < nEntries; i++) {
615 locTrg = (AliMUONLocalTrigger*)localTrigger->At(i);
616 isFired[locTrg->LoCircuit()] = 1; // storing local boards with informations
617 }
618
619 if (!nEntries)
620 AliError("No Trigger information available");
621
ced309a5 622 if(fScalerEvent)
623 // [16(local)*50 words + 14 words]*8(reg) + 6 + 10 + 6 words scaler event 6534 words
624 buffer = new Int_t [6534];
625 else
626 // [16(local)*5 words + 3 words]*8(reg) + 8 words = 672
627 buffer = new Int_t [672];
628
629 if(fScalerEvent) {
630 scalerEvent = new AliMUONScalerEventTrigger();
631 scalerEvent->SetNumbers(); // set some numbers for scalers
632 }
a19e2543 633
634 // open DDL file, on per 1/2 chamber
635 for (Int_t iDDL = 0; iDDL < 2; iDDL++) {
636
637 index = 0;
638
639 // DDL enhanced header
640 word = 0;
641 AliBitPacking::PackWord((UInt_t)iDDL+1,word,28,31); //see AliMUONDDLTrigger.h for details
642 AliBitPacking::PackWord((UInt_t)serialNb,word,24,27);
643 AliBitPacking::PackWord((UInt_t)version,word,16,23);
644 AliBitPacking::PackWord((UInt_t)eventType,word,12,15);
645
646 if (iDDL == 0) // suppose global info in DDL one
647 globalFlag = 2;
648 else
649 globalFlag = 1;
ced309a5 650
a19e2543 651 AliBitPacking::PackWord((UInt_t)globalFlag,word,8,11);
652 fDDLTrigger->SetDDLWord(word);
ced309a5 653 buffer[index++]= word;
a19e2543 654
655 if (iDDL == 0)
656 fDDLTrigger->SetGlobalOutput(gloTrigPat);// no global input for the moment....
657 else
658 fDDLTrigger->SetGlobalOutput(0);
ced309a5 659
660 if (fScalerEvent) {
661 // 6 DARC scaler words
662 memcpy(&buffer[index], scalerEvent->GetDarcScalers(),scalerEvent->GetDarcScalerLength()*4);
663 index += scalerEvent->GetDarcScalerLength();
664 }
665
666 // 4 words of global board input + Global board output
667 memcpy(&buffer[index], fDDLTrigger->GetGlobalInput(), (fDDLTrigger->GetHeaderLength()-1)*4);
668 index += fDDLTrigger->GetHeaderLength() - 1; // kind tricky cos scaler info in-between Darc header
669
670 if (fScalerEvent) {
671 // 10 Global scaler words
672 memcpy(scalerEvent->GetGlobalScalers(), &buffer[index], scalerEvent->GetGlobalScalerLength()*4);
673 index += scalerEvent->GetGlobalScalerLength();
674 }
a19e2543 675
676 // 8 regional cards per DDL
677 for (Int_t iReg = 0; iReg < 8; iReg++) {
678
679 subEvent = new AliMUONSubEventTrigger();
680
681 // Regional card header
682 word = 0;
683 regOut = 0;
684 AliBitPacking::PackWord((UInt_t)serialNb,word,24,28); //see AliMUONSubEventTrigger.h for details
685 AliBitPacking::PackWord((UInt_t)version,word,16,23);
686 AliBitPacking::PackWord((UInt_t)iReg,word,12,15);
687 AliBitPacking::PackWord((UInt_t)regOut,word,0,7); // whenever regional output will be implemented
688
689 subEvent->SetRegWord(word);
ced309a5 690 memcpy(&buffer[index],subEvent->GetRegHeader(),subEvent->GetRegHeaderLength()*4);
691 index += subEvent->GetRegHeaderLength();
a19e2543 692
ced309a5 693 // 11 regional scaler word
694 if (fScalerEvent) {
695 memcpy(&buffer[index], scalerEvent->GetRegScalers(), scalerEvent->GetRegScalerLength()*4);
696 index += scalerEvent->GetRegScalerLength();
697 }
a19e2543 698
699 // 16 local card per regional board
700 for (Int_t iLoc = 0; iLoc < 16; iLoc++) {
701
702 iLocCard = iLoc + iReg*16 + iDDL*128;
703
704 if (isFired[iLocCard]) {
705 locTrg = (AliMUONLocalTrigger*)localTrigger->At(iEntries);
706 locCard = locTrg->LoCircuit();
707 locDec = locTrg->GetLoDecision();
708 trigY = 0;
709 posY = locTrg->LoStripY();
710 posX = locTrg->LoStripX();
711 devX = locTrg->LoDev();
712 AliDebug(4,Form("loctrg %d, posX %d, posY %d, devX %d\n",
713 locTrg->LoCircuit(),locTrg->LoStripX(),locTrg->LoStripY(),locTrg->LoDev()));
714 } else { //no trigger (see PRR chpt 3.4)
715 locCard = -1;
716 locDec = 0;
717 trigY = 1;
718 posY = 15;
719 posX = 0;
720 devX = 0x8;
721 }
722
723 //packing word
724 word = 0;
725 AliBitPacking::PackWord((UInt_t)(iLocCard % 16),word,19,22); //card id number in crate
726 AliBitPacking::PackWord((UInt_t)locDec,word,15,18);
727 AliBitPacking::PackWord((UInt_t)trigY,word,14,14);
728 AliBitPacking::PackWord((UInt_t)posY,word,10,13);
729 AliBitPacking::PackWord((UInt_t)devX,word,5,9);
730 AliBitPacking::PackWord((UInt_t)posX,word,0,4);
731
732 if (locCard == iLocCard) {
733 // add local cards structure
734 buffer[index++] = (locTrg->GetX1Pattern() | (locTrg->GetX2Pattern() << 16));
735 buffer[index++] = (locTrg->GetX3Pattern() | (locTrg->GetX4Pattern() << 16));
736 buffer[index++] = (locTrg->GetY1Pattern() | (locTrg->GetY2Pattern() << 16));
737 buffer[index++] = (locTrg->GetY3Pattern() | (locTrg->GetY4Pattern() << 16));
738 buffer[index++] = (Int_t)word; // data word
739 if (iEntries < nEntries-1)
740 iEntries++;
741 } else {
742 buffer[index++] = 0; // 4 words for x1, x2, y1, y2
743 buffer[index++] = 0;
744 buffer[index++] = 0;
745 buffer[index++] = 0;
746 buffer[index++] = (Int_t)word; // data word
747
748 }
ced309a5 749 // 45 regional scaler word
750 if (fScalerEvent) {
751 memcpy(&buffer[index], scalerEvent->GetLocalScalers(), scalerEvent->GetLocalScalerLength()*4);
752 index += scalerEvent->GetLocalScalerLength();
753 }
754
a19e2543 755 } // local card
756
757 delete subEvent;
758
759 } // Regional card
760
761 buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word
762 buffer[index++] = fDDLTrigger->GetEoD(); // End of DDL word for 64 bits transfer purpose
763
764 // writting onto disk
765 // write DDL 1
766 header.fSize = (index + headerSize) * 4;// total length in bytes
767 fwrite((char*)(&header),headerSize*4,1,fFile[iDDL]);
768 fwrite(buffer,sizeof(int),index,fFile[iDDL]);
769
770 }
771 delete[] buffer;
772
ced309a5 773 if (fScalerEvent)
774 delete scalerEvent;
a19e2543 775
ced309a5 776 return kTRUE;
a19e2543 777}
778
779//____________________________________________________________________
780Int_t AliMUONRawWriter::GetGlobalTriggerPattern(const AliMUONGlobalTrigger* gloTrg) const
781{
782 // global trigger pattern calculation
783
784 Int_t gloTrigPat = 0;
785
786 if (gloTrg->SinglePlusLpt()) gloTrigPat|= 0x1;
787 if (gloTrg->SinglePlusHpt()) gloTrigPat|= 0x2;
788 if (gloTrg->SinglePlusApt()) gloTrigPat|= 0x4;
789
790 if (gloTrg->SingleMinusLpt()) gloTrigPat|= 0x8;
791 if (gloTrg->SingleMinusHpt()) gloTrigPat|= 0x10;
792 if (gloTrg->SingleMinusApt()) gloTrigPat|= 0x20;
793
794 if (gloTrg->SingleUndefLpt()) gloTrigPat|= 0x40;
795 if (gloTrg->SingleUndefHpt()) gloTrigPat|= 0x80;
796 if (gloTrg->SingleUndefApt()) gloTrigPat|= 0x100;
797
798 if (gloTrg->PairUnlikeLpt()) gloTrigPat|= 0x200;
799 if (gloTrg->PairUnlikeHpt()) gloTrigPat|= 0x400;
800 if (gloTrg->PairUnlikeApt()) gloTrigPat|= 0x800;
801
802 if (gloTrg->PairLikeLpt()) gloTrigPat|= 0x1000;
803 if (gloTrg->PairLikeHpt()) gloTrigPat|= 0x2000;
804 if (gloTrg->PairLikeApt()) gloTrigPat|= 0x4000;
805
806 return gloTrigPat;
807}