Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-2013, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 : #include "AliEMCALTriggerPatchInfo.h"
16 : #include "AliLog.h"
17 : #include "AliEMCALGeometry.h"
18 : #include "TArrayI.h"
19 : #include "TMath.h"
20 :
21 : /// \cond CLASSIMP
22 22 : ClassImp(AliEMCALTriggerPatchInfo)
23 : /// \endcond
24 :
25 : /**
26 : * Default constructor
27 : */
28 : AliEMCALTriggerPatchInfo::AliEMCALTriggerPatchInfo() :
29 0 : TObject(),
30 0 : fCenterGeo(),
31 0 : fCenterMass(),
32 0 : fEdge1(),
33 0 : fEdge2(),
34 0 : fADCAmp(0),
35 0 : fADCOfflineAmp(0),
36 0 : fTriggerBits(0),
37 0 : fOffSet(0), // To be set explictly by the trigger maker in order to avoid hard coding
38 0 : fRow0(-1),
39 0 : fCol0(-1),
40 0 : fPatchSize(0),
41 0 : fDetectorType(kEMCALdet),
42 99 : fTriggerBitConfig()
43 0 : {
44 0 : fEdgeCell[0] = -1;
45 0 : fEdgeCell[1] = -1;
46 0 : }
47 :
48 : /**
49 : * Copy constructor
50 : *
51 : * @param p Reference for the copy
52 : */
53 : AliEMCALTriggerPatchInfo::AliEMCALTriggerPatchInfo(const AliEMCALTriggerPatchInfo &p) :
54 0 : TObject(p),
55 0 : fCenterGeo(p.fCenterGeo),
56 0 : fCenterMass(p.fCenterMass),
57 0 : fEdge1(p.fEdge1),
58 0 : fEdge2(p.fEdge2),
59 0 : fADCAmp(p.fADCAmp),
60 0 : fADCOfflineAmp(p.fADCOfflineAmp),
61 0 : fTriggerBits(p.fTriggerBits),
62 0 : fOffSet(p.fOffSet),
63 0 : fRow0(p.fRow0),
64 0 : fCol0(p.fCol0),
65 0 : fPatchSize(p.fPatchSize),
66 0 : fDetectorType(p.fDetectorType),
67 0 : fTriggerBitConfig(p.fTriggerBitConfig)
68 0 : {
69 : // .
70 0 : fEdgeCell[0] = p.fEdgeCell[0];
71 0 : fEdgeCell[1] = p.fEdgeCell[1];
72 0 : }
73 :
74 : /**
75 : * Destructor
76 : */
77 : AliEMCALTriggerPatchInfo::~AliEMCALTriggerPatchInfo()
78 0 : {
79 0 : }
80 :
81 : /**
82 : * Assignment operator
83 : *
84 : * @param p Reference for assignment
85 : * @return This object after assignment
86 : */
87 : AliEMCALTriggerPatchInfo &AliEMCALTriggerPatchInfo::operator=(const AliEMCALTriggerPatchInfo &p)
88 : {
89 0 : if (this != &p) {
90 0 : new (this) AliEMCALTriggerPatchInfo(p);
91 : }
92 :
93 0 : return *this;
94 0 : }
95 :
96 : /**
97 : * Reset all fields to the default values using the standard constructor
98 : */
99 : void AliEMCALTriggerPatchInfo::Reset()
100 : {
101 0 : new (this) AliEMCALTriggerPatchInfo();
102 0 : }
103 :
104 : void AliEMCALTriggerPatchInfo::Initialize(UChar_t col0, UChar_t row0, UChar_t size, UInt_t adc, UInt_t offlineAdc, Double_t patchE, UInt_t bitmask, const TVector3& vertex, const AliEMCALGeometry* geom)
105 : {
106 0 : fCol0 = col0;
107 0 : fRow0 = row0;
108 0 : fPatchSize = size;
109 0 : fADCAmp = adc;
110 0 : fADCOfflineAmp = offlineAdc;
111 0 : fTriggerBits = bitmask;
112 0 : SetEdgeCell(col0*2, row0*2);
113 0 : RecalculateKinematics(patchE, vertex, geom);
114 0 : }
115 :
116 : AliEMCALTriggerPatchInfo* AliEMCALTriggerPatchInfo::CreateAndInitialize(UChar_t col0, UChar_t row0, UChar_t size, UInt_t adc, UInt_t offlineAdc, Double_t patchE, UInt_t bitmask, const TVector3& vertex, const AliEMCALGeometry* geom)
117 : {
118 0 : AliEMCALTriggerPatchInfo* patch = new AliEMCALTriggerPatchInfo;
119 0 : patch->Initialize(col0, row0, size, adc, offlineAdc, patchE, bitmask, vertex, geom);
120 0 : return patch;
121 0 : }
122 :
123 : void AliEMCALTriggerPatchInfo::RecalculateKinematics(Double_t patchE, const TVector3& vertex, const AliEMCALGeometry* geom)
124 : {
125 0 : if (!geom) {
126 0 : AliError("EMCal geometry pointer not set! Unable to recalculate the trigger patch kinematics!");
127 0 : return;
128 : }
129 :
130 : // get the absolute trigger ID
131 0 : Int_t absId=-1;
132 0 : geom->GetAbsFastORIndexFromPositionInEMCAL(fCol0, fRow0, absId);
133 : // convert to the 4 absId of the cells composing the trigger channel
134 0 : Int_t cellAbsId[4]={-1,-1,-1,-1};
135 0 : geom->GetCellIndexFromFastORIndex(absId, cellAbsId);
136 0 : if(cellAbsId[0] < 0 || cellAbsId[1] < 0 || cellAbsId[2] < 0 || cellAbsId[3] < 0){
137 0 : AliWarning(Form("Invalid cell ID [%d|%d|%d|%d]\n", cellAbsId[0], cellAbsId[1], cellAbsId[2], cellAbsId[3]));
138 0 : }
139 :
140 : // get low left edge (eta max, phi min)
141 0 : TVector3 edge1;
142 0 : geom->GetGlobal(cellAbsId[0], edge1);
143 0 : Int_t colEdge1 = fCol0, rowEdge1 = fRow0, absIdEdge1 = absId, cellIdEdge1 = cellAbsId[0]; // Used in warning for invalid patch position
144 :
145 : // get up right edge (eta min, phi max)
146 : // get the absolute trigger ID
147 0 : Int_t posOffset = fPatchSize - 1;
148 :
149 0 : geom->GetAbsFastORIndexFromPositionInEMCAL(fCol0+posOffset, fRow0+posOffset, absId);
150 0 : geom->GetCellIndexFromFastORIndex(absId, cellAbsId);
151 0 : TVector3 edge2;
152 0 : geom->GetGlobal(cellAbsId[3], edge2);
153 0 : Int_t colEdge2 = fCol0+posOffset, rowEdge2 = fRow0+posOffset, absIdEdge2 = absId, cellIdEdge2 = cellAbsId[3]; // Used in warning for invalid patch position
154 :
155 : // get the geometrical center as an average of two diagonally
156 : // adjacent patches in the center
157 : // picking two diagonally closest cells from the patches
158 0 : posOffset = fPatchSize / 2 - 1;
159 :
160 0 : geom->GetAbsFastORIndexFromPositionInEMCAL(fCol0+posOffset, fRow0+posOffset, absId);
161 0 : geom->GetCellIndexFromFastORIndex(absId, cellAbsId);
162 0 : TVector3 center1;
163 0 : geom->GetGlobal(cellAbsId[3], center1);
164 :
165 0 : posOffset = fPatchSize / 2;
166 :
167 0 : geom->GetAbsFastORIndexFromPositionInEMCAL(fCol0+posOffset, fRow0+posOffset, absId);
168 0 : geom->GetCellIndexFromFastORIndex(absId, cellAbsId);
169 0 : TVector3 center2;
170 0 : geom->GetGlobal(cellAbsId[0], center2);
171 :
172 0 : TVector3 centerGeo(center1);
173 0 : centerGeo += center2;
174 0 : centerGeo *= 0.5;
175 :
176 : // relate all to primary vertex
177 0 : TVector3 edge1tmp = edge1, edge2tmp = edge2; // Used in warning for invalid patch position
178 0 : centerGeo -= vertex;
179 0 : edge1 -= vertex;
180 0 : edge2 -= vertex;
181 : // Check for invalid patch positions
182 0 : if(!(edge1[0] || edge1[1] || edge1[2])){
183 0 : AliWarning(Form("Inconsistency in patch position for edge1: [%f|%f|%f]", edge1[0], edge1[1], edge1[2]));
184 0 : AliWarning("Original vectors:");
185 0 : AliWarning(Form("edge1: [%f|%f|%f]", edge1tmp[0], edge1tmp[1], edge1tmp[2]));
186 0 : AliWarning(Form("vertex: [%f|%f|%f]", vertex[0], vertex[1], vertex[2]));
187 0 : AliWarning(Form("Col: %d, Row: %d, FABSID: %d, Cell: %d", colEdge1, rowEdge1, absIdEdge1, cellIdEdge1));
188 : }
189 0 : if(!(edge2[0] || edge2[1] || edge2[2])){
190 0 : AliWarning(Form("Inconsistency in patch position for edge2: [%f|%f|%f]", edge2[0], edge2[1], edge2[2]));
191 0 : AliWarning("Original vectors:");
192 0 : AliWarning(Form("edge2: [%f|%f|%f]", edge2tmp[0], edge2tmp[1], edge2tmp[2]));
193 0 : AliWarning(Form("vertex: [%f|%f|%f]", vertex[0], vertex[1], vertex[2]));
194 0 : AliWarning(Form("Col: %d, Row: %d, FABSID: %d, Cell: %d", colEdge2, rowEdge2, absIdEdge2, cellIdEdge2));
195 : }
196 :
197 0 : Int_t iSM = -1, iEta = -1, iPhi = -1;
198 0 : geom->GetPositionInSMFromAbsFastORIndex(absId, iSM, iEta, iPhi);
199 :
200 0 : if (geom->IsDCALSM(iSM)) {
201 0 : SetDetectorType(kDCALPHOSdet);
202 0 : }
203 : else {
204 0 : SetDetectorType(kEMCALdet);
205 : }
206 :
207 0 : fCenterMass.SetPxPyPzE(0,0,0,0);
208 :
209 0 : SetCenterGeo(centerGeo, patchE);
210 0 : SetEdge1(edge1, patchE);
211 0 : SetEdge2(edge2, patchE);
212 0 : }
213 :
214 :
215 : /**
216 : * Return cell indices of the given patch in the cell array
217 : * @param geom EMCAL Geometry used in the run where the trigger patch was created from
218 : * @param cells Output array of cell indices corresponding to the given trigger patch
219 : */
220 : void AliEMCALTriggerPatchInfo::GetCellIndices( AliEMCALGeometry *geom, TArrayI *cells ){
221 :
222 0 : Int_t globCol, globRow, i, j, k, absId, cellAbsId[4];;
223 :
224 0 : cells->Set( 1024 );
225 :
226 : // get corner, convert from cells to trigger channels
227 0 : globCol = GetEdgeCellX() / 2;
228 0 : globRow = GetEdgeCellY() / 2;
229 :
230 : // get the absolute trigger ID
231 0 : geom->GetAbsFastORIndexFromPositionInEMCAL( globCol, globRow, absId );
232 : // convert to the 4 absId of the cells composing the trigger channel
233 0 : geom->GetCellIndexFromFastORIndex( absId, cellAbsId );
234 :
235 : // sum the available energy in the 32/32 window of cells
236 : // step over trigger channels and get all the corresponding cells
237 0 : for( i = 0; i < 16; i++ ){
238 0 : for( j = 0; j < 16; j++ ){
239 : // get the 4 cells composing the trigger channel
240 0 : geom->GetAbsFastORIndexFromPositionInEMCAL( globCol+i, globRow+j, absId );
241 0 : geom->GetCellIndexFromFastORIndex( absId, cellAbsId );
242 : // add amplitudes and find patch edges
243 0 : for( k = 0; k < 4; k++ ){
244 0 : cells->SetAt( cellAbsId[k], i*16*4+j*4+k );
245 : }
246 : }
247 : } // 32x32 cell window
248 :
249 :
250 0 : }
251 :
252 :
253 : /**
254 : * Define Lorentz vector of the given trigger patch
255 : * @param lv Lorentz vector to be defined
256 : * @param v Patch vector position
257 : * @param e Patch energy
258 : */
259 : void AliEMCALTriggerPatchInfo::SetLorentzVector( TLorentzVector &lv, const TVector3 &v, Double_t e ){
260 : // sets the vector
261 0 : Double_t r = TMath::Sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2] ) ;
262 :
263 0 : lv.SetPxPyPzE( e*v[0]/r, e*v[1]/r, e*v[2]/r, e) ;
264 0 : }
265 :
266 : Double_t AliEMCALTriggerPatchInfo::GetPhiTransform(Double_t phiin) const{
267 0 : if(phiin < 0) return phiin + TMath::TwoPi();
268 0 : return phiin;
269 0 : }
270 :
271 : Double_t AliEMCALTriggerPatchInfo::GetET(Double_t energy) const {
272 0 : TLorentzVector en(fCenterGeo.Px(), fCenterGeo.Py(), fCenterGeo.Pz(), energy);
273 0 : return en.Et();
274 0 : }
|