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