]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG2/FORWARD/analysis/AliFMDAnaParameters.cxx
new features and management of objects
[u/mrichter/AliRoot.git] / PWG2 / FORWARD / analysis / AliFMDAnaParameters.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 //The design of this class is based on the AliFMDParameters class. Its purpose
17 //is to hold parameters for the analysis such as background correction and 
18 //fit functions.
19 //
20 //Author: Hans Hjersing Dalsgaard, NBI, hans.dalsgaard@cern.ch
21 //
22
23 #include "AliFMDDebug.h"                   // ALILOG_H
24 #include "AliFMDAnaParameters.h"           // ALIFMDPARAMETERS_H
25 //#include <AliCDBManager.h>         // ALICDBMANAGER_H
26 //#include <AliCDBEntry.h>           // ALICDBMANAGER_H
27 //#include "AliFMDRing.h"
28 #include <AliLog.h>
29 #include <Riostream.h>
30 #include <sstream>
31 #include <TSystem.h>
32 #include <TH2D.h>
33 #include <TF1.h>
34 #include <TMath.h>
35 #include "AliESDEvent.h"
36 #include "AliESDVertex.h"
37
38 //====================================================================
39 ClassImp(AliFMDAnaParameters)
40 #if 0
41   ; // This is here to keep Emacs for indenting the next line
42 #endif
43
44 //const char* AliFMDAnaParameters::fgkBackgroundCorrection  = "FMD/Correction/Background";
45 //const char* AliFMDAnaParameters::fgkEnergyDists = "FMD/Correction/EnergyDistribution";
46 const char* AliFMDAnaParameters::fgkBackgroundID         = "background";
47 const char* AliFMDAnaParameters::fgkEnergyDistributionID = "energydistributions";
48 const char* AliFMDAnaParameters::fgkEventSelectionEffID  = "eventselectionefficiency";
49 const char* AliFMDAnaParameters::fgkSharingEffID         = "sharingefficiency";
50 //____________________________________________________________________
51 AliFMDAnaParameters* AliFMDAnaParameters::fgInstance = 0;
52
53 //____________________________________________________________________
54
55 AliFMDAnaParameters* 
56 AliFMDAnaParameters::Instance() 
57 {
58   // Get static instance 
59   if (!fgInstance) fgInstance = new AliFMDAnaParameters;
60   return fgInstance;
61 }
62
63 //____________________________________________________________________
64 AliFMDAnaParameters::AliFMDAnaParameters() :
65   fIsInit(kFALSE),
66   fBackground(0),
67   fEnergyDistribution(0),
68   fEventSelectionEfficiency(0),
69   fSharingEfficiency(0),
70   fCorner1(4.2231, 26.6638),
71   fCorner2(1.8357, 27.9500),
72   fEnergyPath("$ALICE_ROOT/PWG2/FORWARD/corrections/EnergyDistribution"),
73   fBackgroundPath("$ALICE_ROOT/PWG2/FORWARD/corrections/Background"),
74   fEventSelectionEffPath("$ALICE_ROOT/PWG2/FORWARD/corrections/EventSelectionEfficiency"),
75   fSharingEffPath("$ALICE_ROOT/PWG2/FORWARD/corrections/SharingEfficiency"),
76   fProcessPrimary(kFALSE),
77   fProcessHits(kFALSE),
78   fTrigger(kMB1),
79   fEnergy(k10000),
80   fMagField(k5G),
81   fSpecies(kPP)
82 {
83   
84   
85   //fVerticies.Add(new TVector2(4.2231, 26.6638));
86   // fVerticies.Add(new TVector2(1.8357, 27.9500));
87   // Default constructor 
88 }
89 //____________________________________________________________________
90 char* AliFMDAnaParameters::GetPath(const char* species) {
91   
92   char* path = "";
93   
94   if(species == fgkBackgroundID)
95     path = Form("%s/%s_%d_%d_%d_%d_%d_%d.root",
96                 fBackgroundPath.Data(),
97                 fgkBackgroundID,
98                 fEnergy,
99                 fTrigger,
100                 fMagField,
101                 fSpecies,
102                 0,
103                 0);
104   if(species == fgkEnergyDistributionID)
105     path = Form("%s/%s_%d_%d_%d_%d_%d_%d.root",
106                 fEnergyPath.Data(),
107                 fgkEnergyDistributionID,
108                 fEnergy,
109                 fTrigger,
110                 fMagField,
111                 fSpecies,
112                 0,
113                 0);
114   if(species == fgkEventSelectionEffID)
115     path = Form("%s/%s_%d_%d_%d_%d_%d_%d.root",
116                 fEventSelectionEffPath.Data(),
117                 fgkEventSelectionEffID,
118                 fEnergy,
119                 fTrigger,
120                 fMagField,
121                 fSpecies,
122                 0,
123                 0);
124   if(species == fgkSharingEffID)
125     path = Form("%s/%s_%d_%d_%d_%d_%d_%d.root",
126                 fSharingEffPath.Data(),
127                 fgkSharingEffID,
128                 fEnergy,
129                 fTrigger,
130                 fMagField,
131                 fSpecies,
132                 0,
133                 0);
134
135   return path;
136 }
137 //____________________________________________________________________
138 void AliFMDAnaParameters::Init(Bool_t forceReInit, UInt_t what)
139 {
140   // Initialize the parameters manager.  We need to get stuff from the
141   // CDB here. 
142   if (forceReInit) fIsInit = kFALSE;
143   if (fIsInit) return;
144   if (what & kBackgroundCorrection)       InitBackground();
145   if (what & kEnergyDistributions)        InitEnergyDists();
146   if (what & kEventSelectionEfficiency)   InitEventSelectionEff();
147   if (what & kSharingEfficiency)          InitSharingEff();
148
149   fIsInit = kTRUE;
150 }
151 //____________________________________________________________________
152
153 void AliFMDAnaParameters::InitBackground() {
154   
155   //AliCDBEntry*   background = GetEntry(fgkBackgroundCorrection);
156   
157   TFile* fin = TFile::Open(GetPath(fgkBackgroundID));
158   
159   if (!fin) return;
160   
161   fBackground = dynamic_cast<AliFMDAnaCalibBackgroundCorrection*>(fin->Get(fgkBackgroundID));
162   if (!fBackground) AliFatal("Invalid background object from CDB");
163   
164 }
165
166 //____________________________________________________________________
167
168 void AliFMDAnaParameters::InitEnergyDists() {
169   
170   TFile* fin = TFile::Open(GetPath(fgkEnergyDistributionID));
171   //AliCDBEntry*   edist = GetEntry(fgkEnergyDists);
172   if (!fin) return;
173   
174   fEnergyDistribution = dynamic_cast<AliFMDAnaCalibEnergyDistribution*>(fin->Get(fgkEnergyDistributionID));
175   
176   if (!fEnergyDistribution) AliFatal("Invalid background object from CDB");
177   
178 }
179
180 //____________________________________________________________________
181
182 void AliFMDAnaParameters::InitEventSelectionEff() {
183   
184   //AliCDBEntry*   background = GetEntry(fgkBackgroundCorrection);
185   TFile* fin = TFile::Open(GetPath(fgkEventSelectionEffID));
186                             
187   if (!fin) return;
188   
189   fEventSelectionEfficiency = dynamic_cast<AliFMDAnaCalibEventSelectionEfficiency*>(fin->Get(fgkEventSelectionEffID));
190   if (!fEventSelectionEfficiency) AliFatal("Invalid background object from CDB");
191   
192 }
193 //____________________________________________________________________
194
195 void AliFMDAnaParameters::PrintStatus() {
196   
197   TString energystring;
198   switch(fEnergy) {
199   case k900:
200     energystring.Form("900 GeV");   break;
201   case k7000:
202     energystring.Form("7000 GeV");  break;
203   case k10000:
204     energystring.Form("10000 GeV"); break;
205   case k14000:
206     energystring.Form("14000 GeV"); break;
207   default:
208     energystring.Form("invalid energy"); break;
209   }
210   TString triggerstring;
211   switch(fTrigger) {
212   case kMB1:
213     triggerstring.Form("Minimum bias 1");   break;
214   case kMB2:
215     triggerstring.Form("Minimum bias 2");   break;
216   case kSPDFASTOR:
217     triggerstring.Form("SPD FAST OR");   break;
218   case kNOCTP:
219     triggerstring.Form("NO TRIGGER TEST");   break;
220   default:
221     energystring.Form("invalid trigger"); break;
222   }
223   TString magstring;
224   switch(fMagField) {
225   case k5G:
226     magstring.Form("5 kGaus");   break;
227   case k0G:
228     magstring.Form("0 kGaus");   break;
229   default:
230     magstring.Form("invalid mag field"); break;
231   }
232   TString collsystemstring;
233   switch(fSpecies) {
234   case kPP:
235     collsystemstring.Form("p+p");   break;
236   case kPbPb:
237     collsystemstring.Form("Pb+Pb");   break;
238   default:
239     collsystemstring.Form("invalid collision system");   break;
240   }
241   
242
243   std::cout<<"Energy      = "<<energystring.Data()<<std::endl;
244   std::cout<<"Trigger     = "<<triggerstring.Data()<<std::endl;
245   std::cout<<"Mag Field   = "<<magstring.Data()<<std::endl;
246   std::cout<<"Coll System = "<<collsystemstring.Data()<<std::endl;
247   
248   
249   
250 }
251
252 //____________________________________________________________________
253
254 void AliFMDAnaParameters::InitSharingEff() {
255   
256   //AliCDBEntry*   background = GetEntry(fgkBackgroundCorrection);
257   TFile* fin = TFile::Open(GetPath(fgkSharingEffID));
258                             
259   if (!fin) return;
260   
261   fSharingEfficiency = dynamic_cast<AliFMDAnaCalibSharingEfficiency*>(fin->Get(fgkSharingEffID));
262   if (!fSharingEfficiency) AliFatal("Invalid background object from CDB");
263   
264 }
265 //____________________________________________________________________
266 Float_t AliFMDAnaParameters::GetVtxCutZ() {
267   
268   if(!fIsInit) {
269     AliWarning("Not initialized yet. Call Init() to remedy");
270     return -1;
271   }
272   
273   return fBackground->GetVtxCutZ();
274 }
275
276 //____________________________________________________________________
277 Int_t AliFMDAnaParameters::GetNvtxBins() {
278   
279   if(!fIsInit) {
280     AliWarning("Not initialized yet. Call Init() to remedy");
281     return -1;
282   }
283   
284   return fBackground->GetNvtxBins();
285 }
286 //____________________________________________________________________
287 TH1F* AliFMDAnaParameters::GetEnergyDistribution(Int_t det, Char_t ring, Float_t eta) {
288   
289   return fEnergyDistribution->GetEnergyDistribution(det, ring, eta);
290 }
291 //____________________________________________________________________
292 Float_t AliFMDAnaParameters::GetSigma(Int_t det, Char_t ring, Float_t eta) {
293   
294   if(!fIsInit) {
295     AliWarning("Not initialized yet. Call Init() to remedy");
296     return 0;
297   }
298   
299   TH1F* hEnergyDist       = GetEnergyDistribution(det,ring, eta);
300   TF1*  fitFunc           = hEnergyDist->GetFunction("FMDfitFunc");
301   if(!fitFunc) {
302     AliWarning(Form("No function for FMD%d%c, eta %f",det,ring,eta));
303     return 1024;
304   }
305   Float_t sigma           = fitFunc->GetParameter(2);
306   return sigma;
307 }
308
309
310 //____________________________________________________________________
311 Float_t AliFMDAnaParameters::GetMPV(Int_t det, Char_t ring, Float_t eta) {
312   
313   if(!fIsInit) {
314     AliWarning("Not initialized yet. Call Init() to remedy");
315     return 0;
316   }
317   
318   TH1F* hEnergyDist     = GetEnergyDistribution(det,ring,eta);
319   TF1*  fitFunc         = hEnergyDist->GetFunction("FMDfitFunc");
320   if(!fitFunc) {
321     AliWarning(Form("No function for FMD%d%c, eta %f",det,ring,eta));
322     return 1024;
323   }
324     
325   Float_t mpv           = fitFunc->GetParameter(1);
326   return mpv;
327 }
328 //____________________________________________________________________
329 Float_t AliFMDAnaParameters::Get2MIPWeight(Int_t det, Char_t ring, Float_t eta) {
330   
331   if(!fIsInit) {
332     AliWarning("Not initialized yet. Call Init() to remedy");
333     return 0;
334   }
335   
336   TH1F* hEnergyDist     = GetEnergyDistribution(det,ring,eta);
337   TF1*  fitFunc         = hEnergyDist->GetFunction("FMDfitFunc");
338   if(!fitFunc) return 0;
339   Float_t twoMIPweight    = fitFunc->GetParameter(3);
340   
341   
342   
343   if(twoMIPweight < 1e-05)
344     twoMIPweight = 0;
345   
346   return twoMIPweight;
347 }
348 //____________________________________________________________________
349 Float_t AliFMDAnaParameters::Get3MIPWeight(Int_t det, Char_t ring, Float_t eta) {
350   
351   if(!fIsInit) {
352     AliWarning("Not initialized yet. Call Init() to remedy");
353     return 0;
354   }
355   
356   TH1F* hEnergyDist     = GetEnergyDistribution(det,ring,eta);
357   TF1*  fitFunc         = hEnergyDist->GetFunction("FMDfitFunc");
358   if(!fitFunc) return 0;
359   Float_t threeMIPweight    = fitFunc->GetParameter(4);
360   
361   if(threeMIPweight < 1e-05)
362     threeMIPweight = 0;
363   
364   Float_t twoMIPweight    = fitFunc->GetParameter(3);
365   
366   if(twoMIPweight < 1e-05)
367     threeMIPweight = 0;
368     
369   return threeMIPweight;
370 }
371 //____________________________________________________________________
372 Int_t AliFMDAnaParameters::GetNetaBins() {
373   return GetBackgroundCorrection(1,'I',0)->GetNbinsX();
374   
375 }
376 //____________________________________________________________________
377 Float_t AliFMDAnaParameters::GetEtaMin() {
378
379   return GetBackgroundCorrection(1,'I',0)->GetXaxis()->GetXmin();
380
381 //____________________________________________________________________
382 Float_t AliFMDAnaParameters::GetEtaMax() {
383
384 return GetBackgroundCorrection(1,'I',0)->GetXaxis()->GetXmax();
385
386 }
387 //____________________________________________________________________
388
389 TH2F* AliFMDAnaParameters::GetBackgroundCorrection(Int_t det, 
390                                                    Char_t ring, 
391                                                    Int_t vtxbin) {
392   
393   if(!fIsInit) {
394     AliWarning("Not initialized yet. Call Init() to remedy");
395     return 0;
396   }
397   
398   
399   
400   if(vtxbin > fBackground->GetNvtxBins()) {
401     AliWarning(Form("No background object for vertex bin %d", vtxbin));
402     return 0;
403   } 
404   
405   return fBackground->GetBgCorrection(det,ring,vtxbin);
406 }
407 //____________________________________________________________________
408
409 TH1F* AliFMDAnaParameters::GetDoubleHitCorrection(Int_t det, 
410                                                   Char_t ring) {
411   
412   if(!fIsInit) {
413     AliWarning("Not initialized yet. Call Init() to remedy");
414     return 0;
415   }
416   
417   return fBackground->GetDoubleHitCorrection(det,ring);
418 }
419 //_____________________________________________________________________
420 Float_t AliFMDAnaParameters::GetEventSelectionEfficiency(Int_t vtxbin) {
421   if(!fIsInit) {
422     AliWarning("Not initialized yet. Call Init() to remedy");
423     return 0;
424   }
425   return fEventSelectionEfficiency->GetCorrection(vtxbin);
426
427 }
428 //_____________________________________________________________________
429 TH1F* AliFMDAnaParameters::GetSharingEfficiency(Int_t det, Char_t ring, Int_t vtxbin) {
430   if(!fIsInit) {
431     AliWarning("Not initialized yet. Call Init() to remedy");
432     return 0;
433   }
434   
435   return fSharingEfficiency->GetSharingEff(det,ring,vtxbin);
436
437 }
438 //_____________________________________________________________________
439 TH1F* AliFMDAnaParameters::GetSharingEfficiencyTrVtx(Int_t det, Char_t ring, Int_t vtxbin) {
440   if(!fIsInit) {
441     AliWarning("Not initialized yet. Call Init() to remedy");
442     return 0;
443   }
444   
445   return fSharingEfficiency->GetSharingEffTrVtx(det,ring,vtxbin);
446
447 }
448 //_____________________________________________________________________
449 Float_t AliFMDAnaParameters::GetMaxR(Char_t ring) const{
450   Float_t radius = 0;
451   if(ring == 'I')
452     radius = 17.2;
453   else if(ring == 'O')
454     radius = 28.0;
455   else
456     AliWarning("Unknown ring - must be I or O!");
457   
458   return radius;
459 }
460 //_____________________________________________________________________
461 Float_t AliFMDAnaParameters::GetMinR(Char_t ring) const{
462   Float_t radius = 0;
463   if(ring == 'I')
464     radius = 4.5213;
465   else if(ring == 'O')
466     radius = 15.4;
467   else
468     AliWarning("Unknown ring - must be I or O!");
469   
470   return radius;
471
472 }
473 //_____________________________________________________________________
474 void AliFMDAnaParameters::SetCorners(Char_t ring) {
475   
476   if(ring == 'I') {
477     fCorner1.Set(4.9895, 15.3560);
478     fCorner2.Set(1.8007, 17.2000);
479   }
480   else {
481     fCorner1.Set(4.2231, 26.6638);
482     fCorner2.Set(1.8357, 27.9500);
483   }
484   
485 }
486 //_____________________________________________________________________
487 Float_t AliFMDAnaParameters::GetPhiFromSector(UShort_t det, Char_t ring, UShort_t sec) const
488 {
489   Int_t nsec = (ring == 'I' ? 20 : 40);
490   Float_t basephi = 0;
491   if(det == 1) 
492     basephi = 1.72787594; 
493   if(det == 2 && ring == 'I')
494     basephi = 0.15707963;
495   if(det == 2 && ring == 'O')
496     basephi = 0.078539818;
497   if(det == 3 && ring == 'I')
498     basephi = 2.984513044;
499   if(det == 3 && ring == 'O')
500     basephi = 3.06305289;
501   
502   Float_t step = 2*TMath::Pi() / nsec;
503   Float_t phi = 0;
504   if(det == 3)
505     phi = basephi - sec*step;
506   else
507     phi = basephi + sec*step;
508   
509   if(phi < 0) 
510     phi = phi +2*TMath::Pi();
511   if(phi > 2*TMath::Pi() )
512     phi = phi - 2*TMath::Pi();
513   
514   return phi;
515 }
516 //_____________________________________________________________________
517 Float_t AliFMDAnaParameters::GetEtaFromStrip(UShort_t det, Char_t ring, UShort_t sec, UShort_t strip, Float_t zvtx) const
518 {
519   // AliFMDRing fmdring(ring);
520   // fmdring.Init();
521   Float_t   rad       = GetMaxR(ring)-GetMinR(ring);
522   Float_t   nStrips   = (ring == 'I' ? 512 : 256);
523   Float_t   segment   = rad / nStrips;
524   Float_t   r         = GetMinR(ring) + segment*strip;
525   Float_t   z         = 0;
526   Int_t hybrid = sec / 2;
527   
528   if(det == 1) {
529     if(!(hybrid%2)) z = 320.266; else z = 319.766;
530   }
531   if(det == 2 && ring == 'I' ) {
532     if(!(hybrid%2)) z = 83.666; else z = 83.166;
533   }
534   if(det == 2 && ring == 'O' ) {
535     if(!(hybrid%2)) z = 74.966; else z = 75.466;
536   }
537   if(det == 3 && ring == 'I' ) {
538     if(!(hybrid%2)) z = -63.066; else z = -62.566;
539   }
540   if(det == 3 && ring == 'O' ) {
541     if(!(hybrid%2)) z = -74.966; else z = -75.466;
542   }
543   
544   //std::cout<<det<<"   "<<ring<<"   "<<sec<<"   "<<hybrid<<"    "<<z<<std::endl;
545   
546   // Float_t   r     = TMath::Sqrt(TMath::Power(x,2)+TMath::Power(y,2));
547   Float_t   theta = TMath::ATan2(r,z-zvtx);
548   Float_t   eta   = -1*TMath::Log(TMath::Tan(0.5*theta));
549   
550   return eta;
551 }
552
553 //_____________________________________________________________________
554
555 void AliFMDAnaParameters::GetVertex(AliESDEvent* esd, Double_t* vertexXYZ) 
556 {
557   const AliESDVertex* vertex = 0;
558   vertex = esd->GetPrimaryVertex();
559   if(!vertex || (vertex->GetXv() < 0.0001 && vertex->GetYv() < 0.0001 && vertex->GetZv() < 0.0001))        
560     vertex = esd->GetPrimaryVertexSPD();
561   if(!vertex || (vertex->GetXv() < 0.0001 && vertex->GetYv() < 0.0001 && vertex->GetZv() < 0.0001))        
562     vertex = esd->GetPrimaryVertexTPC();
563   if(!vertex || (vertex->GetXv() < 0.0001 && vertex->GetYv() < 0.0001 && vertex->GetZv() < 0.0001))    
564     vertex = esd->GetVertex();
565   if (vertex && (vertex->GetXv() > 0.0001 || vertex->GetYv() > 0.0001 || vertex->GetZv() > 0.0010)) {
566     vertex->GetXYZ(vertexXYZ);
567     return;
568   }
569   else { //no valid vertex
570     vertexXYZ[0] = 0;
571     vertexXYZ[1] = 0;
572     vertexXYZ[2] = 0;
573     
574     return;
575   }
576   
577   return;
578   
579 }
580
581 //____________________________________________________________________
582 Bool_t AliFMDAnaParameters::IsEventTriggered(AliESDEvent *esd) const {
583   // check if the event was triggered
584   ULong64_t triggerMask = esd->GetTriggerMask();
585   
586   // definitions from p-p.cfg
587   ULong64_t spdFO = (1 << 14);
588   ULong64_t v0left = (1 << 11);
589   ULong64_t v0right = (1 << 12);
590   
591   switch (fTrigger) {
592   case kMB1: {
593     if (triggerMask & spdFO || ((triggerMask & v0left) || (triggerMask & v0right)))
594       return kTRUE;
595     break;
596   }
597   case kMB2: {
598     if (triggerMask & spdFO && ((triggerMask & v0left) || (triggerMask & v0right)))
599       return kTRUE;
600     break;
601   }
602   case kSPDFASTOR: {
603     if (triggerMask & spdFO)
604       return kTRUE;
605     break;
606   }
607   case kNOCTP: {
608     return kTRUE;
609     break;
610   }
611   }//switch
612
613   return kFALSE;
614 }
615
616 //____________________________________________________________________
617 Float_t 
618 AliFMDAnaParameters::GetStripLength(Char_t ring, UShort_t strip)  
619 {
620   //AliFMDRing fmdring(ring);
621   // fmdring.Init();
622   
623   Float_t rad        = GetMaxR(ring)-GetMinR(ring);
624   Float_t   nStrips   = (ring == 'I' ? 512 : 256);
625   Float_t segment    = rad / nStrips;
626   
627   //TVector2* corner1  = fmdring.GetVertex(2);  
628   // TVector2* corner2  = fmdring.GetVertex(3);
629   
630   SetCorners(ring);
631   /*
632   std::cout<<GetMaxR(ring)<<"   "<<fmdring.GetMaxR()<<std::endl;
633   std::cout<<GetMinR(ring)<<"   "<<fmdring.GetMinR()<<std::endl;
634   std::cout<<corner1->X()<<"   "<<fCorner1.X()<<std::endl;
635   std::cout<<corner2->X()<<"   "<<fCorner2.X()<<std::endl;
636   std::cout<<corner1->Y()<<"   "<<fCorner1.Y()<<std::endl;
637   std::cout<<corner2->Y()<<"   "<<fCorner2.Y()<<std::endl;*/
638   Float_t slope      = (fCorner1.Y() - fCorner2.Y()) / (fCorner1.X() - fCorner2.X());
639   Float_t constant   = (fCorner2.Y()*fCorner1.X()-(fCorner2.X()*fCorner1.Y())) / (fCorner1.X() - fCorner2.X());
640   Float_t radius     = GetMinR(ring) + strip*segment;
641   
642   Float_t d          = TMath::Power(TMath::Abs(radius*slope),2) + TMath::Power(radius,2) - TMath::Power(constant,2);
643   
644   Float_t arclength  = GetBaseStripLength(ring,strip);
645   if(d>0) {
646     
647     Float_t x        = (-1*TMath::Sqrt(d) -slope*constant) / (1+TMath::Power(slope,2));
648     Float_t y        = slope*x + constant;
649     Float_t theta    = TMath::ATan2(x,y);
650     
651     if(x < fCorner1.X() && y > fCorner1.Y()) {
652       arclength = radius*theta;                        //One sector since theta is by definition half-hybrid
653       
654     }
655     
656   }
657   
658   return arclength;
659   
660   
661 }
662 //____________________________________________________________________
663 Float_t 
664 AliFMDAnaParameters::GetBaseStripLength(Char_t ring, UShort_t strip)  
665 {  
666   // AliFMDRing fmdring(ring);
667   // fmdring.Init();
668   Float_t rad             = GetMaxR(ring)-GetMinR(ring);
669   Float_t nStrips         = (ring == 'I' ? 512 : 256);
670   Float_t nSec            = (ring == 'I' ? 20 : 40);
671   Float_t segment         = rad / nStrips;
672   Float_t basearc         = 2*TMath::Pi() / (0.5*nSec); // One hybrid: 36 degrees inner, 18 outer
673   Float_t radius          = GetMinR(ring) + strip*segment;
674   Float_t basearclength   = 0.5*basearc * radius;                // One sector   
675   
676   return basearclength;
677 }
678 //____________________________________________________________________
679 //
680 // EOF
681 //