--- /dev/null
+#include "AliPHOSCpv3GConnection.h"
+
+AliPHOSCpv3GConnection::AliPHOSCpv3GConnection()
+{
+ //version 1
+ // xy2pad[0][0]= 4;
+ // xy2pad[0][1]= 0;
+ // xy2pad[0][2]= 1;
+ // xy2pad[0][3]= 5;
+ // xy2pad[0][4]= 7;
+ // xy2pad[0][5]= 12;
+ // xy2pad[1][0]= 6;
+ // xy2pad[1][1]= 2;
+ // xy2pad[1][2]= 3;
+ // xy2pad[1][3]= 9;
+ // xy2pad[1][4]= 14;
+ // xy2pad[1][5]= 16;
+ // xy2pad[2][0]= 8;
+ // xy2pad[2][1]= 10;
+ // xy2pad[2][2]= 11;
+ // xy2pad[2][3]= 13;
+ // xy2pad[2][4]= 15;
+ // xy2pad[2][5]= 17;
+ // xy2pad[3][0]= 30;
+ // xy2pad[3][1]= 24;
+ // xy2pad[3][2]= 22;
+ // xy2pad[3][3]= 20;
+ // xy2pad[3][4]= 19;
+ // xy2pad[3][5]= 18;
+ // xy2pad[4][0]= 32;
+ // xy2pad[4][1]= 34;
+ // xy2pad[4][2]= 33;
+ // xy2pad[4][3]= 26;
+ // xy2pad[4][4]= 23;
+ // xy2pad[4][5]= 21;
+ // xy2pad[5][0]= 36;
+ // xy2pad[5][1]= 42;
+ // xy2pad[5][2]= 41;
+ // xy2pad[5][3]= 31;
+ // xy2pad[5][4]= 27;
+ // xy2pad[5][5]= 25;
+ // xy2pad[6][0]= 38;
+ // xy2pad[6][1]= 44;
+ // xy2pad[6][2]= 45;
+ // xy2pad[6][3]= 39;
+ // xy2pad[6][4]= 29;
+ // xy2pad[6][5]= 28;
+ // xy2pad[7][0]= 40;
+ // xy2pad[7][1]= 46;
+ // xy2pad[7][2]= 47;
+ // xy2pad[7][3]= 43;
+ // xy2pad[7][4]= 37;
+ // xy2pad[7][5]= 35;
+
+ //version 2
+ // xy2pad[0][0]=35;
+ // xy2pad[0][1]=40;
+ // xy2pad[0][2]=42;
+ // xy2pad[0][3]=46;
+ // xy2pad[0][4]=47;
+ // xy2pad[0][5]=43;
+ // xy2pad[1][0]=31;
+ // xy2pad[1][1]=33;
+ // xy2pad[1][2]=38;
+ // xy2pad[1][3]=44;
+ // xy2pad[1][4]=45;
+ // xy2pad[1][5]=41;
+ // xy2pad[2][0]=30;
+ // xy2pad[2][1]=32;
+ // xy2pad[2][2]=34;
+ // xy2pad[2][3]=36;
+ // xy2pad[2][4]=37;
+ // xy2pad[2][5]=39;
+ // xy2pad[3][0]=29;
+ // xy2pad[3][1]=28;
+ // xy2pad[3][2]=27;
+ // xy2pad[3][3]=25;
+ // xy2pad[3][4]=23;
+ // xy2pad[3][5]=17;
+ // xy2pad[4][0]=26;
+ // xy2pad[4][1]=24;
+ // xy2pad[4][2]=21;
+ // xy2pad[4][3]=14;
+ // xy2pad[4][4]=13;
+ // xy2pad[4][5]=15;
+ // xy2pad[5][0]=22;
+ // xy2pad[5][1]=20;
+ // xy2pad[5][2]=16;
+ // xy2pad[5][3]=6;
+ // xy2pad[5][4]=5;
+ // xy2pad[5][5]=11;
+ // xy2pad[6][0]=19;
+ // xy2pad[6][1]=18;
+ // xy2pad[6][2]=8;
+ // xy2pad[6][3]=2;
+ // xy2pad[6][4]=3;
+ // xy2pad[6][5]=9;
+ // xy2pad[7][0]=12;
+ // xy2pad[7][1]=10;
+ // xy2pad[7][2]=4;
+ // xy2pad[7][3]=0;
+ // xy2pad[7][4]=1;
+ // xy2pad[7][5]=7;
+
+ //version 3
+ // xy2pad[0][0]=44;
+ // xy2pad[0][1]=39;
+ // xy2pad[0][2]=37;
+ // xy2pad[0][3]=33;
+ // xy2pad[0][4]=32;
+ // xy2pad[0][5]=36;
+ // xy2pad[1][0]=16;
+ // xy2pad[1][1]=46;
+ // xy2pad[1][2]=41;
+ // xy2pad[1][3]=35;
+ // xy2pad[1][4]=34;
+ // xy2pad[1][5]=38;
+ // xy2pad[2][0]=17;
+ // xy2pad[2][1]=47;
+ // xy2pad[2][2]=45;
+ // xy2pad[2][3]=43;
+ // xy2pad[2][4]=42;
+ // xy2pad[2][5]=40;
+ // xy2pad[3][0]=18;
+ // xy2pad[3][1]=19;
+ // xy2pad[3][2]=20;
+ // xy2pad[3][3]=22;
+ // xy2pad[3][4]=24;
+ // xy2pad[3][5]=30;
+ // xy2pad[4][0]=21;
+ // xy2pad[4][1]=23;
+ // xy2pad[4][2]=26;
+ // xy2pad[4][3]=1;
+ // xy2pad[4][4]=2;
+ // xy2pad[4][5]=0;
+ // xy2pad[5][0]=25;
+ // xy2pad[5][1]=27;
+ // xy2pad[5][2]=31;
+ // xy2pad[5][3]=9;
+ // xy2pad[5][4]=10;
+ // xy2pad[5][5]=4;
+ // xy2pad[6][0]=28;
+ // xy2pad[6][1]=29;
+ // xy2pad[6][2]=7;
+ // xy2pad[6][3]=13;
+ // xy2pad[6][4]=12;
+ // xy2pad[6][5]=6;
+ // xy2pad[7][0]=3;
+ // xy2pad[7][1]=5;
+ // xy2pad[7][2]=11;
+ // xy2pad[7][3]=15;
+ // xy2pad[7][4]=14;
+ // xy2pad[7][5]=8;
+
+ //version 4
+ xy2pad[0][0]= 3;
+ xy2pad[0][1]= 8;
+ xy2pad[0][2]=10;
+ xy2pad[0][3]=14;
+ xy2pad[0][4]=15;
+ xy2pad[0][5]=11;
+ xy2pad[1][0]=31;
+ xy2pad[1][1]= 1;
+ xy2pad[1][2]= 6;
+ xy2pad[1][3]=12;
+ xy2pad[1][4]=13;
+ xy2pad[1][5]= 9;
+ xy2pad[2][0]=30;
+ xy2pad[2][1]= 0;
+ xy2pad[2][2]= 2;
+ xy2pad[2][3]= 4;
+ xy2pad[2][4]= 5;
+ xy2pad[2][5]= 7;
+ xy2pad[3][0]=29;
+ xy2pad[3][1]=28;
+ xy2pad[3][2]=27;
+ xy2pad[3][3]=25;
+ xy2pad[3][4]=23;
+ xy2pad[3][5]=17;
+ xy2pad[4][0]=26;
+ xy2pad[4][1]=24;
+ xy2pad[4][2]=21;
+ xy2pad[4][3]=46;
+ xy2pad[4][4]=45;
+ xy2pad[4][5]=47;
+ xy2pad[5][0]=22;
+ xy2pad[5][1]=20;
+ xy2pad[5][2]=16;
+ xy2pad[5][3]=38;
+ xy2pad[5][4]=37;
+ xy2pad[5][5]=43;
+ xy2pad[6][0]=19;
+ xy2pad[6][1]=18;
+ xy2pad[6][2]=40;
+ xy2pad[6][3]=34;
+ xy2pad[6][4]=35;
+ xy2pad[6][5]=41;
+ xy2pad[7][0]=44;
+ xy2pad[7][1]=42;
+ xy2pad[7][2]=36;
+ xy2pad[7][3]=32;
+ xy2pad[7][4]=33;
+ xy2pad[7][5]=39;
+
+ for(Int_t iX=0;iX<8;iX++)
+ for(Int_t iY=0;iY<6;iY++){
+ pad2x[xy2pad[iX][iY]] = iX;
+ pad2y[xy2pad[iX][iY]] = iY;
+ }
+}
--- /dev/null
+#ifndef AliPHOSCpv3GConnection_h
+#define AliPHOSCpv3GConnection_h
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+// Connection tables of pads within one 3Gassiplex card.
+// 3Gassiplex card is a matrix of 8x6 pads.
+// This class sets a correspondence between the absolute pad ID (0..47) and
+// (x,z) position of this pad within a 3Gassiplex card
+// Author: Sergey Evdokimov, IHEP Protvino. Oct-2014
+
+#include <TROOT.h>
+#include <iostream>
+
+class AliPHOSCpv3GConnection
+{
+public:
+ AliPHOSCpv3GConnection();
+ Int_t Pad2X(Int_t pad) {return pad2x[pad]; }
+ Int_t Pad2Y(Int_t pad) {return pad2y[pad]; }
+ Int_t XY2Pad(Int_t x, Int_t y) {return xy2pad[x][y];}
+private:
+ Int_t pad2x[48]; //array of 48 elements containing 3gassiplex x coordinate for every channel
+ Int_t pad2y[48]; //array of 48 elements containing 3gassiplex x coordinate for every channel
+ Int_t xy2pad[8][6]; //2D array containing channels for every pad in 3gassiplex card
+};
+
+#endif //AliPHOSCpv3GConnection_h
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+// Class provides a set of static methods to convert absolute number of pad to pair (X,Y)
+// and vice versa
+// and some other
+// Author - Mikhail Stolpovskiy, IHEP Protvino (2013)
+
+#include "AliPHOSCpvParam.h"
+// #include "AliPHOSCpvRawStream.h"
+
+ClassImp(AliPHOSCpvParam);
+
+using namespace std;
+
+//====================================================================================
+AliPHOSCpv3GConnection AliPHOSCpvParam::fConnection;
+//====================================================================================
+Bool_t AliPHOSCpvParam::DecodeRawWord(Int_t ddl,Int_t rWord, Int_t & abs, Int_t & q, Int_t & eType) {
+
+ //std::cout<<"ddl = "<<ddl<<", mod = "<<DDL2Mod(ddl)<<std::endl;
+
+ if (((rWord >> 27) & 1)) { //check if it's end_of_event word for 3gassiplex card.
+ eType = -1;
+ return kFALSE;
+ }
+
+ //std::cout<<"AliPHOSCpvParam::DecodeRawWord(): passed ((rWord >> 27) & 1)"<<std::endl;
+
+ UInt_t statusControlRow = 0x32a8;
+ UInt_t rowControlWord = rWord & 0xfbff;
+ if(rowControlWord == statusControlRow) {
+ eType = -1;
+ return kFALSE;
+ }
+
+ //std::cout<<"AliPHOSCpvParam::DecodeRawWord(): passed rowControlWord == statusControlRow"<<std::endl;
+
+
+ abs = rWord>>12;
+ q = rWord & 0xfff;
+ abs |= (DDL2Mod(ddl))<<15;
+ if(!IsValidAbs(abs)) {
+ eType = -1;
+ return kFALSE;
+ }
+ //std::cout<<"AliPHOSCpvParam::DecodeRawWord(): passed IsValidAbs(abs)"<<std::endl;
+ if(A2Pad(abs) >= kNPadAdd) {
+ // eType = AliPHOSCpvRawStream::kWrongPadErr; // Eliminate circular dependence AliPHOSCpvParam <-> AliPHOSCpvRawStream!
+ eType = 4;
+ return kFALSE;
+ }
+
+ //Printf("AliPHOSCpvParam::DecodeRawWord: mod, cc, 3g, pad , q = %d, %d, %d, %d, %d",A2Mod(abs),A2CC(abs),A23G(abs),A2Pad(abs), q);
+
+ return kTRUE;
+}
+//====================================================================================
+Int_t AliPHOSCpvParam::Abs(Int_t ddl,Int_t columnCtrl,Int_t gassiplex3,Int_t pad) {
+ if(ddl<0 || ddl>=kNDDL ||
+ columnCtrl<0 || columnCtrl>=kNRows ||
+ gassiplex3<0 || gassiplex3>=kN3GAdd ||
+ pad<0 || pad>=kNPadAdd) return -1;
+ Int_t module = DDL2Mod(ddl); // module is number of CPV module (1-5) accordance to the PHOS offline
+ if(module == -1) return -1;
+ return module<<15
+ | (columnCtrl+1)<<10
+ | (gassiplex3+1)<<6
+ | pad;
+}
+//====================================================================================
+Bool_t AliPHOSCpvParam::IsValidAbs(Int_t abs) {
+ // Printf("AliPHOSCpvParam::IsValidAbs: abs = %d",abs);
+ Int_t mod = A2Mod(abs),
+ cc = A2CC(abs),
+ g3 = A23G(abs),
+ pad = A2Pad(abs);
+ // Printf("mod = %d, cc = %d, g3 = %d, pad = %d",mod,cc,g3,pad);
+ if(mod<1 || mod>kNModules ||
+ cc <0 || cc >=kNRows ||
+ g3 <0 || g3 >=kN3GAdd ||
+ pad<0 || pad>=kNPadAdd) return kFALSE;
+ return kTRUE;
+}
+//====================================================================================
+Int_t AliPHOSCpvParam::A2DDL(Int_t abs) { return Mod2DDL(A2Mod(abs));}
+//====================================================================================
+Int_t AliPHOSCpvParam::A2Mod(Int_t abs) { /*cout << "module is" << (abs>>15) << endl;*/ return abs>>15; }
+//====================================================================================
+Int_t AliPHOSCpvParam::DDL2Mod(Int_t ddl) {
+ switch(ddl) {
+ case (0) : return 5; break;
+ case (2) : return 4; break;
+ case (4) : return 3; break;
+ case (6) : return 2; break;
+ case (8) : return 1; break;
+ default : return -1; break;
+ }
+}
+//====================================================================================
+Int_t AliPHOSCpvParam::Mod2DDL(Int_t mod) {
+ switch(mod) {
+ case (1) : return 8; break;
+ case (2) : return 6; break;
+ case (3) : return 4; break;
+ case (4) : return 2; break;
+ case (5) : return 0; break;
+ default : return -1; break;
+ }
+}
+//====================================================================================
+Int_t AliPHOSCpvParam::A2CC (Int_t abs) { return ((abs >> 10) & 0x1f) - 1; }
+//====================================================================================
+Int_t AliPHOSCpvParam::A23G (Int_t abs) { return ((abs >> 6 ) & 0xf) - 1; }
+//====================================================================================
+Int_t AliPHOSCpvParam::A2Pad(Int_t abs) { return abs & 0x3f; }
+//====================================================================================
+Int_t AliPHOSCpvParam::A2X (Int_t abs) {
+ if(!IsValidAbs(abs)) {
+ // Printf("AliPHOSCpvParam::A2X: abs is not valid!");
+ return -1;
+ }
+ return (kNRows - 1 - A2CC(abs))*(kPadPcX/kNRows) + ( fConnection.Pad2X(A2Pad(abs)));
+}
+//====================================================================================
+Int_t AliPHOSCpvParam::A2Y (Int_t abs) {
+ if(!IsValidAbs(abs)) {
+ // Printf("AliPHOSCpvParam::A2Y: abs is not valid!");
+ return -1;
+ }
+ //return A23G(abs)*(kPadPcY/kN3GAdd) + connection.Ch2Y(A2Pad(abs));
+ //return (kN3GAdd - 1 - A23G(abs))*(kPadPcY/kN3GAdd) + (kPadPcY/kN3GAdd - 1 - fConnection.pad2Y(A2Pad(abs)));
+ return (A23G(abs))*(kPadPcY/kN3GAdd) + (5-fConnection.Pad2Y(A2Pad(abs)));
+ //return (kN3GAdd - 1 - A23G(abs))*(kPadPcY/kN3GAdd) + connection.Ch2Y(A2Pad(abs));
+}
+//====================================================================================
+Int_t AliPHOSCpvParam::XY2A (Int_t ddl, Int_t x, Int_t y) {
+ if(x<kMinPx || x>kMaxPx || y<kMinPy || y>kMaxPy) return -1;
+ return Abs(ddl,X2CC(x),Y23G(y),XY2Pad(x,y));
+} // XY2A
+//====================================================================================
+Int_t AliPHOSCpvParam::X2CC (Int_t x) {
+ if(x<kMinPx|| x>kMaxPx) return -1;
+ return kNRows - 1 - x/(kPadPcX/kNRows);
+} // X2CC
+//====================================================================================
+Int_t AliPHOSCpvParam::Y23G (Int_t y) {
+ if(y<kMinPy || y>kMaxPy) return -1;
+ return y/(kPadPcY/kN3GAdd);
+} // Y23G
+//====================================================================================
+Int_t AliPHOSCpvParam::XY2Pad(Int_t x, Int_t y) {
+ if(x<kMinPx || x>kMaxPx || y<kMinPy || y>kMaxPy) return -1;
+ Int_t xPad = x - (kNRows - 1 - X2CC(x))*(kPadPcX/kNRows);
+ //Int_t yPad = y - (kN3GAdd- 1 - Y23G(y))*(kPadPcY/kN3GAdd);
+ Int_t yPad = y - (Y23G(y))*(kPadPcY/kN3GAdd);
+ //return connection.XY2Ch(xPad,yPad);
+ //return fConnection.XY2pad(xPad,kPadPcY/kN3GAdd - 1 - yPad);
+ return fConnection.XY2Pad(xPad,5-yPad);
+} // XY2Pad
+//====================================================================================
+Bool_t AliPHOSCpvParam::GetLimOfCConX( Int_t cc, Int_t &xmin, Int_t &xmax) {
+ //cout<<"cc="<<cc;
+ if(cc < 0 || cc > kNRows) return kFALSE;
+ Int_t a1 = Abs(0,cc,0,fConnection.XY2Pad(0,0)),
+ a2 = Abs(0,cc,0,fConnection.XY2Pad(7,0));
+ if(!(IsValidAbs(a1) && IsValidAbs(a2))) return kFALSE;
+ xmin = A2X(a1);
+ xmax = A2X(a2);
+ //cout<<": xmin = "<<xmin<<" xmax = "<<xmax<<endl;
+ return kTRUE;
+} // GetLimOfCConX
+//====================================================================================
+Bool_t AliPHOSCpvParam::GetLimOf3GonY( Int_t g3, Int_t &ymin, Int_t &ymax) {
+ if(g3 < 0 || g3 > kN3GAdd) return kFALSE;
+ Int_t a1 = Abs(0,0,g3,fConnection.XY2Pad(0,0)),
+ a2 = Abs(0,0,g3,fConnection.XY2Pad(0,5));
+ if(!(IsValidAbs(a1) && IsValidAbs(a2))) return kFALSE;
+ ymin = A2Y(a1);
+ ymax = A2Y(a2);
+ return kTRUE;
+} // GetLimOf3GonY
+//====================================================================================
+Int_t AliPHOSCpvParam::A2fId(Int_t abs) {
+ Int_t fId = 17920;
+ fId += kPadPcX*kPadPcY*(A2DDL(abs)-1);
+ fId += (kPadPcX/kNRows )*A2CC(abs);
+ fId += (kPadPcY/kN3GAdd)*A23G(abs);
+ fId += A2Pad(abs);
+ return fId;
+} // A2fId
--- /dev/null
+#ifndef AliPHOSCPVParam_h
+#define AliPHOSCPVParam_h
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+// Class provides a set of static methods to convert absolute number of pad to pair (X,Y)
+// and vice versa
+// and some other
+// Author - Mikhail Stolpovskiy, IHEP Protvino (2013)
+
+#include <TNamed.h> //base class
+#include "AliPHOSCpv3GConnection.h"
+
+class AliPHOSCpvParam :public TNamed
+{
+ public:
+ enum EChamberData{kMinCh=0,kMaxCh=0}; //Segmenation. CPV has only one chamber
+ enum EPadxData{kPadPcX=128,kMinPx=0,kMaxPx=127}; //Segmentation structure along x
+ enum EPadyData{kPadPcY=60 ,kMinPy=0,kMaxPy=59 }; //Segmentation structure along y
+ enum {
+ kNRows = 16, // Number of rows (column controlers)
+ kN3GAdd = 10, // Number of 3GASSIPLEXs in a row
+ kNPadAdd = 48, // Number of pad row
+ kNRowsPerSegment = 8, // Number of rows per segment
+ kNDDL = 5, // Number of already installed modules (ddls)
+ kNModules = 5 // Number of modules (equals to the number of PHOS modules)
+ };
+
+ // x <=> phi
+ // y <=> Z
+ // But x-y is a local module axes (Int_t)
+
+ static Bool_t IsValidAbs(Int_t abs);
+ static Bool_t DecodeRawWord(Int_t ddl,Int_t rWord, Int_t & abs, Int_t & q, Int_t & eType);
+ static Int_t Abs (Int_t ddl,Int_t columnCtrl,Int_t gassiplex3,Int_t pad); // abs pad
+ static Int_t A2DDL(Int_t abs) ; // abs pad -> ddl
+ static Int_t A2Mod(Int_t abs) ; // abs -> number of module
+ static Int_t DDL2Mod(Int_t ddl);
+ static Int_t Mod2DDL(Int_t mod);
+ static Int_t A2CC (Int_t abs) ; // abs pad -> column controler
+ static Int_t A23G (Int_t abs) ; // abs pad -> number of 3gassiplex card
+ static Int_t A2Pad(Int_t abs) ; // abs pad -> number of pad in 3gassiplex
+ static Int_t A2X (Int_t abs) ; // abs pad -> pad X
+ static Int_t A2Y (Int_t abs) ; // abs pad -> pad Y
+ static Int_t XY2A (Int_t ddl, Int_t x, Int_t y) ; // pad X,Y -> abs pad
+ static Int_t X2CC (Int_t x) ; // pad X -> number of column controller
+ static Int_t Y23G (Int_t y) ; // pad Y -> number of 3gassiplex card
+ static Int_t XY2Pad (Int_t x, Int_t y) ; // pad X,Y -> number of pad in 3gassiplex
+ static Bool_t GetLimOfCConX( Int_t cc, Int_t &xmin, Int_t &xmax); // returns limits on X for column controler cc
+ static Bool_t GetLimOf3GonY( Int_t g3, Int_t &ymin, Int_t &ymax); // returns limits on Y for 3gassiplex g3
+
+ static Int_t A2fId(Int_t abs) ; // returns number of channel with common PHOS+CPV numeration
+
+ private:
+ // connection of channels of 3gassiplex to pads
+ static AliPHOSCpv3GConnection fConnection;
+ ClassDef(AliPHOSCpvParam,1); //CPV main parameters class
+};
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+#include "AliPHOSCpvRawStream.h"
+#include "AliRawReader.h"
+#include <stdio.h>
+
+ClassImp(AliPHOSCpvRawStream);
+using namespace std;
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliPHOSCpvRawStream::AliPHOSCpvRawStream(AliRawReader* rawReader) :
+ fNPads(0),
+ fCharge(0x0),
+ fPad(0x0),
+ fDDLNumber(-1),
+ fnDDLInStream(0x0),
+ fnDDLOutStream(0x0),
+ fLDCNumber( 0),
+ fTimeStamp( 0),
+ fRawReader(rawReader),
+ fData(0x0),
+ fNumOfErr(0x0),
+ fPosition(0),
+ fWord(0),
+ fZeroSup(kTRUE),
+ fPos(0x0),
+ fiPos(0),
+ fTurbo(kFALSE),
+ fRawDataSize(0)
+{
+ //
+ // Constructor
+ //
+ Int_t kNDDL = AliPHOSCpvParam::kNDDL;
+ fNumOfErr = new Int_t*[kNDDL]; // Store the number of errors for a given error type and a given DD
+ for(Int_t iddl=0; iddl<kNDDL; iddl++) {
+ fNumOfErr[iddl] = new Int_t [kSumErr];
+ for(Int_t ierr=0; ierr < kSumErr; ierr++) {
+ fNumOfErr[iddl][ierr]=0; // reset errors
+ }
+ }
+
+ fnDDLInStream = new Int_t[kNDDL];
+ fnDDLOutStream = new Int_t[kNDDL];
+ for(Int_t i=0; i<kNDDL; i++) {
+ fnDDLInStream [i] = -1;
+ fnDDLOutStream[i] = -1;
+ }
+
+ fRawReader->Reset();
+ fRawReader->Select("CPV");
+} // Constructor
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliPHOSCpvRawStream::AliPHOSCpvRawStream() :
+ fNPads(0),
+ fCharge(0x0),
+ fPad(0x0),
+ fDDLNumber(-1),
+ fnDDLInStream(0x0),
+ fnDDLOutStream(0x0),
+ fLDCNumber( 0),
+ fTimeStamp( 0),
+ fRawReader(0x0),
+ fData(0x0),
+ fNumOfErr(0x0),
+ fPosition(0),
+ fWord(0),
+ fZeroSup(kTRUE),
+ fPos(0x0),
+ fiPos(0),
+ fTurbo(kFALSE) ,
+ fRawDataSize(0)
+{
+ //
+ // Default constructor
+ //
+ Int_t kNDDL = AliPHOSCpvParam::kNDDL;
+ fNumOfErr = new Int_t*[kNDDL]; // Store the number of errors for a given error type and a given DD
+ for(Int_t iddl=0; iddl<kNDDL; iddl++) {
+ fNumOfErr[iddl] = new Int_t [kSumErr];
+ for(Int_t ierr=0; ierr < kSumErr; ierr++) {
+ fNumOfErr[iddl][ierr]=0; // reset errors
+ }
+ }
+
+ fnDDLInStream = new Int_t[kNDDL];
+ fnDDLOutStream = new Int_t[kNDDL];
+ for(Int_t i=0; i<kNDDL; i++) {
+ fnDDLInStream [i] = -1;
+ fnDDLOutStream[i] = -1;
+ }
+} // Default constructor
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+AliPHOSCpvRawStream::~AliPHOSCpvRawStream()
+{
+ //
+ // destructor
+ //
+ DelVars();
+
+ fDDLNumber=0;
+ fLDCNumber=0;
+ fTimeStamp=0;
+ fPosition=0;
+ fWord=0;
+ fZeroSup=0;
+ fTurbo=0;
+ fRawDataSize=0;
+ for(Int_t i=0; i<AliPHOSCpvParam::kNDDL; i++) delete [] fNumOfErr[i];
+ delete [] fNumOfErr;
+ delete [] fnDDLInStream;
+ delete [] fnDDLOutStream;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::Reset()
+{
+ // reset raw stream params
+ // Reinitalize the containers
+ fDDLNumber = -1;
+ fLDCNumber = 0;
+ fTimeStamp = 0;
+ fPosition = 0;
+ fData = NULL;
+ if (fRawReader) fRawReader->Reset();
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::Turbo()
+{
+
+ UInt_t row,_3G,pad;
+ Int_t cntGlob = fRawReader->GetDataSize()/4;
+ fPosition = 0;
+ fNPads = 0;
+
+ //std::cout<<"words to be read: "<<cntGlob<<std::endl;
+
+ for(Int_t i=1; i<cntGlob; i++) {
+ if (!GetWord(1)) return kFALSE;
+ //std::cout<<"i've passed getWord(1)"<<std::endl;
+ if (fPosition/4 <= 5) continue; // Skip first 5 words
+
+ row = ((fWord >> kbit22) & 0x1f) - 1;
+ _3G = ((fWord >> kbit18) & 0xf) - 1; // 3GASSIPLEX info in raw word is between bits: 18...21
+ pad = (fWord >> kbit12) & 0x3f; // pad info in raw word is between bits: 12...17
+ //std::cout<<"row = "<<row<<", 3Gassiplex = "<<_3G<<", pad info = "<<pad<<std::endl;
+
+ Int_t charge, abs, eType;
+ if(!AliPHOSCpvParam::DecodeRawWord(fDDLNumber,fWord,abs,charge,eType)) {
+ if(eType > 0){ fNumOfErr[fDDLNumber][eType]++;
+ //std::cout<<"AliPHOSCpvRawStream::Turbo(): I cannot decode word!"<<std::endl;
+ //cout<<"DDL = "<< fDDLNumber << "; word = "<< fWord <<"; abs = " << abs
+ // <<"; charge = "<< charge <<"; etype = "<< eType << endl;
+ }
+ continue;
+ }
+ else {
+ fPad [fNPads] = abs;
+ fCharge[fNPads] = charge;
+ fNPads++;
+ if(charge==0) fNumOfErr[fDDLNumber][kPedQZero]++;
+ //Printf("Size: %i DDL %i row %i 3G %i pad %i fPos %i fNPads: %i Charge: %d fWord %4.4x",cntGlob,fDDLNumber,row,_3G,pad,fPosition,fNPads,fCharge[fNPads-1],fWord);
+ }
+ }//word loop
+ return kTRUE;
+}//Turbo()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::Next()
+{
+ // read next DDL raw data from the CPV raw data stream
+ // return kFALSE in case of error or no data left
+
+ AliDebug(1,"Start.");
+ do {
+ if (!fRawReader->ReadNextData(fData)) return kFALSE;
+ } while (fRawReader->GetDataSize() == 0);
+
+ /*
+ Event type is selected as in $ALICE_ROOT/RAW/event.h
+ #define START_OF_RUN ((eventTypeType) 1)
+ #define END_OF_RUN ((eventTypeType) 2)
+ #define START_OF_RUN_FILES ((eventTypeType) 3)
+ #define END_OF_RUN_FILES ((eventTypeType) 4)
+ #define START_OF_BURST ((eventTypeType) 5)
+ #define END_OF_BURST ((eventTypeType) 6)
+ #define PHYSICS_EVENT ((eventTypeType) 7) <<---------------
+ #define CALIBRATION_EVENT ((eventTypeType) 8)
+ #define EVENT_FORMAT_ERROR ((eventTypeType) 9)
+ #define START_OF_DATA ((eventTypeType)10)
+ #define END_OF_DATA ((eventTypeType)11)
+ #define SYSTEM_SOFTWARE_TRIGGER_EVENT ((eventTypeType)12)
+ #define DETECTOR_SOFTWARE_TRIGGER_EVENT ((eventTypeType)13)
+ #define EVENT_TYPE_MIN 1
+ #define EVENT_TYPE_MAX 13
+ */
+
+ fPosition = 0;
+ Bool_t status=kFALSE;
+ fRawDataSize=0;
+ fDDLNumber = -1;
+ if (fRawReader->GetDDLID()>=0)
+ fDDLNumber = fRawReader->GetDDLID();
+
+ //debug!!!
+ //fDDLNumber=0;
+
+ if(fDDLNumber<0) {
+ AliWarning(Form("fDDLNumber not a acceptable value %i",fDDLNumber));
+ return kFALSE;
+ }
+
+ if(fRawReader->GetType() == 7 || fRawReader->GetType() == 8 ) { //New: Select Physics events, Old: Raw data size is not 0 and not 47148 (pedestal)
+ fnDDLInStream[fDDLNumber]=1;
+ fnDDLOutStream[fDDLNumber]=0;
+
+ fLDCNumber = fRawReader->GetLDCId();
+ fTimeStamp = fRawReader->GetTimestamp();
+
+ fRawDataSize=fRawReader->GetDataSize()/4;
+ DelVars(); //We have to delete the variables initialized in the InitVars before recall InitVars!!!
+ InitVars(fRawDataSize); //To read the charge and pads we cannot delete before the status return
+
+ if(fTurbo==kTRUE) status=Turbo();
+ else status = ReadCPVRawData(); // If there is any error in raw event, the whole event is thrown away
+
+ if(status) AliDebug(1,Form("Event DDL %i successfully decoded!.",fDDLNumber));
+ else AliDebug(1,Form("Event DDL %i ERROR in decoding!.",fDDLNumber));
+ //DumpData(fRawReader->GetDataSize());
+ } // if(Select Physics events)
+
+ if(status==kTRUE) fnDDLOutStream[fDDLNumber]++; //Count the number of events when the DDL was succesfully decoded
+
+ return status;
+} // Next()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::InitVars(Int_t n)
+{
+ fNPads = 0;
+ fCharge = new Int_t[n];
+ fPad = new Int_t[n];
+ fPos = new Int_t[4*n]; //reset debug
+ for(Int_t ie = 0 ; ie < 4*n; ie++) fPos[ie] = 0; //initialize for 0, otherwise the position is considered filled and will not be updated for the dump
+ fiPos = 0;
+} // InitVars()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::DelVars()
+{
+ //Clean the initvars!!!!!!!!
+ fNPads = 0;
+ if (fCharge) { delete [] fCharge; fCharge = 0x0; }
+ if (fPad) { delete [] fPad; fPad = 0x0; }
+ if (fPos) { delete [] fPos; fPos = 0x0; }
+
+ fiPos=0;
+} // DelVars()
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::ReadCPVRawData()
+{
+ //Here the loop on the decoding the raw bank
+ //for one ddl starts.
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+ Int_t cntGlob = fRawReader->GetDataSize()/4;
+ if(cntGlob==0) {fNumOfErr[fDDLNumber][kRawDataSizeErr]++; return kFALSE; }
+
+ Int_t cnt = cntGlob;
+ Int_t nwSeg;
+ Int_t cntSegment;
+
+ if(!GetWord(cnt)) return kFALSE;
+ cnt--;
+
+ while (cnt>20) { //counter limit is changed from 0 to 20 to take into account (skip) the 5 extra words in the equipment header
+ nwSeg = (fWord >> kbit8) & 0xfff;
+ if(!CheckSegment()) return kFALSE;
+ if(!ReadSegment(cntSegment)) return kFALSE;
+ AliDebug(1,"ReadCPVRawData(): ReadSegment() passed");
+ if(nwSeg != cntSegment) return kFALSE;
+ if(!GetWord(cntSegment+1,kBwd)) return kFALSE;
+ cnt -= cntSegment+1;
+ }
+ return kTRUE;
+} // ReadCPVRawData()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::ReadSegment(Int_t &cntSegment)
+{
+ //Read the segment
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+ cntSegment = (fWord >> kbit8) & 0xfff;
+ Int_t cnt = cntSegment;
+ Int_t cntRow;
+ Int_t nwRow;
+
+ if(!GetWord(cnt,kBwd)) return kFALSE;
+
+ while (cnt>0) {
+ // cntRow = (fWord >> kbit16) & 0xfff;
+ cntRow = 490;
+ if(!CheckRowMarker()) return kFALSE;
+ if(!ReadRow(nwRow)) return kFALSE;
+ if(nwRow != cntRow) {AliDebug(1,Form("Error in Row counters: %i different wrt %i",nwRow,cntRow)); return kFALSE;}
+ if(!GetWord(cntRow+1)) return kFALSE;
+ cnt -= cntRow+1;
+ }
+ cntSegment -= cnt;
+ return kTRUE;
+} // ReadSegment()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::ReadRow(Int_t &cntRow)
+{
+ // Read the row
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+
+ // 3G = 3-gassiplex
+ Int_t cnt;
+ Int_t cnt3G;
+ Int_t nw3G;
+
+ // cntRow = (fWord >> kbit16) & 0xfff;
+ cntRow = 490;
+ cnt = cntRow;
+
+ if(!GetWord(cntRow)) return kFALSE;
+
+ while (cnt>480) {
+ if(!CheckEoE(nw3G)) return kFALSE;
+ if(!Read3G(cnt3G)) return kFALSE;
+ if(nw3G != cnt3G) {AliDebug(1,Form("Error in 3gassiplex counters: %i different wrt %i",nw3G,cnt3G));return kFALSE;}
+ if(!GetWord(1,kBwd)) return kFALSE; // go to next 3gassiplex...
+ cnt--;
+ }
+
+ cntRow -= cnt;
+ cntRow += 480;
+ return kTRUE;
+} // ReadRow()
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::Read3G(Int_t &cnt3G)
+{
+ // Read the 3gassiplex
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+
+ cnt3G = fWord & 0x7f;
+
+ Int_t cnt = cnt3G;
+
+ for(Int_t i3G=0; i3G<cnt3G; i3G++) {
+ UInt_t _3G = 0, row = 0;
+ if(!GetWord(1,kBwd)) return kFALSE;
+ //check on row number
+ cnt--;
+ row = ((fWord >> kbit22) & 0x1f) - 1;
+ if(!CheckRow(row)) continue;
+ //check 3gassiplex number
+ _3G = ((fWord >> kbit18) & 0xf) - 1; //3gassiplex info in raw word is between bits: 18...21
+ if(!Check3G(_3G)) continue;
+ //check pad number
+ UInt_t pad = (fWord >> kbit12) & 0x3f; //pad info in raw word is between bits: 12...17
+ if(!CheckPad(pad)) continue;
+ Int_t charge = fWord & 0xfff;
+ if(AliPHOSCpvParam::Abs(fDDLNumber,row,_3G,pad)<0) continue;
+
+ fPad[fNPads] = AliPHOSCpvParam::Abs(fDDLNumber,row,_3G,pad);
+ fCharge[fNPads] = charge;
+ fNPads++;
+
+ if(charge==0)
+ {
+ AliDebug(1,Form("If PEDESTAL run -> WARNING: ZERO charge is read from DDL: %d row: %d 3G: %d pad: %d",fDDLNumber,row,_3G,pad));
+ fNumOfErr[fDDLNumber][kPedQZero]++;
+ }
+
+ }//i3G
+
+ cnt3G -= cnt;
+ return kTRUE;
+} // ReadDilogic
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::CheckSegment()
+{
+ // Check the segment marker
+ // It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+
+ UInt_t markSegment = 0xAB0;
+ UInt_t segMarker = (fWord >> kbit20) & 0xfff;
+
+ if (segMarker != markSegment ) {
+ AliDebug(1,Form("Segment marker %X wrong (expected %0X)! at %i in word %0X!",segMarker,markSegment,fPosition,fWord));
+ fNumOfErr[fDDLNumber][kWrongSegErr]++;
+ return kFALSE;
+ }
+
+ UInt_t segAddress = fWord & 0xff;
+ if (segAddress<1 ||segAddress>3) {
+ AliDebug(1,Form("Segment address %d not in the valid range [1-3]",segAddress));
+ fNumOfErr[fDDLNumber][kWrongSegErr]++;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::CheckRow(UInt_t row)
+{
+ //check on row number
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+ if(row>=0 && row <AliPHOSCpvParam::kNRows) return kTRUE;
+ AliDebug(1,Form("Wrong row index: %d, expected (0 -> %d) word %0X at %i...",row,AliPHOSCpvParam::kNRows-1,fWord,fPosition));
+ fNumOfErr[fDDLNumber][kWrongRowErr]++;
+ return kFALSE;
+}
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::Check3G(UInt_t _3G)
+{
+ //check 3gassiplex number
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+ if (_3G>= 0 && _3G <AliPHOSCpvParam::kN3GAdd) return kTRUE;
+ AliDebug(1,Form("Wrong 3GASSIPLEX index: %d, expected (0 -> %d)!",_3G,AliPHOSCpvParam::kN3GAdd-1));
+ fNumOfErr[fDDLNumber][kWrong3GErr]++;
+ return kFALSE;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::CheckPad(UInt_t pad)
+{
+ //check pad number
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+ if (pad < AliPHOSCpvParam::kNPadAdd) return kTRUE;
+ AliDebug(1,Form("Wrong pad index: %d, expected (0 -> %d)!",pad,AliPHOSCpvParam::kNPadAdd - 1));
+ fNumOfErr[fDDLNumber][kWrongPadErr]++;
+ return kFALSE;
+}
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::CheckEoE(Int_t &nDil)
+{
+ //check the End of Event
+ // "End of event" is not end of event. It checks subordinate words between 3gassiplex blocks
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+
+ if (!((fWord >> kbit27) & 0x1)) { //check 27th bit in EoE. It must be 1!
+ AliDebug(1,Form("Missing end-of-event flag! (%08X) at %i",fWord,fPosition/4));
+ fNumOfErr[fDDLNumber][kEoEFlagErr]++;
+ return kFALSE;
+ }
+ nDil = fWord & 0x7f; //nDil=EoE word count
+ if(nDil < 0 || nDil > 48 ) {
+ AliDebug(1,Form("Wrong end-of-event word-count: %08X",fWord));
+ fNumOfErr[fDDLNumber][kEoESizeErr]++;
+ return kFALSE;
+ }
+ return kTRUE;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::CheckRowMarker()
+{
+ //check the row marker
+ //It returns: kFALSE if any error occurs
+ // kTRUE if all OK
+ UInt_t nMAXwordsInRow = 0x1EA;
+ UInt_t statusControlRow = 0x32A8; // 0x36A8 for zero suppression
+//First check on row marker
+ UInt_t rowControlWord = fWord >> kbit0 & 0xffff;
+
+ if((fWord >> kbit27) & 0x1) return kTRUE;
+
+ if(rowControlWord != statusControlRow) {
+ AliDebug(1,Form("Wrong row marker %x expected 0x32a8!",rowControlWord));
+ fNumOfErr[fDDLNumber][kRowMarkerErr]++;
+ return kFALSE;
+ }
+
+ //Second check on row marker
+ UInt_t wordsInRow = fWord >> kbit16 & 0x0fff; // Number of words after the row marker, bit 10 is skipped in this check
+
+ if (wordsInRow > nMAXwordsInRow) {
+ AliDebug(1,Form(" FATAL: Number of words %x in a row exceeds the expected value: 0x1EA !",wordsInRow));
+ fNumOfErr[fDDLNumber][kRowMarkerSizeErr]++;
+ return kFALSE;
+ }
+
+ return kTRUE;
+}
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Bool_t AliPHOSCpvRawStream::GetWord(Int_t n,EDirection dir)
+{
+ // This method returns the n-th 32 bit word
+ // inside the raw data payload.
+ // The method is supposed to be platform independent.
+
+ fWord = 0;
+ if (fPosition < 0) {
+ AliError("fPosition < 0 !!! Event skipped.");
+ fRawReader->AddMajorErrorLog(kRawDataSizeErr,"fPosition<0");
+ return kFALSE;
+ }
+
+ if(dir==kBwd) n = -n;
+ fPosition += 4*n-4;
+
+ if(fPosition == -4) return kTRUE;
+
+ if(fPosition<0 || fPosition > fRawReader->GetDataSize()) {
+ AliWarning(Form("fPosition out of boundaries %i",fPosition));
+ return kFALSE;
+ }
+
+ StorePosition();
+
+ fWord |= fData[fPosition++];
+ fWord |= fData[fPosition++] << 8;
+ fWord |= fData[fPosition++] << 16;
+ fWord |= fData[fPosition++] << 24;
+
+ return kTRUE;
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::DumpData(Int_t nw)
+{
+ //just a simple raw data dump
+ // in () is the position in bytes
+ //--
+ for(Int_t i=0;i<nw;i+=4) {
+ if(!(i%16)) printf(" \n %8i) ",i);
+ printf("%02X%02X%02X%02X [ %06i ] ",fData[i+3],fData[i+2],fData[i+1],fData[i+0],fPos[i]);
+ }
+ Printf(" \n -----end of dump ----------- ");
+}
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::StorePosition()
+{
+ //just for debug purpose
+ // it stores the position
+ //read for the first time
+// Printf("@@@@@@@@@ fPos: %x fPosition: %d",fPos,fPosition);
+ if(fPos[fPosition]!=0) {
+// Printf("Position already stored!!! Value %i at address %i",fPos[fPosition],fPosition);
+ return;
+ }
+ fiPos++;
+ fPos[fPosition] = fiPos;
+// if(stDeb)Printf("%i - Actual position %i",iPos,fPosition);
+}
--- /dev/null
+#ifndef ALICPVRAWSTREAM_H
+#define ALICPVRAWSTREAM_H
+///////////////////////////////////////////////////////////////////////////////
+///
+/// This is a class for reading raw data of CPV.
+/// Author: Mikhail Stolpovskiy, IHEP Protvino (2013)
+///
+///////////////////////////////////////////////////////////////////////////////
+
+#include <TObject.h>
+#include <TClonesArray.h>
+#include <TFile.h>
+#include "AliPHOSCpvParam.h"
+#include <AliBitPacking.h>
+#include <AliFstream.h>
+#include "AliDAQ.h"
+#include "AliRawDataHeaderSim.h"
+#include "AliLog.h"
+
+#include <assert.h>
+
+class AliRawReader;
+
+class AliPHOSCpvRawStream: public TObject {
+ public :
+ AliPHOSCpvRawStream(AliRawReader* rawReader);
+ AliPHOSCpvRawStream();
+
+ virtual ~AliPHOSCpvRawStream();
+
+ virtual void Reset(); // reset raw stream params, reinitalize the containers
+ virtual Bool_t Next(); // read next DDL raw data from the CPV raw data stream
+ void InitVars(Int_t n); // initialise containers
+ void DelVars(); // delete containers
+
+ static Int_t GetNErrors() { return kSumErr;} // return the number of max # of Error Types
+
+ Int_t GetNPads() const { return fNPads;} //Get number of pads present in the stream
+ Int_t* GetPadArray() const { return fPad;} //Get pad array from stream decoded
+ Int_t* GetChargeArray() const { return fCharge;} //Get the charge of the pads from dedcoded stream
+ Int_t* GetnDDLInStream() const { return fnDDLInStream;} //Get the DDL input check array
+ Int_t* GetnDDLOutStream() const { return fnDDLOutStream;} //Get the DDL output check array
+
+ static inline const Char_t* GetErrName(Int_t eType);
+ inline Int_t GetErrors(Int_t ddl,Int_t eType) const; //Get errors and occurance
+ inline void SetZeroSup (Bool_t isSup) {fZeroSup = isSup;}
+ inline Bool_t GetZeroSup () const {return fZeroSup;}
+
+ Int_t GetDDLNumber() const{ return fDDLNumber;} //return the number of DDL actually being decoded
+ UInt_t GetLDCNumber() const{ return fLDCNumber;} //return the number of LDC actually being decoded
+ UInt_t GetTimeStamp() const{ return fTimeStamp;} //return the time stamp of the event actually being decoded
+
+ void SetTurbo (Bool_t isTurbo) {fTurbo=isTurbo;} // Enable/Disable Turbo
+ Bool_t GetTurbo () { return fTurbo;}
+ Bool_t Turbo(); // Read CPV Raw data withour error check
+ Bool_t ReadCPVRawData(); // Read CPV Raw data
+ Bool_t ReadSegment(Int_t &cntSegment); // Read Segment (we have one segment per DDL in CPV)
+ Bool_t ReadRow(Int_t &cntRow); // Read Row (Row = column controler)
+ Bool_t Read3G(Int_t &cnt3G); // Read 3Gassiplex
+
+ Bool_t CheckRow(UInt_t row); // Check Row
+ Bool_t Check3G (UInt_t _3G); // Check 3Gassiplex
+ Bool_t CheckPad(UInt_t pad); // Check pad
+ Bool_t CheckEoE(Int_t &n3G); // Check EoE
+ Bool_t CheckRowMarker(); // Check RowMarker
+ Bool_t CheckSegment(); // Check Segment
+ void DumpData(Int_t nw); // Dump Data
+ void StorePosition(); // Debug purpose
+
+ Double_t GetDdlDataSize() {return 4.0*fRawDataSize;} //returns the data size for the DDL which is decoded in Next(); fRawDataSize = Bytes/4
+
+ /*
+ // These methods were in AliHMPIDRawStream and I have not yet re-written them for CPV
+ inline void WriteRaw (TObjArray *pDigLst); //write as raw stream
+ inline void WriteRowMarker (AliFstream *ddl,UInt_t size); //write row marker in simulation
+ inline void WriteEoE (AliFstream *ddl,UInt_t row,UInt_t dil,UInt_t wordCnt); //write Enf Of Event word in simulation
+ inline void WriteSegMarker (AliFstream *ddl,UInt_t row, Int_t nwInSeg); //write Segment Marker word in simulation
+ inline void Write5FirmwareWords(AliFstream *ddl); //write the firmware control words in simulation
+ */
+
+ enum EDirection {kFwd,kBwd};
+ enum Ebits {kbit0 ,kbit1 ,kbit2 ,kbit3 ,kbit4 ,kbit5 ,kbit6 ,kbit7 , kbit8,
+ kbit9 ,kbit10,kbit11,kbit12,kbit13,kbit14,kbit15,kbit16,
+ kbit17,kbit18,kbit19,kbit20,kbit21,kbit22,kbit23,kbit24,
+ kbit25,kbit26,kbit27,kbit28,kbit29,kbit30,kbit31,kbit32};
+
+ enum ECPVRawStreamError { kRawDataSizeErr = 0, kRowMarkerErr = 1, kWrongRowErr = 2, kWrong3GErr = 3,
+ kWrongPadErr = 4, kEoEFlagErr = 5, kEoESizeErr = 6, kEoE3GErr = 7,
+ kEoERowErr = 8, kBadSegWordErr = 9, kWrongSegErr = 10, kRowMarkerSizeErr = 11,
+ kPedQZero =12, kSumErr = 13 //This is always the last one, to retreive the number of errors
+ }; //Always check the updated list of names in the .cxx file for print-out!
+
+ enum ECPVRawError {
+ kInvalidRawDataWord = 1
+ };
+
+ private :
+ Bool_t GetWord(Int_t n=0,EDirection dir=kFwd); // Get n-th word
+ UInt_t GetNextWord(); // Get next word
+ Int_t fNPads; // counter of pads in one DDL
+ Int_t *fCharge; // Array for charge values for all channels in one DDL
+ Int_t *fPad; // Array for abs pad values for all channels in one DDL
+ Int_t fDDLNumber; // index of current DDL number
+ Int_t *fnDDLInStream; // if the DDL is in the raw data
+ Int_t *fnDDLOutStream; // if the DDL is in the raw data
+ UInt_t fLDCNumber; // index of current LDC number
+ UInt_t fTimeStamp; // TimeStamp
+ AliRawReader *fRawReader; // object for reading the raw data
+ UChar_t *fData; // raw data
+ Int_t **fNumOfErr; // Store the numner of errors for a given error type and a given DDL
+ Int_t fPosition; // current word
+ UInt_t fWord; // current position in fData
+ Bool_t fZeroSup; // set if zero suppression is applied
+ Int_t *fPos; // for debug purposes
+ Int_t fiPos; // counter for debug
+ Bool_t fTurbo; // kTRUE = Turbo decoding is called. DEFAULT: kFALSE = normal decoding is called
+ Int_t fRawDataSize;
+ ClassDef(AliPHOSCpvRawStream, 1) ; // base class for reading CPV raw digits
+};
+
+/*
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::WriteRowMarker(AliFstream *ddl,UInt_t size)
+{
+ //Writes the row marker for real data and pedestal into the ddl stream
+ //Arguments: ddl stream and the size of the block of the given row, the size is at least the 10 EoE words!
+ //Returns: nothing
+ UInt_t w32=0;
+ UInt_t marker=13992; //for pedestal=12968 == 32a8 for zero suppressed 36a8
+ AliBitPacking::PackWord(size, w32, 16,31); //number of roaw written after row marker (digits and EoE)
+ AliBitPacking::PackWord(marker,w32,0,15); //the marker word
+ ddl->WriteBuffer((char*)&w32,sizeof(w32));
+} // WriteRowMarker
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::WriteEoE(AliFstream *ddl,UInt_t row,UInt_t dil,UInt_t wordCnt )
+{
+ //Writes the EoE word from real data and pedestals into the ddl stream
+ //Arguments: ddl stream, row number, dilogic number and the number of words before the EoE
+ //Retursns: nothing
+ UInt_t e=1;
+ UInt_t w32=0;
+ assert(1<=row&&row<=24); AliBitPacking::PackWord((UInt_t)row ,w32,22,26); // row number (1...24)
+ assert(1<=dil&&dil<=10); AliBitPacking::PackWord((UInt_t)dil ,w32,18,21); // DILOGIC number (1...10)
+ AliBitPacking::PackWord( e ,w32, 7,17); // event number -- not used
+ AliBitPacking::PackWord((UInt_t)wordCnt ,w32, 0, 6); // word counter (0...47) AliBitPacking::PackWord((UInt_t)1 ,w32,27,27); // bit 27 is always 1 by definition of EoE
+ AliBitPacking::PackWord((UInt_t)1 ,w32,27,27); // bit 27 is always 1 by definition of EoE
+ ddl->WriteBuffer((char*)&w32,sizeof(w32));
+} // WriteEoE
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::WriteSegMarker(AliFstream *ddl,UInt_t row, Int_t nwInSeg)
+{
+ //Writes the segment marker (after 8 rows) into the ddl stream
+ //Arguments: ddl stream and the segment: row 8 -> 0x5800, row 16 -> 5801, row 24 -> 5802 for pedestal
+ //Retruns: nothing
+ UInt_t w32=0;
+
+ //Segment marker: 2736 == ab0
+ //AliBitPacking::PackWord((UInt_t)0 ,w32,27,31); //zero out the rest of the bits, since they are not needed
+ AliBitPacking::PackWord((UInt_t)2736 ,w32,20,31); //ab0 the segment marker word
+ AliBitPacking::PackWord((UInt_t)nwInSeg,w32, 8,19); //number of words in the segment
+ AliBitPacking::PackWord((UInt_t)(row/8),w32, 0, 7); //segment 0,1,2
+ ddl->WriteBuffer((char*)&w32,sizeof(w32));
+ //Printf("Segment word created is: %x",w32);
+}
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::Write5FirmwareWords(AliFstream *ddl)
+{
+ //Before each DDL payload 5 words are written:
+ // 1.) Firmware version, for sim = 999
+ // 2.) Status and error bits from CD, for sim = 0
+ // 3.) # FEE RESET received , for sim = 0
+ // 4.) # TTC READY , for sim = 0
+ // 5.) Spare/Reserved , for sim = 0
+ //Returns: nothing
+ UInt_t w32=0;
+ AliBitPacking::PackWord((UInt_t)999,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));
+ AliBitPacking::PackWord((UInt_t) 10,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));
+ AliBitPacking::PackWord((UInt_t) 11,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));
+ AliBitPacking::PackWord((UInt_t) 12,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));
+ AliBitPacking::PackWord((UInt_t) 13,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));
+} // Write5FirmwareWords
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+void AliPHOSCpvRawStream::WriteRaw(TObjArray *pDigAll)
+{
+// Write a list of digits for a given chamber in raw data stream
+// Arguments: pDigAll- list of digits
+// Returns: none
+ Int_t ddl,r,d,a; //32 bits data word
+ Int_t cntLpad,cntRpad;
+ Int_t cntLrow,cntRrow;
+ Int_t cntL=0,cntR=0; //data words counters for DDLs
+ Int_t cntLeoe,cntReoe;
+ UInt_t posL,posR;
+ UInt_t cntLseg,cntRseg;
+ UInt_t cntwInLseg=0,cntwInRseg=0;
+ Int_t cntRdig=0,cntLdig=0;
+
+ UInt_t posLmarker,posRmarker;
+ // Int_t digcnt=0;
+
+ Int_t isDigThere[14][25][11][48];
+
+ for(Int_t iCh=AliPHOSCpvParam::kMinCh;iCh<=AliPHOSCpvParam::kMaxCh;iCh++){//chambers loop
+ cntL=0;cntR=0;
+ for(Int_t iddl=0;iddl<14;iddl++){
+ for(Int_t irow=1;irow<=24;irow++){
+ for(Int_t idil=1;idil<=10;idil++){
+ for(Int_t ipad=0;ipad<48;ipad++){
+ isDigThere[iddl][irow][idil][ipad]=-1;
+ }
+ }
+ }
+ }
+
+ AliFstream* ddlL; //output streams, 2 per chamber
+ AliFstream* ddlR;
+
+ AliRawDataHeaderSim header; header.SetAttribute(0); //empty DDL header
+
+ ddlL = new AliFstream(AliDAQ::DdlFileName("CPV",2*iCh+1)); //left and right looking at the IP
+ ddlR = new AliFstream(AliDAQ::DdlFileName("CPV",2*iCh)); //open both DDL of this chamber in parallel
+
+ ddlL->WriteBuffer((char*)&header,sizeof(header)); //write dummy header as place holder, actual
+ ddlR->WriteBuffer((char*)&header,sizeof(header)); //will be rewritten later when total size of DDL is known
+
+ UInt_t w32=0; //32 bits data word
+ // digcnt=0;
+
+ //added frimware control words
+ Write5FirmwareWords(ddlL); cntL+=5;
+ Write5FirmwareWords(ddlR); cntR+=5;
+
+
+ TClonesArray *pDigCh=(TClonesArray *)pDigAll->At(iCh); //list of digits for current chamber
+
+ for(Int_t iDig=0;iDig<pDigCh->GetEntriesFast();iDig++){//digits loop
+ AliHMPIDDigit *pDig1=(AliHMPIDDigit*)pDigCh->At(iDig);
+ pDig1->Raw(w32,ddl,r,d,a); //??????????
+ isDigThere[ddl][r][d][a]=iDig;
+ }
+
+ for(Int_t row = 1; row <= AliPHOSCpvRawStream::kNRows; row++){ //AliPHOSCpvRawStream::kNRows=25!
+ cntRrow=0;cntLrow=0;cntLseg=0;cntRseg=0;//
+ cntLeoe=0;cntReoe=0;
+ posLmarker=ddlL->Tellp(); WriteRowMarker(ddlL,(UInt_t)1); cntL++; cntRrow++; cntwInRseg++;
+ posRmarker=ddlR->Tellp(); WriteRowMarker(ddlR,(UInt_t)1); cntR++; cntLrow++; cntwInLseg++;
+ for(Int_t dil = 1; dil <= AliPHOSCpvRawStream::kNDILOGICAdd; dil++){ //AliPHOSCpvRawStream::kNDILOGICAdd = 11!
+ cntLpad=0;cntRpad=0;
+ for(Int_t pad = 0; pad < AliPHOSCpvRawStream::kNPadAdd; pad++){ //AliPHOSCpvRawStream::kNPadAdd = 48
+ for ( Int_t iddl=2*iCh; iddl<=2*iCh+1;iddl++){
+ if (isDigThere[iddl][row][dil][pad]!=-1) {
+ AliHMPIDDigit *pDig=(AliHMPIDDigit*)pDigCh->At(isDigThere[iddl][row][dil][pad]);
+ pDig->Raw(w32,ddl,r,d,a);
+ if(pDig->Q() < 0 ) continue; //We can turn of the zero sup for pedestal simulation
+ if(ddl%2){ //write raw digit selecting on DDL
+ ddlL->WriteBuffer((char*)&w32,sizeof(w32)); cntL++; cntLpad++; cntLrow++; cntLdig++; cntwInLseg++;//Printf(" WL: %x isDig: %d",w32,isDigThere[iddl][row][dil][pad]);
+ }else{
+ ddlR->WriteBuffer((char*)&w32,sizeof(w32)); cntR++; cntRpad++; cntRrow++; cntRdig++;cntwInRseg++;//Printf(" WR: %x isDig: %d",w32,isDigThere[iddl][row][dil][pad]);
+ }
+ }//ddl
+ }//isDig
+ }//pad
+ WriteEoE(ddlL,row,dil,cntLpad); cntL++; cntLrow++; cntLeoe++; cntwInLseg++; //molnarl: write EoE markers
+ WriteEoE(ddlR,row,dil,cntRpad); cntR++; cntRrow++; cntReoe++; cntwInRseg++;
+ }//dil
+ if(row%8==0){
+ WriteSegMarker(ddlL,row,cntwInLseg); cntL++; cntLseg++; cntwInLseg=0;
+ WriteSegMarker(ddlR,row,cntwInRseg); cntR++; cntRseg++; cntwInRseg=0;
+ }
+ posL=ddlL->Tellp(); ddlL->Seekp(posLmarker); WriteRowMarker(ddlL,(UInt_t)(cntLrow-1)); ddlL->Seekp(posL); //find the marker position write and go back to the actual position to continue writing
+ posR=ddlR->Tellp(); ddlR->Seekp(posRmarker); WriteRowMarker(ddlR,(UInt_t)(cntRrow-1)); ddlR->Seekp(posR);
+ }//row
+ header.fSize=sizeof(header)+cntL*sizeof(w32); ddlL->Seekp(0); ddlL->WriteBuffer((char*)&header,sizeof(header)); delete ddlL; //rewrite header with size set to
+ header.fSize=sizeof(header)+cntR*sizeof(w32); ddlR->Seekp(0); ddlR->WriteBuffer((char*)&header,sizeof(header)); delete ddlR; //number of bytes and close file
+
+ //Printf("In Ch %d # digits written to LDD %d RDDL %d",iCh,cntLdig,cntRdig);
+
+ }//chambers loop
+}//WriteRaw()
+*/
+
+
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Int_t AliPHOSCpvRawStream::GetErrors(Int_t ddl,Int_t eType)const
+{
+// Return the number of errors for a given error type during raw data reading
+// Arguments: errorType
+// Returns: error or -999 if error Type does not exist
+ if(eType < 0 || eType> kSumErr || ddl < 0 || ddl > AliPHOSCpvParam::kNDDL-1 ) return -999;
+ else return fNumOfErr[ddl][eType];
+} //GetErrors()
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+const Char_t* AliPHOSCpvRawStream::GetErrName(Int_t eType)
+{
+ // Return the name of the error for a given error tye during raw data reading
+ // Arguments: errorType
+ // Returns: error or -999 if error Type does not exist
+ const Char_t *eName[]={ "Raw data size = 0", "Wrong row marker" , "Wrong row index" , "Wrong 3G index",
+ "Wrong pad index","Missing end-of-event flag","Wrong end-of-event word-count","kEoE3GErr",
+ "kEoERowErr" , "kBadSegWordErr", "Segment error" , "Number of words in a row exceeds the expected value",
+ "Ped = 0" , "kSumErr" };
+ const Char_t *eNoErr="NotDefinedErrorType";
+ if(eType<0 || eType>kSumErr) return eNoErr;
+ else return eName[eType];
+}//GetErrName()
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#endif
AliPHOSClusterizerv1.cxx
AliPHOSCpvCalibData.cxx
AliPHOSCpvRecPoint.cxx
+ AliPHOSCpv3GConnection.cxx
+ AliPHOSCpvParam.cxx
+ AliPHOSCpvRawStream.cxx
AliPHOSDigit.cxx
AliPHOSDigitizer.cxx
AliPHOSEmcBadChannelsMap.cxx
#pragma link C++ class AliPHOSTriggerRawReader+;
#pragma link C++ class AliPHOSTRURawReader+;
+#pragma link C++ class AliPHOSCpvRawStream+;
+#pragma link C++ class AliPHOSCpvParam+;
+#pragma link C++ class AliPHOSCpv3GConnection+;
+
#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+// --- ROOT system ---
+#include "TClonesArray.h"
+
+// --- AliRoot header files ---
+#include "AliPHOSCpvRawDigiProducer.h"
+#include "AliPHOSDigit.h"
+#include "AliPHOSCpvRawStream.h"
+#include "AliLog.h"
+#include<iostream>
+using namespace std;
+
+ClassImp(AliPHOSCpvRawDigiProducer);
+
+//--------------------------------------------------------------------------------------
+AliPHOSCpvRawDigiProducer::AliPHOSCpvRawDigiProducer():
+ TObject(),
+ fTurbo(kFALSE),
+ fCpvMinE(10.),
+ fRawStream(0),
+ fhErrors(0),
+ fPedFilesRLoaded(kFALSE)
+{
+ CreateErrHist();
+ // create a 2d array to store the pedestals
+ for (Int_t iDDL=0;iDDL<AliPHOSCpvParam::kNDDL;iDDL++){
+ ped[0][iDDL] = new Int_t *[AliPHOSCpvParam::kPadPcX];
+ ped[1][iDDL] = new Int_t *[AliPHOSCpvParam::kPadPcX];
+ for(Int_t ix=0; ix<AliPHOSCpvParam::kPadPcX; ix++) {
+ ped[0][iDDL][ix] = new Int_t [AliPHOSCpvParam::kPadPcY];
+ ped[1][iDDL][ix] = new Int_t [AliPHOSCpvParam::kPadPcY];
+ }
+ }
+}
+//-------------------------------------------------------------------------------------
+AliPHOSCpvRawDigiProducer::AliPHOSCpvRawDigiProducer(AliRawReader *& rawReader):
+ TObject(),
+ fTurbo(kFALSE),
+ fCpvMinE(10.),
+ fRawStream(0),
+ fhErrors(0),
+ fPedFilesRLoaded(kFALSE)
+{
+ fRawStream = new AliPHOSCpvRawStream(rawReader);
+ fRawStream->SetTurbo(fTurbo);
+ CreateErrHist();
+ // create a 2d array to store the pedestals
+ for (Int_t iDDL=0;iDDL<AliPHOSCpvParam::kNDDL;iDDL++) {
+ ped[0][iDDL] = new Int_t *[AliPHOSCpvParam::kPadPcX];
+ ped[1][iDDL] = new Int_t *[AliPHOSCpvParam::kPadPcX];
+ for(Int_t ix=0; ix<AliPHOSCpvParam::kPadPcX; ix++) {
+ ped[0][iDDL][ix] = new Int_t [AliPHOSCpvParam::kPadPcY];
+ ped[1][iDDL][ix] = new Int_t [AliPHOSCpvParam::kPadPcY];
+ }
+ }
+}
+//--------------------------------------------------------------------------------------
+AliPHOSCpvRawDigiProducer::~AliPHOSCpvRawDigiProducer()
+{
+ if(fRawStream) delete fRawStream;
+ if(fhErrors) delete fhErrors;
+ for(Int_t iDDL = 0;iDDL<AliPHOSCpvParam::kNDDL;iDDL++) {
+ for(Int_t ix=0; ix<AliPHOSCpvParam::kPadPcX; ix++) {
+ delete [] ped[0][iDDL][ix];
+ delete [] ped[1][iDDL][ix];
+ }
+ delete [] ped[0][iDDL];
+ delete [] ped[1][iDDL];
+ }
+}
+//--------------------------------------------------------------------------------------
+Bool_t AliPHOSCpvRawDigiProducer::LoadPedFiles() {
+ // read pedestals from file
+ for(Int_t iDDL = 0;iDDL<AliPHOSCpvParam::kNDDL;iDDL++)
+ for(Int_t iCC=0; iCC<AliPHOSCpvParam::kNRows; iCC++) {
+ FILE * pedFile;
+ pedFile = fopen(Form("thr%d_%02d.dat",iDDL,iCC),"r");
+ if(!pedFile) {
+ Printf("AliPHOSCpvRawDigiProducer::LoadPedFiles: Error, file thr%d_%02d.dat could not be open",iDDL,iCC);
+ continue;
+ //return kFALSE;
+ }
+ Int_t i3g = 0, iPad = 0;
+ Int_t lineCnt = 0;
+ while(!feof(pedFile)) {
+ Int_t abs = AliPHOSCpvParam::Abs(iDDL,iCC,i3g,iPad);
+ if(iPad<48&&i3g<10){
+ if(AliPHOSCpvParam::A2DDL(abs)!=iDDL)
+ cout<<"AliPHOSCpvRawDigiProducer::LoadPedFiles(): wrong connection table! abs = "
+ <<abs<<", DDL = "<<iDDL<<", A2DDL = "<<AliPHOSCpvParam::A2DDL(abs)<<endl;
+ if(AliPHOSCpvParam::A2CC(abs)!=iCC)
+ cout<<"AliPHOSCpvRawDigiProducer::LoadPedFiles(): wrong connection table! abs = "
+ <<abs<<", CC = "<< iCC <<", A2CC = "<<AliPHOSCpvParam::A2CC(abs)<<endl;
+ if(AliPHOSCpvParam::A23G(abs)!=i3g)
+ cout<<"AliPHOSCpvRawDigiProducer::LoadPedFiles(): wrong connection table! abs = "
+ <<abs<<", 3G = "<< i3g <<", A23G = "<<AliPHOSCpvParam::A23G(abs)<<endl;
+ if(AliPHOSCpvParam::A2Pad(abs)!=iPad)
+ cout<<"AliPHOSCpvRawDigiProducer::LoadPedFiles(): wrong connection table! abs = "
+ <<abs<<", Pad = "<< iPad <<", A2Pad = "<<AliPHOSCpvParam::A2Pad(abs)<<endl;
+ }
+ Int_t thr;
+ fscanf(pedFile,"%x",&thr);
+ if(AliPHOSCpvParam::IsValidAbs(abs)) {
+ Int_t s = thr & 0x1ff;
+ Int_t p = thr >> 9;
+ ped[0][iDDL][AliPHOSCpvParam::A2X(abs)][AliPHOSCpvParam::A2Y(abs)] = p-s;
+ ped[1][iDDL][AliPHOSCpvParam::A2X(abs)][AliPHOSCpvParam::A2Y(abs)] = s;
+ int testAbs = AliPHOSCpvParam::XY2A(iDDL,AliPHOSCpvParam::A2X(abs),AliPHOSCpvParam::A2Y(abs));
+ if(abs!=testAbs)
+ cout<<"AliPHOSCpvRawDigiProducer::LoadPedFiles(): wrong connection table! abs = "
+ <<abs<<", testAbs = "<<testAbs<<endl;
+ //Printf("ped[%d][%d] = %d, pad = %d, abs = %d",AliPHOSCpvParam::A2X(abs),AliPHOSCpvParam::A2Y(abs), p + s, iPad, abs);
+ }
+ iPad++;
+ if(iPad == 64) {iPad = 0; i3g++;}
+ lineCnt++;
+ }
+ if(lineCnt < AliPHOSCpvParam::kN3GAdd * 64) return kFALSE;
+ fclose(pedFile);
+ }
+ fPedFilesRLoaded = kTRUE;
+ return kTRUE;
+}
+//--------------------------------------------------------------------------------------
+void AliPHOSCpvRawDigiProducer::SetTurbo(Bool_t turbo)
+{
+ fTurbo = turbo;
+ if(fRawStream) fRawStream->SetTurbo(fTurbo);
+}
+//--------------------------------------------------------------------------------------
+Bool_t AliPHOSCpvRawDigiProducer::LoadNewEvent(AliRawReader *& rawReader)
+{
+ if(fRawStream) delete fRawStream;
+ fRawStream = new AliPHOSCpvRawStream(rawReader);
+ if(fRawStream) {
+ fRawStream->SetTurbo(fTurbo);
+ return kTRUE;
+ }
+ fhErrors->Fill(0);
+ return kFALSE;
+}
+//--------------------------------------------------------------------------------------
+void AliPHOSCpvRawDigiProducer::MakeDigits(TClonesArray *& digits) const
+{
+ // returns histogram of error types
+
+ if(digits)
+ digits->Clear();
+ digits = new TClonesArray("AliPHOSDigit", AliPHOSCpvParam::kNDDL * AliPHOSCpvParam::kNRows * AliPHOSCpvParam::kN3GAdd * AliPHOSCpvParam::kNPadAdd);
+ Int_t iDigit = 0;
+ while(fRawStream->Next()) {
+ for(Int_t iPad=0;iPad<fRawStream->GetNPads();iPad++) {
+ Int_t charge = fRawStream->GetChargeArray()[iPad];
+ Int_t aPad = fRawStream->GetPadArray()[iPad];
+ //cout<<"AliPHOSCpvRawDigiProducer::MakeDigits(): I've got pad "<<aPad<< "with amplitude "<<charge<<endl;
+ if(fPedFilesRLoaded) {
+ Int_t ix = AliPHOSCpvParam::A2X(aPad);
+ Int_t iy = AliPHOSCpvParam::A2Y(aPad);
+ Int_t iddl = AliPHOSCpvParam::A2DDL(aPad);
+ if (charge>ped[0][iddl][ix][iy]+ped[1][iddl][ix][iy]){
+ charge -=ped[0][iddl][ix][iy];
+ }
+ else charge=0;
+ if(charge < fCpvMinE) charge = 0;
+ }
+ // if(charge) new((*digits)[iDigit++]) AliPHOSDigit(AliPHOSCpvParam::A2X(aPad),AliPHOSCpvParam::A2Y(aPad),charge);
+ // Check what is aPad! YK 31.12.2014
+ if(charge) new((*digits)[iDigit++]) AliPHOSDigit(-1,aPad,charge,0);
+
+ }
+ } // while(fRawStream->Next())
+ //cout<<"AliPHOSCpvRawDigiProducer::MakeDigits(): I've created "<<iDigit<<" digits."<<endl;
+ // fill histogram of errors
+ for(Int_t iDDL=0; iDDL<AliPHOSCpvParam::kNDDL; iDDL++) {
+ Int_t nErrors = AliPHOSCpvRawStream::GetNErrors();
+ for(Int_t iType=0; iType<nErrors; iType++) { // iType - type of error
+ fhErrors -> Fill(iType+1,fRawStream -> GetErrors(iDDL,iType));
+ }
+ }
+}
+//--------------------------------------------------------------------------------------
+void AliPHOSCpvRawDigiProducer::CreateErrHist()
+{
+ Int_t nErrors = AliPHOSCpvRawStream::GetNErrors();
+ const char * errNames[nErrors];
+ for(Int_t i=0; i<nErrors; i++) {
+ errNames[i] = AliPHOSCpvRawStream::GetErrName(i);
+ }
+ fhErrors = new TH1I("errorTypes","Errors occured during processing",nErrors+1,0,nErrors+1);
+ TAxis* x = fhErrors->GetXaxis();
+ x->SetBinLabel(1, "Can't get event");
+ for(Int_t i=0; i<nErrors; i++) {
+ x->SetBinLabel(i+2,errNames[i]);
+ }
+
+}
+//--------------------------------------------------------------------------------------
--- /dev/null
+#ifndef ALIPHOSCPVRAWDIGIPRODUCER_H
+#define ALIPHOSCPVRAWDIGIPRODUCER_H
+
+// This class produces CPV digits from raw data stream of one event
+// Raw data is supplied by the object AliRawReader,
+// then AliPHOSCpvRawDigiProducer decodes CPV data and converts is to AliPHOSDigits.
+//!
+// Author: Mikhail Stolpovskiy, mikhail.stolpovskiy@cern.ch
+// modified by Sergey.Evdokimov@cern.ch 30 July 2014
+
+#include "TObject.h"
+#include "TH1I.h"
+
+#include "AliAltroMapping.h"
+#include "AliRawReaderDate.h"
+#include "AliPHOSCpvParam.h"
+
+class AliPHOSDigit ;
+class AliPHOSCpvRawStream;
+
+class AliPHOSCpvRawDigiProducer: public TObject {
+
+public:
+
+ AliPHOSCpvRawDigiProducer() ;
+ AliPHOSCpvRawDigiProducer(AliRawReader *& rawReader); // creates an AliPHOSCpvRawStream(rawReader) object to read data
+
+ virtual ~AliPHOSCpvRawDigiProducer();
+
+ Bool_t LoadPedFiles(); //returns true if ok. Must be called when you process a phys run
+ //If ped files are loaded, then MakeDigits returns digits with
+ //substruct pedestals from ADCs
+
+ Bool_t LoadNewEvent(AliRawReader *& rawReader); // returns true, if ok
+ void SetTurbo(Bool_t turbo); // if turbo==true then do read without error checking
+ Bool_t GetTurbo() const {return fTurbo;}
+
+ void MakeDigits(TClonesArray *& digits) const; // digits is an array of AliPHOSCpvPHOSDigit objects
+ TH1I * GetErrorsHist() const { return fhErrors; } // takes histogram of errors from AliPHOSCpvRawStream
+
+ void SetCpvMinAmp(Int_t cpvMin) { fCpvMinE=cpvMin; } // thresholds would be ped + fCpvMinE
+
+protected:
+ void CreateErrHist(); // initialize histogram of errors
+private:
+ Bool_t fTurbo; // if true, then read without error checking
+ Int_t fCpvMinE ; // minimum energy of digit (ADC)
+ AliPHOSCpvRawStream * fRawStream; //! Raw data stream
+
+ TH1I * fhErrors; // ! histogram of errors
+
+ Int_t ** ped[2][AliPHOSCpvParam::kNDDL]; // pedestals ped[0][iddl][x][y] = pedestal; ped[1][iddl][x][y] = N*sigma (N was used while creating ped files)
+ Bool_t fPedFilesRLoaded;
+
+ ClassDef(AliPHOSCpvRawDigiProducer,1);
+};
+
+#endif
set(SRCS
AliPHOSAodCluster.cxx
AliPHOSClusterizerv2.cxx
+ AliPHOSCpvRawDigiProducer.cxx
AliPHOSEsdCluster.cxx
AliPHOSEvalRecPoint.cxx
AliPHOSGridFile.cxx
#pragma link C++ class AliPHOSEsdCluster+;
#pragma link C++ class AliPHOSAodCluster+;
#pragma link C++ class AliPHOSQADataMakerRec+;
+#pragma link C++ class AliPHOSCpvRawDigiProducer+;
#endif