00001 #include <cassert>
00002 #include <iostream>
00003
00004 #include "ShowerTrace.h"
00005
00006 #include "MessageService/MsgService.h"
00007 #include "AtNuEvent/AtmosShower.h"
00008
00009 #include <cmath>
00010
00011 static const double C45 = sqrt(2.) / 2.;
00012 static const double HalfSideL = 4. / (1. + sqrt(2.));
00013
00014 static const double MaxPossibleTrace = 15.3;
00015 static const double MaxPossibleTraceZ = 14.7;
00016
00017
00018
00019 static const double SM1EdgesZ[2] = { 0.00, 14.75};
00020 static const double SM2EdgesZ[2] = {15.96, 29.94};
00021
00022 CVSID("$Id: ShowerTrace.cxx,v 1.3 2009/02/13 15:03:01 blake Exp $");
00023
00024 void ShowerTrace::Zero() {
00025 Side = -1;
00026 for(int i=0;i<3;i++) TraceVtx[i] = 0.;
00027
00028 Trace = MaxPossibleTrace;
00029 TraceZ = MaxPossibleTraceZ;
00030
00031 ReSide = -1;
00032 for(int i=0;i<3;i++) ReTraceVtx[i] = 0.;
00033 ReTrace = MaxPossibleTrace;
00034 ReTraceZ = MaxPossibleTraceZ;
00035
00036 UpSide = -1;
00037 for(int i=0;i<3;i++) UpTraceVtx[i] = 0.;
00038 UpTrace = MaxPossibleTrace;
00039 UpTraceZ = MaxPossibleTraceZ;
00040 }
00041
00042 void ShowerTrace::Fill(const AtmosShower *shower) {
00043 if(!shower) return;
00044
00045 const double ShwVtxX = shower->VtxX;
00046 const double ShwVtxY = shower->VtxY;
00047 const double ShwVtxZ = shower->VtxZ;
00048 const double ShwVtxU = shower->VtxU;
00049 const double ShwVtxV = shower->VtxV;
00050 const double ShwVtxL[4] = {ShwVtxV,ShwVtxY,ShwVtxU,ShwVtxX};
00051 const int ShwVtxSM = 1 + (shower->VtxPlane/249);
00052
00053
00054 if (fabs(ShwVtxU) > 4.0 ||
00055 fabs(ShwVtxV) > 4.0 ||
00056 fabs(ShwVtxX) > 4.0 ||
00057 fabs(ShwVtxY) > 4.0) {
00058 double ShwVtx[3] = {ShwVtxX, ShwVtxY, ShwVtxZ};
00059 for (int i=0;i<3;i++) {
00060 TraceVtx[i] = ShwVtx[i];
00061 ReTraceVtx[i] = ShwVtx[i];
00062 UpTraceVtx[i] = ShwVtx[i];
00063 }
00064 Trace = 0.; TraceZ = 0.;
00065 ReTrace = 0.; ReTraceZ = 0.;
00066 UpTrace = 0.; UpTraceZ = 0.;
00067
00068 return;
00069 }
00070
00071 const double ShwCosX = shower->VtxDirCosX;
00072 const double ShwCosY = shower->VtxDirCosY;
00073 const double ShwCosZ = shower->VtxDirCosZ;
00074 const double ShwCosU = shower->VtxDirCosU;
00075 const double ShwCosV = shower->VtxDirCosV;
00076 const double ShwCosL[4] = {ShwCosV,ShwCosY,ShwCosU,ShwCosX};
00077
00078 double ZProj(0.), OProj(0.), Wall(0.);
00079
00080
00081 int i = 0;
00082
00083 for (i=0; i<4; i++) {
00084 if(fabs(ShwCosL[i]) < 1.e-6) continue;
00085 Wall = ShwCosL[i] > 0.0 ? 4.0 : -4.0;
00086 int j = i<2 ? i+2 : i-2;
00087
00088
00089
00090
00091 OProj = ShwVtxL[j] + (ShwCosL[j]/ShwCosL[i])*(Wall-ShwVtxL[i]);
00092 if(fabs(OProj) > HalfSideL) continue;
00093
00094
00095 ZProj = ShwVtxZ + (ShwCosZ/ShwCosL[i])*(Wall-ShwVtxL[i]);
00096 break;
00097 }
00098
00099
00100
00101 if ((i>3) || (ZProj<SM1EdgesZ[0]) || (ZProj>SM2EdgesZ[1]) ||
00102 (ZProj>SM1EdgesZ[1] && ShwVtxZ < SM1EdgesZ[1]) ||
00103 (ZProj<SM2EdgesZ[0] && ShwVtxZ > SM2EdgesZ[0])) {
00104
00105 if(ShwCosZ<0.0 && ShwVtxSM==1) {
00106 TraceVtx[2] = SM1EdgesZ[0];
00107 Side = 8;
00108 }
00109
00110 else if(ShwCosZ>0.0 && ShwVtxSM==1) {
00111 TraceVtx[2] = SM1EdgesZ[1];
00112 Side = 9;
00113 }
00114
00115 else if(ShwCosZ<0.0 && ShwVtxSM==2) {
00116 TraceVtx[2] = SM2EdgesZ[0];
00117 Side = 10;
00118 }
00119
00120 else if(ShwCosZ>0.0 && ShwVtxSM==2) {
00121 TraceVtx[2] = SM2EdgesZ[1];
00122 Side = 11;
00123 }
00124
00125 else {
00126 MSG("ShowerTrace", Msg::kError) << "WTF, puking on shoes" << endl;
00127 assert(false);
00128 }
00129 TraceVtx[0] = ShwVtxX + (ShwCosX/ShwCosZ)*(TraceVtx[2]-ShwVtxZ);
00130 TraceVtx[1] = ShwVtxY + (ShwCosY/ShwCosZ)*(TraceVtx[2]-ShwVtxZ);
00131 }
00132 else {
00133 TraceVtx[2] = ZProj;
00134 Side = ShwCosL[i] > 0.0 ? i : i+4;
00135 switch(i) {
00136
00137 case 0:
00138 TraceVtx[0] = C45 * (OProj - Wall);
00139 TraceVtx[1] = C45 * (OProj + Wall);
00140 break;
00141
00142 case 1:
00143 TraceVtx[1] = Wall;
00144 TraceVtx[0] = OProj;
00145 break;
00146
00147 case 2:
00148 TraceVtx[0] = C45 * (Wall - OProj);
00149 TraceVtx[1] = C45 * (Wall + OProj);
00150 break;
00151
00152 case 3:
00153 TraceVtx[1] = OProj;
00154 TraceVtx[0] = Wall;
00155 break;
00156
00157 default:
00158 MSG("ShowerTrace", Msg::kError) << "WTF, puking on shoes" << endl;
00159 assert(false);
00160 break;
00161 }
00162 }
00163 Trace = sqrt(
00164 (TraceVtx[0]-ShwVtxX)*(TraceVtx[0]-ShwVtxX) +
00165 (TraceVtx[1]-ShwVtxY)*(TraceVtx[1]-ShwVtxY) +
00166 (TraceVtx[2]-ShwVtxZ)*(TraceVtx[2]-ShwVtxZ));
00167 TraceZ = fabs(TraceVtx[2] - ShwVtxZ);
00168
00169
00170
00171 for (i=0; i<4; i++) {
00172 if(fabs(ShwCosL[i]) < 1.e-6) continue;
00173 Wall = ShwCosL[i] > 0.0 ? -4.0 : 4.0;
00174 int j = i<2 ? i+2 : i-2;
00175
00176
00177 OProj = ShwVtxL[j] + (ShwCosL[j]/ShwCosL[i])*(Wall-ShwVtxL[i]);
00178 if(fabs(OProj) > HalfSideL) continue;
00179 ZProj = ShwVtxZ + (ShwCosZ/ShwCosL[i])*(Wall-ShwVtxL[i]);
00180 break;
00181 }
00182
00183 if ((i>3) || (ZProj<SM1EdgesZ[0]) || (ZProj>SM2EdgesZ[1]) ||
00184 (ZProj>SM1EdgesZ[1] && ShwVtxZ < SM1EdgesZ[1]) ||
00185 (ZProj<SM2EdgesZ[0] && ShwVtxZ > SM2EdgesZ[0])) {
00186
00187 if(ShwCosZ>0.0 && ShwVtxSM==1) {
00188 ReTraceVtx[2] = SM1EdgesZ[0];
00189 ReSide = 8;
00190 }
00191
00192 else if(ShwCosZ<0.0 && ShwVtxSM==1) {
00193 ReTraceVtx[2] = SM1EdgesZ[1];
00194 ReSide = 9;
00195 }
00196
00197 else if(ShwCosZ>0.0 && ShwVtxSM==2) {
00198 ReTraceVtx[2] = SM2EdgesZ[0];
00199 ReSide = 10;
00200 }
00201
00202 else if(ShwCosZ<0.0 && ShwVtxSM==2) {
00203 ReTraceVtx[2] = SM2EdgesZ[1];
00204 ReSide = 11;
00205 }
00206
00207 else {
00208 MSG("ShowerTrace", Msg::kError) << "WTF, puking on shoes" << endl;
00209 assert(false);
00210 }
00211 ReTraceVtx[0] = ShwVtxX + (ShwCosX/ShwCosZ)*(TraceVtx[2]-ShwVtxZ);
00212 ReTraceVtx[1] = ShwVtxY + (ShwCosY/ShwCosZ)*(TraceVtx[2]-ShwVtxZ);
00213 }
00214 else {
00215 ReTraceVtx[2] = ZProj;
00216 ReSide = ShwCosL[i] < 0.0 ? i : i+4;
00217 switch(i) {
00218
00219 case 0:
00220 ReTraceVtx[0] = C45 * (OProj - Wall);
00221 ReTraceVtx[1] = C45 * (OProj + Wall);
00222 break;
00223
00224 case 1:
00225 ReTraceVtx[1] = Wall;
00226 ReTraceVtx[0] = OProj;
00227 break;
00228
00229 case 2:
00230 ReTraceVtx[0] = C45 * (Wall - OProj);
00231 ReTraceVtx[1] = C45 * (Wall + OProj);
00232 break;
00233
00234 case 3:
00235 ReTraceVtx[1] = OProj;
00236 ReTraceVtx[0] = Wall;
00237 break;
00238
00239 default:
00240 MSG("ShowerTrace", Msg::kError) << "WTF, puking on shoes" << endl;
00241 assert(false);
00242 break;
00243 }
00244 }
00245 ReTrace = sqrt(
00246 (ReTraceVtx[0]-ShwVtxX)*(ReTraceVtx[0]-ShwVtxX) +
00247 (ReTraceVtx[1]-ShwVtxY)*(ReTraceVtx[1]-ShwVtxY) +
00248 (ReTraceVtx[2]-ShwVtxZ)*(ReTraceVtx[2]-ShwVtxZ));
00249 ReTraceZ = fabs(ReTraceVtx[2] - ShwVtxZ);
00250
00251
00252
00253 if (TraceVtx[1] >= ReTraceVtx[1]) {
00254 for(int j=0; j<3; j++) UpTraceVtx[j] = TraceVtx[j];
00255 UpTrace = Trace;
00256 UpTraceZ = TraceZ;
00257 UpSide = Side;
00258 }
00259 else {
00260 for(int j=0; j<3; j++) UpTraceVtx[j] = ReTraceVtx[j];
00261 UpTrace = ReTrace;
00262 UpTraceZ = ReTraceZ;
00263 UpSide = ReSide;
00264 }
00265 }