00001
00002 #ifndef __CINT__
00003 #include <TRandom3.h>
00004 #include <TROOT.h>
00005 #include <TH1.h>
00006 #include <TMath.h>
00007 #include <TGeoManager.h>
00008 #include <TGeoVolume.h>
00009 #include <TGeoPcon.h>
00010 #include <TGeoMatrix.h>
00011 #include <TBenchmark.h>
00012 #include <TApplication.h>
00013
00014 void stressShapes();
00015
00016 int main(int argc, char **argv)
00017 {
00018 TApplication theApp("App", &argc, argv);
00019 stressShapes();
00020 return 0;
00021 }
00022
00023 #endif
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 void sample_volume(Int_t ivol)
00041 {
00042 const Double_t vshape[16] = {40000.0, 36028.3, 39978.70, 48001.3, 28481.2,
00043 8726.2, 42345.4, 9808.2, 12566.8, 64655.6, 37730.4, 23579.7,
00044 25559.5, 18418.3, 49960.2, 47771.1};
00045 gRandom = new TRandom3();
00046 TGeoVolume *vol = (TGeoVolume*)gGeoManager->GetListOfVolumes()->At(ivol);
00047 TGeoShape *shape = vol->GetShape();
00048 Double_t dx = ((TGeoBBox*)shape)->GetDX();
00049 Double_t dy = ((TGeoBBox*)shape)->GetDY();
00050 Double_t dz = ((TGeoBBox*)shape)->GetDZ();
00051 Double_t ox = (((TGeoBBox*)shape)->GetOrigin())[0];
00052 Double_t oy = (((TGeoBBox*)shape)->GetOrigin())[1];
00053 Double_t oz = (((TGeoBBox*)shape)->GetOrigin())[2];
00054 Double_t ratio;
00055 Double_t point[3];
00056 Double_t ngen=1000000;
00057 Double_t iin=0;
00058 Double_t i;
00059 for (i=0; i<ngen; i++) {
00060 point[0] = ox-dx+2*dx*gRandom->Rndm();
00061 point[1] = oy-dy+2*dy*gRandom->Rndm();
00062 point[2] = oz-dz+2*dz*gRandom->Rndm();
00063 if (shape->Contains(point)) iin++;
00064 }
00065 ratio = Double_t(iin)/Double_t(ngen);
00066 Double_t vbox = 8*dx*dy*dz;
00067 Double_t vv = vbox*ratio;
00068 Double_t dvv = TMath::Abs(vv-vshape[ivol-1]);
00069 Double_t sigma = vv/TMath::Sqrt(iin+1);
00070 char result[16];
00071 sprintf(result, "FAILED");
00072 if (dvv<2*sigma) sprintf(result, "OK");
00073 printf("---> testing %-4s ............... %s\n", vol->GetName(), result);
00074 }
00075
00076 void length()
00077 {
00078 const Double_t rms[16] = {6.284, 10.79, 9.545, 14.15, 11.45,
00079 5.871, 7.673, 5.935, 7.61, 5.334, 6.581, 4.954,
00080 7.718, 3.238, 19.09, 14.77};
00081 const Double_t mean[16] = {19.34, 22.53, 18.87, 21.95, 23.29,
00082 16.73, 15.09, 9.516, 12.68, 8.852, 9.518, 7.432,
00083 8.881, 6.489, 28.29, 26.05};
00084 TObjArray *vlist = gGeoManager->GetListOfVolumes();
00085 TGeoVolume *volume;
00086 Int_t nvolumes = vlist->GetEntriesFast();
00087 Double_t len[17];
00088 TList *hlist = new TList();
00089 TH1F *hist;
00090 Int_t i=0;
00091 memset(len, 0, nvolumes*sizeof(Double_t));
00092 for (i=0; i<nvolumes; i++) {
00093 volume = (TGeoVolume*)(vlist->At(i));
00094 hist = new TH1F(volume->GetName(), "lengths inside", 100, 0, 100);
00095 hist->SetBit(TH1::kCanRebin);
00096 hlist->Add(hist);
00097 }
00098 Int_t nrays = 100000;
00099
00100 Double_t dir[3];
00101 TGeoNode *startnode, *endnode;
00102 Int_t istep=0, icrt;
00103 Int_t itot=0;
00104 Int_t n10=nrays/10;
00105
00106 Double_t theta,phi, step;
00107 while (itot<nrays) {
00108 itot++;
00109 if (n10) {
00110 if ((itot%n10) == 0) printf(" %i percent\n", Int_t(100*itot/nrays));
00111 }
00112 phi = 2*TMath::Pi()*gRandom->Rndm();
00113 theta= TMath::ACos(1.-2.*gRandom->Rndm());
00114 dir[0]=TMath::Sin(theta)*TMath::Cos(phi);
00115 dir[1]=TMath::Sin(theta)*TMath::Sin(phi);
00116 dir[2]=TMath::Cos(theta);
00117 gGeoManager->InitTrack(0,0,0, dir[0], dir[1], dir[2]);
00118 startnode = gGeoManager->GetCurrentNode();
00119 if (gGeoManager->IsOutside()) startnode=0;
00120 icrt = 0;
00121 if (startnode) icrt =vlist->IndexOf(startnode->GetVolume());
00122
00123 gGeoManager->FindNextBoundary();
00124 step = gGeoManager->GetStep();
00125 endnode = gGeoManager->Step();
00126 while (step<1E10) {
00127 while (!gGeoManager->IsEntering()) {
00128 istep++;
00129 if (istep>10000) break;
00130 gGeoManager->SetStep(1E-3);
00131 endnode = gGeoManager->Step();
00132 step += 1E-3;
00133 }
00134 if (istep>10000) break;
00135 len[icrt] += step;
00136 hist = (TH1F*)(hlist->At(icrt));
00137 hist->Fill(step);
00138
00139 if (endnode==0 && step>1E10) break;
00140 istep = 0;
00141
00142 startnode = endnode;
00143 icrt = 0;
00144 if (startnode) icrt =vlist->IndexOf(startnode->GetVolume());
00145 gGeoManager->FindNextBoundary();
00146 step = gGeoManager->GetStep();
00147 endnode = gGeoManager->Step();
00148 }
00149 }
00150
00151 Double_t drms, dmean;
00152 for (i=1; i<nvolumes; i++) {
00153 volume = (TGeoVolume*)(vlist->At(i));
00154 hist = (TH1F*)(hlist->At(i));
00155 char result[16];
00156 drms = TMath::Abs(rms[i-1]-hist->GetRMS());
00157 dmean = TMath::Abs(mean[i-1]-hist->GetMean());
00158 sprintf(result, "FAILED");
00159 if (dmean<0.01) {
00160 if (drms<0.01) sprintf(result,"OK");
00161 }
00162 printf(" %-4s : mean_len=%7.4g RMS=%7.4g total_len=%11.4g ... %s\n",
00163 volume->GetName(), hist->GetMean(), hist->GetRMS(), len[i],result);
00164 }
00165 hlist->Delete();
00166 delete hlist;
00167 }
00168
00169 void stressShapes()
00170 {
00171
00172
00173
00174
00175
00176
00177
00178 #ifdef __CINT__
00179 gSystem->Load("libGeom");
00180 #endif
00181
00182 gBenchmark = new TBenchmark();
00183 gBenchmark->Start("stressShapes");
00184
00185 TGeoManager *geom = new TGeoManager("stressShapes", "arbitrary shapes");
00186 TGeoMaterial *mat;
00187 TGeoMixture *mix;
00188
00189 mat = new TGeoMaterial("Vacuum",0,0,0);
00190 mat->SetUniqueID(0);
00191 mat = new TGeoMaterial("Be", 9.01,4,1.848);
00192 mat->SetUniqueID(1);
00193 mat = new TGeoMaterial("Al", 26.98,13,2.7);
00194 mat->SetUniqueID(2);
00195 mat = new TGeoMaterial("Fe", 55.85,26,7.87);
00196 mat->SetUniqueID(3);
00197 mat = new TGeoMaterial("Cu", 63.55,29,8.96);
00198 mat->SetUniqueID(4);
00199 mat = new TGeoMaterial("C",12.01,6,2.265);
00200 mat->SetUniqueID(5);
00201 mat = new TGeoMaterial("Pb",207.19,82,11.35);
00202 mat->SetUniqueID(6);
00203 mat = new TGeoMaterial("Si",28.09,14,2.33);
00204 mat->SetUniqueID(7);
00205 mix = new TGeoMixture("scint",2, 1.03200 );
00206 mix->DefineElement(0,1.008,1,0.7749078E-01);
00207 mix->DefineElement(1,12,6,0.9225092);
00208 mix->SetUniqueID(8);
00209 mat = new TGeoMaterial("Li",6.94,3,0.534);
00210 mat->SetUniqueID(9);
00211 mat = new TGeoMaterial("N",14.01,7,0.808);
00212 mat->SetUniqueID(10);
00213 mat = new TGeoMaterial("Ne",20.18,10,1.207);
00214 mat->SetUniqueID(11);
00215 mat = new TGeoMaterial("Ts",183.85,74,19.3);
00216 mat->SetUniqueID(12);
00217 mat = new TGeoMaterial("CFRP",12.01,6,2.3);
00218 mat->SetUniqueID(13);
00219 mix = new TGeoMixture("H2O",2, 1.00000 );
00220 mix->DefineElement(0,1.01,1,0.1120977);
00221 mix->DefineElement(1,16,8,0.8879023);
00222 mix->SetUniqueID(14);
00223 mix = new TGeoMixture("Ethane_Gas",2, 0.135600E-02);
00224 mix->DefineElement(0,12.01,6,0.7985373);
00225 mix->DefineElement(1,1.01,1,0.2014628);
00226 mix->SetUniqueID(15);
00227 mat = new TGeoMaterial("RHONEYCM",26.98,13,0.601);
00228 mat->SetUniqueID(16);
00229
00230 TGeoMedium *med0 = new TGeoMedium("Vacuum",0,0,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00231 TGeoMedium *med1 = new TGeoMedium("Be",1,1,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00232 TGeoMedium *med2 = new TGeoMedium("Al",2,2,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00233 TGeoMedium *med3 = new TGeoMedium("Fe",3,3,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00234 TGeoMedium *med4 = new TGeoMedium("Cu",4,4,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00235 TGeoMedium *med5 = new TGeoMedium("C",5,5,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00236 TGeoMedium *med6 = new TGeoMedium("Pb",6,6,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00237 TGeoMedium *med7 = new TGeoMedium("Si",7,7,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00238 TGeoMedium *med8 = new TGeoMedium("scint",8,8,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00239 TGeoMedium *med9 = new TGeoMedium("Li",9,9,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00240 TGeoMedium *med10 = new TGeoMedium("N",10,10,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00241 TGeoMedium *med11 = new TGeoMedium("Ne",11,11,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00242 TGeoMedium *med12 = new TGeoMedium("Ts",12,12,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00243 TGeoMedium *med13 = new TGeoMedium("CFRP",13,13,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00244 TGeoMedium *med14 = new TGeoMedium("H2O",14,14,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00245 TGeoMedium *med15 = new TGeoMedium("Ethane gas",15,15,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00246 TGeoMedium *med16 = new TGeoMedium("RHONEYCM",16,16,0,0,0,20,0.1000000E+11,0.212,0.1000000E-02,1.150551);
00247
00248
00249 TGeoVolume *TOP = geom->MakeBox("TOP", med0, 200, 200, 200);
00250 TGeoVolume *BOX = geom->MakeBox("BOX", med1, 10,20,25);
00251 TGeoVolume *TRD1 = geom->MakeTrd1("TRD1", med2, 20,10,20,15);
00252 TGeoVolume *TRD2 = geom->MakeTrd2("TRD2", med3, 20,5,10,25,25);
00253 TGeoVolume *PARA = geom->MakePara("PARA", med4, 10, 20, 30, 15, 15, 120);
00254 Double_t v[16];
00255 v[0]=-22; v[1]=-18; v[2]=-18; v[3]=22; v[4]=22; v[5]=18; v[6]=18; v[7]=-22;
00256 v[8]=-12; v[9]=-8; v[10]=-8; v[11]=12; v[12]=12; v[13]=8; v[14]=8; v[15]=-12;
00257 TGeoVolume *ARB8 = geom->MakeArb8("ARB8", med5, 15, v);
00258 TGeoVolume *SPHE = geom->MakeSphere("SPHE", med6, 5, 15, 45, 180, 0, 270);
00259 TGeoVolume *TUBE = geom->MakeTube("TUBE", med7, 20, 25, 30);
00260 TGeoVolume *TUBS = geom->MakeTubs("TUBS", med8, 10,15,20, 45, 270);
00261 TGeoVolume *ELTU = geom->MakeEltu("ELTU", med9, 10,20,10);
00262 TGeoVolume *CTUB = geom->MakeCtub("CTUB", med10, 25, 30, 50, 0,270, 0, 0.5, -0.5*TMath::Sqrt(3.),0.5,0,0.5*TMath::Sqrt(3.));
00263 TGeoVolume *CONE = geom->MakeCone("CONE", med11, 30, 25, 30, 10, 15);
00264 TGeoVolume *CONS = geom->MakeCons("CONS", med12, 30, 25, 30, 10, 15, -45, 180);
00265 TGeoVolume *PCON = geom->MakePcon("PCON", med13, 0, 360, 3);
00266 TGeoPcon *pcon = (TGeoPcon*)(PCON->GetShape());
00267 pcon->DefineSection(0,-25, 10, 15);
00268 pcon->DefineSection(1,0, 10, 15);
00269 pcon->DefineSection(2,25, 25, 30);
00270 TGeoVolume *PGON = geom->MakePgon("PGON", med14, 0, 270, 4, 3);
00271 pcon = (TGeoPcon*)(PGON->GetShape());
00272 pcon->DefineSection(0,-25, 10, 15);
00273 pcon->DefineSection(1,0, 10, 15);
00274 pcon->DefineSection(2,25, 15, 20);
00275 TGeoVolume *TRAP = geom->MakeTrap("TRAP", med15, 25, 15, 30, 20, 15,10,15, 20,15,10,15);
00276 TGeoVolume *GTRA = geom->MakeGtra("GTRA", med16, 25, 15, 30, 30, 20, 15,10,15, 20,15,10,15);
00277
00278 geom->SetTopVolume(TOP);
00279 TOP->AddNode(BOX, 1);
00280 TOP->AddNode(TRD1, 2, new TGeoTranslation(100, 0, 0));
00281 TOP->AddNode(TRD2, 3, new TGeoTranslation(-100, 0, 0));
00282 TOP->AddNode(PARA, 4, new TGeoTranslation(0, 100, 0));
00283 TOP->AddNode(ARB8, 5, new TGeoTranslation(0, -100, 0));
00284 TOP->AddNode(SPHE, 6, new TGeoTranslation(0, 0, 100));
00285 TOP->AddNode(TUBE, 7, new TGeoTranslation(0, 0, -100));
00286 TOP->AddNode(TUBS, 8, new TGeoTranslation(100, 0, 100));
00287 TOP->AddNode(ELTU, 9, new TGeoTranslation(100, 0, -100));
00288 TOP->AddNode(CTUB, 10, new TGeoTranslation(-100, 0, 100));
00289 TOP->AddNode(CONE, 11, new TGeoTranslation(-100, 0, -100));
00290 TOP->AddNode(CONS, 12, new TGeoTranslation(0, 100, 100));
00291 TOP->AddNode(PCON, 13, new TGeoTranslation(0, -100, 100));
00292 TOP->AddNode(PGON, 14, new TGeoTranslation(100, 100, 100));
00293 TOP->AddNode(TRAP, 15, new TGeoTranslation(-100, -100, -100));
00294 TOP->AddNode(GTRA, 16, new TGeoTranslation(100, 100, 0));
00295
00296 geom->CloseGeometry("d");
00297 geom->DefaultColors();
00298
00299 TIter next(gGeoManager->GetListOfVolumes());
00300 TGeoVolume *vol = (TGeoVolume*)next();
00301 Int_t ivol=1;
00302 printf("=== testing shapes ...\n");
00303 while ((vol=(TGeoVolume*)next())) {
00304 sample_volume(ivol);
00305 ivol++;
00306 }
00307 printf("=== testing global tracking ...\n");
00308 length();
00309
00310
00311 printf("\n");
00312 gBenchmark->Stop("stressShapes");
00313 gBenchmark->Print("stressShapes");
00314 Float_t ct = gBenchmark->GetCpuTime("stressShapes");
00315 Float_t cp_brun = 5.55;
00316 Float_t rootmarks = 860*cp_brun/ct;
00317 printf("*******************************************************************\n");
00318 printf("* ROOTMARKS =%6.1f * Root%-8s %d/%d CP = %7.2fs\n",rootmarks,gROOT->GetVersion(),gROOT->GetVersionDate(),gROOT->GetVersionTime(),ct);
00319 printf("*******************************************************************\n");
00320 }
00321