00001 #include "PhotonFullFibreModel.h"
00002 #include "PhotonTransportMaker.h"
00003 #include "PhotonUtil.h"
00004 #include "MessageService/MsgService.h"
00005 #include "Conventions/Munits.h"
00006 #include <cmath>
00007
00008 CVSID( "$Id: PhotonFullFibreModel.cxx,v 1.10 2006/12/01 19:59:25 rhatcher Exp $" );
00009
00010 ClassImp(PhotonFullFibreModel)
00011
00012 PhotonTransportMakerProxy<PhotonFullFibreModel>
00013 gPhotonFullFibreModelProxy("photonFullFibreModel");
00014
00016
00017 PhotonFullFibreModel::PhotonFullFibreModel() :
00018 fFibreAbsorbTable("PHOTONFIBREABSORB"),
00019 fGreenSpectrumTable("PHOTONGREENSPECTRUM")
00020 {
00021 Configure(PhotonConfiguration());
00022
00023 if (fFibreAbsorbTable.GetNumRows()<1) {
00024 MSG("Photon",Msg::kError) << "Can't find data for table PHOTONFIBREABSORB. Aborting!\n";
00025 assert(0);
00026 }
00027 if (fGreenSpectrumTable.GetNumRows()<1) {
00028 MSG("Photon",Msg::kError) << "Can't find data for table PHOTONFIBREABSORB. Aborting!\n";
00029 assert(0);
00030 }
00031 }
00032
00034
00035 void
00036 PhotonFullFibreModel::Configure( const Registry& r )
00037 {
00038 MSG("Photon",Msg::kDebug) << "Configuring FullFibreModel." << std::endl;
00039 double tmpd;
00040 if (r.Get("FibreRadius",tmpd)) fFibreRadius = tmpd;
00041 if (r.Get("FibreCoreRadius",tmpd)) fFibreCoreRadius = tmpd;
00042 if (r.Get("InnerCladdingRadius",tmpd)) fInnerCladdingRadius = tmpd;
00043
00044 if (r.Get("FibreFlurorDecayTime",tmpd)) fFibreFlurorDecayTime = tmpd;
00045
00046 if (r.Get("FibreIndex",tmpd)) fFibreIndex = tmpd;
00047 if (r.Get("ScintIndex",tmpd)) fScintIndex = tmpd;
00048 if (r.Get("OuterCladdingIndex",tmpd)) fOuterCladdingIndex = tmpd;
00049 if (r.Get("InnerCladdingIndex",tmpd)) fInnerCladdingIndex = tmpd;
00050
00051 SetWlsPrescaleFactor(1.0);
00052 }
00053
00054 void
00055 PhotonFullFibreModel::Reset( const VldContext& cx )
00056 {
00057
00058 fFibreAbsorbTable.Reset(cx);
00059 fGreenSpectrumTable.Reset(cx);
00060 }
00061
00063 Int_t
00064 PhotonFullFibreModel:: FindBlueAbsorptionPosition( const UgliStripHandle& inStrip,
00065 DigiPhoton* inBluePhoton,
00066 TVector3& outPos)
00067 {
00068
00069
00070
00071
00072
00073
00074 TVector3 x = inBluePhoton->GetPos();
00075
00076 x -= TVector3(0,0,
00077 inStrip.GetHalfThickness() - fFibreRadius);
00078 fBlue_Start = fBlue_Stop = fBlue_OuterHit = fBlue_InnerHit = x;
00079
00080 TVector3 v = inBluePhoton->GetDir();
00081
00082
00083 int interact = PhotonUtil::InteractWithCylinder( x,v,
00084 fFibreRadius,
00085 fScintIndex,
00086 fOuterCladdingIndex);
00087 if(interact!=0) {
00088
00089 fBlue_OuterHit = x + v*0.0001;
00090 MSG("Photon",Msg::kWarning) << "Didn't refract into fibre. Huh? x=("
00091 << x.x() << " " << x.y() << " " << x.z() << ") "
00092 << "v=(" << v.x() << " " << v.y() << " " << v.z() <<")\n";
00093
00094 return -2;
00095 }
00096
00097 int inclad1 = PhotonUtil::InteractWithCylinder( x,v,
00098 fInnerCladdingRadius,
00099 fOuterCladdingIndex,
00100 fInnerCladdingIndex );
00101
00102 fBlue_OuterHit = x;
00103 if(inclad1!=0) { return 1; }
00104
00105
00106 int incore = PhotonUtil::InteractWithCylinder( x, v,
00107 fFibreCoreRadius,
00108 fInnerCladdingIndex,
00109 fFibreIndex );
00110 fBlue_InnerHit = x;
00111
00112 if(incore!=0) { return 2; };
00113
00114
00115 double d1, d2;
00116 incore = PhotonUtil::IntersectCylinder( x, v, fFibreCoreRadius, d1, d2 );
00117
00118
00119 if(!incore) { return -3;}
00120
00121
00122 double wavelength = inBluePhoton->WaveLength()/Munits::nm;
00123 if(wavelength<=0) wavelength = 420;
00124
00125
00126 double atten = fFibreAbsorbTable.Interpolate(wavelength);
00127
00128
00129 double d = d1 + fRandom->Exp(atten);
00130
00131
00132 outPos = x + v*d;
00133 fBlue_Stop = outPos;;
00134 if(d>d2) { return 3; }
00135
00136 return 0;
00137 }
00138
00140 DigiPhoton*
00141 PhotonFullFibreModel::MakeGreenPhoton( DigiPhoton* inBluePhoton,
00142 const TVector3& inPos,
00143 StripEnd::StripEnd_t inDirection
00144 )
00145 {
00146
00147 double cosTheta = 2.*fRandom->Rndm()-1.0;
00148 double sinTheta = TMath::Sin(TMath::ACos(cosTheta));
00149 double phi = 2.*TMath::Pi()*fRandom->Rndm();
00150 TVector3 dir( cosTheta,
00151 sinTheta*TMath::Cos(phi),
00152 sinTheta*TMath::Sin(phi) );
00153
00154
00155 switch(inDirection) {
00156 case StripEnd::kPositive:
00157 dir.SetX(fabs(dir.X()));
00158 break;
00159
00160 case StripEnd::kNegative:
00161 dir.SetX(-fabs(dir.X()));
00162 break;
00163
00164 default:
00165
00166 break;
00167 }
00168
00169
00170 double wavelength = fGreenSpectrumTable.Pick(fRandom->Rndm())*Munits::nm;
00171
00172 double time = inBluePhoton->T() + fRandom->Exp(fFibreFlurorDecayTime);
00173
00174 DigiPhoton* green = new DigiPhoton( inBluePhoton->ParentHit(),
00175 wavelength,
00176 time,
00177 inPos,
00178 dir
00179 );
00180 return green;
00181 }
00182
00184 Bool_t
00185 PhotonFullFibreModel::IsGreenTrapped( DigiPhoton* inGreen )
00186 {
00187 TVector3 x = inGreen->GetPos();
00188 TVector3 dir = inGreen->GetDir();
00189
00190
00191 if(dir.x()==0) return false;
00192 if(fabs(dir.x())>=1.) return true;
00193
00194 fGreen_Start = x;
00195
00196 int interact;
00197
00198 interact = PhotonUtil::InteractWithCylinder( x,dir,
00199 fFibreCoreRadius,
00200 fFibreIndex,
00201 fInnerCladdingIndex);
00202 if(interact==-1) {
00203 MSG("Photon",Msg::kError) << "Didn't hit inner wall IsGreenTrapped(). Huh?!?" << endl;
00204 };
00205 fGreen_InnerHit = x;
00206 if(interact==1) {
00207
00208 fGreen_OuterHit = x;
00209 return true;
00210 }
00211
00212
00213
00214 interact = PhotonUtil::InteractWithCylinder( x,dir,
00215 fInnerCladdingRadius,
00216 fInnerCladdingIndex,
00217 fOuterCladdingIndex);
00218 if(interact==-1) {
00219 MSG("Photon",Msg::kError) << "Didn't hit outer wall IsGreenTrapped(). Huh?!?" << endl;
00220 };
00221 fGreen_OuterHit = x;
00222
00223 if(interact==0) return false;
00224 return true;
00225 }
00226
00228 Bool_t
00229 PhotonFullFibreModel::FibreHitToGreenPhoton( const UgliStripHandle& inStrip,
00230 StripEnd::StripEnd_t inDirection,
00231 DigiPhoton* inBluePhoton,
00232 DigiPhoton* &outGreenPhoton
00233 )
00234 {
00235
00236
00237
00238
00239 fLastResult = -1;
00240
00241 outGreenPhoton = NULL;
00242 if(!inBluePhoton) { return false; };
00243
00244 TVector3 flashPos;
00245 fLastResult = FindBlueAbsorptionPosition( inStrip,
00246 inBluePhoton,
00247 flashPos );
00248
00249 if(fLastResult !=0 ) return false;
00250
00251
00252
00253
00254
00255
00256
00257 if(outGreenPhoton) delete outGreenPhoton;
00258 outGreenPhoton = MakeGreenPhoton( inBluePhoton,
00259 flashPos,
00260 inDirection);
00261
00262 if(!outGreenPhoton) return false;
00263
00264 if(IsGreenTrapped(outGreenPhoton)) return true;
00265
00266
00267 return false;
00268 }
00269
00270
00271