]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Added new classes for CPV raw data reconstruction
authorkharlov <Yuri.Kharlov@cern.ch>
Wed, 31 Dec 2014 10:04:58 +0000 (13:04 +0300)
committerkharlov <Yuri.Kharlov@cern.ch>
Wed, 31 Dec 2014 10:04:58 +0000 (13:04 +0300)
12 files changed:
PHOS/PHOSbase/AliPHOSCpv3GConnection.cxx [new file with mode: 0644]
PHOS/PHOSbase/AliPHOSCpv3GConnection.h [new file with mode: 0644]
PHOS/PHOSbase/AliPHOSCpvParam.cxx [new file with mode: 0644]
PHOS/PHOSbase/AliPHOSCpvParam.h [new file with mode: 0644]
PHOS/PHOSbase/AliPHOSCpvRawStream.cxx [new file with mode: 0644]
PHOS/PHOSbase/AliPHOSCpvRawStream.h [new file with mode: 0644]
PHOS/PHOSbase/CMakeLists.txt
PHOS/PHOSbase/PHOSbaseLinkDef.h
PHOS/PHOSrec/AliPHOSCpvRawDigiProducer.cxx [new file with mode: 0644]
PHOS/PHOSrec/AliPHOSCpvRawDigiProducer.h [new file with mode: 0644]
PHOS/PHOSrec/CMakeLists.txt
PHOS/PHOSrec/PHOSrecLinkDef.h

diff --git a/PHOS/PHOSbase/AliPHOSCpv3GConnection.cxx b/PHOS/PHOSbase/AliPHOSCpv3GConnection.cxx
new file mode 100644 (file)
index 0000000..26319aa
--- /dev/null
@@ -0,0 +1,210 @@
+#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;
+    }
+}
diff --git a/PHOS/PHOSbase/AliPHOSCpv3GConnection.h b/PHOS/PHOSbase/AliPHOSCpv3GConnection.h
new file mode 100644 (file)
index 0000000..9f20eef
--- /dev/null
@@ -0,0 +1,28 @@
+#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
diff --git a/PHOS/PHOSbase/AliPHOSCpvParam.cxx b/PHOS/PHOSbase/AliPHOSCpvParam.cxx
new file mode 100644 (file)
index 0000000..23d7bfb
--- /dev/null
@@ -0,0 +1,203 @@
+/**************************************************************************
+ * 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
diff --git a/PHOS/PHOSbase/AliPHOSCpvParam.h b/PHOS/PHOSbase/AliPHOSCpvParam.h
new file mode 100644 (file)
index 0000000..f85735e
--- /dev/null
@@ -0,0 +1,59 @@
+#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
diff --git a/PHOS/PHOSbase/AliPHOSCpvRawStream.cxx b/PHOS/PHOSbase/AliPHOSCpvRawStream.cxx
new file mode 100644 (file)
index 0000000..384d58d
--- /dev/null
@@ -0,0 +1,560 @@
+/**************************************************************************
+ * 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); 
+}
diff --git a/PHOS/PHOSbase/AliPHOSCpvRawStream.h b/PHOS/PHOSbase/AliPHOSCpvRawStream.h
new file mode 100644 (file)
index 0000000..731d705
--- /dev/null
@@ -0,0 +1,309 @@
+#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
index e56973a4dd267ecf8d5a4d5742284ba779a20450..daf03a93e9dfcd38f29a3657a982c2369c1e8898 100644 (file)
@@ -39,6 +39,9 @@ set(SRCS
     AliPHOSClusterizerv1.cxx
     AliPHOSCpvCalibData.cxx
     AliPHOSCpvRecPoint.cxx
+    AliPHOSCpv3GConnection.cxx
+    AliPHOSCpvParam.cxx
+    AliPHOSCpvRawStream.cxx
     AliPHOSDigit.cxx
     AliPHOSDigitizer.cxx
     AliPHOSEmcBadChannelsMap.cxx
index b03aa903574be6ff37bd4b19dab4d377d4cd8736..0c48a699f5465d94dc63c25c5ae5a707d5f5d156 100644 (file)
@@ -56,4 +56,8 @@
 #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
diff --git a/PHOS/PHOSrec/AliPHOSCpvRawDigiProducer.cxx b/PHOS/PHOSrec/AliPHOSCpvRawDigiProducer.cxx
new file mode 100644 (file)
index 0000000..de755b7
--- /dev/null
@@ -0,0 +1,211 @@
+/**************************************************************************
+ * 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]);
+  }
+
+}
+//--------------------------------------------------------------------------------------
diff --git a/PHOS/PHOSrec/AliPHOSCpvRawDigiProducer.h b/PHOS/PHOSrec/AliPHOSCpvRawDigiProducer.h
new file mode 100644 (file)
index 0000000..4eafd5d
--- /dev/null
@@ -0,0 +1,58 @@
+#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
index d75afb4a1199dd80cd006848914b57b42eb53ad5..9ceb5cd0b60b5c39eb7a1fcf77eec9890d8c022d 100644 (file)
@@ -37,6 +37,7 @@ include_directories(${ROOT_INCLUDE_DIRS}
 set(SRCS
     AliPHOSAodCluster.cxx
     AliPHOSClusterizerv2.cxx
+    AliPHOSCpvRawDigiProducer.cxx
     AliPHOSEsdCluster.cxx
     AliPHOSEvalRecPoint.cxx
     AliPHOSGridFile.cxx
index 16a16e4eb5a43b1a001a62749c369241944641be..9d54ebd4441dcc8f5ef06eb968693d6986271b27 100644 (file)
@@ -16,4 +16,5 @@
 #pragma link C++ class AliPHOSEsdCluster+;
 #pragma link C++ class AliPHOSAodCluster+;
 #pragma link C++ class AliPHOSQADataMakerRec+;
+#pragma link C++ class AliPHOSCpvRawDigiProducer+;
 #endif