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