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