Coverity fix for uninitialized variables and check for returned null value
[u/mrichter/AliRoot.git] / MUON / AliMUONResponseTriggerV1.cxx
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
16 /* $Id$ */
17
18 //-----------------------------------------------------------------------------
19 // Class AliMUONTriggerResponseV1
20 // ------------------
21 // Trigger chamber response 
22 // with cluster size activated
23 //-----------------------------------------------------------------------------
24
25 #include "AliMUONResponseTriggerV1.h"
26 #include "AliMUON.h"
27 #include "AliMUONDigit.h"
28 #include "AliMUONGeometryTransformer.h"
29 #include "AliMUONConstants.h"
30
31 #include "AliCDBManager.h"
32 #include "AliCDBPath.h"
33 #include "AliCDBEntry.h"
34
35 #include "AliMpPad.h"
36 #include "AliMpSegmentation.h"
37 #include "AliMpVSegmentation.h"
38 #include "AliMpCathodType.h"
39
40 #include "AliRun.h"
41 #include "AliDCSValue.h"
42
43 #include <TMath.h>
44 #include <TRandom.h>
45 #include <TMap.h>
46
47 /// \cond CLASSIMP
48 ClassImp(AliMUONResponseTriggerV1)
49 /// \endcond
50
51 namespace
52 {
53   AliMUON* muon()
54   {
55     return static_cast<AliMUON*>(gAlice->GetModule("MUON"));
56   }
57
58   void Global2Local(Int_t detElemId, Double_t xg, Double_t yg, Double_t zg, Double_t& xl, Double_t& yl, Double_t& zl)
59   {  
60   // ideally should be : 
61   // Double_t x,y,z;
62   // AliMUONGeometry::Global2Local(detElemId,xg,yg,zg,x,y,z);
63   // but while waiting for this geometry singleton, let's go through
64   // AliMUON still.
65   
66     const AliMUONGeometryTransformer* transformer = muon()->GetGeometryTransformer();
67     transformer->Global2Local(detElemId,xg,yg,zg,xl,yl,zl);
68   }
69
70 }
71                                 
72
73 //------------------------------------------------------------------   
74 AliMUONResponseTriggerV1::AliMUONResponseTriggerV1() : AliMUONResponseTrigger(), fGenerCluster(0), fWorkCondition(2)
75 {  
76   fHVvalues.Set(72);
77   SetHV();
78   
79   fBValues.Set(144);
80   SetBValues();
81 }
82
83 //------------------------------------------------------------------   
84 AliMUONResponseTriggerV1::AliMUONResponseTriggerV1(Int_t mode) : AliMUONResponseTrigger(), fGenerCluster(0)
85 {
86   fWorkCondition = mode; // 1=streamer - 2=avalanche
87   
88   fHVvalues.Set(72);
89   SetHV();
90   
91   fBValues.Set(144);
92   SetBValues();
93 }
94
95 //------------------------------------------------------------------   
96 AliMUONResponseTriggerV1::~AliMUONResponseTriggerV1()
97 {
98 }
99
100 //------------------------------------------------------------------   
101 Int_t AliMUONResponseTriggerV1::SetGenerCluster()
102 {
103   // Set the GenerCluster parameter and return 1
104   fGenerCluster = gRandom->Rndm();
105   return 1;
106 }
107
108 //------------------------------------------------------------------   
109 Float_t AliMUONResponseTriggerV1::FireStripProb(Float_t x4,Float_t theta,Int_t rpc,Int_t plane,Int_t cath) const
110 {
111 /// parametrisation of the probability that a strip neighbour of the main 
112 /// strip is fired
113 /// WARNING : need to convert x4 from cm to mm
114
115   Float_t hv = fHVvalues.At(18*plane+rpc);
116   Float_t parA, parB, parC;
117   
118   if(fWorkCondition == 2) //avalanche
119     parB = fBValues.At(72*cath+18*plane+rpc);
120   else //streamer
121     parB = 2.966;
122   
123   
124   parA = 6.089 * hv - 52.70;
125   parC = 8.3e-4 * hv - 0.5e-3;  
126
127  return (TMath::Cos(theta)*parA/(parA+TMath::Cos(theta)*TMath::Power(x4*10.,parB))+parC)/(TMath::Cos(theta)+parC);
128 }
129
130 //------------------------------------------------------------------
131 void AliMUONResponseTriggerV1::DisIntegrate(const AliMUONHit& hit, TList& digits, Float_t /*timeDif*/)
132 {
133   /// Generate digits (on each cathode) from 1 hit, with cluster-size generation.
134   
135   digits.Clear();
136   
137   Float_t xhit = hit.X();
138   Float_t yhit = hit.Y();
139   Float_t zhit = hit.Z();
140   Int_t detElemId = hit.DetElemId();
141   Int_t plane = detElemId/100 - 11; //plane from 0 to 3
142   Int_t rpc = detElemId%100; //rpc from 0 to 3
143   
144   Double_t x,y,z;
145   Global2Local(detElemId,xhit,yhit,zhit,x,y,z);
146   
147   Float_t tof = hit.Age();
148   Int_t twentyNano(100);
149   if (tof<AliMUONConstants::TriggerTofLimit())
150   {
151     twentyNano=1;
152   }
153   
154   
155   Int_t nboard = 0;
156
157   for(Int_t cath = AliMp::kCath0; cath <= AliMp::kCath1; ++cath)
158   {
159     const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
160     
161     AliMpPad pad = seg->PadByPosition(x,y,kFALSE);
162     Int_t ix = pad.GetIx();
163     Int_t iy = pad.GetIy();
164     
165     AliDebug(1,Form("xhit,yhit=%e,%e lx,ly,lz=%e,%e,%e ix,iy=%d,%d",xhit,yhit,x,y,z,ix,iy));
166     
167     if ( !pad.IsValid() )
168     {
169       AliWarning(Form("hit w/o strip %d-%d xhit,yhit=%e,%e local x,y,z ""%e,%e,%e ix,iy=%d,%d",detElemId,cath,xhit,yhit,x,y,z,ix,iy));
170       continue;
171     }
172     
173     if ( cath == AliMp::kCath0 ) nboard = pad.GetLocalBoardId(0);
174         
175     AliMUONDigit* d = new AliMUONDigit(detElemId,nboard,
176                                        pad.GetLocalBoardChannel(0),
177                                        cath);
178     
179     d->SetPadXY(ix,iy);
180     d->SetCharge(twentyNano);
181     
182     digits.Add(d);
183     
184     SetGenerCluster(); // 1 randum number per cathode (to be checked)
185     
186     Int_t xList[30], yList[30];
187     Neighbours(cath,ix,iy,xList,yList);
188     
189     
190     Int_t qp = 0; // fired/no-fired strip = 1/0
191     for (Int_t i=0; i<30; i++)  // loop on neighbors
192     {
193       if (i==0 || i==15 || qp!=0) // built-up cluster // need to iterate in iy/ix for bending/non-bending plane
194       {
195         Int_t ixNeigh = (cath == 0) ? ix : xList[i];
196         Int_t iyNeigh = (cath == 0) ? yList[i] : iy;
197         
198         AliMpPad padNeigh = seg->PadByIndices(ixNeigh,iyNeigh,kFALSE);
199         if(padNeigh.IsValid()) // existing neighbourg
200         {
201           Int_t dix=-(ixNeigh-ix);
202           Int_t diy=-(iyNeigh-iy);
203           Float_t xlocalNeigh = padNeigh.GetPositionX();
204           Float_t ylocalNeigh = padNeigh.GetPositionY();
205           Float_t dpx = padNeigh.GetDimensionX();
206           Float_t dpy = padNeigh.GetDimensionY();
207           Float_t distX = TMath::Abs((Float_t)dix) * ((Float_t)dix * dpx + xlocalNeigh - x);
208           Float_t distY = TMath::Abs((Float_t)diy) * ((Float_t)diy * dpy + ylocalNeigh - y);
209           Float_t dist = TMath::Sqrt(distX*distX+distY*distY);
210                 
211           if(fGenerCluster < FireStripProb(dist,0,rpc,plane,cath))
212             qp = 1;
213           else
214             qp = 0;
215                 
216           if(qp == 1)
217           { // this digit is fired    
218             AliMUONDigit* dNeigh = new AliMUONDigit(detElemId,padNeigh.GetLocalBoardId(0),padNeigh.GetLocalBoardChannel(0),cath);
219             
220             dNeigh->SetPadXY(ixNeigh,iyNeigh);      
221             dNeigh->SetCharge(twentyNano);
222             digits.Add(dNeigh);
223           } // digit fired
224         } // pad is valid
225       } // built-up cluster
226     } // loop on neighbors
227   } // loop on cathode
228 }
229
230 //------------------------------------------------------------------
231 void AliMUONResponseTriggerV1::SetHV()
232 {
233   TString side;
234   Int_t newRPC=0,newPlane=0;
235   
236   AliCDBManager *manager = AliCDBManager::Instance();
237   AliCDBPath path("MUON/Calib/TriggerDCS");
238   AliCDBEntry *entry = manager->Get(path);
239   if (entry == NULL) {
240     AliWarning("No map found in MUON/Calib/TriggerDCS");
241     return;
242   }
243   TMap *hvMap = dynamic_cast<TMap*>(entry->GetObject());
244   TObjArray *objArr = 0x0;
245   
246   AliDCSValue *dcsValue = 0x0;
247   UInt_t time1,time2,timebegin=0,timeend=0;
248   Int_t nEntries;
249   Float_t voltage = 0;
250   
251   for(Int_t iPlane=0; iPlane<4; iPlane++) //loop on MT
252   {
253     for(Int_t iRPC=0; iRPC<18; iRPC++) //loop on RPC
254     {
255       if(iRPC>=5 && iRPC<=13)
256       {
257         side = "OUTSIDE";
258         newRPC = 14-iRPC;
259       }
260   
261       else
262       {
263         side = "INSIDE";
264     
265         if(iRPC>=14)
266           newRPC = iRPC-13;
267         else
268           newRPC = iRPC+5;
269       }
270   
271       switch(iPlane)
272       {
273         case 0: newPlane = 11; break;
274         case 1: newPlane = 12; break;
275         case 2: newPlane = 21; break;
276         case 3: newPlane = 22; break;
277       }
278   
279       objArr = (TObjArray*)hvMap->GetValue(Form("MTR_%s_MT%d_RPC%d_HV.vEff",side.Data(),newPlane,newRPC));
280       nEntries = objArr->GetEntries();
281         
282       for(Int_t i=0; i<nEntries-1; i++)
283       {   
284         dcsValue = (AliDCSValue*)objArr->At(i+1);
285         time2 = dcsValue->GetTimeStamp();
286     
287         if(i==nEntries-2)
288           timeend = time2;
289     
290         dcsValue = (AliDCSValue*)objArr->At(i);
291           time1 = dcsValue->GetTimeStamp();
292     
293         if(i==0)
294           timebegin = time1;
295     
296         voltage += (dcsValue->GetFloat())*(time2-time1);
297       }
298       
299       fHVvalues.AddAt(voltage/(timeend-timebegin)/1000,18*iPlane+iRPC); //voltage in kV, not in V
300       
301       voltage=0;
302     }
303   }
304 }
305
306 //------------------------------------------------------------------  
307 void AliMUONResponseTriggerV1::SetBValues()
308 {
309   Float_t bValues[2][4][18] =                                                                                                                         {{{1.97,2.47,2.47,2.47,2.97,2.97,2.47,2.47,1.97,2.22,1.97,2.47,1.97,2.97,2.97,2.47,2.47,1.97},  //MT11BP
310     {2.22,2.22,1.97,2.47,2.97,2.97,1.97,2.47,1.97,1.97,1.97,2.47,1.97,2.97,2.97,1.97,1.97,1.97},  //MT12BP
311     {2.22,2.22,2.47,2.47,2.97,2.97,2.47,2.47,2.22,1.97,1.97,2.47,1.97,2.97,2.97,1.97,1.97,1.97},  //MT21BP
312     {1.97,1.97,2.97,2.97,2.97,2.97,2.47,1.97,1.97,1.97,1.72,2.47,2.22,2.97,2.97,1.97,1.97,1.97}}, //MT22BP
313    {{1.97,2.47,2.47,2.97,2.97,2.97,2.97,2.47,1.97,1.97,2.22,2.47,2.97,2.97,2.97,2.97,1.97,1.72},  //MT11NBP
314     {2.47,1.97,2.22,2.97,2.97,2.97,2.47,2.97,1.97,1.97,1.97,2.97,2.97,2.97,2.97,2.97,1.97,1.97},  //MT12NBP
315     {1.97,2.47,2.47,2.97,2.97,2.97,2.97,2.47,2.22,1.97,2.22,2.47,2.97,2.97,2.97,2.47,1.97,1.97},  //MT21NBP
316     {1.72,1.97,2.97,2.97,2.97,2.97,2.97,1.97,1.72,2.22,1.97,2.47,2.97,2.47,2.97,1.97,1.97,1.97}}};//MT22NBP
317                                 
318   for(Int_t iCath=0; iCath<2; iCath++) //loop on side
319   {
320     for(Int_t iPlane=0; iPlane<4; iPlane++) //loop on MT
321     {
322       for(Int_t iRPC=0; iRPC<18; iRPC++) //loop on RPC
323       {
324         fBValues.AddAt(bValues[iCath][iPlane][iRPC],72*iCath+18*iPlane+iRPC);
325       }
326     }
327   }
328 }
329
330 //------------------------------------------------------------------  
331 void AliMUONResponseTriggerV1::Neighbours(const Int_t cath, const Int_t ix, const Int_t iy, Int_t Xlist[30], Int_t Ylist[30]) const
332 {
333   ///-----------------BENDING-----------------------------------------      /n
334   /// Returns list of 30 next neighbours for given X strip (ix, iy)         /n
335   /// neighbour number 4 in the list -                                      /n    
336   /// neighbour number 3 in the list  |                                     /n   
337   /// neighbour number 2 in the list  |_ Upper part                         /n         
338   /// neighbour number 1 in the list  |                                     /n    
339   /// neighbour number 0 in the list -                                      /n   
340   ///      X strip (ix, iy)                                                 /n
341   /// neighbour number 5 in the list -                                      /n
342   /// neighbour number 6 in the list  | _ Lower part                        /n
343   /// neighbour number 7 in the list  |                                     /n
344   /// neighbour number 8 in the list  |                                     /n
345   /// neighbour number 9 in the list -                                      /n
346   ///                                                                       /n
347   ///-----------------NON-BENDING-------------------------------------      /n
348   /// Returns list of 30 next neighbours for given Y strip (ix, iy)         /n 
349   /// neighbour number 9 8 7 6 5 (Y strip (ix, iy)) 0 1 2 3 4 in the list   /n 
350   ///                  |_______|                    |_______|               /n 
351   ///                    left                         right                 /n
352   
353   for (Int_t i=0; i<30; i++)
354   {
355     Xlist[i] = -1;
356     Ylist[i] = -1;
357   }
358   
359   Int_t iList[30]={29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
360   
361   // need to iterate in iy/ix for bending/non-bending plane
362   Int_t iNeigh = (cath == 0) ? iy : ix;
363     
364   Int_t i=0;
365   for (Int_t j=iNeigh-15; j<=iNeigh+15; j++)
366   {
367     if (j == iNeigh)
368       continue;
369         
370     // need to iterate in iy/ix for bending/non-bending plane
371     Int_t ixNeigh = ( cath == 0 ) ? ix : j;
372     Int_t iyNeigh = ( cath == 0 ) ? j : iy;
373         
374 //      cout << " " << cath << " " << ix << " " << iy 
375 //           << " "  << ixNeigh << " " << iyNeigh << "\n";
376         
377     Xlist[iList[i]]=ixNeigh;    
378     Ylist[iList[i]]=iyNeigh;    
379     i++;
380   } 
381 }