Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members
PisaBBC.C
Go to the documentation of this file.00001 #include "PisaBBC.h" 00002 00003 #include <algorithm> 00004 #include <cassert> 00005 #include <iostream> 00006 #include <iomanip> 00007 #include <iterator> 00008 #include <vector> 00009 00010 #include "PHCompositeNode.h" 00011 #include "PHIODataNode.h" 00012 #include "PHObjectVectorTCA.h" 00013 #include "phool.h" 00014 #include "PisaBBCHitv1.h" 00015 #include "PisaHelper.h" 00016 #include "PisaPhnxPar.h" 00017 00018 #include "TGeoManager.h" 00019 #include "TGeoMedium.h" 00020 #include "TGeoVolume.h" 00021 #include "TLorentzVector.h" 00022 #include "TVirtualMC.h" 00023 #include "TMCProcess.h" 00024 #include "TArrayI.h" 00025 00026 namespace 00027 { 00028 double max(double a, double b, double c) 00029 { 00030 return std::max(a,std::max(b,c)); 00031 } 00032 00033 double max(double a, double b, double c, double d) 00034 { 00035 return std::max(a,max(b,c,d)); 00036 } 00037 00038 double min(double a, double b, double c) 00039 { 00040 return std::min(a,std::min(b,c)); 00041 } 00042 00043 double min(double a, double b, double c, double d) 00044 { 00045 return std::min(a,min(b,c,d)); 00046 } 00047 00048 std::string status() 00049 { 00050 std::string rv; 00051 00052 if ( gMC->IsTrackInside() ) 00053 { 00054 rv += " INSIDE"; 00055 } 00056 if ( gMC->IsTrackEntering() ) 00057 { 00058 rv += " ENTERING"; 00059 } 00060 if ( gMC->IsTrackExiting() ) 00061 { 00062 rv += " EXITING"; 00063 } 00064 if ( gMC->IsTrackOut() ) 00065 { 00066 rv += " OUTSIDE"; 00067 } 00068 if ( gMC->IsTrackAlive() ) 00069 { 00070 rv += " ALIVE"; 00071 } 00072 if ( gMC->IsTrackDisappeared() ) 00073 { 00074 rv += " DISAPPEARED"; 00075 } 00076 if ( gMC->IsTrackStop() ) 00077 { 00078 rv += " STOP"; 00079 } 00080 if ( gMC->IsNewTrack() ) 00081 { 00082 rv += " NEWTRACK"; 00083 } 00084 00085 TArrayI array; 00086 int n = gMC->StepProcesses(array); 00087 00088 for ( int i = 0; i < n; ++i ) 00089 { 00090 rv += "+"; 00091 rv += TMCProcessName[array[i]]; 00092 } 00093 return rv; 00094 } 00095 } 00096 00097 //_____________________________________________________________________________ 00098 PisaBBC::PisaBBC(bool enabled) 00099 : PisaDetector() 00100 { 00101 enable(enabled); 00102 } 00103 00104 //_____________________________________________________________________________ 00105 PisaBBC::~PisaBBC() 00106 { 00107 } 00108 00109 //_____________________________________________________________________________ 00110 void 00111 PisaBBC::beginEvent(PHCompositeNode* topNode) 00112 { 00113 PisaBBCHitVector* hits = 00114 PisaHelper::getClass<PisaBBCHitVector>(topNode, "BBCHits","DST"); 00115 00116 if (!hits) 00117 { 00118 fHits = new PHObjectVectorTCA<PisaBBCHit,PisaBBCHitv1>; 00119 PHIODataNode<PisaBBCHitVector>* node = 00120 new PHIODataNode<PisaBBCHitVector>(fHits,"BBCHits","PHObject"); 00121 PisaHelper::getPisaNode(topNode,"DST")->addNode(node); 00122 } 00123 else 00124 { 00125 fHits = hits; 00126 } 00127 00128 } 00129 00130 //_____________________________________________________________________________ 00131 void 00132 PisaBBC::createGeometry(PHCompositeNode* topNode) 00133 { 00134 00135 // This routine defines the geometry for the Beam-Beam 00136 // Counter. Structure of BBC is place in the mother volume "HALL". 00137 // 00138 // HALL --- BBCM --- ! BBC mother volume 00139 // /-- BBCE ! Electron absorber 00140 // /-- BBCF ! Front panel 00141 // /-- BBCS ! Structure tube 00142 // /-- BBCB ! Back panel 00143 // /-- BBCC ! Thin barrel cover 00144 // /-- BBCD -- ! Detector volume 00145 // /-- BBCA ! Attachment plate 00146 // /-- BBCQ ! Quartz block 00147 // /-- BBCP ! PMT 00148 // /-- BBCR ! Breeder module 00149 // /-- BBCH ! Metal shield 00150 // 00151 00152 const int MAXPMT = 100; // Maximum # of PMTs to be installed. 00153 const int MAXREM = 10; // Maximum # of PMTs to be removed. 00154 00155 PisaPhnxPar* parameters = 00156 PisaHelper::getClass<PisaPhnxPar>(topNode, "PHNXPAR"); 00157 assert(parameters != 0); 00158 00159 const PisaPhnxSubPar* bbc_par = parameters->get("bbc_par"); 00160 assert(bbc_par != 0); 00161 00162 TGeoManager* gm = PisaHelper::getGeoManager(); 00163 00164 double BBBCOVER[3]; // BarrelCover with Rmin, Rmax, thick 00165 double BBDETECT[10]; // Detector element for PGON 00166 double BBMOTHER[3]; // BBC Mother Volume with Rmin, Rmax, thick 00167 double BBSHIELD[10]; // Metal shield PGON 00168 00169 // Construct needed parameters from the phnxpar parameters. 00170 00171 BBDETECT[0] = bbc_par->getDouble("BBQUARTZ",0); 00172 BBDETECT[1] = bbc_par->getDouble("BBQUARTZ",1); 00173 BBDETECT[2] = bbc_par->getDouble("BBQUARTZ",2); 00174 BBDETECT[3] = bbc_par->getDouble("BBQUARTZ",3); 00175 BBDETECT[4] = 00176 + bbc_par->getDouble("BBATTACH",4) 00177 + bbc_par->getDouble("BBQUARTZ",4) 00178 - bbc_par->getDouble("BBPMTSIZ",2) 00179 - bbc_par->getDouble("BBBREEDE",2); 00180 BBDETECT[5] = bbc_par->getDouble("BBQUARTZ",5); 00181 BBDETECT[6] = max(bbc_par->getDouble("BBATTACH",6), 00182 bbc_par->getDouble("BBQUARTZ",6), 00183 bbc_par->getDouble("BBPMTSIZ",1)); 00184 BBDETECT[7] = 00185 + bbc_par->getDouble("BBATTACH",7) 00186 + bbc_par->getDouble("BBQUARTZ",7) 00187 + bbc_par->getDouble("BBPMTSIZ",2) 00188 + bbc_par->getDouble("BBBREEDE",2); 00189 BBDETECT[8] = bbc_par->getDouble("BBQUARTZ",8); 00190 BBDETECT[9] = max(bbc_par->getDouble("BBATTACH",9), 00191 bbc_par->getDouble("BBQUARTZ",9), 00192 bbc_par->getDouble("BBPMTSIZ",1)); 00193 00194 BBBCOVER[0] = max(bbc_par->getDouble("BBABSORB",1), 00195 bbc_par->getDouble("BBFRONTB",1), 00196 bbc_par->getDouble("BBSTRUCT",1), 00197 bbc_par->getDouble("BBBACKBD",1)); 00198 BBBCOVER[1] = BBBCOVER[0] + bbc_par->getDouble("BBCOVERT"); 00199 BBBCOVER[2] = bbc_par->getDouble("BBSTRUCT",2); 00200 00201 BBMOTHER[0] = min(bbc_par->getDouble("BBABSORB",0), 00202 bbc_par->getDouble("BBFRONTB",0), 00203 bbc_par->getDouble("BBSTRUCT",0), 00204 bbc_par->getDouble("BBBACKBD",0)); 00205 BBMOTHER[1] = BBBCOVER[1]; 00206 BBMOTHER[2] = bbc_par->getDouble("BBSTRUCT",2); 00207 00208 BBSHIELD[0] = bbc_par->getDouble("BBQUARTZ",0); 00209 BBSHIELD[1] = bbc_par->getDouble("BBQUARTZ",1); 00210 BBSHIELD[2] = bbc_par->getDouble("BBQUARTZ",2); 00211 BBSHIELD[3] = bbc_par->getDouble("BBQUARTZ",3); 00212 BBSHIELD[4] = 00213 + bbc_par->getDouble("BBQUARTZ",4) 00214 - bbc_par->getDouble("BBPMTSIZ",2) 00215 - bbc_par->getDouble("BBBREEDE",2); 00216 BBSHIELD[5] = max(bbc_par->getDouble("BBATTACH",6), 00217 bbc_par->getDouble("BBQUARTZ",6), 00218 bbc_par->getDouble("BBPMTSIZ",1)) 00219 - bbc_par->getDouble("BBSHITHI"); 00220 00221 BBSHIELD[6] = max(bbc_par->getDouble("BBATTACH",6), 00222 bbc_par->getDouble("BBQUARTZ",6), 00223 bbc_par->getDouble("BBPMTSIZ",1)); 00224 BBSHIELD[7] = 00225 + bbc_par->getDouble("BBQUARTZ",7) 00226 + bbc_par->getDouble("BBPMTSIZ",2) 00227 + bbc_par->getDouble("BBBREEDE",2); 00228 BBSHIELD[8] = max(bbc_par->getDouble("BBATTACH",9), 00229 bbc_par->getDouble("BBQUARTZ",9), 00230 bbc_par->getDouble("BBPMTSIZ",1)) 00231 - bbc_par->getDouble("BBSHITHI"); 00232 BBSHIELD[9] = max(bbc_par->getDouble("BBATTACH",9), 00233 bbc_par->getDouble("BBQUARTZ",9), 00234 bbc_par->getDouble("BBPMTSIZ",1)); 00235 00236 double YSTP = bbc_par->getDouble("BBQUARTZ",6) 00237 + bbc_par->getDouble("BBSPACIN")*0.5; 00238 double XSTP = YSTP*sqrt(3.0); 00239 00240 int MROW = static_cast<int>(floor(bbc_par->getDouble("BBFRONTB",1)/YSTP))+1; 00241 int MCOL = static_cast<int>(floor(bbc_par->getDouble("BBFRONTB",1)/XSTP))+1; 00242 00243 double RMAX = bbc_par->getDouble("BBFRONTB",1) 00244 - BBDETECT[6]*2.0/sqrt(3.0); 00245 double RMIN = bbc_par->getDouble("BBFRONTB",0) 00246 + BBDETECT[6]*2.0/sqrt(3.0); 00247 00248 double RRMA = RMAX*RMAX; 00249 double RRMI = RMIN*RMIN; 00250 00251 if ( bbc_par->getInt("BBNUMREM") > MAXREM ) 00252 { 00253 std::cerr << PHWHERE << "BBC: Number of detector to be removed" 00254 << " exceeded MAXREM=" << MAXREM 00255 << std::endl; 00256 exit(1); 00257 } 00258 00259 if ( YSTP <= BBDETECT[6] ) 00260 { 00261 std::cerr << PHWHERE << "BBC : Spacing conflict" << std::endl; 00262 exit(1); 00263 } 00264 00265 // Create a BBC mother volume, BBCM 00266 00267 TGeoVolume* bbcm = gm->Volume("BBCM","TUBE", 00268 bbc_par->getInt("BBMEDMOT"),BBMOTHER,3); 00269 00270 // Place the mother volume BBCM in the HALL volume 00271 // BBZPOSIT gives the z position of a quartz radiator front face. 00272 00273 TGeoVolume* hall = gm->GetVolume("HALL"); 00274 assert(hall != 0); 00275 00276 double zpos = 00277 bbc_par->getDouble("BBZPOSIT",0) 00278 + BBMOTHER[2] 00279 - 2.0*bbc_par->getDouble("BBABSORB",2) 00280 - 2.0*bbc_par->getDouble("BBFRONTB",2) 00281 - ( bbc_par->getDouble("BBATTACH",7) 00282 - bbc_par->getDouble("BBABSORB",2)); 00283 00284 hall->AddNode(bbcm,1,new TGeoTranslation(0.0,0.0,zpos)); 00285 00286 zpos = bbc_par->getDouble("BBZPOSIT",1) 00287 - BBMOTHER[2] 00288 + 2.0*bbc_par->getDouble("BBABSORB",2) 00289 + 2.0*bbc_par->getDouble("BBFRONTB",2) 00290 + ( bbc_par->getDouble("BBATTACH",7) 00291 - bbc_par->getDouble("BBABSORB",2)); 00292 00293 TGeoTranslation t1(0.0,0.0,zpos); 00294 TGeoRotation r1; 00295 00296 r1.SetAngles(90.,0.,90.,90.,180.,0.); // mirror symmetry 00297 00298 TGeoCombiTrans* tr1 = new TGeoCombiTrans(t1,r1); 00299 00300 hall->AddNode(bbcm,2,tr1); 00301 00302 // Create BBCE, BBCF, BBCS, BBCB, BBCC, BBCD volumes 00303 // and place them into BBCM. 00304 00305 TGeoVolume* bbce = gm->MakeTube("BBCE", 00306 gm->GetMedium(bbc_par->getInt("BBMEDABS")), 00307 bbc_par->getDouble("BBABSORB",0), 00308 bbc_par->getDouble("BBABSORB",1), 00309 bbc_par->getDouble("BBABSORB",2)); 00310 bbcm->AddNode(bbce,1, 00311 new TGeoTranslation(0.0,0.0,-BBMOTHER[2]+ 00312 bbc_par->getDouble("BBABSORB",2))); 00313 00314 TGeoVolume* bbcf = gm->MakeTube("BBCF", 00315 gm->GetMedium(bbc_par->getInt("BBMEDFRO")), 00316 bbc_par->getDouble("BBFRONTB",0), 00317 bbc_par->getDouble("BBFRONTB",1), 00318 bbc_par->getDouble("BBFRONTB",2)); 00319 bbcm->AddNode(bbcf,1, 00320 new TGeoTranslation(0.0,0.0,-BBMOTHER[2]+ 00321 2.0*bbc_par->getDouble("BBABSORB",2)+ 00322 bbc_par->getDouble("BBFRONTB",2))); 00323 00324 TGeoVolume* bbcs = gm->MakeTube("BBCS", 00325 gm->GetMedium(bbc_par->getInt("BBMEDSTR")), 00326 bbc_par->getDouble("BBSTRUCT",0), 00327 bbc_par->getDouble("BBSTRUCT",1), 00328 bbc_par->getDouble("BBSTRUCT",2)); 00329 bbcm->AddNode(bbcs,1); 00330 00331 TGeoVolume* bbcb = gm->MakeTube("BBCB", 00332 gm->GetMedium(bbc_par->getInt("BBMEDBAC")), 00333 bbc_par->getDouble("BBBACKBD",0), 00334 bbc_par->getDouble("BBBACKBD",1), 00335 bbc_par->getDouble("BBBACKBD",2)); 00336 00337 bbcm->AddNode(bbcb,1, 00338 new TGeoTranslation(0.0,0.0,BBMOTHER[2]- 00339 bbc_par->getDouble("BBBACKBD",2))); 00340 00341 00342 TGeoVolume* bbcc = gm->Volume("BBCC","TUBE",bbc_par->getInt("BBMEDCOV"), 00343 BBBCOVER,3); 00344 00345 bbcm->AddNode(bbcc,1); 00346 00347 // Now the envelops of the detectors (vacuum) 00348 00349 TGeoVolume* bbcd = gm->Volume("BBCD","PGON",bbc_par->getInt("BBMEDCOV"), 00350 BBDETECT,10); 00351 00352 // bbcm->AddNode(bbcd,1); 00353 00354 zpos = -BBMOTHER[2] 00355 + 2.0*bbc_par->getDouble("BBFRONTB",2) 00356 + 2.0*bbc_par->getDouble("BBABSORB",2) 00357 + ( BBDETECT[7]-BBDETECT[4] ) * 0.5; 00358 00359 int NROW = MROW; 00360 int NCOL = MCOL; 00361 int NDET = 0; 00362 00363 // Find detector element location inside the BBC boundaries. 00364 00365 double XYPS[2][MAXPMT]; 00366 bool LXYP[MAXPMT]; 00367 00368 while ( NROW >= -MROW ) // Start from top left and go right 00369 { 00370 int LROW = abs(NROW/2*2-NROW); // 0 for even, 1 for odd 00371 double YPOS = NROW*YSTP; 00372 NCOL = MCOL; 00373 while ( NCOL >= -MCOL ) 00374 { 00375 int LCOL = abs(NCOL/2*2-NCOL); // 0 for even, 1 for odd 00376 if ( LROW == LCOL ) // since elements are staggered 00377 { 00378 double XPOS = NCOL*XSTP; 00379 double RRAD = XPOS*XPOS+YPOS*YPOS; 00380 if ( (RRAD<=RRMA) && (RRAD>=RRMI) ) // in range ? 00381 { 00382 if ( NDET < MAXPMT ) 00383 { 00384 XYPS[0][NDET] = XPOS; 00385 XYPS[1][NDET] = YPOS; 00386 LXYP[NDET] = true; 00387 } 00388 else 00389 { 00390 std::cerr << PHWHERE << "BBC : max # of PMT exceeded" 00391 << std::endl; 00392 exit(1); 00393 } 00394 ++NDET; 00395 } // in range 00396 } // even-odd 00397 --NCOL; 00398 } // column loop 00399 --NROW; 00400 } // row loop 00401 00402 double RREM=0.0; 00403 00404 for ( int IP1 = 0; IP1 < bbc_par->getInt("BBNUMREM"); ++IP1 ) 00405 { 00406 int RD = 1; 00407 double XX = XYPS[0][NDET] - bbc_par->getDouble("BBPOSREM",IP1*2); 00408 double YY = XYPS[1][NDET] - bbc_par->getDouble("BBPOSREM",IP1*2+1); 00409 RREM = XX*XX + YY*YY; 00410 for ( int IP2 = 1; IP2 < NDET; ++IP2 ) 00411 { 00412 double XX = XYPS[0][IP2] - bbc_par->getDouble("BBPOSREM",IP1*2); 00413 double YY = XYPS[1][IP2] - bbc_par->getDouble("BBPOSREM",IP1*2+1); 00414 double RR = XX*XX + YY*YY; 00415 if ( RR <= RREM ) 00416 { 00417 RD = IP2; 00418 RREM = RR; 00419 } 00420 } 00421 LXYP[RD] = false; 00422 } 00423 00424 for ( int IP1 = 0; IP1 < NDET; ++IP1 ) 00425 { 00426 if ( LXYP[IP1] ) 00427 { 00428 bbcm->AddNode(bbcd,IP1+1, 00429 new TGeoTranslation(XYPS[0][IP1],XYPS[1][IP1],zpos)); 00430 } 00431 } 00432 00433 // Now fills the detector empty envelops with usefull stuff = 00434 // attachment, quartz, PMT, breeder and metal shield. 00435 00436 double BBATTACH[10]; 00437 for ( size_t i = 0; i < 10; ++i ) 00438 { 00439 BBATTACH[i] = bbc_par->getDouble("BBATTACH",i); 00440 } 00441 00442 TGeoVolume* bbca = gm->Volume("BBCA","PGON",bbc_par->getInt("BBMEDATT"), 00443 BBATTACH,10); 00444 00445 zpos = -(BBDETECT[7]-BBDETECT[4])*0.5 00446 + (BBATTACH[7]-BBATTACH[4])*0.5; 00447 00448 bbcd->AddNode(bbca,1,new TGeoTranslation(0.0,0.0,zpos)); 00449 00450 double BBQUARTZ[10]; 00451 for ( size_t i = 0; i < 10; ++i ) 00452 { 00453 BBQUARTZ[i] = bbc_par->getDouble("BBQUARTZ",i); 00454 } 00455 00456 TGeoVolume* bbcq = gm->Volume("BBCQ","PGON",bbc_par->getInt("BBMEDQUA"), 00457 BBQUARTZ,10); 00458 00459 zpos = -(BBDETECT[7]-BBDETECT[4])*0.5 00460 + (BBQUARTZ[7]-BBQUARTZ[4])*0.5 00461 + (BBATTACH[7]-BBATTACH[4]); 00462 00463 bbcd->AddNode(bbcq,1,new TGeoTranslation(0.0,0.0,zpos)); 00464 00465 TGeoVolume* bbcp = gm->MakeTube("BBCP", 00466 gm->GetMedium(bbc_par->getInt("BBMEDPMT")), 00467 bbc_par->getDouble("BBPMTSIZ",0), 00468 bbc_par->getDouble("BBPMTSIZ",1), 00469 bbc_par->getDouble("BBPMTSIZ",2)); 00470 00471 zpos = -(BBDETECT[7]-BBDETECT[4])*0.5 00472 + (BBQUARTZ[7]-BBQUARTZ[4]) 00473 + (BBATTACH[7]-BBATTACH[4]) 00474 + bbc_par->getDouble("BBPMTSIZ",2); 00475 00476 bbcd->AddNode(bbcp,1,new TGeoTranslation(0.0,0.0,zpos)); 00477 00478 TGeoVolume* bbcr = gm->MakeTube("BBCR", 00479 gm->GetMedium(bbc_par->getInt("BBMEDBRE")), 00480 bbc_par->getDouble("BBBREEDE",0), 00481 bbc_par->getDouble("BBBREEDE",1), 00482 bbc_par->getDouble("BBBREEDE",2)); 00483 00484 zpos = -(BBDETECT[7]-BBDETECT[4])*0.5 00485 + (BBQUARTZ[7]-BBQUARTZ[4]) 00486 + (BBATTACH[7]-BBATTACH[4]) 00487 + bbc_par->getDouble("BBPMTSIZ",2)*2.0 00488 + bbc_par->getDouble("BBBREEDE",2); 00489 00490 bbcd->AddNode(bbcr,1,new TGeoTranslation(0.0,0.0,zpos)); 00491 00492 TGeoVolume* bbch = gm->Volume("BBCH","PGON",bbc_par->getInt("BBMEDSHI"), 00493 BBSHIELD,10); 00494 00495 zpos = -(BBDETECT[7]-BBDETECT[4])*0.5 00496 + (BBATTACH[7]-BBATTACH[4]) 00497 + (BBSHIELD[7]-BBSHIELD[4])*0.5; 00498 00499 bbcd->AddNode(bbch,1,new TGeoTranslation(0.0,0.0,zpos)); 00500 } 00501 00502 //_____________________________________________________________________________ 00503 void 00504 PisaBBC::createMaterials(PHCompositeNode*) 00505 { 00506 TGeoManager* gm = PisaHelper::getGeoManager(); 00507 00508 int nmat = 16; // vacuum 00509 00510 gm->Material("Vacuum",0.0,0.0,0.0,nmat,0.0,0.0); 00511 00512 nmat = 9; // aluminium 00513 00514 gm->Material("Aluminium",26.980,13.000,2.700,nmat); 00515 00516 nmat = 46; // iron 00517 00518 gm->Material("Low Mag Iron",55.85,26.0,7.87,nmat,1.76,17.1); 00519 00520 nmat = 201; 00521 00522 double aquartz[] = { 28.09 , 16.0 }; 00523 double zquartz[] = { 14.00 , 8.0 }; 00524 double wquartz[] = { 0.467, 0.532 }; 00525 00526 double dens = 2.64; 00527 00528 gm->Mixture("Quartz-BBQ",aquartz,zquartz,dens,2,wquartz,nmat); 00529 00530 nmat = 202; // why a second material identical to the first one ? 00531 00532 gm->Mixture("Quartz-PMT",aquartz,zquartz,dens,2,wquartz,nmat); 00533 00534 nmat = 802; 00535 00536 // Plastic (lucite) for cover plates (C5H8O2) 00537 double ap[] = { 12.0, 1.0, 16.0 }; 00538 double zp[] = { 6.0, 1.0, 8.0 }; 00539 double wp[] = { 0.6, 0.08, 0.32 }; 00540 double dp = 1.18; 00541 00542 gm->Mixture("Plastic",ap,zp,dp,3,wp,nmat); 00543 00544 // Tracking media # 32 - Vacuum + magnetic field 00545 int isvol = 0; // not sensitive 00546 int ifield = 1; // magnetic field 00547 double fieldm = 5.0; // max field 00548 double tmaxfd = 5.0; // maximum angle due to field (one step) in degrees 00549 double dmaxms = 0.2; // max disp. due to mulsct. in one step (cm) 00550 double deemax = 0.2; // max fractional energy loss in one step 00551 double epsil = 0.1; // tracking precision (cm) 00552 double stmin = 5.00; // min step due to e loss or mulsct. (cm) 00553 00554 gm->Medium("Air + Field",32,nmat,isvol,ifield,fieldm,tmaxfd,dmaxms,deemax,epsil,stmin); 00555 00556 // Tracking media # 26 00557 00558 nmat = 9 ; // aluminium 00559 isvol = 0 ; // insensitive 00560 ifield = 1 ; // magnetic field 00561 fieldm = 5.0 ; // max field 00562 tmaxfd = 1.0 ; // maximum angle due to field (one step) in degrees 00563 dmaxms = 0.2 ; // max disp. due to mulsct. in one step (cm) 00564 deemax = 0.5 ; // max fractional energy loss in one step 00565 epsil = 0.01 ; // tracking precision (cm) 00566 stmin = 0.01 ; // min step due to e loss or mulsct. (cm) 00567 00568 gm->Medium("Aluminum Frame",26,nmat,isvol,ifield,fieldm,tmaxfd,dmaxms,deemax,epsil,stmin); 00569 00570 // Tracking medium #201 -- Quartz for BBQ (sensitive detector) 00571 nmat = 201; 00572 isvol = 1; // sensitive 00573 ifield = 1; 00574 fieldm = 20.0; 00575 tmaxfd = 45.0; 00576 dmaxms = 0.2; 00577 deemax = 0.1; 00578 epsil = 0.01; 00579 stmin = 0.1; 00580 00581 gm->Medium("Quartz-BBQ",201,nmat,isvol,ifield,fieldm,tmaxfd,dmaxms,deemax,epsil,stmin); 00582 00583 nmat = 202; 00584 00585 gm->Medium("Quartz-PMT",202,nmat,isvol,ifield,fieldm,tmaxfd,dmaxms,deemax,epsil,stmin); 00586 00587 nmat = 802; 00588 gm->Medium("Plastic",802,nmat,0,0,0.,10.,1.,0.1,0.01,0.05); 00589 00590 // Tracking media # 46 - Mu Magnet Yoke (Iron) 00591 nmat = 46 ; // iron (low threshold) 00592 isvol = 0 ; // not sensitive 00593 ifield = 0 ; // no magnetic field 00594 fieldm = 0.0 ; // max field 00595 tmaxfd = 0.3 ; // maximum angle due to field (one step) in degrees 00596 dmaxms = 2.0 ; // max disp. due to mulsct. in one step (cm) 00597 deemax = 0.2 ; // max fractional energy loss in one step 00598 epsil = 0.1 ; // tracking precision (cm) 00599 stmin = 0.1 ; // min step due to e loss or mulsct. (cm) 00600 gm->Medium("MU non-mag-low",46,nmat,isvol,ifield,fieldm,tmaxfd,dmaxms,deemax,epsil,stmin); 00601 00602 } 00603 00604 //_____________________________________________________________________________ 00605 void 00606 PisaBBC::finishEvent(PHCompositeNode*) 00607 { 00608 std::cout << PHWHERE << " : nhits=" << fHits->size() << std::endl; 00609 00610 } 00611 00612 //_____________________________________________________________________________ 00613 void 00614 PisaBBC::stepManager() 00615 { 00616 static unsigned int nevt = 0; 00617 00618 ++nevt; 00619 00620 if ( gMC->GetMedium() != 5 ) 00621 { 00622 // This should of course be done by the PisaServer... 00623 // using e.g. a map tracking media -> PisaDetector 00624 // to know at each step which stepManager to call... 00625 return; 00626 } 00627 00628 if ( gMC->TrackCharge() == 0.0 ) 00629 { 00630 // Do not deal with e.g. photons. 00631 return; 00632 } 00633 00634 int copy; 00635 int volid = gMC->CurrentVolID(copy); 00636 00637 int track = gMC->GetStack()->GetCurrentTrackNumber(); 00638 int pid = gMC->TrackPid(); 00639 00640 std::cout << " Track # " << std::setw(4) << track 00641 << " " << gMC->ParticleName(pid) 00642 << " VolID=" << volid << "(copy=" << copy << ") " 00643 << " VolName=" << gMC->CurrentVolName() 00644 << " Medium=" << gMC->GetMedium() 00645 << status() 00646 << " Length=" << gMC->TrackLength() 00647 << std::endl; 00648 00649 00650 if ( gMC->IsTrackEntering() ) 00651 { 00652 // PisaBBCHit* last = fHits->back(); 00653 // int id = 0; 00654 // if (!last) 00655 // { 00656 // id = last->id()+1; 00657 // } 00658 PisaBBCHit* hit = fHits->add(fHits->size()); 00659 // hit->id(id); 00660 hit->track(gMC->GetStack()->GetCurrentTrackNumber()); 00661 hit->pid(gMC->TrackPid()); 00662 TLorentzVector pos; 00663 TLorentzVector mom; 00664 gMC->TrackPosition(pos); 00665 gMC->TrackMomentum(mom); 00666 hit->position(pos.X(),pos.Y(),pos.Z()); 00667 hit->momentum(mom.X(),mom.Y(),mom.Z()); 00668 hit->del(0.0); 00669 hit->tof(gMC->TrackTime()*1e9); 00670 hit->len(0.0); 00671 std::cout << PHWHERE << nevt << " Created hit " << (*hit) << std::endl; 00672 } 00673 00674 if ( gMC->IsTrackInside() ) 00675 { 00676 PisaBBCHit* last = fHits->back(); 00677 assert(last!=0); 00678 assert(last->track()==gMC->GetStack()->GetCurrentTrackNumber()); 00679 assert(last->pid()==gMC->TrackPid()); 00680 last->del(last->del()+gMC->Edep()); 00681 std::cout << PHWHERE << nevt << " Updating hit " << std::endl; 00682 std::cout << (*last) << std::endl; 00683 } 00684 00685 if ( !gMC->IsTrackAlive() || gMC->IsTrackExiting() || gMC->IsTrackOut() ) 00686 { 00687 PisaBBCHit* last = fHits->back(); 00688 assert(last!=0); 00689 assert(last->track()==gMC->GetStack()->GetCurrentTrackNumber()); 00690 assert(last->pid()==gMC->TrackPid()); 00691 last->len(gMC->TrackLength()-last->len()); 00692 std::cout << PHWHERE << nevt << " Really closing hit" << (*last) << std::endl; 00693 } 00694 00695 // if ( gMC->IsTrackEntering() ) 00696 // { 00697 // TLorentzVector track; 00698 // gMC->TrackPosition(track); 00699 // TLorentzVector mom; 00700 // gMC->TrackMomentum(mom); 00701 // hit->position(track.X(),track.Y(),track.Z()); 00702 // hit->momentum(mom.X(),mom.Y(),mom.Z()); 00703 // hit->len(gMC->TrackLength()); 00704 // hit->del(0.0); 00705 // hit->tof(gMC->TrackTime()*1E9); 00706 // hit->etot(gMC->Etot()); 00707 // hit->track(gMC->GetStack()->GetCurrentTrackNumber()); 00708 // hit->pid(gMC->TrackPid()); 00709 // std::cout << "VolID=" << volid << "(copy=" << copy << ") " 00710 // << " VolName=" << gMC->CurrentVolName() 00711 // << " Medium=" << gMC->GetMedium() 00712 // << " IsExiting=" << gMC->IsTrackExiting() 00713 // << " IsInside=" << gMC->IsTrackInside() 00714 // << " IsAlive=" << gMC->IsTrackAlive() 00715 // << " IsStop=" << gMC->IsTrackStop() 00716 // << " IsDisappeared=" << gMC->IsTrackDisappeared() 00717 // << std::endl; 00718 // hit->identify(); 00719 // } 00720 00721 // if ( gMC->IsTrackInside() ) 00722 // { 00723 // std::cout << "Length=" 00724 // << gMC->TrackLength() 00725 // << " VolID=" << volid << "(copy=" << copy << ") " 00726 // << " VolName=" << gMC->CurrentVolName() 00727 // << " Medium=" << gMC->GetMedium() 00728 // << " IsExiting=" << gMC->IsTrackExiting() 00729 // << " IsInside=" << gMC->IsTrackInside() 00730 // << " IsAlive=" << gMC->IsTrackAlive() 00731 // << " IsStop=" << gMC->IsTrackStop() 00732 // << " IsDisappeared=" << gMC->IsTrackDisappeared() 00733 // << std::endl; 00734 00735 // } 00736 }