马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 猪猪虾 于 2023-8-27 17:37 编辑
(下面回复没有解决本质问题,大家别走)
我脑子已经转不动了,实在看不出来啥地方有问题了
有两个类,一个叫EventAction,另一个叫SteppingAction,一次EventAction的调用,会执行多次的SteppingAction的调用,总的会执行很多次的EventAction
我在EventAction类里面,每次EventAction类运行结束,我就对EventAction进行累加,并且加锁的方式判断当前是第几次EventAction,假设我有20次EventAction要执行,每5次的结果依次保存在一个新的txt文件夹里面,
当满足这个条件,我就EventAction里面重命名txt;
另一方面,在SteppingAction里面,我实时获取EventAction里面的txt的文件名字,然后将结果保存到新的txt里面
但是现在问题是,总是只有第一个默认的txt产生,其他txt在执行结束之后,都没有生成。我打印EventAction和SteppingAction里面的中间过程发现,txt名字的更改都是对的且传递也是对的,那么问题在哪呢
txt相关的主要在两个函数里面
EventAction.c 的 void EventAction::EndOfEventAction(const G4Event* aEvent)
以及 SteppingAction.c的void SteppingAction::UserSteppingAction(const G4Step* step)
//
//
/// \file EventAction.hh
namespace B1
{
class RunAction;
class EventAction : public G4UserEventAction
{
public:
EventAction(RunAction* runAction);
~EventAction() override;
void BeginOfEventAction(const G4Event* event) override;
void EndOfEventAction(const G4Event* event) override;
void AddEdep(G4int edep) { fEdep += edep; }
void test();
G4String Get_newFilename(){return filename_in_Event;};
private:
RunAction* fRunAction = nullptr;
G4double fEdep = 0.; //相当于全局变量,能量作加和,在AddEdep实现不断累加
static std::mutex myLock; // 用于保护需要同步的资源
static G4int TotalCount ;
static G4int FileCount ;
G4String filename_in_Event;
};
}
//
/// \file EventAction.cc
/// \brief Implementation of the B1::EventAction class
namespace B1
{
std::mutex EventAction::myLock;
G4int EventAction::TotalCount = 0;
G4int EventAction::FileCount = 0;
EventAction::EventAction(RunAction* runAction)
: fRunAction(runAction)
{
}
EventAction::~EventAction()
{}
void EventAction::BeginOfEventAction(const G4Event*)
{
fEdep = 0.;
}
void EventAction::EndOfEventAction(const G4Event* aEvent)
{
std::lock_guard<std::mutex> lock(myLock); // 加锁
TotalCount ++;
filename_in_Event = "NULL";
if(TotalCount %10000000 ==0)
{
FileCount ++;
filename_in_Event = "DataOfRun_" + std::to_string(FileCount) + ".txt";
// G4cout<< "*!!!!!!!!!!!!!!!!!!******* EndOfEventAction ,TotalCount : "<< TotalCount <<
// ",filename_in_Event :"<<filename_in_Event<<G4endl;
}
// test();
}
void EventAction::test()
{
G4String temp = "NULL";
temp = Get_newFilename();
if(temp == "NULL")
{
G4cout<< "*!!!!!!!!!!!!!!!!!!******* in EventAction :NULL "<<G4endl;
}
else
{
G4cout<< "*!!!!!!!!!!!!!!!!!!******* in EventAction : "<< temp<<G4endl;
}
}
}
//
/// \file SteppingAction.hh
using namespace std;
namespace B1
{
class EventAction;
class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction(EventAction* eventAction);
~SteppingAction() override;
void UserSteppingAction(const G4Step*) override;
private:
EventAction* fEventAction = nullptr;
G4LogicalVolume* fScoringVolume = nullptr;
G4String filename;
};
}
//
/// \file SteppingAction.cc
/// \brief Implementation of the B1::SteppingAction class
namespace B1
{
SteppingAction::SteppingAction(EventAction* eventAction)
: fEventAction(eventAction)
{
filename = "DataOfRun_0.txt";
}
SteppingAction::~SteppingAction()
{}
void SteppingAction::UserSteppingAction(const G4Step* step) {
G4String volumeName = step->GetPreStepPoint()->GetPhysicalVolume()->GetName();
G4String ParticleName = step->GetTrack()->GetDynamicParticle()->GetParticleDefinition()->GetParticleName();
G4String Newfilename = fEventAction->Get_newFilename();
// G4cout<< "*!!!!!!!!!!!!!!!!!!******* Newfilename: "<< Newfilename <<G4endl;
// G4cout<<"############# gaga : volumeName " << volumeName <<G4endl;
// if (ParticleName == "gamma" && volumeName == "DetectorArray")
if (volumeName == "DetectorArray")
{
G4int copyNo = step->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(0);
G4double edep = step->GetTotalEnergyDeposit();
if(Newfilename != "NULL")
{
ofstream outf;
outf.open(Newfilename,ios::app);
outf<< copyNo << ' ' << edep << ' ';
outf.close();
}
else
{
// G4cout<< "*!!!!!!!!!!!!!!!!!!******* in stepAction :NULL , filename = " << filename <<G4endl;
ofstream outf;
outf.open(filename,ios::app);
outf<< copyNo << ' ' << edep << ' ';
outf.close();
}
}
}
}
问题的原因是在EventAction类中,每次EventAction类运行结束后,你使用锁来判断当前是第几次EventAction,并根据条件对文件进行重命名。然而,在SteppingAction类中,你实时获取EventAction类中的文件名,并将结果保存到新的文件中。但是,你在SteppingAction类中使用的文件名始终是初始化时的默认文件名,而不是EventAction类中实时更新的文件名。
解决这个问题的方法是,在SteppingAction类中,你应该使用EventAction类的成员函数Get_newFilename()来获取实时更新的文件名。你可以在SteppingAction类的构造函数中将EventAction类的指针作为参数传递,并将其存储在SteppingAction类的成员变量fEventAction中。然后,在UserSteppingAction函数中,使用fEventAction->Get_newFilename()来获取实时更新的文件名。
以下是修改后的代码示例:
// SteppingAction.hh
using namespace std;
namespace B1
{
class EventAction;
class SteppingAction : public G4UserSteppingAction
{
public:
SteppingAction(EventAction* eventAction);
~SteppingAction() override;
void UserSteppingAction(const G4Step*) override;
private:
EventAction* fEventAction = nullptr;
G4LogicalVolume* fScoringVolume = nullptr;
G4String filename;
};
}
// SteppingAction.cc
namespace B1
{
SteppingAction::SteppingAction(EventAction* eventAction)
: fEventAction(eventAction)
{
filename = "DataOfRun_0.txt";
}
SteppingAction::~SteppingAction()
{}
void SteppingAction::UserSteppingAction(const G4Step* step)
{
G4String volumeName = step->GetPreStepPoint()->GetPhysicalVolume()->GetName();
G4String ParticleName = step->GetTrack()->GetDynamicParticle()->GetParticleDefinition()->GetParticleName();
G4String Newfilename = fEventAction->Get_newFilename();
// 使用实时更新的文件名Newfilename
if (volumeName == "DetectorArray")
{
G4int copyNo = step->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(0);
G4double edep = step->GetTotalEnergyDeposit();
if (Newfilename != "NULL")
{
ofstream outf;
outf.open(Newfilename, ios::app);
outf << copyNo << ' ' << edep << ' ';
outf.close();
}
else
{
ofstream outf;
outf.open(filename, ios::app);
outf << copyNo << ' ' << edep << ' ';
outf.close();
}
}
}
}
通过这种方式,你将能够在SteppingAction类中使用实时更新的文件名,并将结果保存到正确的文件中。
|