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