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