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