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