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