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