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