1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
20 #include "AliMpTriggerReader.h"
23 #include "AliMpMotifReader.h"
24 #include "AliMpFiles.h"
25 #include "AliMpMotifType.h"
27 #include "AliMpSlat.h"
28 #include "AliMpMotifMap.h"
29 #include "AliMpMotifPosition.h"
30 #include "AliMpMotif.h"
31 #include "AliMpHelper.h"
32 #include "AliMpSt345Reader.h"
33 #include "AliMpTrigger.h"
35 #include "Riostream.h"
38 #include "TObjString.h"
44 ClassImp(AliMpTriggerReader)
46 TMap AliMpTriggerReader::fgPCBMap;
47 TMap AliMpTriggerReader::fgLocalBoardMap;
51 const TString KEYWORD_LAYER("LAYER");
52 const TString KEYWORD_SCALE("SCALE");
53 const TString KEYWORD_PCB("PCB");
54 const TString KEYWORD_FLIPX("FLIP_X");
55 const TString KEYWORD_FLIPY("FLIP_Y");
58 //_____________________________________________________________________________
59 AliMpTriggerReader::AliMpTriggerReader() : TObject()
66 //_____________________________________________________________________________
67 AliMpTriggerReader::~AliMpTriggerReader()
73 fgLocalBoardMap.Delete();
76 //_____________________________________________________________________________
78 AliMpTriggerReader::BuildSlat(const char* slatName,
79 AliMpPlaneType planeType,
83 AliMpSlat* slat = new AliMpSlat(slatName, planeType);
87 while ( ( osline = (TObjString*)it.Next() ) )
89 // note that at this stage lines should not be empty.
90 TString sline(osline->String());
92 TObjArray* tokens = sline.Tokenize(' ');
94 TString& keyword = ((TObjString*)tokens->At(0))->String();
96 if ( keyword == KEYWORD_PCB )
98 if ( tokens->GetEntriesFast() != 3 )
100 AliErrorClass(Form("Syntax error : expecting PCB type localboard-list"
101 " in following line:\n%s",sline.Data()));
106 TString pcbName = ((TObjString*)tokens->At(1))->String();
108 TObjArray* localBoardList = ((TObjString*)tokens->At(2))->String().Tokenize(',');
112 std::ostringstream s;
113 s << pcbName.Data() << "x" << scale;
114 pcbName = s.str().c_str();
117 AliMpPCB* pcbType = PCB(pcbName.Data());
120 AliErrorClass(Form("Cannot read pcbType=%s",pcbName.Data()));
125 TArrayI allLocalBoards;
127 for ( Int_t ilb = 0; ilb < localBoardList->GetEntriesFast(); ++ilb)
129 TArrayI localBoardNumbers;
130 TString& localBoards = ((TObjString*)localBoardList->At(ilb))->String();
131 Ssiz_t pos = localBoards.First('-');
134 pos = localBoards.Length();
136 AliMpHelper::DecodeName(localBoards(pos-1,localBoards.Length()-pos+1).Data(),
137 ';',localBoardNumbers);
138 for ( int i = 0; i < localBoardNumbers.GetSize(); ++i )
140 std::ostringstream name;
141 name << localBoards(0,pos-1) << localBoardNumbers[i];
142 AliDebugClass(3,name.str().c_str());
143 localBoardNumbers[i] = LocalBoardNumber(name.str().c_str());
144 AliDebugClass(3,Form("LOCALBOARDNUMBER %d\n",localBoardNumbers[i]));
145 allLocalBoards.Set(allLocalBoards.GetSize()+1);
146 allLocalBoards[allLocalBoards.GetSize()-1] = localBoardNumbers[i];
147 if (localBoardNumbers[i] < 0 )
149 AliErrorClass(Form("Got a negative local board number in %s ? Unlikely"
150 " to be correct... : %s\n",slatName,name.str().c_str()));
155 delete localBoardList;
156 slat->Add(pcbType,allLocalBoards);
160 if ( slat->DX()== 0 || slat->DY() == 0 )
162 AliFatalClass(Form("Slat %s has invalid null size\n",slat->GetID()));
167 //_____________________________________________________________________________
169 AliMpTriggerReader::GetBoardNameFromPCBLine(const TString& s)
173 TObjArray* tokens = s.Tokenize(' ');
175 TString& keyword = ((TObjString*)tokens->At(0))->String();
177 if ( keyword == KEYWORD_PCB &&
178 tokens->GetEntriesFast() == 3 )
180 boardName = ((TObjString*)tokens->At(2))->String();
188 //_____________________________________________________________________________
190 AliMpTriggerReader::FlipLines(TList& lines, Bool_t flipX, Bool_t flipY,
191 Int_t srcLine, Int_t destLine)
194 // Change the local board names contained in lines,
195 // to go from right to left, and/or
196 // from top to bottom
199 // cout << "--- Original lines (flipX=" << flipX << " flipY=" << flipY
200 // << " srcLine=" << srcLine << " destLine=" << destLine << " : " << endl;
205 // Simply swaps R(ight) and L(eft) in the first character of local board names
209 while ( ( oline = (TObjString*)it.Next() ) )
211 TString& s = oline->String();
212 if ( s.Contains("RC") )
214 // Change right to left
215 s.ReplaceAll("RC","LC");
217 else if ( s.Contains("LC") )
219 // Change left to right
220 s.ReplaceAll("LC","RC");
225 // cout << "*** After flipX :" << endl;
230 // Change line number, according to parameters srcLine and destLine
231 // Note that because of road opening (for planes 3 and 4 at least),
232 // we loop for srcLine +-1
234 for ( Int_t line = -1; line <=1; ++line )
236 std::ostringstream src,dest;
237 src << "L" << srcLine+line;
238 dest << "L" << destLine-line;
239 if ( src.str() == dest.str() ) continue;
241 for ( Int_t i = 0; i < lines.GetSize(); ++i )
243 TObjString* oline = (TObjString*)lines.At(i);
245 TString& s = oline->String();
247 if ( !s.Contains(KEYWORD_PCB) )
249 // Only consider PCB lines.
253 if ( s.Contains(src.str().c_str()) )
255 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
256 src.str().c_str(),dest.str().c_str(),s.Data()));
258 s.ReplaceAll(src.str().c_str(),dest.str().c_str());
260 AliDebugClass(4,s.Data());
262 TString boardName(GetBoardNameFromPCBLine(s));
266 // We must also change board numbers, with the tricky
267 // thing that up and down must be swapped...
268 // Up can only be 1 card so it must be B1
269 // Down must be the uppper card of the line before, so
270 // the biggest possible board number for this Line,Column
275 AliDebugClass(4,Form("Forcing B1 in %s\n",s.Data()));
276 s.ReplaceAll(boardName(boardName.Length()-2,2),"B1");
277 AliDebugClass(4,s.Data());
281 // find the largest valid board number
282 for ( int b = 4; b>=1; --b )
284 std::ostringstream bs;
285 bs << boardName(0,boardName.Length()-1) << b;
286 if ( LocalBoardNumber(bs.str().c_str()) >= 0 )
288 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
289 boardName(boardName.Length()-2,2).Data(),
292 s.ReplaceAll(boardName(boardName.Length()-2,2),
299 // Check that the replacement we did is ok. If not,
301 Int_t lbn = LocalBoardNumber(GetBoardNameFromPCBLine(s));
304 AliDebugClass(4,Form("Removing line %s\n",s.Data()));
313 // cout << "*** After flipY :" << endl;
317 //___________________________________________________________________________
319 AliMpTriggerReader::IsLayerLine(const TString& sline)
321 if ( sline.BeginsWith(KEYWORD_LAYER) )
331 //___________________________________________________________________________
333 AliMpTriggerReader::DecodeFlipLine(const TString& sline,
335 Bool_t& flipX, Bool_t& flipY)
337 Ssiz_t blankPos = sline.First(' ');
338 if ( blankPos < 0 ) return 0;
340 TString keyword(sline(0,blankPos));
342 if ( keyword == KEYWORD_FLIPX )
345 } else if ( keyword == KEYWORD_FLIPY )
354 slatType2 = sline(blankPos+1,sline.Length()-blankPos-1);
358 //___________________________________________________________________________
360 AliMpTriggerReader::DecodeScaleLine(const TString& sline,
361 Double_t& scale, TString& slatType)
363 if ( sline(0,KEYWORD_SCALE.Length()) == KEYWORD_SCALE )
365 TString tmp(sline(KEYWORD_SCALE.Length()+1,
366 sline.Length()-KEYWORD_SCALE.Length()-1));
367 Ssiz_t blankPos = tmp.First(' ');
370 AliErrorClass(Form("Syntax error in slat file, should get a slatType after "
371 " SCALE keyword : %s\n",tmp.Data()));
376 slatType = tmp(0,blankPos);
377 scale = TString(tmp(blankPos+1,tmp.Length()-blankPos-1)).Atof();
385 //_____________________________________________________________________________
387 AliMpTriggerReader::GetLine(const TString& slatType)
390 // Assuming slatType is a 4 character string of the form XSLN
391 // where X=1,2,3 or 4
393 // N is the line number
395 if ( isdigit(slatType[0]) &&
396 ( slatType[1] == 'R' || slatType[1] == 'L' ) &&
399 return atoi(slatType(3,1).Data());
404 //_____________________________________________________________________________
406 AliMpTriggerReader::LocalBoardNumber(const char* localBoardName)
408 if ( !fgLocalBoardMap.GetSize() )
410 ReadLocalBoardMapping();
413 TPair* pair = (TPair*)fgLocalBoardMap.FindObject(localBoardName);
417 return atoi(((TObjString*)pair->Value())->String().Data());
422 //_____________________________________________________________________________
424 AliMpTriggerReader::PCB(const char* pcbType)
427 // Get access to an AliMpPCB object, given its type (e.g. N1, SB2, etc...)
429 // Note that the returned object is either a new one (read from file) or a
430 // reused one if it is already present in the internal map.
433 TPair* pair = (TPair*)fgPCBMap.FindObject(pcbType);
436 AliDebugClass(1,Form("Getting pcb %s from internal map",pcbType));
437 return (AliMpPCB*)pair->Value();
441 AliDebugClass(1,Form("Reading pcb %s from file",pcbType));
442 return ReadPCB(pcbType);
446 //_____________________________________________________________________________
448 AliMpTriggerReader::ReadLines(const char* slatType,
449 AliMpPlaneType planeType,
452 Bool_t& flipX, Bool_t& flipY,
453 Int_t& srcLine, Int_t& destLine)
455 AliDebugClass(1,Form("SlatType %s Scale %e FlipX %d FlipY %d srcLine %d"
456 " destLine %d\n",slatType,scale,flipX,flipY,
459 TString filename(AliMpFiles::SlatFilePath(kStationTrigger,slatType,
461 std::ifstream in(filename.Data());
464 AliErrorClass(Form("Cannot read slat from %s",filename.Data()));
469 while ( in.getline(line,80) )
471 TString sline(AliMpHelper::Normalize(line));
473 if ( sline.Length() == 0 || sline[0] == '#' ) continue;
475 Bool_t isKeywordThere =
476 sline.Contains(KEYWORD_PCB) ||
477 sline.Contains(KEYWORD_LAYER) ||
478 sline.Contains(KEYWORD_SCALE) ||
479 sline.Contains(KEYWORD_FLIPY) || sline.Contains(KEYWORD_FLIPX);
481 if ( !isKeywordThere )
483 AliErrorClass(Form("Got a line with no keyword : %s."
484 "That's not valid\n",line));
491 Int_t isScaleLine = DecodeScaleLine(sline,scale2,slatType2);
495 if ( isScaleLine < 0 )
497 AliFatalClass(Form("Syntax error near %s keyword\n",KEYWORD_SCALE.Data()));
499 else if ( isScaleLine > 0 && slatType2 != slatType )
501 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
507 Int_t isFlipLine = DecodeFlipLine(sline,slatType2,fx,fy);
512 srcLine = GetLine(slatType2);
513 destLine = GetLine(slatType);
517 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
521 lines.Add(new TObjString(sline.Data()));
529 //_____________________________________________________________________________
531 AliMpTriggerReader::ReadLocalBoardMapping()
533 TString filename(AliMpFiles::LocalTriggerBoardMapping());
535 AliDebugClass(1,Form("Reading from %s\n",filename.Data()));
537 fgLocalBoardMap.Delete();
539 ifstream in(filename.Data());
542 AliErrorClass(Form("Cannot read file %s\n",filename.Data()));
548 while ( in.getline(line,80) )
550 if ( line[0] == '#' ) continue;
553 TObjArray* tokens = sline.Tokenize(' ');
554 TString& number = ((TObjString*)(tokens->At(0)))->String();
555 TString& name = ((TObjString*)(tokens->At(1)))->String();
556 fgLocalBoardMap.Add(new TObjString(name), new TObjString(number));
557 AliDebugClass(10,Form("Board %s has number %s\n",name.Data(),number.Data()));
564 //_____________________________________________________________________________
566 AliMpTriggerReader::ReadPCB(const char* pcbType)
569 // Create a new AliMpPCB object, by reading it from file.
572 AliDebugClass(1,Form("pcbType=%s\n",pcbType));
574 TString pcbName(pcbType);
576 Ssiz_t pos = pcbName.First('x');
578 Double_t scale = 1.0;
582 scale = TString(pcbName(pos+1,pcbName.Length()-pos-1)).Atof();
583 pcbName = pcbName(0,pos);
586 std::ifstream in(AliMpFiles::SlatPCBFilePath(kStationTrigger,pcbName).Data());
589 AliErrorClass(Form("Cannot open file for PCB %s",pcbName.Data()));
593 AliMpMotifReader reader(kStationTrigger,kNonBendingPlane);
594 // note that the nonbending
595 // parameter is of no use for trigger, as far as reading motif is
596 // concerned, as all motifs are supposed to be in the same directory
597 // (as they are shared by bending/non-bending planes).
601 const TString sizeKeyword("SIZES");
602 const TString motifKeyword("MOTIF");
603 const TString motifSpecialKeyword("SPECIAL_MOTIF");
607 while ( in.getline(line,80) )
609 if ( line[0] == '#' ) continue;
613 if ( sline(0,sizeKeyword.Length()) == sizeKeyword )
615 std::istringstream sin(sline(sizeKeyword.Length(),
616 sline.Length()-sizeKeyword.Length()-1).Data());
617 float padSizeX = 0.0;
618 float padSizeY = 0.0;
619 float pcbSizeX = 0.0;
620 float pcbSizeY = 0.0;
621 sin >> padSizeX >> padSizeY >> pcbSizeX >> pcbSizeY;
623 pcb = new AliMpPCB(pcbType,padSizeX*scale,padSizeY*scale,
624 pcbSizeX*scale,pcbSizeY*scale);
627 if ( sline(0,motifSpecialKeyword.Length()) == motifSpecialKeyword )
629 std::istringstream sin(sline(motifSpecialKeyword.Length(),
630 sline.Length()-motifSpecialKeyword.Length()).Data());
631 TString sMotifSpecial;
633 sin >> sMotifSpecial >> sMotifType;
635 AliMpMotifType* motifType = reader.BuildMotifType(sMotifType);
636 AliMpMotifSpecial* specialMotif =
637 reader.BuildMotifSpecial(sMotifSpecial,motifType,scale);
640 pcb = new AliMpPCB(pcbType,specialMotif);
643 if ( sline(0,motifKeyword.Length()) == motifKeyword )
645 std::istringstream sin(sline(motifKeyword.Length(),
646 sline.Length()-motifKeyword.Length()).Data());
650 sin >> sMotifType >> ix >> iy;
652 AliMpMotifType* motifType = reader.BuildMotifType(sMotifType.Data());
655 pcb->Add(motifType,ix,iy);
661 fgPCBMap.Add(new TObjString(pcbType),pcb);
665 //_____________________________________________________________________________
667 AliMpTriggerReader::ReadSlat(const char* slatType, AliMpPlaneType planeType)
670 // Create a new AliMpTrigger object, by reading it from file.
673 Double_t scale = 1.0;
674 Bool_t flipX = kFALSE;
675 Bool_t flipY = kFALSE;
680 // Read the file and its include (if any) and store the result
681 // in a TObjArray of TObjStrings.
682 ReadLines(slatType,planeType,lines,scale,flipX,flipY,srcLine,destLine);
684 // Here some more sanity checks could be done.
685 // For the moment we only insure that the first line contains
687 TString& firstLine = ((TObjString*)lines.First())->String();
688 if ( !IsLayerLine(firstLine) )
690 std::ostringstream s;
692 lines.AddFirst(new TObjString(s.str().c_str()));
695 AliDebugClass(2,Form("Scale=%g\n",scale));
697 FlipLines(lines,flipX,flipY,srcLine,destLine);
699 // Now splits the lines in packets corresponding to different layers
700 // (if any), and create sub-slats.
706 while ( ( osline = (TObjString*)it.Next() ) )
708 TString& s = osline->String();
709 if ( IsLayerLine(s) )
711 layers.Add(new TList);
716 ((TList*)layers.At(ilayer))->Add(new TObjString(s));
720 AliDebugClass(2,Form("nlayers=%d\n",layers.GetEntriesFast()));
722 AliMpTrigger* triggerSlat = new AliMpTrigger(slatType, planeType);
724 for ( Int_t ilayer = 0; ilayer < layers.GetEntriesFast(); ++ilayer )
726 TList& lines = *((TList*)layers.At(ilayer));
727 std::ostringstream slatName;
728 slatName << slatType << "-LAYER" << ilayer;
729 AliMpSlat* slat = BuildSlat(slatName.str().c_str(),planeType,lines,scale);
732 triggerSlat->AdoptLayer(slat);
736 AliErrorClass(Form("Could not read %s\n",slatName.str().c_str()));
742 layers.SetOwner(kTRUE);
748 //_____________________________________________________________________________
750 AliMpTriggerReader::Reset()