Line data Source code
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 : #include "AliMUONTriggerLut.h"
20 : #include "AliMUONCalibParamNI.h"
21 : #include "AliMUONVStore.h"
22 :
23 : #include "AliMpCDB.h"
24 : #include "AliMpHelper.h"
25 : #include "AliMpConstants.h"
26 : #include "AliMpDDL.h"
27 : #include "AliMpFiles.h"
28 : #include "AliMpDDLStore.h"
29 : #include "AliMpLocalBoard.h"
30 : #include "AliMpTriggerCrate.h"
31 : #include "AliMUONGlobalCrateConfig.h"
32 : #include "AliMUONRegionalTriggerConfig.h"
33 : #include "AliMUONTriggerCrateConfig.h"
34 : #include "AliMUONTriggerScalers.h"
35 :
36 : #include "AliLog.h"
37 :
38 : #include <Riostream.h>
39 : #include <TSystem.h>
40 : #include <TClonesArray.h>
41 :
42 : /// \class AliMUONTriggerIO
43 : ///
44 : /// Handles read/write of masks and LUT to/from online files,
45 : /// to be used by Shuttle and Trigger DA.
46 : ///
47 : /// \author Laurent Aphecetche, Christian Finck Subatech
48 : /// \author Bogdan Vulpescu, LPC Clermont-Ferrand
49 :
50 : using std::endl;
51 : using std::cout;
52 : using std::ofstream;
53 : /// \cond CLASSIMP
54 18 : ClassImp(AliMUONTriggerIO)
55 : /// \endcond
56 :
57 :
58 : const UInt_t AliMUONTriggerIO::fgkLocalLutSize = 1 << 14; // 16384
59 :
60 : //_____________________________________________________________________________
61 : AliMUONTriggerIO::AliMUONTriggerIO()
62 0 : : TObject(),
63 0 : fRegionalTrigger()
64 0 : {
65 : /// ctor
66 0 : }
67 :
68 : //_____________________________________________________________________________
69 : AliMUONTriggerIO::AliMUONTriggerIO(const char* regionalFileToRead)
70 0 : :TObject(),
71 0 : fRegionalTrigger()
72 0 : {
73 : /// ctor
74 0 : ReadRegionalConfig(regionalFileToRead,0);
75 0 : }
76 :
77 : //_____________________________________________________________________________
78 : AliMUONTriggerIO::~AliMUONTriggerIO()
79 0 : {
80 : /// dtor
81 0 : }
82 :
83 : //_____________________________________________________________________________
84 : Bool_t
85 : AliMUONTriggerIO::DeCompAddress(UChar_t &ypos, UChar_t &ytri, UChar_t &xdev, UChar_t &xpos,
86 : UShort_t address) const
87 : {
88 : /// decompose the 15-bits address
89 :
90 : UChar_t bitsYpos = 4;
91 : UChar_t bitsYtri = 1;
92 : UChar_t bitsXdev = 5;
93 : // UChar_t bitsXpos = 5;
94 :
95 : UShort_t maskYpos = 0x000F; // ...0 00001111
96 : UShort_t maskYtri = 0x0001; // ...0 00000001
97 : UShort_t maskXdev = 0x001F; // ...0 00011111
98 : UShort_t maskXpos = 0x001F; // ...0 00011111
99 :
100 0 : ypos = address & maskYpos;
101 0 : ytri = (address >> bitsYpos) & maskYtri;
102 0 : xdev = (address >> (bitsYpos+bitsYtri)) & maskXdev;
103 0 : xpos = (address >> (bitsYpos+bitsYtri+bitsXdev)) & maskXpos;
104 :
105 : // convert deviation format
106 : // online: sign 1bit , dev 4bit
107 : // sign dev trigger
108 : // 0 1-15 mu-
109 : // 1 1-15 mu+
110 : // 0 0 mu+, mu- infinite momentum (unde)
111 : // 1 0 no x-trigger
112 : // offline: dev 5bit
113 : // sign dev trigger
114 : // - 0-14 mu-
115 : // - 16-31 mu+
116 : // - 15 mu+, mu- infinite momentum (unde)
117 :
118 : Int_t iXdevOff, iXdevOn, iXdev, sign;
119 : Bool_t trigx;
120 :
121 0 : iXdev = xdev;
122 :
123 : iXdevOn = sign = 0;
124 0 : iXdevOn += iXdev & 0x0F;
125 0 : sign += (iXdev >> 4) & 0x01;
126 0 : if (iXdevOn == 0) {
127 0 : if (sign == 0) {
128 : iXdevOff = 15;
129 : trigx = kTRUE;
130 0 : } else {
131 : iXdevOff = 15;
132 : trigx = kFALSE;
133 : }
134 : } else {
135 : trigx = kTRUE;
136 0 : if (sign == 0) {
137 0 : iXdevOff = - iXdevOn + 15; // gives range 0-14
138 0 : } else {
139 0 : iXdevOff = + iXdevOn + 15; // gives range 16-30 !
140 : }
141 : }
142 :
143 0 : xdev = iXdevOff;
144 :
145 0 : return trigx;
146 :
147 : }
148 :
149 : //_____________________________________________________________________________
150 : void
151 : AliMUONTriggerIO::FillLut(AliMUONTriggerLut& lut,
152 : Int_t icirc, UChar_t istripX, UChar_t idev,
153 : Int_t lutLpt[16][2], Int_t lutHpt[16][2])
154 : {
155 : /// Fill the LUT histograms
156 :
157 0 : if (icirc == 0 && istripX == 0 && idev == 0)
158 : {
159 0 : AliDebug(1,"Copy board, not filled ...");
160 : return;
161 : }
162 :
163 : Short_t iLptPlus, iLptMinu, iLptUnde;
164 : Short_t iHptPlus, iHptMinu, iHptUnde;
165 :
166 : iLptPlus = iLptMinu = iLptUnde = 0;
167 : iHptPlus = iHptMinu = iHptUnde = 0;
168 :
169 0 : for (Int_t istripY=0; istripY<16; istripY++)
170 : {
171 0 : if (lutLpt[istripY][1] == 0 && lutLpt[istripY][0] ==1)
172 0 : iLptMinu=iLptMinu+(1 << istripY);
173 0 : if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==0)
174 0 : iLptPlus=iLptPlus+(1 << istripY);
175 0 : if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==1)
176 0 : iLptUnde=iLptUnde+(1 << istripY);
177 :
178 0 : if (lutHpt[istripY][1] == 0 && lutHpt[istripY][0] ==1)
179 0 : iHptMinu=iHptMinu+(1 << istripY);
180 0 : if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==0)
181 0 : iHptPlus=iHptPlus+(1 << istripY);
182 0 : if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==1)
183 0 : iHptUnde=iHptUnde+(1 << istripY);
184 :
185 : } // loop on istripY
186 :
187 0 : lut.SetContent("LptMinu",icirc,istripX,idev,iLptMinu);
188 0 : lut.SetContent("LptUnde",icirc,istripX,idev,iLptUnde);
189 0 : lut.SetContent("LptPlus",icirc,istripX,idev,iLptPlus);
190 :
191 0 : lut.SetContent("HptMinu",icirc,istripX,idev,iHptMinu);
192 0 : lut.SetContent("HptUnde",icirc,istripX,idev,iHptUnde);
193 0 : lut.SetContent("HptPlus",icirc,istripX,idev,iHptPlus);
194 0 : }
195 :
196 : //_____________________________________________________________________________
197 : Int_t
198 : AliMUONTriggerIO::ReadLocalMasks(const char* localFile, AliMUONVStore& localMasks) const
199 : {
200 : /// Fills the local masks store from file
201 :
202 0 : if ( !NofLocalBoards() )
203 : {
204 0 : AliError("No local board to read");
205 0 : return 0;
206 : }
207 :
208 0 : FILE* fp = fopen(gSystem->ExpandPathName(localFile),"r");
209 0 : if (!fp)
210 : {
211 0 : AliError(Form("Could not read file %s",localFile));
212 0 : return 0;
213 : }
214 :
215 0 : UShort_t maskBuffer[8];
216 :
217 : Int_t localBoardIndex(0);
218 :
219 0 : while ( fread ( maskBuffer, 2, 8, fp ) == 8 )
220 : {
221 0 : Int_t localBoardId = fRegionalTrigger.LocalBoardId(localBoardIndex);
222 0 : AliDebug(1,Form("LB %03d X1 %4x X2 %4x X3 %4x X4 %4x "
223 : "Y1 %4x Y2 %4x Y3 %4x Y4 %4x",
224 : localBoardId,
225 : maskBuffer[0],
226 : maskBuffer[1],
227 : maskBuffer[2],
228 : maskBuffer[3],
229 : maskBuffer[4],
230 : maskBuffer[5],
231 : maskBuffer[6],
232 : maskBuffer[7]));
233 :
234 0 : if ( localBoardId > 0 )
235 : {
236 0 : AliMUONVCalibParam* localBoard = new AliMUONCalibParamNI(1,8,localBoardId,0,0);
237 0 : for ( Int_t index = 0; index < 8; ++index )
238 : {
239 0 : localBoard->SetValueAsInt(index,0,maskBuffer[index]);
240 : }
241 0 : localMasks.Add(localBoard);
242 0 : }
243 : else
244 : {
245 0 : AliError(Form("Oups. Got localBoardId=%d for index=%d",localBoardId,localBoardIndex));
246 : }
247 :
248 0 : ++localBoardIndex;
249 : }
250 :
251 0 : if ( localBoardIndex != NofLocalBoards() )
252 : {
253 0 : AliError(Form("Read %d out of %d local boards",
254 : localBoardIndex, NofLocalBoards()));
255 0 : }
256 :
257 0 : fclose(fp);
258 :
259 0 : return localBoardIndex+1;
260 0 : }
261 :
262 : //_____________________________________________________________________________
263 : void
264 : AliMUONTriggerIO::ReadLocalLUT(AliMUONTriggerLut& lut,
265 : Int_t localBoardId,
266 : FILE* flut)
267 : {
268 : /// Read the LUT for one local board from an online file
269 :
270 : UShort_t address;
271 :
272 0 : UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
273 : UChar_t mask1 = 0xF0;
274 : UChar_t mask2 = 0x0F;
275 : UChar_t maskHpt = 0x0C;
276 : UChar_t maskLpt = 0x03;
277 : UChar_t lh, lpt, hpt;
278 :
279 0 : UChar_t xpos, xdev, ypos, ytri;
280 :
281 0 : Int_t lutLpt[16][2], lutHpt[16][2];
282 :
283 : Int_t boardnr = localBoardId;
284 :
285 0 : AliDebug(1,Form("Reading LUT values for local board %d",boardnr));
286 :
287 : Int_t ny = 0;
288 : Bool_t trigx = kFALSE;
289 :
290 : // read two lut addresses at once, 32768/2=16384 times
291 0 : if ( fread ( buffer, fgkLocalLutSize, 1, flut ) == 0 ) {
292 0 : AliWarning("Error reading the LUT file");
293 0 : return;
294 : }
295 :
296 : // create the 32767 addresses for the 4-bits lpt and hpt half-bytes
297 0 : for (UShort_t ilut = 0; ilut < fgkLocalLutSize*2; ilut += 2)
298 : {
299 :
300 : // 1st 4-bits half-byte
301 : address = ilut;
302 0 : lh = (buffer[ilut/2] & mask1) >> 4;
303 :
304 : // Lpt and Hpt response
305 0 : hpt = (lh & maskHpt) >> 2;
306 0 : lpt = lh & maskLpt;
307 :
308 : // decompose the 15-bits address
309 0 : trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
310 :
311 : // calculate group of y-strips
312 0 : if (trigx && (ny < 16))
313 : {
314 0 : lutLpt[ny][0] = lpt & 1;
315 0 : lutLpt[ny][1] = (lpt & 2) >> 1;
316 0 : lutHpt[ny][0] = hpt & 1;
317 0 : lutHpt[ny][1] = (hpt & 2) >> 1;
318 0 : ny++;
319 0 : if (ny == 16)
320 : {
321 : ny = 0;
322 : // ytri == 1 means no trigger in y-direction
323 0 : if (ytri == 0)
324 : {
325 0 : FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
326 0 : }
327 : }
328 : }
329 :
330 : // 2nd 4-bits half-byte
331 0 : address = ilut+1;
332 0 : lh = (buffer[ilut/2] & mask2);
333 :
334 : // Lpt and Hpt response
335 0 : hpt = (lh & maskHpt) >> 2;
336 0 : lpt = lh & maskLpt;
337 :
338 : // decompose the 15-bits address
339 0 : trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
340 :
341 : // calculate group of y-strips
342 0 : if (trigx && (ny < 16))
343 : {
344 0 : lutLpt[ny][0] = lpt & 1;
345 0 : lutLpt[ny][1] = (lpt & 2) >> 1;
346 0 : lutHpt[ny][0] = hpt & 1;
347 0 : lutHpt[ny][1] = (hpt & 2) >> 1;
348 0 : ny++;
349 0 : if (ny == 16)
350 : {
351 : ny = 0;
352 : // ytri == 1 means no trigger in y-direction
353 0 : if (ytri == 0)
354 : {
355 0 : FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
356 0 : }
357 : }
358 : }
359 : }
360 0 : }
361 :
362 : //_____________________________________________________________________________
363 : Bool_t
364 : AliMUONTriggerIO::ReadLUT(const char* lutFileToRead, AliMUONTriggerLut& lut)
365 : {
366 : /// Fill the LUT object from online file
367 :
368 0 : if ( !NofLocalBoards() )
369 : {
370 0 : AliError("No local board id defined. Must read a regional file first");
371 0 : return kFALSE;
372 : }
373 :
374 0 : FILE* flut = fopen(gSystem->ExpandPathName(lutFileToRead),"rb");
375 0 : if (!flut)
376 : {
377 0 : AliError(Form("Could not read LUT file %s",lutFileToRead));
378 0 : return kFALSE;
379 : }
380 :
381 0 : for ( Int_t i = 0; i < NofLocalBoards(); ++i )
382 : {
383 0 : ReadLocalLUT(lut,fRegionalTrigger.LocalBoardId(i),flut);
384 : }
385 :
386 : //
387 : // 1st/2nd cut code pt cut [GeV/c]
388 : //
389 : // 0 0.5 (a.k.a. Apt)
390 : // 1 1.0 (a.k.a. Lpt)
391 : // 2 1.7 (a.k.a. Hpt)
392 : // 3 4.2 (a.k.a. infinity)
393 : // 4 free
394 : // .
395 : // .
396 : // .
397 : //15 default (for backward compatibility)
398 :
399 0 : UChar_t lutCode = 0xFF;
400 :
401 0 : if ( fread ( &lutCode, 1, 1, flut ) == 0 ) {
402 0 : AliWarning("No LUT info in the file (old version)");
403 0 : }
404 0 : AliInfo(Form("LUT code: 0x%02x",lutCode));
405 :
406 0 : fclose(flut);
407 :
408 0 : lut.SetLutCode(lutCode);
409 :
410 : return kTRUE;
411 :
412 0 : }
413 :
414 : //_____________________________________________________________________________
415 : Bool_t
416 : AliMUONTriggerIO::ReadTrigScalers(const char* scfile, TClonesArray& scalers) const
417 : {
418 : /// Fill the trigger scalers object from online file
419 :
420 0 : FILE* fp = fopen(gSystem->ExpandPathName(scfile),"r");
421 0 : if (!fp)
422 : {
423 0 : AliError(Form("Could not read file %s",scfile));
424 0 : return 0;
425 : }
426 :
427 : UInt_t nCalibEvents;
428 : UInt_t deltaT;
429 0 : UInt_t glSc[6];
430 : const Int_t nCathodes = 2;
431 : const Int_t nTriChambers = 4;
432 : const Int_t nLocBoards = 234;
433 0 : UInt_t locLptScaler[nLocBoards];
434 0 : ULong64_t locStripScaler[nTriChambers][nLocBoards][nCathodes];
435 0 : UInt_t locStripOver[nTriChambers][nLocBoards][nCathodes];
436 :
437 : const Int_t bufflen =
438 : 8*sizeof(UInt_t)+
439 : nLocBoards*sizeof(UInt_t)+
440 : nLocBoards*nCathodes*nTriChambers*(sizeof(UInt_t)+sizeof(ULong64_t));
441 0 : UChar_t buffer[bufflen];
442 :
443 : UInt_t bftmpUI;
444 : ULong64_t bftmpUL;
445 :
446 0 : AliInfo(Form("Data buffer length = %d",bufflen));
447 :
448 : Int_t ibr, isc = 0;
449 0 : while ( fread ( buffer, bufflen, 1, fp ) == 1 ) {
450 :
451 0 : AliMUONTriggerScalers *scaler = new(scalers[isc++]) AliMUONTriggerScalers();
452 :
453 : ibr = 0;
454 :
455 : // global
456 : nCalibEvents = 0;
457 0 : bftmpUI = buffer[ibr++]; nCalibEvents |= (bftmpUI << 24);
458 0 : bftmpUI = buffer[ibr++]; nCalibEvents |= (bftmpUI << 16);
459 0 : bftmpUI = buffer[ibr++]; nCalibEvents |= (bftmpUI << 8);
460 0 : bftmpUI = buffer[ibr++]; nCalibEvents |= (bftmpUI << 0);
461 0 : scaler->SetNCalibEvents(nCalibEvents);
462 : deltaT = 0;
463 0 : bftmpUI = buffer[ibr++]; deltaT |= (bftmpUI << 24);
464 0 : bftmpUI = buffer[ibr++]; deltaT |= (bftmpUI << 16);
465 0 : bftmpUI = buffer[ibr++]; deltaT |= (bftmpUI << 8);
466 0 : bftmpUI = buffer[ibr++]; deltaT |= (bftmpUI << 0);
467 0 : scaler->SetDeltaT(deltaT);
468 0 : for (Int_t bit = 0; bit < 6; bit++) {
469 0 : glSc[bit] = 0;
470 0 : bftmpUI = buffer[ibr++]; glSc[bit] |= (bftmpUI << 24);
471 0 : bftmpUI = buffer[ibr++]; glSc[bit] |= (bftmpUI << 16);
472 0 : bftmpUI = buffer[ibr++]; glSc[bit] |= (bftmpUI << 8);
473 0 : bftmpUI = buffer[ibr++]; glSc[bit] |= (bftmpUI << 0);
474 0 : scaler->SetGloScaler(glSc[bit],bit);
475 : }
476 :
477 : // local
478 0 : for (Int_t iLoc = 0; iLoc < nLocBoards; iLoc++) {
479 :
480 0 : locLptScaler[iLoc] = 0;
481 0 : bftmpUI = buffer[ibr++]; locLptScaler[iLoc] |= (bftmpUI << 24);
482 0 : bftmpUI = buffer[ibr++]; locLptScaler[iLoc] |= (bftmpUI << 16);
483 0 : bftmpUI = buffer[ibr++]; locLptScaler[iLoc] |= (bftmpUI << 8);
484 0 : bftmpUI = buffer[ibr++]; locLptScaler[iLoc] |= (bftmpUI << 0);
485 :
486 0 : scaler->SetLocScalerLpt(locLptScaler[iLoc],iLoc);
487 :
488 0 : for (Int_t iCath = 0; iCath < nCathodes; iCath++) {
489 0 : for (Int_t iCha = 0; iCha < nTriChambers; iCha++) {
490 :
491 0 : locStripScaler[iCha][iLoc][iCath] = 0;
492 0 : bftmpUL = buffer[ibr++];
493 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 56);
494 0 : bftmpUL = buffer[ibr++];
495 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 48);
496 0 : bftmpUL = buffer[ibr++];
497 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 40);
498 0 : bftmpUL = buffer[ibr++];
499 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 32);
500 0 : bftmpUL = buffer[ibr++];
501 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 24);
502 0 : bftmpUL = buffer[ibr++];
503 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 16);
504 0 : bftmpUL = buffer[ibr++];
505 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 8);
506 0 : bftmpUL = buffer[ibr++];
507 0 : locStripScaler[iCha][iLoc][iCath] |= (bftmpUL << 0);
508 :
509 0 : scaler->SetLocScalerStrip(locStripScaler[iCha][iLoc][iCath],iCath,iCha,iLoc);
510 :
511 0 : locStripOver[iCha][iLoc][iCath] = 0;
512 0 : bftmpUI = buffer[ibr++];
513 0 : locStripOver[iCha][iLoc][iCath] |= (bftmpUI << 24);
514 0 : bftmpUI = buffer[ibr++];
515 0 : locStripOver[iCha][iLoc][iCath] |= (bftmpUI << 16);
516 0 : bftmpUI = buffer[ibr++];
517 0 : locStripOver[iCha][iLoc][iCath] |= (bftmpUI << 8);
518 0 : bftmpUI = buffer[ibr++];
519 0 : locStripOver[iCha][iLoc][iCath] |= (bftmpUI << 0);
520 :
521 0 : scaler->SetLocScalerStripOver(locStripOver[iCha][iLoc][iCath],iCath,iCha,iLoc);
522 :
523 : }
524 : }
525 : }
526 :
527 : //AliInfo("Read from buffer %d bytes",ibr);
528 :
529 : }
530 :
531 0 : fclose(fp);
532 :
533 : return kTRUE;
534 :
535 0 : }
536 :
537 : //_____________________________________________________________________________
538 : Bool_t
539 : AliMUONTriggerIO::ReadConfig(const char* localFile,
540 : const char* regionalFile,
541 : const char* globalFile,
542 : AliMUONVStore* localMasks,
543 : AliMUONRegionalTriggerConfig* regionalConfig,
544 : AliMUONGlobalCrateConfig* globalConfig)
545 : {
546 : /// Fill the various masks store from files
547 :
548 0 : if ( !regionalConfig || !regionalFile || strlen(regionalFile)==0 )
549 : {
550 0 : AliError("Must have a regional file name to proceeed");
551 0 : return kFALSE;
552 : }
553 :
554 0 : AliDebug(1,Form("regionalConfig=%p",regionalConfig));
555 :
556 0 : Int_t nCrates = ReadRegionalConfig(regionalFile, regionalConfig);
557 :
558 0 : if (!nCrates)
559 : {
560 0 : AliError("nCrates=0 !");
561 0 : return kFALSE;
562 : }
563 :
564 0 : if (localMasks && localFile && strlen(localFile) > 0 )
565 : {
566 0 : Int_t nLocal = ReadLocalMasks(localFile,*localMasks);
567 0 : AliDebug(1,Form("Read masks for %d local boards",nLocal));
568 0 : }
569 :
570 0 : Int_t nDarc = ReadGlobalConfig(globalFile, globalConfig);
571 0 : AliDebug(1,Form("Read config for %d DARC boards",nDarc));
572 :
573 0 : if (!nDarc) return kFALSE;
574 :
575 0 : return kTRUE;
576 0 : }
577 :
578 :
579 :
580 : //_____________________________________________________________________________
581 : Int_t
582 : AliMUONTriggerIO::ReadGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const
583 : {
584 : /// read the global crate file
585 : /// the masks are disable bit for each crate, 8 per darc board
586 : /// bit value 0 means enable, 1 means disable *
587 :
588 : Int_t nDarc = 0;
589 0 : if ( !(nDarc = globalConfig->ReadData(globalFile)) ) return 0;
590 :
591 0 : return nDarc;
592 0 : }
593 :
594 : //_____________________________________________________________________________
595 : Int_t
596 : AliMUONTriggerIO::ReadRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig)
597 : {
598 : /// Read regional file to fill
599 :
600 0 : AliDebug(1,Form("regionalConfig=%p",regionalConfig));
601 :
602 : Int_t nCrates = 0;
603 0 : if ( !(nCrates = regionalConfig->ReadData(regionalFile)) ) return 0;
604 :
605 : // read the mapping file also
606 0 : if ( ! fRegionalTrigger.ReadData(regionalFile) ) return 0;
607 :
608 0 : return nCrates;
609 0 : }
610 :
611 :
612 : //_____________________________________________________________________________
613 : Bool_t
614 : AliMUONTriggerIO::WriteLUT(const AliMUONTriggerLut& lut,
615 : const char* lutFileToWrite)
616 : {
617 : /// Convert an offline lut into an online (binary) lut file
618 :
619 0 : if ( !NofLocalBoards() )
620 : {
621 0 : AliError("No local board id defined. Must read a regional file first");
622 0 : return kFALSE;
623 : }
624 :
625 0 : FILE* flut = fopen(gSystem->ExpandPathName(lutFileToWrite),"wb");
626 0 : if (!flut)
627 : {
628 0 : AliError(Form("Could not create output LUT file %s",lutFileToWrite));
629 0 : return kFALSE;
630 : }
631 :
632 0 : for ( Int_t i = 0; i < NofLocalBoards(); ++i )
633 : {
634 0 : WriteLocalLUT(lut,fRegionalTrigger.LocalBoardId(i),flut);
635 : }
636 :
637 0 : fclose(flut);
638 :
639 0 : return kTRUE;
640 0 : }
641 :
642 :
643 : //_____________________________________________________________________________
644 : Bool_t
645 : AliMUONTriggerIO::WriteTrigScalers(const TClonesArray& scalers,
646 : const char* scfile) const
647 : {
648 : /// Convert offline scalers into an online (binary) file
649 :
650 0 : FILE* fp = fopen(gSystem->ExpandPathName(scfile),"wb");
651 0 : if (!fp)
652 : {
653 0 : AliError(Form("Could not create output local file %s",scfile));
654 0 : return kFALSE;
655 : }
656 :
657 : UInt_t nCalibEvents;
658 : UInt_t deltaT;
659 0 : UInt_t glSc[6];
660 : const Int_t nCathodes = 2;
661 : const Int_t nTriChambers = 4;
662 : const Int_t nLocBoards = 234;
663 0 : UInt_t locLptScaler[nLocBoards];
664 0 : ULong64_t locStripScaler[nTriChambers][nLocBoards][nCathodes];
665 0 : UInt_t locStripOver[nTriChambers][nLocBoards][nCathodes];
666 :
667 : const Int_t bufflen =
668 : 8*sizeof(UInt_t)+
669 : nLocBoards*sizeof(UInt_t)+
670 : nLocBoards*nCathodes*nTriChambers*(sizeof(UInt_t)+sizeof(ULong64_t));
671 0 : UChar_t buffer[bufflen];
672 :
673 0 : AliInfo(Form("Data buffer length = %d",bufflen));
674 :
675 0 : Int_t entries = scalers.GetEntries();
676 : Int_t ibr, isc = 0;
677 0 : for (; isc < entries; isc++) {
678 : ibr = 0;
679 0 : AliMUONTriggerScalers *sc = (AliMUONTriggerScalers*)scalers.At(isc);
680 0 : nCalibEvents = sc->GetNCalibEvents();
681 0 : AliInfo(Form("nCalibEvents = %d",sc->GetNCalibEvents()));
682 0 : buffer[ibr++] = (nCalibEvents >> 24) & 0xFF;
683 0 : buffer[ibr++] = (nCalibEvents >> 16) & 0xFF;
684 0 : buffer[ibr++] = (nCalibEvents >> 8) & 0xFF;
685 0 : buffer[ibr++] = (nCalibEvents >> 0) & 0xFF;
686 0 : deltaT = sc->GetDeltaT();
687 0 : buffer[ibr++] = (deltaT >> 24) & 0xFF;
688 0 : buffer[ibr++] = (deltaT >> 16) & 0xFF;
689 0 : buffer[ibr++] = (deltaT >> 8) & 0xFF;
690 0 : buffer[ibr++] = (deltaT >> 0) & 0xFF;
691 0 : for (Int_t bit = 0; bit < 6; bit++) {
692 0 : glSc[bit] = sc->GetGloScal(bit);
693 0 : buffer[ibr++] = (glSc[bit] >> 24) & 0xFF;
694 0 : buffer[ibr++] = (glSc[bit] >> 16) & 0xFF;
695 0 : buffer[ibr++] = (glSc[bit] >> 8) & 0xFF;
696 0 : buffer[ibr++] = (glSc[bit] >> 0) & 0xFF;
697 : }
698 0 : for (Int_t iLoc = 0; iLoc < nLocBoards; iLoc++) {
699 0 : locLptScaler[iLoc] = sc->GetLocScalLpt(iLoc);
700 0 : buffer[ibr++] = (locLptScaler[iLoc] >> 24) & 0xFF;
701 0 : buffer[ibr++] = (locLptScaler[iLoc] >> 16) & 0xFF;
702 0 : buffer[ibr++] = (locLptScaler[iLoc] >> 8) & 0xFF;
703 0 : buffer[ibr++] = (locLptScaler[iLoc] >> 0) & 0xFF;
704 0 : for (Int_t iCath = 0; iCath < nCathodes; iCath++) {
705 0 : for (Int_t iCha = 0; iCha < nTriChambers; iCha++) {
706 0 : locStripScaler[iCath][iCha][iLoc] = sc->GetLocScalStrip(iCath,iCha,iLoc);
707 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 56) & 0xFF;
708 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 48) & 0xFF;
709 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 40) & 0xFF;
710 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 32) & 0xFF;
711 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 24) & 0xFF;
712 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 16) & 0xFF;
713 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 8) & 0xFF;
714 0 : buffer[ibr++] = (locStripScaler[iCath][iCha][iLoc] >> 0) & 0xFF;
715 0 : locStripOver[iCath][iCha][iLoc] = sc->GetLocScalStripOver(iCath,iCha,iLoc);
716 0 : buffer[ibr++] = (locStripOver[iCath][iCha][iLoc] >> 24) & 0xFF;
717 0 : buffer[ibr++] = (locStripOver[iCath][iCha][iLoc] >> 16) & 0xFF;
718 0 : buffer[ibr++] = (locStripOver[iCath][iCha][iLoc] >> 8) & 0xFF;
719 0 : buffer[ibr++] = (locStripOver[iCath][iCha][iLoc] >> 0) & 0xFF;
720 : }
721 : }
722 : }
723 :
724 0 : fwrite(buffer,ibr,1,fp);
725 : //AliInfo("Read to buffer %d bytes",ibr);
726 :
727 : }
728 :
729 0 : fclose(fp);
730 :
731 : return kTRUE;
732 :
733 0 : }
734 :
735 : //_____________________________________________________________________________
736 : Bool_t
737 : AliMUONTriggerIO::WriteConfig(const char* localFile,
738 : const char* regionalFile,
739 : const char* globalFile,
740 : const AliMUONVStore* localMasks,
741 : AliMUONRegionalTriggerConfig* regionalConfig,
742 : AliMUONGlobalCrateConfig* globalConfig) const
743 : {
744 : /// write config files
745 :
746 : Bool_t ok;
747 0 : ok = WriteLocalMasks(localFile, *localMasks);
748 0 : ok &= WriteRegionalConfig(regionalFile, regionalConfig);
749 0 : ok &= WriteGlobalConfig(globalFile, globalConfig);
750 :
751 0 : return ok;
752 :
753 :
754 : }
755 :
756 :
757 : //_____________________________________________________________________________
758 : Bool_t
759 : AliMUONTriggerIO::WriteGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const
760 : {
761 : /// write global config
762 :
763 0 : ofstream out;
764 : Int_t disable = 0;
765 :
766 0 : out.open(globalFile);
767 0 : if (!out.good())
768 : {
769 0 : AliError(Form("Could not create output global file %s", globalFile));
770 0 : return kFALSE;
771 : }
772 :
773 0 : out << globalConfig->GetName() << endl;
774 0 : out << Form("0x%02x",globalConfig->GetGlobalCrateEnable()) << endl;
775 :
776 : Bool_t oldFormat = kTRUE;
777 0 : if (globalConfig->GetEnableJtag() == 0) oldFormat = kFALSE;
778 :
779 0 : if (oldFormat) {
780 : // Jtag
781 0 : out << globalConfig->GetJtagName() << endl;
782 0 : out << Form("0x%08lx", globalConfig->GetJtagVmeAddr()) << endl;
783 0 : out << Form("%d %d %d", globalConfig->GetJtagClockDiv(),
784 0 : globalConfig->GetJtagRxPhase(), globalConfig->GetJtagRdDelay()) << endl;
785 :
786 0 : for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
787 0 : out << Form("%d ", globalConfig->GetEnableJtag(i));
788 0 : out << endl;
789 :
790 0 : for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
791 : {
792 0 : out << i << endl;
793 0 : for (Int_t j = 0; j < globalConfig->GetJtagNofLines(); ++j)
794 0 : out << Form("%s ", globalConfig->GetJtagCrateName(i,j).Data()) << endl;
795 : }
796 :
797 0 : } // end old format
798 :
799 : // first darc board
800 0 : out << globalConfig->GetFirstDarcName() << endl;
801 0 : out << Form("0x%08lx", globalConfig->GetFirstDarcVmeAddr()) << endl;
802 0 : out << globalConfig->GetFirstDarcType() << endl;
803 0 : disable = globalConfig->GetFirstDarcDisable();
804 0 : out << Form("0x%02x", disable) << endl;
805 0 : out << Form("0x%x", globalConfig->GetFirstDarcL0Delay()) << endl;
806 0 : out << Form("0x%x", globalConfig->GetFirstDarcL1TimeOut()) << endl;
807 0 : out << Form("0x%x", globalConfig->GetFirstDarcGlobalL0()) << endl;
808 0 : out << Form("0x%x", globalConfig->GetFirstDarcConfig()) << endl;
809 :
810 0 : if (!oldFormat) {
811 :
812 0 : for (Int_t i = 0; i < globalConfig->GetDarcNofLines(); ++i)
813 0 : out << Form("%d ", globalConfig->GetEnableFirstDarc(i));
814 0 : out << endl;
815 :
816 0 : for (Int_t i = 0; i < globalConfig->GetDarcNofLines(); ++i)
817 : {
818 0 : out << Form("%s ", globalConfig->GetFirstDarcCrateName(i).Data()) << endl;
819 : }
820 :
821 0 : } // end new format
822 :
823 : // second darc board
824 0 : out << globalConfig->GetSecondDarcName() << endl;
825 0 : out << Form("0x%08lx", globalConfig->GetSecondDarcVmeAddr()) << endl;
826 0 : out << globalConfig->GetSecondDarcType() << endl;
827 0 : disable = globalConfig->GetSecondDarcDisable();
828 0 : out << Form("0x%02x", disable) << endl;
829 0 : out << Form("0x%x", globalConfig->GetSecondDarcL0Delay()) << endl;
830 0 : out << Form("0x%x", globalConfig->GetSecondDarcL1TimeOut()) << endl;
831 0 : out << Form("0x%x", globalConfig->GetSecondDarcGlobalL0()) << endl;
832 0 : out << Form("0x%x", globalConfig->GetSecondDarcConfig()) << endl;
833 :
834 0 : if (!oldFormat) {
835 :
836 0 : for (Int_t i = 0; i < globalConfig->GetDarcNofLines(); ++i)
837 0 : out << Form("%d ", globalConfig->GetEnableSecondDarc(i));
838 0 : out << endl;
839 :
840 0 : for (Int_t i = 0; i < globalConfig->GetDarcNofLines(); ++i)
841 : {
842 0 : out << Form("%s ", globalConfig->GetSecondDarcCrateName(i).Data()) << endl;
843 : }
844 :
845 0 : } // end new format
846 :
847 : // global board
848 0 : out << globalConfig->GetGlobalName() << endl;
849 0 : out << Form("0x%08lx", globalConfig->GetGlobalVmeAddr()) << endl;
850 0 : for (Int_t i = 0; i < globalConfig->GetGlobalNofRegisters(); ++i)
851 0 : out << Form("0x%x", globalConfig->GetGlobalRegister(i)) << endl;
852 :
853 : // Fet board
854 0 : out << globalConfig->GetFetName() << endl;
855 0 : out << Form("0x%08lx", globalConfig->GetFetVmeAddr()) << endl;
856 0 : for (Int_t i = 0; i < globalConfig->GetFetNofRegisters(); ++i)
857 0 : out << Form("0x%x", globalConfig->GetFetRegister(i)) << endl;
858 :
859 : return kTRUE;
860 0 : }
861 :
862 : //_____________________________________________________________________________
863 : Bool_t
864 : AliMUONTriggerIO::WriteRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig) const
865 : {
866 :
867 : /// write regional mask with the current configuration
868 : /// if regional masks not defined, take the one from current configuration
869 :
870 0 : ofstream out;
871 0 : out.open(regionalFile);
872 :
873 0 : if (!out.good())
874 : {
875 0 : AliError(Form("Could not create output regional file %s",regionalFile));
876 0 : return kFALSE;
877 : }
878 :
879 0 : Int_t nCrate = fRegionalTrigger.GetNofTriggerCrates();
880 0 : if (!nCrate)
881 : {
882 0 : AliError("Could not write regional no configuration in memory");
883 0 : return kFALSE;
884 : }
885 :
886 : Int_t nofDDLs = 0;
887 0 : TString name;
888 : AliMpTriggerCrate* crate;
889 0 : for (Int_t ddlId = 0; ddlId < 2; ddlId++) // right & left side
890 : {
891 0 : for (Int_t crateId = 0; crateId < 8; crateId++) // 8 crates/regional boards for each side.
892 : {
893 :
894 0 : name = AliMpTriggerCrate::GenerateName(crateId, ddlId, nofDDLs);
895 :
896 0 : crate = fRegionalTrigger.FindTriggerCrate(name, false);
897 :
898 0 : AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(crate->GetName());
899 0 : if (!crateConfig)
900 : {
901 0 : AliError(Form("Cannot find crate %s in CDB", crate->GetName()));
902 0 : return kFALSE;
903 : }
904 :
905 0 : out << crate->GetName() << endl;
906 0 : out << Form("%02x", crate->GetId()) << endl;
907 0 : out << crateConfig->GetMode() << endl;
908 0 : out << crateConfig->GetCoinc() << endl;
909 0 : out << Form("%04x", crateConfig->GetMask()) << endl;
910 0 : out << Form("%02d",crate->GetNofLocalBoards()) << endl;
911 :
912 0 : for (Int_t iLocal = 0; iLocal < crate->GetNofLocalBoards(); ++iLocal)
913 : {
914 0 : Int_t localBoardId = crate->GetLocalBoardId(iLocal);
915 :
916 0 : AliMpLocalBoard* board = fRegionalTrigger.FindLocalBoard(localBoardId);
917 :
918 0 : out << Form("%02d ", board->GetSlot())
919 0 : << board->GetName()
920 0 : << Form(" %03d ", localBoardId)
921 0 : << Form("%03x", board->GetSwitch())
922 0 : << endl;
923 :
924 0 : out << " ";
925 :
926 0 : if (board->IsNotified()) {
927 0 : for (Int_t i = 0; i < board->GetNofDEs(); ++i)
928 0 : out << Form("%4d ", board->GetDEId(i));
929 0 : } else {
930 0 : out << Form("%4d ", 0);
931 : }
932 0 : out << endl;
933 :
934 : // print copy card numbers & TC
935 0 : out << Form(" %4d %4d", board->GetInputXfrom(), board->GetInputXto());
936 0 : out << Form(" %4d %4d", board->GetInputYfrom(), board->GetInputYto());
937 0 : out << Form(" %4d", board->GetTC()) << endl;
938 : }
939 0 : }
940 : }
941 :
942 0 : out.close();
943 :
944 0 : return kTRUE;
945 0 : }
946 :
947 :
948 : //_____________________________________________________________________________
949 : Bool_t
950 : AliMUONTriggerIO::WriteLocalMasks(const char* localFile, const AliMUONVStore& localMasks) const
951 : {
952 : /// write local mask
953 : /// removing/adding enable for a local board need a update of the configuration
954 : /// before calling this method
955 : /// mask are written for all boards including the copy card (Ch.F.)
956 :
957 0 : FILE* fp = fopen(gSystem->ExpandPathName(localFile),"wb");
958 0 : if (!fp)
959 : {
960 0 : AliError(Form("Could not create output local file %s",localFile));
961 0 : return kFALSE;
962 : }
963 :
964 0 : UShort_t maskBuffer[8];
965 : Int_t localBoardIndex(0);
966 0 : while (localBoardIndex < NofLocalBoards()) {
967 :
968 0 : Int_t localBoardId = fRegionalTrigger.LocalBoardId(localBoardIndex);
969 :
970 : AliMUONVCalibParam* localMask =
971 0 : static_cast<AliMUONVCalibParam*>(localMasks.FindObject(localBoardId));
972 :
973 0 : for (Int_t index = 0; index < 8; ++index)
974 : {
975 0 : maskBuffer[index] = localMask->ValueAsInt(index,0);
976 : }
977 :
978 0 : fwrite ( maskBuffer, 2, 8, fp);
979 :
980 0 : ++localBoardIndex;
981 :
982 : }
983 :
984 0 : fclose(fp);
985 :
986 : return kTRUE;
987 :
988 0 : }
989 :
990 : //_____________________________________________________________________________
991 : void
992 : AliMUONTriggerIO::WriteLocalLUT(const AliMUONTriggerLut& lut,
993 : Int_t localBoardId,
994 : FILE* flut)
995 : {
996 : /// loop over the address for the 4-bits lpt and hpt decisions
997 :
998 : const Int_t kMaskYpos = 0x0F;
999 : const Int_t kMaskYtri = 0x01;
1000 : const Int_t kMaskXdev = 0x1F;
1001 : const Int_t kMaskXpos = 0x1F;
1002 :
1003 0 : UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
1004 : Int_t bc = 0;
1005 :
1006 0 : for (UInt_t i = 0; i < fgkLocalLutSize*2; ++i)
1007 : {
1008 0 : Int_t lutLpt[2] = { 0 };
1009 0 : Int_t lutHpt[2] = { 0 };
1010 :
1011 : // decompose address
1012 0 : Int_t iYpos = i & kMaskYpos;
1013 0 : Int_t iYtri = ( i >> 4 ) & kMaskYtri;
1014 0 : Int_t iXdev = ( i >> ( 4 + 1 ) ) & kMaskXdev;
1015 0 : Int_t iXpos = ( i >> ( 4 + 1 + 5 ) ) & kMaskXpos;
1016 :
1017 : // convert deviation format
1018 : // online: sign 1bit , dev 4bit
1019 : // sign dev trigger
1020 : // 0 1-15 mu-
1021 : // 1 1-15 mu+
1022 : // 0 0 mu+, mu- infinite momentum (unde)
1023 : // 1 0 no x-trigger
1024 : // offline: dev 5bit
1025 : // sign dev trigger
1026 : // - 0-14 mu-
1027 : // - 16-31 mu+
1028 : // - 15 mu+, mu- infinite momentum (unde)
1029 : Int_t iXdevOn = 0;
1030 : Int_t iXdevOff = 0;
1031 : Int_t sign = 0;
1032 : Bool_t trigx = kFALSE;
1033 0 : iXdevOn += iXdev & 0x0F;
1034 0 : sign += (iXdev >> 4) & 0x01;
1035 0 : if (iXdevOn == 0) {
1036 0 : if (sign == 0) {
1037 : iXdevOff = 15;
1038 : trigx = kTRUE;
1039 0 : } else {
1040 : iXdevOff = 15;
1041 : trigx = kFALSE;
1042 : }
1043 : } else {
1044 : trigx = kTRUE;
1045 0 : if (sign == 0) {
1046 0 : iXdevOff = - iXdevOn + 15; // gives range 0-14
1047 0 : } else {
1048 0 : iXdevOff = + iXdevOn + 15; // gives range 16-30 !
1049 : }
1050 : }
1051 : iXdev = iXdevOff;
1052 :
1053 : // iYtri == 1 means no trigger in y-direction
1054 0 : if (iYtri == 0 && trigx)
1055 : {
1056 0 : lut.GetLutOutput(localBoardId,iXpos,iXdev,iYpos,lutLpt,lutHpt);
1057 0 : }
1058 :
1059 : // fill byte
1060 0 : if (i%2 == 0)
1061 : {
1062 : // upper half-byte
1063 0 : buffer[bc] = 0;
1064 0 : buffer[bc] += lutHpt[1] << 7;
1065 0 : buffer[bc] += lutHpt[0] << 6;
1066 0 : buffer[bc] += lutLpt[1] << 5;
1067 0 : buffer[bc] += lutLpt[0] << 4;
1068 0 : } else {
1069 : // lower half-byte
1070 0 : buffer[bc] += lutHpt[1] << 3;
1071 0 : buffer[bc] += lutHpt[0] << 2;
1072 0 : buffer[bc] += lutLpt[1] << 1;
1073 0 : buffer[bc] += lutLpt[0] << 0;
1074 0 : bc++;
1075 : }
1076 0 : }
1077 0 : fwrite(&buffer,bc,1,flut);
1078 0 : }
1079 :
1080 : //_____________________________________________________________________________
1081 : Int_t
1082 : AliMUONTriggerIO::LocalBoardId(Int_t index) const
1083 : {
1084 : /// Return the i-th localBoardId, or -1 if index is out of bounds
1085 :
1086 0 : return fRegionalTrigger.LocalBoardId(index);
1087 : }
1088 :
1089 :
1090 : //______________________________________________________________________________
1091 :
1092 : Int_t AliMUONTriggerIO::LocalBoardId(Int_t ddlId, Int_t crateId, Int_t localId) const
1093 : {
1094 : /// Return local board id from crate and local indexes.
1095 :
1096 : Int_t nofDDLs = 0;
1097 0 : TString name = AliMpTriggerCrate::GenerateName(crateId, ddlId, nofDDLs);
1098 :
1099 0 : AliMpTriggerCrate* crate = fRegionalTrigger.FindTriggerCrate(name, false);
1100 0 : return crate->GetLocalBoardId(localId);
1101 0 : }
|