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"
22 #include "AliMpConstants.h"
23 #include "AliMpDataStreams.h"
24 #include "AliMpFiles.h"
25 #include "AliMpHelper.h"
26 #include "AliMpMotif.h"
27 #include "AliMpMotifPosition.h"
28 #include "AliMpMotifReader.h"
29 #include "AliMpMotifSpecial.h"
30 #include "AliMpMotifType.h"
32 #include "AliMpSlat.h"
33 #include "AliMpSlatMotifMap.h"
34 #include "AliMpSlatMotifMap.h"
35 #include "AliMpSt345Reader.h"
36 #include "AliMpTrigger.h"
37 #include "Riostream.h"
40 #include "TObjString.h"
46 //-----------------------------------------------------------------------------
47 /// \class AliMpTriggerReader
48 /// Read trigger slat ASCII files
49 /// Basically provides two methods:
50 /// - AliMpTrigger* ReadSlat()
51 /// - AliMpPCB* ReadPCB()
53 /// \author Laurent Aphecetche
54 //-----------------------------------------------------------------------------
57 ClassImp(AliMpTriggerReader)
61 // static private methods
64 //_____________________________________________________________________________
65 const TString& AliMpTriggerReader::GetKeywordLayer()
68 static const TString kKeywordLayer("LAYER");
72 //_____________________________________________________________________________
73 const TString& AliMpTriggerReader::GetKeywordScale()
76 static const TString kKeywordScale("SCALE");
80 //_____________________________________________________________________________
81 const TString& AliMpTriggerReader::GetKeywordPcb()
84 static const TString kKeywordPcb("PCB");
88 //_____________________________________________________________________________
89 const TString& AliMpTriggerReader::GetKeywordFlipX()
92 static const TString kKeywordFlipX("FLIP_X");
96 //_____________________________________________________________________________
97 const TString& AliMpTriggerReader::GetKeywordFlipY()
100 static const TString kKeywordFlipY("FLIP_Y");
101 return kKeywordFlipY;
108 //_____________________________________________________________________________
109 AliMpTriggerReader::AliMpTriggerReader(const AliMpDataStreams& dataStreams, AliMpSlatMotifMap* motifMap)
111 fkDataStreams(dataStreams),
118 fLocalBoardMap.SetOwner(kTRUE);
121 //_____________________________________________________________________________
122 AliMpTriggerReader::~AliMpTriggerReader()
127 fLocalBoardMap.DeleteAll();
130 //_____________________________________________________________________________
132 AliMpTriggerReader::BuildSlat(const char* slatName,
133 AliMp::PlaneType planeType,
137 /// Construct a slat from the list of lines, taking into account
138 /// the scale factor. The returned pointer must be deleted by the client
140 AliDebug(1,Form("slat %s %s scale %e",
141 slatName,PlaneTypeName(planeType).Data(),scale))
144 AliMpSlat* slat = new AliMpSlat(slatName, planeType);
148 // StdoutToAliDebug(3,lines.Print(););
151 while ( ( osline = (TObjString*)it.Next() ) )
153 // note that at this stage lines should not be empty.
154 TString sline(osline->String());
156 TObjArray* tokens = sline.Tokenize(' ');
158 TString& keyword = ((TObjString*)tokens->At(0))->String();
160 if ( keyword == GetKeywordPcb() )
162 if ( tokens->GetEntriesFast() != 3 )
164 AliErrorClass(Form("Syntax error : expecting PCB type localboard-list"
165 " in following line:\n%s",sline.Data()));
170 TString pcbName = ((TObjString*)tokens->At(1))->String();
172 TObjArray* localBoardList = ((TObjString*)tokens->At(2))->String().Tokenize(',');
176 std::ostringstream s;
177 s << pcbName.Data() << "x" << scale;
178 pcbName = s.str().c_str();
181 AliMpPCB* pcbType = ReadPCB(pcbName.Data());
184 AliErrorClass(Form("Cannot read pcbType=%s",pcbName.Data()));
190 TArrayI allLocalBoards;
192 for ( Int_t ilb = 0; ilb < localBoardList->GetEntriesFast(); ++ilb)
194 TArrayI localBoardNumbers;
195 TString& localBoards = ((TObjString*)localBoardList->At(ilb))->String();
196 Ssiz_t pos = localBoards.First('-');
199 pos = localBoards.Length();
201 AliMpHelper::DecodeName(localBoards(pos-1,localBoards.Length()-pos+1).Data(),
202 ';',localBoardNumbers);
203 for ( int i = 0; i < localBoardNumbers.GetSize(); ++i )
205 std::ostringstream name;
206 name << localBoards(0,pos-1) << localBoardNumbers[i];
207 AliDebugClass(3,name.str().c_str());
208 localBoardNumbers[i] = LocalBoardNumber(name.str().c_str());
209 AliDebugClass(3,Form("LOCALBOARDNUMBER %d\n",localBoardNumbers[i]));
210 allLocalBoards.Set(allLocalBoards.GetSize()+1);
211 allLocalBoards[allLocalBoards.GetSize()-1] = localBoardNumbers[i];
212 if (localBoardNumbers[i] < 0 )
214 AliErrorClass(Form("Got a negative local board number in %s ? Unlikely"
215 " to be correct... : %s\n",slatName,name.str().c_str()));
219 AliDebug(3,"Deleting tokens");
221 AliDebug(3,"Deleting localBoardList");
222 delete localBoardList;
223 AliDebug(3,"Adding pcb to slat");
224 slat->Add(*pcbType,allLocalBoards);
225 AliDebug(3,Form("Deleting pcbType=%p %s",pcbType,pcbName.Data()));
230 if ( slat->DX()== 0 || slat->DY() == 0 )
232 AliFatalClass(Form("Slat %s has invalid null size\n",slat->GetID()));
237 //_____________________________________________________________________________
239 AliMpTriggerReader::GetBoardNameFromPCBLine(const TString& s)
241 /// Decode the string to get the board name
244 TObjArray* tokens = s.Tokenize(' ');
246 TString& keyword = ((TObjString*)tokens->At(0))->String();
248 if ( keyword == GetKeywordPcb() &&
249 tokens->GetEntriesFast() == 3 )
251 boardName = ((TObjString*)tokens->At(2))->String();
259 //_____________________________________________________________________________
261 AliMpTriggerReader::FlipLines(TList& lines, Bool_t flipX, Bool_t flipY,
262 Int_t srcLine, Int_t destLine)
265 /// Change the local board names contained in lines,
266 /// to go from right to left, and/or
267 /// from top to bottom
273 // Simply swaps R(ight) and L(eft) in the first character of
278 while ( ( oline = (TObjString*)it.Next() ) )
280 TString& s = oline->String();
281 if ( s.Contains("RC") )
283 // Change right to left
284 s.ReplaceAll("RC","LC");
286 else if ( s.Contains("LC") )
288 // Change left to right
289 s.ReplaceAll("LC","RC");
296 // Change line number, according to parameters srcLine and destLine
297 // Note that because of road opening (for planes 3 and 4 at least),
298 // we loop for srcLine +-1
300 for ( Int_t line = -1; line <=1; ++line )
302 std::ostringstream src,dest;
303 src << "L" << srcLine+line;
304 dest << "L" << destLine-line;
305 if ( src.str() == dest.str() ) continue;
307 for ( Int_t i = 0; i < lines.GetSize(); ++i )
309 TObjString* oline = (TObjString*)lines.At(i);
311 TString& s = oline->String();
313 if ( !s.Contains(GetKeywordPcb()) )
315 // Only consider PCB lines.
319 if ( s.Contains(src.str().c_str()) )
321 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
322 src.str().c_str(),dest.str().c_str(),s.Data()));
324 s.ReplaceAll(src.str().c_str(),dest.str().c_str());
326 AliDebugClass(4,s.Data());
328 TString boardName(GetBoardNameFromPCBLine(s));
332 // We must also change board numbers, with the tricky
333 // thing that up and down must be swapped...
334 // Up can only be 1 card so it must be B1
335 // Down must be the uppper card of the line before, so
336 // the biggest possible board number for this Line,Column
341 AliDebugClass(4,Form("Forcing B1 in %s\n",s.Data()));
342 s.ReplaceAll(boardName(boardName.Length()-2,2),"B1");
343 AliDebugClass(4,s.Data());
347 // find the largest valid board number
348 for ( int b = 4; b>=1; --b )
350 std::ostringstream bs;
351 bs << boardName(0,boardName.Length()-1) << b;
352 if ( LocalBoardNumber(bs.str().c_str()) >= 0 )
354 AliDebugClass(4,Form("Replacing %s by %s in %s\n",
355 boardName(boardName.Length()-2,2).Data(),
358 s.ReplaceAll(boardName(boardName.Length()-2,2),
365 // Check that the replacement we did is ok. If not,
367 Int_t lbn = LocalBoardNumber(GetBoardNameFromPCBLine(s));
370 AliDebugClass(4,Form("Removing line %s\n",s.Data()));
381 //___________________________________________________________________________
383 AliMpTriggerReader::IsLayerLine(const TString& sline) const
385 /// Whether sline contains LAYER keyword
387 if ( sline.BeginsWith(GetKeywordLayer()) )
397 //___________________________________________________________________________
399 AliMpTriggerReader::DecodeFlipLine(const TString& sline,
401 Bool_t& flipX, Bool_t& flipY)
403 /// Decode a line containing FLIP_X and/or FLIP_Y keywords
405 Ssiz_t blankPos = sline.First(' ');
406 if ( blankPos < 0 ) return 0;
408 TString keyword(sline(0,blankPos));
410 if ( keyword == GetKeywordFlipX() )
413 } else if ( keyword == GetKeywordFlipY() )
422 slatType2 = sline(blankPos+1,sline.Length()-blankPos-1);
426 //___________________________________________________________________________
428 AliMpTriggerReader::DecodeScaleLine(const TString& sline,
429 Double_t& scale, TString& slatType)
431 /// Decode sline containing SCALE keyword
433 if ( sline(0,GetKeywordScale().Length()) == GetKeywordScale() )
435 TString tmp(sline(GetKeywordScale().Length()+1,
436 sline.Length()-GetKeywordScale().Length()-1));
437 Ssiz_t blankPos = tmp.First(' ');
440 AliErrorClass(Form("Syntax error in slat file, should get a slatType after "
441 " SCALE keyword : %s\n",tmp.Data()));
446 slatType = tmp(0,blankPos);
447 scale = TString(tmp(blankPos+1,tmp.Length()-blankPos-1)).Atof();
455 //_____________________________________________________________________________
457 AliMpTriggerReader::GetLine(const TString& slatType)
460 /// Assuming slatType is a 4 character string of the form XSLN
461 /// where X=1,2,3 or 4
463 /// N is the line number
466 if ( isdigit(slatType[0]) &&
467 ( slatType[1] == 'R' || slatType[1] == 'L' ) &&
470 return atoi(slatType(3,1).Data());
475 //_____________________________________________________________________________
477 AliMpTriggerReader::LocalBoardNumber(const char* localBoardName)
479 /// From local board name to local board number
481 if ( !fLocalBoardMap.GetSize() )
483 ReadLocalBoardMapping();
486 TPair* pair = (TPair*)fLocalBoardMap.FindObject(localBoardName);
490 return atoi(((TObjString*)pair->Value())->String().Data());
495 //_____________________________________________________________________________
497 AliMpTriggerReader::ReadLines(const char* slatType,
498 AliMp::PlaneType planeType,
501 Bool_t& flipX, Bool_t& flipY,
502 Int_t& srcLine, Int_t& destLine)
505 /// Reads in lines from file for a given slat
506 /// Returns the list of lines (lines), together with some global
507 /// information as the scale, whether to flip the lines, etc...
509 AliDebugClass(2,Form("SlatType %s Scale %e FlipX %d FlipY %d srcLine %d"
510 " destLine %d\n",slatType,scale,flipX,flipY,
515 CreateDataStream(AliMpFiles::SlatFilePath(
516 AliMp::kStationTrigger,slatType, planeType));
520 while ( in.getline(line,80) )
522 TString sline(AliMpHelper::Normalize(line));
524 if ( sline.Length() == 0 || sline[0] == '#' ) continue;
526 Bool_t isKeywordThere =
527 sline.Contains(GetKeywordPcb()) ||
528 sline.Contains(GetKeywordLayer()) ||
529 sline.Contains(GetKeywordScale()) ||
530 sline.Contains(GetKeywordFlipX()) ||
531 sline.Contains(GetKeywordFlipY());
533 if ( !isKeywordThere )
535 AliErrorClass(Form("Got a line with no keyword : %s."
536 "That's not valid\n",line));
543 Int_t isScaleLine = DecodeScaleLine(sline,scale2,slatType2);
547 if ( isScaleLine < 0 )
549 AliFatalClass(Form("Syntax error near %s keyword\n",GetKeywordScale().Data()));
551 else if ( isScaleLine > 0 && slatType2 != slatType )
553 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
559 Int_t isFlipLine = DecodeFlipLine(sline,slatType2,fx,fy);
564 srcLine = GetLine(slatType2);
565 destLine = GetLine(slatType);
569 ReadLines(slatType2.Data(),planeType,lines,scale,flipX,flipY,srcLine,destLine);
573 lines.Add(new TObjString(sline.Data()));
581 //_____________________________________________________________________________
583 AliMpTriggerReader::ReadLocalBoardMapping()
585 /// Reads the file that contains the mapping local board name <-> number
587 fLocalBoardMap.DeleteAll();
593 CreateDataStream(AliMpFiles::LocalTriggerBoardMapping());
596 Char_t localBoardName[20];
597 Int_t j,localBoardId;
603 for (Int_t i = 0; i < 4; ++i)
604 if (!in.getline(line,80)) continue; //skip 4 first lines
607 if (!in.getline(line,80)) break;
608 sscanf(line,"%hx",&mask);
611 if (!in.getline(line,80)) break;
612 sscanf(line,"%d",&nofBoards);
614 for ( Int_t i = 0; i < nofBoards; ++i )
617 if (!in.getline(line,80)) break;
618 sscanf(line,"%02d %19s %03d %03x", &j, localBoardName, &localBoardId, &switches);
619 if (localBoardId <= AliMpConstants::NofLocalBoards())
621 fLocalBoardMap.Add(new TObjString(localBoardName), new TObjString(Form("%d",localBoardId)));
622 AliDebugClass(10,Form("Board %s has number %d\n", localBoardName, localBoardId));
624 // skip 2 following lines
625 if (!in.getline(line,80)) break;
626 if (!in.getline(line,80)) break;
634 //_____________________________________________________________________________
636 AliMpTriggerReader::ReadPCB(const char* pcbType)
639 /// Create a new AliMpPCB object, by reading it from file.
640 /// Returned pointer must be deleted by client.
642 AliDebugClass(2,Form("pcbType=%s\n",pcbType));
644 TString pcbName(pcbType);
646 Ssiz_t pos = pcbName.First('x');
648 Double_t scale = 1.0;
652 scale = TString(pcbName(pos+1,pcbName.Length()-pos-1)).Atof();
653 pcbName = pcbName(0,pos);
658 CreateDataStream(AliMpFiles::SlatPCBFilePath(
659 AliMp::kStationTrigger,pcbName));
661 AliMpMotifReader reader(fkDataStreams,
662 AliMp::kStationTrigger, AliMq::kNotSt12, AliMp::kNonBendingPlane);
663 // note that the nonbending
664 // parameter is of no use for trigger, as far as reading motif is
665 // concerned, as all motifs are supposed to be in the same directory
666 // (as they are shared by bending/non-bending planes).
670 const TString kSizeKeyword("SIZES");
671 const TString kMotifKeyword("MOTIF");
672 const TString kMotifSpecialKeyword("SPECIAL_MOTIF");
676 while ( in.getline(line,80) )
678 if ( line[0] == '#' ) continue;
682 if ( sline(0,kSizeKeyword.Length()) == kSizeKeyword )
684 std::istringstream sin(sline(kSizeKeyword.Length(),
685 sline.Length()-kSizeKeyword.Length()-1).Data());
686 float padSizeX = 0.0;
687 float padSizeY = 0.0;
688 float pcbSizeX = 0.0;
689 float pcbSizeY = 0.0;
690 sin >> padSizeX >> padSizeY >> pcbSizeX >> pcbSizeY;
693 AliError("pcb not null as expected");
695 pcb = new AliMpPCB(fMotifMap,pcbType,padSizeX*scale,padSizeY*scale,
696 pcbSizeX*scale,pcbSizeY*scale);
699 if ( sline(0,kMotifSpecialKeyword.Length()) == kMotifSpecialKeyword )
701 std::istringstream sin(sline(kMotifSpecialKeyword.Length(),
702 sline.Length()-kMotifSpecialKeyword.Length()).Data());
703 TString sMotifSpecial;
705 sin >> sMotifSpecial >> sMotifType;
707 TString id = reader.MotifSpecialName(sMotifSpecial,scale);
709 AliMpMotifSpecial* specialMotif =
710 dynamic_cast<AliMpMotifSpecial*>(fMotifMap->FindMotif(id));
713 AliDebug(1,Form("Reading motifSpecial %s (%s) from file",
714 sMotifSpecial.Data(),id.Data()));
715 AliMpMotifType* motifType = fMotifMap->FindMotifType(sMotifType.Data());
718 AliDebug(1,Form("Reading motifType %s (%s) from file",
719 sMotifType.Data(),id.Data()));
720 motifType = reader.BuildMotifType(sMotifType.Data());
721 fMotifMap->AddMotifType(motifType);
725 AliDebug(1,Form("Got motifType %s (%s) from motifMap",
726 sMotifType.Data(),id.Data()));
728 specialMotif = reader.BuildMotifSpecial(sMotifSpecial,motifType,scale);
729 fMotifMap->AddMotif(specialMotif);
733 AliDebug(1,Form("Got motifSpecial %s from motifMap",sMotifSpecial.Data()));
737 AliError("pcb not null as expected");
739 pcb = new AliMpPCB(pcbType,specialMotif);
742 if ( sline(0,kMotifKeyword.Length()) == kMotifKeyword )
744 std::istringstream sin(sline(kMotifKeyword.Length(),
745 sline.Length()-kMotifKeyword.Length()).Data());
749 sin >> sMotifType >> ix >> iy;
751 AliMpMotifType* motifType = fMotifMap->FindMotifType(sMotifType.Data());
754 AliDebug(1,Form("Reading motifType %s from file",sMotifType.Data()));
755 motifType = reader.BuildMotifType(sMotifType.Data());
756 fMotifMap->AddMotifType(motifType);
760 AliDebug(1,Form("Got motifType %s from motifMap",sMotifType.Data()));
765 AliError("pcb null");
768 pcb->Add(motifType,ix,iy);
777 //_____________________________________________________________________________
779 AliMpTriggerReader::ReadSlat(const char* slatType, AliMp::PlaneType planeType)
782 /// Create a new AliMpTrigger object, by reading it from file.
783 /// Returned object must be deleted by client.
785 Double_t scale = 1.0;
786 Bool_t flipX = kFALSE;
787 Bool_t flipY = kFALSE;
789 lines.SetOwner(kTRUE);
793 // Read the file and its include (if any) and store the result
794 // in a TObjArray of TObjStrings.
795 ReadLines(slatType,planeType,lines,scale,flipX,flipY,srcLine,destLine);
797 // Here some more sanity checks could be done.
798 // For the moment we only insure that the first line contains
800 TString& firstLine = ((TObjString*)lines.First())->String();
801 if ( !IsLayerLine(firstLine) )
803 std::ostringstream s;
804 s << GetKeywordLayer();
805 lines.AddFirst(new TObjString(s.str().c_str()));
808 AliDebugClass(2,Form("Scale=%g\n",scale));
810 FlipLines(lines,flipX,flipY,srcLine,destLine);
812 // Now splits the lines in packets corresponding to different layers
813 // (if any), and create sub-slats.
815 layers.SetOwner(kTRUE);
820 while ( ( osline = (TObjString*)it.Next() ) )
822 TString& s = osline->String();
823 if ( IsLayerLine(s) )
825 TList* list = new TList;
826 list->SetOwner(kTRUE);
832 ((TList*)layers.At(ilayer))->Add(new TObjString(s));
836 AliDebugClass(2,Form("nlayers=%d\n",layers.GetEntriesFast()));
838 AliMpTrigger* triggerSlat = new AliMpTrigger(slatType, planeType);
840 for ( ilayer = 0; ilayer < layers.GetEntriesFast(); ++ilayer )
842 TList& lines1 = *((TList*)layers.At(ilayer));
843 std::ostringstream slatName;
844 slatName << slatType << "-LAYER" << ilayer;
845 AliMpSlat* slat = BuildSlat(slatName.str().c_str(),planeType,lines1,scale);
848 Bool_t ok = triggerSlat->AdoptLayer(slat);
851 StdoutToAliError(cout << "could not add slat=" << endl;
853 cout << "to the triggerSlat=" << endl;
854 triggerSlat->Print();
856 AliError("Slat is=");
857 for ( Int_t i = 0; i < slat->GetSize(); ++i )
859 AliMpPCB* pcb = slat->GetPCB(i);
860 AliError(Form("ERR pcb %d size %e,%e (unscaled is %e,%e)",
861 i,pcb->DX()*2,pcb->DY()*2,
862 pcb->DX()*2/scale,pcb->DY()*2/scale));
864 AliError("TriggerSlat is=");
865 for ( Int_t j = 0; j < triggerSlat->GetSize(); ++j )
867 AliMpSlat* slat1 = triggerSlat->GetLayer(j);
868 AliError(Form("Layer %d",j));
869 for ( Int_t i = 0; i < slat1->GetSize(); ++i )
871 AliMpPCB* pcb = slat1->GetPCB(i);
872 AliError(Form("ERR pcb %d size %e,%e (unscaled is %e,%e)",
873 i,pcb->DX()*2,pcb->DY()*2,
874 pcb->DX()*2/scale,pcb->DY()*2/scale));
877 StdoutToAliError(fMotifMap->Print(););
882 AliErrorClass(Form("Could not read %s\n",slatName.str().c_str()));