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