FlyoDoc_2011 Pisa 2011 by GmP --- 011
|
00001 /*************************************************************************** 00002 devmagn.cpp - description 00003 ------------------- 00004 begin : Sat May 26 2001 00005 copyright : (C) 2001 by Giuseppe Pierazzini 00006 email : peppe@unipi.it 00007 *************************************************************************** 00008 * * 00009 * NA48 simulation program. * 00010 * * 00011 ***************************************************************************/ 00012 #define ESTERNO 1 00013 #define INTERNO 0 00014 #define INBUCO -1 00015 #define EPSR 1.0E-3 00016 #define MAXITER 500 00017 00018 #include "parm.h" 00019 #include "part_db.h" 00020 #include "evento.h" 00021 #include "particella.h" 00022 #include "reazione.h" 00023 #include "devmagn.h" 00024 00025 using namespace std; 00026 00027 DevMagn::DevMagn() 00028 { 00029 devtype=TypDevMagn; 00030 devclass="NA62 Experimental Magnet"; 00031 fun=Magn; 00032 Gout<<"\n\n < "<<nome <<" > Dev Id "<<idev<<" Device type <"<<devclass<<"> typ "<<devtype; 00033 // campo costante campo=0 default; 00034 // campo variabile campo>0; Definire.... ricorda! 00035 campo=0; 00036 } 00037 00038 00039 DevMagn::~DevMagn() 00040 {} 00041 00042 // in Gvect.h e' definita l'algebra per i vettori (gvet)) 3d.... 00043 // vettori di giuseppe 00044 //=============================================================== 00045 //=================DevMagn============================== 00046 //----------------- -------- 00047 void DevMagn::Prgeom() 00048 { 00049 Gout<<"================== R i v e l a t o r e ================="; 00050 Gout<<"\n --> < "<<nome <<" > [ "<<fun 00051 <<" ] Magnete rettang. con buco rettang."; 00052 Device::Prgeom(); 00053 Gout<<std::endl; 00054 } 00055 //====================================================== 00056 // ======= Magnet tracking 00057 00058 // vettori ==> gvet VW,PL,PT,X,XIN,PIN,P,KIK,RHO,CRHO; 00059 00060 int DevMagn::Traccia(Particella *pr) 00061 { 00062 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 // note 2007 the field is in the hole! 00077 00078 const double ec=2.99792458e-7; 00079 00080 00081 00082 if(nowpos==ESTERNO) return Device::Traccia(pr); // se esterno traccia regolarmente... 00083 else if(nowpos==INTERNO) 00084 { // se interno (!no nel buco) traccio regolarmente per i mu.. le altre particelle sono perse... 00085 if (pr->Get_Nome()==Mum||pr->Get_Nome()==Mup) return Device::Traccia(pr); 00086 else return -1; // traccia lost in the frame 00087 } 00088 if (pr->P.norma == 0.0) return 0; // no motion .... 00089 if (pr->Get_Charg() == 0.0) return Device::Traccia(pr); // neutra traccio regolamente dritto 00090 00091 00092 //------------ tracing in the field.... 00093 X=Lab2cDev(pr->X); // Coordinata di impatto sul dev 00094 PIN=Puls=Lab2Dev(pr->P); // impulso vettore in device.... 00095 VSIN=Pvers=Puls.Verso(); 00096 XIN=X; // device frame coordinates 00097 vol_max=pr->pathok; // cammino potenziale prima di decadere! 00098 P_Cin=X-Centrin; //Occorre in Get_CamMag(), specie per buchi non simmetrici 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 00104 /* Campo in Field 00105 campo=0 B field costante (va definito nella classe) 00106 campo>0 B field variabile 00107 */ 00108 if(campo==0) 00109 { 00110 if (Field.norma == 0.0) 00111 { 00112 Gout<<"\n *** error*** Standard magnet "<<nome<<" null field???"; 00113 exit(0); 00114 } 00115 } 00116 // se variabile ridefinisco il campo iniziale 00117 else Get_Field(P_Cin); 00118 00119 00120 // nota il sistema di riferimento dei vettori e' quello del dev. 00121 // predico il raggio di curvatura.... massimo... 00122 rho= 9999999. ; 00123 if(Field.norma>0.0001)rho = Puls.Norma()/(ec*Field.norma); 00124 00125 // il calcolo corretto e' rho= (P&H).Norma/(H_norma**2*ec) 00126 00127 if(Debugon==1) 00128 00129 // if( (idev==9||idev==10)&&pr->Get_Idm()==14) 00130 {// ok nel caso di campo costante ==> valore significativo 00131 double forkik=ec*Field.norma*cam_max*pr->Get_Charg(); 00132 Gout<<"\n\n Traccia Ev=" 00133 <<setprecision(0)<<fixed 00134 <<setw(6)<<Eventi_Fatti<<" " 00135 <<setw(6)<<pr->Get_Nome()<<" in" 00136 <<setw(6)<<nome<<" pth=" 00137 <<setprecision(1)<<fixed 00138 <<setw(7)<<pr->pathok<<" Cmx=" 00139 <<setw(7)<<cam_max<<" rho=" 00140 <<setw(7)<<rho<<" kik=" 00141 <<setprecision(4)<<fixed 00142 <<setw(6)<<forkik; 00143 Field.print("Field"); 00144 X.print("X_in"); 00145 PIN.print("p_in"); 00146 } 00147 /*************/ 00148 if(rho<2.*freestep) return 1; // la particella resta intrappolata.... 00149 00150 // definizione dello step. 00151 00152 step =rho/3000.; 00153 // if(step<0.04)step=0.04; 00154 double stepmin=freestep/400.; 00155 00156 if(step<stepmin)step=stepmin; 00157 else if(step>3.)step=3.; 00158 if(step>freestep) step= freestep+0.01; 00159 00160 00161 dse = step*ec*pr->Get_Charg(); 00162 path=0.0; 00163 iter_mag=0; 00164 00165 // tracing main loop ======================= 00166 while (iter_mag++<MAXITER) 00167 { 00168 if(campo>0) Get_Field(P_Cin); //variabile 00169 00170 /* 00171 evento_.Event,nome,pr->Get_Nome(),pr->pathok,cam_max,rho); 00172 Pvers.print("pvers"); 00173 P_Cin.print(pr->Get_Nome()); 00174 Field.print("Field") 00175 */ 00176 00177 Puls+= Pvers&Field * dse; // Aggiorno P dopo un cammino ds 00178 Pvers=Puls.NVerso(); // calcola la nuova direzione di volo 00179 P_Cin+= step*Pvers; // aggiorno la posizione 00180 path+=step; // aggiorno il cammino 00181 00182 // check for end iteration... 00183 if(step>freestep) break; // decaduta...o uscita dal mag... 00184 freestep-=step; //aggiorno il cammino da fare 00185 00186 // test if still inside!!Rectangular shape ! for different shape not yet implemented 00187 if (fabs(P_Cin[0])> Lin[0] || fabs(P_Cin[1])> Lin[1] ||fabs(P_Cin[2])> Lin[2]) break; 00188 00189 /*{ 00190 if(idev==36) 00191 { 00192 P_Cin.print("X1");Gout<<" Ev "<<evento_.Event<<" iter "<<iter_mag; 00193 } 00194 00195 break; 00196 }*/ 00197 00198 if(step>freestep) // se supero con uno step il cammino restante allora... 00199 { 00200 00201 // allora calcolo il cammino potenziale restante... 00202 freestep=Get_CamMag(); 00203 if(freestep>vol_max-path)freestep=vol_max-path; 00204 if(step>freestep) 00205 { 00206 step= freestep+0.01; 00207 if(step<0.05)break; 00208 dse = step*ec*pr->Get_Charg(); 00209 } 00210 } 00211 00212 00213 } 00214 00215 00216 00217 // tracing end ==================================== 00218 00219 00220 00222 // ===> go back to the apparatus system 00223 00224 pr->P.setvn(Dev2Lab(Puls),pr->Get_Massa()); // nota calcola anche la norma 00225 pr->Vers=pr->P.Verso(); 00226 X=P_Cin+Centrin; 00227 pr->X=Devc2Lab(X)+ 0.01*pr->Vers; // non norma... + piccolo spostamento 00228 00229 pr->pathok=path; 00230 pr->path_done+=path; 00231 00232 // si deve tener conto del multiploscattering ?? 00233 Mscatter(pr,path); 00234 00235 00236 00237 if (iter_mag> 400) 00238 { 00239 00240 Gout<<"\n\n Even="<<evento_.Gen.Event<<" "<<nome 00241 <<" iter "<<iter_mag<<" for "<< pr->Get_Nome()<< " P_norma "<< pr->P.norma 00242 <<" Camx "<< cam_max<<" rho="<<rho<<" step "<<step; 00243 KIK=Puls-PIN; 00244 Devc2Lab(XIN).print("Xin"); 00245 pr->X.print("Xout"); 00246 PIN.print("Pin"); 00247 Puls.print("Pout"); 00248 KIK.Norma(); 00249 KIK.print("KIK"); 00250 // Field.print("Last Field"); 00251 Gout<<"\n "<<nome<<" for "<<pr->Get_Nome()<<" Zstp=" 00252 <<setprecision(2)<<fixed 00253 <<setw(6)<<freestep<<" Path=" 00254 <<setprecision(1)<<fixed 00255 <<setw(7)<<path<<" Iter=" 00256 <<setw(5)<<iter_mag<<" end tracing"<<std::endl; 00257 00258 return (1); 00259 } 00260 00261 /*****************************/ 00262 if(Debugon==1) 00263 { 00264 KIK=Puls-PIN; 00265 Devc2Lab(XIN).print("Xin"); 00266 pr->X.print("Xout"); 00267 PIN.print("Pin"); 00268 Puls.print("Pout"); 00269 KIK.Norma(); 00270 KIK.print("KIK"); 00271 // Field.print("Last Field"); 00272 Gout<<"\n "<<nome<<" for "<<pr->Get_Nome()<<" Zstp=" 00273 <<std::setprecision(2)<<fixed 00274 <<setw(6)<<freestep<<" Path=" 00275 <<setprecision(1)<<fixed 00276 <<setw(7)<<path<<" Iter=" 00277 <<setw(5)<<iter_mag<<" end tracing"<<std::endl; 00278 } 00279 /*****************************/ 00280 00281 00282 return (0); 00283 } 00284 //================== 00285 00286 double DevMagn::Get_CamMag() 00287 { 00288 // Calcolo il cammino fino alla prima superficie di uscita. 00289 // mi riferisco al centro del buco interno 00290 // il punto deve essere interno al buco!!!! 00291 // P_Cin=X-Centrin; gia' definito prima di chiamare 00292 00293 00294 Dind=P_Cin-Lin; 00295 Dins=-(Lin+P_Cin); 00296 V_dev=Pvers; 00297 00298 00299 00300 return(CamBuco() ); 00301 } 00302 00303 00304 00305