In AliMUONResponseTriggerV1.h
[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   TMap *hvMap = dynamic_cast<TMap*>(entry->GetObject());
240   TObjArray *objArr = 0x0;
241   
242   AliDCSValue *dcsValue = 0x0;
243   UInt_t time1,time2,timebegin,timeend;
244   Int_t nEntries;
245   Float_t voltage = 0;
246   
247   for(Int_t iPlane=0; iPlane<4; iPlane++) //loop on MT
248   {
249     for(Int_t iRPC=0; iRPC<18; iRPC++) //loop on RPC
250     {
251       if(iRPC>=5 && iRPC<=13)
252       {
253         side = "OUTSIDE";
254         newRPC = 14-iRPC;
255       }
256   
257       else
258       {
259         side = "INSIDE";
260     
261         if(iRPC>=14)
262           newRPC = iRPC-13;
263         else
264           newRPC = iRPC+5;
265       }
266   
267       switch(iPlane)
268       {
269         case 0: newPlane = 11; break;
270         case 1: newPlane = 12; break;
271         case 2: newPlane = 21; break;
272         case 3: newPlane = 22; break;
273       }
274   
275       objArr = (TObjArray*)hvMap->GetValue(Form("MTR_%s_MT%d_RPC%d_HV.vEff",side.Data(),newPlane,newRPC));
276       nEntries = objArr->GetEntries();
277         
278       for(Int_t i=0; i<nEntries-1; i++)
279       {   
280         dcsValue = (AliDCSValue*)objArr->At(i+1);
281         time2 = dcsValue->GetTimeStamp();
282     
283         if(i==nEntries-2)
284           timeend = time2;
285     
286         dcsValue = (AliDCSValue*)objArr->At(i);
287           time1 = dcsValue->GetTimeStamp();
288     
289         if(i==0)
290           timebegin = time1;
291     
292         voltage += (dcsValue->GetFloat())*(time2-time1);
293       }
294       
295       fHVvalues.AddAt(voltage/(timeend-timebegin)/1000,18*iPlane+iRPC); //voltage in kV, not in V
296       
297       voltage=0;
298     }
299   }
300 }
301
302 //------------------------------------------------------------------  
303 void AliMUONResponseTriggerV1::SetBValues()
304 {
305   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
306     {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
307     {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
308     {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
309    {{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
310     {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
311     {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
312     {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
313                                 
314   for(Int_t iCath=0; iCath<2; iCath++) //loop on side
315   {
316     for(Int_t iPlane=0; iPlane<4; iPlane++) //loop on MT
317     {
318       for(Int_t iRPC=0; iRPC<18; iRPC++) //loop on RPC
319       {
320         fBValues.AddAt(bValues[iCath][iPlane][iRPC],72*iCath+18*iPlane+iRPC);
321       }
322     }
323   }
324 }
325
326 //------------------------------------------------------------------  
327 void AliMUONResponseTriggerV1::Neighbours(const Int_t cath, const Int_t ix, const Int_t iy, Int_t Xlist[30], Int_t Ylist[30]) const
328 {
329   ///-----------------BENDING-----------------------------------------      /n
330   /// Returns list of 30 next neighbours for given X strip (ix, iy)         /n
331   /// neighbour number 4 in the list -                                      /n    
332   /// neighbour number 3 in the list  |                                     /n   
333   /// neighbour number 2 in the list  |_ Upper part                         /n         
334   /// neighbour number 1 in the list  |                                     /n    
335   /// neighbour number 0 in the list -                                      /n   
336   ///      X strip (ix, iy)                                                 /n
337   /// neighbour number 5 in the list -                                      /n
338   /// neighbour number 6 in the list  | _ Lower part                        /n
339   /// neighbour number 7 in the list  |                                     /n
340   /// neighbour number 8 in the list  |                                     /n
341   /// neighbour number 9 in the list -                                      /n
342   ///                                                                       /n
343   ///-----------------NON-BENDING-------------------------------------      /n
344   /// Returns list of 30 next neighbours for given Y strip (ix, iy)         /n 
345   /// neighbour number 9 8 7 6 5 (Y strip (ix, iy)) 0 1 2 3 4 in the list   /n 
346   ///                  |_______|                    |_______|               /n 
347   ///                    left                         right                 /n
348   
349   for (Int_t i=0; i<30; i++)
350   {
351     Xlist[i] = -1;
352     Ylist[i] = -1;
353   }
354   
355   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};
356   
357   // need to iterate in iy/ix for bending/non-bending plane
358   Int_t iNeigh = (cath == 0) ? iy : ix;
359     
360   Int_t i=0;
361   for (Int_t j=iNeigh-15; j<=iNeigh+15; j++)
362   {
363     if (j == iNeigh)
364       continue;
365         
366     // need to iterate in iy/ix for bending/non-bending plane
367     Int_t ixNeigh = ( cath == 0 ) ? ix : j;
368     Int_t iyNeigh = ( cath == 0 ) ? j : iy;
369         
370 //      cout << " " << cath << " " << ix << " " << iy 
371 //           << " "  << ixNeigh << " " << iyNeigh << "\n";
372         
373     Xlist[iList[i]]=ixNeigh;    
374     Ylist[iList[i]]=iyNeigh;    
375     i++;
376   } 
377 }