FlyoDoc_2011 Pisa 2011 by GmP --- 011
|
00001 /*************************************************************************** 00002 devflt - description 00003 ------------------- 00004 begin : Sun Aug 15 2004 00005 copyright : (C) 2004 by gmp 00006 email : peppe@newpeppe 00007 *************************************************************************** 00008 * * 00009 * NA48 simulation program. * 00010 * * 00011 ***************************************************************************/ 00012 00013 #define ESTERNO 1 00014 #define INTERNO 0 00015 #define INBUCO -1 00016 #define EPSR 1.0E-3 00017 #define MAXITER 500 00018 00019 #include "parm.h" 00020 #include "evento.h" 00021 #include "particella.h" 00022 #include "reazione.h" 00023 #include "devflt.h" 00024 00025 using namespace std; 00026 00027 DevFlt::DevFlt() 00028 : DevRtCl() 00029 { 00030 devtype=TypDevFlt; 00031 devclass="Magn_Filter"; 00034 // campo costante campo=0 default; 00035 // campo variabile campo>0; Definire.... ricorda! 00036 campo=0; 00037 } 00038 00039 00040 DevFlt::~DevFlt() 00041 { 00042 } 00043 00044 //----------------- -------- 00045 void DevFlt::Prgeom() 00046 { 00047 00048 Gout<<"================== R i v e l a t o r e ================="; 00049 Gout<<"\n --> < "<<nome <<" > [ "<<fun 00050 <<" ] Mag in FE con buco cilindrico senza campo."<<std::endl; 00051 Device::Prgeom(); 00052 Gout<<"\n"; 00053 } 00054 //====================================================== 00055 // ======= Magnet tracking 00056 00057 // vettori ==> gvet VW,PL,PT,X,XIN,PIN,P,KIK,RHO,CRHO; 00058 00059 int DevFlt::Traccia(Particella *pr) 00060 { 00061 00062 // see the DevMagn:: Traccia() 00063 // 18/03/03 update: general tracing.. the magnetic field now could be variable 00064 // and without any restriction.. 00065 // attention! inside the magnet no brems, nor pairprod for the moment.. 00066 // the track tracing is iterative with step size small enough to keep the 00067 // tracing errors to very low values 00068 // 00069 //***** 00070 // La carica elementare nel sistema Ibrido e' 00071 // ec=.299792458[ Gev/c * T**(-1) m **(-1) ] 00072 // va qui moltiplicata per 10e-6 poiche' 00073 // si usa il Gauss ed il Centimetro; segue... 00074 // r(cm)=[p cos(lambda)(GeV)]/(2.9979258e-7 * H(Gauss) ) 00075 00076 const double ec=2.99792458e-7; 00077 //**** 00078 00079 00080 // qui il campo è differente da zero solo nel ferro... il campo nel buco è nullo!!! 00081 // si vuole filtrare via i muoni.... 00082 00083 if(nowpos==ESTERNO || nowpos==INBUCO) // se esterno o nel buco traccia regolarmente... 00084 { Device::Traccia(pr); return 0;} 00085 // allora e' INTERNO: si traccia in campo magnetico. 00086 if (pr->P.norma == 0.0) return 0; // no motion .... 00087 if (pr->Get_Charg() == 0.0) // neutra traccio regolamente 00088 { Device::Traccia(pr); return 0;} 00089 00090 00091 //------------ 00092 X=Lab2cDev(pr->X); // Coordinata di impatto sul dev 00093 PIN=Puls=Lab2Dev(pr->P); // impulso vettore in device.... 00094 VSIN=Pvers=Puls.Verso(); 00095 XIN=X; // device frame coordinates 00096 vol_max=pr->pathok; // cammino potenziale prima di decadere! 00097 // P_Cin=X-Centrin; //Occorre in Get_CamMag(), specie per buchi non simmetrici 00098 P_Cin=X; 00099 freestep=cam_max=Get_CamMag(); // cammino potenziale in linea retta per uscire dal magnete 00100 if(freestep>vol_max) freestep=vol_max; 00101 00102 00103 /* Campo in Field 00104 campo=0 B field costante (va definito nella classe) 00105 campo>0 B field variabile 00106 */ 00107 if(campo==0) 00108 { 00109 if (Field.norma == 0.0) 00110 { Gout<<"\n *** error*** Standard magnet "<<nome<<" null field???"; 00111 exit(0);} 00112 } 00113 // se variabile ridefinisco il campo iniziale 00114 else Get_Field(P_Cin); 00115 00116 00117 // nota il sistema di riferimento dei vettori e' quello del dev. 00118 // predico il raggio di curvatura.... massimo... 00119 rho= 9999999. ; 00120 if(Field.norma>0.0001)rho = Puls.Norma()/(ec*Field.norma); 00121 00122 // il calcolo corretto e' rho= (P&H).Norma/(H_norma**2*ec) 00123 00124 00125 /*************/ 00126 if(rho<2.*freestep) return 1; // la particella resta intrappolata.... 00127 00128 // definizione dello step. 00129 step =rho/3000.; 00130 if(step<2.)step=2.; 00131 else if(step>25.)step=25.; 00132 if(step>freestep) step= freestep+0.04; 00133 dse = step*ec*pr->Get_Charg(); 00134 path=0.0; 00135 iter_mag=0; 00136 00137 00138 00139 00140 if(Debugon==1) 00141 {// ok nel caso di campo costante ==> valore significativo 00142 double forkik=ec*Field.norma*cam_max*pr->Get_Charg(); 00143 Gout<<"\n\n Ev="<<evento_.Gen.Event<<" "<<pr->Get_Nome()<<" in "<<nome 00144 <<" pathok="<<pr->pathok<<" Cammx="<< cam_max 00145 <<" freestep "<<freestep 00146 <<" Kik="<<forkik<<" rho="<<rho; 00147 Field.print("Field"); 00148 00149 } 00150 00151 00152 00153 00154 // tracing main loop ======================= 00155 while (iter_mag++<MAXITER) 00156 { 00157 if(campo>0) Get_Field(P_Cin); //variabile 00158 00159 /* 00160 00161 evento_.Event,nome,pr->Get_Nome(),pr->pathok,cam_max,rho); 00162 Pvers.print("pvers"); 00163 P_Cin.print(pr->Get_Nome()); 00164 Field.print("Field"); 00165 */ 00166 00167 Puls+= Pvers&Field * dse; // Aggiorno P dopo un cammino ds 00168 Pvers=Puls.NVerso(); // calcola la nuova direzione di volo 00169 P_Cin+= step*Pvers; // aggiorno la posizione 00170 path+=step; // aggiorno il cammino 00171 00172 // check for end iteration... 00173 if(step>freestep) break; // decaduta...o uscita dal mag... 00174 freestep-=step; //aggiorno il cammino da fare 00175 00176 if (fabs(X[0])> Lout[0] || fabs(X[1])> Lout[1] ||fabs(X[2])> Lout[2]) break; 00177 00178 // if (fabs(P_Cin[0])> Loin[0] || fabs(P_Cin[1])> Lin[1] ||fabs(P_Cin[2])> Lin[2]) break; 00179 00180 00181 if(step>freestep) // se supero con uno step il cammino restante allora... 00182 { 00183 // allora calcolo il cammino potenziale restante... 00184 freestep=Get_CamMag(); 00185 if(freestep>vol_max-path)freestep=vol_max-path; 00186 if(step>freestep) 00187 {step= freestep+0.04; 00188 if(step<0.06) break; 00189 dse = step*ec*pr->Get_Charg(); 00190 } 00191 } 00192 00193 00194 } 00195 00196 00197 00198 // tracing end ==================================== 00199 00200 if (iter_mag> 499) 00201 { 00202 Gout<<"\n\n Ev="<<evento_.Gen.Event<<" Trac. in "<<nome 00203 <<" iter "<<iter_mag<<" for "<< pr->Get_Nome()<< " P norma "<< pr->P.norma 00204 <<" camx "<< cam_max<<" rho="<<rho<<" step "<<step; 00205 return (1); 00206 } 00207 00209 // ===> go back to the apparatus system 00210 00211 pr->P.setvn(Dev2Lab(Puls),pr->Get_Massa()); // nota calcola anche la norma 00212 pr->Vers=pr->P.Verso(); 00213 X=P_Cin+Centrin; 00214 pr->X=Devc2Lab(X)+ 0.01*pr->Vers; // non norma... + piccolo spostamento 00215 00216 pr->pathok=path; 00217 pr->path_done+=path; 00218 00219 /*****************************/ 00220 if(Debugon==1) 00221 { 00222 KIK=Puls-PIN; 00223 Devc2Lab(XIN).print("Xin"); 00224 pr->X.print("Xout"); 00225 PIN.print("Pin"); 00226 Puls.print("Pout"); 00227 KIK.Norma(); 00228 KIK.print("KIK"); 00229 // Field.print("Last Field"); 00230 Gout<<"\n.. "<< nome <<" for "<<pr->Get_Nome()<<" Patok="<<freestep<<" Path " 00231 <<path<<" Iter="<< iter_mag<<std::endl; 00232 } 00233 /*****************************/ 00234 00235 00236 return (0); 00237 } 00238 //================== 00239 00240 double DevFlt::Get_CamMag() 00241 { 00242 // Calcolo il cammino fino alla prima superficie di uscita. 00243 // dall'interno del dev 00244 // (In particolare qui il punto del mu deve essere interno nel ferro!!!! 00245 // P_Cin=X-Centrin; gia' definito prima di chiamare 00246 Dind=P_Cin-Lin; 00247 Dins=-(Lin+P_Cin); 00248 V_dev=Pvers; 00249 return(CamInter() ); 00250 } 00251 00252 00253 00254 00255