Project

General

Profile

Support #595 » SciFiSD.cc

Heidt, Christopher, 13 August 2011 02:59

 
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
}
(2-2/2)