]>
Commit | Line | Data |
---|---|---|
2ab3623b | 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 | // $Id$ | |
17 | ||
18 | #include "AliMUONTriggerIO.h" | |
19 | ||
20 | #include "AliLog.h" | |
890cc210 | 21 | #include "AliMpCDB.h" |
2ab3623b | 22 | #include "AliMpDDLStore.h" |
23 | #include "AliMpTriggerCrate.h" | |
890cc210 | 24 | #include "AliMUONTriggerLut.h" |
2ab3623b | 25 | #include "AliMUONCalibParamNI.h" |
26 | #include "AliMUONVStore.h" | |
27 | #include <Riostream.h> | |
28 | #include <TSystem.h> | |
29 | ||
30 | /// \class AliMUONTriggerIO | |
31 | /// | |
32 | /// Handles read/write of masks and LUT to/from online files, | |
33 | /// to be used by Shuttle and Trigger DA. | |
34 | /// | |
35 | /// \author Laurent Aphecetche, Subatech | |
890cc210 | 36 | /// \author Bogdan Vulpescu, LPC Clermont-Ferrand |
2ab3623b | 37 | |
38 | /// \cond CLASSIMP | |
39 | ClassImp(AliMUONTriggerIO) | |
40 | /// \endcond | |
41 | ||
42 | //_____________________________________________________________________________ | |
43 | AliMUONTriggerIO::AliMUONTriggerIO() : | |
44 | TObject(), fLocalBoardIds(), fNofLocalBoards(0) | |
45 | { | |
46 | /// ctor | |
47 | } | |
48 | ||
890cc210 | 49 | //_____________________________________________________________________________ |
50 | AliMUONTriggerIO::AliMUONTriggerIO(const char* regionalFileToRead) : | |
51 | TObject(), fLocalBoardIds(), fNofLocalBoards(0) | |
52 | { | |
53 | /// ctor | |
54 | ReadRegional(regionalFileToRead,0); | |
55 | } | |
56 | ||
2ab3623b | 57 | //_____________________________________________________________________________ |
58 | AliMUONTriggerIO::~AliMUONTriggerIO() | |
59 | { | |
60 | /// dtor | |
61 | } | |
62 | ||
890cc210 | 63 | //_____________________________________________________________________________ |
64 | void | |
65 | AliMUONTriggerIO::DeCompAddress(UChar_t &ypos, UChar_t &ytri, UChar_t &xdev, UChar_t &xpos, | |
66 | UShort_t address) const | |
67 | { | |
68 | /// decompose the 15-bits address | |
69 | ||
70 | UChar_t bitsYpos = 4; | |
71 | UChar_t bitsYtri = 1; | |
72 | UChar_t bitsXdev = 5; | |
73 | // UChar_t bitsXpos = 5; | |
74 | ||
75 | UShort_t maskYpos = 0x000F; // ...0 00001111 | |
76 | UShort_t maskYtri = 0x0001; // ...0 00000001 | |
77 | UShort_t maskXdev = 0x001F; // ...0 00011111 | |
78 | UShort_t maskXpos = 0x001F; // ...0 00011111 | |
79 | ||
80 | ypos = address & maskYpos; | |
81 | ytri = (address >> bitsYpos) & maskYtri; | |
82 | xdev = (address >> (bitsYpos+bitsYtri)) & maskXdev; | |
83 | xpos = (address >> (bitsYpos+bitsYtri+bitsXdev)) & maskXpos; | |
84 | } | |
85 | ||
86 | //_____________________________________________________________________________ | |
87 | void | |
88 | AliMUONTriggerIO::FillLut(AliMUONTriggerLut& lut, | |
89 | Int_t icirc, UChar_t istripX, UChar_t idev, | |
90 | Int_t lutLpt[16][2], Int_t lutHpt[16][2]) | |
91 | { | |
92 | /// Fill the LUT histograms | |
93 | ||
94 | if (icirc == 0 && istripX == 0 && idev == 0) | |
95 | { | |
96 | AliDebug(1,"Copy board, not filled ..."); | |
97 | return; | |
98 | } | |
99 | ||
100 | Short_t iLptPlus, iLptMinu, iLptUnde; | |
101 | Short_t iHptPlus, iHptMinu, iHptUnde; | |
102 | ||
103 | iLptPlus = iLptMinu = iLptUnde = 0; | |
104 | iHptPlus = iHptMinu = iHptUnde = 0; | |
105 | ||
106 | for (Int_t istripY=0; istripY<16; istripY++) | |
107 | { | |
108 | if (lutLpt[istripY][1] == 0 && lutLpt[istripY][0] ==1) | |
109 | iLptMinu=iLptMinu+(1 << istripY); | |
110 | if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==0) | |
111 | iLptPlus=iLptPlus+(1 << istripY); | |
112 | if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==1) | |
113 | iLptUnde=iLptUnde+(1 << istripY); | |
114 | ||
115 | if (lutHpt[istripY][1] == 0 && lutHpt[istripY][0] ==1) | |
116 | iHptMinu=iHptMinu+(1 << istripY); | |
117 | if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==0) | |
118 | iHptPlus=iHptPlus+(1 << istripY); | |
119 | if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==1) | |
120 | iHptUnde=iHptUnde+(1 << istripY); | |
121 | ||
122 | } // loop on istripY | |
123 | ||
124 | lut.SetContent("LptMinu",icirc,istripX,idev,iLptMinu); | |
125 | lut.SetContent("LptUnde",icirc,istripX,idev,iLptUnde); | |
126 | lut.SetContent("LptPlus",icirc,istripX,idev,iLptPlus); | |
127 | ||
128 | lut.SetContent("HptMinu",icirc,istripX,idev,iLptMinu); | |
129 | lut.SetContent("HptUnde",icirc,istripX,idev,iLptUnde); | |
130 | lut.SetContent("HptPlus",icirc,istripX,idev,iLptPlus); | |
131 | } | |
132 | ||
2ab3623b | 133 | //_____________________________________________________________________________ |
134 | Int_t | |
135 | AliMUONTriggerIO::LocalBoardId(Int_t index) const | |
136 | { | |
137 | /// Return the i-th localBoardId, or -1 if index is out of bounds | |
138 | if ( index >= 0 && index < fNofLocalBoards ) | |
139 | { | |
140 | return fLocalBoardIds[index]; | |
141 | } | |
142 | return -1; | |
143 | } | |
144 | ||
145 | //_____________________________________________________________________________ | |
146 | Int_t | |
147 | AliMUONTriggerIO::ReadLocalMasks(const char* localFile, AliMUONVStore& localMasks) const | |
148 | { | |
149 | /// Fills the local masks store from file | |
150 | ||
151 | if ( !NofLocalBoards() ) | |
152 | { | |
153 | AliError("No local board to read"); | |
154 | return 0; | |
155 | } | |
156 | ||
157 | FILE* fp = fopen(gSystem->ExpandPathName(localFile),"r"); | |
158 | if (!fp) | |
159 | { | |
160 | AliError(Form("Could not read file %s",localFile)); | |
161 | return 0; | |
162 | } | |
163 | ||
164 | UShort_t maskBuffer[8]; | |
165 | ||
166 | Int_t nLocalBoards(0); | |
167 | ||
168 | while ( fread ( maskBuffer, 2, 8, fp ) ) | |
169 | { | |
170 | Int_t localBoardId = LocalBoardId(nLocalBoards); | |
171 | AliDebug(1,Form("LB %03d X1 %4x X2 %4x X3 %4x X4 %4x " | |
172 | "Y1 %4x Y2 %4x Y3 %4x Y4 %4x", | |
173 | localBoardId, | |
174 | maskBuffer[0], | |
175 | maskBuffer[1], | |
176 | maskBuffer[2], | |
177 | maskBuffer[3], | |
178 | maskBuffer[4], | |
179 | maskBuffer[5], | |
180 | maskBuffer[6], | |
181 | maskBuffer[7])); | |
182 | ||
183 | if ( localBoardId ) | |
184 | { | |
185 | AliMUONVCalibParam* localBoard = new AliMUONCalibParamNI(1,8,localBoardId,0,0); | |
186 | for ( Int_t x = 0; x < 2; ++x ) | |
187 | { | |
188 | for ( Int_t y = 0; y < 4; ++y ) | |
189 | { | |
190 | Int_t index = x*4+y; | |
191 | localBoard->SetValueAsInt(index,0,maskBuffer[index]); | |
192 | } | |
193 | } | |
194 | localMasks.Add(localBoard); | |
195 | } | |
196 | ||
197 | ++nLocalBoards; | |
198 | } | |
199 | ||
200 | if ( nLocalBoards != NofLocalBoards() ) | |
201 | { | |
202 | AliError(Form("Read %d out of %d local boards", | |
203 | nLocalBoards, NofLocalBoards())); | |
204 | } | |
205 | ||
206 | fclose(fp); | |
207 | ||
208 | return nLocalBoards; | |
209 | } | |
210 | ||
890cc210 | 211 | //_____________________________________________________________________________ |
212 | void | |
213 | AliMUONTriggerIO::ReadLocalLUT(AliMUONTriggerLut& lut, | |
214 | Int_t localBoardId, | |
215 | FILE* flut) | |
216 | { | |
217 | /// Read the LUT for one local board from an online file | |
218 | ||
219 | UShort_t address; | |
220 | ||
221 | UChar_t buffer; | |
222 | UChar_t mask1 = 0xF0; | |
223 | UChar_t mask2 = 0x0F; | |
224 | UChar_t maskLpt = 0x0C; | |
225 | UChar_t maskHpt = 0x03; | |
226 | UChar_t lh, lpt, hpt; | |
227 | ||
228 | UChar_t xpos, xdev, ypos, ytri; | |
229 | ||
230 | Int_t lutLpt[16][2], lutHpt[16][2]; | |
231 | ||
232 | Int_t boardnr = localBoardId; | |
233 | ||
234 | AliDebug(1,Form("Reading LUT values for local board %d",boardnr)); | |
235 | ||
236 | Int_t ny = 0; | |
237 | ||
238 | // create the 32767 addresses for the 4-bits lpt and hpt half-bytes | |
239 | for (UShort_t ilut = 0; ilut < 0x7FFF; ilut += 2) | |
240 | { | |
241 | // read two lut addresses at once | |
242 | fread(&buffer,1,1,flut); | |
243 | ||
244 | // 1st 4-bits half-byte | |
245 | address = ilut; | |
246 | lh = (buffer & mask1) >> 4; | |
247 | ||
248 | // Lpt and Hpt response | |
249 | lpt = (lh & maskLpt) >> 2; | |
250 | hpt = lh & maskHpt; | |
251 | ||
252 | // decompose the 15-bits address | |
253 | DeCompAddress(ypos,ytri,xdev,xpos,address); | |
254 | ||
255 | // calculate group of y-strips | |
256 | if (ny < 16) | |
257 | { | |
258 | lutLpt[ny][0] = lpt & 1; | |
259 | lutLpt[ny][1] = (lpt & 2) >> 1; | |
260 | lutHpt[ny][0] = hpt & 1; | |
261 | lutHpt[ny][1] = (hpt & 2) >> 1; | |
262 | ny++; | |
263 | if (ny == 16) | |
264 | { | |
265 | ny = 0; | |
266 | // ytri == 1 means no trigger in y-direction | |
267 | if (ytri == 0) | |
268 | { | |
269 | FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt); | |
270 | } | |
271 | } | |
272 | } | |
273 | ||
274 | // 2nd 4-bits half-byte | |
275 | address = ilut+1; | |
276 | lh = (buffer & mask2); | |
277 | ||
278 | // Lpt and Hpt response | |
279 | lpt = (lh & maskLpt) >> 2; | |
280 | hpt = lh & maskHpt; | |
281 | ||
282 | // decompose the 15-bits address | |
283 | DeCompAddress(ypos,ytri,xdev,xpos,address); | |
284 | ||
285 | // calculate group of y-strips | |
286 | if (ny < 16) | |
287 | { | |
288 | lutLpt[ny][0] = lpt & 1; | |
289 | lutLpt[ny][1] = (lpt & 2) >> 1; | |
290 | lutHpt[ny][0] = hpt & 1; | |
291 | lutHpt[ny][1] = (hpt & 2) >> 1; | |
292 | ny++; | |
293 | if (ny == 16) | |
294 | { | |
295 | ny = 0; | |
296 | // ytri == 1 means no trigger in y-direction | |
297 | if (ytri == 0) | |
298 | { | |
299 | FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt); | |
300 | } | |
301 | } | |
302 | } | |
303 | } | |
304 | } | |
305 | ||
306 | //_____________________________________________________________________________ | |
307 | Bool_t | |
308 | AliMUONTriggerIO::ReadLUT(const char* lutFileToRead, AliMUONTriggerLut& lut) | |
309 | { | |
310 | /// Fill the LUT object from online file | |
311 | ||
312 | if ( !NofLocalBoards() ) | |
313 | { | |
314 | AliError("No local board id defined. Must read a regional file first"); | |
315 | return kFALSE; | |
316 | } | |
317 | ||
318 | FILE* flut = fopen(gSystem->ExpandPathName(lutFileToRead),"rb"); | |
319 | if (!flut) | |
320 | { | |
ca6cee23 | 321 | AliError(Form("Could not read LUT file %s",lutFileToRead)); |
890cc210 | 322 | return kFALSE; |
323 | } | |
324 | ||
325 | for ( Int_t i = 0; i < NofLocalBoards(); ++i ) | |
326 | { | |
327 | ReadLocalLUT(lut,LocalBoardId(i),flut); | |
328 | } | |
329 | ||
330 | fclose(flut); | |
331 | ||
332 | return kTRUE; | |
333 | ||
334 | } | |
335 | ||
2ab3623b | 336 | //_____________________________________________________________________________ |
337 | Bool_t | |
338 | AliMUONTriggerIO::ReadMasks(const char* localFile, | |
339 | const char* regionalFile, | |
890cc210 | 340 | const char* /* globalFile */, |
2ab3623b | 341 | AliMUONVStore* localMasks, |
342 | AliMUONVStore* regionalMasks, | |
890cc210 | 343 | AliMUONVCalibParam* /* globalMasks */) |
2ab3623b | 344 | { |
345 | /// Fill the various masks store from files | |
346 | ||
347 | if ( !regionalFile ) | |
348 | { | |
349 | AliError("Must have a regional file name to proceeed"); | |
350 | return kFALSE; | |
351 | } | |
352 | ||
353 | Int_t nCrates = ReadRegional(regionalFile,regionalMasks); | |
354 | ||
355 | if (!nCrates) return kFALSE; | |
356 | ||
357 | if (localMasks && localFile) | |
358 | { | |
359 | Int_t nLocal = ReadLocalMasks(localFile,*localMasks); | |
360 | AliDebug(1,Form("Read masks for %d local boards",nLocal)); | |
361 | } | |
362 | ||
363 | return kTRUE; | |
364 | } | |
365 | ||
366 | //_____________________________________________________________________________ | |
367 | Int_t | |
368 | AliMUONTriggerIO::ReadRegional(const char* regionalFile, AliMUONVStore* regionalMasks) | |
369 | { | |
370 | /// Read regional file to fill the regional mask store *AND* | |
371 | /// determine the order in which local boards will appear in local | |
372 | /// and lut files. | |
373 | ||
374 | fLocalBoardIds.Reset(); | |
375 | fNofLocalBoards = 0; | |
376 | ||
377 | std::ifstream in(gSystem->ExpandPathName(regionalFile)); | |
378 | if (!in.good()) | |
379 | { | |
380 | AliError(Form("Cannot read file %s",regionalFile)); | |
381 | return 0; | |
382 | } | |
383 | ||
384 | char name[80]; | |
385 | char line[80]; | |
386 | ||
387 | Int_t nCrates(0); | |
388 | ||
890cc210 | 389 | if (!AliMpDDLStore::Instance(kFALSE)) |
390 | { | |
391 | AliMpCDB::LoadDDLStore(); | |
392 | } | |
393 | ||
2ab3623b | 394 | while (!in.eof()) |
395 | { | |
396 | in.getline(name,80); | |
397 | ||
398 | if (!strlen(name)) break; | |
399 | ||
400 | AliDebug(1,Form("Looking for crate %s",name)); | |
401 | ||
402 | AliMpTriggerCrate* triggerCrate = AliMpDDLStore::Instance()->GetTriggerCrate(name); | |
403 | ||
404 | if (!triggerCrate) | |
405 | { | |
406 | AliError(Form("Mapping error : could not get crate %s",name)); | |
407 | return 0; | |
408 | } | |
409 | ||
410 | ++nCrates; | |
411 | ||
412 | UShort_t id, mask; | |
413 | Int_t mode, coincidence; | |
414 | ||
415 | in.getline(line,80); | |
416 | sscanf(line,"%hx",&id); | |
417 | ||
418 | in.getline(line,80); | |
419 | sscanf(line,"%d",&mode); | |
420 | ||
421 | in.getline(line,80); | |
422 | sscanf(line,"%d",&coincidence); | |
423 | ||
424 | in.getline(line,80); | |
425 | sscanf(line,"%hx",&mask); | |
426 | ||
427 | if ( regionalMasks ) | |
428 | { | |
429 | AliMUONVCalibParam* regionalBoard = new AliMUONCalibParamNI(1,16,id,0,0); | |
430 | regionalBoard->SetValueAsInt(0,0,mask); | |
431 | regionalMasks->Add(regionalBoard); | |
432 | //FIXME: lines below should not be needed, as regionalMask should be only 1 16 bits word, not 16 16 bits word... | |
433 | for ( Int_t j = 1; j < 16; ++j ) | |
434 | { | |
435 | regionalBoard->SetValueAsInt(j,0,0x3F); | |
436 | } | |
437 | } | |
438 | ||
439 | AliDebug(1,Form("Name %s ID %x Mode %d Coin %d Mask %x", | |
440 | name,id,mode,coincidence,mask)); | |
441 | ||
442 | for ( Int_t i = 0; i < 16; ++i ) | |
443 | { | |
444 | if ( (mask >> i ) & 0x1 ) | |
445 | { | |
446 | in.getline(line,80); | |
447 | char localBoardName[20]; | |
448 | int j,localBoardId,switches; | |
449 | sscanf(line,"%02d %s %03d %03x",&j,localBoardName,&localBoardId,&switches); | |
450 | AliDebug(1,Form("%02d %s %03d %03x",j,localBoardName,localBoardId,switches)); | |
451 | fLocalBoardIds.Set(fNofLocalBoards+1); | |
452 | fLocalBoardIds[fNofLocalBoards] = localBoardId; | |
453 | ++fNofLocalBoards; | |
454 | } | |
455 | } | |
456 | } | |
457 | ||
458 | return nCrates; | |
459 | } | |
890cc210 | 460 | |
461 | //_____________________________________________________________________________ | |
462 | Bool_t | |
463 | AliMUONTriggerIO::WriteLUT(const AliMUONTriggerLut& lut, | |
464 | const char* lutFileToWrite) | |
465 | { | |
466 | /// Convert an offline lut into an online (binary) lut file | |
467 | ||
468 | if ( !NofLocalBoards() ) | |
469 | { | |
470 | AliError("No local board id defined. Must read a regional file first"); | |
471 | return kFALSE; | |
472 | } | |
473 | ||
474 | FILE* flut = fopen(gSystem->ExpandPathName(lutFileToWrite),"wb"); | |
475 | if (!flut) | |
476 | { | |
477 | AliError(Form("Could not create output LUT file %s",lutFileToWrite)); | |
478 | return kFALSE; | |
479 | } | |
480 | ||
481 | for ( Int_t i = 0; i < NofLocalBoards(); ++i ) | |
482 | { | |
483 | WriteLocalLUT(lut,LocalBoardId(i),flut); | |
484 | } | |
485 | ||
486 | fclose(flut); | |
487 | ||
488 | return kTRUE; | |
489 | } | |
490 | ||
491 | //_____________________________________________________________________________ | |
492 | void | |
493 | AliMUONTriggerIO::WriteLocalLUT(const AliMUONTriggerLut& lut, | |
494 | Int_t localBoardId, | |
495 | FILE* flut) | |
496 | { | |
497 | /// loop over the address for the 4-bits lpt and hpt decisions | |
498 | ||
499 | const Int_t kMaskYpos = 0x0F; | |
500 | const Int_t kMaskYtri = 0x01; | |
501 | const Int_t kMaskXdev = 0x1F; | |
502 | const Int_t kMaskXpos = 0x1F; | |
503 | ||
504 | for (Int_t i = 0; i < 32768; ++i) | |
505 | { | |
506 | Int_t lutLpt[2] = { 0 }; | |
507 | Int_t lutHpt[2] = { 0 }; | |
508 | ||
509 | // decompose address | |
510 | Int_t iYpos = i & kMaskYpos; | |
511 | Int_t iYtri = ( i >> 4 ) & kMaskYtri; | |
512 | Int_t iXdev = ( i >> ( 4 + 1 ) ) & kMaskXdev; | |
513 | Int_t iXpos = ( i >> ( 4 + 1 + 5 ) ) & kMaskXpos; | |
514 | ||
515 | // iYtri == 1 means no trigger in y-direction | |
516 | if (iYtri == 0) | |
517 | { | |
518 | lut.GetLutOutput(localBoardId,iXpos,iXdev,iYpos,lutLpt,lutHpt); | |
519 | } | |
520 | ||
521 | UChar_t buffer; | |
522 | ||
523 | // fill byte | |
524 | if (i%2 == 0) | |
525 | { | |
526 | // upper half-byte | |
527 | buffer = 0; | |
528 | buffer += lutLpt[1] << 7; | |
529 | buffer += lutLpt[0] << 6; | |
530 | buffer += lutHpt[1] << 5; | |
531 | buffer += lutHpt[0] << 4; | |
532 | } else { | |
533 | // lower half-byte | |
534 | buffer += lutLpt[1] << 3; | |
535 | buffer += lutLpt[0] << 2; | |
536 | buffer += lutHpt[1] << 1; | |
537 | buffer += lutHpt[0] << 0; | |
538 | fwrite(&buffer,1,1,flut); | |
539 | } | |
540 | } | |
541 | } | |
542 |