]>
Commit | Line | Data |
---|---|---|
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 | 72 | ClassImp(AliMUONRawWriter) // Class implementation in ROOT context |
ced309a5 | 73 | |
74 | Int_t AliMUONRawWriter::fgManuPerBusSwp1B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 224, 232}; | |
75 | Int_t AliMUONRawWriter::fgManuPerBusSwp1NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 225, 233}; | |
76 | ||
77 | Int_t AliMUONRawWriter::fgManuPerBusSwp2B[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 226, 246}; | |
78 | Int_t AliMUONRawWriter::fgManuPerBusSwp2NB[12] = {1, 27, 53, 79, 105, 131, 157, 183, 201, 214, 227, 245}; | |
79 | ||
80 | ||
a19e2543 | 81 | //__________________________________________________________________________ |
82 | AliMUONRawWriter::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 | //__________________________________________________________________________ | |
110 | AliMUONRawWriter::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 | //_______________________________________________________________________ | |
126 | AliMUONRawWriter::AliMUONRawWriter (const AliMUONRawWriter& rhs) | |
127 | : TObject(rhs) | |
128 | { | |
129 | // Protected copy constructor | |
130 | ||
131 | AliFatal("Not implemented."); | |
132 | } | |
133 | ||
134 | //_______________________________________________________________________ | |
135 | AliMUONRawWriter & | |
136 | AliMUONRawWriter::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 | //__________________________________________________________________________ | |
148 | AliMUONRawWriter::~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 | //____________________________________________________________________ | |
167 | Int_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 | //____________________________________________________________________ | |
223 | Int_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 | //____________________________________________________________________ | |
465 | Int_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 | //____________________________________________________________________ |
564 | Int_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 | //____________________________________________________________________ | |
780 | Int_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 | } |