21.1.2011 Kamil Sedlak
This version contains many changes! 1) Optical photon simulation is now possible - some work still may need to be done (e.g. the manual is not updated yet), but it should basically work already now. 2) Changes in the musrSimAna - correction of some bugs (mainly in the coincidence of coincidence and veto detectors) and some other improvements
This commit is contained in:
@ -64,6 +64,9 @@
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4ProductionCuts.hh"
|
||||
|
||||
//#include "G4OpticalSurface.hh"
|
||||
#include "G4LogicalBorderSurface.hh"
|
||||
|
||||
#include "musrRootOutput.hh" //cks for storing some info in the Root output file
|
||||
#include "musrParameters.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
@ -71,9 +74,10 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrDetectorConstruction::musrDetectorConstruction()
|
||||
:parameterFileName("Unset"), checkOverlap(true), aScintSD(0)
|
||||
musrDetectorConstruction::musrDetectorConstruction(G4String steeringFileName)
|
||||
:checkOverlap(true), aScintSD(0)
|
||||
{
|
||||
parameterFileName = steeringFileName;
|
||||
DefineMaterials();
|
||||
detectorMessenger = new musrDetectorMessenger(this);
|
||||
}
|
||||
@ -102,7 +106,9 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
||||
// G4double roundingErr=0.01*mm; // 0.01mm precision is OK for displaying subtracted volumes, while 0.001mm is not
|
||||
//----------------------
|
||||
|
||||
musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
musrSteppingAction* mySteppingAction = musrSteppingAction::GetInstance();
|
||||
|
||||
|
||||
G4VPhysicalVolume* pointerToWorldVolume=NULL;
|
||||
// Read detector configuration parameters from the steering file:
|
||||
@ -483,7 +489,6 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
||||
if (strstr(name,"save")!=NULL) {
|
||||
if (volumeID!=0) { // do not store hits in special "save" volume if ID of this volume is 0
|
||||
// (due to difficulties to distinguish between ID=0 and no save volume when using std::map)
|
||||
musrSteppingAction* mySteppingAction = musrSteppingAction::GetInstance();
|
||||
mySteppingAction->SetLogicalVolumeAsSpecialSaveVolume(logicName,volumeID);
|
||||
musrRootOutput::GetRootInstance()->SetSpecialSaveVolumeDefined();
|
||||
}
|
||||
@ -562,6 +567,164 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
||||
}
|
||||
}
|
||||
|
||||
// cks: Optical Boundary (needed only when simulating optical photons)
|
||||
else if (strcmp(tmpString1,"opticalSurface")==0) {
|
||||
if (musrParameters::boolG4OpticalPhotons) {
|
||||
char optSurfaceName[100];
|
||||
char physVolName1[100];
|
||||
char physVolName2[100];
|
||||
char type[100];
|
||||
char finish[100];
|
||||
char model[100];
|
||||
char materialPropertiesTableName[100]="Undefined";
|
||||
sscanf(&line[0],"%*s %*s %s %s %s %s %s %s %s",optSurfaceName,physVolName1,physVolName2,type,finish,model,materialPropertiesTableName);
|
||||
G4VPhysicalVolume* pPhysVol1 = FindPhysicalVolume(physVolName1);
|
||||
G4VPhysicalVolume* pPhysVol2 = FindPhysicalVolume(physVolName2);
|
||||
if ((pPhysVol1==NULL)||(pPhysVol2==NULL)) {
|
||||
G4cout << "ERROR! musrDetectorConstruction::Construct(): Physical Volume not found!"<<G4endl;
|
||||
G4cout << " ==> S T O P F O R C E D"<<G4endl;
|
||||
ReportGeometryProblem(line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
G4OpticalSurface* optSurfTMP = new G4OpticalSurface(optSurfaceName);
|
||||
new G4LogicalBorderSurface(optSurfaceName,pPhysVol1,pPhysVol2,optSurfTMP);
|
||||
|
||||
std::map<std::string,G4SurfaceType> OpticalTypeMap;
|
||||
std::map<std::string,G4OpticalSurfaceModel> OpticalModelMap;
|
||||
std::map<std::string,G4OpticalSurfaceFinish> OpticalFinishMap;
|
||||
|
||||
OpticalTypeMap["dielectric_metal"]=dielectric_metal; // dielectric-metal interface
|
||||
OpticalTypeMap["dielectric_dielectric"]=dielectric_dielectric; // dielectric-dielectric interface
|
||||
OpticalTypeMap["dielectric_LUT"]=dielectric_LUT; // dielectric-Look-Up-Table interface
|
||||
OpticalTypeMap["firsov"]=firsov; // for Firsov Process
|
||||
OpticalTypeMap["x_ray"]=x_ray; // for x-ray mirror process
|
||||
|
||||
OpticalModelMap["glisur"]=glisur; // original GEANT3 model
|
||||
OpticalModelMap["unified"]=unified; // UNIFIED model
|
||||
OpticalModelMap["LUT"]=LUT; // Look-Up-Table model
|
||||
|
||||
OpticalFinishMap["polished"]=polished; // smooth perfectly polished surface
|
||||
OpticalFinishMap["polishedfrontpainted"]=polishedfrontpainted; // smooth top-layer (front) paint
|
||||
OpticalFinishMap["polishedbackpainted"]=polishedbackpainted; // same is 'polished' but with a back-paint
|
||||
OpticalFinishMap["ground"]=ground; // rough surface
|
||||
OpticalFinishMap["groundfrontpainted"]=groundfrontpainted; // rough top-layer (front) paint
|
||||
OpticalFinishMap["groundbackpainted"]=groundbackpainted; // same as 'ground' but with a back-paint
|
||||
OpticalFinishMap["polishedlumirrorair"]=polishedlumirrorair; // mechanically polished surface, with lumirror
|
||||
OpticalFinishMap["polishedlumirrorglue"]=polishedlumirrorglue; // mechanically polished surface, with lumirror & meltmount
|
||||
OpticalFinishMap["polishedair"]=polishedair; // mechanically polished surface
|
||||
OpticalFinishMap["polishedteflonair"]=polishedteflonair; // mechanically polished surface, with teflon
|
||||
OpticalFinishMap["polishedtioair"]=polishedtioair; // mechanically polished surface, with tio paint
|
||||
OpticalFinishMap["polishedtyvekair"]=polishedtyvekair; // mechanically polished surface, with tyvek
|
||||
OpticalFinishMap["polishedvm2000air"]=polishedvm2000air; // mechanically polished surface, with esr film
|
||||
OpticalFinishMap["polishedvm2000glue"]=polishedvm2000glue; // mechanically polished surface, with esr film & meltmount
|
||||
OpticalFinishMap["etchedlumirrorair"]=etchedlumirrorair; // chemically etched surface, with lumirror
|
||||
OpticalFinishMap["etchedlumirrorglue"]=etchedlumirrorglue; // chemically etched surface, with lumirror & meltmount
|
||||
OpticalFinishMap["etchedair"]=etchedair; // chemically etched surface
|
||||
OpticalFinishMap["etchedteflonair"]=etchedteflonair; // chemically etched surface, with teflon
|
||||
OpticalFinishMap["etchedtioair"]=etchedtioair; // chemically etched surface, with tio paint
|
||||
OpticalFinishMap["etchedtyvekair"]=etchedtyvekair; // chemically etched surface, with tyvek
|
||||
OpticalFinishMap["etchedvm2000air"]=etchedvm2000air; // chemically etched surface, with esr film
|
||||
OpticalFinishMap["etchedvm2000glue"]=etchedvm2000glue; // chemically etched surface, with esr film & meltmount
|
||||
OpticalFinishMap["groundlumirrorair"]=groundlumirrorair; // rough-cut surface, with lumirror
|
||||
OpticalFinishMap["groundlumirrorglue"]=groundlumirrorglue; // rough-cut surface, with lumirror & meltmount
|
||||
OpticalFinishMap["groundair"]=groundair; // rough-cut surface
|
||||
OpticalFinishMap["groundteflonair"]=groundteflonair; // rough-cut surface, with teflon
|
||||
OpticalFinishMap["groundtioair"]=groundtioair; // rough-cut surface, with tio paint
|
||||
OpticalFinishMap["groundtyvekair"]=groundtyvekair; // rough-cut surface, with tyvek
|
||||
OpticalFinishMap["groundvm2000air"]=groundvm2000air; // rough-cut surface, with esr film
|
||||
OpticalFinishMap["groundvm2000glue"]=groundvm2000glue; // rough-cut surface, with esr film & meltmount
|
||||
|
||||
|
||||
G4SurfaceType OpticalType = OpticalTypeMap[type];
|
||||
G4OpticalSurfaceModel OpticalModel = OpticalModelMap[model];
|
||||
G4OpticalSurfaceFinish OpticalFinish = OpticalFinishMap[finish];
|
||||
if ((OpticalType==0)&&(strcmp(type,"dielectric_metal")!=0)) {
|
||||
G4cout<<"ERROR! musrDetectorConstruction::Construct(): Optical type \""<<type<<"\" not found!"<<G4endl;
|
||||
G4cout << " ==> S T O P F O R C E D"<<G4endl;
|
||||
G4cout<<" "<<line;
|
||||
exit(1);
|
||||
}
|
||||
if ((OpticalModel==0)&&(strcmp(model,"glisur")!=0)) {
|
||||
G4cout<<"ERROR! musrDetectorConstruction::Construct(): Optical surface model \""<<model<<"\" not found!"<<G4endl;
|
||||
G4cout << " ==> S T O P F O R C E D"<<G4endl;
|
||||
G4cout<<" "<<line;
|
||||
exit(1);
|
||||
}
|
||||
if ((OpticalFinish==0)&&(strcmp(finish,"polished")!=0)) {
|
||||
G4cout<<"ERROR! musrDetectorConstruction::Construct(): Optical surface finish \""<<finish<<"\" not found!"<<G4endl;
|
||||
G4cout << " ==> S T O P F O R C E D"<<G4endl;
|
||||
G4cout<<" "<<line;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
optSurfTMP->SetType(OpticalType);
|
||||
optSurfTMP->SetFinish(OpticalFinish);
|
||||
optSurfTMP->SetModel(OpticalModel);
|
||||
// Assign the "Material properties table" if required by the user:
|
||||
G4cout<<"materialPropertiesTableName="<<materialPropertiesTableName<<G4endl;
|
||||
if (strcmp(materialPropertiesTableName,"Undefined")!=0) {
|
||||
G4MaterialPropertiesTable* MPT_tmp=NULL;
|
||||
itMPT = materialPropertiesTableMap.find(materialPropertiesTableName);
|
||||
if (itMPT==materialPropertiesTableMap.end()) { // G4MaterialPropertiesTable of this name does not exist --> problem
|
||||
G4cout<<"\n\n musrDetectorConstruction(): Material Properties Table \""<<materialPropertiesTableName
|
||||
<<"\" should be assigned to G4OpticalSurface \""<<optSurfaceName<<"\""<<G4endl;
|
||||
G4cout<<" but the table was not defined yet (by command /musr/command materialPropertiesTable )"<<G4endl;
|
||||
G4cout << "S T O P F O R C E D"<<G4endl;
|
||||
G4cout << line << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
MPT_tmp = itMPT->second;
|
||||
}
|
||||
optSurfTMP->SetMaterialPropertiesTable(MPT_tmp);
|
||||
G4cout<<optSurfTMP<<G4endl;
|
||||
optSurfTMP->GetMaterialPropertiesTable()->DumpTable();
|
||||
}
|
||||
G4cout<<"Optical surface \""<<optSurfaceName<<"\" created. OpticalType="<<OpticalType
|
||||
<<" OpticalFinish="<<OpticalFinish<<" OpticalModel="<<OpticalModel<<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(tmpString1,"OPSA")==0){ // optical photon signal analysis
|
||||
if (musrParameters::boolG4OpticalPhotons) {
|
||||
musrScintSD* myMusrScintSD = musrScintSD::GetInstance();
|
||||
if (myMusrScintSD==NULL) {
|
||||
sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): musrScintSD::GetInstance() is NULL - no musr/ScintSD set?");
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
|
||||
}
|
||||
char varName[100];
|
||||
float fVarValue;
|
||||
int iVarValue;
|
||||
sscanf(&line[0],"%*s %*s %s",varName);
|
||||
if (strcmp(varName,"minNrOfDetectedPhotons")==0) {
|
||||
sscanf(&line[0],"%*s %*s %*s %d",&iVarValue);
|
||||
myMusrScintSD -> Set_OPSA_minNrOfDetectedPhotons(iVarValue);
|
||||
}
|
||||
else if (strcmp(varName,"signalSeparationTime")==0) {
|
||||
sscanf(&line[0],"%*s %*s %*s %g",&fVarValue);
|
||||
myMusrScintSD -> Set_OPSA_SignalSeparationTime(fVarValue*nanosecond);
|
||||
}
|
||||
else if (strcmp(varName,"photonFractions")==0) {
|
||||
float a, b, c, d, e;
|
||||
sscanf(&line[0],"%*s %*s %*s %g %g %g %g %g",&a, &b, &c, &d, &e);
|
||||
myMusrScintSD -> Set_OPSA_frac(a,b,c,d,e);
|
||||
}
|
||||
else if (strcmp(varName,"eventsForOPSAhistos")==0) {
|
||||
int i_eventID, i_detectorID;
|
||||
sscanf(&line[0],"%*s %*s %*s %d %d",&i_eventID,&i_detectorID);
|
||||
myMusrScintSD -> AddEventIDToMultimapOfEventIDsForOPSAhistos(i_eventID,i_detectorID);
|
||||
}
|
||||
else if (strcmp(varName,"OPSAhist")==0) {
|
||||
int nBins;
|
||||
float min, max;
|
||||
sscanf(&line[0],"%*s %*s %*s %d %g %g",&nBins,&min,&max);
|
||||
myMusrScintSD -> SetOPSAhistoBinning(nBins,min*nanosecond,max*nanosecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cks: Implementation of the Global Field (to allow overlapping fields) based
|
||||
// on the Peter Gumplinger's implementation of G4BeamLine code into Geant4.
|
||||
//
|
||||
@ -823,7 +986,6 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
||||
int eventWeight;
|
||||
char tmpLogVolName[100];
|
||||
sscanf(&line[0],"%*s %*s %*s %s %d",tmpLogVolName,&eventWeight);
|
||||
musrSteppingAction* mySteppingAction = musrSteppingAction::GetInstance();
|
||||
mySteppingAction -> SetVolumeForMuonEventReweighting(G4String(tmpLogVolName),eventWeight);
|
||||
}
|
||||
else {
|
||||
@ -979,6 +1141,15 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
||||
if (strcmp(tmpString2,"det_VvvProcID")==0){musrRootOutput::store_det_VvvProcID = false;}
|
||||
if (strcmp(tmpString2,"det_VvvTrackID")==0){musrRootOutput::store_det_VvvTrackID = false;}
|
||||
if (strcmp(tmpString2,"det_VvvParticleID")==0){musrRootOutput::store_det_VvvParticleID = false;}
|
||||
if (strcmp(tmpString2,"odet_ID")==0) {musrRootOutput::store_odet_ID = false;}
|
||||
if (strcmp(tmpString2,"odet_nPhot")==0) {musrRootOutput::store_odet_nPhot = false;}
|
||||
if (strcmp(tmpString2,"odet_timeFirst")==0) {musrRootOutput::store_odet_timeFirst = false;}
|
||||
if (strcmp(tmpString2,"odet_timeA")==0) {musrRootOutput::store_odet_timeA = false;}
|
||||
if (strcmp(tmpString2,"odet_timeB")==0) {musrRootOutput::store_odet_timeB = false;}
|
||||
if (strcmp(tmpString2,"odet_timeC")==0) {musrRootOutput::store_odet_timeC = false;}
|
||||
if (strcmp(tmpString2,"odet_timeD")==0) {musrRootOutput::store_odet_timeD = false;}
|
||||
if (strcmp(tmpString2,"odet_timeE")==0) {musrRootOutput::store_odet_timeE = false;}
|
||||
if (strcmp(tmpString2,"odet_timeLast")==0) {musrRootOutput::store_odet_timeLast = false;}
|
||||
}
|
||||
else if(strcmp(storeIt,"on")==0) {
|
||||
if (strcmp(tmpString2,"fieldIntegralBx")==0){musrRootOutput::store_fieldIntegralBx = true;}
|
||||
@ -991,12 +1162,13 @@ G4VPhysicalVolume* musrDetectorConstruction::Construct() {
|
||||
if ((musrRootOutput::store_fieldIntegralBx)||(musrRootOutput::store_fieldIntegralBy)||
|
||||
(musrRootOutput::store_fieldIntegralBz)||(musrRootOutput::store_fieldIntegralBz1)||
|
||||
(musrRootOutput::store_fieldIntegralBz2)||(musrRootOutput::store_fieldIntegralBz3) ) {
|
||||
musrSteppingAction::GetInstance()->SetCalculationOfFieldIntegralRequested(true);
|
||||
mySteppingAction -> SetCalculationOfFieldIntegralRequested(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(tmpString1,"process")==0) {
|
||||
else if ((strcmp(tmpString1,"process")==0)||(strcmp(tmpString1,"G4OpticalPhotons")==0)
|
||||
||(strcmp(tmpString1,"materialPropertiesTable")==0)||(strcmp(tmpString1,"setMaterialPropertiesTable")==0)) {
|
||||
; // processes are interpreded later in musrPhysicsList.cc
|
||||
}
|
||||
|
||||
@ -1133,49 +1305,140 @@ void musrDetectorConstruction::DefineMaterials()
|
||||
|
||||
new G4Material("ArgonGas", z= 18., a= 39.95*g/mole, density= 0.00000000001*mg/cm3);
|
||||
|
||||
if (musrParameters::boolG4OpticalPhotons) {
|
||||
G4NistManager* man = G4NistManager::Instance();
|
||||
G4Material* scintik = man->FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
|
||||
// G4Material* scintik = G4Material::GetMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
|
||||
G4cout<<"scintik="<<scintik<<G4endl;
|
||||
if (scintik!=NULL) {
|
||||
const G4int nEntries = 14;
|
||||
G4double PhotonEnergy[nEntries] =
|
||||
{ 2.695*eV, 2.75489*eV, 2.8175*eV, 2.88302*eV, // 460, 450, 440, 430 nm
|
||||
2.95167*eV, 3.02366*eV, 3.09925*eV, 3.17872*eV, 3.26237*eV, // 420, 410, 400, 390, 380 nm
|
||||
3.30587*eV, 3.35054*eV, 3.44361*eV, 3.542*eV, 3.64618*eV }; // 375, 370, 360, 350, 340 nm
|
||||
G4double RefractiveIndex[nEntries] =
|
||||
{ 1.58, 1.58, 1.58, 1.58,
|
||||
1.58, 1.58, 1.58, 1.58, 1.58,
|
||||
1.58, 1.58, 1.58, 1.58, 1.58 };
|
||||
G4double Absorption[nEntries] =
|
||||
{ 8*cm, 8*cm, 8*cm, 8*cm,
|
||||
8*cm, 8*cm, 8*cm, 8*cm, 8*cm,
|
||||
8*cm, 8*cm, 8*cm, 8*cm, 8*cm };
|
||||
G4double ScintilFast[nEntries] =
|
||||
{ 0.01, 0.07, 0.15, 0.26,
|
||||
0.375, 0.52, 0.65, 0.80, 0.95,
|
||||
1, 0.88, 0.44, 0.08, 0.01 };
|
||||
G4double ScintilSlow[nEntries] =
|
||||
{ 0.01, 0.07, 0.15, 0.26,
|
||||
0.375, 0.52, 0.65, 0.80, 0.95,
|
||||
1, 0.88, 0.44, 0.08, 0.01 };
|
||||
G4MaterialPropertiesTable* myMPT1 = new G4MaterialPropertiesTable();
|
||||
myMPT1->AddProperty("RINDEX", PhotonEnergy, RefractiveIndex, nEntries);
|
||||
myMPT1->AddProperty("ABSLENGTH", PhotonEnergy, Absorption, nEntries);
|
||||
myMPT1->AddProperty("FASTCOMPONENT", PhotonEnergy, ScintilFast, nEntries);
|
||||
myMPT1->AddProperty("SLOWCOMPONENT", PhotonEnergy, ScintilSlow, nEntries);
|
||||
myMPT1->AddConstProperty("SCINTILLATIONYIELD", 8400./MeV);
|
||||
myMPT1->AddConstProperty("RESOLUTIONSCALE",1.0);
|
||||
myMPT1->AddConstProperty("FASTTIMECONSTANT",1.6*ns);
|
||||
myMPT1->AddConstProperty("SLOWTIMECONSTANT",1.6*ns);
|
||||
myMPT1->AddConstProperty("YIELDRATIO",1.0);
|
||||
scintik->SetMaterialPropertiesTable(myMPT1);
|
||||
|
||||
scintik->GetMaterialPropertiesTable()->DumpTable();
|
||||
if (musrParameters::boolG4OpticalPhotons) {
|
||||
|
||||
FILE *fSteeringFile=fopen(parameterFileName.c_str(),"r");
|
||||
if (fSteeringFile) {
|
||||
char line[5001];
|
||||
while (!feof(fSteeringFile)) {
|
||||
fgets(line,5000,fSteeringFile);
|
||||
if ((line[0]!='#')&&(line[0]!='\n')&&(line[0]!='\r')) {
|
||||
char tmpString0[100]="Unset";
|
||||
sscanf(&line[0],"%s",tmpString0);
|
||||
if ( (strcmp(tmpString0,"/musr/ignore")!=0) &&(strcmp(tmpString0,"/musr/command")!=0) ) continue;
|
||||
|
||||
|
||||
char tmpString1[100]="Unset",tmpString2[100]="Unset";
|
||||
sscanf(&line[0],"%*s %s %s",tmpString1,tmpString2);
|
||||
if (strcmp(tmpString1,"materialPropertiesTable")==0){
|
||||
std::string materialPropertiesTableName=tmpString2;
|
||||
G4MaterialPropertiesTable* MPT_tmp;
|
||||
itMPT = materialPropertiesTableMap.find(materialPropertiesTableName);
|
||||
if (itMPT==materialPropertiesTableMap.end()) { // G4MaterialPropertiesTable of this name does not exist yet --> create it
|
||||
MPT_tmp = new G4MaterialPropertiesTable();
|
||||
materialPropertiesTableMap.insert ( std::pair<std::string,G4MaterialPropertiesTable*>(materialPropertiesTableName,MPT_tmp) );
|
||||
}
|
||||
else {
|
||||
MPT_tmp = itMPT->second;
|
||||
}
|
||||
|
||||
char propertyName[100];
|
||||
int nEntries;
|
||||
sscanf(&line[0],"%*s %*s %*s %s %d",propertyName,&nEntries);
|
||||
std::cout<<" Optical Material Def: MPT_tmp="<<MPT_tmp<<", materialPropertiesTableName="<<materialPropertiesTableName
|
||||
<<", propertyName="<<propertyName<<", nEntries="<<nEntries<<std::endl;
|
||||
|
||||
if (nEntries==0) { // AddConstProperty
|
||||
float value;
|
||||
sscanf(&line[0],"%*s %*s %*s %*s %*d %g",&value);
|
||||
MPT_tmp->AddConstProperty(propertyName,value);
|
||||
}
|
||||
else { // AddProperty
|
||||
char* pch = strstr(line,propertyName)+strlen(propertyName);
|
||||
float value;
|
||||
G4double photonEnergyArray[100];
|
||||
G4double valueArray[100];
|
||||
char dummy[100];
|
||||
sscanf(pch,"%s",dummy); char* pch2=strstr(pch,dummy)+strlen(dummy); pch = pch2;
|
||||
for (int i=0; i<nEntries; i++) {
|
||||
sscanf(pch,"%g",&value);
|
||||
// G4cout<<" DDDDD var1="<<value<<" &pch="<<&pch<<G4endl;
|
||||
photonEnergyArray[i]=value;
|
||||
sscanf(pch,"%s",dummy); char* pch2=strstr(pch,dummy)+strlen(dummy); pch = pch2;
|
||||
}
|
||||
for (int i=0; i<nEntries; i++) {
|
||||
sscanf(pch,"%g",&value);
|
||||
// G4cout<<" DDDDD var2="<<value<<" &pch="<<&pch<<G4endl;
|
||||
valueArray[i]=value;
|
||||
sscanf(pch,"%s",dummy); char* pch2=strstr(pch,dummy)+strlen(dummy); pch = pch2;
|
||||
}
|
||||
MPT_tmp->AddProperty(propertyName,photonEnergyArray,valueArray,nEntries);
|
||||
}
|
||||
}
|
||||
else if (strcmp(tmpString1,"setMaterialPropertiesTable")==0){
|
||||
char tmpString3[100]="Unset";
|
||||
sscanf(&line[0],"%*s %*s %*s %s",tmpString3);
|
||||
std::string materialPropertiesTableName=tmpString2;
|
||||
std::string materialName = tmpString3;
|
||||
G4NistManager* man = G4NistManager::Instance();
|
||||
G4Material* myMaterial = man->FindOrBuildMaterial(materialName);
|
||||
|
||||
G4MaterialPropertiesTable* MPT_tmp=NULL;
|
||||
itMPT = materialPropertiesTableMap.find(materialPropertiesTableName);
|
||||
if (itMPT==materialPropertiesTableMap.end()) { // G4MaterialPropertiesTable of this name does not exist --> problem
|
||||
G4cout<<"\n\n musrDetectorConstruction::DefineMaterials(): Material Properties Table \""<<materialPropertiesTableName
|
||||
<<"\" should be assigned to material \""<<materialName<<"\""<<G4endl;
|
||||
G4cout<<" but the table was not defined yet (by command /musr/command materialPropertiesTable )"<<G4endl;
|
||||
G4cout <<" ===> S T O P F O R C E D"<<G4endl;
|
||||
G4cout<<line<<G4endl;
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
MPT_tmp = itMPT->second;
|
||||
}
|
||||
myMaterial->SetMaterialPropertiesTable(MPT_tmp);
|
||||
G4cout<<myMaterial<<G4endl;
|
||||
myMaterial->GetMaterialPropertiesTable()->DumpTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
G4cout<<"OK konec"<<G4endl;
|
||||
exit(0);
|
||||
fclose(fSteeringFile);
|
||||
|
||||
// G4cout<<" 1eV = "<<eV<<G4endl;
|
||||
// G4cout<<" 1MeV = "<<MeV<<G4endl;
|
||||
// G4cout<<" 1ns = "<<ns<<G4endl;
|
||||
//
|
||||
// G4NistManager* man = G4NistManager::Instance();
|
||||
// G4Material* scintik = man->FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
|
||||
// G4cout<<"scintik="<<scintik<<G4endl;
|
||||
// if (scintik!=NULL) {
|
||||
// const G4int nEntries = 14;
|
||||
// G4double PhotonEnergy[nEntries] =
|
||||
// { 2.695*eV, 2.75489*eV, 2.8175*eV, 2.88302*eV, // 460, 450, 440, 430 nm
|
||||
// 2.95167*eV, 3.02366*eV, 3.09925*eV, 3.17872*eV, 3.26237*eV, // 420, 410, 400, 390, 380 nm
|
||||
// 3.30587*eV, 3.35054*eV, 3.44361*eV, 3.542*eV, 3.64618*eV }; // 375, 370, 360, 350, 340 nm
|
||||
// G4double RefractiveIndex[nEntries] =
|
||||
// { 1.58, 1.58, 1.58, 1.58,
|
||||
// 1.58, 1.58, 1.58, 1.58, 1.58,
|
||||
// 1.58, 1.58, 1.58, 1.58, 1.58 };
|
||||
// G4double Absorption[nEntries] =
|
||||
// { 8*cm, 8*cm, 8*cm, 8*cm,
|
||||
// 8*cm, 8*cm, 8*cm, 8*cm, 8*cm,
|
||||
// 8*cm, 8*cm, 8*cm, 8*cm, 8*cm };
|
||||
// G4double ScintilFast[nEntries] =
|
||||
// { 0.01, 0.07, 0.15, 0.26,
|
||||
// 0.375, 0.52, 0.65, 0.80, 0.95,
|
||||
// 1, 0.88, 0.44, 0.08, 0.01 };
|
||||
// G4double ScintilSlow[nEntries] =
|
||||
// { 0.01, 0.07, 0.15, 0.26,
|
||||
// 0.375, 0.52, 0.65, 0.80, 0.95,
|
||||
// 1, 0.88, 0.44, 0.08, 0.01 };
|
||||
// G4MaterialPropertiesTable* myMPT1 = new G4MaterialPropertiesTable();
|
||||
// myMPT1->AddProperty("RINDEX", PhotonEnergy, RefractiveIndex, nEntries);
|
||||
// myMPT1->AddProperty("ABSLENGTH", PhotonEnergy, Absorption, nEntries);
|
||||
// myMPT1->AddProperty("FASTCOMPONENT", PhotonEnergy, ScintilFast, nEntries);
|
||||
// myMPT1->AddProperty("SLOWCOMPONENT", PhotonEnergy, ScintilSlow, nEntries);
|
||||
// myMPT1->AddConstProperty("SCINTILLATIONYIELD", 8400./MeV);
|
||||
// myMPT1->AddConstProperty("RESOLUTIONSCALE",1.0);
|
||||
// myMPT1->AddConstProperty("FASTTIMECONSTANT",1.6*ns);
|
||||
// myMPT1->AddConstProperty("SLOWTIMECONSTANT",1.6*ns);
|
||||
// myMPT1->AddConstProperty("YIELDRATIO",1.0);
|
||||
// scintik->SetMaterialPropertiesTable(myMPT1);
|
||||
|
||||
// scintik->GetMaterialPropertiesTable()->DumpTable();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1240,6 +1503,25 @@ G4LogicalVolume* musrDetectorConstruction::FindLogicalVolume(G4String LogicalVol
|
||||
return NULL;
|
||||
}
|
||||
|
||||
G4VPhysicalVolume* musrDetectorConstruction::FindPhysicalVolume(G4String PhysicalVolumeName) {
|
||||
G4PhysicalVolumeStore* pPhysStore = G4PhysicalVolumeStore::GetInstance();
|
||||
if (pPhysStore==NULL) {
|
||||
G4cout<<"ERROR: musrDetectorConstruction.cc: G4PhysicalVolumeStore::GetInstance() not found!"<<G4endl;
|
||||
}
|
||||
else {
|
||||
for (unsigned int i=0; i<pPhysStore->size(); i++) {
|
||||
G4VPhysicalVolume* pPhysVol=pPhysStore->at(i);
|
||||
G4String iPhysName=pPhysVol->GetName();
|
||||
if (iPhysName==PhysicalVolumeName) {
|
||||
return pPhysVol;
|
||||
}
|
||||
}
|
||||
}
|
||||
G4cout<<"\n musrDetectorConstruction.cc::FindPhysicalVolume: \n ERROR !!! Physical volume "
|
||||
<<PhysicalVolumeName<<" not found !!!"<<G4endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void musrDetectorConstruction::SetColourOfLogicalVolume(G4LogicalVolume* pLogVol,char* colour) {
|
||||
if (pLogVol!=NULL) {
|
||||
if (strcmp(colour,"red" )==0) {pLogVol->SetVisAttributes(G4Colour(1,0,0));}
|
||||
|
@ -77,6 +77,8 @@ void musrEventAction::BeginOfEventAction(const G4Event* evt) {
|
||||
void musrEventAction::EndOfEventAction(const G4Event* evt) {
|
||||
// cout << ":." << flush;
|
||||
long thisEventNr = (long) evt->GetEventID();
|
||||
|
||||
// musrSteppingAction::GetInstance()->DoAtTheEndOfEvent();
|
||||
|
||||
// write out the root tree:
|
||||
musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "G4StepLimiter.hh"
|
||||
#include "G4UserSpecialCuts.hh"
|
||||
|
||||
#include "G4OpticalPhysics.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrPhysicsList::musrPhysicsList(): G4VUserPhysicsList()
|
||||
@ -55,6 +57,26 @@ musrPhysicsList::musrPhysicsList(): G4VUserPhysicsList()
|
||||
cutForElectron = 0.1*mm;
|
||||
cutForMuon = 0.01*mm;
|
||||
SetVerboseLevel(0);
|
||||
|
||||
if (musrParameters::boolG4OpticalPhotons) {
|
||||
|
||||
|
||||
// // * Optical Physics
|
||||
// G4OpticalPhysics* opticalPhysics = new G4OpticalPhysics();
|
||||
// RegisterPhysics( opticalPhysics );
|
||||
//
|
||||
// // adjust some parameters for the optical physics
|
||||
// opticalPhysics->SetWLSTimeProfile("delta");
|
||||
//
|
||||
// opticalPhysics->SetScintillationYieldFactor(1.0);
|
||||
// opticalPhysics->SetScintillationExcitationRatio(0.0);
|
||||
//
|
||||
// opticalPhysics->SetMaxNumPhotonsPerStep(100);
|
||||
// opticalPhysics->SetMaxBetaChangePerStep(10.0);
|
||||
//
|
||||
// opticalPhysics->SetTrackSecondariesFirst(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@ -71,6 +93,13 @@ void musrPhysicsList::ConstructParticle()
|
||||
ConstructLeptons();
|
||||
ConstructMesons();
|
||||
ConstructBaryons();
|
||||
|
||||
if (musrParameters::boolG4OpticalPhotons) {
|
||||
// optical photon
|
||||
G4OpticalPhoton::OpticalPhotonDefinition();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@ -234,6 +263,9 @@ void musrPhysicsList::ConstructProcess()
|
||||
// For a simple Muonium "scattering" when Mu hits solid materials
|
||||
#include "musrMuScatter.hh"
|
||||
|
||||
// For optical photons
|
||||
#include "G4Scintillation.hh"
|
||||
|
||||
// For models
|
||||
#include "G4ProcessTable.hh"
|
||||
#include "G4WentzelVIModel.hh"
|
||||
@ -273,6 +305,11 @@ void musrPhysicsList::ConstructEM()
|
||||
G4ParticleDefinition* particleDefinition = G4ParticleTable::GetParticleTable() -> FindParticle(stringParticleName);
|
||||
// G4cout<<"particleDefinition of "<<stringParticleName<<" = "<<particleDefinition<<G4endl;
|
||||
if (particleDefinition==NULL) {
|
||||
if ((stringParticleName=="opticalphoton")&& (!(musrParameters::boolG4OpticalPhotons))) {
|
||||
musrErrorMessage::GetInstance()->musrError(INFO,
|
||||
"musrPhysicsList: Ignoring optical photon process definition because G4OpticalPhotons in *.mac file is set to false",false);
|
||||
continue;
|
||||
}
|
||||
sprintf(eMessage,"musrPhysicsList: Partile \"%s\" not found in G4ParticleTable when trying to find or assign process \"%s\".",
|
||||
charParticleName,charProcessName);
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
|
||||
@ -294,6 +331,11 @@ void musrPhysicsList::ConstructEM()
|
||||
else if (stringProcessName=="G4LowEnergyRayleigh") pManager->AddDiscreteProcess(new G4LowEnergyRayleigh);
|
||||
|
||||
else if (stringProcessName=="G4CoulombScattering") pManager->AddDiscreteProcess(new G4CoulombScattering);
|
||||
|
||||
else if (stringProcessName=="G4OpAbsorption") pManager->AddDiscreteProcess(new G4OpAbsorption);
|
||||
else if (stringProcessName=="G4OpRayleigh") pManager->AddDiscreteProcess(new G4OpRayleigh);
|
||||
else if (stringProcessName=="G4OpBoundaryProcess") pManager->AddDiscreteProcess(new G4OpBoundaryProcess);
|
||||
else if (stringProcessName=="G4OpWLS") pManager->AddDiscreteProcess(new G4OpWLS);
|
||||
else {
|
||||
sprintf(eMessage,"musrPhysicsList: Process \"%s\" is not implemented in musrPhysicsList.cc for addDiscreteProcess. It can be easily added.",
|
||||
charProcessName);
|
||||
@ -325,6 +367,7 @@ void musrPhysicsList::ConstructEM()
|
||||
// else if (stringProcessName=="G4hIonisation") pManager->AddProcess(new G4hIonisation,nr1,nr2,nr3);
|
||||
// else if (stringProcessName=="G4hLowEnergyIonisation") pManager->AddProcess(new G4hLowEnergyIonisation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="musrMuFormation") pManager->AddProcess(new musrMuFormation,nr1,nr2,nr3);
|
||||
else if (stringProcessName=="G4Scintillation") pManager->AddProcess(new G4Scintillation,nr1,nr2,nr3);
|
||||
// cks: musrMuScatter could be uncommented here, but testing is needed, because Toni has some strange comments
|
||||
// in his original "musrPhysicsList.cc about implementing musrMuScatter.
|
||||
// else if (stringProcessName=="musrMuScatter") pManager->AddProcess(new musrMuScatter,nr1,nr2,nr3);
|
||||
@ -394,7 +437,6 @@ void musrPhysicsList::ConstructEM()
|
||||
G4MuMultipleScattering* mmm = (G4MuMultipleScattering*) processTable->FindProcess("muMsc",particleDefinition);
|
||||
mmm->AddEmModel(modelPriority, new G4UrbanMscModel93());
|
||||
}
|
||||
|
||||
else {
|
||||
sprintf(eMessage,"musrPhysicsList: Model \"%s\" is not implemented for \"%s\" in musrPhysicsList.cc for addModel. It can be easily added.",
|
||||
charModelName,charProcessName);
|
||||
|
@ -147,6 +147,16 @@ G4bool musrRootOutput::store_fieldIntegralBz = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBz1 = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBz2 = false;
|
||||
G4bool musrRootOutput::store_fieldIntegralBz3 = false;
|
||||
G4bool musrRootOutput::store_odet_ID = true;
|
||||
G4bool musrRootOutput::store_odet_nPhot = true;
|
||||
G4bool musrRootOutput::store_odet_timeFirst = true;
|
||||
G4bool musrRootOutput::store_odet_timeA = true;
|
||||
G4bool musrRootOutput::store_odet_timeB = true;
|
||||
G4bool musrRootOutput::store_odet_timeC = true;
|
||||
G4bool musrRootOutput::store_odet_timeD = true;
|
||||
G4bool musrRootOutput::store_odet_timeE = true;
|
||||
G4bool musrRootOutput::store_odet_timeLast = true;
|
||||
|
||||
|
||||
G4int musrRootOutput::oldEventNumberInG4EqEMFieldWithSpinFunction=-1;
|
||||
|
||||
@ -265,6 +275,19 @@ void musrRootOutput::BeginOfRunAction() {
|
||||
rootTree->Branch("save_poly",&save_poly,"save_poly[save_n]/D");
|
||||
rootTree->Branch("save_polz",&save_polz,"save_polz[save_n]/D");
|
||||
}
|
||||
|
||||
if (store_odet_ID || store_odet_nPhot || store_odet_timeFirst || store_odet_timeA || store_odet_timeB ||
|
||||
store_odet_timeC || store_odet_timeD || store_odet_timeE || store_odet_timeLast)
|
||||
{rootTree->Branch("odet_n",&odet_n,"odet_n/I");}
|
||||
if (store_odet_ID) {rootTree->Branch("odet_ID",&odet_ID,"odet_ID[odet_n]/I");}
|
||||
if (store_odet_nPhot) {rootTree->Branch("odet_nPhot",&odet_nPhot,"odet_nPhot[odet_n]/I");}
|
||||
if (store_odet_timeFirst) {rootTree->Branch("odet_timeFirst",&odet_timeFirst,"odet_timeFirst[odet_n]/D");}
|
||||
if (store_odet_timeA) {rootTree->Branch("odet_timeA",&odet_timeA,"odet_timeA[odet_n]/D");}
|
||||
if (store_odet_timeB) {rootTree->Branch("odet_timeB",&odet_timeB,"odet_timeB[odet_n]/D");}
|
||||
if (store_odet_timeC) {rootTree->Branch("odet_timeC",&odet_timeC,"odet_timeC[odet_n]/D");}
|
||||
if (store_odet_timeD) {rootTree->Branch("odet_timeD",&odet_timeD,"odet_timeD[odet_n]/D");}
|
||||
if (store_odet_timeE) {rootTree->Branch("odet_timeE",&odet_timeE,"odet_timeE[odet_n]/D");}
|
||||
if (store_odet_timeLast) {rootTree->Branch("odet_timeLast",&odet_timeLast,"odet_timeLast[odet_n]/D");}
|
||||
|
||||
// htest1 = new TH1F("htest1","The debugging histogram 1",50,-4.,4.);
|
||||
// htest2 = new TH1F("htest2","The debugging histogram 2",50,0.,3.142);
|
||||
@ -317,7 +340,7 @@ void musrRootOutput::FillEvent() {
|
||||
htest5->Fill(atan2(posIniMomy,posIniMomx));
|
||||
htest6->Fill(atan2(sqrt(posIniMomx*posIniMomx+posIniMomy*posIniMomy),posIniMomz));
|
||||
if (weight>0.) {
|
||||
if ( !((musrParameters::storeOnlyEventsWithHits)&&(det_n<=0)) ) {
|
||||
if ( !((musrParameters::storeOnlyEventsWithHits)&&(det_n<=0)&&(odet_n<=0)) ) {
|
||||
rootTree->Fill();
|
||||
}
|
||||
}
|
||||
@ -349,7 +372,7 @@ void musrRootOutput::ClearAllRootVariables() {
|
||||
BzIntegral1 = -1000; BzIntegral2 = -1000; BzIntegral3 = -1000;
|
||||
det_n=0;
|
||||
save_n=0;
|
||||
|
||||
odet_n=0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@ -498,3 +521,27 @@ void musrRootOutput::SetDetectorInfoVvv (G4int nDetectors,
|
||||
det_VvvParticleID[nDetectors]=particleID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void musrRootOutput::SetOPSAinfo (G4int nDetectors, G4int ID, G4int nPhot, G4double timeFirst, G4double timeA,
|
||||
G4double timeB, G4double timeC, G4double timeD, G4double timeE, G4double timeLast)
|
||||
{
|
||||
if ((nDetectors<0)||(nDetectors>=(odet_nMax-1))) {
|
||||
char message[200];
|
||||
sprintf(message,"musrRootOutput.cc::SetOPSAInfo: nDetectors %i is larger than det_nMax = %i",nDetectors,det_nMax);
|
||||
musrErrorMessage::GetInstance()->musrError(SERIOUS,message,false);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
odet_n=nDetectors+1;
|
||||
odet_ID[nDetectors]=ID;
|
||||
odet_nPhot[nDetectors]=nPhot;
|
||||
odet_timeFirst[nDetectors]=timeFirst/microsecond;
|
||||
odet_timeA[nDetectors]=timeA/microsecond;
|
||||
odet_timeB[nDetectors]=timeB/microsecond;
|
||||
odet_timeC[nDetectors]=timeC/microsecond;
|
||||
odet_timeD[nDetectors]=timeD/microsecond;
|
||||
odet_timeE[nDetectors]=timeE/microsecond;
|
||||
odet_timeLast[nDetectors]=timeLast/microsecond;
|
||||
}
|
||||
}
|
||||
|
@ -29,9 +29,14 @@
|
||||
#include "G4ios.hh"
|
||||
#include <algorithm> // needed for the sort() function
|
||||
#include "G4VProcess.hh" // needed for the degugging message of the process name
|
||||
#include "G4OpBoundaryProcess.hh" // Optical photon process
|
||||
#include "G4RunManager.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "musrSteppingAction.hh"
|
||||
//#include "TCanvas.h"
|
||||
#include "TMath.h"
|
||||
#include "TF1.h"
|
||||
#include <vector>
|
||||
|
||||
//bool myREMOVEfunction (int i,int j) { return (i<j); }
|
||||
@ -49,17 +54,38 @@
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
Double_t poissonf(Double_t* x, Double_t* par) {
|
||||
return par[0]*TMath::Poisson(x[0],par[1]);
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
musrScintSD::musrScintSD(G4String name)
|
||||
:G4VSensitiveDetector(name)
|
||||
{
|
||||
pointer=this;
|
||||
G4String HCname;
|
||||
collectionName.insert(HCname="scintCollection");
|
||||
OPSA_minNrOfDetectedPhotons = 1;
|
||||
OPSA_signalSeparationTime = 10.;
|
||||
OPSA_fracA = 0.01;
|
||||
OPSA_fracB = 0.05;
|
||||
OPSA_fracC = 0.10;
|
||||
OPSA_fracD = 0.20;
|
||||
OPSA_fracE = 0.5;
|
||||
bool_multimapOfEventIDsForOPSAhistosEXISTS = false;
|
||||
OPSAhistoNbin = 100;
|
||||
OPSAhistoMin =0;
|
||||
OPSAhistoMax = 10.;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
musrScintSD::~musrScintSD(){ }
|
||||
|
||||
musrScintSD* musrScintSD::pointer=NULL;
|
||||
musrScintSD* musrScintSD::GetInstance() {return pointer;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrScintSD::Initialize(G4HCofThisEvent* HCE) {
|
||||
@ -78,6 +104,7 @@ void musrScintSD::Initialize(G4HCofThisEvent* HCE) {
|
||||
myStoreOnlyEventsWithHitInDetID = musrParameters::storeOnlyEventsWithHitInDetID;
|
||||
musrSteppingAction* myMusrSteppingAction = musrSteppingAction::GetInstance();
|
||||
boolIsVvvInfoRequested = myMusrSteppingAction->IsVvvInfoRequested();
|
||||
myRootOutput = musrRootOutput::GetRootInstance();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@ -91,7 +118,15 @@ G4bool musrScintSD::ProcessHits(G4Step* aStep,G4TouchableHistory*)
|
||||
}
|
||||
|
||||
G4Track* aTrack = aStep->GetTrack();
|
||||
G4String actualVolume=aTrack->GetVolume()->GetLogicalVolume()->GetName();
|
||||
// G4LogicalVolume* hitLogicalVolume = aTrack->GetVolume()->GetLogicalVolume();
|
||||
// G4String actualVolume=aTrack->GetVolume()->GetLogicalVolume()->GetName();
|
||||
G4String hitLogicalVolumeName = aTrack->GetVolume()->GetLogicalVolume()->GetName();
|
||||
G4String particleName=aTrack->GetDefinition()->GetParticleName();
|
||||
// if (particleName=="opticalphoton") {G4cout<<"UFON JE TU: edep="<<edep<<G4endl; return false;}
|
||||
if (particleName=="opticalphoton") {
|
||||
ProcessOpticalPhoton(aStep);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If requested, store only the hit that happened first (usefull for some special studies, not for a serious simulation)
|
||||
if (myStoreOnlyTheFirstTimeHit) {
|
||||
@ -101,17 +136,21 @@ G4bool musrScintSD::ProcessHits(G4Step* aStep,G4TouchableHistory*)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
musrScintHit* newHit = new musrScintHit();
|
||||
newHit->SetParticleName (aTrack->GetDefinition()->GetParticleName());
|
||||
// newHit->SetParticleName (aTrack->GetDefinition()->GetParticleName());
|
||||
newHit->SetParticleName(particleName);
|
||||
G4int particleID = aTrack->GetDefinition()->GetPDGEncoding();
|
||||
newHit->SetParticleID (particleID);
|
||||
newHit->SetEdep (edep);
|
||||
newHit->SetPrePos (aStep->GetPreStepPoint()->GetPosition());
|
||||
newHit->SetPostPos (aStep->GetPostStepPoint()->GetPosition());
|
||||
newHit->SetPol (aTrack->GetPolarization());
|
||||
G4LogicalVolume* hitLogicalVolume = aTrack->GetVolume()->GetLogicalVolume();
|
||||
newHit->SetLogVolName(hitLogicalVolume->GetName());
|
||||
// G4LogicalVolume* hitLogicalVolume = aTrack->GetVolume()->GetLogicalVolume();
|
||||
newHit->SetLogVolName(hitLogicalVolumeName);
|
||||
// newHit->SetLogVolName(hitLogicalVolume->GetName());
|
||||
newHit->SetGlobTime(aTrack->GetGlobalTime());
|
||||
// Warning - aStep->IsFirstStepInVolume() only available in Geant version >= 4.8.2 !
|
||||
// newHit->SetFirstStepInVolumeFlag(aStep->IsFirstStepInVolume());
|
||||
@ -141,6 +180,94 @@ G4bool musrScintSD::ProcessHits(G4Step* aStep,G4TouchableHistory*)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrScintSD::ProcessOpticalPhoton(G4Step* aStep) {
|
||||
// //Was the photon absorbed by the absorption process ?
|
||||
// const G4VProcess* process = aStep->GetPostStepPoint()->GetProcessDefinedStep();
|
||||
// G4String processName = (process) ? process->GetProcessName() : "Unknown";
|
||||
// G4cout<<"processName="<<processName<<G4endl;
|
||||
// if (processName=="OpAbsorption") {
|
||||
// G4cout<<"\n ABSORPTION\n";
|
||||
// }
|
||||
|
||||
|
||||
G4OpBoundaryProcessStatus boundaryStatus=Undefined;
|
||||
static G4OpBoundaryProcess* boundaryProc=NULL;
|
||||
//find the boundary process only once
|
||||
if(!boundaryProc){
|
||||
G4ProcessManager* pm = aStep->GetTrack()->GetDefinition()->GetProcessManager();
|
||||
G4int nprocesses = pm->GetProcessListLength();
|
||||
G4ProcessVector* pv = pm->GetProcessList();
|
||||
for(G4int i=0; i<nprocesses; i++){
|
||||
if((*pv)[i]->GetProcessName()=="OpBoundary"){
|
||||
boundaryProc = (G4OpBoundaryProcess*)(*pv)[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boundaryStatus=boundaryProc->GetStatus();
|
||||
|
||||
//Check to see if the partcile was actually at a boundary
|
||||
//Otherwise the boundary status may not be valid
|
||||
//Prior to Geant4.6.0-p1 this would not have been enough to check
|
||||
if(aStep->GetPostStepPoint()->GetStepStatus()==fGeomBoundary){
|
||||
// G4cout<<" boundaryStatus="<<boundaryStatus<<" ";
|
||||
G4String actualVolume = aStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetName();
|
||||
Int_t detID = myRootOutput->ConvertVolumeToID(actualVolume);
|
||||
// G4cout<<" detID ="<<detID<<" actualVolume="<<actualVolume;
|
||||
optHitMapType::iterator iter = optHitMap.find(detID);
|
||||
if (iter==optHitMap.end()) { // optHitDetectorMapType does not exist ==> create it
|
||||
optHitDetectorMapType* optHitDetectorMapTmp = new optHitDetectorMapType;
|
||||
optHitMap.insert(std::pair<Int_t,optHitDetectorMapType*>(detID,optHitDetectorMapTmp));
|
||||
iter = optHitMap.find(detID);
|
||||
}
|
||||
optHitDetectorMapType* optHitDetectorMap = (*iter).second;
|
||||
// optHitDetectorMapType optHitDetectorMap = optHitMap[detID];
|
||||
G4double tmpTime = aStep->GetPreStepPoint()->GetGlobalTime();
|
||||
// G4cout<<" tmpTime="<<tmpTime;
|
||||
// optHitDetectorMap->insert(std::pair<G4double,G4int>(tmpTime,boundaryStatus));
|
||||
|
||||
if (boundaryStatus!=Detection) {
|
||||
char message[200];
|
||||
sprintf(message,"musrScintSD.cc::ProcessOpticalPhoton(): Optical photon boundary status is not Detection but %i",boundaryStatus);
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,message,false);
|
||||
}
|
||||
|
||||
// switch(boundaryStatus){
|
||||
// case Absorption:
|
||||
// G4cout<<" AAAAAAAAAAAAAAAAAA Absorption"<<G4endl;
|
||||
// break;
|
||||
// case Detection: //Note, this assumes that the volume causing detection
|
||||
//is the photocathode because it is the only one with
|
||||
//non-zero efficiency
|
||||
optHitDetectorMap->insert(std::pair<G4double,G4int>(tmpTime,boundaryStatus));
|
||||
// G4cout<<" Detection"<<G4endl;
|
||||
// break;
|
||||
// case FresnelReflection:
|
||||
// case LambertianReflection:
|
||||
// case LobeReflection:
|
||||
// case TotalInternalReflection:
|
||||
// case SpikeReflection:
|
||||
// G4cout<<" Reflection"<<G4endl;
|
||||
// break;
|
||||
// case StepTooSmall:
|
||||
// G4cout<<" StepTooSmall"<<G4endl;
|
||||
// break;
|
||||
// case NoRINDEX:
|
||||
// G4cout<<" NoRINDEX"<<G4endl;
|
||||
// break;
|
||||
// // case :
|
||||
// // G4cout<<" "<<G4endl;
|
||||
// // break;
|
||||
// default:
|
||||
// G4cout<<" SomethingElse"<<G4endl;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void musrScintSD::EndOfEvent(G4HCofThisEvent*) {
|
||||
if (verboseLevel>1) {
|
||||
G4cout<<"VERBOSE 2: musrScintSD::EndOfEvent"<<G4endl;
|
||||
@ -149,8 +276,6 @@ void musrScintSD::EndOfEvent(G4HCofThisEvent*) {
|
||||
<< " hits in the scint chambers: " << G4endl;
|
||||
}
|
||||
|
||||
// Positron_momentum_already_stored=0;
|
||||
musrRootOutput* myRootOutput = musrRootOutput::GetRootInstance();
|
||||
|
||||
G4int NbHits = scintCollection->entries();
|
||||
|
||||
@ -367,6 +492,144 @@ void musrScintSD::EndOfEvent(G4HCofThisEvent*) {
|
||||
|
||||
}
|
||||
} //end "if (NbHits>0)"
|
||||
|
||||
// Analyse optical photons if they were produced
|
||||
if (musrParameters::boolG4OpticalPhotons) EndOfEvent_OptiacalPhotons();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void musrScintSD::EndOfEvent_OptiacalPhotons() {
|
||||
// G4double kCarTolerance = G4GeometryTolerance::GetInstance() ->GetSurfaceTolerance();
|
||||
// G4cout<<" DEBUG 10: kCarTolerance="<<kCarTolerance<<G4endl;
|
||||
|
||||
if (optHitMap.empty()) return;
|
||||
|
||||
G4RunManager* fRunManager = G4RunManager::GetRunManager();
|
||||
G4int eeeventID = fRunManager->GetCurrentEvent()->GetEventID();
|
||||
|
||||
for (optHitMapType::const_iterator it=optHitMap.begin() ; it != optHitMap.end(); it++ ) {
|
||||
G4bool boolStoreThisOPSAhist = false;
|
||||
G4int OPSA_detID= it->first;
|
||||
optHitDetectorMapType* optHitDetectorMap = it->second;
|
||||
|
||||
// Check whether OPSA histograming of times of optical photon detection is required for this eventID.
|
||||
if (bool_multimapOfEventIDsForOPSAhistosEXISTS) {
|
||||
if (multimapOfEventIDsForOPSAhistos.find(eeeventID)!=multimapOfEventIDsForOPSAhistos.end()) {
|
||||
// Now check whether the histogramming is required for the currently analysed detector.
|
||||
std::pair<multimapOfEventIDsForOPSAhistos_Type::iterator,multimapOfEventIDsForOPSAhistos_Type::iterator> retOPSAhist;
|
||||
multimapOfEventIDsForOPSAhistos_Type::iterator itOPSAhist;
|
||||
retOPSAhist = multimapOfEventIDsForOPSAhistos.equal_range(eeeventID);
|
||||
for (itOPSAhist = retOPSAhist.first; itOPSAhist!=retOPSAhist.second; itOPSAhist++) {
|
||||
// Store histograms if the second parameters of eventsForOPSAhistos (i.e. detector ID)
|
||||
// is set to 0 or corresponds to the currently analysed sensitive detector.
|
||||
if ( (itOPSAhist->second == 0) || (itOPSAhist->second == OPSA_detID) ) boolStoreThisOPSAhist = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optHitDetectorMap->empty()) continue;
|
||||
optHitDetectorMapType::const_iterator it2_START = optHitDetectorMap->begin();
|
||||
optHitDetectorMapType::const_iterator it2_STOP = it2_START;
|
||||
optHitDetectorMapType::const_iterator it2_LAST = optHitDetectorMap->end(); it2_LAST--;
|
||||
Double_t time = -1000, lastTime = -1000;
|
||||
G4int OPSA_nPhot = 0;
|
||||
G4double OPSA_timeFirst = -1000;
|
||||
G4double OPSA_timeA = -1000;
|
||||
G4double OPSA_timeB = -1000;
|
||||
G4double OPSA_timeC = -1000;
|
||||
G4double OPSA_timeD = -1000;
|
||||
G4double OPSA_timeE = -1000;
|
||||
G4double OPSA_timeLast = -1000;
|
||||
G4int iHistNr = -1;
|
||||
TF1* poiss = NULL;
|
||||
for (optHitDetectorMapType::const_iterator it2 = optHitDetectorMap->begin(); it2 != optHitDetectorMap->end(); it2++ ) {
|
||||
OPSA_nPhot++;
|
||||
lastTime = time;
|
||||
time = it2->first;
|
||||
if (OPSA_nPhot==1) lastTime=time; // First photon does not have a proper "lastTime" defined
|
||||
if ( (it2==it2_LAST) || ((time-lastTime) > OPSA_signalSeparationTime)) {
|
||||
// The iterator it2 reached last element of the map optHitDetectorMap or
|
||||
// the time difference between two subsequently detected photons is too big ==> divide the signal into more signals
|
||||
it2_STOP = it2;
|
||||
if (it2==it2_LAST) it2_STOP++; // if we are at the end of optHitDetectorMap,
|
||||
// the it2_STOP should point just behind the last map element
|
||||
else OPSA_nPhot--; // if we split the optHitDetectorMap, however, the latest optical photon
|
||||
// should have not be counted, because it belong to the next signal.
|
||||
optHitDetectorMapType optHitDetectorSUBmap(it2_START, it2_STOP);
|
||||
it2_START = it2_STOP;
|
||||
if (OPSA_nPhot >= OPSA_minNrOfDetectedPhotons) { // ignore hits with too low number of detected photons
|
||||
G4double OPSA_f_nPhot = OPSA_nPhot;
|
||||
G4int NA = int (OPSA_fracA * OPSA_f_nPhot + 0.5);
|
||||
G4int NB = int (OPSA_fracB * OPSA_f_nPhot + 0.5);
|
||||
G4int NC = int (OPSA_fracC * OPSA_f_nPhot + 0.5);
|
||||
G4int ND = int (OPSA_fracD * OPSA_f_nPhot + 0.5);
|
||||
G4int NE = int (OPSA_fracE * OPSA_f_nPhot + 0.5);
|
||||
Int_t nP=0;
|
||||
// Define OPSA histograms if required for this event
|
||||
if (boolStoreThisOPSAhist) {
|
||||
iHistNr++;
|
||||
char nameHist[100]; sprintf(nameHist,"OPSAhist_%d_%d_%d",eeeventID,OPSA_detID,iHistNr);
|
||||
char nameHistTitle[100]; sprintf(nameHistTitle,"OPSAhist_%d_%d_%d;time (ns);Nr of photons",eeeventID,OPSA_detID,iHistNr);
|
||||
OPSAhisto = new TH1D(nameHist, nameHistTitle, OPSAhistoNbin, OPSAhistoMin, OPSAhistoMax);
|
||||
poiss = new TF1("poiss",poissonf,0.,.5,2); // x in [0;300], 2
|
||||
poiss->SetParameter(0,1);
|
||||
poiss->SetParameter(1,1);
|
||||
}
|
||||
|
||||
for (optHitDetectorMapType::const_iterator it3 = optHitDetectorSUBmap.begin(); it3 != optHitDetectorSUBmap.end(); it3++) {
|
||||
nP++;
|
||||
if (nP==1) OPSA_timeFirst = it3->first;
|
||||
if (nP==NA) OPSA_timeA = it3->first;
|
||||
if (nP==NB) OPSA_timeB = it3->first;
|
||||
if (nP==NC) OPSA_timeC = it3->first;
|
||||
if (nP==ND) OPSA_timeD = it3->first;
|
||||
if (nP==NE) OPSA_timeE = it3->first;
|
||||
if (nP==OPSA_nPhot) OPSA_timeLast = it3->first;
|
||||
if (boolStoreThisOPSAhist) OPSAhisto->Fill((it3->first)-OPSA_timeFirst+0.00000000001);
|
||||
}
|
||||
signalInfo* mySignalInfo = new signalInfo(OPSA_detID,OPSA_nPhot,OPSA_timeFirst,OPSA_timeA,OPSA_timeB,OPSA_timeC,
|
||||
OPSA_timeD,OPSA_timeE,OPSA_timeLast);
|
||||
OPSA_signal_Map.insert(std::pair<G4int,signalInfo*>(OPSA_nPhot,mySignalInfo) );
|
||||
if (boolStoreThisOPSAhist) {
|
||||
OPSAhisto->Fit(poiss,"Q");
|
||||
OPSAhisto->Write();
|
||||
// TCanvas* cc = new TCanvas();
|
||||
// OPSAhisto->Draw();
|
||||
// cc->Update();
|
||||
}
|
||||
}
|
||||
OPSA_nPhot = 0;
|
||||
OPSA_timeFirst = -1000;
|
||||
OPSA_timeA = -1000;
|
||||
OPSA_timeB = -1000;
|
||||
OPSA_timeC = -1000;
|
||||
OPSA_timeD = -1000;
|
||||
OPSA_timeE = -1000;
|
||||
OPSA_timeLast = -1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now delete all optHitDetectorMap*
|
||||
for (optHitMapType::const_iterator it=optHitMap.begin() ; it != optHitMap.end(); it++ ) {
|
||||
delete (it->second);
|
||||
}
|
||||
optHitMap.clear();
|
||||
|
||||
|
||||
// Now store the information of all mySignalInfo* to rootOutputFile
|
||||
G4int nn=0;
|
||||
for (OPSA_signal_MapType::reverse_iterator ritOPSA = OPSA_signal_Map.rbegin(); ritOPSA != OPSA_signal_Map.rend(); ritOPSA++) {
|
||||
(ritOPSA->second) -> transferDataToRoot(myRootOutput,nn);
|
||||
nn++;
|
||||
}
|
||||
// Now delete all mySignalInfo* from OPSA_signal_Map
|
||||
for (OPSA_signal_MapType::const_iterator itOPSA = OPSA_signal_Map.begin(); itOPSA != OPSA_signal_Map.end(); itOPSA++) {
|
||||
delete (itOPSA->second);
|
||||
}
|
||||
OPSA_signal_Map.clear();
|
||||
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
@ -29,25 +29,35 @@
|
||||
#include "G4MagneticField.hh" // needed for storing the magnetic field to the Root class
|
||||
#include "G4FieldManager.hh" // ---------------||------------------
|
||||
#include "G4TransportationManager.hh" // ---------------||------------------
|
||||
//#include "G4OpBoundaryProcess.hh" // Optical photon process
|
||||
#include "musrErrorMessage.hh"
|
||||
#include "musrParameters.hh"
|
||||
#include "F04GlobalField.hh"
|
||||
//#include "TCanvas.h"
|
||||
//#include "TMath.h"
|
||||
//#include "TF1.h"
|
||||
//#include "G4GeometryTolerance.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//Double_t poissonf(Double_t* x, Double_t* par) {
|
||||
// return par[0]*TMath::Poisson(x[0],par[1]);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
musrSteppingAction::musrSteppingAction() {
|
||||
pointer=this;
|
||||
|
||||
boolIsAnySpecialSaveVolumeDefined = false;
|
||||
boolIsVvvInfoRequested = false;
|
||||
boolMuonEventReweighting = false;
|
||||
boolCalculateFieldIntegral = false;
|
||||
myRootOutput = musrRootOutput::GetRootInstance();
|
||||
if (myRootOutput == NULL) {
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,
|
||||
"musrSteppingAction::musrSteppingAction(): pointer to the musrRootOutput class not found! ==> EXECUTION STOPPED",true);
|
||||
}
|
||||
lastActualVolume="Unset";
|
||||
pointer=this;
|
||||
|
||||
boolIsAnySpecialSaveVolumeDefined = false;
|
||||
boolIsVvvInfoRequested = false;
|
||||
boolMuonEventReweighting = false;
|
||||
boolCalculateFieldIntegral = false;
|
||||
myRootOutput = musrRootOutput::GetRootInstance();
|
||||
if (myRootOutput == NULL) {
|
||||
musrErrorMessage::GetInstance()->musrError(FATAL,
|
||||
"musrSteppingAction::musrSteppingAction(): pointer to the musrRootOutput class not found! ==> EXECUTION STOPPED",true);
|
||||
}
|
||||
lastActualVolume="Unset";
|
||||
}
|
||||
|
||||
musrSteppingAction::~musrSteppingAction() {
|
||||
@ -140,7 +150,7 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
||||
}
|
||||
|
||||
|
||||
// Save info about the old tracks, if the user wish to have Vvv info in the output Root Tree.
|
||||
// Save info about the old tracks, if the user wishes to have Vvv info in the output Root Tree.
|
||||
if (boolIsVvvInfoRequested) {
|
||||
G4VPhysicalVolume* nextVolume = aTrack->GetNextVolume();
|
||||
if (nextVolume!=NULL) {
|
||||
@ -375,6 +385,7 @@ void musrSteppingAction::UserSteppingAction(const G4Step* aStep) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
@ -472,3 +483,17 @@ G4bool musrSteppingAction::AreTracksCommingFromSameParent(G4int trackID1, G4int
|
||||
// G4cout<<"\t\t\t\ttrack1="<<track1<<"\ttrack2="<<track2<<G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// //Double_t musrSteppingAction::poissonf(Double_t* x, Double_t* par)
|
||||
// //{
|
||||
//Double_t musrSteppingAction::poissonf(Double_t* x, Double_t* par) {
|
||||
// // if (x<0)
|
||||
// // return 0;
|
||||
// // else if (x == 0.0)
|
||||
// // return 1./Math::Exp(par);
|
||||
// // else {
|
||||
// // Double_t lnpoisson = x*log(par)-par-LnGamma(x+1.);
|
||||
// // return Exp(lnpoisson);
|
||||
// // }
|
||||
// return par[0]*TMath::Poisson(x[0],par[1]);
|
||||
//}
|
||||
|
Reference in New Issue
Block a user