Corrections needed on HP
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpReader.cxx
1 // $Id$
2 // Category: sector
3 //
4 // Class AliMpReader
5 // -------------------
6 // Class that takes care of reading the sector data.
7 //
8 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
9
10 #if !defined(__HP_aCC) && !defined(__alpha)
11   #include <sstream>
12 #endif
13
14 #include <Riostream.h>
15 #include <Rstrstream.h>
16 #include <TSystem.h>
17 #include <TError.h>
18 #include <TMath.h>
19
20 #include "AliMpReader.h"
21 #include "AliMpSector.h"
22 #include "AliMpFiles.h"
23 #include "AliMpZone.h"
24 #include "AliMpSubZone.h"
25 #include "AliMpRow.h"
26 #include "AliMpVRowSegment.h"
27 #include "AliMpRowSegment.h"
28 #include "AliMpRowSegmentLSpecial.h"
29 #include "AliMpRowSegmentRSpecial.h"
30 #include "AliMpPadRow.h"
31 #include "AliMpMotifMap.h"
32 #include "AliMpMotif.h"
33 #include "AliMpMotifSpecial.h"
34 #include "AliMpMotifType.h"
35 #include "AliMpConnection.h"
36 #include "AliMpIntPair.h"
37 #include "AliMpDirection.h"
38
39 ClassImp(AliMpReader)
40
41 #ifdef WITH_ROOT
42 const Int_t    AliMpReader::fgkSeparator = 100;
43 #endif
44
45 const TString  AliMpReader::fgkSectorKeyword  = "SECTOR_DATA";
46 const TString  AliMpReader::fgkZoneKeyword    = "ZONE";
47 const TString  AliMpReader::fgkSubZoneKeyword = "SUBZONE";
48 const TString  AliMpReader::fgkRowKeyword     = "ROW_SEGMENT";
49 const TString  AliMpReader::fgkEofKeyword     = "EOF";
50 const TString  AliMpReader::fgkSectorSpecialKeyword  = "SECTOR_SPECIAL_DATA";
51 const TString  AliMpReader::fgkMotifKeyword          = "MOTIF";
52 const TString  AliMpReader::fgkRowSpecialKeyword     = "ROW";
53 const TString  AliMpReader::fgkPadRowsKeyword        = "PAD_ROWS";
54 const TString  AliMpReader::fgkPadRowSegmentKeyword  = "PAD_ROW_SEGMENT";
55
56 //_____________________________________________________________________________
57 AliMpReader::AliMpReader(AliMpStationType station, AliMpPlaneType plane) 
58   : TObject(),
59     fStationType(station),
60     fPlaneType(plane),
61     fSector(0),
62     fVerboseLevel(0)
63 {
64 //
65 }
66
67 //_____________________________________________________________________________
68 AliMpReader::AliMpReader() 
69   : TObject(),
70     fStationType(kStation1),
71     fPlaneType(kBendingPlane),
72     fSector(0),
73     fVerboseLevel(0)
74 {
75 //
76 }
77
78 //_____________________________________________________________________________
79 AliMpReader::~AliMpReader() {
80 //  
81 }
82
83 //
84 // private methods
85 //
86
87 #ifdef WITH_ROOT
88 //_____________________________________________________________________________
89 Int_t  AliMpReader::GetIndex(const string& s) const 
90 {
91 // Converts the TString to integer.
92 // ---
93
94   if (s.length() > 5) {
95     Fatal("GetIndex", "String too long.");
96     return 0;
97   }  
98
99   Int_t index = 0;
100   for (Int_t i=s.length(); i>=0; --i)  index = index*100 + int(s[i]);
101   
102   return index;
103 }
104
105 //______________________________________________________________________________
106 Int_t  AliMpReader::GetIndex(const AliMpIntPair& pair) const
107 {
108 // Converts the pair of integers to integer.
109 // ---
110
111   if (pair.GetFirst() >= fgkSeparator || pair.GetSecond() >= fgkSeparator)
112     Fatal("GetIndex", "Index out of limit.");
113       
114   return pair.GetFirst()*fgkSeparator + pair.GetSecond() + 1;
115 }  
116
117 //_____________________________________________________________________________
118 string  AliMpReader::GetString(Int_t index) const
119 {
120 // Converts the integer index to the string.
121 // ---
122
123   string s;
124   while (index >0) {
125     Char_t c = index%100;
126     s += c;
127     index = index/100;
128   }
129   
130   return s;
131   
132 }
133
134 //______________________________________________________________________________
135 AliMpIntPair  AliMpReader::GetPair(Int_t index) const
136 {
137 // Converts the integer index to the pair of integers.
138 // ---
139
140   return AliMpIntPair((index-1)/fgkSeparator, (index-1)%fgkSeparator);
141 }  
142 #endif
143
144 //_____________________________________________________________________________
145 void  AliMpReader::ReadSectorData(ifstream& in)
146 {
147 // Reads sector input data;
148 // prepares zones and rows vectors to be filled in.
149 // ---
150
151   TString keyword;
152   in >> keyword;
153   
154   if (fVerboseLevel>0) 
155     cout << keyword << endl;
156
157   if (keyword != fgkSectorKeyword) {
158      Fatal("ReadSectorData", "Wrong file format.");
159      return;
160   }   
161     
162   Int_t nofZones, nofRows;
163   TString directionStr;
164   in >> nofZones;
165   in >> nofRows;
166   in >> directionStr;
167   
168   AliMpDirection direction;
169   direction = (directionStr == "Y") ? kY  :  kX;
170   if (fVerboseLevel>0) 
171      cout << nofZones << " " <<  nofRows << endl;
172
173   fSector = new AliMpSector("Not defined", nofZones, nofRows,direction);
174   
175   TString nextKeyword;
176   in >> nextKeyword;
177     
178   if (nextKeyword != fgkZoneKeyword) {
179      Fatal("ReadSectorData", "Wrong file format.");
180      return;
181   }      
182   
183   ReadZoneData(in);
184 }  
185
186 //_____________________________________________________________________________
187 void AliMpReader::ReadZoneData(ifstream& in)
188 {
189 // Reads zone input data;
190 // creates zone and adds it to zones vector.
191 // ---
192
193   Int_t zoneID;
194   Double_t  sizex, sizey; 
195   in >> zoneID;    
196   in >> sizex;
197   in >> sizey;
198   if (fVerboseLevel>0) 
199      cout << fgkZoneKeyword << " " <<  zoneID << "  "        
200           << sizex << " " << sizey << endl;
201   
202   AliMpZone* zone =  fSector->GetZone(zoneID);
203   zone->SetPadDimensions(TVector2(sizex/2.,sizey/2.)); 
204       
205   TString nextKeyword;
206   in >> nextKeyword;
207     
208   if (nextKeyword != fgkSubZoneKeyword) {
209      Fatal("ReadZoneData", "Wrong file format.");
210      return;
211   }  
212     
213   ReadSubZoneData(in, zone);
214 }
215
216 //_____________________________________________________________________________
217 void AliMpReader::ReadSubZoneData(ifstream& in, AliMpZone* zone)
218 {
219 // Reads subzone input data;
220 // creates subzone and its to the specified zone.
221 // ---
222
223   if (fVerboseLevel>0) 
224     cout << fgkSubZoneKeyword << " ";
225
226   AliMpVMotif* motif = ReadMotifData(in, zone);
227   AliMpSubZone* subZone = new AliMpSubZone(motif); 
228   zone->AddSubZone(subZone); 
229
230   TString nextKeyword;
231   in >> nextKeyword;
232     
233   if (nextKeyword != fgkRowKeyword) {
234      Fatal("ReadSubZoneData", "Wrong file format.");
235      return;
236   }  
237     
238   ReadRowSegmentsData(in, zone, subZone);
239 }   
240
241 //_____________________________________________________________________________
242 AliMpVMotif*  AliMpReader::ReadMotifData(ifstream& in, AliMpZone* zone)
243 {
244 // Reads the motif input data.
245 // ---
246
247   TString  motifID;
248   TString  motifTypeID;
249   in >> motifID;
250   in >> motifTypeID;
251   if (fVerboseLevel>0) {
252     cout << motifID << " " 
253          << motifTypeID << endl;
254   }      
255   
256   AliMpMotifMap* motifMap = fSector->GetMotifMap();
257
258   AliMpMotifType* motifType = 0;
259   AliMpVMotif* motif 
260     = motifMap->FindMotif(motifID, motifTypeID, zone->GetPadDimensions());
261   if (!motif) {    
262     motifType = motifMap->FindMotifType(motifTypeID);
263     if (!motifType) {
264       motifType = BuildMotifType(motifTypeID);     
265       motifMap->AddMotifType(motifType);
266     }
267     
268     if (zone->GetPadDimensions().X() != 0. && zone->GetPadDimensions().Y() != 0.) 
269       motif = new AliMpMotif(motifID, motifType, zone->GetPadDimensions());
270     else 
271       motif = BuildMotifSpecial(motifID, motifType);
272       
273     if (motif) 
274       motifMap->AddMotif(motif);
275
276   }  
277
278   return motif;   
279 }  
280
281 //_____________________________________________________________________________
282 void AliMpReader::ReadRowSegmentsData(ifstream& in, 
283                                       AliMpZone* zone, AliMpSubZone* subZone)
284 {
285 // Reads row segments input data of a specified zone and subzone;
286 // creates row segment and adds it to the specified subzone
287 // and a corresponding row in the rows vector.
288 // ---
289
290   TString nextKeyword;
291   do {
292     // 
293     // Read data from file
294     //
295     Int_t offX, offY, inRow, nofMotifs, firstMotifPositionId, firstMotifPositionDId;
296     in >> offX;
297     in >> offY;
298     in >> inRow;
299     in >> nofMotifs;
300     in >> firstMotifPositionId;
301     in >> firstMotifPositionDId;
302     if (fVerboseLevel>0) 
303        cout << fgkRowKeyword << " " 
304             << offX << " " << offY << " " << inRow << " " << nofMotifs << " " 
305             << firstMotifPositionId << " " << firstMotifPositionDId
306             << endl;
307
308     in >> nextKeyword;
309
310     //
311     // Process data
312     //
313     AliMpRow* row = fSector->GetRow(inRow);
314     AliMpVMotif* motif = subZone->GetMotif();
315     
316     // Create row segment and add it to its zone, row   
317     AliMpVRowSegment* rowSegment
318       = new AliMpRowSegment(row, motif, AliMpIntPair(offX, offY), nofMotifs, 
319                         firstMotifPositionId, firstMotifPositionDId);
320                         
321     subZone->AddRowSegment(rowSegment);
322     row->AddRowSegment(rowSegment);
323   }
324   while (!in.eof() && (nextKeyword == fgkRowKeyword));
325
326   if (in.eof()) return;
327
328   if (nextKeyword == fgkZoneKeyword) {
329     ReadZoneData(in);
330   }
331   else if (nextKeyword == fgkSubZoneKeyword) {
332     ReadSubZoneData(in, zone);
333   }   
334   else {
335     Fatal("ReadRowSegmentsData", "Wrong file format.");
336   } 
337 }   
338
339 //_____________________________________________________________________________
340 void AliMpReader::ReadSectorSpecialData(ifstream& in, AliMpXDirection direction)
341 {
342 // Reads sector input data
343 // with a special (irregular) motifs.
344 // ---
345
346   TString keyword;
347   in >> keyword;
348   if (fVerboseLevel>0) 
349     cout << keyword << endl;
350
351   if (keyword != fgkSectorSpecialKeyword) {
352      Fatal("ReadSectorSpecialData", "Wrong file format.");
353      return;
354   }   
355
356   TString nextKeyword;
357   in >> nextKeyword;
358   if (fVerboseLevel>0) 
359     cout << keyword << endl;
360     
361   if (nextKeyword != fgkMotifKeyword) {
362     Fatal("ReadSectorSpecialData", "Wrong file format.");
363     return;
364   }  
365
366   ReadMotifsSpecialData(in);     
367   ReadRowSpecialData(in, direction); 
368 }  
369
370 //_____________________________________________________________________________
371 void AliMpReader::ReadMotifsSpecialData(ifstream& in)
372 {
373 // Reads the special (irregular) motifs input data.
374 // ---
375
376   if (fVerboseLevel>0) 
377     cout << fgkMotifKeyword << " ";
378
379   TString nextKeyword;
380   do {
381     Int_t zone;
382     in >> zone;
383     AliMpVMotif* motif =  ReadMotifData(in, fSector->GetZone(zone));
384     AliMpSubZone* subZone = new AliMpSubZone(motif); 
385     fSector->GetZone(zone)->AddSubZone(subZone); 
386   
387     in >> nextKeyword;
388     if (fVerboseLevel>0) 
389       cout << nextKeyword << " ";      
390   }
391   while (nextKeyword == fgkMotifKeyword);
392     
393   if (nextKeyword != fgkRowSpecialKeyword) {
394      Fatal("ReadMotifSpecialData", "Wrong file format.");
395      return;
396   }      
397 }  
398
399 //_____________________________________________________________________________
400 void AliMpReader::ReadRowSpecialData(ifstream& in, AliMpXDirection direction)
401 {
402 // Reads row input data
403 // with a special (irregular) motifs.
404 // ---
405
406   Int_t id;
407   in >> id;
408   if (fVerboseLevel>0) 
409       cout << id << endl;      
410   
411   // Get the row and its border
412   AliMpRow* row = fSector->GetRow(id);
413
414   AliMpVRowSegmentSpecial* segment = 0;
415   if (direction == kLeft) {
416     AliMpVRowSegment* firstNormalSeg = row->GetRowSegment(0);
417     Double_t offsetX = firstNormalSeg->LeftBorderX();
418   
419     // Create a special row segment
420     segment = new AliMpRowSegmentLSpecial(row, offsetX);
421     row->AddRowSegmentInFront(segment);
422   }
423   else { 
424     AliMpVRowSegment* precedentNormalSeg 
425       = row->GetRowSegment(row->GetNofRowSegments()-1);
426     Double_t offsetX = precedentNormalSeg->RightBorderX();
427   
428     // Create a special row segment
429     segment = new AliMpRowSegmentRSpecial(row, offsetX);
430     row->AddRowSegment(segment);
431   }  
432       
433   TString nextKeyword;
434   in >> nextKeyword;
435   if (fVerboseLevel>0) 
436     cout << nextKeyword << " ";
437     
438   if (nextKeyword != fgkPadRowsKeyword) {
439      Fatal("ReadRowSpecialData", "Wrong file format.");
440      return;
441   }  
442     
443   ReadRowSegmentSpecialData(in, segment, direction); 
444   
445   // Update row segment and set it to all subzones associated with
446   // contained motifs
447   
448   segment->UpdateMotifVector();
449   segment->UpdatePadsOffset();
450   
451   for (Int_t i=0; i<segment->GetNofMotifs(); i++) {
452     AliMpSubZone* subZone = 0;
453     Int_t j = 0;
454     while (!subZone && j<fSector->GetNofZones())
455       subZone = fSector->GetZone(++j)->FindSubZone(segment->GetMotif(i));
456     
457     subZone->AddRowSegment(segment);
458   }  
459 }  
460
461 //_____________________________________________________________________________
462 void AliMpReader::ReadRowSegmentSpecialData(ifstream& in, 
463                                             AliMpVRowSegmentSpecial* segment,
464                                             AliMpXDirection direction)
465 {
466 // Reads row segment input data
467 // with a special (irregular) motifs.
468 // ---
469
470   Int_t nofPadRows;
471   in >> nofPadRows;
472   if (fVerboseLevel>0) 
473     cout << nofPadRows << endl;
474   
475   TString keyword;
476   in >> keyword;
477   if (fVerboseLevel>0) 
478     cout << keyword << " ";
479     
480   if (keyword != fgkPadRowSegmentKeyword) {
481      Fatal("ReadRowSegmentSpecialData", "Wrong file format.");
482      return;
483   }  
484   
485   //
486   // Process data
487   //
488     
489   PadRowVector  newPadRows;
490   for (Int_t i=0; i<nofPadRows; i++) {
491     
492      // Create pad row
493      AliMpPadRow* padRow = new AliMpPadRow(direction);
494      segment->AddPadRow(padRow);
495      
496      // Keep the new rows in a temporary vector
497 #ifdef WITH_STL
498      newPadRows.push_back(padRow);
499 #endif
500 #ifdef WITH_ROOT
501      newPadRows.Add(padRow);
502 #endif
503   }   
504       
505   TString nextKeyword;
506   do {
507     // 
508     // Read data from file
509     //
510     Int_t    nofPadsInRow, motifPositionId;
511     TString   motifId, motifTypeId;
512     in >> nofPadsInRow;
513     in >> motifId;
514     in >> motifPositionId; 
515   
516     if (fVerboseLevel>0) 
517        cout << nofPadsInRow << " " << motifId << " " << motifPositionId << endl;
518
519     in >> nextKeyword;
520     if (fVerboseLevel>0) 
521       cout << nextKeyword << " ";
522
523     //
524     // Process data
525     //
526     
527     for (Int_t i=0; i<nofPadRows; i++) {
528     
529       // Get pad row from the temporary vector
530 #ifdef WITH_STL
531       AliMpPadRow* padRow = newPadRows[i];
532 #endif
533 #ifdef WITH_ROOT
534       AliMpPadRow* padRow = (AliMpPadRow*)newPadRows[i];
535 #endif
536       
537       // Find motif
538       AliMpVMotif* motif = fSector->GetMotifMap()->FindMotif(motifId);
539       
540       if (!motif) {
541         Fatal("ReadRowSegmentSpecialData", "Unknown motif.");
542         return;
543       }
544
545       // Create pad row segment
546       padRow->AddPadRowSegment(dynamic_cast<AliMpMotif *>(motif), 
547                                motifPositionId, nofPadsInRow);
548     }  
549   }
550   while (!in.eof() && (nextKeyword == fgkPadRowSegmentKeyword));
551   
552   if (in.eof()) return;
553
554   if (nextKeyword == fgkPadRowsKeyword) {
555     ReadRowSegmentSpecialData(in, segment, direction);
556   }
557   else if (nextKeyword == fgkRowSpecialKeyword) {
558     ReadRowSpecialData(in, direction);
559   }   
560   else {
561     Fatal("ReadRowSegmentSpecialData", "Wrong file format.");
562   } 
563 }  
564
565 //
566 // public methods
567 //
568
569 //_____________________________________________________________________________
570 AliMpSector* AliMpReader::BuildSector()
571 {
572 // Reads the mapping data from ascii file
573 // $MINSTALL/data/fileName and creates the basic objects:
574 // zones, subzones, rows, row segments, motifs.
575 // ---
576
577   // Open input file
578   ifstream in(AliMpFiles::Instance()
579               ->SectorFilePath(fStationType, fPlaneType).Data(), ios::in);
580   if (!in) {
581      cerr << AliMpFiles::Instance()
582               ->SectorFilePath(fStationType, fPlaneType) << endl;       
583      Error("BuildSector", "File not found.");
584      return 0;
585   }
586   
587   ReadSectorData(in);
588   fSector->SetRowSegmentOffsets();
589
590   // Open input file for special inner zone
591   TString sectorSpecialFileName 
592     = AliMpFiles::Instance()->SectorSpecialFilePath(fStationType, fPlaneType);
593   if (!gSystem->AccessPathName(sectorSpecialFileName.Data())) {
594     ifstream in2(sectorSpecialFileName.Data(), ios::in);
595     if (!in2) { 
596        cerr << AliMpFiles::Instance()
597               ->SectorSpecialFilePath(fStationType, fPlaneType) << endl;        
598        Error("BuildSector", "File not found.");
599        return 0;
600     }
601     
602     ReadSectorSpecialData(in2, kLeft);
603   }   
604
605   // Open input file for special outer zone
606   TString sectorSpecialFileName2 
607     = AliMpFiles::Instance()->SectorSpecialFilePath2(fStationType, fPlaneType);
608   if (!gSystem->AccessPathName(sectorSpecialFileName2.Data())) {
609     ifstream in3(sectorSpecialFileName2.Data(), ios::in);
610     if (!in3) { 
611        cerr << AliMpFiles::Instance()
612               ->SectorSpecialFilePath2(fStationType, fPlaneType) << endl;       
613        Error("Build", "File not found.");
614        return 0;
615     }
616     
617     ReadSectorSpecialData(in3, kRight);
618   }   
619
620   fSector->Initialize();
621   
622   return fSector;
623 }  
624
625 //_____________________________________________________________________________
626 AliMpMotifType* AliMpReader::BuildMotifType(const TString& motifTypeId)
627 {
628
629   // Read the files describing a motif in the "$MINSTALL/data" directory
630   // and fill the AliMpMotifType structure with.
631   // The files mentioned are are named padPos<maskName>.dat
632   // and connect<maskName>.dat
633
634   AliMpMotifType*  motifType = new AliMpMotifType(motifTypeId); 
635
636   TString strPadPos 
637     = AliMpFiles::Instance()
638       ->PadPosFilePath(fStationType, fPlaneType, motifTypeId);
639   ifstream padPos(strPadPos.Data());
640   if (fVerboseLevel>0) cout<<"Opening file "<<strPadPos<<endl;
641
642   PadMapType positions;
643
644   char line[256];
645   do {
646     padPos.getline(line,255);
647     if (!padPos) break;
648
649 #if defined (__HP_aCC) || (__alpha)
650     strstream strline;
651     strline << line;
652 #else
653     istringstream strline(line);
654 #endif    
655     string key;
656
657     strline>>key;
658     if ((key=="#") || (key=="") ) continue;
659
660     int i,j;
661     strline>>i>>j;
662 #ifdef WITH_STL
663     positions[key].first=i;
664     positions[key].second=j;
665 #endif
666 #ifdef WITH_ROOT
667     positions.Add(GetIndex(key), GetIndex(AliMpIntPair(i,j))); 
668 #endif
669   } while (!padPos.eof());
670
671   padPos.close();
672
673   if (fVerboseLevel>0) 
674     cout << "Opening file "
675          << AliMpFiles::Instance()->BergToGCFilePath(fStationType)
676          << endl;
677
678   ifstream bergToGCFile(AliMpFiles::Instance()->BergToGCFilePath(fStationType));
679   Int_t gassiChannel[80];
680   while(1) {
681     Int_t bergNum;
682     TString gcStr;
683     bergToGCFile>>bergNum>>gcStr;
684     if (!bergToGCFile.good()) break;
685     if (gcStr=="GND") continue;
686     if (bergNum>80) {
687         Fatal("BuildMotifType","Berg number > 80 ...");
688         continue;
689     }
690     gassiChannel[bergNum-1]= atoi(gcStr);
691   }
692   bergToGCFile.close();
693   
694   TString strMotif 
695     = AliMpFiles::Instance()
696       ->MotifFilePath(fStationType, fPlaneType, motifTypeId);
697   ifstream motif(strMotif);
698   if (fVerboseLevel>0) cout<<"Opening file "<<strMotif<<endl;
699
700
701   Int_t nofPadsX=0;
702   Int_t nofPadsY=0;
703
704   do {
705   
706     Int_t ix,iy,numBerg,numKapton,padNum,gassiNum;
707
708     TString lineStr,token;
709     lineStr.ReadLine(motif);
710     if (!motif.good()) break;
711 #if defined (__HP_aCC) || (__alpha)
712     strstream tokenList;
713     tokenList << lineStr.Data();
714 #else
715     istringstream tokenList(lineStr.Data());
716 #endif    
717     
718     token.ReadToken(tokenList);
719     if (!tokenList.good()) continue; // column is missing...
720     if ( (token.Length()>0) && (token[0]=='#') ) continue; // this is a comment line
721     
722     numBerg = atoi(token.Data());
723     if (numBerg==0) {
724       Warning("BuildMotifType","Berg number invalid");
725       continue;
726     }
727     
728     token.ReadToken(tokenList);
729     if (!tokenList.good()) continue; // column is missing...
730     numKapton = atoi(token.Data());
731     if (numKapton==0) continue;
732
733     
734     token.ReadToken(tokenList);
735     if (!tokenList.good()) continue; // column is missing...
736     if (token=="GND") continue;
737     string padName = token.Data();
738     padNum = motifType->PadNum(token);
739     
740      token.ReadToken(tokenList);
741      if (token.IsNull() ) continue; // column is missing...
742 //     if (token[0]!='E') {
743 //       cerr<<"Problem : gassinumber isn't begining with E:"<<token<<endl;
744 //       continue;
745 //     }  else {
746 //        gassiNum = atoi(token.Data() +1 )-1;
747 //     }
748     if ( (numBerg<1) || (numBerg>80) ) {
749         Warning("BuildMotifType","Berg number outside range");
750         continue;
751     }
752     
753     gassiNum  = gassiChannel[numBerg-1];
754
755 #ifdef WITH_STL
756     PadMapTypeIterator iter = positions.find(padName);
757     if (iter==positions.end()) {
758       cerr<<"Problem: Pad number "<<padNum<<" found in the file "<<strMotif
759           <<" but not in the file"<<strPadPos<<endl;
760       continue;
761     }
762
763     ix= iter->second.first;
764     iy= iter->second.second;
765 #endif
766
767 #ifdef WITH_ROOT
768     Long_t value = positions.GetValue(GetIndex(padName));
769     if (!value) {
770       cerr<<"Problem: Pad number "<<padNum<<" found in the file "<<strMotif
771           <<" but not in the file"<<strPadPos<<endl;
772       continue;
773     }
774
775     ix = GetPair(value).GetFirst();
776     iy = GetPair(value).GetSecond();
777 #endif
778
779     motifType->AddConnection(AliMpIntPair(ix,iy),
780                   new AliMpConnection(padNum,numBerg,numKapton,gassiNum));
781
782     if (ix>=nofPadsX) nofPadsX=ix+1;
783     if (iy>=nofPadsY) nofPadsY=iy+1;
784
785   } while (!motif.eof());    
786
787
788   motifType->SetNofPads(nofPadsX, nofPadsY);
789
790   motif.close();
791
792   return motifType;
793 }
794
795
796 //_____________________________________________________________________________
797 AliMpMotifSpecial*  
798 AliMpReader::BuildMotifSpecial(const TString& motifID,
799                                AliMpMotifType* motifType)
800 {
801 // Build a special motif by reading the file motifSpecial<motifId>.dat
802 // in the data directory
803 // ---
804
805   // Open the input file
806   ifstream in(AliMpFiles::Instance()
807               ->MotifSpecialFilePath(fStationType, fPlaneType, motifID).Data(), 
808               ios::in);
809   if (!in) {    
810      Error("BuildMotifSpecial", "File not found.");
811      return 0;
812   }
813
814   AliMpMotifSpecial* res = new AliMpMotifSpecial(motifID,motifType);
815   Int_t i,j;
816   Double_t x,y;
817   in >> i;
818   while (!in.eof()){
819     in >>j >>x >> y;
820     res->SetPadDimensions(AliMpIntPair(i,j),TVector2(x/2.,y/2.));
821     in >> i;
822   }
823   
824   in.close();
825   return res;
826 }
827
828
829 //_____________________________________________________________________________
830 void AliMpReader::SetVerboseLevel(Int_t verboseLevel)
831 {
832 // Sets verbose level.
833 // ---
834
835   fVerboseLevel = verboseLevel;
836 }
837