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