- Added new functions:
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpDDLStore.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17 // $MpId: AliMpDDLStore.cxx,v 1.4 2006/05/24 13:58:34 ivana Exp $
18 // Category: management
19 //
20 // Class AliMpDDLStore
21 // --------------------
22 // The top container class for DDLs, det elements and bus patched
23 // It provides acces to DDL, det element and bus patches objects
24 // via various characteristics.
25 // Authors: Ivana Hrivnacova, IPN Orsay
26 //          Christian Finck, SUBATECH Nantes
27 #include "AliMpConstants.h"
28 #include "AliMpDDLStore.h"
29 #include "AliMpDEStore.h"
30 #include "AliMpDDL.h"
31 #include "AliMpFiles.h"
32 #include "AliMpHelper.h"
33 #include "AliMpDEManager.h"
34 #include "AliMpDetElement.h"
35 #include "AliMpBusPatch.h"
36 #include "AliMpSegmentation.h"
37 #include "AliMpVSegmentation.h"
38
39 #include "AliLog.h"
40
41 #include <Riostream.h>
42 #include <TList.h>
43
44 /// \cond CLASSIMP
45 ClassImp(AliMpDDLStore)
46 /// \endcond
47
48 AliMpDDLStore* AliMpDDLStore::fgInstance = 0;
49 const Int_t    AliMpDDLStore::fgkNofDDLs = 20;
50
51 //
52 // static methods
53 //
54
55 //______________________________________________________________________________
56 AliMpDDLStore* AliMpDDLStore::Instance()
57 {
58 /// Create the DDL store if it does not yet exist
59 /// and return its instance
60
61   if ( ! fgInstance )
62     fgInstance = new AliMpDDLStore();
63     
64   return fgInstance;
65 }    
66
67 //
68 // ctors, dtor
69 //
70
71 //______________________________________________________________________________
72 AliMpDDLStore::AliMpDDLStore()
73 : TObject(),
74   fDDLs(fgkNofDDLs),
75   fDetElements(AliMpDEStore::Instance()),
76   fBusPatches(true),
77   fManuList12()
78 {  
79 /// Standard constructor
80
81   AliDebug(1,"");
82   fDDLs.SetOwner(true);
83   fBusPatches.SetOwner(true);
84   fBusPatches.SetSize(900);
85
86   // Create all detection elements
87   ReadDDLs();
88   SetManus();
89 }
90
91 //______________________________________________________________________________
92 AliMpDDLStore::AliMpDDLStore(TRootIOCtor* /*ioCtor*/)
93 : TObject(),
94   fDDLs(),
95   fDetElements(0),
96   fBusPatches()
97 {  
98 /// Constructor for IO
99
100   AliDebug(1,"");
101
102   fgInstance = this;
103 }
104
105
106 //______________________________________________________________________________
107 AliMpDDLStore::~AliMpDDLStore()
108 {
109 /// Destructor
110
111   AliDebug(1,"");
112
113   delete fDetElements;
114
115   // DDL objects are deleted with fDDLs 
116   // Bus patches objects are deleted with fBusPatches 
117   
118   fgInstance = 0;
119 }
120
121 //
122 // private methods
123 //
124
125 //______________________________________________________________________________
126 Int_t  AliMpDDLStore::GetManuListIndex(Int_t detElemId) const
127 {
128 /// Return the index of the manu list for given detElemId
129
130   return AliMpDEManager::GetChamberId(detElemId)*4 + (detElemId % 100);
131 }  
132   
133
134 //______________________________________________________________________________
135 Int_t AliMpDDLStore::GetBusPatchIndex(Int_t detElemId, Int_t manuId) const
136 {
137 /// Calculate the index of the buspatch from manuId
138
139     Int_t pos = 0;
140     AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
141     static Int_t manuMask = AliMpConstants::ManuMask(AliMp::kNonBendingPlane) - 1;
142
143     if( stationType == AliMp::kStation345) {
144       pos = (manuId & manuMask)/100;
145     } else {
146       Int_t idx = GetManuListIndex(detElemId);
147
148       // using array defined from DetElemIdToBusPatch.dat file
149       for (pos = fManuList12[idx].GetSize()-1; pos >= 0; --pos)
150           if ( manuId >= fManuList12[idx].At(pos)) break;
151     }
152
153     return pos;
154 }
155
156
157 //______________________________________________________________________________
158 Bool_t AliMpDDLStore::ReadDDLs()
159 {
160 /// Read ddl <-> bus patch file
161  
162     
163   TString infile = AliMpFiles::BusPatchFilePath();
164
165   ifstream in(infile, ios::in);
166   if (!in) {
167     AliErrorStream() << "Data file " << infile << " not found.";
168     return false;
169   }  
170       
171   char line[255];
172
173   while ( in.getline(line,255) ) {
174
175      if ( line[0] == '#' ) continue;
176
177      TString tmp(AliMpHelper::Normalize(line));
178
179      Int_t blankPos  = tmp.First(' ');
180      Int_t blankPos1 = tmp.Last(' ');
181      Int_t length = 0;
182
183      TString sDE(tmp(0, blankPos));
184
185      Int_t idDE = atoi(sDE.Data());
186
187      // reading 1st manu Id for each bus patch (station 1 & 2)
188      if(AliMpDEManager::GetStationType(idDE) != AliMp::kStation345) {
189
190        TString sManu(tmp(blankPos1 + 1, tmp.Length()-blankPos1));
191        AliMpHelper::DecodeName(sManu,',',fManuList12[GetManuListIndex(idDE)]);
192
193        TString tmp1(tmp(blankPos + 1, blankPos1 -  blankPos));
194        blankPos1 = blankPos + tmp1.First(' ') + 1;
195        length    = tmp.Last(' ') - blankPos1; 
196
197      } else {
198        length = tmp.Length()-blankPos1;
199      }
200
201      TString sDDL(tmp(blankPos1 + 1, length));
202      Int_t  iDDL = atoi(sDDL.Data());
203            
204
205      TString busPatch(tmp(blankPos + 1,blankPos1-blankPos-1));
206      AliDebugStream(3)
207          << "idDE " << idDE << " buspatch " << busPatch.Data() << " iDDL " << iDDL 
208          << endl;
209
210      if ( iDDL < 0 || iDDL >= fgkNofDDLs ) {
211        AliErrorStream() << "DDL id "<< iDDL << " outside limits." << endl;
212        return false;
213      }  
214
215      if ( ! AliMpDEManager::IsValidDetElemId(idDE, false) ) {
216        AliErrorStream() << "DetElemId "<< idDE << " not valid." << endl;
217        return false;
218      }  
219
220      AliMpDDL* ddl = GetDDL(iDDL, false);
221      if ( !ddl) {
222        ddl = new AliMpDDL(iDDL);
223        fDDLs.AddAt(ddl, iDDL);
224      }  
225      ddl->AddDE(idDE);
226      
227      TArrayI busPatchList;
228      // decoding range of buspatch
229      AliMpHelper::DecodeName(busPatch,';',busPatchList);
230      
231      // Update DE
232      AliMpDetElement* de = AliMpDEManager::GetDetElement(idDE);
233      de->SetDdlId(iDDL);
234      // filling buspatch -> idDE
235      for (Int_t i = 0; i < busPatchList.GetSize(); i++) {
236        fBusPatches.Add(busPatchList[i], 
237                        new AliMpBusPatch(busPatchList[i], idDE, iDDL));
238        de->AddBusPatch(busPatchList[i]);
239      }  
240    }
241    
242    // Fill bus patch Ids array in DDLs now
243    for ( Int_t i=0; i<fDDLs.GetEntriesFast(); i++ ) {
244      AliMpDDL* ddl = (AliMpDDL*) fDDLs.At(i);
245      ddl->FillBusPatchIds();
246    }  
247    
248    in.close();
249    return true;
250 }
251 //______________________________________________________________________________
252 Bool_t AliMpDDLStore::SetManus()
253 {
254 /// Set manus for each bus patch
255
256     Int_t manuMask = AliMpConstants::ManuMask(AliMp::kNonBendingPlane) - 1;
257
258     // loop over DDL 
259     for (Int_t iDDL = 0; iDDL < fgkNofDDLs; ++iDDL) {
260
261       AliDebug(3, Form("DDL # %d\n", iDDL));
262
263       AliMpDDL* ddl = GetDDL(iDDL);
264
265       // loop over DE in the given DDL
266       for (Int_t detElemIdx = 0; detElemIdx < ddl->GetNofDEs(); ++detElemIdx) {
267
268         Int_t detElemId = ddl->GetDEId(detElemIdx);
269
270         AliMpDetElement* detElement = GetDetElement(detElemId);
271
272         AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
273
274
275         // list of manu per DE on both cathode
276         TList manuList;
277         for ( Int_t cath = 0; cath < 2 ; ++cath ) {
278           const AliMpVSegmentation* seg 
279               = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
280         
281           AliMp::PlaneType planeType = detElement->GetPlaneType(AliMp::GetCathodType(cath));
282
283           TArrayI manus;
284           seg->GetAllElectronicCardIDs(manus);
285           
286           // filling TList manu
287           for ( Int_t im = 0; im < manus.GetSize(); ++im ) {
288
289             AliMpIntPair* manu = 0x0;
290             if( stationType == AliMp::kStation345) 
291                 manu = new AliMpIntPair((manus[im] & manuMask), planeType, kTRUE); //remove offset for NB
292             else 
293                 manu = new AliMpIntPair(manus[im], planeType, kTRUE); //keep offset for NB
294             
295             manuList.Add(manu);
296           }        
297         }// cathode
298
299         manuList.Sort(); // sort regardless B or NB plane
300
301         // filling manu to the corresponding buspatch
302         for (Int_t iEntry = 0; iEntry < manuList.GetEntries(); ++iEntry) {
303
304           AliMpIntPair* manuPtr = (AliMpIntPair*)manuList.At(iEntry);
305
306           Int_t manuId = manuPtr->GetFirst();
307           Int_t pos    = GetBusPatchIndex(detElemId, manuId);
308
309           if (pos > detElement->GetNofBusPatches()) {
310             AliError(Form("pos greater %d than size %d manuId %d detElemId %d \n", 
311                           pos, detElement->GetNofBusPatches(), manuId, detElemId));
312             return false;
313           }
314           
315           // get buspatch and fill manus
316           Int_t busPatchId = detElement->GetBusPatchId(pos);
317           AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
318
319           if( stationType == AliMp::kStation345) {
320
321             if (manuPtr->GetSecond()) 
322                 busPatch->AddManu(manuId+manuMask+1); // add offset again after sorted
323             else 
324                 busPatch->AddManu(manuId); 
325
326           } else {
327         
328             busPatch->AddManu(manuId); 
329
330           }
331         }
332
333         manuList.Delete();
334
335         if (AliDebugLevel() == 3) {
336
337           // print out for checking
338           for(Int_t pos = 0; pos < detElement->GetNofBusPatches(); ++pos) {
339             Int_t busPatchId = detElement->GetBusPatchId(pos);
340             AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
341             printf("BusPatch: %d\n", busPatch->GetId());
342             for (Int_t iEntry = 0; iEntry < busPatch->GetNofManus(); ++iEntry) 
343                 printf("manu Id: %d\n", busPatch->GetManuId(iEntry));
344           }
345         }
346
347       } // detection element loop
348     }// DDL loop
349
350     return true;
351 }
352
353 //
354 // public methods
355 //
356
357
358 //______________________________________________________________________________
359 AliMpDDL* AliMpDDLStore::GetDDL(Int_t ddlId, Bool_t warn) const
360 {
361 /// Return DDL for given ddlId
362
363   AliMpDDL* ddl 
364     = (AliMpDDL*)fDDLs.At(ddlId);
365     
366   if ( ! ddl && warn ) {  
367     AliErrorStream() 
368         << "DDL with Id = " << ddlId << " not defined." << endl;
369   }     
370
371   return ddl;
372 }    
373
374 //______________________________________________________________________________
375 AliMpDetElement*  AliMpDDLStore::GetDetElement(Int_t detElemId, Bool_t warn) const
376 {
377 /// Return detection element with given detElemId
378
379   return fDetElements->GetDetElement(detElemId, warn);
380 }  
381
382 //______________________________________________________________________________
383 AliMpBusPatch* AliMpDDLStore::GetBusPatch(Int_t busPatchId, Bool_t warn) const
384 {
385 /// Return bus patch with given Id
386
387   AliMpBusPatch* busPatch
388     = (AliMpBusPatch*) fBusPatches.GetValue(busPatchId);
389     
390   if ( ! busPatch && warn ) {  
391     AliErrorStream() 
392         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
393   }     
394
395   return busPatch;
396 }    
397
398 //______________________________________________________________________________
399 Int_t  AliMpDDLStore::GetDEfromBus(Int_t busPatchId) const
400 {
401 /// Return detection element Id for given busPatchId
402
403   AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
404   
405   if ( ! busPatch ) {
406     AliErrorStream() 
407         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
408     return 0;    
409   }     
410
411   return busPatch->GetDEId();
412 }  
413
414 //______________________________________________________________________________
415 Int_t  AliMpDDLStore::GetDDLfromBus(Int_t busPatchId) const
416 {
417 /// Return DDL Id for given busPatchId
418
419   AliMpBusPatch* busPatch = GetBusPatch(busPatchId);
420   
421   if ( ! busPatch ) {
422     AliErrorStream() 
423         << "Bus patch with Id = " << busPatchId << " not defined." << endl;
424     return 0;    
425   }     
426
427   return busPatch->GetDdlId();
428 }  
429
430 //______________________________________________________________________________
431 Int_t AliMpDDLStore::GetBusPatchId(Int_t detElemId, Int_t manuId) const
432 {
433 /// Return bus patch for a given manuId
434
435   AliMpDetElement* detElement = GetDetElement(detElemId);
436   Int_t pos = GetBusPatchIndex(detElemId, manuId);
437
438   if ( pos > detElement->GetNofBusPatches() ) {
439     AliErrorStream() 
440       << "Pos = " << pos 
441       << " greater than the size = " <<  detElement->GetNofBusPatches()
442       << " for detElemId = " << detElemId 
443       << " manuId = " << manuId << endl;
444     return -1;
445   }
446
447   return detElement->GetBusPatchId(pos);
448 }    
449
450 //______________________________________________________________________________
451 AliMpIntPair  AliMpDDLStore::GetDetElemIdManu(Int_t manuSerial) const
452 {
453 /// Return the detElemId and manuId for given serial manu number
454
455   return fDetElements->GetDetElemIdManu(manuSerial);
456 }