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