Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
extended/hadronic/Hadr01/src/HistoManager.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 /// \file hadronic/Hadr01/src/HistoManager.cc
27 /// \brief Implementation of the HistoManager class
28 //
29 // $Id: HistoManager.cc 70761 2013-06-05 12:30:51Z gcosmo $
30 //
31 //---------------------------------------------------------------------------
32 //
33 // ClassName: HistoManager
34 //
35 //
36 // Author: V.Ivanchenko 30/01/01
37 //
38 // Modified:
39 // 04.06.2006 Adoptation of Hadr01 (V.Ivanchenko)
40 // 16.11.2006 Add beamFlag (V.Ivanchenko)
41 //
42 //----------------------------------------------------------------------------
43 //
44 
45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
47 
48 #include "HistoManager.hh"
49 #include "G4Track.hh"
50 #include "G4Step.hh"
51 #include "G4UnitsTable.hh"
52 #include "G4Neutron.hh"
53 #include "G4Proton.hh"
54 #include "G4AntiProton.hh"
55 #include "G4Gamma.hh"
56 #include "G4Electron.hh"
57 #include "G4Positron.hh"
58 #include "G4MuonPlus.hh"
59 #include "G4MuonMinus.hh"
60 #include "G4PionPlus.hh"
61 #include "G4PionMinus.hh"
62 #include "G4PionZero.hh"
63 #include "G4KaonPlus.hh"
64 #include "G4KaonMinus.hh"
65 #include "G4KaonZeroShort.hh"
66 #include "G4KaonZeroLong.hh"
67 #include "G4Deuteron.hh"
68 #include "G4Triton.hh"
69 #include "G4He3.hh"
70 #include "G4Alpha.hh"
71 #include "Histo.hh"
72 #include "globals.hh"
73 #include "G4SystemOfUnits.hh"
74 #include "G4PhysicalConstants.hh"
75 
76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
77 
78 HistoManager* HistoManager::fManager = 0;
79 
80 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
81 
83 {
84  if(!fManager) {
85  static HistoManager manager;
86  fManager = &manager;
87  }
88  return fManager;
89 }
90 
91 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
92 
94 : fPrimaryDef(0),
95  fNeutron(0),
96  fEdepMax(1.0*GeV),
97  fLength (300.*mm),
98  fPrimaryKineticEnergy(0.0),
99  fVerbose(0),
100  fNBinsE (100),
101  fNSlices(300),
102  fNHisto (25),
103  fBeamFlag(true),
104  fHistoBooked(false),
105  fHisto(0)
106 {
107  fHisto = new Histo();
108  fHisto->SetVerbose(fVerbose);
109  fNeutron = G4Neutron::Neutron();
110 }
111 
112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
113 
115 {
116  delete fHisto;
117 }
118 
119 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
120 
122 {
123  fHistoBooked = true;
124  fHisto->Add1D("1","Energy deposition (MeV/mm/event) in the target",
125  fNSlices,0.0,fLength/mm,MeV/mm);
126  fHisto->Add1D("2","Log10 Energy (MeV) of gammas",fNBinsE,-5.,5.,1.0);
127  fHisto->Add1D("3","Log10 Energy (MeV) of electrons",fNBinsE,-5.,5.,1.0);
128  fHisto->Add1D("4","Log10 Energy (MeV) of positrons",fNBinsE,-5.,5.,1.0);
129  fHisto->Add1D("5","Log10 Energy (MeV) of protons",fNBinsE,-5.,5.,1.0);
130  fHisto->Add1D("6","Log10 Energy (MeV) of neutrons",fNBinsE,-5.,5.,1.0);
131  fHisto->Add1D("7","Log10 Energy (MeV) of charged pions",fNBinsE,-4.,6.,1.0);
132  fHisto->Add1D("8","Log10 Energy (MeV) of pi0",fNBinsE,-4.,6.,1.0);
133  fHisto->Add1D("9","Log10 Energy (MeV) of charged kaons",fNBinsE,-4.,6.,1.0);
134  fHisto->Add1D("10","Log10 Energy (MeV) of neutral kaons",fNBinsE,-4.,6.,1.0);
135  fHisto->Add1D("11","Log10 Energy (MeV) of deuterons and tritons",
136  fNBinsE,-5.,5.,1.0);
137  fHisto->Add1D("12","Log10 Energy (MeV) of He3 and alpha",fNBinsE,-5.,5.,1.0);
138  fHisto->Add1D("13","Log10 Energy (MeV) of Generic Ions",fNBinsE,-5.,5.,1.0);
139  fHisto->Add1D("14","Log10 Energy (MeV) of muons",fNBinsE,-4.,6.,1.0);
140  fHisto->Add1D("15","log10 Energy (MeV) of side-leaked neutrons",
141  fNBinsE,-5.,5.,1.0);
142  fHisto->Add1D("16","log10 Energy (MeV) of forward-leaked neutrons",
143  fNBinsE,-5.,5.,1.0);
144  fHisto->Add1D("17","log10 Energy (MeV) of backward-leaked neutrons",
145  fNBinsE,-5.,5.,1.0);
146  fHisto->Add1D("18","log10 Energy (MeV) of leaking protons",
147  fNBinsE,-4.,6.,1.0);
148  fHisto->Add1D("19","log10 Energy (MeV) of leaking charged pions",
149  fNBinsE,-4.,6.,1.0);
150  fHisto->Add1D("20","Log10 Energy (MeV) of pi+",fNBinsE,-4.,6.,1.0);
151  fHisto->Add1D("21","Log10 Energy (MeV) of pi-",fNBinsE,-4.,6.,1.0);
152  fHisto->Add1D("22",
153  "Energy deposition in the target normalized to beam energy",
154  110,0.0,1.1,1.0);
155  fHisto->Add1D("23",
156  "EM energy deposition in the target normalized to beam energy",
157  110,0.0,1.1,1.0);
158  fHisto->Add1D("24",
159  "Pion energy deposition in the target normalized to beam energy",
160  110,0.0,1.1,1.0);
161  fHisto->Add1D("25",
162  "Proton energy deposition in the target normalized to beam energy",
163  110,0.0,1.1,1.0);
164 }
165 
166 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
167 
169 {
170  fAbsZ0 = -0.5*fLength;
171  fNevt = 0;
172  fNelec = 0;
173  fNposit = 0;
174  fNgam = 0;
175  fNstep = 0;
176  fNprot_leak = 0;
177  fNpiofNleak = 0;
178  fNions = 0;
179  fNdeut = 0;
180  fNalpha = 0;
181  fNkaons = 0;
182  fNmuons = 0;
183  fNcpions = 0;
184  fNpi0 = 0;
185  fNneutron = 0;
186  fNproton = 0;
187  fNaproton = 0;
188  fNneu_forw = 0;
189  fNneu_leak = 0;
190  fNneu_back = 0;
191 
192  fEdepSum = 0.0;
193  fEdepSum2 = 0.0;
194 
195  if(!fHistoBooked) { bookHisto(); }
196  fHisto->Book();
197 
198  if(fVerbose > 0) {
199  G4cout << "HistoManager: Histograms are booked and run has been started"
200  <<G4endl;
201  }
202 }
203 
204 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
205 
207 {
208 
209  G4cout << "HistoManager: End of run actions are started" << G4endl;
210 
211  // Average values
212  G4cout<<"========================================================"<<G4endl;
213 
214  G4double x = (G4double)fNevt;
215  if(fNevt > 0) { x = 1.0/x; }
216 
217  G4double xe = x*(G4double)fNelec;
218  G4double xg = x*(G4double)fNgam;
219  G4double xp = x*(G4double)fNposit;
220  G4double xs = x*(G4double)fNstep;
221  G4double xn = x*(G4double)fNneutron;
222  G4double xpn = x*(G4double)fNproton;
223  G4double xap = x*(G4double)fNaproton;
224  G4double xnf = x*(G4double)fNneu_forw;
225  G4double xnb = x*(G4double)fNneu_leak;
226  G4double xnbw= x*(G4double)fNneu_back;
227  G4double xpl = x*(G4double)fNprot_leak;
228  G4double xal = x*(G4double)fNpiofNleak;
229  G4double xpc = x*(G4double)fNcpions;
230  G4double xp0 = x*(G4double)fNpi0;
231  G4double xpk = x*(G4double)fNkaons;
232  G4double xpm = x*(G4double)fNmuons;
233  G4double xid = x*(G4double)fNdeut;
234  G4double xia = x*(G4double)fNalpha;
235  G4double xio = x*(G4double)fNions;
236 
237  fEdepSum *= x;
238  fEdepSum2 *= x;
239  fEdepSum2 -= fEdepSum*fEdepSum;
240  if(fEdepSum2 > 0.0) { fEdepSum2 = std::sqrt(fEdepSum2); }
241  else { fEdepSum2 = 0.0; }
242 
243  G4cout << "Beam particle "
244  << fPrimaryDef->GetParticleName() <<G4endl;
245  G4cout << "Beam Energy(MeV) "
246  << fPrimaryKineticEnergy/MeV <<G4endl;
247  G4cout << "Number of events "
248  << fNevt <<G4endl;
249  G4cout << std::setprecision(4) << "Average energy deposit (MeV) "
250  << fEdepSum/MeV
251  << " RMS(MeV) " << fEdepSum2/MeV << G4endl;
252  G4cout << std::setprecision(4) << "Average number of steps "
253  << xs << G4endl;
254  G4cout << std::setprecision(4) << "Average number of gamma "
255  << xg << G4endl;
256  G4cout << std::setprecision(4) << "Average number of e- "
257  << xe << G4endl;
258  G4cout << std::setprecision(4) << "Average number of e+ "
259  << xp << G4endl;
260  G4cout << std::setprecision(4) << "Average number of neutrons "
261  << xn << G4endl;
262  G4cout << std::setprecision(4) << "Average number of protons "
263  << xpn << G4endl;
264  G4cout << std::setprecision(4) << "Average number of antiprotons "
265  << xap << G4endl;
266  G4cout << std::setprecision(4) << "Average number of pi+ & pi- "
267  << xpc << G4endl;
268  G4cout << std::setprecision(4) << "Average number of pi0 "
269  << xp0 << G4endl;
270  G4cout << std::setprecision(4) << "Average number of kaons "
271  << xpk << G4endl;
272  G4cout << std::setprecision(4) << "Average number of muons "
273  << xpm << G4endl;
274  G4cout << std::setprecision(4) << "Average number of deuterons+tritons "
275  << xid << G4endl;
276  G4cout << std::setprecision(4) << "Average number of He3+alpha "
277  << xia << G4endl;
278  G4cout << std::setprecision(4) << "Average number of ions "
279  << xio << G4endl;
280  G4cout << std::setprecision(4) << "Average number of forward neutrons "
281  << xnf << G4endl;
282  G4cout << std::setprecision(4) << "Average number of reflected neutrons "
283  << xnb << G4endl;
284  G4cout << std::setprecision(4) << "Average number of leaked neutrons "
285  << xnbw << G4endl;
286  G4cout << std::setprecision(4) << "Average number of proton leak "
287  << xpl << G4endl;
288  G4cout << std::setprecision(4) << "Average number of pion leak "
289  << xal << G4endl;
290  G4cout<<"========================================================"<<G4endl;
291  G4cout<<G4endl;
292 
293  // normalise histograms
294  for(G4int i=0; i<fNHisto; i++) {
295  fHisto->ScaleH1(i,x);
296  }
297 
298  fHisto->Save();
299 }
300 
301 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
302 
304 {
305  fEdepEvt = 0.0;
306  fEdepEM = 0.0;
307  fEdepPI = 0.0;
308  fEdepP = 0.0;
309 }
310 
311 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
312 
314 {
315  fEdepSum += fEdepEvt;
316  fEdepSum2 += fEdepEvt*fEdepEvt;
317  fHisto->Fill(21,fEdepEvt/fPrimaryKineticEnergy,1.0);
318  fHisto->Fill(22,fEdepEM/fPrimaryKineticEnergy,1.0);
319  fHisto->Fill(23,fEdepPI/fPrimaryKineticEnergy,1.0);
320  fHisto->Fill(24,fEdepP/fPrimaryKineticEnergy,1.0);
321 }
322 
323 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
324 
325 void HistoManager::ScoreNewTrack(const G4Track* track)
326 {
327  const G4ParticleDefinition* pd = track->GetDefinition();
328  G4String name = pd->GetParticleName();
329  G4double e = track->GetKineticEnergy();
330 
331  // Primary track
332  if(0 == track->GetParentID()) {
333 
334  fNevt++;
335  fPrimaryKineticEnergy = e;
336  fPrimaryDef = pd;
337  G4ThreeVector dir = track->GetMomentumDirection();
338  if(1 < fVerbose)
339  G4cout << "### Primary " << name
340  << " kinE(MeV)= " << e/MeV
341  << "; m(MeV)= " << pd->GetPDGMass()/MeV
342  << "; pos(mm)= " << track->GetPosition()/mm
343  << "; dir= " << track->GetMomentumDirection()
344  << G4endl;
345 
346  // Secondary track
347  } else {
348  if(1 < fVerbose)
349  G4cout << "=== Secondary " << name
350  << " kinE(MeV)= " << e/MeV
351  << "; m(MeV)= " << pd->GetPDGMass()/MeV
352  << "; pos(mm)= " << track->GetPosition()/mm
353  << "; dir= " << track->GetMomentumDirection()
354  << G4endl;
355  e = std::log10(e/MeV);
356  if(pd == G4Gamma::Gamma()) {
357  fNgam++;
358  fHisto->Fill(1,e,1.0);
359  } else if ( pd == G4Electron::Electron()) {
360  fNelec++;
361  fHisto->Fill(2,e,1.0);
362  } else if ( pd == G4Positron::Positron()) {
363  fNposit++;
364  fHisto->Fill(3,e,1.0);
365  } else if ( pd == G4Proton::Proton()) {
366  fNproton++;
367  fHisto->Fill(4,e,1.0);
368  } else if ( pd == fNeutron) {
369  fNneutron++;
370  fHisto->Fill(5,e,1.0);
371  } else if ( pd == G4AntiProton::AntiProton()) {
372  fNaproton++;
373  } else if ( pd == G4PionPlus::PionPlus() ) {
374  fNcpions++;
375  fHisto->Fill(6,e,1.0);
376  fHisto->Fill(19,e,1.0);
377 
378  } else if ( pd == G4PionMinus::PionMinus()) {
379  fNcpions++;
380  fHisto->Fill(6,e,1.0);
381  fHisto->Fill(20,e,1.0);
382 
383  } else if ( pd == G4PionZero::PionZero()) {
384  fNpi0++;
385  fHisto->Fill(7,e,1.0);
386  } else if ( pd == G4KaonPlus::KaonPlus() ||
387  pd == G4KaonMinus::KaonMinus()) {
388  fNkaons++;
389  fHisto->Fill(8,e,1.0);
390  } else if ( pd == G4KaonZeroShort::KaonZeroShort() ||
392  fNkaons++;
393  fHisto->Fill(9,e,1.0);
394  } else if ( pd == G4Deuteron::Deuteron() || pd == G4Triton::Triton()) {
395  fNdeut++;
396  fHisto->Fill(10,e,1.0);
397  } else if ( pd == G4He3::He3() || pd == G4Alpha::Alpha()) {
398  fNalpha++;
399  fHisto->Fill(11,e,1.0);
400  } else if ( pd->GetParticleType() == "nucleus") {
401  fNions++;
402  fHisto->Fill(12,e,1.0);
403  } else if ( pd == G4MuonPlus::MuonPlus() ||
404  pd == G4MuonMinus::MuonMinus()) {
405  fNmuons++;
406  fHisto->Fill(13,e,1.0);
407  }
408  }
409 }
410 
411 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
412 
414 {
415  fNstep++;
416  G4double fEdep = step->GetTotalEnergyDeposit();
417  if(1 < fVerbose) {
418  G4cout << "TargetSD::ProcessHits: beta1= "
419  << step->GetPreStepPoint()->GetVelocity()/c_light
420  << " beta2= " << step->GetPostStepPoint()->GetVelocity()/c_light
421  << " weight= " << step->GetTrack()->GetWeight()
422  << G4endl;
423  }
424  if(fEdep >= DBL_MIN) {
425  const G4Track* track = step->GetTrack();
426 
427  G4ThreeVector pos =
428  (step->GetPreStepPoint()->GetPosition() +
429  step->GetPostStepPoint()->GetPosition())*0.5;
430 
431  G4double z = pos.z() - fAbsZ0;
432 
433  // scoring
434  fEdepEvt += fEdep;
435  fHisto->Fill(0,z,fEdep);
436  const G4ParticleDefinition* pd = track->GetDefinition();
437 
438  if(pd == G4Gamma::Gamma() || pd == G4Electron::Electron()
439  || pd == G4Positron::Positron()) {
440  fEdepEM += fEdep;
441  } else if ( pd == G4PionPlus::PionPlus() ||
442  pd == G4PionMinus::PionMinus()) {
443  fEdepPI += fEdep;
444  } else if ( pd == G4Proton::Proton() ||
445  pd == G4AntiProton::AntiProton()) {
446  fEdepP += fEdep;
447  }
448 
449  if(1 < fVerbose) {
450  G4cout << "HistoManager::AddEnergy: e(keV)= " << fEdep/keV
451  << "; z(mm)= " << z/mm
452  << "; step(mm)= " << step->GetStepLength()/mm
453  << " by " << pd->GetParticleName()
454  << " E(MeV)= " << track->GetKineticEnergy()/MeV
455  << G4endl;
456  }
457  }
458 }
459 
460 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
461 
463 {
464  const G4ParticleDefinition* pd = track->GetDefinition();
465  G4double e = std::log10(track->GetKineticEnergy()/MeV);
466 
467  G4ThreeVector pos = track->GetPosition();
468  G4ThreeVector dir = track->GetMomentumDirection();
469  G4double x = pos.x();
470  G4double y = pos.y();
471  G4double z = pos.z();
472 
473  G4bool isLeaking = false;
474 
475  // Forward
476  if(z > -fAbsZ0 && dir.z() > 0.0) {
477  isLeaking = true;
478  if(pd == fNeutron) {
479  ++fNneu_forw;
480  fHisto->Fill(15,e,1.0);
481  } else isLeaking = true;
482 
483  // Backward
484  } else if (z < fAbsZ0 && dir.z() < 0.0) {
485  isLeaking = true;
486  if(pd == fNeutron) {
487  ++fNneu_back;
488  fHisto->Fill(16,e,1.0);
489  } else isLeaking = true;
490 
491  // Side
492  } else if (std::abs(z) <= -fAbsZ0 && x*dir.x() + y*dir.y() > 0.0) {
493  isLeaking = true;
494  if(pd == fNeutron) {
495  ++fNneu_leak;
496  fHisto->Fill(14,e,1.0);
497  } else isLeaking = true;
498  }
499 
500  // protons and pions
501  if(isLeaking) {
502  if(pd == G4Proton::Proton()) {
503  fHisto->Fill(17,e,1.0);
504  ++fNprot_leak;
505  } else if (pd == G4PionPlus::PionPlus() ||
506  pd == G4PionMinus::PionMinus()) {
507  fHisto->Fill(18,e,1.0);
508  ++fNpiofNleak;
509  }
510  }
511 }
512 
513 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
514 
516 {
517  fVerbose = val;
518  fHisto->SetVerbose(val);
519 }
520 
521 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
522 
524 {
525  fHisto->Fill(id, x, w);
526 }
527 
528 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
529 
G4ParticleDefinition * GetDefinition() const
G4int GetParentID() const
static G4MuonPlus * MuonPlus()
Definition: G4MuonPlus.cc:99
G4double GetStepLength() const
double x() const
G4double z
Definition: TRTMaterials.hh:39
const G4ThreeVector & GetPosition() const
static G4KaonZeroLong * KaonZeroLong()
const XML_Char * name
G4double GetVelocity() const
int G4int
Definition: G4Types.hh:78
const G4String & GetParticleName() const
double z() const
static G4KaonMinus * KaonMinus()
Definition: G4KaonMinus.cc:113
G4StepPoint * GetPreStepPoint() const
G4double GetKineticEnergy() const
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetPosition() const
static G4KaonZeroShort * KaonZeroShort()
static G4AntiProton * AntiProton()
Definition: G4AntiProton.cc:93
bool G4bool
Definition: G4Types.hh:79
static G4Triton * Triton()
Definition: G4Triton.cc:95
static G4Proton * Proton()
Definition: G4Proton.cc:93
static G4PionPlus * PionPlus()
Definition: G4PionPlus.cc:98
const G4String & GetParticleType() const
Definition: G4Step.hh:76
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
void Fill(G4int id, G4double x, G4double w)
static G4Gamma * Gamma()
Definition: G4Gamma.cc:86
static G4PionZero * PionZero()
Definition: G4PionZero.cc:104
static G4Deuteron * Deuteron()
Definition: G4Deuteron.cc:94
G4double GetTotalEnergyDeposit() const
static G4Positron * Positron()
Definition: G4Positron.cc:94
const G4ThreeVector & GetMomentumDirection() const
G4double GetPDGMass() const
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:98
G4StepPoint * GetPostStepPoint() const
double y() const
#define DBL_MIN
Definition: templates.hh:75
G4double GetWeight() const
static G4MuonMinus * MuonMinus()
Definition: G4MuonMinus.cc:100
static G4Electron * Electron()
Definition: G4Electron.cc:94
#define G4endl
Definition: G4ios.hh:61
static G4Alpha * Alpha()
Definition: G4Alpha.cc:89
double G4double
Definition: G4Types.hh:76
static G4KaonPlus * KaonPlus()
Definition: G4KaonPlus.cc:113
G4Track * GetTrack() const
static G4He3 * He3()
Definition: G4He3.cc:94
float c_light
Definition: hepunit.py:257