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 **************************************************************************/
17 // $MpId: AliMpTriggerReader.cxx,v 1.2 2006/03/02 16:36:30 ivana Exp $
19 #include "AliMpTriggerReader.h"
20 #include "AliMpMotifReader.h"
21 #include "AliMpFiles.h"
22 #include "AliMpMotifType.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"
34 #include "Riostream.h"
36 #include "TObjString.h"
44 /// \class AliMpTriggerReader
45 /// Read trigger slat ASCII files
46 /// Basically provides 2 static methods:
47 /// - AliMpTrigger* ReadSlat()
48 /// - AliMpPCB* ReadPCB()
50 /// \author Laurent Aphecetche
52 TMap AliMpTriggerReader::fgPCBMap;
53 TMap AliMpTriggerReader::fgLocalBoardMap;
55 const TString AliMpTriggerReader::fgkKeywordLayer("LAYER");
56 const TString AliMpTriggerReader::fgkKeywordScale("SCALE");
57 const TString AliMpTriggerReader::fgkKeywordPcb("PCB");
58 const TString AliMpTriggerReader::fgkKeywordFlipX("FLIP_X");
59 const TString AliMpTriggerReader::fgkKeywordFlipY("FLIP_Y");
61 ClassImp(AliMpTriggerReader)
63 //_____________________________________________________________________________
64 AliMpTriggerReader::AliMpTriggerReader() : TObject()
71 //_____________________________________________________________________________
72 AliMpTriggerReader::~AliMpTriggerReader()
78 fgLocalBoardMap.Delete();
81 //_____________________________________________________________________________
83 AliMpTriggerReader::BuildSlat(const char* slatName,
84 AliMpPlaneType planeType,
88 // Construct a slat from the list of lines, taking into account
91 AliMpSlat* slat = new AliMpSlat(slatName, planeType);
95 while ( ( osline = (TObjString*)it.Next() ) )
97 // note that at this stage lines should not be empty.
98 TString sline(osline->String());
100 TObjArray* tokens = sline.Tokenize(' ');
102 TString& keyword = ((TObjString*)tokens->At(0))->String();
104 if ( keyword == fgkKeywordPcb )
106 if ( tokens->GetEntriesFast() != 3 )
108 AliErrorClass(Form("Syntax error : expecting PCB type localboard-list"
109 " in following line:\n%s",sline.Data()));
114 TString pcbName = ((TObjString*)tokens->At(1))->String();
116 TObjArray* localBoardList = ((TObjString*)tokens->At(2))->String().Tokenize(',');
120 std::ostringstream s;
121 s << pcbName.Data() << "x" << scale;
122 pcbName = s.str().c_str();
125 AliMpPCB* pcbType = PCB(pcbName.Data());
128 AliErrorClass(Form("Cannot read pcbType=%s",pcbName.Data()));
133 TArrayI allLocalBoards;
135 for ( Int_t ilb = 0; ilb < localBoardList->GetEntriesFast(); ++ilb)
137 TArrayI localBoardNumbers;
138 TString& localBoards = ((TObjString*)localBoardList->At(ilb))->String();
139 Ssiz_t pos = localBoards.First('-');
142 pos = localBoards.Length();
144 AliMpHelper::DecodeName(localBoards(pos-1,localBoards.Length()-pos+1).Data(),
145 ';',localBoardNumbers);
146 for ( int i = 0; i < localBoardNumbers.GetSize(); ++i )
148 std::ostringstream name;
149 name << localBoards(0,pos-1) << localBoardNumbers[i];
150 AliDebugClass(3,name.str().c_str());
151 localBoardNumbers[i] = LocalBoardNumber(name.str().c_str());
152 AliDebugClass(3,Form("LOCALBOARDNUMBER %d\n",localBoardNumbers[i]));
153 allLocalBoards.Set(allLocalBoards.GetSize()+1);
154 allLocalBoards[allLocalBoards.GetSize()-1] = localBoardNumbers[i];
155 if (localBoardNumbers[i] < 0 )
157 AliErrorClass(Form("Got a negative local board number in %s ? Unlikely"
158 " to be correct... : %s\n",slatName,name.str().c_str()));
163 delete localBoardList;
164 slat->Add(pcbType,allLocalBoards);
168 if ( slat->DX()== 0 || slat->DY() == 0 )
170 AliFatalClass(Form("Slat %s has invalid null size\n",slat->GetID()));
175 //_____________________________________________________________________________
177 AliMpTriggerReader::GetBoardNameFromPCBLine(const TString& s)
179 // Decode the string to get the board name
182 TObjArray* tokens = s.Tokenize(' ');
184 TString& keyword = ((TObjString*)tokens->At(0))->String();
186 if ( keyword == fgkKeywordPcb &&
187 tokens->GetEntriesFast() == 3 )
189 boardName = ((TObjString*)tokens->At(2))->String();
197 //_____________________________________________________________________________
199 AliMpTriggerReader::FlipLines(TList& lines, Bool_t flipX, Bool_t flipY,
200 Int_t srcLine, Int_t destLine)
203 // Change the local board names contained in lines,
204 // to go from right to left, and/or
205 // from top to bottom
211 // Simply swaps R(ight) and L(eft) in the first character of
216 while ( ( oline = (TObjString*)it.Next() ) )
218 TString& s = oline->String();
219 if ( s.Contains("RC") )
221 // Change right to left
222 s.ReplaceAll("RC","LC");
224 else if ( s.Contains("LC") )
226 // Change left to right
227 s.ReplaceAll("LC","RC");
234 // Change line number, according to parameters srcLine and destLine
235 // Note that because of road opening (for planes 3 and 4 at least),
236 // we loop for srcLine +-1
238 for ( Int_t line = -1; line <=1; ++line )
240 std::ostringstream src,dest;
241 src << "L" << srcLine+line;
242 dest << "L" << destLine-line;
243 if ( src.str() == dest.str() ) continue;
245 for ( Int_t i = 0; i < lines.GetSize(); ++i )
247 TObjString* oline = (TObjString*)lines.At(i);
249 TString& s = oline->String();
251 if ( !s.Contains(fgkKeywordPcb) )
253 // Only consider PCB lines.
257 if ( s.Contains(src.str().c_str()) )
259 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
260 src.str().c_str(),dest.str().c_str(),s.Data()));
262 s.ReplaceAll(src.str().c_str(),dest.str().c_str());
264 AliDebugClass(4,s.Data());
266 TString boardName(GetBoardNameFromPCBLine(s));
270 // We must also change board numbers, with the tricky
271 // thing that up and down must be swapped...
272 // Up can only be 1 card so it must be B1
273 // Down must be the uppper card of the line before, so
274 // the biggest possible board number for this Line,Column
279 AliDebugClass(4,Form("Forcing B1 in %s\n",s.Data()));
280 s.ReplaceAll(boardName(boardName.Length()-2,2),"B1");
281 AliDebugClass(4,s.Data());
285 // find the largest valid board number
286 for ( int b = 4; b>=1; --b )
288 std::ostringstream bs;
289 bs << boardName(0,boardName.Length()-1) << b;
290 if ( LocalBoardNumber(bs.str().c_str()) >= 0 )
292 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
293 boardName(boardName.Length()-2,2).Data(),
296 s.ReplaceAll(boardName(boardName.Length()-2,2),
303 // Check that the replacement we did is ok. If not,
305 Int_t lbn = LocalBoardNumber(GetBoardNameFromPCBLine(s));
308 AliDebugClass(4,Form("Removing line %s\n",s.Data()));
319 //___________________________________________________________________________
321 AliMpTriggerReader::IsLayerLine(const TString& sline)
323 // Whether sline contains LAYER keyword
325 if ( sline.BeginsWith(fgkKeywordLayer) )
335 //___________________________________________________________________________
337 AliMpTriggerReader::DecodeFlipLine(const TString& sline,
339 Bool_t& flipX, Bool_t& flipY)
341 // Decode a line containing FLIP_X and/or FLIP_Y keywords
343 Ssiz_t blankPos = sline.First(' ');
344 if ( blankPos < 0 ) return 0;
346 TString keyword(sline(0,blankPos));
348 if ( keyword == fgkKeywordFlipX )
351 } else if ( keyword == fgkKeywordFlipY )
360 slatType2 = sline(blankPos+1,sline.Length()-blankPos-1);
364 //___________________________________________________________________________
366 AliMpTriggerReader::DecodeScaleLine(const TString& sline,
367 Double_t& scale, TString& slatType)
369 // Decode sline containing SCALE keyword
371 if ( sline(0,fgkKeywordScale.Length()) == fgkKeywordScale )
373 TString tmp(sline(fgkKeywordScale.Length()+1,
374 sline.Length()-fgkKeywordScale.Length()-1));
375 Ssiz_t blankPos = tmp.First(' ');
378 AliErrorClass(Form("Syntax error in slat file, should get a slatType after "
379 " SCALE keyword : %s\n",tmp.Data()));
384 slatType = tmp(0,blankPos);
385 scale = TString(tmp(blankPos+1,tmp.Length()-blankPos-1)).Atof();
393 //_____________________________________________________________________________
395 AliMpTriggerReader::GetLine(const TString& slatType)
398 // Assuming slatType is a 4 character string of the form XSLN
399 // where X=1,2,3 or 4
401 // N is the line number
403 if ( isdigit(slatType[0]) &&
404 ( slatType[1] == 'R' || slatType[1] == 'L' ) &&
407 return atoi(slatType(3,1).Data());
412 //_____________________________________________________________________________
414 AliMpTriggerReader::LocalBoardNumber(const char* localBoardName)
416 // From local board name to local board number
418 if ( !fgLocalBoardMap.GetSize() )
420 ReadLocalBoardMapping();
423 TPair* pair = (TPair*)fgLocalBoardMap.FindObject(localBoardName);
427 return atoi(((TObjString*)pair->Value())->String().Data());
432 //_____________________________________________________________________________
434 AliMpTriggerReader::PCB(const char* pcbType)
437 // Get access to an AliMpPCB object, given its type (e.g. N1, SB2, etc...)
439 // Note that the returned object is either a new one (read from file) or a
440 // reused one if it is already present in the internal map.
443 TPair* pair = (TPair*)fgPCBMap.FindObject(pcbType);
446 AliDebugClass(1,Form("Getting pcb %s from internal map",pcbType));
447 return (AliMpPCB*)pair->Value();
451 AliDebugClass(1,Form("Reading pcb %s from file",pcbType));
452 return ReadPCB(pcbType);
456 //_____________________________________________________________________________
458 AliMpTriggerReader::ReadLines(const char* slatType,
459 AliMpPlaneType planeType,
462 Bool_t& flipX, Bool_t& flipY,
463 Int_t& srcLine, Int_t& destLine)
466 // Reads in lines from file for a given slat
467 // Returns the list of lines (lines), together with some global
468 // information as the scale, whether to flip the lines, etc...
470 AliDebugClass(1,Form("SlatType %s Scale %e FlipX %d FlipY %d srcLine %d"
471 " destLine %d\n",slatType,scale,flipX,flipY,
474 TString filename(AliMpFiles::SlatFilePath(kStationTrigger,slatType,
476 std::ifstream in(filename.Data());
479 AliErrorClass(Form("Cannot read slat from %s",filename.Data()));
484 while ( in.getline(line,80) )
486 TString sline(AliMpHelper::Normalize(line));
488 if ( sline.Length() == 0 || sline[0] == '#' ) continue;
490 Bool_t isKeywordThere =
491 sline.Contains(fgkKeywordPcb) ||
492 sline.Contains(fgkKeywordLayer) ||
493 sline.Contains(fgkKeywordScale) ||
494 sline.Contains(fgkKeywordFlipX) ||
495 sline.Contains(fgkKeywordFlipY);
497 if ( !isKeywordThere )
499 AliErrorClass(Form("Got a line with no keyword : %s."
500 "That's not valid\n",line));
507 Int_t isScaleLine = DecodeScaleLine(sline,scale2,slatType2);
511 if ( isScaleLine < 0 )
513 AliFatalClass(Form("Syntax error near %s keyword\n",fgkKeywordScale.Data()));
515 else if ( isScaleLine > 0 && slatType2 != slatType )
517 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
523 Int_t isFlipLine = DecodeFlipLine(sline,slatType2,fx,fy);
528 srcLine = GetLine(slatType2);
529 destLine = GetLine(slatType);
533 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
537 lines.Add(new TObjString(sline.Data()));
545 //_____________________________________________________________________________
547 AliMpTriggerReader::ReadLocalBoardMapping()
549 // Reads the file that contains the mapping local board name <-> number
551 TString filename(AliMpFiles::LocalTriggerBoardMapping());
553 AliDebugClass(1,Form("Reading from %s\n",filename.Data()));
555 fgLocalBoardMap.Delete();
557 ifstream in(filename.Data());
560 AliErrorClass(Form("Cannot read file %s\n",filename.Data()));
566 while ( in.getline(line,80) )
568 if ( line[0] == '#' ) continue;
571 TObjArray* tokens = sline.Tokenize(' ');
572 TString& number = ((TObjString*)(tokens->At(0)))->String();
573 TString& name = ((TObjString*)(tokens->At(1)))->String();
574 fgLocalBoardMap.Add(new TObjString(name), new TObjString(number));
575 AliDebugClass(10,Form("Board %s has number %s\n",name.Data(),number.Data()));
582 //_____________________________________________________________________________
584 AliMpTriggerReader::ReadPCB(const char* pcbType)
587 // Create a new AliMpPCB object, by reading it from file.
590 AliDebugClass(1,Form("pcbType=%s\n",pcbType));
592 TString pcbName(pcbType);
594 Ssiz_t pos = pcbName.First('x');
596 Double_t scale = 1.0;
600 scale = TString(pcbName(pos+1,pcbName.Length()-pos-1)).Atof();
601 pcbName = pcbName(0,pos);
604 std::ifstream in(AliMpFiles::SlatPCBFilePath(kStationTrigger,pcbName).Data());
607 AliErrorClass(Form("Cannot open file for PCB %s",pcbName.Data()));
611 AliMpMotifReader reader(kStationTrigger,kNonBendingPlane);
612 // note that the nonbending
613 // parameter is of no use for trigger, as far as reading motif is
614 // concerned, as all motifs are supposed to be in the same directory
615 // (as they are shared by bending/non-bending planes).
619 const TString kSizeKeyword("SIZES");
620 const TString kMotifKeyword("MOTIF");
621 const TString kMotifSpecialKeyword("SPECIAL_MOTIF");
625 while ( in.getline(line,80) )
627 if ( line[0] == '#' ) continue;
631 if ( sline(0,kSizeKeyword.Length()) == kSizeKeyword )
633 std::istringstream sin(sline(kSizeKeyword.Length(),
634 sline.Length()-kSizeKeyword.Length()-1).Data());
635 float padSizeX = 0.0;
636 float padSizeY = 0.0;
637 float pcbSizeX = 0.0;
638 float pcbSizeY = 0.0;
639 sin >> padSizeX >> padSizeY >> pcbSizeX >> pcbSizeY;
641 pcb = new AliMpPCB(pcbType,padSizeX*scale,padSizeY*scale,
642 pcbSizeX*scale,pcbSizeY*scale);
645 if ( sline(0,kMotifSpecialKeyword.Length()) == kMotifSpecialKeyword )
647 std::istringstream sin(sline(kMotifSpecialKeyword.Length(),
648 sline.Length()-kMotifSpecialKeyword.Length()).Data());
649 TString sMotifSpecial;
651 sin >> sMotifSpecial >> sMotifType;
653 AliMpMotifType* motifType = reader.BuildMotifType(sMotifType);
654 AliMpMotifSpecial* specialMotif =
655 reader.BuildMotifSpecial(sMotifSpecial,motifType,scale);
658 pcb = new AliMpPCB(pcbType,specialMotif);
661 if ( sline(0,kMotifKeyword.Length()) == kMotifKeyword )
663 std::istringstream sin(sline(kMotifKeyword.Length(),
664 sline.Length()-kMotifKeyword.Length()).Data());
668 sin >> sMotifType >> ix >> iy;
670 AliMpMotifType* motifType = reader.BuildMotifType(sMotifType.Data());
673 pcb->Add(motifType,ix,iy);
679 fgPCBMap.Add(new TObjString(pcbType),pcb);
683 //_____________________________________________________________________________
685 AliMpTriggerReader::ReadSlat(const char* slatType, AliMpPlaneType planeType)
688 // Create a new AliMpTrigger object, by reading it from file.
691 Double_t scale = 1.0;
692 Bool_t flipX = kFALSE;
693 Bool_t flipY = kFALSE;
698 // Read the file and its include (if any) and store the result
699 // in a TObjArray of TObjStrings.
700 ReadLines(slatType,planeType,lines,scale,flipX,flipY,srcLine,destLine);
702 // Here some more sanity checks could be done.
703 // For the moment we only insure that the first line contains
705 TString& firstLine = ((TObjString*)lines.First())->String();
706 if ( !IsLayerLine(firstLine) )
708 std::ostringstream s;
709 s << fgkKeywordLayer;
710 lines.AddFirst(new TObjString(s.str().c_str()));
713 AliDebugClass(2,Form("Scale=%g\n",scale));
715 FlipLines(lines,flipX,flipY,srcLine,destLine);
717 // Now splits the lines in packets corresponding to different layers
718 // (if any), and create sub-slats.
724 while ( ( osline = (TObjString*)it.Next() ) )
726 TString& s = osline->String();
727 if ( IsLayerLine(s) )
729 layers.Add(new TList);
734 ((TList*)layers.At(ilayer))->Add(new TObjString(s));
738 AliDebugClass(2,Form("nlayers=%d\n",layers.GetEntriesFast()));
740 AliMpTrigger* triggerSlat = new AliMpTrigger(slatType, planeType);
742 for ( Int_t ilayer = 0; ilayer < layers.GetEntriesFast(); ++ilayer )
744 TList& lines = *((TList*)layers.At(ilayer));
745 std::ostringstream slatName;
746 slatName << slatType << "-LAYER" << ilayer;
747 AliMpSlat* slat = BuildSlat(slatName.str().c_str(),planeType,lines,scale);
750 triggerSlat->AdoptLayer(slat);
754 AliErrorClass(Form("Could not read %s\n",slatName.str().c_str()));
760 layers.SetOwner(kTRUE);
766 //_____________________________________________________________________________
768 AliMpTriggerReader::Reset()
770 // Resets the PCB internal map