1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 // Class AliMUONTriggerResponseV1
21 // Trigger chamber response
22 // with cluster size activated
23 //-----------------------------------------------------------------------------
25 #include "AliMUONResponseTriggerV1.h"
27 #include "AliMUONDigit.h"
28 #include "AliMUONGeometryTransformer.h"
29 #include "AliMUONConstants.h"
31 #include "AliCDBManager.h"
32 #include "AliCDBPath.h"
33 #include "AliCDBEntry.h"
36 #include "AliMpSegmentation.h"
37 #include "AliMpVSegmentation.h"
38 #include "AliMpCathodType.h"
41 #include "AliDCSValue.h"
48 ClassImp(AliMUONResponseTriggerV1)
55 return static_cast<AliMUON*>(gAlice->GetModule("MUON"));
58 void Global2Local(Int_t detElemId, Double_t xg, Double_t yg, Double_t zg, Double_t& xl, Double_t& yl, Double_t& zl)
60 // ideally should be :
62 // AliMUONGeometry::Global2Local(detElemId,xg,yg,zg,x,y,z);
63 // but while waiting for this geometry singleton, let's go through
66 const AliMUONGeometryTransformer* transformer = muon()->GetGeometryTransformer();
67 transformer->Global2Local(detElemId,xg,yg,zg,xl,yl,zl);
73 //------------------------------------------------------------------
74 AliMUONResponseTriggerV1::AliMUONResponseTriggerV1() : AliMUONResponseTrigger(), fGenerCluster(0), fHVvalues(), fBValues(), fWorkCondition(2)
78 //------------------------------------------------------------------
79 AliMUONResponseTriggerV1::AliMUONResponseTriggerV1(Int_t mode) : AliMUONResponseTrigger(), fGenerCluster(0), fHVvalues(), fBValues(), fWorkCondition(mode)
81 //mode: 1=streamer - 2=avalanche
86 //------------------------------------------------------------------
87 AliMUONResponseTriggerV1::~AliMUONResponseTriggerV1()
91 //------------------------------------------------------------------
92 Int_t AliMUONResponseTriggerV1::SetGenerCluster()
94 // Set the GenerCluster parameter and return 1
95 fGenerCluster = gRandom->Rndm();
99 //------------------------------------------------------------------
100 Float_t AliMUONResponseTriggerV1::FireStripProb(Float_t x4,Float_t theta,Int_t rpc,Int_t plane,Int_t cath) const
102 /// parametrisation of the probability that a strip neighbour of the main
104 /// WARNING : need to convert x4 from cm to mm
106 Float_t hv = fHVvalues.At(18*plane+rpc);
107 Float_t parA, parB, parC;
109 if(fWorkCondition == 2) //avalanche
110 parB = fBValues.At(72*cath+18*plane+rpc);
115 parA = 6.089 * hv - 52.70;
116 parC = 8.3e-4 * hv - 0.5e-3;
118 return (TMath::Cos(theta)*parA/(parA+TMath::Cos(theta)*TMath::Power(x4*10.,parB))+parC)/(TMath::Cos(theta)+parC);
121 //------------------------------------------------------------------
122 void AliMUONResponseTriggerV1::DisIntegrate(const AliMUONHit& hit, TList& digits, Float_t /*timeDif*/)
124 /// Generate digits (on each cathode) from 1 hit, with cluster-size generation.
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
136 Global2Local(detElemId,xhit,yhit,zhit,x,y,z);
138 Float_t tof = hit.Age();
139 Int_t twentyNano(100);
140 if (tof<AliMUONConstants::TriggerTofLimit())
148 for(Int_t cath = AliMp::kCath0; cath <= AliMp::kCath1; ++cath)
150 const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
152 AliMpPad pad = seg->PadByPosition(x,y,kFALSE);
153 Int_t ix = pad.GetIx();
154 Int_t iy = pad.GetIy();
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));
158 if ( !pad.IsValid() )
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));
164 if ( cath == AliMp::kCath0 ) nboard = pad.GetLocalBoardId(0);
166 AliMUONDigit* d = new AliMUONDigit(detElemId,nboard,
167 pad.GetLocalBoardChannel(0),
171 d->SetCharge(twentyNano);
175 SetGenerCluster(); // 1 randum number per cathode (to be checked)
177 Int_t xList[30], yList[30];
178 Neighbours(cath,ix,iy,xList,yList);
181 Int_t qp = 0; // fired/no-fired strip = 1/0
182 for (Int_t i=0; i<30; i++) // loop on neighbors
184 if (i==0 || i==15 || qp!=0) // built-up cluster // need to iterate in iy/ix for bending/non-bending plane
186 Int_t ixNeigh = (cath == 0) ? ix : xList[i];
187 Int_t iyNeigh = (cath == 0) ? yList[i] : iy;
189 AliMpPad padNeigh = seg->PadByIndices(ixNeigh,iyNeigh,kFALSE);
190 if(padNeigh.IsValid()) // existing neighbourg
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);
202 if(fGenerCluster < FireStripProb(dist,0,rpc,plane,cath))
208 { // this digit is fired
209 AliMUONDigit* dNeigh = new AliMUONDigit(detElemId,padNeigh.GetLocalBoardId(0),padNeigh.GetLocalBoardChannel(0),cath);
211 dNeigh->SetPadXY(ixNeigh,iyNeigh);
212 dNeigh->SetCharge(twentyNano);
216 } // built-up cluster
217 } // loop on neighbors
221 //------------------------------------------------------------------
222 void AliMUONResponseTriggerV1::SetHV()
225 /// Set HV values from OCDB
229 Int_t newRPC=0,newPlane=0;
231 AliCDBManager *manager = AliCDBManager::Instance();
232 AliCDBPath path("MUON/Calib/TriggerDCS");
233 AliCDBEntry *entry = manager->Get(path);
235 AliWarning("No map found in MUON/Calib/TriggerDCS");
238 TMap *hvMap = dynamic_cast<TMap*>(entry->GetObject());
239 TObjArray *objArr = 0x0;
241 AliDCSValue *dcsValue = 0x0;
242 UInt_t time1,time2,timebegin=0,timeend=0;
246 for(Int_t iPlane=0; iPlane<4; iPlane++) //loop on MT
248 for(Int_t iRPC=0; iRPC<18; iRPC++) //loop on RPC
250 if(iRPC>=5 && iRPC<=13)
268 case 0: newPlane = 11; break;
269 case 1: newPlane = 12; break;
270 case 2: newPlane = 21; break;
271 case 3: newPlane = 22; break;
274 objArr = (TObjArray*)hvMap->GetValue(Form("MTR_%s_MT%d_RPC%d_HV.vEff",side.Data(),newPlane,newRPC));
275 nEntries = objArr->GetEntries();
277 for(Int_t i=0; i<nEntries-1; i++)
279 dcsValue = (AliDCSValue*)objArr->At(i+1);
280 time2 = dcsValue->GetTimeStamp();
285 dcsValue = (AliDCSValue*)objArr->At(i);
286 time1 = dcsValue->GetTimeStamp();
291 voltage += (dcsValue->GetFloat())*(time2-time1);
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
299 AliDebug(1,Form("HV value for MTR_%s_MT%d_RPC%d_HV.vEff = %g (kV)",side.Data(),newPlane,newRPC,meanVoltage));
304 //------------------------------------------------------------------
305 void AliMUONResponseTriggerV1::SetBValues()
308 /// Set B values for cluster size function
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
322 for(Int_t iCath=0; iCath<2; iCath++) //loop on side
324 for(Int_t iPlane=0; iPlane<4; iPlane++) //loop on MT
326 for(Int_t iRPC=0; iRPC<18; iRPC++) //loop on RPC
328 fBValues.AddAt(bValues[iCath][iPlane][iRPC],72*iCath+18*iPlane+iRPC);
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
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
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
357 for (Int_t i=0; i<30; i++)
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};
365 // need to iterate in iy/ix for bending/non-bending plane
366 Int_t iNeigh = (cath == 0) ? iy : ix;
369 for (Int_t j=iNeigh-15; j<=iNeigh+15; j++)
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;
378 // cout << " " << cath << " " << ix << " " << iy
379 // << " " << ixNeigh << " " << iyNeigh << "\n";
381 Xlist[iList[i]]=ixNeigh;
382 Ylist[iList[i]]=iyNeigh;