--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+//_________________________________________________________________________
+// This is a TTask that made the calculation of the Time zero using TOF.
+// Description: The algorithm used to calculate the time zero of interaction
+// using TOF detector is the following.
+// We select in the MonteCarlo some primary particles - or tracks in the following -
+// that strike the TOF detector (the larger part are pions, kaons or protons).
+// We choose a set of 10 selected tracks, for each track You have the length
+// of the track when the TOF is reached (a standard TOF hit does not contain this
+// additional information, this is the reason why we implemented a new time zero
+// dedicated TOF hit class AliTOFhitT0; in order to store this type of hit You
+// have to use the AliTOFv4T0 as TOF class in Your Config.C. In AliTOFv4T0 the
+// StepManager was modified in order to fill the TOF hit branch with this type
+// of hits; in fact the AliTOF::AddT0Hit is called rather that the usual AliTOF::AddHit),
+// the momentum at generation (from TreeK) and the time of flight
+// given by the TOF detector.
+// (Observe that the ctor of the AliTOF class, when the AliTOFv4T0 class is used, is called
+// with the "tzero" option: it is in order create the fHits TClonesArray filled with
+// AliTOFhitT0 objects, rather than with normal AliTOFhit)
+// Then Momentum and time of flight for each track are smeared according to
+// known experimental resolution (all sources of error have been token into account).
+// Let consider now only one set of 10 tracks (the algorithm is the same for all sets).
+// Assuming the (mass) hypothesis that each track can be AUT a pion, AUT a kaon, AUT a proton,
+// we consider all the 3 at 10 possible cases.
+// For each track in each (mass) configuration
+// (a configuration can be e.g. pion/pion/kaon/proton/pion/proton/kaon/kaon/pion/pion)
+// we calculate the time zero (we know in fact the velocity of the track after
+// the assumption about its mass, the time of flight given by the TOF, and the
+// corresponding path travelled till the TOF detector). Then for each mass configuration we have
+// 10 time zero and we can calculate the ChiSquare for the current configuration using the
+// weighted mean over all 10 time zero.
+// We call the best assignment the mass configuration that gives the minimum value of the ChiSquare.
+// We plot the weighted mean over all 10 time zero for the best assignment,
+// the ChiSquare for the best assignment and the corresponding confidence level.
+// The strong assumption is the MC selection of primary particles. It will be introduced
+// in the future also some more realistic simulation about this point.
+// Use case:
+// root [0] AliTOFT0 * tzero = new AliTOFT0("galice.root")
+// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
+// root [1] tzero->ExecuteTask()
+// root [2] tzero->ExecuteTask("tim")
+// // available parameters:
+// tim - print benchmarking information
+// all - print usefull informations about the number of misidentified tracks
+// and a comparison about the true configuration (known from MC) and the best
+// assignment
+//-- Author: F. Pierella
+//////////////////////////////////////////////////////////////////////////////
+
+#include "AliTOFT0.h"
+#include "AliTOFhitT0.h"
+#include "AliTOF.h"
+#include "AliTOFv4T0.h"
+#include "AliRun.h"
+#include "AliDetector.h"
+#include "AliMC.h"
+
+#include "TH1.h"
+#include "TFile.h"
+#include "TTask.h"
+#include "TTree.h"
+#include "TSystem.h"
+#include "TCanvas.h"
+#include "TFrame.h"
+#include "TROOT.h"
+#include "TFolder.h"
+#include "TBenchmark.h"
+#include "TParticle.h"
+#include "TClonesArray.h"
+#include <stdlib.h>
+#include <iostream.h>
+#include <fstream.h>
+#include <iomanip.h>
+
+ClassImp(AliTOFT0)
+
+//____________________________________________________________________________
+ AliTOFT0::AliTOFT0():TTask("AliTOFT0","")
+{
+ // ctor
+ fNevents = 0 ;
+ fHits = 0 ;
+
+}
+
+//____________________________________________________________________________
+ AliTOFT0::AliTOFT0(char* headerFile, Int_t nEvents):TTask("AliTOFT0","")
+{
+ fNevents=nEvents ; // Number of events for which calculate the T0,
+ // default 0: it means all evens in current file
+ fLowerMomBound=1.5; // [GeV/c] default value
+ fUpperMomBound=2. ; // [GeV/c] default value
+ fTimeResolution = 1.2e-10; // 120 ps by default
+ fHeadersFile = headerFile ;
+ fHits = 0 ;
+
+ TFile * file = (TFile*) gROOT->GetFile(fHeadersFile.Data() ) ;
+
+ //File was not opened yet
+ if(file == 0){
+ if(fHeadersFile.Contains("rfio"))
+ file = TFile::Open(fHeadersFile,"update") ;
+ else
+ file = new TFile(fHeadersFile.Data(),"update") ;
+ gAlice = (AliRun *) file->Get("gAlice") ;
+ }
+
+ // add Task to //root/Tasks folder
+ TTask * roottasks = (TTask*)gROOT->GetRootFolder()->FindObject("Tasks") ;
+ roottasks->Add(this) ;
+}
+
+//____________________________________________________________________________
+ AliTOFT0::~AliTOFT0()
+{
+ // dtor
+}
+
+//____________________________________________________________________________
+void AliTOFT0::Exec(Option_t *option)
+{
+ //
+ // calculate T0 distribution for all events using chisquare
+ //
+ Int_t ngood=0;
+ Int_t nmisidentified=0;
+ Int_t nmisidentified0=0;
+ Int_t nmisidentified1=0;
+ Int_t nmisidentified2=0;
+ Int_t nmisidentified3=0;
+ Int_t nmisidentified4=0;
+ Int_t nmisidentified5=0;
+ Int_t nmisidentified6=0;
+ Int_t nmisidentified7=0;
+ Int_t nmisidentified8=0;
+ Int_t nmisidentified9=0;
+ Int_t ipartold = -1;
+ Int_t ipart;
+ Int_t selected=0;
+ Int_t istop=0;
+ Float_t timeresolutioninns=fTimeResolution*(1.e+9); // convert in [ns]
+ const Int_t kUPDATE = 5; // for visual option
+ Int_t itimes=0;
+ TCanvas* c1=0;
+ TCanvas* c2=0;
+ TCanvas* c3=0;
+
+ if(strstr(option,"visual")){
+ // Create a new canvas.
+ //c1 = new TCanvas("c1","Dynamic Visual Filling of time zero histo",10,10,500,500);
+ c1 = new TCanvas("c1","Dynamic Visual Filling of time zero histo",10,10,370,370);
+ c1->SetFillColor(35);
+ c1->GetFrame()->SetFillColor(21);
+ c1->GetFrame()->SetBorderSize(6);
+ c1->GetFrame()->SetBorderMode(-1);
+
+ //c2 = new TCanvas("c2","Dynamic Visual Filling of chisquare histo",550,10,500,500);
+ c2 = new TCanvas("c2","Dynamic Visual Filling of chisquare histo",380,10,370,370);
+ c2->SetFillColor(35);
+ c2->GetFrame()->SetFillColor(21);
+ c2->GetFrame()->SetBorderSize(6);
+ c2->GetFrame()->SetBorderMode(-1);
+
+ //c3 = new TCanvas("c3","Dynamic Visual Filling of confidence level histo",280,550,500,500);
+ c3 = new TCanvas("c3","Dynamic Visual Filling of confidence level histo",760,10,370,370);
+ c3->SetFillColor(35);
+ c3->GetFrame()->SetFillColor(21);
+ c3->GetFrame()->SetBorderSize(6);
+ c3->GetFrame()->SetBorderMode(-1);
+ }
+
+ if(strstr(option,"tim") || strstr(option,"all"))
+ gBenchmark->Start("TOFT0");
+
+ TH1F *htzerobest= new TH1F("htzerobest","T0 for best assignment",200,-1.,1.);
+ TH1F* hchibest = new TH1F("hchibest","ChiSquare Min Distribution",80,0.,40.);
+ TH1F* hchibestconflevel = new TH1F("hchibestconflevel","ChiSquare Min Confidence Level",10,0.,1.);
+
+ // setting histo colors
+ if(strstr(option,"visual")){
+ htzerobest->SetFillColor(48);
+ hchibest->SetFillColor(50);
+ hchibestconflevel->SetFillColor(52);
+ }
+
+ Int_t assparticle[10]={3,3,3,3,3,3,3,3,3,3};
+ Int_t truparticle[10]={3,3,3,3,3,3,3,3,3,3};
+ Float_t t0best=999.;
+ Float_t timeofflight[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
+ Float_t momentum[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
+ Float_t timezero[10];
+ Float_t weightedtimezero[10];
+ Float_t beta[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
+ Float_t sqMomError[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
+ Float_t sqTrackError[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
+ Float_t massarray[3]={0.13957,0.493677,0.9382723};
+ Float_t dummychisquare=0.;
+ Float_t chisquare=999.;
+ Float_t tracktoflen[10]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
+
+ AliTOF *TOF = (AliTOF *) gAlice->GetDetector ("TOF");
+
+ if (!TOF) {
+ Error("AliTOFT0","TOF not found");
+ return;
+ }
+
+ if(strstr(option,"all")){
+ cout << "Selecting primary tracks with momentum between " << fLowerMomBound << " GeV/c and " << fUpperMomBound << " GeV/c" << endl;
+ cout << "Memorandum: 0 means PION | 1 means KAON | 2 means PROTON" << endl;
+ }
+
+ if (fNevents == 0) fNevents = (Int_t) gAlice->TreeE()->GetEntries();
+
+ for (Int_t ievent = 0; ievent < fNevents; ievent++) {
+ gAlice->GetEvent(ievent);
+ TTree *TH = gAlice->TreeH ();
+ if (!TH)
+ return;
+ TParticle* particle;
+ AliTOFhitT0* tofHit;
+ TClonesArray* TOFhits = TOF->Hits();
+
+ Int_t lasttrack=-1;
+ Int_t nset=0;
+ // Start loop on primary tracks in the hits containers
+
+ Int_t ntracks = static_cast<Int_t>(TH->GetEntries());
+ for (Int_t track = 0; track < ntracks; track++)
+ {
+ if(nset>=5) break; // check on the number of set analyzed
+
+ gAlice->ResetHits();
+ TH->GetEvent(track);
+ particle = gAlice->Particle(track);
+ Int_t nhits = TOFhits->GetEntriesFast();
+
+ for (Int_t hit = 0; hit < nhits; hit++)
+ {
+ tofHit = (AliTOFhitT0 *) TOFhits->UncheckedAt(hit);
+ ipart = tofHit->GetTrack();
+ // check to discard the case when the same particle is selected more than one
+ // time
+
+ if (ipart != ipartold){
+
+ particle = (TParticle*)gAlice->Particle(ipart);
+
+ Float_t idealtime=tofHit->GetTof();
+ // Float_t time=idealtime;
+ Float_t time = gRandom->Gaus(idealtime, fTimeResolution);
+ Float_t toflen=tofHit->GetLen();
+ toflen=toflen/100.; // toflen given in m
+ Int_t pdg = particle->GetPdgCode();
+ Int_t abspdg =TMath::Abs(pdg);
+ Float_t idealmom = particle->P();
+ Float_t momres=idealmom*0.025; // 2.5% res token into account for all momenta
+ Float_t mom =gRandom->Gaus(idealmom,momres);
+
+ Bool_t isgoodpart=(abspdg==211 || abspdg==2212 || abspdg==321);
+
+ time*=1.E+9; // tof given in nanoseconds
+ if (particle->GetFirstMother() < 0 && isgoodpart && mom<=fUpperMomBound && mom>=fLowerMomBound){
+ selected+=1;
+ istop=selected;
+ if(istop>10) break;
+ Int_t index=selected-1;
+ timeofflight[index]=time;
+ tracktoflen[index]=toflen;
+ momentum[index]=mom;
+ // cout << timeofflight[index] << " " << tracktoflen[index] << " " << momentum[index] << endl;
+ switch (abspdg) {
+ case 211:
+ truparticle[index]=0;
+ break ;
+ case 321:
+ truparticle[index]=1;
+ break ;
+ case 2212:
+ truparticle[index]=2;
+ break ;
+ }
+
+ }
+ ipartold = ipart;
+
+ if(istop==10){ // start analysis on current set
+ nset+=1;
+ lasttrack=track;
+ istop=0;
+ selected=0;
+ //cout << "starting t0 calculation for current set" << endl;
+ for (Int_t i1=0; i1<3;i1++) {
+ for (Int_t i2=0; i2<3;i2++) {
+ for (Int_t i3=0; i3<3;i3++) {
+ for (Int_t i4=0; i4<3;i4++) {
+ for (Int_t i5=0; i5<3;i5++) {
+ for (Int_t i6=0; i6<3;i6++) {
+ for (Int_t i7=0; i7<3;i7++) {
+ for (Int_t i8=0; i8<3;i8++) {
+ for (Int_t i9=0; i9<3;i9++) {
+ for (Int_t i10=0; i10<3;i10++) {
+
+ beta[0]=momentum[0]/sqrt(massarray[i1]*massarray[i1]+momentum[0]*momentum[0]);
+ beta[1]=momentum[1]/sqrt(massarray[i2]*massarray[i2]+momentum[1]*momentum[1]);
+ beta[2]=momentum[2]/sqrt(massarray[i3]*massarray[i3]+momentum[2]*momentum[2]);
+ beta[3]=momentum[3]/sqrt(massarray[i4]*massarray[i4]+momentum[3]*momentum[3]);
+ beta[4]=momentum[4]/sqrt(massarray[i5]*massarray[i5]+momentum[4]*momentum[4]);
+ beta[5]=momentum[5]/sqrt(massarray[i6]*massarray[i6]+momentum[5]*momentum[5]);
+ beta[6]=momentum[6]/sqrt(massarray[i7]*massarray[i7]+momentum[6]*momentum[6]);
+ beta[7]=momentum[7]/sqrt(massarray[i8]*massarray[i8]+momentum[7]*momentum[7]);
+ beta[8]=momentum[8]/sqrt(massarray[i9]*massarray[i9]+momentum[8]*momentum[8]);
+ beta[9]=momentum[9]/sqrt(massarray[i10]*massarray[i10]+momentum[9]*momentum[9]);
+
+
+ Float_t meantzero=0.;
+ Float_t sumAllweights=0.;
+ for (Int_t itz=0; itz<10;itz++) {
+ sqMomError[itz]=((1.-beta[itz]*beta[itz])*0.025)*((1.-beta[itz]*beta[itz])*0.025)*(tracktoflen[itz]/(0.299792*beta[itz]))*(tracktoflen[itz]/(0.299792*beta[itz])); // this gives the square of the momentum error in nanoseconds
+ sqTrackError[itz]=(timeresolutioninns*timeresolutioninns+sqMomError[itz]); // total error for the current track
+ sumAllweights+=1./sqTrackError[itz];
+ // redefining beta, it is useful in order to calculate t zero
+ beta[itz]*=0.299792;
+ timezero[itz]=(tracktoflen[itz]/beta[itz])-timeofflight[itz];
+ weightedtimezero[itz]=((tracktoflen[itz]/beta[itz])-timeofflight[itz])/sqTrackError[itz];// weighted time zero for current track
+ meantzero+=weightedtimezero[itz];
+ } // end loop for (Int_t itz=0; itz<10;itz++)
+ meantzero=meantzero/sumAllweights; // it is given in [ns]
+
+ dummychisquare=0.;
+ // calculate the chisquare for the current assignment
+ for (Int_t icsq=0; icsq<10;icsq++) {
+ dummychisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
+ } // end loop for (Int_t icsq=0; icsq<10;icsq++)
+
+ if(dummychisquare<=chisquare){
+ assparticle[0]=i1;
+ assparticle[1]=i2;
+ assparticle[2]=i3;
+ assparticle[3]=i4;
+ assparticle[4]=i5;
+ assparticle[5]=i6;
+ assparticle[6]=i7;
+ assparticle[7]=i8;
+ assparticle[8]=i9;
+ assparticle[9]=i10;
+ chisquare=dummychisquare;
+ t0best=meantzero;
+ } // close if(dummychisquare<=chisquare)
+
+ } // end loop on i10
+ } // end loop on i9
+ } // end loop on i8
+ } // end loop on i7
+ } // end loop on i6
+ } // end loop on i5
+ } // end loop on i4
+ } // end loop on i3
+ } // end loop on i2
+ } // end loop on i1
+
+ if(truparticle[0]==assparticle[0] && truparticle[1]==assparticle[1] && truparticle[2]==assparticle[2] && truparticle[3]==assparticle[3] && truparticle[4]==assparticle[4]&& truparticle[5]==assparticle[5] && truparticle[6]==assparticle[6] && truparticle[7]==assparticle[7] && truparticle[8]==assparticle[8] && truparticle[9]==assparticle[9]) ngood+=1;
+ if(truparticle[0]!=assparticle[0]) nmisidentified0+=1;
+ if(truparticle[1]!=assparticle[1]) nmisidentified1+=1;
+ if(truparticle[2]!=assparticle[2]) nmisidentified2+=1;
+ if(truparticle[3]!=assparticle[3]) nmisidentified3+=1;
+ if(truparticle[4]!=assparticle[4]) nmisidentified4+=1;
+ if(truparticle[5]!=assparticle[5]) nmisidentified5+=1;
+ if(truparticle[6]!=assparticle[6]) nmisidentified6+=1;
+ if(truparticle[7]!=assparticle[7]) nmisidentified7+=1;
+ if(truparticle[8]!=assparticle[8]) nmisidentified8+=1;
+ if(truparticle[9]!=assparticle[9]) nmisidentified9+=1;
+ // filling histos
+ htzerobest->Fill(t0best);
+ hchibest->Fill(chisquare);
+ Double_t dblechisquare=(Double_t)chisquare;
+ Float_t confLevel=(Float_t)TMath::Prob(dblechisquare,9); // ndf 10-1=9
+ hchibestconflevel->Fill(confLevel);
+ itimes++;
+ if(strstr(option,"all")){
+ cout << "True Assignment " << truparticle[0] << truparticle[1] << truparticle[2] << truparticle[3] << truparticle[4] << truparticle[5] << truparticle[6] << truparticle[7] << truparticle[8] << truparticle[9] <<endl;
+ cout << "Best Assignment " << assparticle[0] << assparticle[1] << assparticle[2] << assparticle[3] << assparticle[4] << assparticle[5] << assparticle[6] << assparticle[7] << assparticle[8] << assparticle[9] << endl;
+ cout << "Minimum ChiSquare for current set " << chisquare << endl;
+ cout << "Confidence Level (Minimum ChiSquare) " << confLevel << endl;
+ }
+ if (strstr(option,"visual") && itimes && (itimes%kUPDATE) == 0) {
+ if (itimes == kUPDATE){
+ c1->cd();
+ htzerobest->Draw();
+ c2->cd();
+ hchibest->Draw();
+ c3->cd();
+ hchibestconflevel->Draw();
+ }
+ c1->Modified();
+ c1->Update();
+ c2->Modified();
+ c2->Update();
+ c3->Modified();
+ c3->Update();
+ if (gSystem->ProcessEvents())
+ break;
+ }
+ chisquare=999.;
+ t0best=999.;
+
+ } // end for the current set. close if(istop==5)
+ } // end condition on ipartold
+ } // end loop on hits for the current track
+ if(istop>=10) break;
+ } // end loop on ntracks
+ } //event loop
+
+ if(strstr(option,"all")){
+ nmisidentified=(nmisidentified0+nmisidentified1+nmisidentified2+nmisidentified3+nmisidentified4+nmisidentified5+nmisidentified6+nmisidentified7+nmisidentified8+nmisidentified9);
+ cout << "total number of tracks token into account " << 10*5*fNevents << endl;
+ Float_t badPercentage=100.*(Float_t)nmisidentified/(10*5*fNevents);
+ cout << "total misidentified " << nmisidentified << "("<< badPercentage << "%)" <<endl;
+ cout << "Total Number of set token into account " << 5*fNevents << endl;
+ Float_t goodSetPercentage=100.*(Float_t)ngood/(5*fNevents);
+ cout << "Number of set with no misidentified tracks " << ngood << "("<< goodSetPercentage << "%)" <<endl;
+ }
+
+ // free used memory for canvas
+ delete c1; c1=0;
+ delete c2; c2=0;
+ delete c3; c3=0;
+
+ // generating output filename only if not previously specified using SetTZeroFile
+ char outFileName[70];
+ strcpy(outFileName,"ht010tr120ps"); // global time resolution has to be converted from Int_t to char
+ // in order to have in the output filename this parameter
+ strcat(outFileName,fHeadersFile);
+
+ if(fT0File.IsNull()) fT0File=outFileName;
+
+ TFile* houtfile = new TFile(fT0File,"recreate");
+ houtfile->cd();
+ htzerobest->Write(0,TObject::kOverwrite);
+ hchibest->Write(0,TObject::kOverwrite);
+ hchibestconflevel->Write(0,TObject::kOverwrite);
+ houtfile->Close();
+
+
+ if(strstr(option,"tim") || strstr(option,"all")){
+ gBenchmark->Stop("TOFT0");
+ cout << "AliTOFT0:" << endl ;
+ cout << " took " << gBenchmark->GetCpuTime("TOFT0") << " seconds in order to calculate T0 "
+ << gBenchmark->GetCpuTime("TOFT0")/fNevents << " seconds per event " << endl ;
+ cout << endl ;
+ }
+}
+
+//__________________________________________________________________
+void AliTOFT0::SetTZeroFile(char * file ){
+ cout << "Destination file : " << file << endl ;
+ fT0File=file;
+}
+//__________________________________________________________________
+void AliTOFT0::Print(Option_t* option)const
+{
+ cout << "------------------- "<< GetName() << " -------------" << endl ;
+ if(!fT0File.IsNull())
+ cout << " Writing T0 Distribution to file " << (char*) fT0File.Data() << endl ;
+}
+
+//__________________________________________________________________
+Bool_t AliTOFT0::operator==( AliTOFT0 const &tzero )const
+{
+ // Equal operator.
+ //
+
+ if( (fTimeResolution==tzero.fTimeResolution)&&(fLowerMomBound==tzero.fLowerMomBound)&&(fUpperMomBound==tzero.fUpperMomBound))
+ return kTRUE ;
+ else
+ return kFALSE ;
+}
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Time Of Flight: design of C.Williams
+//
+// This class contains the functions for version 4 of the Time Of Flight //
+// detector. //
+//
+// VERSION WITH 5 MODULES AND TILTED STRIPS
+//
+// FULL COVERAGE VERSION
+//
+// Author:
+// Fabrizio Pierella
+// University of Bologna - Italy
+//
+//
+//Begin_Html
+/*
+<img src="picts/AliTOFv4T0Class.gif">
+*/
+//End_Html
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+#include <iostream.h>
+#include <stdlib.h>
+
+#include "AliTOFv4T0.h"
+#include "TBRIK.h"
+#include "TGeometry.h"
+#include "TNode.h"
+#include <TLorentzVector.h>
+#include "TObject.h"
+#include "AliRun.h"
+#include "AliMC.h"
+#include "AliConst.h"
+
+
+ClassImp(AliTOFv4T0)
+
+//_____________________________________________________________________________
+AliTOFv4T0::AliTOFv4T0()
+{
+ //
+ // Default constructor
+ //
+}
+
+//_____________________________________________________________________________
+AliTOFv4T0::AliTOFv4T0(const char *name, const char *title)
+ : AliTOF(name,title,"tzero")
+{
+ //
+ // Standard constructor
+ //
+ //
+ // Check that FRAME is there otherwise we have no place where to
+ // put TOF
+ AliModule* frame=gAlice->GetModule("FRAME");
+ if(!frame) {
+ Error("Ctor","TOF needs FRAME to be present\n");
+ exit(1);
+ } else
+ if(frame->IsVersion()!=1) {
+ Error("Ctor","FRAME version 1 needed with this version of TOF\n");
+ exit(1);
+ }
+
+}
+
+//____________________________________________________________________________
+
+void AliTOFv4T0::BuildGeometry()
+{
+ //
+ // Build TOF ROOT geometry for the ALICE event display
+ //
+ TNode *node, *top;
+ const int kColorTOF = 27;
+
+ // Find top TNODE
+ top = gAlice->GetGeometry()->GetNode("alice");
+
+ // Position the different copies
+ const Float_t krTof =(fRmax+fRmin)/2;
+ const Float_t khTof = fRmax-fRmin;
+ const Int_t kNTof = fNTof;
+ const Float_t kPi = TMath::Pi();
+ const Float_t kangle = 2*kPi/kNTof;
+ Float_t ang;
+
+ // Define TOF basic volume
+
+ char nodeName0[7], nodeName1[7], nodeName2[7];
+ char nodeName3[7], nodeName4[7], rotMatNum[7];
+
+ new TBRIK("S_TOF_C","TOF box","void",
+ 120*0.5,khTof*0.5,fZlenC*0.5);
+ new TBRIK("S_TOF_B","TOF box","void",
+ 120*0.5,khTof*0.5,fZlenB*0.5);
+ new TBRIK("S_TOF_A","TOF box","void",
+ 120*0.5,khTof*0.5,fZlenA*0.5);
+
+ for (Int_t nodeNum=1;nodeNum<19;nodeNum++){
+
+ if (nodeNum<10) {
+ sprintf(rotMatNum,"rot50%i",nodeNum);
+ sprintf(nodeName0,"FTO00%i",nodeNum);
+ sprintf(nodeName1,"FTO10%i",nodeNum);
+ sprintf(nodeName2,"FTO20%i",nodeNum);
+ sprintf(nodeName3,"FTO30%i",nodeNum);
+ sprintf(nodeName4,"FTO40%i",nodeNum);
+ }
+ if (nodeNum>9) {
+ sprintf(rotMatNum,"rot5%i",nodeNum);
+ sprintf(nodeName0,"FTO0%i",nodeNum);
+ sprintf(nodeName1,"FTO1%i",nodeNum);
+ sprintf(nodeName2,"FTO2%i",nodeNum);
+ sprintf(nodeName3,"FTO3%i",nodeNum);
+ sprintf(nodeName4,"FTO4%i",nodeNum);
+ }
+
+ new TRotMatrix(rotMatNum,rotMatNum,90,-20*nodeNum,90,90-20*nodeNum,0,0);
+ ang = (4.5-nodeNum) * kangle;
+
+ top->cd();
+ node = new TNode(nodeName0,nodeName0,"S_TOF_C",krTof*TMath::Cos(ang),krTof*TMath::Sin(ang),299.15,rotMatNum);
+ node->SetLineColor(kColorTOF);
+ fNodes->Add(node);
+
+ top->cd();
+ node = new TNode(nodeName1,nodeName1,"S_TOF_C",krTof*TMath::Cos(ang),krTof*TMath::Sin(ang),-299.15,rotMatNum);
+ node->SetLineColor(kColorTOF);
+ fNodes->Add(node);
+
+ top->cd();
+ node = new TNode(nodeName2,nodeName2,"S_TOF_B",krTof*TMath::Cos(ang),krTof*TMath::Sin(ang),146.45,rotMatNum);
+ node->SetLineColor(kColorTOF);
+ fNodes->Add(node);
+
+ top->cd();
+ node = new TNode(nodeName3,nodeName3,"S_TOF_B",krTof*TMath::Cos(ang),krTof*TMath::Sin(ang),-146.45,rotMatNum);
+ node->SetLineColor(kColorTOF);
+ fNodes->Add(node);
+
+ top->cd();
+ node = new TNode(nodeName4,nodeName4,"S_TOF_A",krTof*TMath::Cos(ang),krTof*TMath::Sin(ang),0.,rotMatNum);
+ node->SetLineColor(kColorTOF);
+ fNodes->Add(node);
+ } // end loop on nodeNum
+}
+
+
+
+//_____________________________________________________________________________
+void AliTOFv4T0::CreateGeometry()
+{
+ //
+ // Create geometry for Time Of Flight version 0
+ //
+ //Begin_Html
+ /*
+ <img src="picts/AliTOFv4T0.gif">
+ */
+ //End_Html
+ //
+ // Creates common geometry
+ //
+ AliTOF::CreateGeometry();
+}
+
+//_____________________________________________________________________________
+void AliTOFv4T0::TOFpc(Float_t xtof, Float_t ytof, Float_t zlenC,
+ Float_t zlenB, Float_t zlenA, Float_t ztof0)
+{
+ //
+ // Definition of the Time Of Fligh Resistive Plate Chambers
+ // xFLT, yFLT, zFLT - sizes of TOF modules (large)
+
+ Float_t ycoor, zcoor;
+ Float_t par[3];
+ Int_t *idtmed = fIdtmed->GetArray()-499;
+ Int_t idrotm[100];
+ Int_t nrot = 0;
+ Float_t hTof = fRmax-fRmin;
+
+ Float_t radius = fRmin+2.;//cm
+
+ par[0] = xtof * 0.5;
+ par[1] = ytof * 0.5;
+ par[2] = zlenC * 0.5;
+ gMC->Gsvolu("FTOC", "BOX ", idtmed[506], par, 3);
+ par[2] = zlenB * 0.5;
+ gMC->Gsvolu("FTOB", "BOX ", idtmed[506], par, 3);
+ par[2] = zlenA * 0.5;
+ gMC->Gsvolu("FTOA", "BOX ", idtmed[506], par, 3);
+
+
+// Positioning of modules
+
+ Float_t zcor1 = ztof0 - zlenC*0.5;
+ Float_t zcor2 = ztof0 - zlenC - zlenB*0.5;
+ Float_t zcor3 = 0.;
+
+ AliMatrix(idrotm[0], 90., 0., 0., 0., 90,-90.);
+ AliMatrix(idrotm[1], 90.,180., 0., 0., 90, 90.);
+ gMC->Gspos("FTOC", 1, "BTO1", 0, zcor1, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOC", 2, "BTO1", 0, -zcor1, 0, idrotm[1], "ONLY");
+ gMC->Gspos("FTOC", 1, "BTO2", 0, zcor1, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOC", 2, "BTO2", 0, -zcor1, 0, idrotm[1], "ONLY");
+ gMC->Gspos("FTOC", 1, "BTO3", 0, zcor1, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOC", 2, "BTO3", 0, -zcor1, 0, idrotm[1], "ONLY");
+
+ gMC->Gspos("FTOB", 1, "BTO1", 0, zcor2, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOB", 2, "BTO1", 0, -zcor2, 0, idrotm[1], "ONLY");
+ gMC->Gspos("FTOB", 1, "BTO2", 0, zcor2, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOB", 2, "BTO2", 0, -zcor2, 0, idrotm[1], "ONLY");
+ gMC->Gspos("FTOB", 1, "BTO3", 0, zcor2, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOB", 2, "BTO3", 0, -zcor2, 0, idrotm[1], "ONLY");
+
+ gMC->Gspos("FTOA", 0, "BTO1", 0, zcor3, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOA", 0, "BTO2", 0, zcor3, 0, idrotm[0], "ONLY");
+ gMC->Gspos("FTOA", 0, "BTO3", 0, zcor3, 0, idrotm[0], "ONLY");
+
+ Float_t db = 0.5;//cm
+ Float_t xFLT, xFST, yFLT, zFLTA, zFLTB, zFLTC;
+
+ xFLT = fStripLn;
+ yFLT = ytof;
+ zFLTA = zlenA;
+ zFLTB = zlenB;
+ zFLTC = zlenC;
+
+ xFST = xFLT-fDeadBndX*2;//cm
+
+// Sizes of MRPC pads
+
+ Float_t yPad = 0.505;//cm
+
+// Large not sensitive volumes with Insensitive Freon
+ par[0] = xFLT*0.5;
+ par[1] = yFLT*0.5;
+
+ if (fDebug) cout << ClassName() <<
+ ": ************************* TOF geometry **************************"<<endl;
+
+ par[2] = (zFLTA *0.5);
+ gMC->Gsvolu("FLTA", "BOX ", idtmed[512], par, 3); // Insensitive Freon
+ gMC->Gspos ("FLTA", 0, "FTOA", 0., 0., 0., 0, "ONLY");
+
+ par[2] = (zFLTB * 0.5);
+ gMC->Gsvolu("FLTB", "BOX ", idtmed[512], par, 3); // Insensitive Freon
+ gMC->Gspos ("FLTB", 0, "FTOB", 0., 0., 0., 0, "ONLY");
+
+ par[2] = (zFLTC * 0.5);
+ gMC->Gsvolu("FLTC", "BOX ", idtmed[512], par, 3); // Insensitive Freon
+ gMC->Gspos ("FLTC", 0, "FTOC", 0., 0., 0., 0, "ONLY");
+
+////////// Layers of Aluminum before and after detector //////////
+////////// Aluminum Box for Modules (2.0 mm thickness) /////////
+////////// lateral walls not simulated
+ par[0] = xFLT*0.5;
+ par[1] = 0.1;//cm
+ ycoor = -yFLT/2 + par[1];
+ par[2] = (zFLTA *0.5);
+ gMC->Gsvolu("FALA", "BOX ", idtmed[508], par, 3); // Alluminium
+ gMC->Gspos ("FALA", 1, "FLTA", 0., ycoor, 0., 0, "ONLY");
+ gMC->Gspos ("FALA", 2, "FLTA", 0.,-ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTB *0.5);
+ gMC->Gsvolu("FALB", "BOX ", idtmed[508], par, 3); // Alluminium
+ gMC->Gspos ("FALB", 1, "FLTB", 0., ycoor, 0., 0, "ONLY");
+ gMC->Gspos ("FALB", 2, "FLTB", 0.,-ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTC *0.5);
+ gMC->Gsvolu("FALC", "BOX ", idtmed[508], par, 3); // Alluminium
+ gMC->Gspos ("FALC", 1, "FLTC", 0., ycoor, 0., 0, "ONLY");
+ gMC->Gspos ("FALC", 2, "FLTC", 0.,-ycoor, 0., 0, "ONLY");
+
+///////////////// Detector itself //////////////////////
+
+ const Float_t kdeadBound = fDeadBndZ; //cm non-sensitive between the pad edge
+ //and the boundary of the strip
+ const Int_t knx = fNpadX; // number of pads along x
+ const Int_t knz = fNpadZ; // number of pads along z
+ const Float_t kspace = fSpace; //cm distance from the front plate of the box
+
+ Float_t zSenStrip = fZpad*fNpadZ;//cm
+ Float_t stripWidth = zSenStrip + 2*kdeadBound;
+
+ par[0] = xFLT*0.5;
+ par[1] = yPad*0.5;
+ par[2] = stripWidth*0.5;
+
+// new description for strip volume -double stack strip-
+// -- all constants are expressed in cm
+// heigth of different layers
+ const Float_t khhony = 1. ; // heigth of HONY Layer
+ const Float_t khpcby = 0.15 ; // heigth of PCB Layer
+ const Float_t khmyly = 0.035 ; // heigth of MYLAR Layer
+ const Float_t khgraphy = 0.02 ; // heigth of GRAPHITE Layer
+ const Float_t khglasseiy = 0.17; // 0.6 Ext. Glass + 1.1 i.e. (Int. Glass/2) (mm)
+ const Float_t khsensmy = 0.11 ; // heigth of Sensitive Freon Mixture
+ const Float_t kwsensmz = 2*3.5 ; // cm
+ const Float_t klsensmx = 48*2.5; // cm
+ const Float_t kwpadz = 3.5; // cm z dimension of the FPAD volume
+ const Float_t klpadx = 2.5; // cm x dimension of the FPAD volume
+
+ // heigth of the FSTR Volume (the strip volume)
+ const Float_t khstripy = 2*khhony+3*khpcby+4*(khmyly+khgraphy+khglasseiy)+2*khsensmy;
+ // width of the FSTR Volume (the strip volume)
+ const Float_t kwstripz = 10.;
+ // length of the FSTR Volume (the strip volume)
+ const Float_t klstripx = 122.;
+
+ Float_t parfp[3]={klstripx*0.5,khstripy*0.5,kwstripz*0.5};
+// coordinates of the strip center in the strip reference frame; used for positioning
+// internal strip volumes
+ Float_t posfp[3]={0.,0.,0.};
+
+
+ // FSTR volume definition and filling this volume with non sensitive Gas Mixture
+ gMC->Gsvolu("FSTR","BOX",idtmed[512],parfp,3);
+ //-- HONY Layer definition
+// parfp[0] = -1;
+ parfp[1] = khhony*0.5;
+// parfp[2] = -1;
+ gMC->Gsvolu("FHON","BOX",idtmed[503],parfp,3);
+ // positioning 2 HONY Layers on FSTR volume
+
+ posfp[1]=-khstripy*0.5+parfp[1];
+ gMC->Gspos("FHON",1,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FHON",2,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+
+ //-- PCB Layer definition
+ parfp[1] = khpcby*0.5;
+ gMC->Gsvolu("FPCB","BOX",idtmed[504],parfp,3);
+ // positioning 2 PCB Layers on FSTR volume
+ posfp[1]=-khstripy*0.5+khhony+parfp[1];
+ gMC->Gspos("FPCB",1,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FPCB",2,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+ // positioning the central PCB layer
+ gMC->Gspos("FPCB",3,"FSTR",0.,0.,0.,0,"ONLY");
+
+
+
+ //-- MYLAR Layer definition
+ parfp[1] = khmyly*0.5;
+ gMC->Gsvolu("FMYL","BOX",idtmed[511],parfp,3);
+ // positioning 2 MYLAR Layers on FSTR volume
+ posfp[1] = -khstripy*0.5+khhony+khpcby+parfp[1];
+ gMC->Gspos("FMYL",1,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FMYL",2,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+ // adding further 2 MYLAR Layers on FSTR volume
+ posfp[1] = khpcby*0.5+parfp[1];
+ gMC->Gspos("FMYL",3,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FMYL",4,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+
+
+ //-- Graphite Layer definition
+ parfp[1] = khgraphy*0.5;
+ gMC->Gsvolu("FGRP","BOX",idtmed[502],parfp,3);
+ // positioning 2 Graphite Layers on FSTR volume
+ posfp[1] = -khstripy*0.5+khhony+khpcby+khmyly+parfp[1];
+ gMC->Gspos("FGRP",1,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FGRP",2,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+ // adding further 2 Graphite Layers on FSTR volume
+ posfp[1] = khpcby*0.5+khmyly+parfp[1];
+ gMC->Gspos("FGRP",3,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FGRP",4,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+
+
+ //-- Glass (EXT. +Semi INT.) Layer definition
+ parfp[1] = khglasseiy*0.5;
+ gMC->Gsvolu("FGLA","BOX",idtmed[514],parfp,3);
+ // positioning 2 Glass Layers on FSTR volume
+ posfp[1] = -khstripy*0.5+khhony+khpcby+khmyly+khgraphy+parfp[1];
+ gMC->Gspos("FGLA",1,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FGLA",2,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+ // adding further 2 Glass Layers on FSTR volume
+ posfp[1] = khpcby*0.5+khmyly+khgraphy+parfp[1];
+ gMC->Gspos("FGLA",3,"FSTR",0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FGLA",4,"FSTR",0.,-posfp[1],0.,0,"ONLY");
+
+
+ //-- Sensitive Mixture Layer definition
+ parfp[0] = klsensmx*0.5;
+ parfp[1] = khsensmy*0.5;
+ parfp[2] = kwsensmz*0.5;
+ gMC->Gsvolu("FSEN","BOX",idtmed[513],parfp,3);
+ gMC->Gsvolu("FNSE","BOX",idtmed[512],parfp,3);
+ // positioning 2 gas Layers on FSTR volume
+ // the upper is insensitive freon
+ // while the remaining is sensitive
+ posfp[1] = khpcby*0.5+khmyly+khgraphy+khglasseiy+parfp[1];
+ gMC->Gspos("FNSE",0,"FSTR", 0., posfp[1],0.,0,"ONLY");
+ gMC->Gspos("FSEN",0,"FSTR", 0.,-posfp[1],0.,0,"ONLY");
+
+ // dividing FSEN along z in knz=2 and along x in knx=48
+ gMC->Gsdvn("FSEZ","FSEN",knz,3);
+ gMC->Gsdvn("FSEX","FSEZ",knx,1);
+
+ // FPAD volume definition
+ parfp[0] = klpadx*0.5;
+ parfp[1] = khsensmy*0.5;
+ parfp[2] = kwpadz*0.5;
+ gMC->Gsvolu("FPAD","BOX",idtmed[513],parfp,3);
+ // positioning the FPAD volumes on previous divisions
+ gMC->Gspos("FPAD",0,"FSEX",0.,0.,0.,0,"ONLY");
+
+//// Positioning the Strips (FSTR) in the FLT volumes /////
+
+ // Plate A (Central)
+
+ Float_t t = zFLTC+zFLTB+zFLTA*0.5+ 2*db;//Half Width of Barrel
+
+ Float_t gap = fGapA; //cm distance between the strip axis
+ Float_t zpos = 0;
+ Float_t ang = 0;
+ Int_t i=1,j=1;
+ nrot = 0;
+ zcoor = 0;
+ ycoor = -14.5 + kspace ; //2 cm over front plate
+
+ AliMatrix (idrotm[0], 90., 0.,90.,90.,0., 90.);
+ gMC->Gspos("FSTR",j,"FLTA",0.,ycoor, 0.,idrotm[0],"ONLY");
+ if(fDebug) {
+ printf("%s: %f, St. %2i, Pl.3 ",ClassName(),ang*kRaddeg,i);
+ printf("y = %f, z = %f, zpos = %f \n",ycoor,zcoor,zpos);
+ }
+ zcoor -= zSenStrip;
+ j++;
+ Int_t upDown = -1; // upDown=-1 -> Upper strip
+ // upDown=+1 -> Lower strip
+ do{
+ ang = atan(zcoor/radius);
+ ang *= kRaddeg;
+ AliMatrix (idrotm[nrot], 90., 0.,90.-ang,90.,-ang, 90.);
+ AliMatrix (idrotm[nrot+1],90.,180.,90.+ang,90., ang, 90.);
+ ang /= kRaddeg;
+ ycoor = -14.5+ kspace; //2 cm over front plate
+ ycoor += (1-(upDown+1)/2)*gap;
+ gMC->Gspos("FSTR",j ,"FLTA",0.,ycoor, zcoor,idrotm[nrot], "ONLY");
+ gMC->Gspos("FSTR",j+1,"FLTA",0.,ycoor,-zcoor,idrotm[nrot+1],"ONLY");
+ if(fDebug) {
+ printf("%s: %f, St. %2i, Pl.3 ",ClassName(),ang*kRaddeg,i);
+ printf("y = %f, z = %f, zpos = %f \n",ycoor,zcoor,zpos);
+ }
+ j += 2;
+ upDown*= -1; // Alternate strips
+ zcoor = zcoor-(zSenStrip/2)/TMath::Cos(ang)-
+ upDown*gap*TMath::Tan(ang)-
+ (zSenStrip/2)/TMath::Cos(ang);
+ } while (zcoor-(stripWidth/2)*TMath::Cos(ang)>-t+zFLTC+zFLTB+db*2);
+
+ zcoor = zcoor+(zSenStrip/2)/TMath::Cos(ang)+
+ upDown*gap*TMath::Tan(ang)+
+ (zSenStrip/2)/TMath::Cos(ang);
+
+ gap = fGapB;
+ zcoor = zcoor-(zSenStrip/2)/TMath::Cos(ang)-
+ upDown*gap*TMath::Tan(ang)-
+ (zSenStrip/2)/TMath::Cos(ang);
+
+ ang = atan(zcoor/radius);
+ ang *= kRaddeg;
+ AliMatrix (idrotm[nrot], 90., 0.,90.-ang,90.,-ang, 90.);
+ AliMatrix (idrotm[nrot+1],90.,180.,90.+ang,90., ang, 90.);
+ ang /= kRaddeg;
+
+ ycoor = -14.5+ kspace; //2 cm over front plate
+ ycoor += (1-(upDown+1)/2)*gap;
+ gMC->Gspos("FSTR",j ,"FLTA",0.,ycoor, zcoor,idrotm[nrot], "ONLY");
+ gMC->Gspos("FSTR",j+1,"FLTA",0.,ycoor,-zcoor,idrotm[nrot+1],"ONLY");
+ if(fDebug) {
+ printf("%s: %f, St. %2i, Pl.3 ",ClassName(),ang*kRaddeg,i);
+ printf("y = %f, z = %f, zpos = %f \n",ycoor,zcoor,zpos);
+ }
+ ycoor = -hTof/2.+ kspace;//2 cm over front plate
+
+ // Plate B
+
+ nrot = 0;
+ i=1;
+ upDown = 1;
+ Float_t deadRegion = 1.0;//cm
+
+ zpos = zcoor - (zSenStrip/2)/TMath::Cos(ang)-
+ upDown*gap*TMath::Tan(ang)-
+ (zSenStrip/2)/TMath::Cos(ang)-
+ deadRegion/TMath::Cos(ang);
+
+ ang = atan(zpos/radius);
+ ang *= kRaddeg;
+ AliMatrix (idrotm[nrot], 90., 0., 90.-ang,90.,ang, 270.);
+ ang /= kRaddeg;
+ ycoor = -hTof*0.5+ kspace ; //2 cm over front plate
+ ycoor += (1-(upDown+1)/2)*gap;
+ zcoor = zpos+(zFLTA*0.5+zFLTB*0.5+db); // Moves to the system of the modulus FLTB
+ gMC->Gspos("FSTR",i, "FLTB", 0., ycoor, zcoor,idrotm[nrot], "ONLY");
+ if(fDebug) {
+ printf("%s: %f, St. %2i, Pl.4 ",ClassName(),ang*kRaddeg,i);
+ printf("y = %f, z = %f, zpos = %f \n",ycoor,zcoor,zpos);
+ }
+ i++;
+ upDown*=-1;
+
+ do {
+ zpos = zpos - (zSenStrip/2)/TMath::Cos(ang)-
+ upDown*gap*TMath::Tan(ang)-
+ (zSenStrip/2)/TMath::Cos(ang);
+ ang = atan(zpos/radius);
+ ang *= kRaddeg;
+ AliMatrix (idrotm[nrot], 90., 0., 90.-ang,90.,ang, 270.);
+ ang /= kRaddeg;
+ ycoor = -hTof*0.5+ kspace ; //2 cm over front plate
+ ycoor += (1-(upDown+1)/2)*gap;
+ zcoor = zpos+(zFLTA*0.5+zFLTB*0.5+db); // Moves to the system of the modulus FLTB
+ gMC->Gspos("FSTR",i, "FLTB", 0., ycoor, zcoor,idrotm[nrot], "ONLY");
+ if(fDebug) {
+ printf("%s: %f, St. %2i, Pl.4 ",ClassName(),ang*kRaddeg,i);
+ printf("y = %f, z = %f, zpos = %f \n",ycoor,zcoor,zpos);
+ }
+ upDown*=-1;
+ i++;
+ } while (TMath::Abs(ang*kRaddeg)<22.5);
+ //till we reach a tilting angle of 22.5 degrees
+
+ ycoor = -hTof*0.5+ kspace ; //2 cm over front plate
+ zpos = zpos - zSenStrip/TMath::Cos(ang);
+
+ do {
+ ang = atan(zpos/radius);
+ ang *= kRaddeg;
+ AliMatrix (idrotm[nrot], 90., 0., 90.-ang,90.,ang, 270.);
+ ang /= kRaddeg;
+ zcoor = zpos+(zFLTB/2+zFLTA/2+db);
+ gMC->Gspos("FSTR",i, "FLTB", 0., ycoor, zcoor,idrotm[nrot], "ONLY");
+ zpos = zpos - zSenStrip/TMath::Cos(ang);
+ if(fDebug) {
+ printf("%s: %f, St. %2i, Pl.4 ",ClassName(),ang*kRaddeg,i);
+ printf("y = %f, z = %f, zpos = %f \n",ycoor,zcoor,zpos);
+ }
+ i++;
+
+ } while (zpos-stripWidth*0.5/TMath::Cos(ang)>-t+zFLTC+db);
+
+ // Plate C
+
+ zpos = zpos + zSenStrip/TMath::Cos(ang);
+
+ zpos = zpos - (zSenStrip/2)/TMath::Cos(ang)+
+ gap*TMath::Tan(ang)-
+ (zSenStrip/2)/TMath::Cos(ang);
+
+ nrot = 0;
+ i=0;
+ ycoor= -hTof*0.5+kspace+gap;
+
+ do {
+ i++;
+ ang = atan(zpos/radius);
+ ang *= kRaddeg;
+ AliMatrix (idrotm[nrot], 90., 0., 90.-ang,90.,ang, 270.);
+ ang /= kRaddeg;
+ zcoor = zpos+(zFLTC*0.5+zFLTB+zFLTA*0.5+db*2);
+ gMC->Gspos("FSTR",i, "FLTC", 0., ycoor, zcoor,idrotm[nrot], "ONLY");
+ if(fDebug) {
+ printf("%s: %f, St. %2i, Pl.5 ",ClassName(),ang*kRaddeg,i);
+ printf("y = %f, z = %f, zpos = %f \n",ycoor,zcoor,zpos);
+ }
+ zpos = zpos - zSenStrip/TMath::Cos(ang);
+ } while (zpos-stripWidth*TMath::Cos(ang)*0.5>-t);
+
+
+////////// Layers after strips /////////////////
+// honeycomb (Polyethilene) Layer after (1.2cm)
+
+ Float_t overSpace = fOverSpc;//cm
+
+ par[0] = xFLT*0.5;
+ par[1] = 0.6;
+ par[2] = (zFLTA *0.5);
+ ycoor = -yFLT/2 + overSpace + par[1];
+ gMC->Gsvolu("FPEA", "BOX ", idtmed[503], par, 3); // Hony
+ gMC->Gspos ("FPEA", 0, "FLTA", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTB *0.5);
+ gMC->Gsvolu("FPEB", "BOX ", idtmed[503], par, 3); // Hony
+ gMC->Gspos ("FPEB", 0, "FLTB", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTC *0.5);
+ gMC->Gsvolu("FPEC", "BOX ", idtmed[503], par, 3); // Hony
+ gMC->Gspos ("FPEC", 0, "FLTC", 0., ycoor, 0., 0, "ONLY");
+
+// Electronics (Cu) after
+ ycoor += par[1];
+ par[0] = xFLT*0.5;
+ par[1] = 1.43*0.05*0.5; // 5% of X0
+ par[2] = (zFLTA *0.5);
+ ycoor += par[1];
+ gMC->Gsvolu("FECA", "BOX ", idtmed[501], par, 3); // Cu
+ gMC->Gspos ("FECA", 0, "FLTA", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTB *0.5);
+ gMC->Gsvolu("FECB", "BOX ", idtmed[501], par, 3); // Cu
+ gMC->Gspos ("FECB", 0, "FLTB", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTC *0.5);
+ gMC->Gsvolu("FECC", "BOX ", idtmed[501], par, 3); // Cu
+ gMC->Gspos ("FECC", 0, "FLTC", 0., ycoor, 0., 0, "ONLY");
+
+// cooling WAter after
+ ycoor += par[1];
+ par[0] = xFLT*0.5;
+ par[1] = 36.1*0.02*0.5; // 2% of X0
+ par[2] = (zFLTA *0.5);
+ ycoor += par[1];
+ gMC->Gsvolu("FWAA", "BOX ", idtmed[515], par, 3); // Water
+ gMC->Gspos ("FWAA", 0, "FLTA", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTB *0.5);
+ gMC->Gsvolu("FWAB", "BOX ", idtmed[515], par, 3); // Water
+ gMC->Gspos ("FWAB", 0, "FLTB", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTC *0.5);
+ gMC->Gsvolu("FWAC", "BOX ", idtmed[515], par, 3); // Water
+ gMC->Gspos ("FWAC", 0, "FLTC", 0., ycoor, 0., 0, "ONLY");
+
+// frame of Air
+ ycoor += par[1];
+ par[0] = xFLT*0.5;
+ par[1] = (yFLT/2-ycoor-0.2)*0.5; // Aluminum layer considered (0.2 cm)
+ par[2] = (zFLTA *0.5);
+ ycoor += par[1];
+ gMC->Gsvolu("FAIA", "BOX ", idtmed[500], par, 3); // Air
+ gMC->Gspos ("FAIA", 0, "FLTA", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTB *0.5);
+ gMC->Gsvolu("FAIB", "BOX ", idtmed[500], par, 3); // Air
+ gMC->Gspos ("FAIB", 0, "FLTB", 0., ycoor, 0., 0, "ONLY");
+ par[2] = (zFLTC *0.5);
+ gMC->Gsvolu("FAIC", "BOX ", idtmed[500], par, 3); // Air
+ gMC->Gspos ("FAIC", 0, "FLTC", 0., ycoor, 0., 0, "ONLY");
+/* fp
+//Back Plate honycomb (2cm)
+ par[0] = -1;
+ par[1] = 2 *0.5;
+ par[2] = -1;
+ ycoor = yFLT/2 - par[1];
+ gMC->Gsvolu("FBPA", "BOX ", idtmed[503], par, 3); // Hony
+ gMC->Gspos ("FBPA", 0, "FLTA", 0., ycoor, 0., 0, "ONLY");
+ gMC->Gsvolu("FBPB", "BOX ", idtmed[503], par, 3); // Hony
+ gMC->Gspos ("FBPB", 0, "FLTB", 0., ycoor, 0., 0, "ONLY");
+ gMC->Gsvolu("FBPC", "BOX ", idtmed[503], par, 3); // Hony
+ gMC->Gspos ("FBPC", 0, "FLTC", 0., ycoor, 0., 0, "ONLY");
+fp */
+}
+
+//_____________________________________________________________________________
+void AliTOFv4T0::DrawModule() const
+{
+ //
+ // Draw a shaded view of the Time Of Flight version 4
+ //
+ // Set everything unseen
+ gMC->Gsatt("*", "seen", -1);
+ //
+ // Set ALIC mother transparent
+ gMC->Gsatt("ALIC","SEEN",0);
+ //
+ // Set the volumes visible
+ gMC->Gsatt("ALIC","SEEN",0);
+
+ gMC->Gsatt("FTOA","SEEN",1);
+ gMC->Gsatt("FTOB","SEEN",1);
+ gMC->Gsatt("FTOC","SEEN",1);
+ gMC->Gsatt("FLTA","SEEN",1);
+ gMC->Gsatt("FLTB","SEEN",1);
+ gMC->Gsatt("FLTC","SEEN",1);
+ gMC->Gsatt("FPLA","SEEN",1);
+ gMC->Gsatt("FPLB","SEEN",1);
+ gMC->Gsatt("FPLC","SEEN",1);
+ gMC->Gsatt("FSTR","SEEN",1);
+ gMC->Gsatt("FPEA","SEEN",1);
+ gMC->Gsatt("FPEB","SEEN",1);
+ gMC->Gsatt("FPEC","SEEN",1);
+
+ gMC->Gsatt("FLZ1","SEEN",0);
+ gMC->Gsatt("FLZ2","SEEN",0);
+ gMC->Gsatt("FLZ3","SEEN",0);
+ gMC->Gsatt("FLX1","SEEN",0);
+ gMC->Gsatt("FLX2","SEEN",0);
+ gMC->Gsatt("FLX3","SEEN",0);
+ gMC->Gsatt("FPAD","SEEN",0);
+
+ gMC->Gdopt("hide", "on");
+ gMC->Gdopt("shad", "on");
+ gMC->Gsatt("*", "fill", 7);
+ gMC->SetClipBox(".");
+ gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000);
+ gMC->DefaultRange();
+ gMC->Gdraw("alic", 40, 30, 0, 12, 9.5, .02, .02);
+ gMC->Gdhead(1111, "Time Of Flight");
+ gMC->Gdman(18, 4, "MAN");
+ gMC->Gdopt("hide","off");
+}
+//_____________________________________________________________________________
+void AliTOFv4T0::DrawDetectorModules()
+{
+//
+// Draw a shaded view of the TOF detector version 4
+//
+
+ AliMC* pMC = AliMC::GetMC();
+
+//Set ALIC mother transparent
+ pMC->Gsatt("ALIC","SEEN",0);
+
+//
+//Set volumes visible
+//
+//=====> Level 1
+ // Level 1 for TOF volumes
+ gMC->Gsatt("B077","seen",0);
+
+
+//==========> Level 2
+ // Level 2
+ gMC->Gsatt("B076","seen",-1); // all B076 sub-levels skipped -
+ gMC->Gsatt("B071","seen",0);
+ gMC->Gsatt("B074","seen",0);
+ gMC->Gsatt("B075","seen",0);
+ gMC->Gsatt("B080","seen",0); // B080 does not has sub-level
+
+
+ // Level 2 of B071
+ gMC->Gsatt("B063","seen",-1); // all B063 sub-levels skipped -
+ gMC->Gsatt("B065","seen",-1); // all B065 sub-levels skipped -
+ gMC->Gsatt("B067","seen",-1); // all B067 sub-levels skipped -
+ gMC->Gsatt("B069","seen",-1); // all B069 sub-levels skipped -
+ gMC->Gsatt("B056","seen",0); // B056 does not has sub-levels -
+ gMC->Gsatt("B059","seen",-1); // all B059 sub-levels skipped -
+ gMC->Gsatt("B072","seen",-1); // all B072 sub-levels skipped -
+ gMC->Gsatt("BTR1","seen",0); // BTR1 do not have sub-levels -
+ gMC->Gsatt("BTO1","seen",0);
+
+
+ // Level 2 of B074
+ gMC->Gsatt("BTR2","seen",0); // BTR2 does not has sub-levels -
+ gMC->Gsatt("BTO2","seen",0);
+
+ // Level 2 of B075
+ gMC->Gsatt("BTR3","seen",0); // BTR3 do not have sub-levels -
+ gMC->Gsatt("BTO3","seen",0);
+
+// ==================> Level 3
+ // Level 3 of B071 / Level 2 of BTO1
+ gMC->Gsatt("FTOC","seen",-2);
+ gMC->Gsatt("FTOB","seen",-2);
+ gMC->Gsatt("FTOA","seen",-2);
+
+ // Level 3 of B074 / Level 2 of BTO2
+ // -> cfr previous settings
+
+ // Level 3 of B075 / Level 2 of BTO3
+ // -> cfr previous settings
+
+ gMC->Gdopt("hide","on");
+ gMC->Gdopt("shad","on");
+ gMC->Gsatt("*", "fill", 5);
+ gMC->SetClipBox(".");
+ gMC->SetClipBox("*", 0, 1000, 0, 1000, 0, 1000);
+ gMC->DefaultRange();
+ gMC->Gdraw("alic", 45, 40, 0, 10, 10, .015, .015);
+ gMC->Gdhead(1111,"TOF detector V1");
+ gMC->Gdman(18, 4, "MAN");
+ gMC->Gdopt("hide","off");
+}
+
+//_____________________________________________________________________________
+void AliTOFv4T0::DrawDetectorStrips()
+{
+ //
+ // Draw a shaded view of the TOF strips for version 4
+ //
+
+ AliMC* pMC = AliMC::GetMC();
+
+ //Set ALIC mother transparent
+ pMC->Gsatt("ALIC","SEEN",0);
+
+ //
+ //Set volumes visible
+ //=====> Level 1
+ // Level 1 for TOF volumes
+ gMC->Gsatt("B077","seen",0);
+
+ //==========> Level 2
+ // Level 2
+ gMC->Gsatt("B076","seen",-1); // all B076 sub-levels skipped -
+ gMC->Gsatt("B071","seen",0);
+ gMC->Gsatt("B074","seen",0);
+ gMC->Gsatt("B075","seen",0);
+ gMC->Gsatt("B080","seen",0); // B080 does not has sub-level
+
+ // Level 2 of B071
+ gMC->Gsatt("B063","seen",-1); // all B063 sub-levels skipped -
+ gMC->Gsatt("B065","seen",-1); // all B065 sub-levels skipped -
+ gMC->Gsatt("B067","seen",-1); // all B067 sub-levels skipped -
+ gMC->Gsatt("B069","seen",-1); // all B069 sub-levels skipped -
+ gMC->Gsatt("B056","seen",0); // B056 does not has sub-levels -
+ gMC->Gsatt("B059","seen",-1); // all B059 sub-levels skipped -
+ gMC->Gsatt("B072","seen",-1); // all B072 sub-levels skipped -
+ gMC->Gsatt("BTR1","seen",0); // BTR1 do not have sub-levels -
+ gMC->Gsatt("BTO1","seen",0);
+
+ // ==================> Level 3
+ // Level 3 of B071 / Level 2 of BTO1
+ gMC->Gsatt("FTOC","seen",0);
+ gMC->Gsatt("FTOB","seen",0);
+ gMC->Gsatt("FTOA","seen",0);
+
+ // Level 3 of B074 / Level 2 of BTO2
+ // -> cfr previous settings
+
+ // Level 3 of B075 / Level 2 of BTO3
+ // -> cfr previous settings
+
+
+ // ==========================> Level 4
+ // Level 4 of B071 / Level 3 of BTO1 / Level 2 of FTOC
+ gMC->Gsatt("FLTC","seen",0);
+ // Level 4 of B071 / Level 3 of BTO1 / Level 2 of FTOB
+ gMC->Gsatt("FLTB","seen",0);
+ // Level 4 of B071 / Level 3 of BTO1 / Level 2 of FTOA
+ gMC->Gsatt("FLTA","seen",0);
+
+ // Level 4 of B074 / Level 3 of BTO2 / Level 2 of FTOC
+ // -> cfr previous settings
+ // Level 4 of B074 / Level 3 of BTO2 / Level 2 of FTOB
+ // -> cfr previous settings
+
+ // Level 4 of B075 / Level 3 of BTO3 / Level 2 of FTOC
+ // -> cfr previous settings
+
+ //======================================> Level 5
+ // Level 5 of B071 / Level 4 of BTO1 / Level 3 of FTOC / Level 2 of FLTC
+ gMC->Gsatt("FALC","seen",0); // no children for FALC
+ gMC->Gsatt("FSTR","seen",-2);
+ gMC->Gsatt("FPEC","seen",0); // no children for FPEC
+ gMC->Gsatt("FECC","seen",0); // no children for FECC
+ gMC->Gsatt("FWAC","seen",0); // no children for FWAC
+ gMC->Gsatt("FAIC","seen",0); // no children for FAIC
+
+ // Level 5 of B071 / Level 4 of BTO1 / Level 3 of FTOB / Level 2 of FLTB
+ gMC->Gsatt("FALB","seen",0); // no children for FALB
+ //--> gMC->Gsatt("FSTR","seen",-2);
+
+
+ // -> cfr previous settings
+ gMC->Gsatt("FPEB","seen",0); // no children for FPEB
+ gMC->Gsatt("FECB","seen",0); // no children for FECB
+ gMC->Gsatt("FWAB","seen",0); // no children for FWAB
+ gMC->Gsatt("FAIB","seen",0); // no children for FAIB
+
+ // Level 5 of B071 / Level 4 of BTO1 / Level 3 of FTOA / Level 2 of FLTA
+ gMC->Gsatt("FALA","seen",0); // no children for FALB
+ //--> gMC->Gsatt("FSTR","seen",-2);
+ // -> cfr previous settings
+ gMC->Gsatt("FPEA","seen",0); // no children for FPEA
+ gMC->Gsatt("FECA","seen",0); // no children for FECA
+ gMC->Gsatt("FWAA","seen",0); // no children for FWAA
+ gMC->Gsatt("FAIA","seen",0); // no children for FAIA
+
+ // Level 2 of B074
+ gMC->Gsatt("BTR2","seen",0); // BTR2 does not has sub-levels -
+ gMC->Gsatt("BTO2","seen",0);
+
+ // Level 2 of B075
+ gMC->Gsatt("BTR3","seen",0); // BTR3 do not have sub-levels -
+ gMC->Gsatt("BTO3","seen",0);
+
+ // for others Level 5, cfr. previous settings
+
+ gMC->Gdopt("hide","on");
+ gMC->Gdopt("shad","on");
+ gMC->Gsatt("*", "fill", 5);
+ gMC->SetClipBox(".");
+ gMC->SetClipBox("*", 0, 1000, 0, 1000, 0, 1000);
+ gMC->DefaultRange();
+ gMC->Gdraw("alic", 45, 40, 0, 10, 10, .015, .015);
+ gMC->Gdhead(1111,"TOF Strips V1");
+ gMC->Gdman(18, 4, "MAN");
+ gMC->Gdopt("hide","off");
+}
+
+//_____________________________________________________________________________
+void AliTOFv4T0::CreateMaterials()
+{
+ //
+ // Define materials for the Time Of Flight
+ //
+ AliTOF::CreateMaterials();
+}
+
+//_____________________________________________________________________________
+void AliTOFv4T0::Init()
+{
+ //
+ // Initialise the detector after the geometry has been defined
+ //
+ if(fDebug) {
+ printf("%s: **************************************"
+ " TOF "
+ "**************************************\n",ClassName());
+ printf("\n%s: Version 4 of TOF initialing, "
+ "symmetric TOF - Full Coverage version\n",ClassName());
+ }
+
+ AliTOF::Init();
+
+ fIdFTOA = gMC->VolId("FTOA");
+ fIdFTOB = gMC->VolId("FTOB");
+ fIdFTOC = gMC->VolId("FTOC");
+ fIdFLTA = gMC->VolId("FLTA");
+ fIdFLTB = gMC->VolId("FLTB");
+ fIdFLTC = gMC->VolId("FLTC");
+
+ if(fDebug) {
+ printf("%s: **************************************"
+ " TOF "
+ "**************************************\n",ClassName());
+ }
+}
+
+//_____________________________________________________________________________
+void AliTOFv4T0::StepManager()
+{
+ //
+ // Procedure called at each step in the Time Of Flight
+ //
+ TLorentzVector mom, pos;
+ Float_t xm[3],pm[3],xpad[3],ppad[3];
+ Float_t hits[14],phi,phid,z;
+ Int_t vol[5];
+ Int_t sector, plate, padx, padz, strip;
+ Int_t copy, padzid, padxid, stripid, i;
+ Int_t *idtmed = fIdtmed->GetArray()-499;
+ Float_t incidenceAngle;
+
+ if(gMC->GetMedium()==idtmed[513] &&
+ gMC->IsTrackEntering() && gMC->TrackCharge()
+ && gMC->CurrentVolID(copy)==fIdSens)
+ {
+ // getting information about hit volumes
+
+ padzid=gMC->CurrentVolOffID(2,copy);
+ padz=copy;
+
+ padxid=gMC->CurrentVolOffID(1,copy);
+ padx=copy;
+
+ stripid=gMC->CurrentVolOffID(4,copy);
+ strip=copy;
+
+ gMC->TrackPosition(pos);
+ gMC->TrackMomentum(mom);
+
+// Double_t NormPos=1./pos.Rho();
+ Double_t normMom=1./mom.Rho();
+
+// getting the cohordinates in pad ref system
+ xm[0] = (Float_t)pos.X();
+ xm[1] = (Float_t)pos.Y();
+ xm[2] = (Float_t)pos.Z();
+
+ pm[0] = (Float_t)mom.X()*normMom;
+ pm[1] = (Float_t)mom.Y()*normMom;
+ pm[2] = (Float_t)mom.Z()*normMom;
+
+ gMC->Gmtod(xm,xpad,1);
+ gMC->Gmtod(pm,ppad,2);
+
+ incidenceAngle = TMath::ACos(ppad[1])*kRaddeg;
+
+ z = pos[2];
+
+ plate = 0;
+ if (TMath::Abs(z) <= fZlenA*0.5) plate = 3;
+ if (z < (fZlenA*0.5+fZlenB) &&
+ z > fZlenA*0.5) plate = 4;
+ if (z >-(fZlenA*0.5+fZlenB) &&
+ z < -fZlenA*0.5) plate = 2;
+ if (z > (fZlenA*0.5+fZlenB)) plate = 5;
+ if (z <-(fZlenA*0.5+fZlenB)) plate = 1;
+
+ phi = pos.Phi();
+ phid = phi*kRaddeg+180.;
+ sector = Int_t (phid/20.);
+ sector++;
+
+ for(i=0;i<3;++i) {
+ hits[i] = pos[i];
+ hits[i+3] = pm[i];
+ }
+
+ hits[6] = mom.Rho();
+ hits[7] = pos[3];
+ hits[8] = xpad[0];
+ hits[9] = xpad[1];
+ hits[10]= xpad[2];
+ hits[11]= incidenceAngle;
+ hits[12]= gMC->Edep();
+ hits[13]= gMC->TrackLength();
+
+ vol[0]= sector;
+ vol[1]= plate;
+ vol[2]= strip;
+ vol[3]= padx;
+ vol[4]= padz;
+
+ AddT0Hit(gAlice->CurrentTrack(),vol, hits);
+ }
+}