]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpTriggerReader.cxx
Updated comments for Doxygen - corrected warnings
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpTriggerReader.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 purpeateose. It is      *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 // $Id$
17 // $MpId: AliMpTriggerReader.cxx,v 1.4 2006/05/24 13:58:52 ivana Exp $
18
19 #include "AliMpTriggerReader.h"
20 #include "AliMpMotifReader.h"
21 #include "AliMpFiles.h"
22 #include "AliMpMotifType.h"
23 #include "AliMpPCB.h"
24 #include "AliMpSlat.h"
25 #include "AliMpMotifMap.h"
26 #include "AliMpMotifPosition.h"
27 #include "AliMpMotif.h"
28 #include "AliMpHelper.h"
29 #include "AliMpSt345Reader.h"
30 #include "AliMpTrigger.h"
31
32 #include "AliLog.h"
33
34 #include "Riostream.h"
35 #include "TClass.h"
36 #include "TObjString.h"
37 #include "TList.h"
38 #include "TString.h"
39
40 #include <sstream>
41 #include <cassert>
42
43 /// 
44 /// \class AliMpTriggerReader
45 /// Read trigger slat ASCII files
46 /// Basically provides 2 static methods:
47 /// - AliMpTrigger* ReadSlat()
48 /// - AliMpPCB* ReadPCB()
49 ///
50 /// \author Laurent Aphecetche
51
52 /// \cond CLASSIMP
53 ClassImp(AliMpTriggerReader)
54 /// \endcond
55
56 TMap AliMpTriggerReader::fgPCBMap;
57 TMap AliMpTriggerReader::fgLocalBoardMap;
58
59 const TString AliMpTriggerReader::fgkKeywordLayer("LAYER");
60 const TString AliMpTriggerReader::fgkKeywordScale("SCALE");
61 const TString AliMpTriggerReader::fgkKeywordPcb("PCB");  
62 const TString AliMpTriggerReader::fgkKeywordFlipX("FLIP_X");
63 const TString AliMpTriggerReader::fgkKeywordFlipY("FLIP_Y");
64
65 //_____________________________________________________________________________
66 AliMpTriggerReader::AliMpTriggerReader() : TObject()
67 {
68   //
69   // Default ctor.
70   //
71
72
73 //_____________________________________________________________________________
74 AliMpTriggerReader::~AliMpTriggerReader()
75 {
76   //
77   // Dtor.
78   //
79   fgPCBMap.Delete();
80   fgLocalBoardMap.Delete();
81 }
82
83 //_____________________________________________________________________________
84 AliMpSlat*
85 AliMpTriggerReader::BuildSlat(const char* slatName,
86                               AliMpPlaneType planeType,
87                               const TList& lines,
88                               Double_t scale)
89 {
90   // Construct a slat from the list of lines, taking into account
91   // the scale factor
92
93   AliMpSlat* slat = new AliMpSlat(slatName, planeType);
94     
95   TIter it(&lines);
96   TObjString* osline;
97   while ( ( osline = (TObjString*)it.Next() ) )
98   {
99     // note that at this stage lines should not be empty.
100     TString sline(osline->String());
101     
102     TObjArray* tokens = sline.Tokenize(' ');
103     
104     TString& keyword = ((TObjString*)tokens->At(0))->String();
105     
106     if ( keyword == fgkKeywordPcb )
107     {
108       if ( tokens->GetEntriesFast() != 3 )
109       {
110         AliErrorClass(Form("Syntax error : expecting PCB type localboard-list"
111                            " in following line:\n%s",sline.Data()));
112         delete slat;
113         delete tokens;
114         return 0;
115       }
116       TString pcbName = ((TObjString*)tokens->At(1))->String();
117       
118       TObjArray* localBoardList = ((TObjString*)tokens->At(2))->String().Tokenize(',');
119       
120       if ( scale != 1.0 )
121       {
122         std::ostringstream s;
123         s << pcbName.Data() << "x" << scale;
124         pcbName = s.str().c_str();
125       }
126       
127       AliMpPCB* pcbType = PCB(pcbName.Data());    
128       if (!pcbType)
129       {
130         AliErrorClass(Form("Cannot read pcbType=%s",pcbName.Data()));
131         delete slat;
132         return 0;
133       }      
134
135       TArrayI allLocalBoards;
136       
137       for ( Int_t ilb = 0; ilb < localBoardList->GetEntriesFast(); ++ilb)
138       {
139         TArrayI localBoardNumbers;
140         TString& localBoards = ((TObjString*)localBoardList->At(ilb))->String();
141         Ssiz_t pos = localBoards.First('-');
142         if ( pos < 0 ) 
143         {
144           pos = localBoards.Length();
145         }
146         AliMpHelper::DecodeName(localBoards(pos-1,localBoards.Length()-pos+1).Data(),
147                                 ';',localBoardNumbers);      
148         for ( int i = 0; i < localBoardNumbers.GetSize(); ++i )
149         {
150           std::ostringstream name;
151           name << localBoards(0,pos-1) << localBoardNumbers[i];
152           AliDebugClass(3,name.str().c_str());
153           localBoardNumbers[i] = LocalBoardNumber(name.str().c_str());
154           AliDebugClass(3,Form("LOCALBOARDNUMBER %d\n",localBoardNumbers[i]));
155           allLocalBoards.Set(allLocalBoards.GetSize()+1);
156           allLocalBoards[allLocalBoards.GetSize()-1] = localBoardNumbers[i];
157           if (localBoardNumbers[i] < 0 )
158           {
159             AliErrorClass(Form("Got a negative local board number in %s ? Unlikely"
160                                " to be correct... : %s\n",slatName,name.str().c_str()));
161           }
162         }
163       }
164       delete tokens;
165       delete localBoardList;
166       slat->Add(pcbType,allLocalBoards);
167     }
168   }
169   
170   if ( slat->DX()== 0 || slat->DY() == 0 )
171   {
172     AliFatalClass(Form("Slat %s has invalid null size\n",slat->GetID()));
173   }
174   return slat;
175 }
176
177 //_____________________________________________________________________________
178 TString
179 AliMpTriggerReader::GetBoardNameFromPCBLine(const TString& s)
180 {
181   // Decode the string to get the board name
182   TString boardName;
183   
184   TObjArray* tokens = s.Tokenize(' ');
185   
186   TString& keyword = ((TObjString*)tokens->At(0))->String();
187
188   if ( keyword == fgkKeywordPcb &&
189        tokens->GetEntriesFast() == 3 )
190   {
191     boardName = ((TObjString*)tokens->At(2))->String();
192   }
193   
194   delete tokens;
195   
196   return boardName;
197 }
198   
199 //_____________________________________________________________________________
200 void
201 AliMpTriggerReader::FlipLines(TList& lines, Bool_t flipX, Bool_t flipY,
202                               Int_t srcLine, Int_t destLine)
203 {
204   //
205   // Change the local board names contained in lines, 
206   // to go from right to left, and/or
207   // from top to bottom
208   //
209  
210
211   if ( flipX )
212   {
213     // Simply swaps R(ight) and L(eft) in the first character of 
214     // local board names
215
216     TObjString* oline;
217     TIter it(&lines);
218     while ( ( oline = (TObjString*)it.Next() ) )
219     {
220       TString& s = oline->String();
221       if ( s.Contains("RC") ) 
222       {
223         // Change right to left
224         s.ReplaceAll("RC","LC");
225       }
226       else if ( s.Contains("LC") )
227       {
228         // Change left to right
229         s.ReplaceAll("LC","RC");
230       }
231     }
232   }
233   
234   if ( flipY )
235   {
236     // Change line number, according to parameters srcLine and destLine
237     // Note that because of road opening (for planes 3 and 4 at least),
238     // we loop for srcLine +-1
239     //
240     for ( Int_t line = -1; line <=1; ++line )
241     {
242       std::ostringstream src,dest;
243       src << "L" << srcLine+line;
244       dest << "L" << destLine-line;
245       if ( src.str() == dest.str() ) continue;
246       
247       for ( Int_t i = 0; i < lines.GetSize(); ++i )
248       {
249         TObjString* oline = (TObjString*)lines.At(i);
250         
251         TString& s = oline->String();
252         
253         if ( !s.Contains(fgkKeywordPcb) )
254         {
255           // Only consider PCB lines.
256           continue;
257         }
258         
259         if ( s.Contains(src.str().c_str()) )
260         {
261           AliDebugClass(4,Form("Replacing %s by %s in %s\n",
262                                src.str().c_str(),dest.str().c_str(),s.Data()));
263           
264           s.ReplaceAll(src.str().c_str(),dest.str().c_str());
265           
266           AliDebugClass(4,s.Data());
267           
268           TString boardName(GetBoardNameFromPCBLine(s));
269           
270           if ( line )
271           {
272             // We must also change board numbers, with the tricky
273             // thing that up and down must be swapped...
274             // Up can only be 1 card so it must be B1
275             // Down must be the uppper card of the line before, so
276             // the biggest possible board number for this Line,Column
277             
278             if (line>0)
279             {
280                 // force to B1
281               AliDebugClass(4,Form("Forcing B1 in %s\n",s.Data()));
282               s.ReplaceAll(boardName(boardName.Length()-2,2),"B1");
283               AliDebugClass(4,s.Data());
284             }
285             else
286             {
287               // find the largest valid board number
288               for ( int b = 4; b>=1; --b )
289               {
290                 std::ostringstream bs;
291                 bs << boardName(0,boardName.Length()-1) << b;
292                 if ( LocalBoardNumber(bs.str().c_str()) >= 0 )
293                 {
294                   AliDebugClass(4,Form("Replacing %s by %s in %s\n",
295                                   boardName(boardName.Length()-2,2).Data(),
296                                   Form("B%d",b),
297                                   s.Data()));
298                   s.ReplaceAll(boardName(boardName.Length()-2,2),
299                                Form("B%d",b));
300                   AliDebugClass(4,s);
301                   break;
302                 }
303               }
304             }  
305             // Check that the replacement we did is ok. If not,
306             // skip the line.
307             Int_t lbn = LocalBoardNumber(GetBoardNameFromPCBLine(s));
308             if ( lbn < 0 )
309             {
310               AliDebugClass(4,Form("Removing line %s\n",s.Data()));
311               lines.Remove(oline);
312             }
313             
314           } // if (line)          
315         }
316       }    
317     }
318   }
319 }
320
321 //___________________________________________________________________________
322 Int_t
323 AliMpTriggerReader::IsLayerLine(const TString& sline)
324 {
325   // Whether sline contains LAYER keyword
326
327   if ( sline.BeginsWith(fgkKeywordLayer) )
328   {
329     return 1;
330   }
331   else
332   {
333     return 0;
334   }
335 }
336
337 //___________________________________________________________________________
338 Int_t
339 AliMpTriggerReader::DecodeFlipLine(const TString& sline,
340                                    TString& slatType2,
341                                    Bool_t& flipX, Bool_t& flipY)
342 {
343   // Decode a line containing FLIP_X and/or FLIP_Y keywords
344
345   Ssiz_t blankPos = sline.First(' ');
346   if ( blankPos < 0 ) return 0;
347   
348   TString keyword(sline(0,blankPos));
349   
350   if ( keyword == fgkKeywordFlipX )
351   {
352     flipX = kTRUE;
353   } else if ( keyword == fgkKeywordFlipY )
354   {
355     flipY = kTRUE;
356   }
357   else
358   {
359     return 0;
360   }
361   
362   slatType2 = sline(blankPos+1,sline.Length()-blankPos-1);
363   return 1;
364 }
365
366 //___________________________________________________________________________
367 Int_t
368 AliMpTriggerReader::DecodeScaleLine(const TString& sline, 
369                                     Double_t& scale, TString& slatType)
370 {
371   // Decode sline containing SCALE keyword
372
373   if ( sline(0,fgkKeywordScale.Length()) == fgkKeywordScale )
374   {
375     TString tmp(sline(fgkKeywordScale.Length()+1,
376                       sline.Length()-fgkKeywordScale.Length()-1));
377     Ssiz_t blankPos = tmp.First(' ');
378     if ( blankPos < 0 )
379     {
380       AliErrorClass(Form("Syntax error in slat file, should get a slatType after "
381                     " SCALE keyword : %s\n",tmp.Data()));
382       return -1;
383     }
384     else
385     {
386       slatType = tmp(0,blankPos);
387       scale = TString(tmp(blankPos+1,tmp.Length()-blankPos-1)).Atof();
388       return 1;
389     }
390   }
391   scale = 1.0;
392   return 0;
393 }
394
395 //_____________________________________________________________________________
396 Int_t
397 AliMpTriggerReader::GetLine(const TString& slatType)
398 {
399   //
400   // Assuming slatType is a 4 character string of the form XSLN
401   // where X=1,2,3 or 4
402   // S = R or L
403   // N is the line number
404   // returns N
405   if ( isdigit(slatType[0]) && 
406        ( slatType[1] == 'R' || slatType[1] == 'L' ) &&
407        slatType[2] == 'L' )
408   {
409     return atoi(slatType(3,1).Data());
410   }
411   return -1;
412 }
413
414 //_____________________________________________________________________________
415 int
416 AliMpTriggerReader::LocalBoardNumber(const char* localBoardName)
417 {
418   // From local board name to local board number
419
420   if ( !fgLocalBoardMap.GetSize() ) 
421   {
422     ReadLocalBoardMapping();
423   }
424   
425   TPair* pair = (TPair*)fgLocalBoardMap.FindObject(localBoardName);
426   
427   if (pair)
428   {
429     return atoi(((TObjString*)pair->Value())->String().Data());
430   }
431   return -1;
432 }
433
434 //_____________________________________________________________________________
435 AliMpPCB*
436 AliMpTriggerReader::PCB(const char* pcbType)
437 {
438   //
439   // Get access to an AliMpPCB object, given its type (e.g. N1, SB2, etc...)
440   //
441   // Note that the returned object is either a new one (read from file) or a 
442   // reused one if it is already present in the internal map.
443   //
444   
445   TPair* pair = (TPair*)fgPCBMap.FindObject(pcbType);
446   if ( pair )
447   {
448     AliDebugClass(1,Form("Getting pcb %s from internal map",pcbType));
449     return (AliMpPCB*)pair->Value();
450   }
451   else
452   {
453     AliDebugClass(1,Form("Reading pcb %s from file",pcbType));
454     return ReadPCB(pcbType);
455   }
456 }
457
458 //_____________________________________________________________________________
459 void 
460 AliMpTriggerReader::ReadLines(const char* slatType,
461                               AliMpPlaneType planeType,
462                               TList& lines,
463                               Double_t& scale,
464                               Bool_t& flipX, Bool_t& flipY,
465                               Int_t& srcLine, Int_t& destLine)
466 {
467   //
468   // Reads in lines from file for a given slat
469   // Returns the list of lines (lines), together with some global
470   // information as the scale, whether to flip the lines, etc...
471   //
472   AliDebugClass(1,Form("SlatType %s Scale %e FlipX %d FlipY %d srcLine %d"
473                        " destLine %d\n",slatType,scale,flipX,flipY,
474                        srcLine,destLine));
475   
476   TString filename(AliMpFiles::SlatFilePath(kStationTrigger,slatType,
477                                             planeType).Data());
478   std::ifstream in(filename.Data());
479   if (!in.good()) 
480   {
481     AliErrorClass(Form("Cannot read slat from %s",filename.Data()));
482   }
483   
484   char line[80];
485   
486   while ( in.getline(line,80) )
487   {
488     TString sline(AliMpHelper::Normalize(line));
489
490     if ( sline.Length() == 0 || sline[0] == '#' ) continue;
491     
492     Bool_t isKeywordThere = 
493       sline.Contains(fgkKeywordPcb) || 
494       sline.Contains(fgkKeywordLayer) ||
495       sline.Contains(fgkKeywordScale) || 
496       sline.Contains(fgkKeywordFlipX) || 
497       sline.Contains(fgkKeywordFlipY);
498     
499     if ( !isKeywordThere ) 
500     {
501       AliErrorClass(Form("Got a line with no keyword : %s."
502                          "That's not valid\n",line));
503       continue; 
504     }
505     
506     Double_t scale2;
507     TString slatType2;
508     
509     Int_t isScaleLine = DecodeScaleLine(sline,scale2,slatType2);
510     
511     scale *= scale2;
512
513     if ( isScaleLine < 0 )
514     {
515       AliFatalClass(Form("Syntax error near %s keyword\n",fgkKeywordScale.Data()));
516     }
517     else if ( isScaleLine > 0 && slatType2 != slatType )
518     {
519       ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
520     }
521     else    
522     {
523       Bool_t fx(kFALSE);
524       Bool_t fy(kFALSE);
525       Int_t isFlipLine = DecodeFlipLine(sline,slatType2,fx,fy);
526       if ( isFlipLine )
527       {
528         if (fy)
529         {
530           srcLine = GetLine(slatType2);
531           destLine = GetLine(slatType);
532         }
533         flipX |= fx;
534         flipY |= fy;
535         ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
536       }
537       else
538       {
539         lines.Add(new TObjString(sline.Data()));
540       }
541     }
542   }
543   
544   in.close();
545 }
546                                         
547 //_____________________________________________________________________________
548 void
549 AliMpTriggerReader::ReadLocalBoardMapping()
550 {
551   // Reads the file that contains the mapping local board name <-> number
552
553   TString filename(AliMpFiles::LocalTriggerBoardMapping());
554   
555   AliDebugClass(1,Form("Reading from %s\n",filename.Data()));
556
557   fgLocalBoardMap.Delete();
558   
559   ifstream in(filename.Data());
560   if (!in.good())
561   {
562     AliErrorClass(Form("Cannot read file %s\n",filename.Data()));    
563   }
564   else
565   {
566     char line[80];
567     
568     while ( in.getline(line,80) )
569     {
570       if ( line[0] == '#' ) continue;
571       
572       TString sline(line);
573       if ( sline.Contains("Board") )
574       {
575         TObjArray* tokens = sline.Tokenize(' ');
576         TString& number = ((TObjString*)(tokens->At(1)))->String();
577         Int_t n = atoi(number.Data());
578         if ( n == 0 ) continue;
579         TString& name = ((TObjString*)(tokens->At(4)))->String();
580         fgLocalBoardMap.Add(new TObjString(name), new TObjString(number));
581         AliDebugClass(10,Form("Board %s has number %s\n",name.Data(),number.Data()));
582         delete tokens;
583       }
584     }      
585   }
586   in.close();
587 }
588
589 //_____________________________________________________________________________
590 AliMpPCB*
591 AliMpTriggerReader::ReadPCB(const char* pcbType)
592
593   //
594   // Create a new AliMpPCB object, by reading it from file.
595   //
596   
597   AliDebugClass(1,Form("pcbType=%s\n",pcbType));
598   
599   TString pcbName(pcbType);
600   
601   Ssiz_t pos = pcbName.First('x');
602
603   Double_t scale = 1.0;
604   
605   if ( pos > 0 )
606   {
607     scale = TString(pcbName(pos+1,pcbName.Length()-pos-1)).Atof();
608     pcbName = pcbName(0,pos);
609   }
610   
611   std::ifstream in(AliMpFiles::SlatPCBFilePath(kStationTrigger,pcbName).Data());
612   if (!in.good()) 
613   {
614     AliErrorClass(Form("Cannot open file for PCB %s",pcbName.Data()));
615     return 0;
616   }
617  
618   AliMpMotifReader reader(kStationTrigger,kNonBendingPlane); 
619   // note that the nonbending
620   // parameter is of no use for trigger, as far as reading motif is 
621   // concerned, as all motifs are supposed to be in the same directory
622   // (as they are shared by bending/non-bending planes).
623      
624   char line[80];
625   
626   const TString kSizeKeyword("SIZES");
627   const TString kMotifKeyword("MOTIF");
628   const TString kMotifSpecialKeyword("SPECIAL_MOTIF");
629   
630   AliMpPCB* pcb = 0;
631   
632   while ( in.getline(line,80) )
633   {
634     if ( line[0] == '#' ) continue;
635     
636     TString sline(line);
637     
638     if ( sline(0,kSizeKeyword.Length()) == kSizeKeyword )
639     {
640       std::istringstream sin(sline(kSizeKeyword.Length(),
641                                    sline.Length()-kSizeKeyword.Length()-1).Data());
642       float padSizeX = 0.0;
643       float padSizeY = 0.0;
644       float pcbSizeX = 0.0;
645       float pcbSizeY = 0.0;
646       sin >> padSizeX >> padSizeY >> pcbSizeX >> pcbSizeY;
647       assert(pcb==0);
648       pcb = new AliMpPCB(pcbType,padSizeX*scale,padSizeY*scale,
649                          pcbSizeX*scale,pcbSizeY*scale);
650     }
651     
652     if ( sline(0,kMotifSpecialKeyword.Length()) == kMotifSpecialKeyword )
653     {
654       std::istringstream sin(sline(kMotifSpecialKeyword.Length(),
655                                    sline.Length()-kMotifSpecialKeyword.Length()).Data());
656       TString sMotifSpecial;
657       TString sMotifType;
658       sin >> sMotifSpecial >> sMotifType;
659       
660       AliMpMotifType* motifType = reader.BuildMotifType(sMotifType);
661       AliMpMotifSpecial* specialMotif = 
662         reader.BuildMotifSpecial(sMotifSpecial,motifType,scale);
663       
664       assert(pcb==0);      
665       pcb = new AliMpPCB(pcbType,specialMotif);
666     }
667     
668     if ( sline(0,kMotifKeyword.Length()) == kMotifKeyword )
669     {
670       std::istringstream sin(sline(kMotifKeyword.Length(),
671                                    sline.Length()-kMotifKeyword.Length()).Data());
672       TString sMotifType;
673       int ix;
674       int iy;
675       sin >> sMotifType >> ix >> iy;
676       
677       AliMpMotifType* motifType = reader.BuildMotifType(sMotifType.Data());
678       
679       assert(pcb!=0);
680       pcb->Add(motifType,ix,iy);
681     }
682   }
683   
684   in.close();
685   
686   fgPCBMap.Add(new TObjString(pcbType),pcb);
687   return pcb;
688 }
689
690 //_____________________________________________________________________________
691 AliMpTrigger*
692 AliMpTriggerReader::ReadSlat(const char* slatType, AliMpPlaneType planeType)
693 {
694   //
695   // Create a new AliMpTrigger object, by reading it from file.
696   //
697
698   Double_t scale = 1.0;
699   Bool_t flipX = kFALSE;
700   Bool_t flipY = kFALSE;
701   TList lines;
702   Int_t srcLine(-1);
703   Int_t destLine(-1);
704   
705   // Read the file and its include (if any) and store the result
706   // in a TObjArray of TObjStrings.
707   ReadLines(slatType,planeType,lines,scale,flipX,flipY,srcLine,destLine);
708
709   // Here some more sanity checks could be done.
710   // For the moment we only insure that the first line contains 
711   // a layer keyword.
712   TString& firstLine = ((TObjString*)lines.First())->String();
713   if ( !IsLayerLine(firstLine) ) 
714   {
715     std::ostringstream s;
716     s << fgkKeywordLayer;
717     lines.AddFirst(new TObjString(s.str().c_str()));
718   }
719   
720   AliDebugClass(2,Form("Scale=%g\n",scale));
721   
722   FlipLines(lines,flipX,flipY,srcLine,destLine);
723   
724   // Now splits the lines in packets corresponding to different layers 
725   // (if any), and create sub-slats.
726   TObjArray layers;
727   Int_t ilayer(-1);
728   TIter it(&lines);
729   TObjString* osline;
730   
731   while ( ( osline = (TObjString*)it.Next() ) )
732   {
733     TString& s = osline->String();
734     if ( IsLayerLine(s) )
735     {
736       layers.Add(new TList);
737       ++ilayer;
738     }
739     else
740     {
741       ((TList*)layers.At(ilayer))->Add(new TObjString(s));
742     }
743   }
744
745   AliDebugClass(2,Form("nlayers=%d\n",layers.GetEntriesFast()));
746
747   AliMpTrigger* triggerSlat = new AliMpTrigger(slatType, planeType);
748     
749   for ( Int_t ilayer = 0; ilayer < layers.GetEntriesFast(); ++ilayer )
750   {
751     TList& lines = *((TList*)layers.At(ilayer));
752     std::ostringstream slatName;
753     slatName << slatType << "-LAYER" << ilayer;
754     AliMpSlat* slat = BuildSlat(slatName.str().c_str(),planeType,lines,scale);
755     if ( slat )
756     {
757       triggerSlat->AdoptLayer(slat);
758     }
759     else
760     {
761       AliErrorClass(Form("Could not read %s\n",slatName.str().c_str()));
762       delete triggerSlat;
763       return 0;
764     }
765   }
766   
767   layers.SetOwner(kTRUE);
768   layers.Delete();
769   
770   return triggerSlat;
771 }
772
773 //_____________________________________________________________________________
774 void
775 AliMpTriggerReader::Reset()
776 {
777   // Resets the PCB internal map
778   fgPCBMap.Delete();
779 }