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