Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

PisaMAG.C

Go to the documentation of this file.
00001 #include "PisaMAG.h"
00002 
00003 #include <cassert>
00004 #include <cstdlib>
00005 
00006 #include "TGeoManager.h"
00007 #include "TGeoMaterial.h"
00008 #include "TGeoMedium.h"
00009 #include "TGeoPcon.h"
00010 #include "TVirtualMC.h"
00011 
00012 #include "PHCompositeNode.h"
00013 #include "PisaPhnxPar.h"
00014 #include "PisaHelper.h"
00015 #include "PisaServer.h"
00016 #include "phool.h"
00017 
00018 //_____________________________________________________________________________
00019 PisaMAG::~PisaMAG()
00020 {}
00021 
00022 //_____________________________________________________________________________
00023 void
00024 PisaMAG::buildCM(PHCompositeNode* topNode)
00025 {
00026   PisaPhnxPar* parameters = PisaHelper::getClass<PisaPhnxPar>(topNode, "PHNXPAR");
00027   assert(parameters != 0);
00028 
00029   const PisaPhnxSubPar* mag_par = parameters->get
00030     ("mag_par");
00031   assert(mag_par != 0);
00032 
00033   TGeoManager* gm = PisaHelper::getGeoManager();
00034 
00035   const char* MAG[] = { "MAGD","MAGU" };
00036   const char* AMG[] = { "AMGD","AMGU" };
00037   const int sign[] = { +1, -1 };
00038 
00039   for ( size_t i = 0; i < 2; ++i )
00040     {
00041       // Loop on north/south.
00042 
00043       int nz = 14; // number of z planes for the following PCON
00044 
00045       TGeoPcon* mag_shape = new TGeoPcon(0.0,      // phi min
00046                                          360.0,    // dphi
00047                                          nz);
00048       
00049       for ( int iz = 0; iz < nz; ++iz )
00050         {
00051           int index = (nz-1)*i + sign[i]*iz;
00052 
00053           mag_shape->DefineSection
00054             (iz,
00055              sign[i]*mag_par->getDouble("z_cent",index),
00056              mag_par->getDouble("rmin_cent",index),
00057              mag_par->getDouble("rmax_cent",index)
00058              );
00059         }
00060       
00061       TGeoMedium* medium = gm->GetMedium(mag_par->getInt("nmed_cent"));
00062       assert(medium != 0);
00063       
00064       TGeoVolume* magd = new TGeoVolume(MAG[i], mag_shape, medium);
00065       
00066       int nzextra = 3;
00067       
00068       mag_shape = new TGeoPcon(0.0, 360.0, nzextra);
00069       
00070       for ( int iz = 0; iz < nzextra; ++iz )
00071         {
00072           int index = (nzextra-1)*i + sign[i]*iz + nz-1;
00073           mag_shape->DefineSection(iz,
00074                                    sign[i]*mag_par->getDouble("z_cent",index),
00075                                    mag_par->getDouble("rmin_cent",index),
00076                                    mag_par->getDouble("rmax_cent",index));
00077         }
00078       
00079       TGeoVolume* amgd = new TGeoVolume(AMG[i], mag_shape, medium);
00080       
00081       // The inner and outer coils
00082       
00083       medium = gm->GetMedium(mag_par->getInt("cencoil_med", 0));
00084       assert(medium != 0);
00085       
00086       double z1 = mag_par->getDouble("cencoil_z", 0);
00087       double z2 = mag_par->getDouble("cencoil_z", 1);
00088       
00089       TGeoVolume* m1co = gm->MakeTube("M1CO", medium,
00090                                       mag_par->getDouble("cencoil_rin", 0),
00091                                       mag_par->getDouble("cencoil_rout", 0),
00092                                       0.5 * (z2 - z1));
00093       
00094       magd->AddNode(m1co, 1, new TGeoTranslation(0.0, 0.0, 
00095                                                  sign[i]*0.5*(z1 + z2)));
00096       
00097       
00098       medium = gm->GetMedium(mag_par->getInt("cencoil_med", 1));
00099       assert(medium != 0);
00100       
00101       z1 = mag_par->getDouble("cencoil_z", 2);
00102       z2 = mag_par->getDouble("cencoil_z", 3);
00103       double zsize = 0.5 * (z2 - z1) / 6.0;
00104       
00105       TGeoVolume* m2co = gm->MakeTube("M2CO", medium,
00106                                       mag_par->getDouble("cencoil_rin", 1),
00107                                       mag_par->getDouble("cencoil_rout", 1),
00108                                       zsize);
00109       
00110       for ( int j = 1; j <= 6; ++j )
00111         {
00112           double zcoil = sign[i]*(0.5 * (z2 + z1) + (j - 3) * zsize * 2.0) 
00113             + 0.1;
00114           magd->AddNode(m2co,j, new TGeoTranslation(0.0, 0.0, zcoil));
00115         }
00116       
00117       // Attach the volumes to the HALL
00118       
00119       TGeoVolume* hall = gm->GetVolume("HALL");
00120       assert(hall != 0);
00121       
00122       hall->AddNode(amgd, 1);
00123       hall->AddNode(magd, 1);
00124       
00125     }
00126 
00127   // FIXME: use the colors of the phnx.par file, if available
00128 
00129  //  gm->GetVolume("MAGD")->SetLineColor(1);
00130 //   gm->GetVolume("AMGD")->SetLineColor(2);
00131 //   gm->GetVolume("M1CO")->SetLineColor(3);
00132 //   gm->GetVolume("M2CO")->SetLineColor(4);
00133 }
00134 
00135 //_____________________________________________________________________________
00136 void
00137 PisaMAG::buildYokes(PHCompositeNode* topNode)
00138 {
00139   PisaPhnxPar* parameters = PisaHelper::getClass<PisaPhnxPar>(topNode, "PHNXPAR");
00140   assert(parameters != 0);
00141 
00142   const PisaPhnxSubPar* mag_par = parameters->get
00143     ("mag_par");
00144   assert(mag_par != 0);
00145 
00146   TGeoManager* gm = PisaHelper::getGeoManager();
00147 
00148   int cyoke_flag = mag_par->getInt("cyoke_flag");
00149 
00150   //         cyoke_flag = 0   means no yoke volumes installed
00151   //         cyoke_flag = 1   means only upper (+Y) return yoke is installed
00152   //         cyoke_flag = 2   means both upper and lower return yokes installed
00153   //         cyoke_flag = -1  means only lower (-Y) return yoke is installed
00154   
00155 
00156   // CYOKE is the "horizontal" cross piece from Z = -242 to +242 cm,
00157   //          159.85 full width along X, and 100 cm full height along Y
00158   //
00159   // DYOKE is the "vertical" piece on the North and South ends; it goes from
00160   //          Z = 135 to 242 cm (North Side), and from 217 to 295 cm vertical;
00161   //          The X full width is the same as the CYOKE.
00162   //          This model is slightly inaccurate since there is a base X width
00163   //          of 180.0 full width extending from Y = 217.0 to 234.0 cm, and
00164   //          the DYOKE volume overlaps with the central steel shape.
00165   //
00166 
00167   TGeoMedium* medium = gm->GetMedium(mag_par->getInt("nmed_cent"));
00168   assert(medium != 0);
00169 
00170   if ( cyoke_flag == 1 || cyoke_flag == 2 )
00171     {
00172       // Upper Parts of Return Yoke
00173       TGeoVolume* crtu = gm->MakeBox("CRTU", medium,
00174                                      mag_par->getDouble("cyoke_dx"),
00175                                      mag_par->getDouble("cyoke_dy"),
00176                                      mag_par->getDouble("cyoke_dz"));
00177 
00178       TGeoVolume* crru = gm->MakeBox("CRRU", medium,
00179                                      mag_par->getDouble("dyoke_dx"),
00180                                      mag_par->getDouble("dyoke_dy"),
00181                                      mag_par->getDouble("dyoke_dz"));
00182 
00183       TGeoVolume* crlu = gm->MakeBox("CRLU", medium,
00184                                      mag_par->getDouble("dyoke_dx"),
00185                                      mag_par->getDouble("dyoke_dy"),
00186                                      mag_par->getDouble("dyoke_dz"));
00187 
00188       TGeoVolume* hall = gm->GetVolume("HALL");
00189       assert(hall != 0);
00190 
00191       hall->AddNode(crtu, 0, new TGeoTranslation
00192                     (0.0, mag_par->getDouble("cyoke_yp"), 0.0));
00193 
00194       hall->AddNode(crru, 0, new TGeoTranslation
00195                     (0.0, mag_par->getDouble("dyoke_yp"),
00196                      mag_par->getDouble("dyoke_zp")));
00197 
00198       hall->AddNode(crlu, 0, new TGeoTranslation
00199                     (0.0, mag_par->getDouble("dyoke_yp"),
00200                      -mag_par->getDouble("dyoke_zp")));
00201     }
00202 
00203   if ( cyoke_flag == -1 || cyoke_flag == 2 )
00204     {
00205       // Lower Parts of Return Yoke
00206       TGeoVolume* crtd = gm->MakeBox("CRTD", medium,
00207                                      mag_par->getDouble("cyoke_dx"),
00208                                      mag_par->getDouble("cyoke_dy"),
00209                                      mag_par->getDouble("cyoke_dz"));
00210 
00211       TGeoVolume* crrd = gm->MakeBox("CRRD", medium,
00212                                      mag_par->getDouble("dyoke_dx"),
00213                                      mag_par->getDouble("dyoke_dy"),
00214                                      mag_par->getDouble("dyoke_dz"));
00215 
00216       TGeoVolume* crld = gm->MakeBox("CRLD", medium,
00217                                      mag_par->getDouble("dyoke_dx"),
00218                                      mag_par->getDouble("dyoke_dy"),
00219                                      mag_par->getDouble("dyoke_dz"));
00220 
00221       TGeoVolume* hall = gm->GetVolume("HALL");
00222       assert(hall != 0);
00223 
00224       hall->AddNode(crtd, 0, new TGeoTranslation
00225                     (0.0, -mag_par->getDouble("cyoke_yp"), 0.0));
00226 
00227       hall->AddNode(crrd, 0, new TGeoTranslation
00228                     (0.0, -mag_par->getDouble("dyoke_yp"),
00229                      mag_par->getDouble("dyoke_zp")));
00230 
00231       hall->AddNode(crld, 0, new TGeoTranslation
00232                     (0.0, -mag_par->getDouble("dyoke_yp"),
00233                      -mag_par->getDouble("dyoke_zp")));
00234     }
00235 }
00236 
00237 //_____________________________________________________________________________
00238 void
00239 PisaMAG::createGeometry(PHCompositeNode* topNode)
00240 {
00241   // A few checks to start with.
00242 
00243   assert(gMC->IsRootGeometrySupported() == true); // insure we deal with VMC
00244 
00245   TGeoManager* gm = PisaHelper::getGeoManager();
00246 
00247   TGeoVolume* hall = gm->GetVolume("HALL");
00248 
00249   if (!hall)
00250     {
00251       std::cerr << PHWHERE << "HALL Volume does not exist ! Aborting now"
00252                 << std::endl;
00253       exit(1);
00254     }
00255 
00256   buildCM(topNode);
00257 
00258   buildYokes(topNode);
00259 }
00260 
00261 //_____________________________________________________________________________
00262 void
00263 PisaMAG::createMaterials(PHCompositeNode*)
00264 {
00265   TGeoMaterial* iron = new TGeoMaterial("IRON", 55.85, 26, 7.87);
00266   iron->SetUniqueID(10);
00267 
00268   TGeoMaterial* copper = new TGeoMaterial("COPPER", 63.54, 29, 8.96);
00269   copper->SetUniqueID(11);
00270 
00271   new TGeoMedium("YOKE", 5, iron->GetUniqueID(),
00272                  0, 1, 5, 0.3, 0.1000000E+11, 0.25,
00273                  0.1, 0.2813469E-01);
00274 
00275   new TGeoMedium("CU", 15, copper->GetUniqueID(), 0, 1, 5, 1,
00276                  0.1000000E+11, 0.25, 0.1, 0.2813862E-01);
00277 }