]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONSt1Response.cxx
Improving stepmanager and reponse function of the chambers: gain and saturation ...
[u/mrichter/AliRoot.git] / MUON / AliMUONSt1Response.cxx
CommitLineData
ba030c0e 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// Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
19//
20// Class AliMUONSt1Response
21// ----------------------------
22// Response class for station 1 including electronics and detector response.
23// Individual pedestals or noise levels can be controlled separately.
24// The current pulse height responses do not contain any physics
25
26#include <vector>
ba030c0e 27#include <TMath.h>
28#include <TRandom.h>
29#include <TSystem.h>
74d70ece 30#include <Riostream.h>
5f91c9e8 31#include "AliMpIntPair.h"
32#include "AliMpPlaneSegmentation.h"
33#include "AliMpPad.h"
34#include "AliMpMotifMap.h"
35#include "AliMpSector.h"
36#include "AliMpPlane.h"
37#include "AliMpZone.h"
38#include "AliMpSubZone.h"
39#include "AliMpVRowSegment.h"
ba030c0e 40#include "AliMUONSt1Response.h"
41#include "AliMUONSt1ResponseParameter.h"
42#include "AliMUONSt1ResponseRule.h"
43#include "AliMUONSt1IniReader.h"
44#include "AliMUONSt1Decoder.h"
45#include "AliMUONTransientDigit.h"
46
47ClassImp(AliMUONSt1Response);
48
74d70ece 49const TString AliMUONSt1Response::fgkTopDir = getenv("ALICE_ROOT");
50const TString AliMUONSt1Response::fgkDataDir = "/MUON/data/";
ba030c0e 51const TString AliMUONSt1Response::fgkConfigBaseName = "configChamber";
52const TString AliMUONSt1Response::fgkStandardIniFileName = "st1StdParameter.ini";
53
54const TString AliMUONSt1Response::fgkBaseName ="base";
55const TString AliMUONSt1Response::fgkIncludeName ="include";
56const TString AliMUONSt1Response::fgkParameterName ="parameter";
57const TString AliMUONSt1Response::fgkRegionName ="region";
58const TString AliMUONSt1Response::fgkRuleName ="rule";
59const TString AliMUONSt1Response::fgkNameName ="name";
60const TString AliMUONSt1Response::fgkPedestalName ="pedestal";
61const TString AliMUONSt1Response::fgkNoiseName ="noise";
62const TString AliMUONSt1Response::fgkStateName ="state";
63const TString AliMUONSt1Response::fgkMName ="padM";
64const TString AliMUONSt1Response::fgkMGName ="padMG";
65const TString AliMUONSt1Response::fgkMGCName ="padMGC";
66const TString AliMUONSt1Response::fgkIJName ="padIJ";
67const TString AliMUONSt1Response::fgkXYName ="padXY";
68const TString AliMUONSt1Response::fgkZoneName ="zone";
69const TString AliMUONSt1Response::fgkStickyOnName ="stickyOn";
70const TString AliMUONSt1Response::fgkStickyOffName ="stickyOff";
71const TString AliMUONSt1Response::fgkFileName ="file";
72const TString AliMUONSt1Response::fgkValueName ="value";
73const TString AliMUONSt1Response::fgkGausName ="gaus";
74const TString AliMUONSt1Response::fgkNotName ="no";
75const TString AliMUONSt1Response::fgkNofSigmaName ="nofSigma";
76
77
78
79//__________________________________________________________________________
80AliMUONSt1Response::AliMUONSt1Response(Int_t chamber)
81 :AliMUONResponseV0()
82 ,fChamber(chamber),fParams(),fRegions(),fTrashList()
83
84{
85 // default pedestal value
86 fCountNofCalls=0;
87 fCountUnknownZone=0;
88 fCountUnknownIndices=0;
89
90 Int_t i;
91 for (i=0;i<2;i++){
92 fIniFileName[i]="";
93 fPlane[0]=0;
94 fPlaneSegmentation[i]=0;
95 for (Int_t j=0;j<fgkNofZones;j++)
96 {
97 fDefaultParameters[i][j]=0;
98 }
99 }
100 fTrashList.SetOwner(kTRUE);
101}
102
103
104//__________________________________________________________________________
105AliMUONSt1Response::~AliMUONSt1Response()
106{
107//destructor
108 Int_t i;
109 for (i=0;i<2;i++){
110 if (fPlaneSegmentation[i]) delete fPlaneSegmentation[i];
111 if (fPlane[i]) delete fPlane[i];
112 fTrashList.Delete();
113 }
114}
115
116//__________________________________________________________________________
117void AliMUONSt1Response::SetIniFileName(Int_t plane,const TString& fileName)
118{
119// Set the file to be read for the response parameters
120 if ((plane>=0) && (plane<=1)) fIniFileName[plane] = fileName;
121}
122
123
124//__________________________________________________________________________
125void AliMUONSt1Response::ReadCouplesOfIntRanges(const string& value,TList* list,AliMUONSt1ElectronicElement::TDescription descr)
126{
127// Decode couplets of integer ranges (enclosed within parenthesis and
128// separated by a comma, eg. (12/20,33/60) for ranges 12 to 20 and 33 to 60)
129// and save these ranges in <list>
130 vector<string> lstCpl = decoder::SplitNtuples(value);
131 for (unsigned int n=0;n<lstCpl.size();n++){ // for each (..,..) couplet
132 vector<string> lst = decoder::SplitList(lstCpl[n],",");
133 // should have 2 elements
134 if (lst.size() != 2) {
135 Warning("ReadIniFile","Bad pad definition");
136 continue;
137 }
138 vector<pair <int,int> > lst1 = decoder::DecodeListOfIntRanges(lst[0],";");
139 vector<pair <int,int> > lst2 = decoder::DecodeListOfIntRanges(lst[1],";");
140 for (unsigned int u1=0;u1<lst1.size();u1++){
141 for (unsigned int u2=0;u2<lst2.size();u2++){
142 AliMUONSt1ElectronicElement* elem
143 = new AliMUONSt1ElectronicElement(descr);
144 fTrashList.Add(elem);
145 elem->SetRange(0,lst1[u1].first,lst1[u1].second);
146 elem->SetRange(1,lst2[u2].first,lst2[u2].second);
147 list->Add(elem);
148 }
149 }
150 }
151}
152
153
154//__________________________________________________________________________
155void AliMUONSt1Response::ReadCouplesOfFloatRanges(const string& value,TList* list)
156{
157// Decode couplets of floating point ranges (enclosed within parenthesis and
158// separated by a comma, eg. (12./20.,33./60.) for ranges 12. to 20. and 33. to 60.)
159// and save these ranges in <list>
160 vector<string> lstCpl = decoder::SplitNtuples(value);
161 for (unsigned int n=0;n<lstCpl.size();n++){ // for each (..,..) couplets
162 vector<string> lst = decoder::SplitList(lstCpl[n],",");
163 // should have 2 elements
164 if (lst.size() != 2) {
165 Warning("ReadIniFile","Bad pad definition");
166 continue;
167 }
168 vector<pair <double,double> > lst1 = decoder::DecodeListOfFloatRanges(lst[0],";");
169 vector<pair <double,double> > lst2 = decoder::DecodeListOfFloatRanges(lst[1],";");
170 for (unsigned int u1=0;u1<lst1.size();u1++){
171 for (unsigned int u2=0;u2<lst2.size();u2++){
172 AliMUONSt1ElectronicElement* elem
173 = new AliMUONSt1ElectronicElement(AliMUONSt1ElectronicElement::kXY);
174 fTrashList.Add(elem);
175 elem->SetRange(0,lst1[u1].first,lst1[u1].second);
176 elem->SetRange(1,lst2[u2].first,lst2[u2].second);
177 list->Add(elem);
178 }
179 }
180 }
181}
182
183
184//__________________________________________________________________________
185void AliMUONSt1Response::SetPairToParam(const string& name,const string& value,AliMUONSt1ResponseParameter* param) const
186{
187// set a (name,value) pair to <param>
74d70ece 188 TString path = fgkTopDir + fgkDataDir ;
ba030c0e 189 const char* nm = name.c_str();
190 if (fgkStateName.CompareTo(nm,TString::kIgnoreCase)==0){
191 param->SetState(atoi(value.c_str()));
192 } else if (fgkPedestalName.CompareTo(nm,TString::kIgnoreCase)==0){
193 vector<string> lst = decoder::SplitList(value," ");
194 if ((lst.size()>0) && (fgkNotName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
195 param->UnSetPedestal();
196 } else if ((lst.size()>1) && (fgkValueName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
197 param->SetPedestal(atof(lst[1].c_str()));
198 } else if ((lst.size()>1) && (fgkFileName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
199 param->SetPedestal(path+lst[1].c_str());
200 } else if ((lst.size()>2) && (fgkGausName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
201 param->SetPedestal(atof(lst[1].c_str()),atof(lst[2].c_str()));
202 }
203 } else if (fgkNoiseName.CompareTo(nm,TString::kIgnoreCase)==0){
204 vector<string> lst = decoder::SplitList(value," ");
205 if ((lst.size()>1) && (fgkValueName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
206 param->SetNoise(atof(lst[1].c_str()));
207 } else if ((lst.size()>1) && (fgkFileName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
208 param->SetNoise(path+lst[1].c_str());
209 } else if ((lst.size()>2) && (fgkGausName.CompareTo(lst[0].c_str(),TString::kIgnoreCase)==0)){
210 param->SetNoise(atof(lst[1].c_str()),atof(lst[2].c_str()));
211 }
212 } else if (fgkNofSigmaName.CompareTo(nm,TString::kIgnoreCase)==0){
213 param->SetNofSigma(atoi(value.c_str()));
214 } else if (fgkStickyOnName.CompareTo(nm,TString::kIgnoreCase)==0){
215 vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
216 for (unsigned int i=0;i<lst.size();i++){
217 for (int j=lst[i].first;(j<12) && (j<=lst[i].second);j++){
218 param->SetStickyBitOn(j);
219 }
220 }
221 } else if (fgkStickyOffName.CompareTo(nm,TString::kIgnoreCase)==0){
222 vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
223 for (unsigned int i=0;i<lst.size();i++){
224 for (int j=lst[i].first;(j<12) && (j<=lst[i].second);j++){
225 param->SetStickyBitOff(j);
226 }
227 }
228 }
229}
230
231
232//__________________________________________________________________________
233void AliMUONSt1Response::SetPairToListElem(const string& name,const string& value,TList* list)
234{
235// set a (name,value) pair to <list>
236 const char* nm = name.c_str();
237 if (fgkIJName.CompareTo(nm,TString::kIgnoreCase)==0){
238 ReadCouplesOfIntRanges(value,list,AliMUONSt1ElectronicElement::kIJ);
239 } else if (fgkMGCName.CompareTo(nm,TString::kIgnoreCase)==0){
240 ReadCouplesOfIntRanges(value,list,AliMUONSt1ElectronicElement::kMGC);
241 } else if (fgkMGName.CompareTo(nm,TString::kIgnoreCase)==0){
242 ReadCouplesOfIntRanges(value,list,AliMUONSt1ElectronicElement::kMG);
243 } else if (fgkMName.CompareTo(nm,TString::kIgnoreCase)==0){
244 vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
245 for (unsigned int i=0;i<lst.size();i++){
246 AliMUONSt1ElectronicElement* elem
247 = new AliMUONSt1ElectronicElement(AliMUONSt1ElectronicElement::kM);
248 fTrashList.Add(elem);
249 elem->SetRange(0,lst[i].first,lst[i].second);
250 list->Add(elem);
251 }
252 } else if (fgkXYName.CompareTo(nm,TString::kIgnoreCase)==0){
253 ReadCouplesOfFloatRanges(value,list);
254 }
255}
256
257
258//__________________________________________________________________________
259void AliMUONSt1Response::ReadIniFile(Int_t plane)
260{
261 //Read the ini file and fill the <plane>th structures
74d70ece 262 TString path = fgkTopDir + fgkDataDir ;
ba030c0e 263 //read .ini file
264 if (gSystem->AccessPathName(path+fIniFileName[plane],kReadPermission)){
265 Fatal("ReadIniFile",
266 Form("Unable to Read the file %s",fIniFileName[plane].Data()));
267 return;
268 }
269 fRegions.clear();
270 fParams.clear();
271 ReadIniFile(plane,path+fIniFileName[plane],kTRUE,kTRUE,kTRUE);
272}
273
274
275//__________________________________________________________________________
276void AliMUONSt1Response::ReadIniFile(Int_t plane,const TString& fileName,
277 Bool_t rdParam,Bool_t rdRegion,Bool_t rdRule)
278{
279 //Read the given ini file and fill the <plane>th structures
280 cout<<"Reading parameter file "<<fileName<<endl;
281 AliMUONSt1IniReader iniFile(fileName.Data());
282 AliMUONSt1IniReader::TChapter chap;
283 AliMUONSt1IniReader::TValueList vals;
284 AliMUONSt1IniReader::TValueList::iterator itValue;
285 while (!iniFile.Eof()){
286 chap = iniFile.MakeCurrentChapter();
287 TString chapName = chap.first.c_str();
288 vals = chap.second;
289 if (fgkBaseName.CompareTo(chapName,TString::kIgnoreCase)==0){
290 for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
291 string name = (*itValue).first;
292 string value = (*itValue).second;
293 if (fgkIncludeName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
294 vector<string> lst = decoder::SplitList(value,":");
295 if (lst.size()>0){
296 TString inFileName = TString(gSystem->DirName(fileName))+"/" + lst[0].c_str();
297 Bool_t inParam=kFALSE,inRegion=kFALSE,inRule=kFALSE;
298 if (lst.size()>1) {
299 vector<string> lst2 = decoder::SplitList(lst[1],",");
300 for (unsigned int k=0;k<lst2.size();k++){
301 if (fgkParameterName.CompareTo(lst2[k].c_str(),TString::kIgnoreCase)==0){
302 inParam=kTRUE;
303 } else if (fgkRegionName.CompareTo(lst2[k].c_str(),TString::kIgnoreCase)==0){
304 inRegion=kTRUE;
305 } else if (fgkRuleName.CompareTo(lst2[k].c_str(),TString::kIgnoreCase)==0){
306 inRule=kTRUE;
307 }
308 }
309 } else {
310 inParam=inRegion=inRule=kTRUE;
311 }
312 ReadIniFile(plane,inFileName,inParam,inRegion,inRule);
313 }
314 }
315 }
316 } else if (rdParam && fgkParameterName.CompareTo(chapName,TString::kIgnoreCase)==0){
317 AliMUONSt1ResponseParameter* param = new AliMUONSt1ResponseParameter();
318 fTrashList.Add(param);
319 string paramName=Form("Parameter %d",fParams.size()+1);
320 for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
321 string name = (*itValue).first;
322 string value = (*itValue).second;
323 if (fgkNameName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
324 paramName=value;
325 } else SetPairToParam(name,value,param);
326 }
327 fParams[paramName]=param;
328 } else if (rdRegion && fgkRegionName.CompareTo(chapName,TString::kIgnoreCase)==0){
329 TList* lstElem = new TList;
330 string listName=Form("Region %d",fRegions.size()+1);
331 for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
332 string name = (*itValue).first;
333 string value = (*itValue).second;
334 if (fgkNameName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
335 listName=value;
336 } else SetPairToListElem(name,value,lstElem);
337 }
338 fRegions[listName]=lstElem;
339 }
340 }
341 iniFile.Reset();
342 while (!iniFile.Eof()){
343 chap = iniFile.MakeCurrentChapter();
344 TString chapName = chap.first.c_str();
345 vals = chap.second;
346 if (rdRule && fgkRuleName.CompareTo(chapName,TString::kIgnoreCase)==0){
347 Int_t i;
348 Bool_t zones[fgkNofZones];
349 for (i=0;i<fgkNofZones;i++) zones[i]=kFALSE;
350 AliMUONSt1ResponseRule* rule=0;
351 for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
352 string name = (*itValue).first;
353 string value = (*itValue).second;
354 if (fgkZoneName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
355 vector< pair<int,int> > lst = decoder::DecodeListOfIntRanges(value);
356 for (unsigned int i=0;i<lst.size();i++){
357 for (int j=lst[i].first;(j<=fgkNofZones) && (j<=lst[i].second);j++) {
358 if (j>0) zones[j-1] = kTRUE;
359 }
360 }
361 } else if (fgkRegionName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
362 TListMap::iterator it = fRegions.find(value);
363 if (it != fRegions.end()){
364 if (!rule) {
365 rule = new AliMUONSt1ResponseRule();
366 fTrashList.Add(rule);
367 }
368 TIter next((*it).second);
369 AliMUONSt1ElectronicElement* el;
370 while ((el = static_cast<AliMUONSt1ElectronicElement*>(next()))){
371 rule->AddElement(el);
372 }
373 } else Warning("ReadIniFile",Form("Can't find region named %s",value.c_str()));
374 }
375 }
376 for (itValue = vals.begin() ; itValue != vals.end(); ++itValue){
377 string name = (*itValue).first;
378 string value = (*itValue).second;
379 if (fgkParameterName.CompareTo(name.c_str(),TString::kIgnoreCase)==0){
380 TParamsMap::iterator it = fParams.find(value);
381 if (it != fParams.end()){
382 AliMUONSt1ResponseParameter* param = (*it).second;
383 for (i=0;i<fgkNofZones;i++) if (zones[i]) {
384 fDefaultParameters[plane][i]=param;
385 }
386 if (rule) rule->AddParameter(param);
387 } else Warning("ReadIniFile",Form("Can't find parameter named %s",value.c_str()));
388 }
389 }
390 if (rule) fRulesList[plane].AddFirst(rule);
391 }
392 }
393 for (TListMap::iterator it = fRegions.begin() ; it != fRegions.end(); ++it) delete (*it).second;
394}
395
396
397//__________________________________________________________________________
398void AliMUONSt1Response::ReadFiles()
399{
400// Define the current response rules with respect to the description
401// given in the "configChamber1.ini" and "configChamber2.ini" files.
402 Int_t i;
74d70ece 403 TString path = fgkTopDir + fgkDataDir ;
ba030c0e 404
405 TString configFileName = path + fgkConfigBaseName + Form("%d.ini",fChamber);
406 if (gSystem->AccessPathName(configFileName,kReadPermission)){
407 // no configChamberI.ini file exists
408 SetIniFileName(0,fgkStandardIniFileName);
409 SetIniFileName(1,fgkStandardIniFileName);
410 } else {
411 cout<<"Reading configuration file "<<configFileName<<endl;
412 AliMUONSt1IniReader iniFile(configFileName.Data());
413 while (!iniFile.Eof()) {
414 iniFile.ReadNextLine();
415 if (iniFile.GetCurrentType() != AliMUONSt1IniReader::kValue) continue;
416 Int_t plane;
417 if ((sscanf(iniFile.GetCurrentName().c_str()
418 ,"file%d",&plane)==1) && (plane>=0) && (plane<=1)){
419 SetIniFileName(plane,iniFile.GetCurrentValue().c_str());
420 }
421 }
422 }
423 //book memory and fill them with .ini files
4a147321 424 fPlane[0]=AliMpPlane::Create(kStation1, kBendingPlane);
425 fPlane[1]=AliMpPlane::Create(kStation1, kNonBendingPlane);
ba030c0e 426 for (i=0;i<2;i++){
5f91c9e8 427 fPlaneSegmentation[i]= new AliMpPlaneSegmentation(fPlane[i]);
ba030c0e 428 ReadIniFile(i);
429 }
430}
431
432//__________________________________________________________________________
433Float_t AliMUONSt1Response::IntPH(Float_t eloss)
434{
435 // Calculate charge from given ionization energy lost.
436 Int_t nel;
437 nel= Int_t(eloss*1.e9/20);
438 Float_t charge=0;
439 if (nel == 0) nel=1;
440 for (Int_t i=1;i<=nel;i++) {
441 Float_t arg=0.;
442 while(!arg) arg = gRandom->Rndm();
443 charge -= fChargeSlope*TMath::Log(arg);
444 }
445 return charge;
446}
447
448
449//__________________________________________________________________________
5f91c9e8 450AliMpZone* AliMUONSt1Response::FindZone(AliMpSector* sector,Int_t posId)
ba030c0e 451{
5f91c9e8 452// to be moved to AliMpSector::
ba030c0e 453 for (Int_t izone=1;izone<=sector->GetNofZones();izone++){
5f91c9e8 454 AliMpZone* zone = sector->GetZone(izone);
ba030c0e 455 for (Int_t isub=0;isub<zone->GetNofSubZones();isub++){
5f91c9e8 456 AliMpSubZone* sub=zone->GetSubZone(isub);
ba030c0e 457 for (Int_t iseg=0;iseg<sub->GetNofRowSegments();iseg++){
458 if (sub->GetRowSegment(iseg)->HasMotifPosition(posId)) return zone;
459 }
460 }
461 }
462 return 0;
463}
464
465
466//__________________________________________________________________________
467
468Int_t AliMUONSt1Response::DigitResponse(Int_t digit,AliMUONTransientDigit* where)
469{
470 // returns the electronic response of pad located at <where>, when
471 // a charge <digit> is present
472
473 //cout<<"electronic of pad "<<where->PadX()<<' '<<where->PadY()
474 // <<" on plane "<<where->Cathode()<<endl;
475
476 //read the files the first time this function is called
477 if (!fPlane[0]) ReadFiles();
478
479 fCountNofCalls++;
480
5f91c9e8 481 AliMpIntPair indices(where->PadX(),where->PadY());
482 AliMpPad pad = fPlaneSegmentation[where->Cathode()]->PadByIndices(indices,kFALSE);
ba030c0e 483 Int_t GC=0;
484 Int_t numZone=0;
5f91c9e8 485 AliMpZone* zone=0;
ba030c0e 486
487 if (pad.IsValid()) {
5f91c9e8 488 AliMpIntPair location = pad.GetLocation();
ba030c0e 489 //cout<<location.GetFirst()<<endl;
490 Int_t posId=abs(location.GetFirst());
5f91c9e8 491 AliMpSector* sector=0;
ba030c0e 492 if (fPlane[0]->GetFrontSector()->GetMotifMap()->FindMotifPosition(posId))
5f91c9e8 493 sector=(AliMpSector*)fPlane[0]->GetFrontSector();
ba030c0e 494 else if (fPlane[0]->GetBackSector()->GetMotifMap()->FindMotifPosition(posId))
5f91c9e8 495 sector=(AliMpSector*)fPlane[0]->GetBackSector();
ba030c0e 496
497 if (sector) zone=FindZone(sector,posId);
498 if (zone){
499 numZone=zone->GetID()-1;
500 GC=location.GetSecond();
501 } else {
502 fCountUnknownZone++;
503 }
504 } else {
505 fCountUnknownIndices++;
506 }
507
508 if (!zone) {
509 cout<<"Probleme electronic of pad "<<where->PadX()<<' '<<where->PadY()
510 <<" on plane "<<where->Cathode()<<endl;
511 return 6666;
512 }
513 TList listParams;
514 TIter next(&fRulesList[where->Cathode()]);
515 AliMUONSt1ResponseRule* rule;
516 while ( (rule = static_cast<AliMUONSt1ResponseRule*>(next())))
517 if (rule->Contains(pad)) listParams.AddAll(rule->GetParameters());
518 if (fDefaultParameters[where->Cathode()][numZone])
519 listParams.Add(fDefaultParameters[where->Cathode()][numZone]);
520
521 AliMUONSt1ResponseParameter* param;
522 TIter nextParam(&listParams);
523 while ( (param = static_cast<AliMUONSt1ResponseParameter*>(nextParam()))){
524 if (param->GetState()==kFALSE) {
525 return 0;
526 }
527 }
528 nextParam.Reset();
529 while ( (param = static_cast<AliMUONSt1ResponseParameter*>(nextParam()))){
530 if (param->HasPedestal()) {
531 digit = param->ApplyPedestal(digit,GC);
532 break; // Apply pedestals just once --> break the loop once a pedestal
533// rule is applied
534 }
535 }
536 if ( digit < 0) digit=0;
537 if (digit > MaxAdc()) digit=MaxAdc();
538 nextParam.Reset();
539 while ( (param = static_cast<AliMUONSt1ResponseParameter*>(nextParam()))){
540 digit = param->ApplyStickyBits(digit);
541 }
542
543 //cout<<digit<<endl;
544 return digit;
545}
546
547
548//__________________________________________________________________________
549void AliMUONSt1Response::PrintStatistics() const
550{
551// Show the results of the statistics
552 cout<<"The DigitResponse() method was called "<<fCountNofCalls<<" times"<<endl;
553 cout<<" it was unable to find the pad corresponding to the given indices "
554 <<fCountUnknownIndices<<" times ("
555 <<(Double_t)100.*fCountUnknownIndices/fCountNofCalls
556 <<"%)"<<endl;
557 cout<<" it was unable to find the zone corresponding to the found pad "
558 <<fCountUnknownZone<<" times ("
559 <<(Double_t)100.*fCountUnknownZone/fCountNofCalls
560 <<"%)"<<endl;
561}
562
563
564
565
566
567
568