1
|
/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
|
2
|
*
|
3
|
* MAUS is free software: you can redistribute it and/or modify
|
4
|
* it under the terms of the GNU General Public License as published by
|
5
|
* the Free Software Foundation, either version 3 of the License, or
|
6
|
* (at your option) any later version.
|
7
|
*
|
8
|
* MAUS is distributed in the hope that it will be useful,
|
9
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
* GNU General Public License for more details.
|
12
|
*
|
13
|
* You should have received a copy of the GNU General Public License
|
14
|
* along with MAUS. If not, see <http://www.gnu.org/licenses/>.
|
15
|
*
|
16
|
*/
|
17
|
#include <iostream>
|
18
|
#include <fstream>
|
19
|
#include <cmath>
|
20
|
|
21
|
#include "TFile.h"
|
22
|
#include "TH1F.h"
|
23
|
#include "TH2F.h"
|
24
|
#include "TTree.h"
|
25
|
|
26
|
#include "G4TransportationManager.hh"
|
27
|
#include "G4FieldManager.hh"
|
28
|
#include "G4Field.hh"
|
29
|
#include "G4HCofThisEvent.hh"
|
30
|
#include "G4Step.hh"
|
31
|
#include "G4ThreeVector.hh"
|
32
|
#include "G4SDManager.hh"
|
33
|
#include "G4ios.hh"
|
34
|
|
35
|
#include "Interface/MICEEvent.hh"
|
36
|
#include "Config/MiceModule.hh"
|
37
|
|
38
|
#include "SciFiSD.hh"
|
39
|
|
40
|
SciFiSD::SciFiSD(MiceModule* mod) : MAUSSD(mod) {
|
41
|
}
|
42
|
|
43
|
|
44
|
G4bool SciFiSD::ProcessHits(G4Step* aStep, G4TouchableHistory* ROhist) {
|
45
|
|
46
|
/* edep reads the total energy deposited by an event. If the total energy is zero
|
47
|
then this function returns false, no hit has occured. If there was some energy
|
48
|
deposited in the tracker then space is made in the vector and the event information
|
49
|
is stored in the ith position */
|
50
|
G4double edep = aStep->GetTotalEnergyDeposit();
|
51
|
|
52
|
double pid = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
|
53
|
|
54
|
if ( edep == 0. ) return false;
|
55
|
|
56
|
int old_chanNo = legacy_chanNo(aStep);
|
57
|
|
58
|
//Every time the function is called hit_i is assigned to the final spot
|
59
|
//in the vector and then the size of the vector is increased by one.
|
60
|
int hit_i = _hits.size();
|
61
|
_hits.push_back(Json::Value());
|
62
|
|
63
|
//All the information for the tracker event is stored in _hits
|
64
|
G4TouchableHandle theTouchable = aStep->GetPreStepPoint()->GetTouchableHandle();
|
65
|
G4int fiberNumber = theTouchable->GetCopyNumber(); // get the fiber copy number
|
66
|
G4ThreeVector Pos = aStep->GetPreStepPoint()->GetPosition(); // true MC position
|
67
|
G4ThreeVector Mom = aStep->GetTrack()->GetMomentum(); // true momentum
|
68
|
|
69
|
Json::Value channel_id;
|
70
|
channel_id["type"] = "Tracker";
|
71
|
channel_id["fiber_number"] = fiberNumber;
|
72
|
channel_id["tracker_number"] = _module->propertyInt("Tracker");
|
73
|
channel_id["station_number"] = _module->propertyInt("Station");
|
74
|
channel_id["plane_number"] = _module->propertyInt("Plane");
|
75
|
|
76
|
_hits[hit_i]["channel_id"] = channel_id;
|
77
|
_hits[hit_i]["track_id"] = aStep->GetTrack()->GetTrackID();
|
78
|
_hits[hit_i]["energy"] = aStep->GetTrack()->GetTotalEnergy();
|
79
|
_hits[hit_i]["charge"] = aStep->GetTrack()->GetDefinition()->GetPDGCharge();
|
80
|
_hits[hit_i]["pid"] = pid;
|
81
|
_hits[hit_i]["mass"]= aStep->GetTrack()->GetDefinition()->GetPDGMass();
|
82
|
_hits[hit_i]["time"]= aStep->GetPreStepPoint()->GetGlobalTime();
|
83
|
_hits[hit_i]["energy_deposited"] = edep;
|
84
|
_hits[hit_i]["momentum"]["x"]=Mom.x();
|
85
|
_hits[hit_i]["momentum"]["y"]=Mom.y();
|
86
|
_hits[hit_i]["momentum"]["z"]=Mom.z();
|
87
|
_hits[hit_i]["hit_position"]["x"]=Pos.x();
|
88
|
_hits[hit_i]["hit_position"]["y"]=Pos.y();
|
89
|
_hits[hit_i]["hit_position"]["z"]=Pos.z();
|
90
|
|
91
|
/*
|
92
|
int parent = aStep->GetTrack()->GetParentID();
|
93
|
int track = aStep->GetTrack()->GetTrackID();
|
94
|
double alarm = 0;
|
95
|
|
96
|
if (_hits[hit_i]["momentum"]["z"].asDouble() < 0.0 ) {
|
97
|
alarm=-999;
|
98
|
}
|
99
|
std::ofstream out1("negative_mom.txt", std::ios::out | std::ios::app);
|
100
|
out1 << aStep->GetTrack()->GetCurrentStepNumber() << " " << _hits[hit_i]["momentum"]["x"].asDouble() << " " << _hits[hit_i]["momentum"]["y"].asDouble() << " " << _hits[hit_i]["momentum"]["z"].asDouble() << " "
|
101
|
<< _hits[hit_i]["hit_position"]["x"].asDouble() << " " << _hits[hit_i]["hit_position"]["y"].asDouble() << " " << _hits[hit_i]["hit_position"]["z"].asDouble()
|
102
|
<< " " << edep << " " << pid << " " << parent << " " << track << " " << alarm << "\n";
|
103
|
out1.close();
|
104
|
*/
|
105
|
|
106
|
//Determines the channel number the fiber is located in.
|
107
|
//It does not look like this is saved to a vector or used above, is this data used anywhere?
|
108
|
int chanNo;
|
109
|
int numbFibers = 7*2*(_module->propertyDouble("CentralFibre")+0.5);
|
110
|
if ( _module->propertyInt("Tracker") == 0 ) {
|
111
|
chanNo = floor((numbFibers-fiberNumber)/7.0);
|
112
|
} else {
|
113
|
chanNo = floor(fiberNumber/7.0); // -1 because we start numbering from 0
|
114
|
}
|
115
|
|
116
|
return true;
|
117
|
}
|
118
|
|
119
|
// Shouldn't this be used to clear out variables before calling the above again?
|
120
|
void SciFiSD::EndOfEvent(G4HCofThisEvent* HCE) {
|
121
|
// do nothing
|
122
|
}
|
123
|
|
124
|
// This probably should not be here in the final version.
|
125
|
// If we need a check on the above code a unit test should be written and placed there.
|
126
|
int SciFiSD::legacy_chanNo(G4Step* aStep) {
|
127
|
Hep3Vector pos = _module->globalPosition();
|
128
|
Hep3Vector perp(-1., 0., 0.);
|
129
|
double chanWidth = 1.4945; // effective channel width without overlap
|
130
|
perp *= _module->globalRotation();
|
131
|
Hep3Vector delta = aStep->GetPreStepPoint()->GetPosition() - pos;
|
132
|
double dist = delta.x() * perp.x() + delta.y() * perp.y() + delta.z() * perp.z();
|
133
|
double fibre = _module->propertyDouble("CentralFibre") + dist * 2.0 /
|
134
|
( _module->propertyDouble("Pitch") * 7.0 );
|
135
|
|
136
|
double centFibre = _module->propertyDouble("CentralFibre");
|
137
|
int firstChan = (int)(fibre + 0.5);
|
138
|
int secondChan(-1);
|
139
|
double overlap = chanWidth - (0.1365/2.0);
|
140
|
double underlap = (0.1365/2.0);
|
141
|
// int nChans(1);
|
142
|
nChans = 1;
|
143
|
double distInChan = ((firstChan - centFibre)*chanWidth) - dist;
|
144
|
// distance in channel greater than section which does not overlap
|
145
|
if ((sqrt(distInChan*distInChan) > overlap) || (sqrt(distInChan*distInChan) < underlap)) {
|
146
|
nChans = 2;
|
147
|
if (distInChan < 0) {
|
148
|
secondChan = firstChan - 1;
|
149
|
} else {
|
150
|
secondChan = firstChan + 1;
|
151
|
}
|
152
|
}
|
153
|
return firstChan;
|
154
|
}
|