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.4 2006/05/24 13:58:52 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
53 ClassImp(AliMpTriggerReader)
56 TMap AliMpTriggerReader::fgPCBMap;
57 TMap AliMpTriggerReader::fgLocalBoardMap;
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");
65 //_____________________________________________________________________________
66 AliMpTriggerReader::AliMpTriggerReader() : TObject()
73 //_____________________________________________________________________________
74 AliMpTriggerReader::~AliMpTriggerReader()
80 fgLocalBoardMap.Delete();
83 //_____________________________________________________________________________
85 AliMpTriggerReader::BuildSlat(const char* slatName,
86 AliMpPlaneType planeType,
90 // Construct a slat from the list of lines, taking into account
93 AliMpSlat* slat = new AliMpSlat(slatName, planeType);
97 while ( ( osline = (TObjString*)it.Next() ) )
99 // note that at this stage lines should not be empty.
100 TString sline(osline->String());
102 TObjArray* tokens = sline.Tokenize(' ');
104 TString& keyword = ((TObjString*)tokens->At(0))->String();
106 if ( keyword == fgkKeywordPcb )
108 if ( tokens->GetEntriesFast() != 3 )
110 AliErrorClass(Form("Syntax error : expecting PCB type localboard-list"
111 " in following line:\n%s",sline.Data()));
116 TString pcbName = ((TObjString*)tokens->At(1))->String();
118 TObjArray* localBoardList = ((TObjString*)tokens->At(2))->String().Tokenize(',');
122 std::ostringstream s;
123 s << pcbName.Data() << "x" << scale;
124 pcbName = s.str().c_str();
127 AliMpPCB* pcbType = PCB(pcbName.Data());
130 AliErrorClass(Form("Cannot read pcbType=%s",pcbName.Data()));
135 TArrayI allLocalBoards;
137 for ( Int_t ilb = 0; ilb < localBoardList->GetEntriesFast(); ++ilb)
139 TArrayI localBoardNumbers;
140 TString& localBoards = ((TObjString*)localBoardList->At(ilb))->String();
141 Ssiz_t pos = localBoards.First('-');
144 pos = localBoards.Length();
146 AliMpHelper::DecodeName(localBoards(pos-1,localBoards.Length()-pos+1).Data(),
147 ';',localBoardNumbers);
148 for ( int i = 0; i < localBoardNumbers.GetSize(); ++i )
150 std::ostringstream name;
151 name << localBoards(0,pos-1) << localBoardNumbers[i];
152 AliDebugClass(3,name.str().c_str());
153 localBoardNumbers[i] = LocalBoardNumber(name.str().c_str());
154 AliDebugClass(3,Form("LOCALBOARDNUMBER %d\n",localBoardNumbers[i]));
155 allLocalBoards.Set(allLocalBoards.GetSize()+1);
156 allLocalBoards[allLocalBoards.GetSize()-1] = localBoardNumbers[i];
157 if (localBoardNumbers[i] < 0 )
159 AliErrorClass(Form("Got a negative local board number in %s ? Unlikely"
160 " to be correct... : %s\n",slatName,name.str().c_str()));
165 delete localBoardList;
166 slat->Add(pcbType,allLocalBoards);
170 if ( slat->DX()== 0 || slat->DY() == 0 )
172 AliFatalClass(Form("Slat %s has invalid null size\n",slat->GetID()));
177 //_____________________________________________________________________________
179 AliMpTriggerReader::GetBoardNameFromPCBLine(const TString& s)
181 // Decode the string to get the board name
184 TObjArray* tokens = s.Tokenize(' ');
186 TString& keyword = ((TObjString*)tokens->At(0))->String();
188 if ( keyword == fgkKeywordPcb &&
189 tokens->GetEntriesFast() == 3 )
191 boardName = ((TObjString*)tokens->At(2))->String();
199 //_____________________________________________________________________________
201 AliMpTriggerReader::FlipLines(TList& lines, Bool_t flipX, Bool_t flipY,
202 Int_t srcLine, Int_t destLine)
205 // Change the local board names contained in lines,
206 // to go from right to left, and/or
207 // from top to bottom
213 // Simply swaps R(ight) and L(eft) in the first character of
218 while ( ( oline = (TObjString*)it.Next() ) )
220 TString& s = oline->String();
221 if ( s.Contains("RC") )
223 // Change right to left
224 s.ReplaceAll("RC","LC");
226 else if ( s.Contains("LC") )
228 // Change left to right
229 s.ReplaceAll("LC","RC");
236 // Change line number, according to parameters srcLine and destLine
237 // Note that because of road opening (for planes 3 and 4 at least),
238 // we loop for srcLine +-1
240 for ( Int_t line = -1; line <=1; ++line )
242 std::ostringstream src,dest;
243 src << "L" << srcLine+line;
244 dest << "L" << destLine-line;
245 if ( src.str() == dest.str() ) continue;
247 for ( Int_t i = 0; i < lines.GetSize(); ++i )
249 TObjString* oline = (TObjString*)lines.At(i);
251 TString& s = oline->String();
253 if ( !s.Contains(fgkKeywordPcb) )
255 // Only consider PCB lines.
259 if ( s.Contains(src.str().c_str()) )
261 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
262 src.str().c_str(),dest.str().c_str(),s.Data()));
264 s.ReplaceAll(src.str().c_str(),dest.str().c_str());
266 AliDebugClass(4,s.Data());
268 TString boardName(GetBoardNameFromPCBLine(s));
272 // We must also change board numbers, with the tricky
273 // thing that up and down must be swapped...
274 // Up can only be 1 card so it must be B1
275 // Down must be the uppper card of the line before, so
276 // the biggest possible board number for this Line,Column
281 AliDebugClass(4,Form("Forcing B1 in %s\n",s.Data()));
282 s.ReplaceAll(boardName(boardName.Length()-2,2),"B1");
283 AliDebugClass(4,s.Data());
287 // find the largest valid board number
288 for ( int b = 4; b>=1; --b )
290 std::ostringstream bs;
291 bs << boardName(0,boardName.Length()-1) << b;
292 if ( LocalBoardNumber(bs.str().c_str()) >= 0 )
294 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
295 boardName(boardName.Length()-2,2).Data(),
298 s.ReplaceAll(boardName(boardName.Length()-2,2),
305 // Check that the replacement we did is ok. If not,
307 Int_t lbn = LocalBoardNumber(GetBoardNameFromPCBLine(s));
310 AliDebugClass(4,Form("Removing line %s\n",s.Data()));
321 //___________________________________________________________________________
323 AliMpTriggerReader::IsLayerLine(const TString& sline)
325 // Whether sline contains LAYER keyword
327 if ( sline.BeginsWith(fgkKeywordLayer) )
337 //___________________________________________________________________________
339 AliMpTriggerReader::DecodeFlipLine(const TString& sline,
341 Bool_t& flipX, Bool_t& flipY)
343 // Decode a line containing FLIP_X and/or FLIP_Y keywords
345 Ssiz_t blankPos = sline.First(' ');
346 if ( blankPos < 0 ) return 0;
348 TString keyword(sline(0,blankPos));
350 if ( keyword == fgkKeywordFlipX )
353 } else if ( keyword == fgkKeywordFlipY )
362 slatType2 = sline(blankPos+1,sline.Length()-blankPos-1);
366 //___________________________________________________________________________
368 AliMpTriggerReader::DecodeScaleLine(const TString& sline,
369 Double_t& scale, TString& slatType)
371 // Decode sline containing SCALE keyword
373 if ( sline(0,fgkKeywordScale.Length()) == fgkKeywordScale )
375 TString tmp(sline(fgkKeywordScale.Length()+1,
376 sline.Length()-fgkKeywordScale.Length()-1));
377 Ssiz_t blankPos = tmp.First(' ');
380 AliErrorClass(Form("Syntax error in slat file, should get a slatType after "
381 " SCALE keyword : %s\n",tmp.Data()));
386 slatType = tmp(0,blankPos);
387 scale = TString(tmp(blankPos+1,tmp.Length()-blankPos-1)).Atof();
395 //_____________________________________________________________________________
397 AliMpTriggerReader::GetLine(const TString& slatType)
400 // Assuming slatType is a 4 character string of the form XSLN
401 // where X=1,2,3 or 4
403 // N is the line number
405 if ( isdigit(slatType[0]) &&
406 ( slatType[1] == 'R' || slatType[1] == 'L' ) &&
409 return atoi(slatType(3,1).Data());
414 //_____________________________________________________________________________
416 AliMpTriggerReader::LocalBoardNumber(const char* localBoardName)
418 // From local board name to local board number
420 if ( !fgLocalBoardMap.GetSize() )
422 ReadLocalBoardMapping();
425 TPair* pair = (TPair*)fgLocalBoardMap.FindObject(localBoardName);
429 return atoi(((TObjString*)pair->Value())->String().Data());
434 //_____________________________________________________________________________
436 AliMpTriggerReader::PCB(const char* pcbType)
439 // Get access to an AliMpPCB object, given its type (e.g. N1, SB2, etc...)
441 // Note that the returned object is either a new one (read from file) or a
442 // reused one if it is already present in the internal map.
445 TPair* pair = (TPair*)fgPCBMap.FindObject(pcbType);
448 AliDebugClass(2,Form("Getting pcb %s from internal map",pcbType));
449 return (AliMpPCB*)pair->Value();
453 AliDebugClass(2,Form("Reading pcb %s from file",pcbType));
454 return ReadPCB(pcbType);
458 //_____________________________________________________________________________
460 AliMpTriggerReader::ReadLines(const char* slatType,
461 AliMpPlaneType planeType,
464 Bool_t& flipX, Bool_t& flipY,
465 Int_t& srcLine, Int_t& destLine)
468 // Reads in lines from file for a given slat
469 // Returns the list of lines (lines), together with some global
470 // information as the scale, whether to flip the lines, etc...
472 AliDebugClass(2,Form("SlatType %s Scale %e FlipX %d FlipY %d srcLine %d"
473 " destLine %d\n",slatType,scale,flipX,flipY,
476 TString filename(AliMpFiles::SlatFilePath(kStationTrigger,slatType,
478 std::ifstream in(filename.Data());
481 AliErrorClass(Form("Cannot read slat from %s",filename.Data()));
486 while ( in.getline(line,80) )
488 TString sline(AliMpHelper::Normalize(line));
490 if ( sline.Length() == 0 || sline[0] == '#' ) continue;
492 Bool_t isKeywordThere =
493 sline.Contains(fgkKeywordPcb) ||
494 sline.Contains(fgkKeywordLayer) ||
495 sline.Contains(fgkKeywordScale) ||
496 sline.Contains(fgkKeywordFlipX) ||
497 sline.Contains(fgkKeywordFlipY);
499 if ( !isKeywordThere )
501 AliErrorClass(Form("Got a line with no keyword : %s."
502 "That's not valid\n",line));
509 Int_t isScaleLine = DecodeScaleLine(sline,scale2,slatType2);
513 if ( isScaleLine < 0 )
515 AliFatalClass(Form("Syntax error near %s keyword\n",fgkKeywordScale.Data()));
517 else if ( isScaleLine > 0 && slatType2 != slatType )
519 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
525 Int_t isFlipLine = DecodeFlipLine(sline,slatType2,fx,fy);
530 srcLine = GetLine(slatType2);
531 destLine = GetLine(slatType);
535 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
539 lines.Add(new TObjString(sline.Data()));
547 //_____________________________________________________________________________
549 AliMpTriggerReader::ReadLocalBoardMapping()
551 // Reads the file that contains the mapping local board name <-> number
553 TString filename(AliMpFiles::LocalTriggerBoardMapping());
555 AliDebugClass(2,Form("Reading from %s\n",filename.Data()));
557 fgLocalBoardMap.Delete();
559 ifstream in(filename.Data());
562 AliErrorClass(Form("Cannot read file %s\n",filename.Data()));
568 while ( in.getline(line,80) )
570 if ( line[0] == '#' ) continue;
573 if ( sline.Contains("Board") )
575 TObjArray* tokens = sline.Tokenize(' ');
576 TString& number = ((TObjString*)(tokens->At(1)))->String();
577 Int_t n = atoi(number.Data());
578 if ( n == 0 ) continue;
579 TString& name = ((TObjString*)(tokens->At(4)))->String();
580 fgLocalBoardMap.Add(new TObjString(name), new TObjString(number));
581 AliDebugClass(10,Form("Board %s has number %s\n",name.Data(),number.Data()));
589 //_____________________________________________________________________________
591 AliMpTriggerReader::ReadPCB(const char* pcbType)
594 // Create a new AliMpPCB object, by reading it from file.
597 AliDebugClass(2,Form("pcbType=%s\n",pcbType));
599 TString pcbName(pcbType);
601 Ssiz_t pos = pcbName.First('x');
603 Double_t scale = 1.0;
607 scale = TString(pcbName(pos+1,pcbName.Length()-pos-1)).Atof();
608 pcbName = pcbName(0,pos);
611 std::ifstream in(AliMpFiles::SlatPCBFilePath(kStationTrigger,pcbName).Data());
614 AliErrorClass(Form("Cannot open file for PCB %s",pcbName.Data()));
618 AliMpMotifReader reader(kStationTrigger,kNonBendingPlane);
619 // note that the nonbending
620 // parameter is of no use for trigger, as far as reading motif is
621 // concerned, as all motifs are supposed to be in the same directory
622 // (as they are shared by bending/non-bending planes).
626 const TString kSizeKeyword("SIZES");
627 const TString kMotifKeyword("MOTIF");
628 const TString kMotifSpecialKeyword("SPECIAL_MOTIF");
632 while ( in.getline(line,80) )
634 if ( line[0] == '#' ) continue;
638 if ( sline(0,kSizeKeyword.Length()) == kSizeKeyword )
640 std::istringstream sin(sline(kSizeKeyword.Length(),
641 sline.Length()-kSizeKeyword.Length()-1).Data());
642 float padSizeX = 0.0;
643 float padSizeY = 0.0;
644 float pcbSizeX = 0.0;
645 float pcbSizeY = 0.0;
646 sin >> padSizeX >> padSizeY >> pcbSizeX >> pcbSizeY;
648 pcb = new AliMpPCB(pcbType,padSizeX*scale,padSizeY*scale,
649 pcbSizeX*scale,pcbSizeY*scale);
652 if ( sline(0,kMotifSpecialKeyword.Length()) == kMotifSpecialKeyword )
654 std::istringstream sin(sline(kMotifSpecialKeyword.Length(),
655 sline.Length()-kMotifSpecialKeyword.Length()).Data());
656 TString sMotifSpecial;
658 sin >> sMotifSpecial >> sMotifType;
660 AliMpMotifType* motifType = reader.BuildMotifType(sMotifType);
661 AliMpMotifSpecial* specialMotif =
662 reader.BuildMotifSpecial(sMotifSpecial,motifType,scale);
665 pcb = new AliMpPCB(pcbType,specialMotif);
668 if ( sline(0,kMotifKeyword.Length()) == kMotifKeyword )
670 std::istringstream sin(sline(kMotifKeyword.Length(),
671 sline.Length()-kMotifKeyword.Length()).Data());
675 sin >> sMotifType >> ix >> iy;
677 AliMpMotifType* motifType = reader.BuildMotifType(sMotifType.Data());
680 pcb->Add(motifType,ix,iy);
686 fgPCBMap.Add(new TObjString(pcbType),pcb);
690 //_____________________________________________________________________________
692 AliMpTriggerReader::ReadSlat(const char* slatType, AliMpPlaneType planeType)
695 // Create a new AliMpTrigger object, by reading it from file.
698 Double_t scale = 1.0;
699 Bool_t flipX = kFALSE;
700 Bool_t flipY = kFALSE;
705 // Read the file and its include (if any) and store the result
706 // in a TObjArray of TObjStrings.
707 ReadLines(slatType,planeType,lines,scale,flipX,flipY,srcLine,destLine);
709 // Here some more sanity checks could be done.
710 // For the moment we only insure that the first line contains
712 TString& firstLine = ((TObjString*)lines.First())->String();
713 if ( !IsLayerLine(firstLine) )
715 std::ostringstream s;
716 s << fgkKeywordLayer;
717 lines.AddFirst(new TObjString(s.str().c_str()));
720 AliDebugClass(2,Form("Scale=%g\n",scale));
722 FlipLines(lines,flipX,flipY,srcLine,destLine);
724 // Now splits the lines in packets corresponding to different layers
725 // (if any), and create sub-slats.
731 while ( ( osline = (TObjString*)it.Next() ) )
733 TString& s = osline->String();
734 if ( IsLayerLine(s) )
736 layers.Add(new TList);
741 ((TList*)layers.At(ilayer))->Add(new TObjString(s));
745 AliDebugClass(2,Form("nlayers=%d\n",layers.GetEntriesFast()));
747 AliMpTrigger* triggerSlat = new AliMpTrigger(slatType, planeType);
749 for ( Int_t ilayer = 0; ilayer < layers.GetEntriesFast(); ++ilayer )
751 TList& lines = *((TList*)layers.At(ilayer));
752 std::ostringstream slatName;
753 slatName << slatType << "-LAYER" << ilayer;
754 AliMpSlat* slat = BuildSlat(slatName.str().c_str(),planeType,lines,scale);
757 triggerSlat->AdoptLayer(slat);
761 AliErrorClass(Form("Could not read %s\n",slatName.str().c_str()));
767 layers.SetOwner(kTRUE);
773 //_____________________________________________________________________________
775 AliMpTriggerReader::Reset()
777 // Resets the PCB internal map