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 "AliMpSlatMotifMap.h"
26 #include "AliMpMotifSpecial.h"
27 #include "AliMpMotifPosition.h"
28 #include "AliMpMotif.h"
29 #include "AliMpHelper.h"
30 #include "AliMpSt345Reader.h"
31 #include "AliMpTrigger.h"
35 #include "Riostream.h"
37 #include "TObjString.h"
43 //-----------------------------------------------------------------------------
44 /// \class AliMpTriggerReader
45 /// Read trigger slat ASCII files
46 /// Basically provides two methods:
47 /// - AliMpTrigger* ReadSlat()
48 /// - AliMpPCB* ReadPCB()
50 /// \author Laurent Aphecetche
51 //-----------------------------------------------------------------------------
54 ClassImp(AliMpTriggerReader)
57 const TString AliMpTriggerReader::fgkKeywordLayer("LAYER");
58 const TString AliMpTriggerReader::fgkKeywordScale("SCALE");
59 const TString AliMpTriggerReader::fgkKeywordPcb("PCB");
60 const TString AliMpTriggerReader::fgkKeywordFlipX("FLIP_X");
61 const TString AliMpTriggerReader::fgkKeywordFlipY("FLIP_Y");
63 //_____________________________________________________________________________
64 AliMpTriggerReader::AliMpTriggerReader(AliMpSlatMotifMap& motifMap)
72 fLocalBoardMap.SetOwner(kTRUE);
75 //_____________________________________________________________________________
76 AliMpTriggerReader::~AliMpTriggerReader()
81 fLocalBoardMap.DeleteAll();
84 //_____________________________________________________________________________
86 AliMpTriggerReader::BuildSlat(const char* slatName,
87 AliMp::PlaneType planeType,
91 /// Construct a slat from the list of lines, taking into account
92 /// the scale factor. The returned pointer must be deleted by the client
94 AliDebug(1,Form("slat %s %s scale %e",
95 slatName,PlaneTypeName(planeType).Data(),scale))
98 AliMpSlat* slat = new AliMpSlat(slatName, planeType);
102 // StdoutToAliDebug(3,lines.Print(););
105 while ( ( osline = (TObjString*)it.Next() ) )
107 // note that at this stage lines should not be empty.
108 TString sline(osline->String());
110 TObjArray* tokens = sline.Tokenize(' ');
112 TString& keyword = ((TObjString*)tokens->At(0))->String();
114 if ( keyword == fgkKeywordPcb )
116 if ( tokens->GetEntriesFast() != 3 )
118 AliErrorClass(Form("Syntax error : expecting PCB type localboard-list"
119 " in following line:\n%s",sline.Data()));
124 TString pcbName = ((TObjString*)tokens->At(1))->String();
126 TObjArray* localBoardList = ((TObjString*)tokens->At(2))->String().Tokenize(',');
130 std::ostringstream s;
131 s << pcbName.Data() << "x" << scale;
132 pcbName = s.str().c_str();
135 AliMpPCB* pcbType = ReadPCB(pcbName.Data());
138 AliErrorClass(Form("Cannot read pcbType=%s",pcbName.Data()));
143 TArrayI allLocalBoards;
145 for ( Int_t ilb = 0; ilb < localBoardList->GetEntriesFast(); ++ilb)
147 TArrayI localBoardNumbers;
148 TString& localBoards = ((TObjString*)localBoardList->At(ilb))->String();
149 Ssiz_t pos = localBoards.First('-');
152 pos = localBoards.Length();
154 AliMpHelper::DecodeName(localBoards(pos-1,localBoards.Length()-pos+1).Data(),
155 ';',localBoardNumbers);
156 for ( int i = 0; i < localBoardNumbers.GetSize(); ++i )
158 std::ostringstream name;
159 name << localBoards(0,pos-1) << localBoardNumbers[i];
160 AliDebugClass(3,name.str().c_str());
161 localBoardNumbers[i] = LocalBoardNumber(name.str().c_str());
162 AliDebugClass(3,Form("LOCALBOARDNUMBER %d\n",localBoardNumbers[i]));
163 allLocalBoards.Set(allLocalBoards.GetSize()+1);
164 allLocalBoards[allLocalBoards.GetSize()-1] = localBoardNumbers[i];
165 if (localBoardNumbers[i] < 0 )
167 AliErrorClass(Form("Got a negative local board number in %s ? Unlikely"
168 " to be correct... : %s\n",slatName,name.str().c_str()));
172 AliDebug(3,"Deleting tokens");
174 AliDebug(3,"Deleting localBoardList");
175 delete localBoardList;
176 AliDebug(3,"Adding pcb to slat");
177 slat->Add(*pcbType,allLocalBoards);
178 AliDebug(3,Form("Deleting pcbType=%p %s",pcbType,pcbName.Data()));
183 if ( slat->DX()== 0 || slat->DY() == 0 )
185 AliFatalClass(Form("Slat %s has invalid null size\n",slat->GetID()));
190 //_____________________________________________________________________________
192 AliMpTriggerReader::GetBoardNameFromPCBLine(const TString& s)
194 /// Decode the string to get the board name
197 TObjArray* tokens = s.Tokenize(' ');
199 TString& keyword = ((TObjString*)tokens->At(0))->String();
201 if ( keyword == fgkKeywordPcb &&
202 tokens->GetEntriesFast() == 3 )
204 boardName = ((TObjString*)tokens->At(2))->String();
212 //_____________________________________________________________________________
214 AliMpTriggerReader::FlipLines(TList& lines, Bool_t flipX, Bool_t flipY,
215 Int_t srcLine, Int_t destLine)
218 /// Change the local board names contained in lines,
219 /// to go from right to left, and/or
220 /// from top to bottom
226 // Simply swaps R(ight) and L(eft) in the first character of
231 while ( ( oline = (TObjString*)it.Next() ) )
233 TString& s = oline->String();
234 if ( s.Contains("RC") )
236 // Change right to left
237 s.ReplaceAll("RC","LC");
239 else if ( s.Contains("LC") )
241 // Change left to right
242 s.ReplaceAll("LC","RC");
249 // Change line number, according to parameters srcLine and destLine
250 // Note that because of road opening (for planes 3 and 4 at least),
251 // we loop for srcLine +-1
253 for ( Int_t line = -1; line <=1; ++line )
255 std::ostringstream src,dest;
256 src << "L" << srcLine+line;
257 dest << "L" << destLine-line;
258 if ( src.str() == dest.str() ) continue;
260 for ( Int_t i = 0; i < lines.GetSize(); ++i )
262 TObjString* oline = (TObjString*)lines.At(i);
264 TString& s = oline->String();
266 if ( !s.Contains(fgkKeywordPcb) )
268 // Only consider PCB lines.
272 if ( s.Contains(src.str().c_str()) )
274 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
275 src.str().c_str(),dest.str().c_str(),s.Data()));
277 s.ReplaceAll(src.str().c_str(),dest.str().c_str());
279 AliDebugClass(4,s.Data());
281 TString boardName(GetBoardNameFromPCBLine(s));
285 // We must also change board numbers, with the tricky
286 // thing that up and down must be swapped...
287 // Up can only be 1 card so it must be B1
288 // Down must be the uppper card of the line before, so
289 // the biggest possible board number for this Line,Column
294 AliDebugClass(4,Form("Forcing B1 in %s\n",s.Data()));
295 s.ReplaceAll(boardName(boardName.Length()-2,2),"B1");
296 AliDebugClass(4,s.Data());
300 // find the largest valid board number
301 for ( int b = 4; b>=1; --b )
303 std::ostringstream bs;
304 bs << boardName(0,boardName.Length()-1) << b;
305 if ( LocalBoardNumber(bs.str().c_str()) >= 0 )
307 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
308 boardName(boardName.Length()-2,2).Data(),
311 s.ReplaceAll(boardName(boardName.Length()-2,2),
318 // Check that the replacement we did is ok. If not,
320 Int_t lbn = LocalBoardNumber(GetBoardNameFromPCBLine(s));
323 AliDebugClass(4,Form("Removing line %s\n",s.Data()));
334 //___________________________________________________________________________
336 AliMpTriggerReader::IsLayerLine(const TString& sline)
338 /// Whether sline contains LAYER keyword
340 if ( sline.BeginsWith(fgkKeywordLayer) )
350 //___________________________________________________________________________
352 AliMpTriggerReader::DecodeFlipLine(const TString& sline,
354 Bool_t& flipX, Bool_t& flipY)
356 /// Decode a line containing FLIP_X and/or FLIP_Y keywords
358 Ssiz_t blankPos = sline.First(' ');
359 if ( blankPos < 0 ) return 0;
361 TString keyword(sline(0,blankPos));
363 if ( keyword == fgkKeywordFlipX )
366 } else if ( keyword == fgkKeywordFlipY )
375 slatType2 = sline(blankPos+1,sline.Length()-blankPos-1);
379 //___________________________________________________________________________
381 AliMpTriggerReader::DecodeScaleLine(const TString& sline,
382 Double_t& scale, TString& slatType)
384 /// Decode sline containing SCALE keyword
386 if ( sline(0,fgkKeywordScale.Length()) == fgkKeywordScale )
388 TString tmp(sline(fgkKeywordScale.Length()+1,
389 sline.Length()-fgkKeywordScale.Length()-1));
390 Ssiz_t blankPos = tmp.First(' ');
393 AliErrorClass(Form("Syntax error in slat file, should get a slatType after "
394 " SCALE keyword : %s\n",tmp.Data()));
399 slatType = tmp(0,blankPos);
400 scale = TString(tmp(blankPos+1,tmp.Length()-blankPos-1)).Atof();
408 //_____________________________________________________________________________
410 AliMpTriggerReader::GetLine(const TString& slatType)
413 /// Assuming slatType is a 4 character string of the form XSLN
414 /// where X=1,2,3 or 4
416 /// N is the line number
419 if ( isdigit(slatType[0]) &&
420 ( slatType[1] == 'R' || slatType[1] == 'L' ) &&
423 return atoi(slatType(3,1).Data());
428 //_____________________________________________________________________________
430 AliMpTriggerReader::LocalBoardNumber(const char* localBoardName)
432 /// From local board name to local board number
434 if ( !fLocalBoardMap.GetSize() )
436 ReadLocalBoardMapping();
439 TPair* pair = (TPair*)fLocalBoardMap.FindObject(localBoardName);
443 return atoi(((TObjString*)pair->Value())->String().Data());
448 //_____________________________________________________________________________
450 AliMpTriggerReader::ReadLines(const char* slatType,
451 AliMp::PlaneType planeType,
454 Bool_t& flipX, Bool_t& flipY,
455 Int_t& srcLine, Int_t& destLine)
458 /// Reads in lines from file for a given slat
459 /// Returns the list of lines (lines), together with some global
460 /// information as the scale, whether to flip the lines, etc...
462 AliDebugClass(2,Form("SlatType %s Scale %e FlipX %d FlipY %d srcLine %d"
463 " destLine %d\n",slatType,scale,flipX,flipY,
466 TString filename(AliMpFiles::SlatFilePath(AliMp::kStationTrigger,slatType,
468 std::ifstream in(filename.Data());
471 AliErrorClass(Form("Cannot read slat from %s",filename.Data()));
476 while ( in.getline(line,80) )
478 TString sline(AliMpHelper::Normalize(line));
480 if ( sline.Length() == 0 || sline[0] == '#' ) continue;
482 Bool_t isKeywordThere =
483 sline.Contains(fgkKeywordPcb) ||
484 sline.Contains(fgkKeywordLayer) ||
485 sline.Contains(fgkKeywordScale) ||
486 sline.Contains(fgkKeywordFlipX) ||
487 sline.Contains(fgkKeywordFlipY);
489 if ( !isKeywordThere )
491 AliErrorClass(Form("Got a line with no keyword : %s."
492 "That's not valid\n",line));
499 Int_t isScaleLine = DecodeScaleLine(sline,scale2,slatType2);
503 if ( isScaleLine < 0 )
505 AliFatalClass(Form("Syntax error near %s keyword\n",fgkKeywordScale.Data()));
507 else if ( isScaleLine > 0 && slatType2 != slatType )
509 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
515 Int_t isFlipLine = DecodeFlipLine(sline,slatType2,fx,fy);
520 srcLine = GetLine(slatType2);
521 destLine = GetLine(slatType);
525 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
529 lines.Add(new TObjString(sline.Data()));
537 //_____________________________________________________________________________
539 AliMpTriggerReader::ReadLocalBoardMapping()
541 /// Reads the file that contains the mapping local board name <-> number
543 TString filename(AliMpFiles::LocalTriggerBoardMapping());
545 AliDebugClass(2,Form("Reading from %s\n",filename.Data()));
547 fLocalBoardMap.DeleteAll();
549 ifstream in(filename.Data());
552 AliErrorClass(Form("Cannot read file %s\n",filename.Data()));
558 while ( in.getline(line,80) )
560 if ( line[0] == '#' ) continue;
563 if ( sline.Contains("Board") )
565 TObjArray* tokens = sline.Tokenize(' ');
566 TString& number = ((TObjString*)(tokens->At(1)))->String();
567 Int_t n = atoi(number.Data());
570 TString& name = ((TObjString*)(tokens->At(4)))->String();
571 fLocalBoardMap.Add(new TObjString(name), new TObjString(number));
572 AliDebugClass(10,Form("Board %s has number %s\n",name.Data(),number.Data()));
581 //_____________________________________________________________________________
583 AliMpTriggerReader::ReadPCB(const char* pcbType)
586 /// Create a new AliMpPCB object, by reading it from file.
587 /// Returned pointer must be deleted by client.
589 AliDebugClass(2,Form("pcbType=%s\n",pcbType));
591 TString pcbName(pcbType);
593 Ssiz_t pos = pcbName.First('x');
595 Double_t scale = 1.0;
599 scale = TString(pcbName(pos+1,pcbName.Length()-pos-1)).Atof();
600 pcbName = pcbName(0,pos);
603 std::ifstream in(AliMpFiles::SlatPCBFilePath(AliMp::kStationTrigger,pcbName).Data());
606 AliErrorClass(Form("Cannot open file for PCB %s",pcbName.Data()));
610 AliMpMotifReader reader(AliMp::kStationTrigger,AliMp::kNonBendingPlane);
611 // note that the nonbending
612 // parameter is of no use for trigger, as far as reading motif is
613 // concerned, as all motifs are supposed to be in the same directory
614 // (as they are shared by bending/non-bending planes).
618 const TString kSizeKeyword("SIZES");
619 const TString kMotifKeyword("MOTIF");
620 const TString kMotifSpecialKeyword("SPECIAL_MOTIF");
624 while ( in.getline(line,80) )
626 if ( line[0] == '#' ) continue;
630 if ( sline(0,kSizeKeyword.Length()) == kSizeKeyword )
632 std::istringstream sin(sline(kSizeKeyword.Length(),
633 sline.Length()-kSizeKeyword.Length()-1).Data());
634 float padSizeX = 0.0;
635 float padSizeY = 0.0;
636 float pcbSizeX = 0.0;
637 float pcbSizeY = 0.0;
638 sin >> padSizeX >> padSizeY >> pcbSizeX >> pcbSizeY;
641 AliError("pcb not null as expected");
643 pcb = new AliMpPCB(&fMotifMap,pcbType,padSizeX*scale,padSizeY*scale,
644 pcbSizeX*scale,pcbSizeY*scale);
647 if ( sline(0,kMotifSpecialKeyword.Length()) == kMotifSpecialKeyword )
649 std::istringstream sin(sline(kMotifSpecialKeyword.Length(),
650 sline.Length()-kMotifSpecialKeyword.Length()).Data());
651 TString sMotifSpecial;
653 sin >> sMotifSpecial >> sMotifType;
655 TString id = reader.MotifSpecialName(sMotifSpecial,scale);
657 AliMpMotifSpecial* specialMotif =
658 dynamic_cast<AliMpMotifSpecial*>(fMotifMap.FindMotif(id));
661 AliDebug(1,Form("Reading motifSpecial %s (%s) from file",
662 sMotifSpecial.Data(),id.Data()));
663 AliMpMotifType* motifType = fMotifMap.FindMotifType(sMotifType.Data());
666 AliDebug(1,Form("Reading motifType %s (%s) from file",
667 sMotifType.Data(),id.Data()));
668 motifType = reader.BuildMotifType(sMotifType.Data());
669 fMotifMap.AddMotifType(motifType);
673 AliDebug(1,Form("Got motifType %s (%s) from motifMap",
674 sMotifType.Data(),id.Data()));
676 specialMotif = reader.BuildMotifSpecial(sMotifSpecial,motifType,scale);
677 fMotifMap.AddMotif(specialMotif);
681 AliDebug(1,Form("Got motifSpecial %s from motifMap",sMotifSpecial.Data()));
685 AliError("pcb not null as expected");
687 pcb = new AliMpPCB(pcbType,specialMotif);
690 if ( sline(0,kMotifKeyword.Length()) == kMotifKeyword )
692 std::istringstream sin(sline(kMotifKeyword.Length(),
693 sline.Length()-kMotifKeyword.Length()).Data());
697 sin >> sMotifType >> ix >> iy;
699 AliMpMotifType* motifType = fMotifMap.FindMotifType(sMotifType.Data());
702 AliDebug(1,Form("Reading motifType %s from file",sMotifType.Data()));
703 motifType = reader.BuildMotifType(sMotifType.Data());
704 fMotifMap.AddMotifType(motifType);
708 AliDebug(1,Form("Got motifType %s from motifMap",sMotifType.Data()));
711 pcb->Add(motifType,ix,iy);
720 //_____________________________________________________________________________
722 AliMpTriggerReader::ReadSlat(const char* slatType, AliMp::PlaneType planeType)
725 /// Create a new AliMpTrigger object, by reading it from file.
726 /// Returned object must be deleted by client.
728 Double_t scale = 1.0;
729 Bool_t flipX = kFALSE;
730 Bool_t flipY = kFALSE;
732 lines.SetOwner(kTRUE);
736 // Read the file and its include (if any) and store the result
737 // in a TObjArray of TObjStrings.
738 ReadLines(slatType,planeType,lines,scale,flipX,flipY,srcLine,destLine);
740 // Here some more sanity checks could be done.
741 // For the moment we only insure that the first line contains
743 TString& firstLine = ((TObjString*)lines.First())->String();
744 if ( !IsLayerLine(firstLine) )
746 std::ostringstream s;
747 s << fgkKeywordLayer;
748 lines.AddFirst(new TObjString(s.str().c_str()));
751 AliDebugClass(2,Form("Scale=%g\n",scale));
753 FlipLines(lines,flipX,flipY,srcLine,destLine);
755 // Now splits the lines in packets corresponding to different layers
756 // (if any), and create sub-slats.
758 layers.SetOwner(kTRUE);
763 while ( ( osline = (TObjString*)it.Next() ) )
765 TString& s = osline->String();
766 if ( IsLayerLine(s) )
768 TList* list = new TList;
769 list->SetOwner(kTRUE);
775 ((TList*)layers.At(ilayer))->Add(new TObjString(s));
779 AliDebugClass(2,Form("nlayers=%d\n",layers.GetEntriesFast()));
781 AliMpTrigger* triggerSlat = new AliMpTrigger(slatType, planeType);
783 for ( Int_t ilayer = 0; ilayer < layers.GetEntriesFast(); ++ilayer )
785 TList& lines = *((TList*)layers.At(ilayer));
786 std::ostringstream slatName;
787 slatName << slatType << "-LAYER" << ilayer;
788 AliMpSlat* slat = BuildSlat(slatName.str().c_str(),planeType,lines,scale);
791 Bool_t ok = triggerSlat->AdoptLayer(slat);
794 StdoutToAliError(cout << "could not add slat=" << endl;
796 cout << "to the triggerSlat=" << endl;
797 triggerSlat->Print();
799 AliError("Slat is=");
800 for ( Int_t i = 0; i < slat->GetSize(); ++i )
802 AliMpPCB* pcb = slat->GetPCB(i);
803 AliError(Form("ERR pcb %d size %e,%e (unscaled is %e,%e)",
804 i,pcb->DX()*2,pcb->DY()*2,
805 pcb->DX()*2/scale,pcb->DY()*2/scale));
807 AliError("TriggerSlat is=");
808 for ( Int_t j = 0; j < triggerSlat->GetSize(); ++j )
810 AliMpSlat* slat = triggerSlat->GetLayer(j);
811 AliError(Form("Layer %d",j));
812 for ( Int_t i = 0; i < slat->GetSize(); ++i )
814 AliMpPCB* pcb = slat->GetPCB(i);
815 AliError(Form("ERR pcb %d size %e,%e (unscaled is %e,%e)",
816 i,pcb->DX()*2,pcb->DY()*2,
817 pcb->DX()*2/scale,pcb->DY()*2/scale));
820 StdoutToAliError(fMotifMap.Print(););
825 AliErrorClass(Form("Could not read %s\n",slatName.str().c_str()));