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