Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, 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 : /* $Id$ */
16 :
17 : //_________________________________________________________________________
18 : // Class for trigger analysis.
19 : // Digits are grouped in TRU's (Trigger Units). A TRU consist of 16x28
20 : // crystals ordered fNTRUPhi x fNTRUZ. The algorithm searches all possible
21 : // 2x2 and nxn (n multiple of 2) crystal combinations per each TRU, adding the
22 : // digits amplitude and finding the maximum. If found, look if it is isolated.
23 : // Maxima are transformed in ADC time samples. Each time bin is compared to the trigger
24 : // threshold until it is larger and then, triggers are set. Thresholds need to be fixed.
25 : // Usage:
26 : //
27 : // //Inside the event loop
28 : // AliPHOSTrigger *tr = new AliPHOSTrigger();//Init Trigger
29 : // tr->SetL0Threshold(100);
30 : // tr->SetL1JetLowPtThreshold(1000);
31 : // tr->SetL1JetMediumPtThreshold(10000);
32 : // tr->SetL1JetHighPtThreshold(20000);
33 : // ....
34 : // tr->Trigger(); //Execute Trigger
35 : // tr->Print(""); //Print data members after calculation.
36 : //
37 : //
38 : //*-- Author: Gustavo Conesa & Yves Schutz (IFIC, CERN)
39 : //////////////////////////////////////////////////////////////////////////////
40 :
41 :
42 : // --- ROOT system ---
43 : #include "TMath.h"
44 :
45 : // --- ALIROOT system ---
46 : #include "AliConfig.h"
47 : #include "AliPHOS.h"
48 : #include "AliPHOSTrigger.h"
49 : #include "AliPHOSGeometry.h"
50 : #include "AliPHOSDigit.h"
51 : #include "AliPHOSLoader.h"
52 : #include "AliPHOSPulseGenerator.h"
53 : #include "AliTriggerInput.h"
54 :
55 :
56 22 : ClassImp(AliPHOSTrigger)
57 :
58 : //______________________________________________________________________
59 : AliPHOSTrigger::AliPHOSTrigger()
60 0 : : AliTriggerDetector(),
61 0 : f2x2MaxAmp(-1), f2x2CrystalPhi(-1), f2x2CrystalEta(-1), f2x2SM(0),
62 0 : fnxnMaxAmp(-1), fnxnCrystalPhi(-1), fnxnCrystalEta(-1), fnxnSM(0),
63 0 : fADCValuesHighnxn(0), fADCValuesLownxn(0),
64 0 : fADCValuesHigh2x2(0), fADCValuesLow2x2(0), fDigitsList(0),
65 0 : fAmptrus(0), fAmpmods(0), fTimeRtrus(0),
66 0 : fL0Threshold(50), fL1JetLowPtThreshold(200), fL1JetMediumPtThreshold(500),
67 0 : fL1JetHighPtThreshold(1000),
68 0 : fNTRU(8), fNTRUZ(2), fNTRUPhi(4),
69 0 : fNCrystalsPhi(16),
70 0 : fNCrystalsZ(28),
71 0 : fPatchSize(1), fIsolPatchSize(1),
72 0 : f2x2AmpOutOfPatch(-1), fnxnAmpOutOfPatch(-1),
73 0 : f2x2AmpOutOfPatchThres(2), fnxnAmpOutOfPatchThres(2), //2 GeV out of patch
74 0 : fIs2x2Isol(kFALSE), fIsnxnIsol(kFALSE),
75 0 : fSimulation(kTRUE), fIsolateInModule(kTRUE)
76 0 : {
77 : //ctor
78 0 : fADCValuesHighnxn = 0x0; //new Int_t[fTimeBins];
79 0 : fADCValuesLownxn = 0x0; //new Int_t[fTimeBins];
80 0 : fADCValuesHigh2x2 = 0x0; //new Int_t[fTimeBins];
81 0 : fADCValuesLow2x2 = 0x0; //new Int_t[fTimeBins];
82 :
83 0 : SetName("PHOS");
84 0 : CreateInputs();
85 :
86 0 : fAmptrus = new TClonesArray("TMatrixD",1000);
87 0 : fAmpmods = new TClonesArray("TMatrixD",1000);
88 0 : fTimeRtrus = new TClonesArray("TMatrixD",1000);
89 0 : }
90 :
91 : //____________________________________________________________________________
92 : AliPHOSTrigger::AliPHOSTrigger(const AliPHOSTrigger & trig) :
93 0 : AliTriggerDetector(trig),
94 0 : f2x2MaxAmp(trig.f2x2MaxAmp),
95 0 : f2x2CrystalPhi(trig.f2x2CrystalPhi),
96 0 : f2x2CrystalEta(trig.f2x2CrystalEta),
97 0 : f2x2SM(trig.f2x2SM),
98 0 : fnxnMaxAmp(trig.fnxnMaxAmp),
99 0 : fnxnCrystalPhi(trig.fnxnCrystalPhi),
100 0 : fnxnCrystalEta(trig.fnxnCrystalEta),
101 0 : fnxnSM(trig.fnxnSM),
102 0 : fADCValuesHighnxn(trig.fADCValuesHighnxn),
103 0 : fADCValuesLownxn(trig.fADCValuesLownxn),
104 0 : fADCValuesHigh2x2(trig.fADCValuesHigh2x2),
105 0 : fADCValuesLow2x2(trig.fADCValuesLow2x2),
106 0 : fDigitsList(trig.fDigitsList),
107 0 : fAmptrus(trig.fAmptrus), fAmpmods(trig.fAmpmods), fTimeRtrus(trig.fTimeRtrus),
108 0 : fL0Threshold(trig.fL0Threshold),
109 0 : fL1JetLowPtThreshold(trig.fL1JetLowPtThreshold),
110 0 : fL1JetMediumPtThreshold(trig.fL1JetMediumPtThreshold),
111 0 : fL1JetHighPtThreshold(trig.fL1JetHighPtThreshold),
112 0 : fNTRU(trig.fNTRU),
113 0 : fNTRUZ(trig.fNTRUZ),
114 0 : fNTRUPhi(trig.fNTRUPhi),
115 0 : fNCrystalsPhi(trig.fNCrystalsPhi),
116 0 : fNCrystalsZ(trig. fNCrystalsZ),
117 0 : fPatchSize(trig.fPatchSize),
118 0 : fIsolPatchSize(trig.fIsolPatchSize),
119 0 : f2x2AmpOutOfPatch(trig.f2x2AmpOutOfPatch),
120 0 : fnxnAmpOutOfPatch(trig.fnxnAmpOutOfPatch),
121 0 : f2x2AmpOutOfPatchThres(trig.f2x2AmpOutOfPatchThres),
122 0 : fnxnAmpOutOfPatchThres(trig.fnxnAmpOutOfPatchThres),
123 0 : fIs2x2Isol(trig.fIs2x2Isol),
124 0 : fIsnxnIsol(trig.fIsnxnIsol),
125 0 : fSimulation(trig.fSimulation),
126 0 : fIsolateInModule(trig.fIsolateInModule)
127 0 : {
128 : // cpy ctor
129 0 : }
130 :
131 : //_________________________________________________________________________
132 : AliPHOSTrigger::~AliPHOSTrigger()
133 0 : {
134 : // dtor
135 :
136 0 : if(fADCValuesHighnxn)delete [] fADCValuesHighnxn;
137 0 : if(fADCValuesLownxn)delete [] fADCValuesLownxn;
138 0 : if(fADCValuesHigh2x2)delete [] fADCValuesHigh2x2;
139 0 : if(fADCValuesLow2x2)delete [] fADCValuesLow2x2;
140 : // fDigitsList is now ours...
141 0 : if(fAmptrus) { fAmptrus->Delete() ; delete fAmptrus ; }
142 0 : if(fAmpmods) { fAmpmods->Delete() ; delete fAmpmods ; }
143 0 : if(fTimeRtrus) { fTimeRtrus->Delete(); delete fTimeRtrus; }
144 0 : }
145 :
146 : //_________________________________________________________________________
147 : AliPHOSTrigger & AliPHOSTrigger::operator = (const AliPHOSTrigger &)
148 : {
149 0 : Fatal("operator =", "no implemented");
150 0 : return *this;
151 : }
152 :
153 : void AliPHOSTrigger::CreateInputs()
154 : {
155 : // inputs
156 :
157 : // Do not create inputs again!!
158 0 : if( fInputs.GetEntriesFast() > 0 ) return;
159 :
160 0 : TString name = GetName();
161 :
162 0 : fInputs.AddLast( new AliTriggerInput( "0PH0", name, 0 ) );
163 0 : fInputs.AddLast( new AliTriggerInput( "PHOS_JetHPt_L1",name, 1 ) );
164 0 : fInputs.AddLast( new AliTriggerInput( "PHOS_JetMPt_L1",name, 1 ) );
165 0 : fInputs.AddLast( new AliTriggerInput( "PHOS_JetLPt_L1",name, 1 ) );
166 :
167 0 : }
168 :
169 : //____________________________________________________________________________
170 : void AliPHOSTrigger::FillTRU(const TClonesArray * digits, const AliPHOSGeometry * geom) const {
171 :
172 : //Orders digits ampitudes list and times in fNTRU TRUs (28x16 crystals)
173 : //per module. Each TRU is a TMatrixD, and they are kept in TClonesArrays.
174 : //In a module, the number of TRU in phi is fNTRUPhi, and the number of
175 : //TRU in eta is fNTRUZ. Also fill a matrix with all amplitudes in module for isolation studies.
176 :
177 : //Check data members
178 :
179 0 : if(fNTRUZ*fNTRUPhi != fNTRU)
180 0 : Error("FillTRU"," Wrong number of TRUS per Z or Phi");
181 :
182 : //Initilize and declare variables
183 0 : Int_t nModules = geom->GetNModules();
184 0 : Int_t relid[4] ;
185 : Float_t amp = -1;
186 : Float_t timeR = -1;
187 : Int_t id = -1;
188 :
189 : //List of TRU matrices initialized to 0.
190 0 : for(Int_t k = 0; k < fNTRU*nModules ; k++){
191 0 : TMatrixD amptrus(fNCrystalsPhi,fNCrystalsZ) ;
192 0 : TMatrixD timeRtrus(fNCrystalsPhi,fNCrystalsZ) ;
193 0 : for(Int_t i = 0; i < fNCrystalsPhi; i++){
194 0 : for(Int_t j = 0; j < fNCrystalsZ; j++){
195 0 : amptrus(i,j) = 0.0;
196 0 : timeRtrus(i,j) = 0.0;
197 : }
198 : }
199 0 : new((*fAmptrus)[k]) TMatrixD(amptrus) ;
200 0 : new((*fTimeRtrus)[k]) TMatrixD(timeRtrus) ;
201 0 : }
202 :
203 : //List of Modules matrices initialized to 0.
204 0 : Int_t nmodphi = geom->GetNPhi();
205 0 : Int_t nmodz = geom->GetNZ();
206 :
207 0 : for(Int_t k = 0; k < nModules ; k++){
208 0 : TMatrixD ampmods(nmodphi,nmodz) ;
209 0 : for(Int_t i = 0; i < nmodphi; i++){
210 0 : for(Int_t j = 0; j < nmodz; j++){
211 0 : ampmods(i,j) = 0.0;
212 : }
213 : }
214 0 : new((*fAmpmods)[k]) TMatrixD(ampmods) ;
215 0 : }
216 :
217 : AliPHOSDigit * dig ;
218 :
219 : //Digits loop to fill TRU matrices with amplitudes.
220 0 : for(Int_t idig = 0 ; idig < digits->GetEntriesFast() ; idig++){
221 :
222 0 : dig = static_cast<AliPHOSDigit *>(digits->At(idig)) ;
223 0 : amp = dig->GetEnergy() ; // Energy of the digit
224 0 : id = dig->GetId() ; // Id label of the cell
225 0 : timeR = dig->GetTimeR() ; // Earliest time of the digit
226 0 : geom->AbsToRelNumbering(id, relid) ;
227 : //Transform digit number into 4 numbers
228 : //relid[0] = module
229 : //relid[1] = EMC (0) or CPV (-1)
230 : //relid[2] = row <= 64 (fNPhi)
231 : //relid[3] = column <= 56 (fNZ)
232 :
233 0 : if(relid[1] == 0){//Not CPV, Only EMC digits
234 : //############# TRU ###################
235 : //Check to which TRU in the supermodule belongs the crystal.
236 : //Supermodules are divided in a TRU matrix of dimension
237 : //(fNTRUPhi,fNTRUZ).
238 : //Each TRU is a crystal matrix of dimension (fNCrystalsPhi,fNCrystalsZ)
239 :
240 : //First calculate the row and column in the supermodule
241 : //of the TRU to which the crystal belongs.
242 0 : Int_t col = (relid[3]-1)/fNCrystalsZ+1;
243 0 : Int_t row = (relid[2]-1)/fNCrystalsPhi+1;
244 :
245 : //Calculate label number of the TRU
246 0 : Int_t itru = (row-1) + (col-1)*fNTRUPhi + (relid[0]-1)*fNTRU ;
247 :
248 : //Fill TRU matrix with crystal values
249 0 : TMatrixD * amptrus = static_cast<TMatrixD *>(fAmptrus ->At(itru)) ;
250 0 : TMatrixD * timeRtrus = static_cast<TMatrixD *>(fTimeRtrus->At(itru)) ;
251 :
252 : //Calculate row and column of the crystal inside the TRU with number itru
253 0 : Int_t irow = (relid[2]-1) - (row-1) * fNCrystalsPhi;
254 0 : Int_t icol = (relid[3]-1) - (col-1) * fNCrystalsZ;
255 :
256 0 : (*amptrus)(irow,icol) = amp ;
257 0 : (*timeRtrus)(irow,icol) = timeR ;
258 :
259 : //####################MODULE MATRIX ##################
260 0 : TMatrixD * ampmods = static_cast<TMatrixD *>(fAmpmods->At(relid[0]-1)) ;
261 0 : (*ampmods)(relid[2]-1,relid[3]-1) = amp ;
262 0 : }
263 : }
264 0 : }
265 :
266 : //______________________________________________________________________
267 : void AliPHOSTrigger::GetCrystalPhiEtaIndexInModuleFromTRUIndex(Int_t itru, Int_t iphitru, Int_t ietatru,Int_t &iphiMod,Int_t &ietaMod) const
268 : {
269 : // This method transforms the (eta,phi) index of a crystals in a
270 : // TRU matrix into Super Module (eta,phi) index.
271 :
272 : // Calculate in which row and column in which the TRU are
273 : // ordered in the SM
274 0 : Int_t col = itru/ fNTRUPhi + 1;
275 0 : Int_t row = itru - (col-1)*fNTRUPhi + 1;
276 :
277 : //Calculate the (eta,phi) index in SM
278 :
279 0 : iphiMod = fNCrystalsPhi*(row-1) + iphitru + 1 ;
280 0 : ietaMod = fNCrystalsZ*(col-1) + ietatru + 1 ;
281 :
282 0 : }
283 :
284 : //____________________________________________________________________________
285 : Bool_t AliPHOSTrigger::IsPatchIsolated(Int_t iPatchType, const Int_t imod, const Int_t mtru, const Float_t maxamp, const Int_t maxphi, const Int_t maxeta) {
286 :
287 : //Calculate if the maximum patch found is isolated, find amplitude around maximum (2x2 or nxn) patch,
288 : //inside isolation patch . iPatchType = 0 means calculation for 2x2 patch,
289 : //iPatchType = 1 means calculation for nxn patch.
290 : //In the next table there is an example of the different options of patch size and isolation patch size:
291 : // Patch Size (fPatchSize)
292 : // 0 1 2
293 : // fIsolPatchSize 2x2 (not overlap) 4x4 (overlapped) 6x6(overlapped) ...
294 : // 1 4x4 8x8 10x10
295 : // 2 6x6 12x12 14x14
296 : // 3 8x8 16x16 18x18
297 :
298 : Bool_t b = kFALSE;
299 : Float_t amp = 0;
300 :
301 : //Get matrix of TRU or Module with maximum amplitude patch.
302 0 : Int_t itru = mtru+imod*fNTRU ; //number of tru, min 0 max 8*5.
303 : TMatrixD * ampmatrix = 0x0;
304 : Int_t colborder = 0;
305 : Int_t rowborder = 0;
306 :
307 0 : if(fIsolateInModule){
308 0 : ampmatrix = static_cast<TMatrixD *>(fAmpmods->At(imod)) ;
309 0 : rowborder = fNCrystalsPhi*fNTRUPhi;
310 0 : colborder = fNCrystalsZ*fNTRUZ;
311 0 : AliDebug(2,"Isolate trigger in Module");
312 : }
313 : else{
314 0 : ampmatrix = static_cast<TMatrixD *>(fAmptrus->At(itru)) ;
315 0 : rowborder = fNCrystalsPhi;
316 0 : colborder = fNCrystalsZ;
317 0 : AliDebug(2,"Isolate trigger in TRU");
318 : }
319 :
320 : //Define patch cells
321 0 : Int_t isolcells = fIsolPatchSize*(1+iPatchType);
322 0 : Int_t ipatchcells = 2*(1+fPatchSize*iPatchType);
323 0 : Int_t minrow = maxphi - isolcells;
324 0 : Int_t mincol = maxeta - isolcells;
325 0 : Int_t maxrow = maxphi + isolcells + ipatchcells;
326 0 : Int_t maxcol = maxeta + isolcells + ipatchcells;
327 :
328 0 : AliDebug(2,Form("Number of added Isol Cells %d, Patch Size %d",isolcells, ipatchcells));
329 0 : AliDebug(2,Form("Patch: minrow %d, maxrow %d, mincol %d, maxcol %d",minrow,maxrow,mincol,maxcol));
330 :
331 0 : if(minrow < 0 || mincol < 0 || maxrow > rowborder || maxcol > colborder){
332 0 : AliDebug(1,Form("Out of Module/TRU range, cannot isolate patch"));
333 0 : return kFALSE;
334 : }
335 :
336 : //Add amplitudes in all isolation patch
337 0 : for(Int_t irow = minrow ; irow < maxrow; irow ++)
338 0 : for(Int_t icol = mincol ; icol < maxcol ; icol ++)
339 0 : amp += (*ampmatrix)(irow,icol);
340 :
341 0 : AliDebug(2,Form("Type %d, Maximum amplitude %f, patch+isol square %f",iPatchType, maxamp, amp));
342 :
343 0 : if(amp < maxamp){
344 0 : AliError(Form("Bad sum: Type %d, Maximum amplitude %f, patch+isol square %f",iPatchType, maxamp, amp));
345 0 : return kFALSE;
346 : }
347 : else
348 0 : amp-=maxamp; //Calculate energy in isolation patch that do not comes from maximum patch.
349 :
350 0 : AliDebug(2, Form("Maximum amplitude %f, Out of patch %f",maxamp, amp));
351 :
352 : //Fill isolation amplitude data member and say if patch is isolated.
353 0 : if(iPatchType == 0){ //2x2 case
354 0 : f2x2AmpOutOfPatch = amp;
355 0 : if(amp < f2x2AmpOutOfPatchThres)
356 0 : b=kTRUE;
357 : }
358 0 : else if(iPatchType == 1){ //nxn case
359 0 : fnxnAmpOutOfPatch = amp;
360 0 : if(amp < fnxnAmpOutOfPatchThres)
361 0 : b=kTRUE;
362 : }
363 :
364 0 : return b;
365 :
366 0 : }
367 :
368 :
369 : //____________________________________________________________________________
370 : void AliPHOSTrigger::MakeSlidingCell(const Int_t imod, TMatrixD &max2, TMatrixD &maxn)
371 : {
372 : //Sums energy of all possible 2x2 (L0) and nxn (L1) crystals per each TRU.
373 : //Fast signal in the experiment is given by 2x2 crystals,
374 : //for this reason we loop inside the TRU crystals by 2.
375 :
376 : //Declare and initialize varibles
377 : Float_t amp2 = 0 ;
378 : Float_t ampn = 0 ;
379 0 : for(Int_t i = 0; i < 4; i++){
380 0 : for(Int_t j = 0; j < fNTRU; j++){
381 0 : ampmax2(i,j) = -1;
382 0 : ampmaxn(i,j) = -1;
383 : }
384 : }
385 :
386 : //Create matrix that will contain 2x2 amplitude sums
387 : //used to calculate the nxn sums
388 0 : TMatrixD tru2x2(fNCrystalsPhi/2,fNCrystalsZ/2) ;
389 0 : for(Int_t i = 0; i < fNCrystalsPhi/2; i++)
390 0 : for(Int_t j = 0; j < fNCrystalsZ/2; j++)
391 0 : tru2x2(i,j) = -1.;
392 :
393 : //Loop over all TRUS in a module
394 0 : for(Int_t itru = 0 + imod * fNTRU ; itru < (imod+1)*fNTRU ; itru++){
395 0 : TMatrixD * amptru = static_cast<TMatrixD *>(fAmptrus ->At(itru)) ;
396 0 : TMatrixD * timeRtru = static_cast<TMatrixD *>(fTimeRtrus->At(itru)) ;
397 0 : Int_t mtru = itru-imod*fNTRU ; //Number of TRU in Module
398 :
399 : //Sliding 2x2, add 2x2 amplitudes (NOT OVERLAP)
400 0 : for(Int_t irow = 0 ; irow < fNCrystalsPhi; irow += 2){
401 0 : for(Int_t icol = 0 ; icol < fNCrystalsZ ; icol += 2){
402 0 : amp2 = (*amptru)(irow,icol)+(*amptru)(irow+1,icol)+
403 0 : (*amptru)(irow,icol+1)+(*amptru)(irow+1,icol+1);
404 : //Fill new matrix with added 2x2 crystals for use in nxn sums
405 0 : tru2x2(irow/2,icol/2) = amp2 ;
406 : //Select 2x2 maximum sums to select L0
407 0 : if(amp2 > ampmax2(0,mtru)){
408 0 : ampmax2(0,mtru) = amp2 ;
409 0 : ampmax2(1,mtru) = irow;
410 0 : ampmax2(2,mtru) = icol;
411 0 : }
412 : }
413 : }
414 :
415 : //Find most recent time in the selected 2x2 cell
416 0 : ampmax2(3,mtru) = 1 ;
417 0 : Int_t row2 = static_cast <Int_t> (ampmax2(1,mtru));
418 0 : Int_t col2 = static_cast <Int_t> (ampmax2(2,mtru));
419 0 : for(Int_t i = 0; i<2; i++){
420 0 : for(Int_t j = 0; j<2; j++){
421 0 : if((*amptru)(row2+i,col2+j) > 0 && (*timeRtru)(row2+i,col2+j)> 0){
422 0 : if((*timeRtru)(row2+i,col2+j) < ampmax2(3,mtru) )
423 0 : ampmax2(3,mtru) = (*timeRtru)(row2+i,col2+j);
424 : }
425 : }
426 : }
427 :
428 : //Sliding nxn, add nxn amplitudes (OVERLAP)
429 0 : if(fPatchSize > 0){
430 0 : for(Int_t irow = 0 ; irow < fNCrystalsPhi/2; irow++){
431 0 : for(Int_t icol = 0 ; icol < fNCrystalsZ/2 ; icol++){
432 : ampn = 0;
433 0 : if( (irow+fPatchSize) < fNCrystalsPhi/2 && (icol+fPatchSize) < fNCrystalsZ/2){//Avoid exit the TRU
434 0 : for(Int_t i = 0 ; i <= fPatchSize ; i++)
435 0 : for(Int_t j = 0 ; j <= fPatchSize ; j++)
436 0 : ampn += tru2x2(irow+i,icol+j);
437 : //Select nxn maximum sums to select L1
438 0 : if(ampn > ampmaxn(0,mtru)){
439 0 : ampmaxn(0,mtru) = ampn ;
440 0 : ampmaxn(1,mtru) = irow*2;
441 0 : ampmaxn(2,mtru) = icol*2;
442 0 : }
443 : }
444 : }
445 : }
446 :
447 : //Find most recent time in selected nxn cell
448 0 : ampmaxn(3,mtru) = 1 ;
449 0 : Int_t rown = static_cast <Int_t> (ampmaxn(1,mtru));
450 0 : Int_t coln = static_cast <Int_t> (ampmaxn(2,mtru));
451 0 : for(Int_t i = 0; i<4*fPatchSize; i++){
452 0 : for(Int_t j = 0; j<4*fPatchSize; j++){
453 0 : if( (rown+i) < fNCrystalsPhi && (coln+j) < fNCrystalsZ/2){//Avoid exit the TRU
454 0 : if((*amptru)(rown+i,coln+j) > 0 && (*timeRtru)(rown+i,coln+j)> 0){
455 0 : if((*timeRtru)(rown+i,coln+j) < ampmaxn(3,mtru) )
456 0 : ampmaxn(3,mtru) = (*timeRtru)(rown+i,coln+j);
457 : }
458 : }
459 : }
460 : }
461 0 : }
462 : else {
463 0 : ampmaxn(0,mtru) = ampmax2(0,mtru);
464 0 : ampmaxn(1,mtru) = ampmax2(1,mtru);
465 0 : ampmaxn(2,mtru) = ampmax2(2,mtru);
466 0 : ampmaxn(3,mtru) = ampmax2(3,mtru);
467 : }
468 : }
469 0 : }
470 :
471 :
472 : //____________________________________________________________________________
473 : void AliPHOSTrigger::Print(const Option_t * opt) const
474 : {
475 :
476 : //Prints main parameters
477 :
478 0 : if(! opt)
479 : return;
480 : AliTriggerInput* in = 0x0 ;
481 :
482 0 : printf( " Maximum Amplitude after Sliding Crystal, \n") ;
483 0 : printf( " -2x2 crystals sum (not overlapped): %10.2f, in Super Module %d\n",
484 0 : f2x2MaxAmp,f2x2SM) ;
485 0 : printf( " -2x2 from row %d to row %d and from column %d to column %d\n", f2x2CrystalPhi, f2x2CrystalPhi+2, f2x2CrystalEta, f2x2CrystalEta+2) ;
486 0 : printf( " -2x2 Isolation Patch %d x %d, Amplitude out of 2x2 patch is %f, threshold %f, Isolated? %d \n",
487 0 : 2*fIsolPatchSize+2, 2*fIsolPatchSize+2, f2x2AmpOutOfPatch, f2x2AmpOutOfPatchThres,static_cast<Int_t> (fIs2x2Isol)) ;
488 0 : if(fPatchSize > 0){
489 0 : printf( " Patch Size, n x n: %d x %d cells\n",2*(fPatchSize+1), 2*(fPatchSize+1));
490 0 : printf( " -nxn crystals sum (overlapped) : %10.2f, in Super Module %d\n",
491 0 : fnxnMaxAmp,fnxnSM) ;
492 0 : printf( " -nxn from row %d to row %d and from column %d to column %d\n", fnxnCrystalPhi, fnxnCrystalPhi+4*fPatchSize, fnxnCrystalEta, fnxnCrystalEta+4*fPatchSize) ;
493 0 : printf( " -nxn Isolation Patch %d x %d, Amplitude out of nxn patch is %f, threshold %f, Isolated? %d \n",
494 0 : 4*fIsolPatchSize+2*(fPatchSize+1),4*fIsolPatchSize+2*(fPatchSize+1) , fnxnAmpOutOfPatch, fnxnAmpOutOfPatchThres,static_cast<Int_t> (fIsnxnIsol) ) ;
495 0 : }
496 :
497 0 : printf( " Isolate in Module? %d\n",
498 0 : fIsolateInModule) ;
499 :
500 0 : printf( " Threshold for LO %10.1f\n",
501 0 : fL0Threshold) ;
502 :
503 0 : printf( " Threshold for LO %10.2f\n", fL0Threshold) ;
504 0 : in = (AliTriggerInput*)fInputs.FindObject( "0PH0" );
505 0 : if(in->GetValue())
506 0 : printf( " *** PHOS LO is set ***\n") ;
507 :
508 0 : printf( " Jet Low Pt Threshold for L1 %10.2f\n", fL1JetLowPtThreshold) ;
509 0 : in = (AliTriggerInput*)fInputs.FindObject( "PHOS_JetLPt_L1" );
510 0 : if(in->GetValue())
511 0 : printf( " *** PHOS Jet Low Pt for L1 is set ***\n") ;
512 :
513 0 : printf( " Jet Medium Pt Threshold for L1 %10.2f\n", fL1JetMediumPtThreshold) ;
514 0 : in = (AliTriggerInput*)fInputs.FindObject( "PHOS_JetMPt_L1" );
515 0 : if(in->GetValue())
516 0 : printf( " *** PHOS Jet Medium Pt for L1 is set ***\n") ;
517 :
518 0 : printf( " Jet High Pt Threshold for L1 %10.2f\n", fL1JetHighPtThreshold) ;
519 0 : in = (AliTriggerInput*) fInputs.FindObject( "PHOS_JetHPt_L1" );
520 0 : if(in->GetValue())
521 0 : printf( " *** PHOS Jet High Pt for L1 is set ***\n") ;
522 :
523 0 : }
524 :
525 : //____________________________________________________________________________
526 : void AliPHOSTrigger::SetTriggers(const Int_t iMod, const TMatrixD & ampmax2, const TMatrixD & ampmaxn)
527 : {
528 : //Checks the 2x2 and nxn maximum amplitude per each TRU and compares
529 : //with the different L0 and L1 triggers thresholds. It finds if maximum amplitudes are isolated.
530 :
531 : //Initialize variables
532 : Float_t max2[] = {-1,-1,-1,-1} ;
533 : Float_t maxn[] = {-1,-1,-1,-1} ;
534 : Int_t mtru2 = -1 ;
535 : Int_t mtrun = -1 ;
536 :
537 :
538 : //Find maximum summed amplitude of all the TRU
539 : //in a Module
540 0 : for(Int_t i = 0 ; i < fNTRU ; i++){
541 0 : if(max2[0] < ampmax2(0,i) ){
542 0 : max2[0] = ampmax2(0,i) ; // 2x2 summed max amplitude
543 0 : max2[1] = ampmax2(1,i) ; // corresponding phi position in TRU
544 0 : max2[2] = ampmax2(2,i) ; // corresponding eta position in TRU
545 0 : max2[3] = ampmax2(3,i) ; // corresponding most recent time
546 : mtru2 = i ; // TRU number in module
547 0 : }
548 0 : if(maxn[0] < ampmaxn(0,i) ){
549 0 : maxn[0] = ampmaxn(0,i) ; // nxn summed max amplitude
550 0 : maxn[1] = ampmaxn(1,i) ; // corresponding phi position in TRU
551 0 : maxn[2] = ampmaxn(2,i) ; // corresponding eta position in TRU
552 0 : maxn[3] = ampmaxn(3,i) ; // corresponding most recent time
553 : mtrun = i ; // TRU number in module
554 0 : }
555 : }
556 :
557 : //Set max amplitude if larger than in other Modules
558 : Float_t maxtimeR2 = -1 ;
559 : Float_t maxtimeRn = -1 ;
560 : // Create a shaper pulse object
561 0 : AliPHOSPulseGenerator pulse ;
562 0 : Int_t nTimeBins = pulse.GetRawFormatTimeBins() ;
563 :
564 : //Set max 2x2 amplitude and select L0 trigger
565 0 : if(max2[0] > f2x2MaxAmp ){
566 0 : f2x2MaxAmp = max2[0] ;
567 0 : f2x2SM = iMod ;
568 : maxtimeR2 = max2[3] ;
569 0 : GetCrystalPhiEtaIndexInModuleFromTRUIndex(mtru2,
570 0 : static_cast<Int_t>(max2[1]),
571 0 : static_cast<Int_t>(max2[2]),
572 0 : f2x2CrystalPhi,f2x2CrystalEta) ;
573 :
574 : //Isolated patch?
575 0 : if(fIsolateInModule)
576 0 : fIs2x2Isol = IsPatchIsolated(0, iMod, mtru2, f2x2MaxAmp, f2x2CrystalPhi,f2x2CrystalEta) ;
577 : else
578 0 : fIs2x2Isol = IsPatchIsolated(0, iMod, mtru2, f2x2MaxAmp, static_cast<Int_t>(max2[1]), static_cast<Int_t>(max2[2])) ;
579 :
580 : //Transform digit amplitude in Raw Samples
581 0 : if (fADCValuesLow2x2 == 0) {
582 0 : fADCValuesLow2x2 = new Int_t[nTimeBins];
583 0 : }
584 0 : if(!fADCValuesHigh2x2) fADCValuesHigh2x2 = new Int_t[nTimeBins];
585 :
586 :
587 0 : pulse.SetAmplitude(f2x2MaxAmp);
588 0 : pulse.SetTZero(maxtimeR2);
589 0 : pulse.MakeSamples();
590 0 : pulse.GetSamples(fADCValuesHigh2x2, fADCValuesLow2x2) ;
591 :
592 : //Set Trigger Inputs, compare ADC time bins until threshold is attained
593 : //Set L0
594 0 : for(Int_t i = 0 ; i < nTimeBins ; i++){
595 0 : if(fADCValuesHigh2x2[i] >= fL0Threshold || fADCValuesLow2x2[i] >= fL0Threshold) {
596 0 : SetInput("0PH0") ;
597 0 : break;
598 : }
599 : }
600 0 : }
601 :
602 : //Set max nxn amplitude and select L1 triggers
603 0 : if(maxn[0] > fnxnMaxAmp && fPatchSize > 0){
604 0 : fnxnMaxAmp = maxn[0] ;
605 0 : fnxnSM = iMod ;
606 : maxtimeRn = maxn[3] ;
607 0 : GetCrystalPhiEtaIndexInModuleFromTRUIndex(mtrun,
608 0 : static_cast<Int_t>(maxn[1]),
609 0 : static_cast<Int_t>(maxn[2]),
610 0 : fnxnCrystalPhi,fnxnCrystalEta) ;
611 :
612 : //Isolated patch?
613 0 : if(fIsolateInModule)
614 0 : fIsnxnIsol = IsPatchIsolated(1, iMod, mtrun, fnxnMaxAmp, fnxnCrystalPhi, fnxnCrystalEta) ;
615 : else
616 0 : fIsnxnIsol = IsPatchIsolated(1, iMod, mtrun, fnxnMaxAmp, static_cast<Int_t>(maxn[1]), static_cast<Int_t>(maxn[2])) ;
617 :
618 : //Transform digit amplitude in Raw Samples
619 0 : if (fADCValuesHighnxn == 0) {
620 0 : fADCValuesHighnxn = new Int_t[nTimeBins];
621 0 : fADCValuesLownxn = new Int_t[nTimeBins];
622 0 : }
623 :
624 0 : pulse.SetAmplitude(fnxnMaxAmp);
625 0 : pulse.SetTZero(maxtimeRn);
626 0 : pulse.MakeSamples();
627 0 : pulse.GetSamples(fADCValuesHighnxn, fADCValuesLownxn) ;
628 :
629 : //Set Trigger Inputs, compare ADC time bins until threshold is attained
630 : //SetL1 Low
631 0 : for(Int_t i = 0 ; i < nTimeBins ; i++){
632 0 : if(fADCValuesHighnxn[i] >= fL1JetLowPtThreshold || fADCValuesLownxn[i] >= fL1JetLowPtThreshold){
633 0 : SetInput("PHOS_JetLPt_L1") ;
634 0 : break;
635 : }
636 : }
637 : //SetL1 Medium
638 0 : for(Int_t i = 0 ; i < nTimeBins ; i++){
639 0 : if(fADCValuesHighnxn[i] >= fL1JetMediumPtThreshold || fADCValuesLownxn[i] >= fL1JetMediumPtThreshold){
640 0 : SetInput("PHOS_JetMPt_L1") ;
641 0 : break;
642 : }
643 : }
644 : //SetL1 High
645 0 : for(Int_t i = 0 ; i < nTimeBins ; i++){
646 0 : if(fADCValuesHighnxn[i] >= fL1JetHighPtThreshold || fADCValuesLownxn[i] >= fL1JetHighPtThreshold){
647 0 : SetInput("PHOS_JetHPt_L1") ;
648 0 : break;
649 : }
650 : }
651 0 : }
652 0 : }
653 :
654 : //____________________________________________________________________________
655 : void AliPHOSTrigger::Trigger(TClonesArray *digits)
656 : {
657 : //Main Method to select triggers.
658 :
659 0 : fDigitsList = digits;
660 0 : DoIt() ;
661 0 : }
662 :
663 : //____________________________________________________________________________
664 : void AliPHOSTrigger::DoIt()
665 : {
666 : // does the trigger job
667 :
668 0 : AliRunLoader* rl = AliRunLoader::Instance() ;
669 0 : AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
670 :
671 : // Get PHOS Geometry object
672 : AliPHOSGeometry *geom;
673 0 : if (!(geom = AliPHOSGeometry::GetInstance()))
674 0 : geom = AliPHOSGeometry::GetInstance("IHEP","");
675 :
676 : //Define parameters
677 0 : Int_t nModules = geom->GetNModules();
678 0 : fNCrystalsPhi = geom->GetNPhi()/fNTRUPhi ;// 64/4=16
679 0 : fNCrystalsZ = geom->GetNZ()/fNTRUZ ;// 56/2=28
680 :
681 : //Intialize data members each time the trigger is called in event loop
682 0 : f2x2MaxAmp = -1; f2x2CrystalPhi = -1; f2x2CrystalEta = -1;
683 0 : fnxnMaxAmp = -1; fnxnCrystalPhi = -1; fnxnCrystalEta = -1;
684 :
685 : //Take the digits list if simulation
686 0 : if(fSimulation)
687 0 : fDigitsList = phosLoader->Digits() ;
688 :
689 0 : if(!fDigitsList)
690 0 : AliFatal("Digits not found !") ;
691 :
692 : //Fill TRU Matrix
693 : // TClonesArray * amptrus = new TClonesArray("TMatrixD",1000);
694 : // TClonesArray * ampmods = new TClonesArray("TMatrixD",1000);
695 : // TClonesArray * timeRtrus = new TClonesArray("TMatrixD",1000);
696 0 : FillTRU(fDigitsList,geom) ;
697 :
698 : //Do Crystal Sliding and select Trigger
699 : //Initialize varible that will contain maximum amplitudes and
700 : //its corresponding cell position in eta and phi, and time.
701 0 : TMatrixD ampmax2(4,fNTRU) ;
702 0 : TMatrixD ampmaxn(4,fNTRU) ;
703 :
704 0 : for(Int_t imod = 0 ; imod < nModules ; imod++) {
705 :
706 : //Do 2x2 and nxn sums, select maximums.
707 0 : MakeSlidingCell(imod, ampmax2, ampmaxn);
708 : //Set the trigger
709 0 : SetTriggers(imod,ampmax2,ampmaxn) ;
710 : }
711 :
712 0 : fAmptrus->Delete();
713 : // delete amptrus; amptrus=0;
714 0 : fAmpmods->Delete();
715 : // delete ampmods; ampmods=0;
716 0 : fTimeRtrus->Delete();
717 : // delete timeRtrus; timeRtrus=0;
718 : //Print();
719 :
720 0 : }
|