In GetTriggerCrate(): Add protection for DDL number (Christian)
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpDDLStore.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 // $MpId: AliMpDDLStore.cxx,v 1.4 2006/05/24 13:58:34 ivana Exp $
18 // Category: management
19 //
20 // Class AliMpDDLStore
21 // --------------------
22 // The top container class for DDLs, det elements and bus patched
23 // It provides acces to DDL, det element and bus patches objects
24 // via various characteristics.
25 // Authors: Ivana Hrivnacova, IPN Orsay
26 //          Christian Finck, SUBATECH Nantes
27
28 #include "AliMpDDLStore.h"
29 #include "AliMpConstants.h"
30 #include "AliMpDEStore.h"
31 #include "AliMpDDL.h"
32 #include "AliMpFiles.h"
33 #include "AliMpHelper.h"
34 #include "AliMpDEManager.h"
35 #include "AliMpDetElement.h"
36 #include "AliMpBusPatch.h"
37 #include "AliMpTriggerCrate.h"
38 #include "AliMpLocalBoard.h"
39 #include "AliMpSegmentation.h"
40 #include "AliMpVSegmentation.h"
41 #include "AliMpStringObjMap.h"
42 #include "AliLog.h"
43
44 #include <Riostream.h>
45 #include <TList.h>
46 #include <TObjArray.h>
47 #include <TString.h>
48 #include <TObjString.h>
49
50 /// \cond CLASSIMP
51 ClassImp(AliMpDDLStore)
52 /// \endcond
53
54 AliMpDDLStore* AliMpDDLStore::fgInstance = 0;
55 const Int_t    AliMpDDLStore::fgkNofDDLs = 20;
56 const Int_t    AliMpDDLStore::fgkNofTriggerDDLs = 2;
57
58 //
59 // static methods
60 //
61
62 //______________________________________________________________________________
63 AliMpDDLStore* AliMpDDLStore::Instance()
64 {
65 /// Create the DDL store if it does not yet exist
66 /// and return its instance
67
68   if ( ! fgInstance )
69     fgInstance = new AliMpDDLStore();
70     
71   return fgInstance;
72 }    
73
74 //
75 // ctors, dtor
76 //
77
78 //______________________________________________________________________________
79 AliMpDDLStore::AliMpDDLStore()
80 : TObject(),
81   fDDLs(fgkNofDDLs+fgkNofTriggerDDLs), // FIXEME
82   fDetElements(AliMpDEStore::Instance()),
83   fBusPatches(true),
84   fTriggerCrates(true),
85   fLocalBoards(true),
86   fManuList12()
87 {  
88 /// Standard constructor
89
90   AliDebug(1,"");
91   fDDLs.SetOwner(true);
92   fBusPatches.SetOwner(true);
93   fBusPatches.SetSize(900);
94
95   fTriggerCrates.SetOwner(true);
96   fTriggerCrates.SetSize(16);
97
98   fLocalBoards.SetOwner(true);
99   fLocalBoards.SetSize(242); // included non-identied board
100
101   // Create all detection elements
102   ReadDDLs();
103   ReadTriggerDDLs();
104   SetManus();
105   SetPatchModules();
106 }
107
108 //______________________________________________________________________________
109 AliMpDDLStore::AliMpDDLStore(TRootIOCtor* /*ioCtor*/)
110 : TObject(),
111   fDDLs(),
112   fDetElements(0),
113   fBusPatches(),
114   fTriggerCrates(true),
115   fLocalBoards(true)
116 {  
117 /// Constructor for IO
118
119   AliDebug(1,"");
120
121   fgInstance = this;
122 }
123
124
125 //______________________________________________________________________________
126 AliMpDDLStore::~AliMpDDLStore()
127 {
128 /// Destructor
129
130   AliDebug(1,"");
131
132   delete fDetElements;
133
134   // DDL objects are deleted with fDDLs 
135   // Bus patches objects are deleted with fBusPatches 
136   
137   fgInstance = 0;
138 }
139
140 //
141 // private methods
142 //
143
144 //______________________________________________________________________________
145 Int_t  AliMpDDLStore::GetManuListIndex(Int_t detElemId) const
146 {
147 /// Return the index of the manu list for given detElemId
148
149   return AliMpDEManager::GetChamberId(detElemId)*4 + (detElemId % 100);
150 }  
151   
152
153 //______________________________________________________________________________
154 Int_t AliMpDDLStore::GetBusPatchIndex(Int_t detElemId, Int_t manuId) const
155 {
156 /// Calculate the index of the buspatch from manuId
157
158     Int_t pos = 0;
159     AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
160     static Int_t manuMask = AliMpConstants::ManuMask(AliMp::kNonBendingPlane) - 1;
161
162     if( stationType == AliMp::kStation345) {
163       pos = (manuId & manuMask)/100;
164     } else {
165       Int_t idx = GetManuListIndex(detElemId);
166
167       // using array defined from DetElemIdToBusPatch.dat file
168       for (pos = fManuList12[idx].GetSize()-1; pos >= 0; --pos)
169           if ( manuId >= fManuList12[idx].At(pos)) break;
170     }
171
172     return pos;
173 }
174
175
176 //______________________________________________________________________________
177 Bool_t AliMpDDLStore::ReadDDLs()
178 {
179 /// Read ddl <-> bus patch file
180  
181     
182   TString infile = AliMpFiles::BusPatchFilePath();
183
184   ifstream in(infile, ios::in);
185   if (!in) {
186     AliErrorStream() << "Data file " << infile << " not found.";
187     return false;
188   }  
189       
190   char line[255];
191
192   while ( in.getline(line,255) ) {
193
194      if ( line[0] == '#' ) continue;
195
196      TString tmp(AliMpHelper::Normalize(line));
197
198      Int_t blankPos  = tmp.First(' ');
199      Int_t blankPos1 = tmp.Last(' ');
200      Int_t length = 0;
201
202      TString sDE(tmp(0, blankPos));
203
204      Int_t idDE = atoi(sDE.Data());
205
206      // reading 1st manu Id for each bus patch (station 1 & 2)
207      if(AliMpDEManager::GetStationType(idDE) != AliMp::kStation345) {
208
209        TString sManu(tmp(blankPos1 + 1, tmp.Length()-blankPos1));
210        AliMpHelper::DecodeName(sManu,',',fManuList12[GetManuListIndex(idDE)]);
211
212        TString tmp1(tmp(blankPos + 1, blankPos1 -  blankPos));
213        blankPos1 = blankPos + tmp1.First(' ') + 1;
214        length    = tmp.Last(' ') - blankPos1; 
215
216      } else {
217        length = tmp.Length()-blankPos1;
218      }
219
220      TString sDDL(tmp(blankPos1 + 1, length));
221      Int_t  iDDL = atoi(sDDL.Data());
222            
223
224      TString busPatch(tmp(blankPos + 1,blankPos1-blankPos-1));
225      AliDebugStream(3)
226          << "idDE " << idDE << " buspatch " << busPatch.Data() << " iDDL " << iDDL 
227          << endl;
228
229      if ( iDDL < 0 || iDDL >= fgkNofDDLs ) {
230        AliErrorStream() << "DDL id "<< iDDL << " outside limits." << endl;
231        return false;
232      }  
233
234      if ( ! AliMpDEManager::IsValidDetElemId(idDE, false) ) {
235        AliErrorStream() << "DetElemId "<< idDE << " not valid." << endl;
236        return false;
237      }  
238
239      AliMpDDL* ddl = GetDDL(iDDL, false);
240      if ( !ddl) {
241        ddl = new AliMpDDL(iDDL);
242        fDDLs.AddAt(ddl, iDDL);
243      }  
244      ddl->AddDE(idDE);
245      
246      TArrayI busPatchList;
247      // decoding range of buspatch
248      AliMpHelper::DecodeName(busPatch,';',busPatchList);
249      
250      // Update DE
251      AliMpDetElement* de = AliMpDEManager::GetDetElement(idDE);
252      de->SetDdlId(iDDL);
253      // filling buspatch -> idDE
254      for (Int_t i = 0; i < busPatchList.GetSize(); i++) {
255        fBusPatches.Add(busPatchList[i], 
256                        new AliMpBusPatch(busPatchList[i], idDE, iDDL));
257        de->AddBusPatch(busPatchList[i]);
258      }  
259    }
260    
261    // Fill bus patch Ids array in DDLs now
262    for ( Int_t i=0; i<fDDLs.GetEntriesFast(); i++ ) {
263      AliMpDDL* ddl = (AliMpDDL*) fDDLs.At(i);
264      ddl->FillBusPatchIds();
265    }  
266    
267    in.close();
268    return true;
269 }
270
271 //______________________________________________________________________________
272 Bool_t  AliMpDDLStore::ReadTriggerDDLs()
273 {
274 /// create trigger DDL object ddl<->Crate<->local board
275   
276    AliMpStringObjMap inputXfromMap;
277    AliMpStringObjMap inputXtoMap;
278    AliMpStringObjMap inputYfromMap;
279    AliMpStringObjMap inputYtoMap;
280
281     Int_t nonNotified = 0;
282
283     Int_t iDDL = -1;
284
285     TString infile = AliMpFiles::LocalTriggerBoardMapping();
286   
287     ifstream in(infile, ios::in);
288     
289     if (!in) {
290       AliError(Form("Local Trigger Board Mapping File %s not found", infile.Data()));
291       return kFALSE;
292     }
293   
294     AliMpLocalBoard* board = 0x0;
295     AliMpTriggerCrate* crate = 0x0;
296
297     TString localNumber;
298     Int_t localNumberId = 0;
299     TArrayI list;
300
301     char line[255];
302     while (in.getline(line, 255))
303     {
304
305       // files contains lines with some blank caracters ???
306       if (line[0] == ' ' && strlen(line) < 12) continue;
307
308       TString tmp(AliMpHelper::Normalize(line));
309       if (tmp.IsNull()) continue; // Ignore empty lines
310  
311       if (tmp.Contains("Board")) 
312       {
313         // extract id, name, slot & crate name
314         TObjArray* stringList = tmp.Tokenize(TString(" "));
315   
316         TString localNumber = ((TObjString*)stringList->At(1))->GetString();
317
318         if (localNumber.CompareTo("nn") != 0) // Notified cards
319             localNumberId = localNumber.Atoi();
320         else 
321             localNumberId = AliMpConstants::NofLocalBoards()  + (++nonNotified);
322
323         TString localName = ((TObjString*)stringList->At(4))->GetString();
324         TString slotName  = ((TObjString*)stringList->At(10))->GetString();
325
326         AliDebug(3, Form("%d %s %d\n", localNumberId, localName.Data(), slotName.Atoi()));
327
328         board = new AliMpLocalBoard(localNumberId, localName.Data(), slotName.Atoi());
329
330         // not notified board
331         if (localNumber.CompareTo("nn") == 0)
332             board->SetNotified(false);
333
334         // compose name with number and side (Right or Left)
335         TString crateNumber = ((TObjString*)stringList->At(6))->GetString();
336         TString crateSide = ((TObjString*)stringList->At(7))->GetString();
337         TString crateName = crateNumber + crateSide;
338
339         // set crate name
340         board->SetCrate(crateName);
341
342         // determine ddl number vs crate side
343         if (crateName.Contains("R")) 
344             iDDL = fgkNofDDLs; // starts where tracker ends
345         else 
346             iDDL = fgkNofDDLs + 1;
347         
348         AliMpDDL* ddl = GetDDL(iDDL, false);
349         if ( !ddl) {
350           ddl = new AliMpDDL(iDDL);
351           fDDLs.AddAt(ddl, iDDL);
352         }  
353         
354         Int_t crateId; 
355         if (crateNumber.CompareTo("2-3") != 0)
356             crateId = crateNumber.Atoi();
357         else
358             crateId = 23;
359
360         // add trigger crate number for given ddl if not present
361         if ( !ddl->HasTriggerCrateId(crateId) )
362             ddl->AddTriggerCrate(crateId);
363
364         // if crate not existing then creating
365         if (!GetTriggerCrate(crateName, false)) {
366             crate = new AliMpTriggerCrate(crateName.Data(), iDDL);
367             fTriggerCrates.Add(crateName.Data(), crate);
368         }
369
370         // create list of local board in this crate
371         crate->AddLocalBoard(localNumberId);
372
373         delete stringList;
374       }
375
376       if (tmp.Contains("DetElemId")) 
377       {
378         list.Reset();
379         AliMpDDL* ddl = GetDDL(iDDL, true);
380
381         // add  DE for local board and DDL
382         TString detElem = &tmp[tmp.First(" ")+1];
383         AliMpHelper::DecodeName(detElem,' ',list);
384         for (Int_t i = 0; i < list.GetSize(); ++i) {
385             board->AddDE(list[i]);
386             if(!ddl->HasDEId(list[i]))
387                 ddl->AddDE(list[i]);
388         }
389       }
390
391       // map the different copies between cards in X and Y inputs
392       // when copying Xinput, Yinput are copied as well
393       if (tmp.Contains("X3input1")) 
394       {
395         TObjArray* stringList = tmp.Tokenize(TString(" "));
396   
397         TString copyX = ((TObjString*)stringList->At(3))->GetString();
398         TString input = ((TObjString*)stringList->At(2))->GetString();;
399
400         if (copyX.Contains("(1)")) { 
401           inputXfromMap.Add(input, board);
402           inputYfromMap.Add(input, board);
403
404         }
405         if (copyX.Contains("(2)")) {
406           inputXtoMap.Add(input, board);
407           inputYtoMap.Add(input, board);
408         }
409         delete stringList;
410       }
411
412       if (tmp.Contains("Y1input1")) 
413       {
414         TObjArray* stringList = tmp.Tokenize(TString(" "));
415
416         TString copyY = ((TObjString*)stringList->At(3))->GetString();
417         TString input = ((TObjString*)stringList->At(2))->GetString();;
418
419         if (copyY.Contains("(1)")) 
420             inputYfromMap.Add(input, board);
421         if (copyY.Contains("(2)")) 
422             inputYtoMap.Add(input, board);
423         delete stringList;
424       }
425
426
427       if (tmp.Contains("transv")) 
428       {
429         // set transverse connector
430         Int_t blankPos = tmp.Last(' ');
431
432         TString transv(tmp(blankPos+1, tmp.Length()-blankPos));
433         transv.ToUpper();
434         if (transv.CompareTo("NONE") == 0)
435             board->SetTC(false);
436       }
437
438       if (tmp.Contains("Switch")) 
439       {
440         list.Reset();
441         in.getline(line, 255);// skip one line
442
443         in.getline(line, 255);
444         TString tmp(AliMpHelper::Normalize(line));
445
446         // decode switches
447         AliMpHelper::DecodeName(tmp,' ',list);
448
449         // store switches
450         AliMpArrayI switches;
451
452         for (Int_t i = 0; i < list.GetSize(); ++i)
453             board->AddSwitch(list[i]);
454
455         // add local board into map
456         fLocalBoards.Add(board->GetId(), board);
457
458       }
459     }
460     
461     // set copy card number to where the X-Y inputs are copied and
462     // from where the X-Y inputs come.
463     // deleting the first item (TString) done by AliMpStringObjMap itself
464     // keep AliMpLocalBoard object undelete
465
466     TString value;
467
468     for (inputXfromMap.First(); !inputXfromMap.IsDone(); inputXfromMap.Next()) {
469       
470       value = inputXfromMap.CurrentKey();
471       AliMpLocalBoard* boardFrom = (AliMpLocalBoard*)inputXfromMap.CurrentItem();
472       AliMpLocalBoard* boardTo   = (AliMpLocalBoard*)inputXtoMap.Get(value);
473       boardFrom->SetInputXto(boardTo->GetId());
474       boardTo->SetInputXfrom(boardFrom->GetId());
475       AliDebug(3, Form("copy xInputs from local id %d_%s_%d to %d_%s_%d\n", 
476                        boardTo->GetInputXfrom(), boardFrom->GetCrate().Data(), boardFrom->GetSlot(),
477                        boardFrom->GetInputXto(), boardTo->GetCrate().Data(), boardTo->GetSlot()));
478     }
479
480     for (inputYfromMap.First(); !inputYfromMap.IsDone(); inputYfromMap.Next()) {
481
482       value = inputYfromMap.CurrentKey();
483       AliMpLocalBoard* boardFrom = (AliMpLocalBoard*)inputYfromMap.CurrentItem();
484       AliMpLocalBoard* boardTo   = (AliMpLocalBoard*)inputYtoMap.Get(value);
485       boardFrom->SetInputYto(boardTo->GetId());
486       boardTo->SetInputYfrom(boardFrom->GetId());
487       AliDebug(3, Form("copy yInputs from local id %d_%s_%d to %d_%s_%d\n", 
488                        boardTo->GetInputYfrom(), boardFrom->GetCrate().Data(), boardFrom->GetSlot(),
489                        boardFrom->GetInputYto(), boardTo->GetCrate().Data(), boardTo->GetSlot()));
490     }
491
492     return kTRUE;
493 }
494
495 //______________________________________________________________________________
496 Bool_t AliMpDDLStore::SetManus()
497 {
498 /// Set manus for each bus patch
499
500     Int_t manuMask = AliMpConstants::ManuMask(AliMp::kNonBendingPlane) - 1;
501
502     // loop over DDL 
503     for (Int_t iDDL = 0; iDDL < fgkNofDDLs; ++iDDL) {
504
505       AliDebug(3, Form("DDL # %d\n", iDDL));
506
507       AliMpDDL* ddl = GetDDL(iDDL);
508
509       // loop over DE in the given DDL
510       for (Int_t detElemIdx = 0; detElemIdx < ddl->GetNofDEs(); ++detElemIdx) {
511
512         Int_t detElemId = ddl->GetDEId(detElemIdx);
513
514         AliMpDetElement* detElement = GetDetElement(detElemId);
515
516         AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
517
518
519         // list of manu per DE on both cathode
520         TList manuList;
521         for ( Int_t cath = 0; cath < 2 ; ++cath ) {
522           const AliMpVSegmentation* seg 
523               = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
524         
525           AliMp::PlaneType planeType = detElement->GetPlaneType(AliMp::GetCathodType(cath));
526
527           TArrayI manus;
528           seg->GetAllElectronicCardIDs(manus);
529           
530           // filling TList manu
531           for ( Int_t im = 0; im < manus.GetSize(); ++im ) {
532
533             AliMpIntPair* manu = 0x0;
534             if( stationType == AliMp::kStation345) 
535                 manu = new AliMpIntPair((manus[im] & manuMask), planeType, kTRUE); //remove offset for NB
536             else 
537                 manu = new AliMpIntPair(manus[im], planeType, kTRUE); //keep offset for NB
538             
539             manuList.Add(manu);
540           }        
541         }// cathode
542
543         manuList.Sort(); // sort regardless B or NB plane
544
545         // filling manu to the corresponding buspatch
546         for (Int_t iEntry = 0; iEntry < manuList.GetEntries(); ++iEntry) {
547
548           AliMpIntPair* manuPtr = (AliMpIntPair*)manuList.At(iEntry);
549
550           Int_t manuId = manuPtr->GetFirst();
551           Int_t pos    = GetBusPatchIndex(detElemId, manuId);
552
553           if (pos > detElement->GetNofBusPatches()) {
554             AliError(Form("pos greater %d than size %d manuId %d detElemId %d \n", 
555                           pos, detElement->GetNofBusPatches(), manuId, detElemId));
556             return false;
557           }
558           
559           // get buspatch and fill manus
560           Int_t busPatchId = detElement->GetBusPatchId(pos);
561           AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
562
563           if( stationType == AliMp::kStation345) {
564
565             if (manuPtr->GetSecond()) 
566                 busPatch->AddManu(manuId+manuMask+1); // add offset again after sorted
567             else 
568                 busPatch->AddManu(manuId); 
569
570           } else {
571         
572             busPatch->AddManu(manuId); 
573
574           }
575         }
576
577         manuList.Delete();
578
579         if (AliDebugLevel() == 3) {
580
581           // print out for checking
582           for(Int_t pos = 0; pos < detElement->GetNofBusPatches(); ++pos) {
583             Int_t busPatchId = detElement->GetBusPatchId(pos);
584             AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
585             printf("BusPatch: %d\n", busPatch->GetId());
586             for (Int_t iEntry = 0; iEntry < busPatch->GetNofManus(); ++iEntry) 
587                 printf("manu Id: %d\n", busPatch->GetManuId(iEntry));
588           }
589         }
590
591       } // detection element loop
592     }// DDL loop
593
594     return true;
595 }
596
597 //______________________________________________________________________________
598 Bool_t AliMpDDLStore::SetPatchModules()
599 {
600 /// Compute the number of manu per PCB for each buspatch 
601
602   Bool_t result = true;
603
604   for (Int_t i = 0; i < fBusPatches.GetSize(); ++i) {
605     AliMpBusPatch* busPatch = (AliMpBusPatch*)fBusPatches.GetObject(i);
606     Bool_t newResult = busPatch->SetNofManusPerModule();
607     result = result && newResult;
608
609     if (AliDebugLevel() == 3) {
610       // print out for checking
611       printf("\nbus patch %d\n", busPatch->GetId());
612       for (Int_t i = 0; i < busPatch->GetNofPatchModules(); ++i) 
613         printf("manu per %dth pcb %d\n", i, busPatch->GetNofManusPerModule(i));
614     }    
615   }  
616   
617   return result;
618 }
619
620 //________________________________________________________________
621 Int_t AliMpDDLStore::GetLocalBoardId(TString name) const
622 {
623 /// return the first board with a given side and line
624
625    TExMapIter i = fLocalBoards.GetIterator();
626     Long_t key, value;
627     while ( i.Next(key, value) ) {
628       AliMpLocalBoard* local = (AliMpLocalBoard*)value;
629
630       TString tmp(&local->GetName()[4], 2);
631       if (name.Contains(tmp))
632           if (name[0] == local->GetName()[0])
633               return local->GetId();
634     }
635
636     return 0;
637
638 }
639
640 //
641 // public methods
642 //
643
644
645 //______________________________________________________________________________
646 AliMpDDL* AliMpDDLStore::GetDDL(Int_t ddlId, Bool_t warn) const
647 {
648 /// Return DDL for given ddlId
649
650   AliMpDDL* ddl 
651     = (AliMpDDL*)fDDLs.At(ddlId);
652     
653   if ( ! ddl && warn ) {  
654     AliErrorStream() 
655         << "DDL with Id = " << ddlId << " not defined." << endl;
656   }     
657
658   return ddl;
659 }    
660
661 //______________________________________________________________________________
662 AliMpDetElement*  AliMpDDLStore::GetDetElement(Int_t detElemId, Bool_t warn) const
663 {
664 /// Return detection element with given detElemId
665
666   return fDetElements->GetDetElement(detElemId, warn);
667 }  
668
669 //______________________________________________________________________________
670 AliMpBusPatch* AliMpDDLStore::GetBusPatch(Int_t busPatchId, Bool_t warn) const
671 {
672 /// Return bus patch with given Id
673
674   AliMpBusPatch* busPatch
675     = (AliMpBusPatch*) fBusPatches.GetValue(busPatchId);
676     
677   if ( ! busPatch && warn ) {  
678     AliErrorStream() 
679         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
680   }     
681
682   return busPatch;
683 }    
684
685 //______________________________________________________________________________
686 AliMpLocalBoard* AliMpDDLStore::GetLocalBoard(Int_t localBoardId, Bool_t warn) const
687 {
688 /// Return bus patch with given Id
689
690   AliMpLocalBoard* localBoard
691     = (AliMpLocalBoard*) fLocalBoards.GetValue(localBoardId);
692     
693   if ( ! localBoard && warn ) {  
694     AliErrorStream() 
695         << "Local board with Id = " << localBoardId << " not defined." << endl;
696   }     
697
698   return localBoard;
699 }    
700
701 //______________________________________________________________________________
702 AliMpTriggerCrate* AliMpDDLStore::GetTriggerCrate(TString name, Bool_t warn) const
703 {
704 /// Return trigger crate with given name
705
706   AliMpTriggerCrate* crate
707      = (AliMpTriggerCrate*) fTriggerCrates.GetValue(name.Data());
708     
709   if ( ! crate && warn ) {  
710     AliErrorStream() 
711         << "Trigger crate with name = " << name.Data() << " not defined." << endl;
712   }     
713
714   return crate;
715 }  
716
717 //______________________________________________________________________________
718 AliMpTriggerCrate* AliMpDDLStore::GetTriggerCrate(Int_t ddlId, Int_t index, Bool_t warn) const
719 {
720 /// Return trigger crate with given ddl and index crate
721
722   if (ddlId == 0 || ddlId == 1)
723       ddlId += fgkNofDDLs;
724
725   AliMpDDL* ddl = GetDDL(ddlId, warn);
726   if ( ! ddl ) return 0; 
727   
728   if ( index >= ddl->GetNofTriggerCrates() ) {
729       AliError(Form("crate id %d greater than array[%d]", index, ddl->GetNofTriggerCrates()));
730       return 0;
731   }    
732    
733   Int_t crateId = ddl->GetTriggerCrateId(index);
734   TString name = AliMpTriggerCrate::GenerateName(crateId, ddlId, fgkNofDDLs);
735   
736   return GetTriggerCrate(name, warn);
737 }  
738
739 //______________________________________________________________________________
740 Int_t  AliMpDDLStore::GetDEfromBus(Int_t busPatchId) const
741 {
742 /// Return detection element Id for given busPatchId
743
744   AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
745   
746   if ( ! busPatch ) {
747     AliErrorStream() 
748         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
749     return 0;    
750   }     
751
752   return busPatch->GetDEId();
753 }  
754
755 //______________________________________________________________________________
756 Int_t  AliMpDDLStore::GetDEfromLocalBoard(Int_t localBoardId, Int_t chamberId) const
757 {
758 /// Return detElemId for local board Id and chamber id.
759
760   AliMpLocalBoard* localBoard = GetLocalBoard(localBoardId);
761   
762   if ( ! localBoard ) {
763     AliErrorStream() 
764         << "Loacl board with Id = " << localBoardId << " not defined." << endl;
765     return 0;    
766   }     
767
768    return localBoard->GetDEIdByChamber(chamberId);
769 }
770
771 //______________________________________________________________________________
772 Int_t  AliMpDDLStore::GetDDLfromBus(Int_t busPatchId) const
773 {
774 /// Return DDL Id for given busPatchId
775
776   AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
777   
778   if ( ! busPatch ) {
779     AliErrorStream() 
780         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
781     return 0;    
782   }     
783
784   return busPatch->GetDdlId();
785 }  
786
787 //______________________________________________________________________________
788 Int_t AliMpDDLStore::GetBusPatchId(Int_t detElemId, Int_t manuId) const
789 {
790 /// Return bus patch for a given manuId
791
792   AliMpDetElement* detElement = GetDetElement(detElemId);
793   Int_t pos = GetBusPatchIndex(detElemId, manuId);
794
795   if ( pos > detElement->GetNofBusPatches() ) {
796     AliErrorStream() 
797       << "Pos = " << pos 
798       << " greater than the size = " <<  detElement->GetNofBusPatches()
799       << " for detElemId = " << detElemId 
800       << " manuId = " << manuId << endl;
801     return -1;
802   }
803
804   return detElement->GetBusPatchId(pos);
805 }    
806
807 //______________________________________________________________________________
808 AliMpIntPair  AliMpDDLStore::GetDetElemIdManu(Int_t manuSerial) const
809 {
810 /// Return the detElemId and manuId for given serial manu number
811
812   return fDetElements->GetDetElemIdManu(manuSerial);
813 }  
814
815 //______________________________________________________________________________
816 void AliMpDDLStore::PrintAllManu() const
817 {
818 /// Print all manu Ids and their serial numbers sorted by detection element
819 /// and bus patch.                                                            \n
820 /// As serial manu numbers are filled in a different way than manu Ids this
821 /// printing allows to check that both ways are consistent
822
823   // Loop over DE
824   AliMpDEIterator it;
825   for ( it.First(); ! it.IsDone(); it.Next() ) {
826      AliMpDetElement* de = it.CurrentDE();
827      cout << "DE: " << de->GetId() << endl; 
828      
829      // Loop over bus patches in this DE
830      for ( Int_t i=0; i< de->GetNofBusPatches(); ++i ) {
831
832        AliMpBusPatch* busPatch = GetBusPatch(de->GetBusPatchId(i));    
833        cout << "  busPatch: " << busPatch->GetId() << endl; 
834
835        cout << "    Manu       : ";
836        for ( Int_t j=0; j<busPatch->GetNofManus(); ++j ) {
837          cout << std::setw(6) << busPatch->GetManuId(j) << " ";
838        }
839        cout << endl;
840        
841        cout << "    Manu serial: ";
842        for ( Int_t k=0; k<busPatch->GetNofManus(); ++k ) {
843          cout << std::setw(6) << de->GetManuSerialFromId(busPatch->GetManuId(k)) << " ";
844        }        
845        cout << endl;
846      }
847   }
848 }  
849
850 //________________________________________________________________
851 Int_t  AliMpDDLStore::GetNextDEfromLocalBoard(Int_t localBoardId, Int_t chamberId ) const
852 {
853 /// return the next detection element in line
854
855     AliMpLocalBoard* localBoard  =  GetLocalBoard(localBoardId);
856
857     TString name(localBoard->GetName());
858
859     Int_t line = localBoard->GetPosition().GetFirst();
860     ++line;
861     
862     name.Replace(4,1,Form("%d", line));
863
864    Int_t nextLocalId;
865     if ((nextLocalId = GetLocalBoardId(name)))
866         return GetDEfromLocalBoard(nextLocalId, chamberId);
867     else
868         return 0;
869
870     return 0;
871 }
872
873 //________________________________________________________________
874 Int_t  AliMpDDLStore::GetPreviousDEfromLocalBoard(Int_t localBoardId, Int_t chamberId) const
875 {
876 /// return the previous detection element in line
877
878     AliMpLocalBoard* localBoard  =  GetLocalBoard(localBoardId);
879
880     TString name(localBoard->GetName());
881
882     Int_t line = localBoard->GetPosition().GetFirst();
883     --line;
884     
885     name.Replace(4,1,Form("%d", line));
886
887     Int_t prevLocalId;
888     if ((prevLocalId = GetLocalBoardId(name)))
889         return GetDEfromLocalBoard(prevLocalId, chamberId);
890     else
891         return 0;
892
893 }
894