Fix coverity defect
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerIO.cxx
CommitLineData
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"
acdc80b6 19#include "AliMUONTriggerLut.h"
20#include "AliMUONCalibParamNI.h"
21#include "AliMUONVStore.h"
2ab3623b 22
890cc210 23#include "AliMpCDB.h"
5dde41b3 24#include "AliMpHelper.h"
5eff9abc 25#include "AliMpConstants.h"
aed0186b 26#include "AliMpDDL.h"
5dde41b3 27#include "AliMpFiles.h"
2ab3623b 28#include "AliMpDDLStore.h"
5eff9abc 29#include "AliMpLocalBoard.h"
2ab3623b 30#include "AliMpTriggerCrate.h"
92c23b09 31#include "AliMUONGlobalCrateConfig.h"
32#include "AliMUONRegionalTriggerConfig.h"
33#include "AliMUONTriggerCrateConfig.h"
5eff9abc 34
acdc80b6 35#include "AliLog.h"
5eff9abc 36
2ab3623b 37#include <Riostream.h>
38#include <TSystem.h>
39
40/// \class AliMUONTriggerIO
41///
42/// Handles read/write of masks and LUT to/from online files,
43/// to be used by Shuttle and Trigger DA.
44///
5eff9abc 45/// \author Laurent Aphecetche, Christian Finck Subatech
890cc210 46/// \author Bogdan Vulpescu, LPC Clermont-Ferrand
2ab3623b 47
48/// \cond CLASSIMP
49ClassImp(AliMUONTriggerIO)
50/// \endcond
51
92c23b09 52
53const UInt_t AliMUONTriggerIO::fgkLocalLutSize = 1 << 14; // 16384
54
2ab3623b 55//_____________________________________________________________________________
5eff9abc 56AliMUONTriggerIO::AliMUONTriggerIO()
57 : TObject(),
33245d2c 58 fRegionalTrigger()
2ab3623b 59{
60 /// ctor
61}
62
63//_____________________________________________________________________________
5eff9abc 64AliMUONTriggerIO::AliMUONTriggerIO(const char* regionalFileToRead)
65 :TObject(),
33245d2c 66 fRegionalTrigger()
890cc210 67{
68 /// ctor
92c23b09 69 ReadRegionalConfig(regionalFileToRead,0);
890cc210 70}
71
72//_____________________________________________________________________________
2ab3623b 73AliMUONTriggerIO::~AliMUONTriggerIO()
74{
75 /// dtor
76}
77
78//_____________________________________________________________________________
e26b1a52 79Bool_t
890cc210 80AliMUONTriggerIO::DeCompAddress(UChar_t &ypos, UChar_t &ytri, UChar_t &xdev, UChar_t &xpos,
81 UShort_t address) const
82{
83 /// decompose the 15-bits address
84
85 UChar_t bitsYpos = 4;
86 UChar_t bitsYtri = 1;
87 UChar_t bitsXdev = 5;
88 // UChar_t bitsXpos = 5;
89
90 UShort_t maskYpos = 0x000F; // ...0 00001111
91 UShort_t maskYtri = 0x0001; // ...0 00000001
92 UShort_t maskXdev = 0x001F; // ...0 00011111
93 UShort_t maskXpos = 0x001F; // ...0 00011111
94
95 ypos = address & maskYpos;
96 ytri = (address >> bitsYpos) & maskYtri;
97 xdev = (address >> (bitsYpos+bitsYtri)) & maskXdev;
98 xpos = (address >> (bitsYpos+bitsYtri+bitsXdev)) & maskXpos;
e26b1a52 99
100 // convert deviation format
101 // online: sign 1bit , dev 4bit
102 // sign dev trigger
103 // 0 1-15 mu-
104 // 1 1-15 mu+
105 // 0 0 mu+, mu- infinite momentum (unde)
106 // 1 0 no x-trigger
107 // offline: dev 5bit
108 // sign dev trigger
109 // - 0-14 mu-
110 // - 16-31 mu+
111 // - 15 mu+, mu- infinite momentum (unde)
112
113 Int_t iXdevOff, iXdevOn, iXdev, sign;
114 Bool_t trigx;
115
116 iXdev = xdev;
117
118 iXdevOn = sign = 0;
119 iXdevOn += iXdev & 0x0F;
120 sign += (iXdev >> 4) & 0x01;
121 if (iXdevOn == 0) {
122 if (sign == 0) {
123 iXdevOff = 15;
124 trigx = kTRUE;
125 } else {
126 iXdevOff = 15;
127 trigx = kFALSE;
128 }
129 } else {
130 trigx = kTRUE;
131 if (sign == 0) {
132 iXdevOff = - iXdevOn + 15; // gives range 0-14
133 } else {
134 iXdevOff = + iXdevOn + 15; // gives range 16-30 !
135 }
136 }
137
138 xdev = iXdevOff;
139
140 return trigx;
141
890cc210 142}
143
144//_____________________________________________________________________________
145void
146AliMUONTriggerIO::FillLut(AliMUONTriggerLut& lut,
147 Int_t icirc, UChar_t istripX, UChar_t idev,
148 Int_t lutLpt[16][2], Int_t lutHpt[16][2])
149{
150 /// Fill the LUT histograms
151
152 if (icirc == 0 && istripX == 0 && idev == 0)
153 {
154 AliDebug(1,"Copy board, not filled ...");
155 return;
156 }
157
158 Short_t iLptPlus, iLptMinu, iLptUnde;
159 Short_t iHptPlus, iHptMinu, iHptUnde;
160
161 iLptPlus = iLptMinu = iLptUnde = 0;
162 iHptPlus = iHptMinu = iHptUnde = 0;
163
164 for (Int_t istripY=0; istripY<16; istripY++)
165 {
166 if (lutLpt[istripY][1] == 0 && lutLpt[istripY][0] ==1)
167 iLptMinu=iLptMinu+(1 << istripY);
168 if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==0)
169 iLptPlus=iLptPlus+(1 << istripY);
170 if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==1)
171 iLptUnde=iLptUnde+(1 << istripY);
172
173 if (lutHpt[istripY][1] == 0 && lutHpt[istripY][0] ==1)
174 iHptMinu=iHptMinu+(1 << istripY);
175 if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==0)
176 iHptPlus=iHptPlus+(1 << istripY);
177 if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==1)
178 iHptUnde=iHptUnde+(1 << istripY);
179
180 } // loop on istripY
181
182 lut.SetContent("LptMinu",icirc,istripX,idev,iLptMinu);
183 lut.SetContent("LptUnde",icirc,istripX,idev,iLptUnde);
184 lut.SetContent("LptPlus",icirc,istripX,idev,iLptPlus);
185
e26b1a52 186 lut.SetContent("HptMinu",icirc,istripX,idev,iHptMinu);
187 lut.SetContent("HptUnde",icirc,istripX,idev,iHptUnde);
188 lut.SetContent("HptPlus",icirc,istripX,idev,iHptPlus);
890cc210 189}
190
191//_____________________________________________________________________________
2ab3623b 192Int_t
193AliMUONTriggerIO::ReadLocalMasks(const char* localFile, AliMUONVStore& localMasks) const
194{
195 /// Fills the local masks store from file
196
197 if ( !NofLocalBoards() )
198 {
199 AliError("No local board to read");
200 return 0;
201 }
202
203 FILE* fp = fopen(gSystem->ExpandPathName(localFile),"r");
204 if (!fp)
205 {
206 AliError(Form("Could not read file %s",localFile));
207 return 0;
208 }
209
210 UShort_t maskBuffer[8];
211
5cf57a25 212 Int_t localBoardIndex(0);
630711ed 213
2ab3623b 214 while ( fread ( maskBuffer, 2, 8, fp ) )
215 {
5cf57a25 216 Int_t localBoardId = fRegionalTrigger.LocalBoardId(localBoardIndex);
2ab3623b 217 AliDebug(1,Form("LB %03d X1 %4x X2 %4x X3 %4x X4 %4x "
218 "Y1 %4x Y2 %4x Y3 %4x Y4 %4x",
219 localBoardId,
220 maskBuffer[0],
221 maskBuffer[1],
222 maskBuffer[2],
223 maskBuffer[3],
224 maskBuffer[4],
225 maskBuffer[5],
226 maskBuffer[6],
227 maskBuffer[7]));
228
5cf57a25 229 if ( localBoardId > 0 )
2ab3623b 230 {
231 AliMUONVCalibParam* localBoard = new AliMUONCalibParamNI(1,8,localBoardId,0,0);
5eff9abc 232 for ( Int_t index = 0; index < 8; ++index )
2ab3623b 233 {
5cf57a25 234 localBoard->SetValueAsInt(index,0,maskBuffer[index]);
2ab3623b 235 }
236 localMasks.Add(localBoard);
237 }
5cf57a25 238 else
239 {
240 AliError(Form("Oups. Got localBoardId=%d for index=%d",localBoardId,localBoardIndex));
241 }
2ab3623b 242
5cf57a25 243 ++localBoardIndex;
2ab3623b 244 }
245
5cf57a25 246 if ( localBoardIndex != NofLocalBoards() )
2ab3623b 247 {
248 AliError(Form("Read %d out of %d local boards",
5cf57a25 249 localBoardIndex, NofLocalBoards()));
2ab3623b 250 }
251
252 fclose(fp);
253
5cf57a25 254 return localBoardIndex+1;
2ab3623b 255}
256
257//_____________________________________________________________________________
890cc210 258void
259AliMUONTriggerIO::ReadLocalLUT(AliMUONTriggerLut& lut,
260 Int_t localBoardId,
261 FILE* flut)
262{
263 /// Read the LUT for one local board from an online file
264
265 UShort_t address;
266
92c23b09 267 UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
890cc210 268 UChar_t mask1 = 0xF0;
269 UChar_t mask2 = 0x0F;
e26b1a52 270 UChar_t maskHpt = 0x0C;
271 UChar_t maskLpt = 0x03;
890cc210 272 UChar_t lh, lpt, hpt;
273
274 UChar_t xpos, xdev, ypos, ytri;
275
276 Int_t lutLpt[16][2], lutHpt[16][2];
277
278 Int_t boardnr = localBoardId;
279
280 AliDebug(1,Form("Reading LUT values for local board %d",boardnr));
281
282 Int_t ny = 0;
e26b1a52 283 Bool_t trigx = kFALSE;
890cc210 284
97c4e962 285 // read two lut addresses at once, 32768/2=16384 times
cbcc4fb0 286 if (fread(buffer,fgkLocalLutSize,1,flut) == 0) {
287 AliWarning("Error reading the LUT file");
288 return;
289 }
97c4e962 290
890cc210 291 // create the 32767 addresses for the 4-bits lpt and hpt half-bytes
92c23b09 292 for (UShort_t ilut = 0; ilut < fgkLocalLutSize*2; ilut += 2)
890cc210 293 {
890cc210 294
295 // 1st 4-bits half-byte
296 address = ilut;
97c4e962 297 lh = (buffer[ilut/2] & mask1) >> 4;
890cc210 298
299 // Lpt and Hpt response
e26b1a52 300 hpt = (lh & maskHpt) >> 2;
301 lpt = lh & maskLpt;
890cc210 302
303 // decompose the 15-bits address
e26b1a52 304 trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
890cc210 305
306 // calculate group of y-strips
e26b1a52 307 if (trigx && (ny < 16))
890cc210 308 {
309 lutLpt[ny][0] = lpt & 1;
310 lutLpt[ny][1] = (lpt & 2) >> 1;
311 lutHpt[ny][0] = hpt & 1;
312 lutHpt[ny][1] = (hpt & 2) >> 1;
313 ny++;
314 if (ny == 16)
315 {
316 ny = 0;
317 // ytri == 1 means no trigger in y-direction
318 if (ytri == 0)
319 {
320 FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
321 }
322 }
323 }
324
325 // 2nd 4-bits half-byte
326 address = ilut+1;
97c4e962 327 lh = (buffer[ilut/2] & mask2);
890cc210 328
329 // Lpt and Hpt response
e26b1a52 330 hpt = (lh & maskHpt) >> 2;
331 lpt = lh & maskLpt;
890cc210 332
333 // decompose the 15-bits address
e26b1a52 334 trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
890cc210 335
336 // calculate group of y-strips
e26b1a52 337 if (trigx && (ny < 16))
890cc210 338 {
339 lutLpt[ny][0] = lpt & 1;
340 lutLpt[ny][1] = (lpt & 2) >> 1;
341 lutHpt[ny][0] = hpt & 1;
342 lutHpt[ny][1] = (hpt & 2) >> 1;
343 ny++;
344 if (ny == 16)
345 {
346 ny = 0;
347 // ytri == 1 means no trigger in y-direction
348 if (ytri == 0)
349 {
350 FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
351 }
352 }
353 }
354 }
355}
356
357//_____________________________________________________________________________
358Bool_t
359AliMUONTriggerIO::ReadLUT(const char* lutFileToRead, AliMUONTriggerLut& lut)
360{
361 /// Fill the LUT object from online file
362
363 if ( !NofLocalBoards() )
364 {
365 AliError("No local board id defined. Must read a regional file first");
366 return kFALSE;
367 }
368
369 FILE* flut = fopen(gSystem->ExpandPathName(lutFileToRead),"rb");
370 if (!flut)
371 {
ca6cee23 372 AliError(Form("Could not read LUT file %s",lutFileToRead));
890cc210 373 return kFALSE;
374 }
375
376 for ( Int_t i = 0; i < NofLocalBoards(); ++i )
377 {
630711ed 378 ReadLocalLUT(lut,fRegionalTrigger.LocalBoardId(i),flut);
890cc210 379 }
380
b0ac3c26 381 //
382 // 1st/2nd cut code pt cut [GeV/c]
383 //
384 // 0 0.5 (a.k.a. Apt)
385 // 1 1.0 (a.k.a. Lpt)
386 // 2 1.7 (a.k.a. Hpt)
387 // 3 4.2 (a.k.a. infinity)
388 // 4 free
389 // .
390 // .
391 // .
392 //15 default (for backward compatibility)
393
394 UChar_t lutCode = 0xFF;
395
396 if (!fread(&lutCode,1,1,flut)) {
397 AliWarning("No LUT info in the file (old version)");
398 }
399 AliInfo(Form("LUT code: 0x%02x",lutCode));
400
890cc210 401 fclose(flut);
b0ac3c26 402
403 lut.SetLutCode(lutCode);
404
890cc210 405 return kTRUE;
406
407}
408
409//_____________________________________________________________________________
2ab3623b 410Bool_t
92c23b09 411AliMUONTriggerIO::ReadConfig(const char* localFile,
11ee2085 412 const char* regionalFile,
413 const char* globalFile,
414 AliMUONVStore* localMasks,
415 AliMUONRegionalTriggerConfig* regionalConfig,
416 AliMUONGlobalCrateConfig* globalConfig)
2ab3623b 417{
418 /// Fill the various masks store from files
419
5a26af27 420 if ( !regionalConfig || !regionalFile || strlen(regionalFile)==0 )
2ab3623b 421 {
422 AliError("Must have a regional file name to proceeed");
423 return kFALSE;
424 }
425
5cf57a25 426 AliDebug(1,Form("regionalConfig=%p",regionalConfig));
427
92c23b09 428 Int_t nCrates = ReadRegionalConfig(regionalFile, regionalConfig);
113ad708 429
5cf57a25 430 if (!nCrates)
431 {
432 AliError("nCrates=0 !");
433 return kFALSE;
434 }
2ab3623b 435
11ee2085 436 if (localMasks && localFile && strlen(localFile) > 0 )
2ab3623b 437 {
438 Int_t nLocal = ReadLocalMasks(localFile,*localMasks);
439 AliDebug(1,Form("Read masks for %d local boards",nLocal));
440 }
441
92c23b09 442 Int_t nDarc = ReadGlobalConfig(globalFile, globalConfig);
5cf57a25 443 AliDebug(1,Form("Read config for %d DARC boards",nDarc));
5dde41b3 444
445 if (!nDarc) return kFALSE;
446
2ab3623b 447 return kTRUE;
448}
449
92c23b09 450
451
2ab3623b 452//_____________________________________________________________________________
5dde41b3 453 Int_t
40a42243 454 AliMUONTriggerIO::ReadGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const
5dde41b3 455{
92c23b09 456 /// read the global crate file
5dde41b3 457 /// the masks are disable bit for each crate, 8 per darc board
458 /// bit value 0 means enable, 1 means disable *
459
460 Int_t nDarc = 0;
92c23b09 461 if ( !(nDarc = globalConfig->ReadData(globalFile)) ) return 0;
5dde41b3 462
463 return nDarc;
464}
465
466//_____________________________________________________________________________
2ab3623b 467Int_t
92c23b09 468AliMUONTriggerIO::ReadRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig)
2ab3623b 469{
92c23b09 470 /// Read regional file to fill
5cf57a25 471
472 AliDebug(1,Form("regionalConfig=%p",regionalConfig));
473
92c23b09 474 Int_t nCrates = 0;
475 if ( !(nCrates = regionalConfig->ReadData(regionalFile)) ) return 0;
acdc80b6 476
92c23b09 477 // read the mapping file also
478 if ( ! fRegionalTrigger.ReadData(regionalFile) ) return 0;
2ab3623b 479
2ab3623b 480 return nCrates;
481}
890cc210 482
92c23b09 483
890cc210 484//_____________________________________________________________________________
485Bool_t
486AliMUONTriggerIO::WriteLUT(const AliMUONTriggerLut& lut,
487 const char* lutFileToWrite)
488{
489 /// Convert an offline lut into an online (binary) lut file
490
491 if ( !NofLocalBoards() )
492 {
493 AliError("No local board id defined. Must read a regional file first");
494 return kFALSE;
495 }
496
497 FILE* flut = fopen(gSystem->ExpandPathName(lutFileToWrite),"wb");
498 if (!flut)
499 {
500 AliError(Form("Could not create output LUT file %s",lutFileToWrite));
501 return kFALSE;
502 }
503
504 for ( Int_t i = 0; i < NofLocalBoards(); ++i )
505 {
630711ed 506 WriteLocalLUT(lut,fRegionalTrigger.LocalBoardId(i),flut);
890cc210 507 }
508
509 fclose(flut);
510
511 return kTRUE;
512}
513
92c23b09 514
890cc210 515//_____________________________________________________________________________
92c23b09 516Bool_t
517AliMUONTriggerIO::WriteConfig(const char* localFile,
5eff9abc 518 const char* regionalFile,
5dde41b3 519 const char* globalFile,
57e2ad1a 520 const AliMUONVStore* localMasks,
92c23b09 521 AliMUONRegionalTriggerConfig* regionalConfig,
522 AliMUONGlobalCrateConfig* globalConfig) const
5eff9abc 523{
92c23b09 524/// write config files
525
5dde41b3 526 Bool_t ok;
79abc6a9 527 ok = WriteLocalMasks(localFile, *localMasks);
92c23b09 528 ok &= WriteRegionalConfig(regionalFile, regionalConfig);
529 ok &= WriteGlobalConfig(globalFile, globalConfig);
5dde41b3 530
531 return ok;
92c23b09 532
533
5dde41b3 534}
5eff9abc 535
92c23b09 536
5dde41b3 537 //_____________________________________________________________________________
538Bool_t
92c23b09 539AliMUONTriggerIO::WriteGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const
5dde41b3 540{
92c23b09 541 /// write global config
5dde41b3 542
543 ofstream out;
544 Int_t disable = 0;
545
546 out.open(globalFile);
547 if (!out.good())
548 {
92c23b09 549 AliError(Form("Could not create output global file %s", globalFile));
5dde41b3 550 return kFALSE;
551 }
552
92c23b09 553 out << globalConfig->GetName() << endl;
41a38dec 554 out << Form("0x%x",globalConfig->GetGlobalCrateEnable()) << endl;
92c23b09 555
5dde41b3 556 // Jtag
92c23b09 557 out << globalConfig->GetJtagName() << endl;
1130977f 558 out << Form("0x%08lx", globalConfig->GetJtagVmeAddr()) << endl;
92c23b09 559 out << Form("%d %d %d", globalConfig->GetJtagClockDiv(),
560 globalConfig->GetJtagRxPhase(), globalConfig->GetJtagRdDelay()) << endl;
5dde41b3 561
92c23b09 562 for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
563 out << Form("%d ", globalConfig->GetEnableJtag(i));
5dde41b3 564 out << endl;
565
566
92c23b09 567 for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
5dde41b3 568 {
569 out << i << endl;
92c23b09 570 for (Int_t j = 0; j < globalConfig->GetJtagNofLines(); ++j)
571 out << Form(" %s", globalConfig->GetJtagCrateName(i,j).Data()) << endl;
5dde41b3 572 }
573
574 // first darc board
92c23b09 575 out << globalConfig->GetFirstDarcName() << endl;
1130977f 576 out << Form("0x%08lx", globalConfig->GetFirstDarcVmeAddr()) << endl;
92c23b09 577 out << globalConfig->GetFirstDarcType() << endl;
578 disable = globalConfig->GetFirstDarcDisable();
5dde41b3 579 out << Form("0x%02x", disable) << endl;
92c23b09 580 out << Form("0x%x", globalConfig->GetFirstDarcL0Delay()) << endl;
581 out << Form("0x%x", globalConfig->GetFirstDarcL1TimeOut()) << endl;
582 out << Form("0x%x", globalConfig->GetFirstDarcGlobalL0()) << endl;
583 out << Form("0x%x", globalConfig->GetFirstDarcConfig()) << endl;
5dde41b3 584
585 // second darc board
92c23b09 586 out << globalConfig->GetSecondDarcName() << endl;
1130977f 587 out << Form("0x%08lx", globalConfig->GetSecondDarcVmeAddr()) << endl;
92c23b09 588 out << globalConfig->GetSecondDarcType() << endl;
589 disable = globalConfig->GetSecondDarcDisable();
5dde41b3 590 out << Form("0x%02x", disable) << endl;
92c23b09 591 out << Form("0x%x", globalConfig->GetSecondDarcL0Delay()) << endl;
592 out << Form("0x%x", globalConfig->GetSecondDarcL1TimeOut()) << endl;
593 out << Form("0x%x", globalConfig->GetSecondDarcGlobalL0()) << endl;
594 out << Form("0x%x", globalConfig->GetSecondDarcConfig()) << endl;
5dde41b3 595
596 // global board
92c23b09 597 out << globalConfig->GetGlobalName() << endl;
1130977f 598 out << Form("0x%08lx", globalConfig->GetGlobalVmeAddr()) << endl;
92c23b09 599 for (Int_t i = 0; i < globalConfig->GetGlobalNofRegisters(); ++i)
600 out << Form("0x%x", globalConfig->GetGlobalRegister(i)) << endl;
5dde41b3 601
602 // Fet board
92c23b09 603 out << globalConfig->GetFetName() << endl;
1130977f 604 out << Form("0x%08lx", globalConfig->GetFetVmeAddr()) << endl;
92c23b09 605 for (Int_t i = 0; i < globalConfig->GetFetNofRegisters(); ++i)
606 out << Form("0x%x", globalConfig->GetFetRegister(i)) << endl;
5dde41b3 607
608 return kTRUE;
5eff9abc 609}
5dde41b3 610
5eff9abc 611//_____________________________________________________________________________
612Bool_t
92c23b09 613AliMUONTriggerIO::WriteRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig) const
5eff9abc 614{
615
616 /// write regional mask with the current configuration
5dde41b3 617 /// if regional masks not defined, take the one from current configuration
5eff9abc 618
619 ofstream out;
620 out.open(regionalFile);
5dde41b3 621
5eff9abc 622 if (!out.good())
623 {
624 AliError(Form("Could not create output regional file %s",regionalFile));
625 return kFALSE;
626 }
627
92c23b09 628 Int_t nCrate = fRegionalTrigger.GetNofTriggerCrates();
629 if (!nCrate)
5eff9abc 630 {
92c23b09 631 AliError("Could not write regional no configuration in memory");
632 return kFALSE;
633 }
41a38dec 634
635 Int_t nofDDLs = 0;
636 TString name;
630711ed 637 AliMpTriggerCrate* crate;
41a38dec 638 for (Int_t ddlId = 0; ddlId < 2; ddlId++) // right & left side
92c23b09 639 {
41a38dec 640 for (Int_t crateId = 0; crateId < 8; crateId++) // 8 crates/regional boards for each side.
641 {
642
643 name = AliMpTriggerCrate::GenerateName(crateId, ddlId, nofDDLs);
644
645 crate = fRegionalTrigger.FindTriggerCrate(name, false);
646
647 AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(crate->GetName());
648 if (!crateConfig)
649 {
650 AliError(Form("Cannot find crate %s in CDB", crate->GetName()));
651 return kFALSE;
652 }
653
654 out << crate->GetName() << endl;
655 out << Form("%02x", crate->GetId()) << endl;
656 out << crateConfig->GetMode() << endl;
657 out << crateConfig->GetCoinc() << endl;
658 out << Form("%04x", crateConfig->GetMask()) << endl;
659 out << Form("%02d",crate->GetNofLocalBoards()) << endl;
660
661 for (Int_t iLocal = 0; iLocal < crate->GetNofLocalBoards(); ++iLocal)
662 {
663 Int_t localBoardId = crate->GetLocalBoardId(iLocal);
664
665 AliMpLocalBoard* board = fRegionalTrigger.FindLocalBoard(localBoardId);
666
667 out << Form("%02d ", board->GetSlot())
668 << board->GetName()
669 << Form(" %03d ", localBoardId)
670 << Form("%03x", board->GetSwitch())
671 << endl;
672
673 out << " ";
674
675 if (board->IsNotified()) {
676 for (Int_t i = 0; i < board->GetNofDEs(); ++i)
677 out << Form("%4d ", board->GetDEId(i));
678 } else {
679 out << Form("%4d ", 0);
680 }
681 out << endl;
682
683 // print copy card numbers & TC
684 out << Form(" %4d %4d", board->GetInputXfrom(), board->GetInputXto());
685 out << Form(" %4d %4d", board->GetInputYfrom(), board->GetInputYto());
686 out << Form(" %4d", board->GetTC()) << endl;
687 }
688 }
92c23b09 689 }
690
5eff9abc 691 out.close();
692
693 return kTRUE;
694}
695
92c23b09 696
5eff9abc 697//_____________________________________________________________________________
698Bool_t
57e2ad1a 699AliMUONTriggerIO::WriteLocalMasks(const char* localFile, const AliMUONVStore& localMasks) const
5eff9abc 700{
701 /// write local mask
702 /// removing/adding enable for a local board need a update of the configuration
703 /// before calling this method
704 /// mask are written for all boards including the copy card (Ch.F.)
705
706 FILE* fp = fopen(gSystem->ExpandPathName(localFile),"wb");
707 if (!fp)
708 {
709 AliError(Form("Could not create output local file %s",localFile));
710 return kFALSE;
711 }
712
713 UShort_t maskBuffer[8];
42a52f7b 714 Int_t localBoardIndex(0);
715 while (localBoardIndex < NofLocalBoards()) {
5eff9abc 716
42a52f7b 717 Int_t localBoardId = fRegionalTrigger.LocalBoardId(localBoardIndex);
5eff9abc 718
42a52f7b 719 AliMUONVCalibParam* localMask =
720 static_cast<AliMUONVCalibParam*>(localMasks.FindObject(localBoardId));
5eff9abc 721
42a52f7b 722 for (Int_t index = 0; index < 8; ++index)
5eff9abc 723 {
42a52f7b 724 maskBuffer[index] = localMask->ValueAsInt(index,0);
5eff9abc 725 }
42a52f7b 726
727 fwrite ( maskBuffer, 2, 8, fp);
728
729 ++localBoardIndex;
5eff9abc 730
5eff9abc 731 }
732
733 fclose(fp);
734
735 return kTRUE;
736
737}
738
739//_____________________________________________________________________________
890cc210 740void
741AliMUONTriggerIO::WriteLocalLUT(const AliMUONTriggerLut& lut,
742 Int_t localBoardId,
743 FILE* flut)
744{
745 /// loop over the address for the 4-bits lpt and hpt decisions
746
747 const Int_t kMaskYpos = 0x0F;
748 const Int_t kMaskYtri = 0x01;
749 const Int_t kMaskXdev = 0x1F;
750 const Int_t kMaskXpos = 0x1F;
97c4e962 751
92c23b09 752 UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
97c4e962 753 Int_t bc = 0;
890cc210 754
92c23b09 755 for (UInt_t i = 0; i < fgkLocalLutSize*2; ++i)
890cc210 756 {
757 Int_t lutLpt[2] = { 0 };
758 Int_t lutHpt[2] = { 0 };
759
760 // decompose address
761 Int_t iYpos = i & kMaskYpos;
762 Int_t iYtri = ( i >> 4 ) & kMaskYtri;
763 Int_t iXdev = ( i >> ( 4 + 1 ) ) & kMaskXdev;
764 Int_t iXpos = ( i >> ( 4 + 1 + 5 ) ) & kMaskXpos;
765
e26b1a52 766 // convert deviation format
767 // online: sign 1bit , dev 4bit
768 // sign dev trigger
769 // 0 1-15 mu-
770 // 1 1-15 mu+
771 // 0 0 mu+, mu- infinite momentum (unde)
772 // 1 0 no x-trigger
773 // offline: dev 5bit
774 // sign dev trigger
775 // - 0-14 mu-
776 // - 16-31 mu+
777 // - 15 mu+, mu- infinite momentum (unde)
778 Int_t iXdevOn = 0;
779 Int_t iXdevOff = 0;
780 Int_t sign = 0;
781 Bool_t trigx = kFALSE;
782 iXdevOn += iXdev & 0x0F;
783 sign += (iXdev >> 4) & 0x01;
784 if (iXdevOn == 0) {
785 if (sign == 0) {
786 iXdevOff = 15;
787 trigx = kTRUE;
788 } else {
789 iXdevOff = 15;
790 trigx = kFALSE;
791 }
792 } else {
793 trigx = kTRUE;
794 if (sign == 0) {
795 iXdevOff = - iXdevOn + 15; // gives range 0-14
796 } else {
797 iXdevOff = + iXdevOn + 15; // gives range 16-30 !
798 }
799 }
800 iXdev = iXdevOff;
801
890cc210 802 // iYtri == 1 means no trigger in y-direction
e26b1a52 803 if (iYtri == 0 && trigx)
890cc210 804 {
805 lut.GetLutOutput(localBoardId,iXpos,iXdev,iYpos,lutLpt,lutHpt);
806 }
807
890cc210 808 // fill byte
809 if (i%2 == 0)
810 {
811 // upper half-byte
97c4e962 812 buffer[bc] = 0;
813 buffer[bc] += lutHpt[1] << 7;
814 buffer[bc] += lutHpt[0] << 6;
815 buffer[bc] += lutLpt[1] << 5;
816 buffer[bc] += lutLpt[0] << 4;
890cc210 817 } else {
818 // lower half-byte
97c4e962 819 buffer[bc] += lutHpt[1] << 3;
820 buffer[bc] += lutHpt[0] << 2;
821 buffer[bc] += lutLpt[1] << 1;
822 buffer[bc] += lutLpt[0] << 0;
823 bc++;
890cc210 824 }
825 }
97c4e962 826 fwrite(&buffer,bc,1,flut);
890cc210 827}
5eff9abc 828
829//_____________________________________________________________________________
acdc80b6 830Int_t
831AliMUONTriggerIO::LocalBoardId(Int_t index) const
832{
833 /// Return the i-th localBoardId, or -1 if index is out of bounds
aed0186b 834
630711ed 835 return fRegionalTrigger.LocalBoardId(index);
aed0186b 836}
113ad708 837
838
839//______________________________________________________________________________
840
841Int_t AliMUONTriggerIO::LocalBoardId(Int_t ddlId, Int_t crateId, Int_t localId) const
842{
843 /// Return local board id from crate and local indexes.
844
845 Int_t nofDDLs = 0;
846 TString name = AliMpTriggerCrate::GenerateName(crateId, ddlId, nofDDLs);
847
848 AliMpTriggerCrate* crate = fRegionalTrigger.FindTriggerCrate(name, false);
849 return crate->GetLocalBoardId(localId);
850}