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