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