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