]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpDDLStore.cxx
Corrected off-by-one index test errors
[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 DDL 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     delete stringList;
549   }
550   
551   delete &in;
552   
553   return kTRUE;
554 }    
555  
556
557 //______________________________________________________________________________
558 Bool_t AliMpDDLStore::SetPatchModules() 
559 {
560     /// Compute the number of manu per PCB for each buspatch
561
562     AliMpDEIterator it;
563     Bool_t result = true;
564
565     for ( it.First(); !it.IsDone(); it.Next() ) {
566
567         AliMpDetElement* detElement = it.CurrentDE();
568
569         for (Int_t i = 0; i < detElement->GetNofBusPatches(); ++i) {
570             AliMpBusPatch* busPatch = GetBusPatch(detElement->GetBusPatchId(i));
571             Bool_t newResult = false;
572             Int_t idDE = busPatch->GetDEId();
573
574             if (AliMpDEManager::GetStation12Type(idDE) == AliMq::kStation2 )
575                 newResult = busPatch->SetNofManusPerModule(fManuBridge2[GetManuListIndex(idDE)].At(i));
576             else
577                 newResult = busPatch->SetNofManusPerModule();
578         }
579     }
580
581     return result;
582 }
583
584 //______________________________________________________________________________
585 Bool_t AliMpDDLStore::ReadBusPatchInfo() 
586 {
587     /// read the buspatch info file and set buspatch info
588
589     istream& in 
590       = fkDataStreams.
591           CreateDataStream(AliMpFiles::BusPatchInfoFilePath());
592
593     char line[255];
594
595     for (Int_t iDDL = 0; iDDL < fgkNofDDLs; ++iDDL ) {
596         AliMpDDL* ddl = GetDDL(iDDL);
597
598         for (Int_t iBusPatch = 0; iBusPatch < ddl->GetNofBusPatches(); ++iBusPatch) {
599
600             do {
601                 if (!in.getline(line,255)) {
602                     AliWarning(Form("Wrong size in bus patch length file; index %d DDL %d",
603                                     iBusPatch, iDDL));
604                     return false;
605                 }
606             } while(line[0] == '#');
607
608             TString tmp(AliMpHelper::Normalize(line));
609
610             TObjArray* stringList = tmp.Tokenize(TString(" "));
611
612             // Crocus label
613             TString crLabel    = ((TObjString*)stringList->At(0))->GetString();
614             Int_t pos          = crLabel.First('-');
615             tmp                = crLabel(pos-2, crLabel.Length()-pos+2);
616             TArrayI list;
617             AliMpHelper::DecodeName(tmp.Data(), '-', list);
618             
619             Int_t localDDLId  = list[0];
620             Int_t frtId       = list[1] - 1; // begin at zero ! 
621             Int_t localBusId  = list[2];
622
623             // Add FRT number for given ddl if not present
624             if ( !ddl->HasFrtId(frtId) )
625               ddl->AddFrt(frtId);
626
627             // BP & translator label
628             TString label      = ((TObjString*)stringList->At(1))->GetString();
629             TString transLabel = ((TObjString*)stringList->At(2))->GetString();
630
631             // BP length
632             TString sLength    = ((TObjString*)stringList->At(3))->GetString();
633             Float_t length     = sLength.Atof();
634
635             delete stringList;
636                        
637             if (localBusId != iBusPatch + 1)
638                AliWarning(Form("Wrong local buspatch id %d instead of %d", iBusPatch+1, localBusId));
639                
640             if(localDDLId != ddl->GetId()+1)
641                 AliWarning(Form("Wrong local DDL id %d instead of %d", ddl->GetId()+1, localDDLId));
642
643             Int_t busPatchId = ddl->GetBusPatchId(iBusPatch);
644             AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
645             busPatch->SetCableLength(length);
646             busPatch->SetCableLabel(label);
647             busPatch->SetTranslatorLabel(transLabel);
648             busPatch->SetFrtId(frtId);
649
650         }
651     }
652     
653     delete &in;
654
655     return true;
656 }
657
658
659 //________________________________________________________________
660 Int_t AliMpDDLStore::GetLocalBoardId(TString name) const {
661     /// return the first board with a given side and line
662
663   TIter next(fRegionalTrigger.CreateLocalBoardIterator());
664   AliMpLocalBoard* local;
665   
666   while ( ( local = static_cast<AliMpLocalBoard*>(next()) ) )
667   {
668         TString tmp(&local->GetName()[4], 2);
669         if (name.Contains(tmp))
670             if (name[0] == local->GetName()[0])
671                 return local->GetId();
672     }
673
674     return 0;
675 }
676
677 //
678 // public methods
679 //
680
681
682 //______________________________________________________________________________
683 AliMpDDL* AliMpDDLStore::GetDDL(Int_t ddlId, Bool_t warn) const {
684     /// Return DDL for given ddlId
685
686     AliMpDDL* ddl
687     = (AliMpDDL*)fDDLs.At(ddlId);
688
689     if ( ! ddl && warn ) {
690         AliErrorStream()
691         << "DDL with Id = " << ddlId << " not defined." << endl;
692     }
693
694     return ddl;
695 }
696
697 //______________________________________________________________________________
698 AliMpDetElement*  AliMpDDLStore::GetDetElement(Int_t detElemId, Bool_t warn) const {
699     /// Return detection element with given detElemId
700
701     if ( ! AliMpDEStore::Instance() ) {
702         AliFatal("DE Store has not been loaded.");
703         return 0;
704     }
705
706     return AliMpDEStore::Instance()->GetDetElement(detElemId, warn);
707 }
708
709 //______________________________________________________________________________
710 AliMpBusPatch* AliMpDDLStore::GetBusPatch(Int_t busPatchId, Bool_t warn) const {
711     /// Return bus patch with given Id
712
713     AliMpBusPatch* busPatch
714     = (AliMpBusPatch*) fBusPatches.GetValue(busPatchId);
715
716     if ( ! busPatch && warn ) {
717         AliErrorStream()
718         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
719     }
720
721     return busPatch;
722 }
723
724
725 //______________________________________________________________________________
726 AliMpLocalBoard* AliMpDDLStore::GetLocalBoard(Int_t localBoardId, Bool_t warn) const {
727     /// Return bus patch with given Id
728
729     return fRegionalTrigger.FindLocalBoard(localBoardId, warn);
730 }
731
732 //______________________________________________________________________________
733 AliMpTriggerCrate* AliMpDDLStore::GetTriggerCrate(TString name, Bool_t warn) const  {
734     /// Return trigger crate with given name
735
736     return fRegionalTrigger.FindTriggerCrate(name, warn);
737 }
738
739 //______________________________________________________________________________
740 AliMpTriggerCrate* AliMpDDLStore::GetTriggerCrate(Int_t ddlId, Int_t index, Bool_t warn) const  {
741     /// Return trigger crate with given ddl and index crate
742
743     if (ddlId == 0 || ddlId == 1)
744         ddlId += fgkNofDDLs;
745
746     AliMpDDL* ddl = GetDDL(ddlId, warn);
747     if ( ! ddl )
748         return 0;
749
750     if ( index >= ddl->GetNofTriggerCrates() ) {
751         AliError(Form("crate id %d greater than array[%d]", index, ddl->GetNofTriggerCrates()));
752         return 0;
753     }
754
755     TString name = AliMpTriggerCrate::GenerateName(index, ddlId, fgkNofDDLs);
756
757     return GetTriggerCrate(name, warn);
758 }
759
760 //______________________________________________________________________________
761 Int_t  AliMpDDLStore::GetDEfromBus(Int_t busPatchId) const {
762     /// Return detection element Id for given busPatchId
763
764     AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
765
766     if ( ! busPatch ) {
767         AliErrorStream()
768         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
769         return 0;
770     }
771
772     return busPatch->GetDEId();
773 }
774
775 //______________________________________________________________________________
776 Int_t  AliMpDDLStore::GetDEfromLocalBoard(Int_t localBoardId, Int_t chamberId) const {
777     /// Return detElemId for local board Id and chamber id.
778
779     AliMpLocalBoard* localBoard = GetLocalBoard(localBoardId);
780
781     if ( ! localBoard ) {
782         AliErrorStream()
783         << "Loacl board with Id = " << localBoardId << " not defined." << endl;
784         return 0;
785     }
786
787     return localBoard->GetDEIdByChamber(chamberId);
788 }
789
790 //______________________________________________________________________________
791 Int_t  AliMpDDLStore::GetDDLfromBus(Int_t busPatchId) const {
792     /// Return DDL Id for given busPatchId
793
794     AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
795
796     if ( ! busPatch ) {
797         AliErrorStream()
798         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
799         return 0;
800     }
801
802     return busPatch->GetDdlId();
803 }
804
805 //______________________________________________________________________________
806 Int_t AliMpDDLStore::GetBusPatchId(Int_t detElemId, Int_t manuId) const {
807     /// Return bus patch for a given manuId
808
809     AliMpDetElement* detElement = GetDetElement(detElemId);
810     Int_t pos = GetBusPatchIndex(detElemId, manuId);
811
812     if ( pos >= detElement->GetNofBusPatches() ) 
813     {
814         AliErrorStream()
815         << "Pos = " << pos
816         << " greater than the size = " <<  detElement->GetNofBusPatches()
817         << " for detElemId = " << detElemId
818         << " manuId = " << manuId << endl;
819         return -1;
820     }
821
822     return detElement->GetBusPatchId(pos);
823 }
824
825
826 //______________________________________________________________________________
827 Long_t AliMpDDLStore::GetLinkPortId(Int_t busPatchId) const {
828
829     /// Get link port and DSP from busPatch id.
830     /// Return -1 if the value is not valid 
831     /// (the validity has to be tested in the client code)
832
833     AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
834     Int_t ddlId = busPatch->GetDdlId();
835         
836     Int_t localBusPatchId = AliMpBusPatch::GetLocalBusID(busPatchId, ddlId) - 1; // begin at zero
837
838     Int_t pos = (localBusPatchId % AliMpFrtCrocusConstants::GetNofBusPatches()); 
839     
840     return AliMpFrtCrocusConstants::GetLinkPortId(pos);
841
842 }
843
844 //______________________________________________________________________________
845 void AliMpDDLStore::PrintAllManu() const {
846     /// Print all manu Ids and their serial numbers sorted by detection element
847     /// and bus patch.                                                            \n
848     /// As serial manu numbers are filled in a different way than manu Ids this
849     /// printing allows to check that both ways are consistent
850
851     // Loop over DE
852     AliMpDEIterator it;
853     for ( it.First(); ! it.IsDone(); it.Next() ) {
854         AliMpDetElement* de = it.CurrentDE();
855         cout << "DE: " << de->GetId() << endl;
856
857         // Loop over bus patches in this DE
858         for ( Int_t i=0; i< de->GetNofBusPatches(); ++i ) {
859
860             AliMpBusPatch* busPatch = GetBusPatch(de->GetBusPatchId(i));
861             cout << "  busPatch: " << busPatch->GetId() << endl;
862
863             cout << "    Manu       : ";
864             for ( Int_t j=0; j<busPatch->GetNofManus(); ++j ) {
865                 cout << std::setw(6) << busPatch->GetManuId(j) << " ";
866             }
867             cout << endl;
868
869             if ( AliMpManuStore::Instance(kFALSE) ) {
870               cout << "    Manu serial: ";
871               for ( Int_t k=0; k<busPatch->GetNofManus(); ++k ) {
872                 cout << std::setw(6) 
873                      << AliMpManuStore::Instance()
874                         ->GetManuSerial(de->GetId(), busPatch->GetManuId(k)) << " ";
875               }
876               cout << endl;
877             }  
878         }
879     }
880 }
881
882 //______________________________________________________________________________
883 Int_t  AliMpDDLStore::GetNextDEfromLocalBoard(Int_t localBoardId, Int_t chamberId ) const {
884     /// return the next detection element in line
885
886     AliMpLocalBoard* localBoard  =  GetLocalBoard(localBoardId);
887
888     TString name(localBoard->GetName());
889
890     Int_t line = AliMp::PairFirst(localBoard->GetPosition());
891     ++line;
892
893     name.Replace(4,1,Form("%d", line));
894
895     Int_t nextLocalId;
896     if ((nextLocalId = GetLocalBoardId(name)))
897         return GetDEfromLocalBoard(nextLocalId, chamberId);
898     else
899         return 0;
900
901     return 0;
902 }
903
904 //______________________________________________________________________________
905 Int_t  AliMpDDLStore::GetPreviousDEfromLocalBoard(Int_t localBoardId, Int_t chamberId) const {
906     /// return the previous detection element in line
907
908     AliMpLocalBoard* localBoard  =  GetLocalBoard(localBoardId);
909
910     TString name(localBoard->GetName());
911
912     Int_t line = AliMp::PairFirst(localBoard->GetPosition());
913     --line;
914
915     name.Replace(4,1,Form("%d", line));
916
917     Int_t prevLocalId;
918     if ((prevLocalId = GetLocalBoardId(name)))
919         return GetDEfromLocalBoard(prevLocalId, chamberId);
920     else
921         return 0;
922
923 }
924
925 //______________________________________________________________________________
926 void AliMpDDLStore::SetRegionalTrigger(const AliMpRegionalTrigger& regionalTrigger)
927 {
928 /// Replace the existing regional trigger with the given one
929
930   fRegionalTrigger = regionalTrigger;
931   
932   // Remove the existing trigger DDLsf
933   fDDLs.RemoveAt(fgkNofDDLs+1);
934   fDDLs.RemoveAt(fgkNofDDLs);
935   
936   // Set new trigger DDLs from new regional trigger
937   SetTriggerDDLs();
938 }  
939
940
941 //______________________________________________________________________________
942 TIterator* 
943 AliMpDDLStore::CreateBusPatchIterator() const
944 {
945 /// Create the iterator over bus patches
946
947   return fBusPatches.CreateIterator();
948 }